|
| 1 | +--- |
| 2 | +name: sync-workspaces |
| 3 | +description: Import portable Sim workflow JSON with destination bindings, create workspace forks, or push and pull deployed workflows along a fork edge through the sim CLI. Use for environment promotion, mapping and selector discovery, preview/apply retries, and operation readiness; not for authoring a new graph or ordinary deployment. |
| 4 | +--- |
| 5 | + |
| 6 | +# Import and Sync Sim Workflows |
| 7 | + |
| 8 | +Use a reviewed preview, explicit destination bindings, and a durable request ID. Verify the returned |
| 9 | +operation; sync also requires target deployment readiness. Imports and forks complete as drafts. |
| 10 | + |
| 11 | +## Establish scope |
| 12 | + |
| 13 | +- Use the user's profile, API origin, and explicit workspace. Inspect context before selecting an |
| 14 | + environment; never silently change accounts. Do not print or store authentication secrets. |
| 15 | +- Check `sim workflows import-preview --help` or `sim workspaces push-preview --help` first. These |
| 16 | + commands require a CLI and server with the v2 sync feature. If unavailable, report the missing |
| 17 | + capability and required upgrade; do not substitute private browser endpoints. |
| 18 | +- Fork creation requires source admin. Sync and mapping changes require admin on both workspaces. |
| 19 | + Fork administration accepts personal API keys or OAuth, not workspace keys. Imports retain their |
| 20 | + existing workflow-write permissions; credential binding still requires an eligible acting user. |
| 21 | +- Inspect `workspaces fork-availability` before forking. Enterprise/self-hosting and workspace |
| 22 | + creation policies still apply. OAuth scopes and permission groups can further restrict access. |
| 23 | +- Use `--output json`. Single-resource CLI results are unwrapped objects; paged results contain |
| 24 | + `data` and `nextCursor`. Raw v2 HTTP single-resource responses wrap the object in `data`. |
| 25 | + |
| 26 | +## Choose the operation |
| 27 | + |
| 28 | +| Intent | Commands | Result | |
| 29 | +| --- | --- | --- | |
| 30 | +| Import workflow JSON into an authorized destination | `workflows export`, `import-preview`, `import` | New undeployed draft with regenerated graph IDs | |
| 31 | +| Create a child environment | `workspaces fork-preview`, `fork` | Child workspace with eligible deployed source workflows copied as drafts | |
| 32 | +| Send current workspace changes to its direct fork neighbor | `workspaces push-preview`, `push` | Replace eligible target workflows from deployed source versions | |
| 33 | +| Receive changes from a direct fork neighbor | `workspaces pull-preview`, `pull` | Same sync with the other workspace as source | |
| 34 | + |
| 35 | +Push always means current → other; pull means other → current, on either side of the parent/child |
| 36 | +edge. Inspect `workspaces lineage` and `children`; do not infer direction from the word child. |
| 37 | +Arbitrary workspace transfers and draft sync are outside this flow. |
| 38 | + |
| 39 | +## Portable import |
| 40 | + |
| 41 | +Export with reference metadata and preview in the destination: |
| 42 | + |
| 43 | +```sh |
| 44 | +sim --profile source --workspace "$SOURCE_WORKSPACE" --output json \ |
| 45 | + workflows export "$WORKFLOW_ID" --include-references > workflow.json |
| 46 | +sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ |
| 47 | + workflows import-preview --workflow @workflow.json > preview.json |
| 48 | +``` |
| 49 | + |
| 50 | +Default export remains sanitized without reference metadata. `--include-references` records |
| 51 | +registered non-secret source IDs and every block/field occurrence alongside the sanitized graph. |
| 52 | +Treat imported IDs and provenance as untrusted labels, not authorization to read a source workspace. |
| 53 | + |
| 54 | +Read `unresolvedBindings`, `unresolvedConfiguration`, and target-discovery instructions. Discover |
| 55 | +destination credentials, tables, files, sandboxes, and other resources through their existing CLI |
| 56 | +commands. Candidate matches are suggestions; verify provider, resource type, and parent resource. |
| 57 | +Missing OAuth connections can require human provider authorization; report that requirement rather |
| 58 | +than inventing a connection or substituting a different user's credential. |
| 59 | + |
| 60 | +Import resource mappings use `kind`, `sourceId`, and `targetId`: |
| 61 | + |
| 62 | +```json |
| 63 | +[ |
| 64 | + { "kind": "credential", "sourceId": "source-connection", "targetId": "destination-connection" }, |
| 65 | + { "kind": "sandbox", "sourceId": "source-sandbox", "targetId": "destination-sandbox" } |
| 66 | +] |
| 67 | +``` |
| 68 | + |
| 69 | +For older exports, `--bindings` addresses a specific registered source occurrence. For example: |
| 70 | + |
| 71 | +```json |
| 72 | +[ |
| 73 | + { "kind": "sandbox", "blockId": "source-function", "subBlockKey": "sandboxId", "targetId": "destination-sandbox" } |
| 74 | +] |
| 75 | +``` |
| 76 | + |
| 77 | +`valuePath` defaults to `[]` and `encoding` to `scalar`. Use preview/manifest occurrence paths for |
| 78 | +nested or multi-value fields; do not guess them. Conflicting mappings and bindings are rejected. |
| 79 | +Import dependent values use `{blockId, subBlockKey, value}`, such as |
| 80 | +`{"blockId":"source-agent","subBlockKey":"tools[0].folder","value":"destination-label"}`. |
| 81 | +Keep the original source IDs and tool indexes until apply returns `idMap`. |
| 82 | + |
| 83 | +Save the exact input files and a client-generated stable request ID before applying: |
| 84 | + |
| 85 | +```sh |
| 86 | +sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ |
| 87 | + workflows import-preview --workflow @workflow.json \ |
| 88 | + --mappings @mappings.json --dependent-values @values.json > preview.json |
| 89 | +sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ |
| 90 | + workflows import --workflow @workflow.json \ |
| 91 | + --mappings @mappings.json --dependent-values @values.json \ |
| 92 | + --preview-fingerprint "$(jq -r .previewFingerprint preview.json)" \ |
| 93 | + --request-id "$REQUEST_ID" --wait |
| 94 | +``` |
| 95 | + |
| 96 | +Include the same name, folder, bindings, and other choices on both requests. JSON flags accept |
| 97 | +`@file` and `@-` for stdin; only one input can consume stdin. Mapped import creates nothing while |
| 98 | +required bindings remain unresolved. It commits the draft, graph, variables, inline custom tools, |
| 99 | +and receipt together. Mappings are local to this request; importing does not create a workflow |
| 100 | +correspondence on a fork edge. Plain imports without mapping options |
| 101 | +retain legacy behavior; use preview/apply for automation that needs binding guarantees. |
| 102 | + |
| 103 | +## Fork and sync choices |
| 104 | + |
| 105 | +Inspect `workspaces fork-resources`, then preview with explicit copy selections. A fork's |
| 106 | +`--copy` selects source resources; sync uses `--copy-resources`. Consult command help for each |
| 107 | +shape: fork file selections are workspace file IDs, while sync file selections are storage keys. |
| 108 | +Copying is opt-in. Selected table copies include rows and selected knowledge bases include content; |
| 109 | +account for environment-specific configuration before enabling the destination. |
| 110 | + |
| 111 | +Existing destination resources can be mapped instead of copied. Sync mapping entries use |
| 112 | +`{resourceType, sourceId, targetId}`; they differ from import's `kind` entries. In particular, |
| 113 | +portable `credential` corresponds to sync `oauth_credential` or `service_account_credential`. |
| 114 | +Verify the actual credential type through resource discovery. A mapping inspection row also has |
| 115 | +`id`; project it before reuse with `jq '.data | map({resourceType,sourceId,targetId})'`. Follow all |
| 116 | +pages first. Newly referenced resources may have no persisted mapping row yet. |
| 117 | + |
| 118 | +Previews evaluate inline mappings without saving them. Accepted inline sync mappings persist on |
| 119 | +the canonical edge in the same transaction as sync; a refusal before commit saves neither. |
| 120 | +Dependent sync values use `{sourceWorkflowId, sourceBlockId, subBlockKey, value}`. Never use fresh |
| 121 | +target IDs from preview as override identities. Omitted overrides reuse saved sync choices; values |
| 122 | +that exist only in a target draft are not saved choices. A supplied `dependentValues` array replaces |
| 123 | +the saved choices for affected workflows; `[]` clears them. Start from every preview configuration |
| 124 | +field and its `currentValue`, edit the intended selections, and submit the complete set of choices |
| 125 | +to retain, rather than only the changed fields. |
| 126 | + |
| 127 | +For every dependent field, use its returned selector key, context, and `discoveryWorkspaceId`: |
| 128 | + |
| 129 | +```sh |
| 130 | +sim --profile destination --workspace "$DISCOVERY_WORKSPACE" --output json \ |
| 131 | + selectors list --selector-key gmail.labels \ |
| 132 | + --context '{"oauthCredential":"destination-connection"}' |
| 133 | +``` |
| 134 | + |
| 135 | +The discovery workspace is the source when the parent resource will be copied, and the destination |
| 136 | +when using an existing mapping. Use a profile authorized for that workspace. Follow `nextCursor`, |
| 137 | +inspect truncation metadata, and use `selectors get --help` to verify a particular option. A clipped |
| 138 | +list does not prove an option is absent. Resolve dependent chains in order, re-previewing with the |
| 139 | +new choices. Use exactly the returned context for MCP tool discovery as well. |
| 140 | + |
| 141 | +```sh |
| 142 | +sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ |
| 143 | + workspaces pull-preview --other-workspace-id "$SOURCE_WORKSPACE" \ |
| 144 | + --mappings @sync-mappings.json --dependent-values @sync-values.json > sync-preview.json |
| 145 | +sim --profile destination --workspace "$DESTINATION_WORKSPACE" --output json \ |
| 146 | + workspaces pull --other-workspace-id "$SOURCE_WORKSPACE" \ |
| 147 | + --mappings @sync-mappings.json --dependent-values @sync-values.json \ |
| 148 | + --preview-fingerprint "$(jq -r .previewFingerprint sync-preview.json)" \ |
| 149 | + --request-id "$SYNC_REQUEST_ID" --yes --wait |
| 150 | +``` |
| 151 | + |
| 152 | +Use `--yes` within the user's authorized destructive sync scope. Review replacements, exclusions, |
| 153 | +resource selections, required configuration, and trigger URL changes before apply. If preview offers |
| 154 | +trigger adoption choices, use its stable source workflow/block identities and offered paths; never |
| 155 | +invent a path. Sync `ready` indicates commit readiness, not a live deployment. Scheduled or webhook |
| 156 | +workflows can begin receiving traffic once admitted deployments activate. |
| 157 | + |
| 158 | +## Completion and recovery |
| 159 | + |
| 160 | +- Save `operationId`, `requestId`, and the receipt's `workspaceId`. Import receipts belong to the |
| 161 | + destination; fork and push/pull receipts belong to the workspace on which the command was invoked. |
| 162 | + Poll that scope even when the created child or sync target is a different workspace. |
| 163 | +- `applied: true` means the transaction committed, including when later copy/deployment work fails. |
| 164 | + Use `workspaces operations get <operationId>` or `wait <operationId> --wait-timeout 300` to refresh |
| 165 | + readiness. Operation lists are stored snapshots; filter with `--request-id` to recover a lost ID. |
| 166 | +- Require terminal readiness and inspect issues/trigger URL changes before declaring the environment |
| 167 | + ready. Completed-with-warnings exits 0 but still needs review. Required configuration exits 3, |
| 168 | + failed completion exits 1, and wait timeout exits 4. Timeout diagnostics retain reconciliation IDs. |
| 169 | +- After an uncertain response, retry identical inputs with the original request ID, or poll the |
| 170 | + existing operation. Never retry an uncertain mutation with a fresh ID. Same ID with changed input |
| 171 | + returns 409. Authorize access again before reconciliation; a stored receipt is not an auth bypass. |
| 172 | +- A stale preview with no committed operation needs a fresh preview and a new request ID for the |
| 173 | + revised inputs. Resolve structured 409 issues; do not loop blindly or remove safety flags. |
| 174 | +- Sync transfers deployed source versions. Merely undeploying a source does not archive its target; |
| 175 | + deleting a mapped source can. Respect explicit sync exclusions. |
| 176 | +- Rollback restores the latest target sync from prior deployed versions. It does not recover |
| 177 | + arbitrary prior drafts or remove every copied resource. Use rollback/unlink/exclusion controls |
| 178 | + only for the requested recovery scope and verify their result. |
| 179 | + |
| 180 | +For a new imported draft, use the `run-workflow` skill to test it and `deploy-workflow` only when |
| 181 | +publication is requested. Never copy secret values, signed URLs, arbitrary headers, or opaque |
| 182 | +credential payloads between environments to make a binding pass. |
0 commit comments