@synap-core/cli 1.10.0 → 1.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -198
- package/dist/build-info.json +6 -0
- package/dist/commands/agent-run.js +3 -2
- package/dist/commands/agent-run.js.map +1 -1
- package/dist/commands/agents.d.ts +33 -17
- package/dist/commands/agents.js +203 -237
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/app.d.ts +143 -0
- package/dist/commands/app.js +523 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/automate.d.ts +21 -0
- package/dist/commands/automate.js +42 -0
- package/dist/commands/automate.js.map +1 -0
- package/dist/commands/automation-schema.test.d.ts +16 -0
- package/dist/commands/automation-schema.test.js +77 -0
- package/dist/commands/automation-schema.test.js.map +1 -0
- package/dist/commands/automation.d.ts +12 -0
- package/dist/commands/automation.js +80 -35
- package/dist/commands/automation.js.map +1 -1
- package/dist/commands/bridge-setup.d.ts +14 -1
- package/dist/commands/bridge-setup.js +392 -128
- package/dist/commands/bridge-setup.js.map +1 -1
- package/dist/commands/cap-connections.d.ts +4 -4
- package/dist/commands/cap-connections.js +14 -14
- package/dist/commands/cap-connections.js.map +1 -1
- package/dist/commands/capability.d.ts +2 -0
- package/dist/commands/capability.js +297 -176
- package/dist/commands/capability.js.map +1 -1
- package/dist/commands/catalog.d.ts +275 -0
- package/dist/commands/catalog.js +481 -0
- package/dist/commands/catalog.js.map +1 -0
- package/dist/commands/cell.d.ts +155 -8
- package/dist/commands/cell.js +416 -40
- package/dist/commands/cell.js.map +1 -1
- package/dist/commands/centrality.js +3 -14
- package/dist/commands/centrality.js.map +1 -1
- package/dist/commands/connect.d.ts +38 -13
- package/dist/commands/connect.js +68 -167
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connections.d.ts +3 -2
- package/dist/commands/connections.js +95 -25
- package/dist/commands/connections.js.map +1 -1
- package/dist/commands/context.js +9 -2
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +34 -0
- package/dist/commands/data-extra.js +198 -25
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +120 -2
- package/dist/commands/data.js +307 -24
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +66 -4
- package/dist/commands/diagnose.js +329 -29
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/digest.js +2 -1
- package/dist/commands/digest.js.map +1 -1
- package/dist/commands/doc.d.ts +25 -4
- package/dist/commands/doc.js +100 -18
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +130 -0
- package/dist/commands/doctor.js +814 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.js +3 -1
- package/dist/commands/events.js.map +1 -1
- package/dist/commands/explain.js +5 -5
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/graph.js +5 -3
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/import.d.ts +368 -13
- package/dist/commands/import.js +1096 -55
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts +20 -9
- package/dist/commands/init.js +433 -973
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.d.ts +1 -0
- package/dist/commands/keys.js +15 -2
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/knowledge.d.ts +28 -6
- package/dist/commands/knowledge.js +358 -73
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/launch.js +2 -2
- package/dist/commands/launch.js.map +1 -1
- package/dist/commands/lens.d.ts +37 -1
- package/dist/commands/lens.js +193 -72
- package/dist/commands/lens.js.map +1 -1
- package/dist/commands/market-authoring.d.ts +72 -0
- package/dist/commands/market-authoring.js +566 -0
- package/dist/commands/market-authoring.js.map +1 -0
- package/dist/commands/market-official.d.ts +58 -0
- package/dist/commands/market-official.js +84 -0
- package/dist/commands/market-official.js.map +1 -0
- package/dist/commands/market.d.ts +419 -20
- package/dist/commands/market.js +2124 -193
- package/dist/commands/market.js.map +1 -1
- package/dist/commands/mcp.d.ts +70 -13
- package/dist/commands/mcp.js +308 -40
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/open.d.ts +39 -9
- package/dist/commands/open.js +80 -25
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/playbook.d.ts +42 -0
- package/dist/commands/playbook.js +162 -0
- package/dist/commands/playbook.js.map +1 -0
- package/dist/commands/pod.js +1 -1
- package/dist/commands/pod.js.map +1 -1
- package/dist/commands/pods.d.ts +19 -0
- package/dist/commands/pods.js +220 -85
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.d.ts +62 -0
- package/dist/commands/proposals-actions.js +146 -8
- package/dist/commands/proposals-actions.js.map +1 -1
- package/dist/commands/proposals-await.d.ts +68 -0
- package/dist/commands/proposals-await.js +248 -0
- package/dist/commands/proposals-await.js.map +1 -0
- package/dist/commands/proton-setup.d.ts +73 -0
- package/dist/commands/proton-setup.js +577 -0
- package/dist/commands/proton-setup.js.map +1 -0
- package/dist/commands/providers.d.ts +23 -0
- package/dist/commands/providers.js +126 -1
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/raycast.js +6 -2
- package/dist/commands/raycast.js.map +1 -1
- package/dist/commands/rule.d.ts +150 -0
- package/dist/commands/rule.js +447 -0
- package/dist/commands/rule.js.map +1 -0
- package/dist/commands/session-wait.d.ts +111 -0
- package/dist/commands/session-wait.js +209 -0
- package/dist/commands/session-wait.js.map +1 -0
- package/dist/commands/sessions.d.ts +52 -0
- package/dist/commands/sessions.js +479 -58
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/skill-manage.d.ts +21 -0
- package/dist/commands/skill-manage.js +136 -19
- package/dist/commands/skill-manage.js.map +1 -1
- package/dist/commands/skills.js +19 -1
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +1 -4
- package/dist/commands/status.js +5 -34
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/statusline.backoff.test.d.ts +13 -0
- package/dist/commands/statusline.backoff.test.js +100 -0
- package/dist/commands/statusline.backoff.test.js.map +1 -0
- package/dist/commands/statusline.js +16 -9
- package/dist/commands/statusline.js.map +1 -1
- package/dist/commands/sync-status.d.ts +12 -0
- package/dist/commands/sync-status.js +125 -0
- package/dist/commands/sync-status.js.map +1 -0
- package/dist/commands/templates-retire.d.ts +34 -0
- package/dist/commands/templates-retire.js +192 -0
- package/dist/commands/templates-retire.js.map +1 -0
- package/dist/commands/tools.js +6 -21
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/tracks.d.ts +51 -0
- package/dist/commands/tracks.js +291 -0
- package/dist/commands/tracks.js.map +1 -0
- package/dist/commands/update.d.ts +3 -11
- package/dist/commands/update.js +5 -134
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upload.d.ts +68 -0
- package/dist/commands/upload.js +257 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/commands/vendor.d.ts +28 -0
- package/dist/commands/vendor.js +110 -0
- package/dist/commands/vendor.js.map +1 -0
- package/dist/commands/versions.js +6 -0
- package/dist/commands/versions.js.map +1 -1
- package/dist/commands/view.js +10 -5
- package/dist/commands/view.js.map +1 -1
- package/dist/commands/whoami.d.ts +23 -3
- package/dist/commands/whoami.js +169 -23
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/worker.d.ts +122 -0
- package/dist/commands/worker.js +435 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/commands/worker.test.d.ts +1 -0
- package/dist/commands/worker.test.js +116 -0
- package/dist/commands/worker.test.js.map +1 -0
- package/dist/commands/workspace-ops.d.ts +35 -0
- package/dist/commands/workspace-ops.js +153 -0
- package/dist/commands/workspace-ops.js.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1009 -171
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-connections.d.ts +31 -0
- package/dist/lib/agent-connections.js +33 -0
- package/dist/lib/agent-connections.js.map +1 -0
- package/dist/lib/agent-detect.d.ts +27 -0
- package/dist/lib/agent-detect.js +71 -0
- package/dist/lib/agent-detect.js.map +1 -0
- package/dist/lib/agent-door.d.ts +138 -0
- package/dist/lib/agent-door.js +426 -0
- package/dist/lib/agent-door.js.map +1 -0
- package/dist/lib/agents-config.d.ts +2 -0
- package/dist/lib/agents-config.js +4 -9
- package/dist/lib/agents-config.js.map +1 -1
- package/dist/lib/approval-poll.d.ts +31 -2
- package/dist/lib/approval-poll.js +20 -7
- package/dist/lib/approval-poll.js.map +1 -1
- package/dist/lib/atomic-file.d.ts +48 -0
- package/dist/lib/atomic-file.js +129 -0
- package/dist/lib/atomic-file.js.map +1 -0
- package/dist/lib/auth.d.ts +14 -9
- package/dist/lib/auth.js +44 -61
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/batch-approval.d.ts +85 -0
- package/dist/lib/batch-approval.js +170 -0
- package/dist/lib/batch-approval.js.map +1 -0
- package/dist/lib/capture-lane.d.ts +6 -5
- package/dist/lib/capture-lane.js +11 -8
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +342 -0
- package/dist/lib/capture-structure.js +295 -0
- package/dist/lib/capture-structure.js.map +1 -0
- package/dist/lib/catalog-templates.d.ts +59 -0
- package/dist/lib/catalog-templates.js +126 -0
- package/dist/lib/catalog-templates.js.map +1 -0
- package/dist/lib/cli-build.d.ts +19 -0
- package/dist/lib/cli-build.js +37 -0
- package/dist/lib/cli-build.js.map +1 -0
- package/dist/lib/conversation-headers.d.ts +18 -0
- package/dist/lib/conversation-headers.js +32 -0
- package/dist/lib/conversation-headers.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +216 -4
- package/dist/lib/cp-packages.js +414 -11
- package/dist/lib/cp-packages.js.map +1 -1
- package/dist/lib/credential-class.d.ts +117 -0
- package/dist/lib/credential-class.js +116 -0
- package/dist/lib/credential-class.js.map +1 -0
- package/dist/lib/describe-lens.d.ts +35 -0
- package/dist/lib/describe-lens.js +40 -0
- package/dist/lib/describe-lens.js.map +1 -1
- package/dist/lib/device-connect.d.ts +125 -0
- package/dist/lib/device-connect.js +256 -0
- package/dist/lib/device-connect.js.map +1 -0
- package/dist/lib/directory-lens.d.ts +99 -0
- package/dist/lib/directory-lens.js +187 -0
- package/dist/lib/directory-lens.js.map +1 -0
- package/dist/lib/exporter-coverage.d.ts +71 -0
- package/dist/lib/exporter-coverage.js +97 -0
- package/dist/lib/exporter-coverage.js.map +1 -0
- package/dist/lib/hub-client.d.ts +43 -9
- package/dist/lib/hub-client.js +429 -65
- package/dist/lib/hub-client.js.map +1 -1
- package/dist/lib/id.d.ts +23 -0
- package/dist/lib/id.js +35 -0
- package/dist/lib/id.js.map +1 -0
- package/dist/lib/init-connect.d.ts +41 -0
- package/dist/lib/init-connect.js +75 -0
- package/dist/lib/init-connect.js.map +1 -0
- package/dist/lib/init-exit.d.ts +24 -0
- package/dist/lib/init-exit.js +41 -0
- package/dist/lib/init-exit.js.map +1 -0
- package/dist/lib/init-flow.d.ts +25 -0
- package/dist/lib/init-flow.js +40 -0
- package/dist/lib/init-flow.js.map +1 -0
- package/dist/lib/init-handoff.d.ts +16 -0
- package/dist/lib/init-handoff.js +19 -0
- package/dist/lib/init-handoff.js.map +1 -0
- package/dist/lib/init-output.d.ts +18 -0
- package/dist/lib/init-output.js +43 -0
- package/dist/lib/init-output.js.map +1 -0
- package/dist/lib/init-pod.d.ts +45 -0
- package/dist/lib/init-pod.js +36 -0
- package/dist/lib/init-pod.js.map +1 -0
- package/dist/lib/installed.d.ts +210 -11
- package/dist/lib/installed.js +234 -36
- package/dist/lib/installed.js.map +1 -1
- package/dist/lib/key-approval.d.ts +57 -0
- package/dist/lib/key-approval.js +117 -0
- package/dist/lib/key-approval.js.map +1 -0
- package/dist/lib/key-diagnosis.d.ts +56 -0
- package/dist/lib/key-diagnosis.js +227 -0
- package/dist/lib/key-diagnosis.js.map +1 -0
- package/dist/lib/key-doctor.d.ts +136 -0
- package/dist/lib/key-doctor.js +286 -0
- package/dist/lib/key-doctor.js.map +1 -0
- package/dist/lib/key-locations.d.ts +120 -0
- package/dist/lib/key-locations.js +326 -0
- package/dist/lib/key-locations.js.map +1 -0
- package/dist/lib/key-source.d.ts +66 -0
- package/dist/lib/key-source.js +106 -0
- package/dist/lib/key-source.js.map +1 -0
- package/dist/lib/key-state.d.ts +70 -0
- package/dist/lib/key-state.js +115 -0
- package/dist/lib/key-state.js.map +1 -0
- package/dist/lib/kind-package.d.ts +181 -0
- package/dist/lib/kind-package.js +679 -0
- package/dist/lib/kind-package.js.map +1 -0
- package/dist/lib/knowledge-title.d.ts +24 -0
- package/dist/lib/knowledge-title.js +46 -0
- package/dist/lib/knowledge-title.js.map +1 -0
- package/dist/lib/knowledge-title.test.d.ts +1 -0
- package/dist/lib/knowledge-title.test.js +34 -0
- package/dist/lib/knowledge-title.test.js.map +1 -0
- package/dist/lib/machine-instance.d.ts +64 -0
- package/dist/lib/machine-instance.js +142 -0
- package/dist/lib/machine-instance.js.map +1 -0
- package/dist/lib/mcp-bridge.d.ts +42 -0
- package/dist/lib/mcp-bridge.js +147 -0
- package/dist/lib/mcp-bridge.js.map +1 -0
- package/dist/lib/mcp-bridge.test.d.ts +1 -0
- package/dist/lib/mcp-bridge.test.js +90 -0
- package/dist/lib/mcp-bridge.test.js.map +1 -0
- package/dist/lib/mcp-call.d.ts +30 -0
- package/dist/lib/mcp-call.js +107 -0
- package/dist/lib/mcp-call.js.map +1 -0
- package/dist/lib/mcp-snippets.d.ts +53 -0
- package/dist/lib/mcp-snippets.js +82 -0
- package/dist/lib/mcp-snippets.js.map +1 -0
- package/dist/lib/next-steps.d.ts +8 -0
- package/dist/lib/next-steps.js +31 -1
- package/dist/lib/next-steps.js.map +1 -1
- package/dist/lib/package-wire.d.ts +179 -0
- package/dist/lib/package-wire.js +68 -0
- package/dist/lib/package-wire.js.map +1 -0
- package/dist/lib/pair-link.d.ts +38 -0
- package/dist/lib/pair-link.js +68 -0
- package/dist/lib/pair-link.js.map +1 -0
- package/dist/lib/pod-wide.d.ts +40 -0
- package/dist/lib/pod-wide.js +46 -0
- package/dist/lib/pod-wide.js.map +1 -0
- package/dist/lib/pod.d.ts +119 -115
- package/dist/lib/pod.js +206 -412
- package/dist/lib/pod.js.map +1 -1
- package/dist/lib/project-ref.d.ts +9 -3
- package/dist/lib/project-ref.js +10 -4
- package/dist/lib/project-ref.js.map +1 -1
- package/dist/lib/review-credential.d.ts +119 -0
- package/dist/lib/review-credential.js +147 -0
- package/dist/lib/review-credential.js.map +1 -0
- package/dist/lib/safe-open.d.ts +49 -0
- package/dist/lib/safe-open.js +119 -0
- package/dist/lib/safe-open.js.map +1 -0
- package/dist/lib/session-lens.d.ts +40 -1
- package/dist/lib/session-lens.js +54 -4
- package/dist/lib/session-lens.js.map +1 -1
- package/dist/lib/superwhisper-import.d.ts +8 -0
- package/dist/lib/superwhisper-import.js +14 -7
- package/dist/lib/superwhisper-import.js.map +1 -1
- package/dist/lib/superwhisper-title.test.d.ts +1 -0
- package/dist/lib/superwhisper-title.test.js +18 -0
- package/dist/lib/superwhisper-title.test.js.map +1 -0
- package/dist/lib/targets.d.ts +134 -10
- package/dist/lib/targets.js +962 -258
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/template-file.d.ts +78 -0
- package/dist/lib/template-file.js +140 -0
- package/dist/lib/template-file.js.map +1 -0
- package/dist/lib/template-lifecycle.d.ts +217 -0
- package/dist/lib/template-lifecycle.js +433 -0
- package/dist/lib/template-lifecycle.js.map +1 -0
- package/dist/lib/template-steps.d.ts +88 -0
- package/dist/lib/template-steps.js +118 -0
- package/dist/lib/template-steps.js.map +1 -0
- package/dist/lib/time-ago.d.ts +2 -0
- package/dist/lib/time-ago.js +15 -0
- package/dist/lib/time-ago.js.map +1 -0
- package/dist/utils/logger.js +5 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +25 -18
- package/skills/README.md +12 -10
- package/skills/agent-os/SKILL.md +220 -99
- package/skills/manifest.json +2 -2
- package/skills/onboard/SKILL.md +61 -25
- package/skills/synap/README.md +5 -8
- package/skills/synap/SKILL.md +1185 -301
- package/skills/synap/_order.txt +7 -0
- package/skills/synap/_skill.yaml +1 -1
- package/skills/synap/automations.md +15 -0
- package/skills/synap/capture.md +54 -151
- package/skills/synap/cli-operations.md +24 -18
- package/skills/synap/common-mistakes.md +1 -0
- package/skills/synap/concepts.md +28 -0
- package/skills/synap/content-os.md +92 -0
- package/skills/synap/creative-loop.md +15 -10
- package/skills/synap/crm.md +21 -52
- package/skills/synap/digesting-a-channel.md +25 -0
- package/skills/synap/document-embeds.md +141 -47
- package/skills/synap/escalation-ladder.md +20 -10
- package/skills/synap/focus-sessions.md +47 -21
- package/skills/synap/from-intent.md +142 -0
- package/skills/synap/governance-rules.md +4 -4
- package/skills/synap/governance.md +10 -7
- package/skills/synap/hand-off.md +33 -0
- package/skills/synap/inline-patterns.md +15 -7
- package/skills/synap/lenses.md +33 -15
- package/skills/synap/linking.md +41 -40
- package/skills/synap/mcp-remote-servers.md +64 -0
- package/skills/synap/mental-model.md +24 -22
- package/skills/synap/multi-entity-capture.md +6 -4
- package/skills/synap/operating-mode-rules.md +1 -1
- package/skills/synap/processes.md +118 -0
- package/skills/synap/quick-reference.md +5 -1
- package/skills/synap/reading.md +3 -1
- package/skills/synap/reflexes.md +12 -42
- package/skills/synap/viewframe-cells.md +38 -5
- package/skills/synap/work-flow.md +1 -1
- package/skills/synap/work-model.md +96 -0
- package/skills/synap/worked-examples.md +21 -1
- package/skills/synap/workspace-design.md +14 -10
- package/skills/synap/writes.md +165 -35
- package/skills/synap/writing-titles.md +63 -0
- package/skills/synap-app/SKILL.md +319 -0
- package/skills/synap-app/_order.txt +5 -0
- package/skills/synap-app/_skill.yaml +20 -0
- package/skills/synap-app/creating-the-base-app.md +64 -0
- package/skills/synap-app/governance.md +42 -0
- package/skills/synap-app/install-commands.md +55 -0
- package/skills/synap-app/overview.md +50 -0
- package/skills/synap-app/using-the-sdk.md +73 -0
- package/skills/synap-design/SKILL.md +474 -0
- package/skills/synap-design/_order.txt +4 -0
- package/skills/synap-design/_skill.yaml +21 -0
- package/skills/synap-design/loop.md +134 -0
- package/skills/synap-design/overview.md +44 -0
- package/skills/synap-design/principles.md +130 -0
- package/skills/synap-design/system.md +133 -0
- package/skills/synap-market/SKILL.md +625 -0
- package/skills/synap-market/_order.txt +5 -0
- package/skills/synap-market/_skill.yaml +24 -0
- package/skills/synap-market/author-and-publish.md +212 -0
- package/skills/synap-market/discover-and-fetch.md +59 -0
- package/skills/synap-market/governance-and-catalog.md +63 -0
- package/skills/synap-market/install.md +133 -0
- package/skills/synap-market/overview.md +119 -0
- package/skills/synap-schema/SKILL.md +172 -10
- package/skills/synap-schema/_order.txt +2 -0
- package/skills/synap-schema/_skill.yaml +4 -2
- package/skills/synap-schema/common-mistakes.md +4 -2
- package/skills/synap-schema/discover-profiles.md +1 -1
- package/skills/synap-schema/entity-scope.md +15 -3
- package/skills/synap-schema/extend-first.md +29 -0
- package/skills/synap-schema/extend-vs-create.md +1 -1
- package/skills/synap-schema/intent-vocabulary-ssot.md +111 -0
- package/skills/synap-schema/property-types.md +1 -1
- package/skills/synap-schema/relations.md +1 -1
- package/skills/synap-ui/SKILL.md +19 -12
- package/skills/synap-ui/_skill.yaml +1 -1
- package/skills/synap-ui/ai-companion.md +1 -1
- package/skills/synap-ui/arranging-bento.md +2 -0
- package/skills/synap-ui/bento-layouts.md +10 -10
- package/skills/synap-ui/bento-recipes.md +313 -543
- package/skills/synap-ui/four-builds.md +5 -0
- package/skills/synap-ui/view-types.md +2 -2
- package/skills/synap-ui/widget-catalog.md +22 -278
- package/templates/automations/bookmark-enrichment.automation.json +290 -13
- package/templates/automations/url-bookmark-capture.automation.json +73 -11
- package/templates/skills/authoring-playbooks/SKILL.md +6 -3
- package/templates/skills/authoring-playbooks/reference/stages-contract.md +15 -0
- package/templates/skills/authoring-playbooks/reference/worked-example.md +3 -0
- package/dist/commands/infra.d.ts +0 -21
- package/dist/commands/infra.js +0 -262
- package/dist/commands/infra.js.map +0 -1
- package/dist/lib/browser-auth.d.ts +0 -35
- package/dist/lib/browser-auth.js +0 -170
- package/dist/lib/browser-auth.js.map +0 -1
- package/dist/lib/openclaw.d.ts +0 -32
- package/dist/lib/openclaw.js +0 -164
- package/dist/lib/openclaw.js.map +0 -1
- package/dist/lib/seed.d.ts +0 -13
- package/dist/lib/seed.js +0 -135
- package/dist/lib/seed.js.map +0 -1
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template lifecycle on the CLI side — two pod answers rendered in plain words.
|
|
3
|
+
*
|
|
4
|
+
* 1. DATA CHANGES that ride a template update (contract C). The pod's update
|
|
5
|
+
* preview lists conversion ops still owed to this pod's data
|
|
6
|
+
* (`dataChanges: [{ opKey, description, affected, destructive }]`); a real
|
|
7
|
+
* apply that does not consent to every one of them is refused with 409
|
|
8
|
+
* `DATA_CHANGES_NEED_CONSENT` and writes nothing. This module turns that
|
|
9
|
+
* wire into lines a person reads, and decides which opKeys the person has
|
|
10
|
+
* ACTUALLY agreed to — never more.
|
|
11
|
+
* 2. RETIRED TEMPLATES (contract A). The pod's template health says, per
|
|
12
|
+
* workspace, whether its template is `current`, `retired` (replaced by X),
|
|
13
|
+
* `unlisted` (gone from a COMPLETE catalog read) or `unknown` (the catalog
|
|
14
|
+
* read was not provably complete — never claimed gone).
|
|
15
|
+
*
|
|
16
|
+
* Every parser here distinguishes "the pod did not send this field" (an older
|
|
17
|
+
* pod: behave exactly as before) from "the pod sent it and it is empty"
|
|
18
|
+
* (nothing to agree to). The two are different facts and are never folded.
|
|
19
|
+
*/
|
|
20
|
+
export interface DataChange {
|
|
21
|
+
/** Stable conversion-op key — what `acceptDataChanges` names. */
|
|
22
|
+
opKey: string;
|
|
23
|
+
/** One plain sentence from the pod, e.g. "Deals move their stage to the commercial stage". */
|
|
24
|
+
description: string;
|
|
25
|
+
/** Records the engine's own dry run says the op changes, pod-wide. `null` = not counted (see `error`). */
|
|
26
|
+
affected: number | null;
|
|
27
|
+
/**
|
|
28
|
+
* The op retires data. It is NEVER run by an update and cannot be agreed to
|
|
29
|
+
* here: it is an operator step (`operatorCommand`). The CLI never sends its key.
|
|
30
|
+
*/
|
|
31
|
+
destructive: boolean;
|
|
32
|
+
/** Why the count failed, when `affected` is null. */
|
|
33
|
+
error?: string;
|
|
34
|
+
/** Destructive only: the command an operator runs (dry run first). */
|
|
35
|
+
operatorCommand?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare const DATA_CHANGES_CONSENT_CODE = "DATA_CHANGES_NEED_CONSENT";
|
|
38
|
+
/**
|
|
39
|
+
* Read `dataChanges` off a pod response.
|
|
40
|
+
* - `undefined`: the pod sent no such field (an older pod) — behave as before.
|
|
41
|
+
* - `[]`: the pod checked and nothing is owed.
|
|
42
|
+
* Entries without an `opKey` are dropped: a change with no key cannot be
|
|
43
|
+
* consented to, so it cannot be sent back either.
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseDataChanges(raw: unknown): DataChange[] | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* The data changes a space's update is HELD for, as the pod's health row
|
|
48
|
+
* carries them (Hub `GET /workspaces` `pendingDataChanges`): the stamp waits
|
|
49
|
+
* until a person agrees. The row has no opKeys — the person's door is
|
|
50
|
+
* `synap templates update <slug>`, whose prompt lists them with their keys.
|
|
51
|
+
*/
|
|
52
|
+
export interface PendingDataChanges {
|
|
53
|
+
/** How many changes the update waits on. 0 only when `unreadable`. */
|
|
54
|
+
count: number;
|
|
55
|
+
/** The pod's own sentence per change (or the one "could not be read" sentence). */
|
|
56
|
+
sentences: string[];
|
|
57
|
+
/** The pod knows the update is held but could not read which changes. Held all the same. */
|
|
58
|
+
unreadable: boolean;
|
|
59
|
+
/** The READER cannot agree themselves: it takes a pod owner or admin. */
|
|
60
|
+
needsPodAdmin: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read `pendingDataChanges` off a health row.
|
|
64
|
+
* - `undefined`: the pod sent no such field (an older pod) — draw nothing new.
|
|
65
|
+
* - `null`: the pod checked and nothing is held.
|
|
66
|
+
* A malformed value reads as `undefined` (unknown), never as "nothing held".
|
|
67
|
+
*/
|
|
68
|
+
export declare function parsePendingDataChanges(row: Record<string, unknown>): PendingDataChanges | null | undefined;
|
|
69
|
+
/** An agent's pending "update this space" proposal (`updateProposal`), or null. */
|
|
70
|
+
export declare function parseUpdateProposal(row: Record<string, unknown>): {
|
|
71
|
+
id: string;
|
|
72
|
+
} | null;
|
|
73
|
+
/** The data changes a 409 consent refusal carries, or null when the error is something else. */
|
|
74
|
+
export declare function dataChangesFromRefusal(err: unknown): DataChange[] | null;
|
|
75
|
+
/**
|
|
76
|
+
* True when a 409 consent refusal is about WHO asked, not what was agreed: the
|
|
77
|
+
* caller is an agent, and only a person can agree to a data change. The pod
|
|
78
|
+
* says so with `needsPerson`; an older pod is read from its shape — it refuses
|
|
79
|
+
* a person only for a missing agreement, so an empty `missing` beside an owed
|
|
80
|
+
* agreeable change can only be an agent's refusal.
|
|
81
|
+
*/
|
|
82
|
+
export declare function consentNeedsPerson(err: unknown): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* The pod's two other data-change refusals, in plain words. `null` for any
|
|
85
|
+
* other error (the caller's generic failure path renders those).
|
|
86
|
+
* - 403 `DATA_CHANGES_NEED_POD_ADMIN`: you agreed, but a data change rewrites
|
|
87
|
+
* its kind pod-wide, so only a pod owner or admin may run it.
|
|
88
|
+
* - 409 `DATA_CHANGES_FAILED`: a change failed mid-run; the template was NOT
|
|
89
|
+
* applied. Changes that ran stay applied, so a re-run lists only the rest.
|
|
90
|
+
*/
|
|
91
|
+
export declare function dataChangeRefusalMessage(err: unknown): string | null;
|
|
92
|
+
/** One line per data change: the pod's own sentence, then its count. */
|
|
93
|
+
export declare function formatDataChange(dc: DataChange): string;
|
|
94
|
+
/** Print the "Data changes" block for one template. Prints nothing for an empty list. */
|
|
95
|
+
export declare function printDataChanges(slug: string, changes: DataChange[]): void;
|
|
96
|
+
/** `--accept-data-changes a,b c` → ["a","b","c"]. Commander hands a string (or undefined). */
|
|
97
|
+
export declare function parseAcceptList(raw: string | string[] | undefined): string[];
|
|
98
|
+
export interface ConsentDecision {
|
|
99
|
+
/** opKeys the person agreed to, in the pod's order. Only these are ever sent. */
|
|
100
|
+
accepted: string[];
|
|
101
|
+
/** Agreeable changes the person has NOT agreed to. Non-empty ⇒ the update must not be applied. */
|
|
102
|
+
missing: DataChange[];
|
|
103
|
+
/** Destructive changes the person named: an operator step, so never sent. */
|
|
104
|
+
refusedOperatorSteps: string[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Decide consent WITHOUT prompting. Only NON-destructive changes can be agreed
|
|
108
|
+
* to here; a destructive one is an operator step, never sent (the pod refuses
|
|
109
|
+
* an accepted destructive key). `yes` agrees to every agreeable change (the
|
|
110
|
+
* person typed `--yes` on a command that has just printed them); otherwise only
|
|
111
|
+
* the opKeys named in `acceptList` count. A name that is not pending is simply
|
|
112
|
+
* not sent — agreeing to a change the pod did not list means nothing.
|
|
113
|
+
*/
|
|
114
|
+
export declare function decideConsent(pending: DataChange[], input: {
|
|
115
|
+
yes?: boolean;
|
|
116
|
+
acceptList?: string[];
|
|
117
|
+
}): ConsentDecision;
|
|
118
|
+
/** The exact command that re-runs an update with consent to these changes. */
|
|
119
|
+
export declare function consentRerunCommand(slug: string, changes: DataChange[]): string;
|
|
120
|
+
/**
|
|
121
|
+
* What the CLI says when the pod refuses an update for its data changes (409
|
|
122
|
+
* `DATA_CHANGES_NEED_CONSENT`). `person` = `consentNeedsPerson`: the refusal is
|
|
123
|
+
* about WHO ran it. The person may well be at this terminal with an agent key
|
|
124
|
+
* configured, so the hint says how to tell: `synap whoami` must say
|
|
125
|
+
* "Is agent: no" for the agreement to count.
|
|
126
|
+
*/
|
|
127
|
+
export declare function consentRefusalLines(name: string, slug: string, owed: DataChange[], person: boolean): {
|
|
128
|
+
warn: string;
|
|
129
|
+
hints: string[];
|
|
130
|
+
};
|
|
131
|
+
export type TemplateLifecycle = "current" | "retired" | "unlisted" | "unknown";
|
|
132
|
+
export interface LifecycleInfo {
|
|
133
|
+
lifecycle: TemplateLifecycle;
|
|
134
|
+
replacedBy: string | null;
|
|
135
|
+
retiredReason: string | null;
|
|
136
|
+
/** The pod's own plain sentence (`lifecycleWarning`) — preferred over the CLI's fallback wording. */
|
|
137
|
+
warning: string | null;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Read lifecycle off a Hub `/workspaces` row. `undefined` = the pod sent no
|
|
141
|
+
* lifecycle (older pod): the caller shows exactly what it showed before. A
|
|
142
|
+
* value this CLI does not know reads as `unknown` — never as `current`.
|
|
143
|
+
*/
|
|
144
|
+
export declare function parseLifecycle(row: Record<string, unknown>): LifecycleInfo | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* The plain sentence for a template that is not `current`, with the command
|
|
147
|
+
* that acts on it. Null for `current` (nothing to say).
|
|
148
|
+
*/
|
|
149
|
+
export declare function lifecycleNotice(slug: string, info: LifecycleInfo): {
|
|
150
|
+
label: string;
|
|
151
|
+
action: string | null;
|
|
152
|
+
} | null;
|
|
153
|
+
export interface OverlayInfo {
|
|
154
|
+
slug: string;
|
|
155
|
+
info: LifecycleInfo;
|
|
156
|
+
/** Retired, and its replacement is already on this space: nothing to move. */
|
|
157
|
+
replacementHere: boolean;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Read `overlays` off a Hub `/workspaces` row. `undefined` = the pod sent no
|
|
161
|
+
* such field (an older pod): show exactly what was shown before. `[]` = the
|
|
162
|
+
* space has no overlays. An entry with no lifecycle reads as `unknown`.
|
|
163
|
+
*/
|
|
164
|
+
export declare function parseOverlays(row: Record<string, unknown>): OverlayInfo[] | undefined;
|
|
165
|
+
/**
|
|
166
|
+
* The notice for an overlay: the SAME label `lifecycleNotice` gives a space
|
|
167
|
+
* (the pod's own sentence first), but never an action — an overlay is not a
|
|
168
|
+
* space, so `synap templates retire` has nothing to move for it.
|
|
169
|
+
*/
|
|
170
|
+
export declare function overlayNotice(o: OverlayInfo): {
|
|
171
|
+
label: string;
|
|
172
|
+
action: null;
|
|
173
|
+
} | null;
|
|
174
|
+
/** An overlay that needs the person: retired, and its replacement is not on the space. */
|
|
175
|
+
export declare function overlayNeedsAttention(o: OverlayInfo): boolean;
|
|
176
|
+
export interface RetireMove {
|
|
177
|
+
kind: string;
|
|
178
|
+
count: number | null;
|
|
179
|
+
}
|
|
180
|
+
export interface RetireStay {
|
|
181
|
+
kind: string;
|
|
182
|
+
count: number | null;
|
|
183
|
+
reason: string;
|
|
184
|
+
}
|
|
185
|
+
export interface RetirePlan {
|
|
186
|
+
sourceName: string | null;
|
|
187
|
+
sourceSlug: string | null;
|
|
188
|
+
targetSlug: string | null;
|
|
189
|
+
targetWorkspaceId: string | null;
|
|
190
|
+
targetName: string | null;
|
|
191
|
+
willInstall: boolean;
|
|
192
|
+
moves: RetireMove[];
|
|
193
|
+
stays: RetireStay[];
|
|
194
|
+
willArchive: boolean | null;
|
|
195
|
+
}
|
|
196
|
+
export type RetireOutcome = {
|
|
197
|
+
kind: "plan";
|
|
198
|
+
plan: RetirePlan;
|
|
199
|
+
} | {
|
|
200
|
+
kind: "applied";
|
|
201
|
+
plan: RetirePlan;
|
|
202
|
+
archived: boolean | null;
|
|
203
|
+
remaining: RetireStay[];
|
|
204
|
+
} | {
|
|
205
|
+
kind: "proposed";
|
|
206
|
+
plan: RetirePlan | null;
|
|
207
|
+
proposalId: string | null;
|
|
208
|
+
reviewUrl: string | null;
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* Parse the retire-into response defensively. Returns null when the body has
|
|
212
|
+
* no recognisable plan AND no proposal — a caller must then say "the pod's
|
|
213
|
+
* answer couldn't be read", never "nothing to move".
|
|
214
|
+
*/
|
|
215
|
+
export declare function parseRetireResponse(raw: unknown): RetireOutcome | null;
|
|
216
|
+
/** The plan in plain lines (no trailing hints). */
|
|
217
|
+
export declare function formatRetirePlan(plan: RetirePlan): string[];
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template lifecycle on the CLI side — two pod answers rendered in plain words.
|
|
3
|
+
*
|
|
4
|
+
* 1. DATA CHANGES that ride a template update (contract C). The pod's update
|
|
5
|
+
* preview lists conversion ops still owed to this pod's data
|
|
6
|
+
* (`dataChanges: [{ opKey, description, affected, destructive }]`); a real
|
|
7
|
+
* apply that does not consent to every one of them is refused with 409
|
|
8
|
+
* `DATA_CHANGES_NEED_CONSENT` and writes nothing. This module turns that
|
|
9
|
+
* wire into lines a person reads, and decides which opKeys the person has
|
|
10
|
+
* ACTUALLY agreed to — never more.
|
|
11
|
+
* 2. RETIRED TEMPLATES (contract A). The pod's template health says, per
|
|
12
|
+
* workspace, whether its template is `current`, `retired` (replaced by X),
|
|
13
|
+
* `unlisted` (gone from a COMPLETE catalog read) or `unknown` (the catalog
|
|
14
|
+
* read was not provably complete — never claimed gone).
|
|
15
|
+
*
|
|
16
|
+
* Every parser here distinguishes "the pod did not send this field" (an older
|
|
17
|
+
* pod: behave exactly as before) from "the pod sent it and it is empty"
|
|
18
|
+
* (nothing to agree to). The two are different facts and are never folded.
|
|
19
|
+
*/
|
|
20
|
+
import chalk from "chalk";
|
|
21
|
+
import { HubError } from "./hub-client.js";
|
|
22
|
+
export const DATA_CHANGES_CONSENT_CODE = "DATA_CHANGES_NEED_CONSENT";
|
|
23
|
+
/**
|
|
24
|
+
* Read `dataChanges` off a pod response.
|
|
25
|
+
* - `undefined`: the pod sent no such field (an older pod) — behave as before.
|
|
26
|
+
* - `[]`: the pod checked and nothing is owed.
|
|
27
|
+
* Entries without an `opKey` are dropped: a change with no key cannot be
|
|
28
|
+
* consented to, so it cannot be sent back either.
|
|
29
|
+
*/
|
|
30
|
+
export function parseDataChanges(raw) {
|
|
31
|
+
if (!raw || typeof raw !== "object")
|
|
32
|
+
return undefined;
|
|
33
|
+
const field = raw.dataChanges;
|
|
34
|
+
if (!Array.isArray(field))
|
|
35
|
+
return undefined;
|
|
36
|
+
const out = [];
|
|
37
|
+
for (const item of field) {
|
|
38
|
+
if (!item || typeof item !== "object")
|
|
39
|
+
continue;
|
|
40
|
+
const r = item;
|
|
41
|
+
const opKey = typeof r.opKey === "string" ? r.opKey.trim() : "";
|
|
42
|
+
if (!opKey)
|
|
43
|
+
continue;
|
|
44
|
+
const affected = typeof r.affected === "number" && Number.isFinite(r.affected) ? r.affected : null;
|
|
45
|
+
out.push({
|
|
46
|
+
opKey,
|
|
47
|
+
description: typeof r.description === "string" && r.description.trim()
|
|
48
|
+
? r.description.trim()
|
|
49
|
+
: opKey,
|
|
50
|
+
affected,
|
|
51
|
+
destructive: r.destructive === true,
|
|
52
|
+
...(typeof r.error === "string" && r.error.trim() ? { error: r.error.trim() } : {}),
|
|
53
|
+
...(typeof r.operatorCommand === "string" && r.operatorCommand.trim()
|
|
54
|
+
? { operatorCommand: r.operatorCommand.trim() }
|
|
55
|
+
: {}),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Read `pendingDataChanges` off a health row.
|
|
62
|
+
* - `undefined`: the pod sent no such field (an older pod) — draw nothing new.
|
|
63
|
+
* - `null`: the pod checked and nothing is held.
|
|
64
|
+
* A malformed value reads as `undefined` (unknown), never as "nothing held".
|
|
65
|
+
*/
|
|
66
|
+
export function parsePendingDataChanges(row) {
|
|
67
|
+
if (!("pendingDataChanges" in row))
|
|
68
|
+
return undefined;
|
|
69
|
+
const raw = row.pendingDataChanges;
|
|
70
|
+
if (raw === null)
|
|
71
|
+
return null;
|
|
72
|
+
if (!raw || typeof raw !== "object")
|
|
73
|
+
return undefined;
|
|
74
|
+
const r = raw;
|
|
75
|
+
const sentences = Array.isArray(r.sentences)
|
|
76
|
+
? r.sentences.filter((s) => typeof s === "string" && s.trim() !== "").map((s) => s.trim())
|
|
77
|
+
: [];
|
|
78
|
+
const count = typeof r.count === "number" && Number.isFinite(r.count) ? r.count : sentences.length;
|
|
79
|
+
return {
|
|
80
|
+
count,
|
|
81
|
+
sentences,
|
|
82
|
+
unreadable: r.unreadable === true,
|
|
83
|
+
// Unknown reads as "you may not be able to agree": the pod's own default.
|
|
84
|
+
needsPodAdmin: r.needsPodAdmin !== false,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** An agent's pending "update this space" proposal (`updateProposal`), or null. */
|
|
88
|
+
export function parseUpdateProposal(row) {
|
|
89
|
+
const raw = row.updateProposal;
|
|
90
|
+
return raw && typeof raw.id === "string" && raw.id ? { id: raw.id } : null;
|
|
91
|
+
}
|
|
92
|
+
/** The data changes a 409 consent refusal carries, or null when the error is something else. */
|
|
93
|
+
export function dataChangesFromRefusal(err) {
|
|
94
|
+
if (!(err instanceof HubError))
|
|
95
|
+
return null;
|
|
96
|
+
const body = err.body;
|
|
97
|
+
const code = err.code ?? (typeof body?.code === "string" ? body.code : undefined);
|
|
98
|
+
if (err.status !== 409 || code !== DATA_CHANGES_CONSENT_CODE)
|
|
99
|
+
return null;
|
|
100
|
+
return parseDataChanges(body) ?? [];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* True when a 409 consent refusal is about WHO asked, not what was agreed: the
|
|
104
|
+
* caller is an agent, and only a person can agree to a data change. The pod
|
|
105
|
+
* says so with `needsPerson`; an older pod is read from its shape — it refuses
|
|
106
|
+
* a person only for a missing agreement, so an empty `missing` beside an owed
|
|
107
|
+
* agreeable change can only be an agent's refusal.
|
|
108
|
+
*/
|
|
109
|
+
export function consentNeedsPerson(err) {
|
|
110
|
+
if (dataChangesFromRefusal(err) === null)
|
|
111
|
+
return false;
|
|
112
|
+
const body = err.body;
|
|
113
|
+
if (typeof body?.needsPerson === "boolean")
|
|
114
|
+
return body.needsPerson;
|
|
115
|
+
const owed = parseDataChanges(body) ?? [];
|
|
116
|
+
return Array.isArray(body?.missing) && body.missing.length === 0 && owed.some((d) => !d.destructive);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The pod's two other data-change refusals, in plain words. `null` for any
|
|
120
|
+
* other error (the caller's generic failure path renders those).
|
|
121
|
+
* - 403 `DATA_CHANGES_NEED_POD_ADMIN`: you agreed, but a data change rewrites
|
|
122
|
+
* its kind pod-wide, so only a pod owner or admin may run it.
|
|
123
|
+
* - 409 `DATA_CHANGES_FAILED`: a change failed mid-run; the template was NOT
|
|
124
|
+
* applied. Changes that ran stay applied, so a re-run lists only the rest.
|
|
125
|
+
*/
|
|
126
|
+
export function dataChangeRefusalMessage(err) {
|
|
127
|
+
if (!(err instanceof HubError))
|
|
128
|
+
return null;
|
|
129
|
+
const body = err.body;
|
|
130
|
+
const code = err.code ?? (typeof body?.code === "string" ? body.code : undefined);
|
|
131
|
+
if (err.status === 403 && code === "DATA_CHANGES_NEED_POD_ADMIN") {
|
|
132
|
+
return "Its data changes rewrite records across the whole pod, so only a pod owner or admin can run them. Nothing was written.";
|
|
133
|
+
}
|
|
134
|
+
if (err.status === 409 && code === "DATA_CHANGES_FAILED") {
|
|
135
|
+
const detail = typeof body?.error === "string" && body.error.trim() ? ` ${body.error.trim()}` : "";
|
|
136
|
+
return `A data change failed, so the template was not applied.${detail} The changes that ran stay done; run the update again to finish.`;
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
function countPhrase(n) {
|
|
141
|
+
if (n === null)
|
|
142
|
+
return "count not reported";
|
|
143
|
+
return `${n} ${n === 1 ? "record" : "records"}`;
|
|
144
|
+
}
|
|
145
|
+
/** One line per data change: the pod's own sentence, then its count. */
|
|
146
|
+
export function formatDataChange(dc) {
|
|
147
|
+
let line = `${dc.description} ${chalk.dim(`(${countPhrase(dc.affected)} · ${dc.opKey})`)}`;
|
|
148
|
+
if (dc.affected === null && dc.error) {
|
|
149
|
+
line += "\n " + chalk.yellow(`The pod couldn't count it: ${dc.error}`);
|
|
150
|
+
}
|
|
151
|
+
if (dc.destructive) {
|
|
152
|
+
line += "\n " + chalk.dim("It retires old data, so it never runs with an update. An operator runs it:");
|
|
153
|
+
if (dc.operatorCommand)
|
|
154
|
+
line += "\n " + chalk.dim(dc.operatorCommand);
|
|
155
|
+
}
|
|
156
|
+
return line;
|
|
157
|
+
}
|
|
158
|
+
/** Print the "Data changes" block for one template. Prints nothing for an empty list. */
|
|
159
|
+
export function printDataChanges(slug, changes) {
|
|
160
|
+
if (changes.length === 0)
|
|
161
|
+
return;
|
|
162
|
+
console.log(" " + chalk.bold(`Data changes for ${slug}`) + chalk.dim(" (they run with the update, once you agree)"));
|
|
163
|
+
for (const dc of changes.filter((d) => !d.destructive))
|
|
164
|
+
console.log(" • " + formatDataChange(dc));
|
|
165
|
+
const operator = changes.filter((d) => d.destructive);
|
|
166
|
+
if (operator.length > 0) {
|
|
167
|
+
console.log(" " + chalk.bold(`Operator steps for ${slug}`) + chalk.dim(" (never run by an update)"));
|
|
168
|
+
for (const dc of operator)
|
|
169
|
+
console.log(" • " + formatDataChange(dc));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** `--accept-data-changes a,b c` → ["a","b","c"]. Commander hands a string (or undefined). */
|
|
173
|
+
export function parseAcceptList(raw) {
|
|
174
|
+
if (!raw)
|
|
175
|
+
return [];
|
|
176
|
+
const parts = Array.isArray(raw) ? raw : [raw];
|
|
177
|
+
return parts
|
|
178
|
+
.flatMap((p) => p.split(/[,\s]+/))
|
|
179
|
+
.map((s) => s.trim())
|
|
180
|
+
.filter(Boolean);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Decide consent WITHOUT prompting. Only NON-destructive changes can be agreed
|
|
184
|
+
* to here; a destructive one is an operator step, never sent (the pod refuses
|
|
185
|
+
* an accepted destructive key). `yes` agrees to every agreeable change (the
|
|
186
|
+
* person typed `--yes` on a command that has just printed them); otherwise only
|
|
187
|
+
* the opKeys named in `acceptList` count. A name that is not pending is simply
|
|
188
|
+
* not sent — agreeing to a change the pod did not list means nothing.
|
|
189
|
+
*/
|
|
190
|
+
export function decideConsent(pending, input) {
|
|
191
|
+
const named = new Set(input.acceptList ?? []);
|
|
192
|
+
const accepted = [];
|
|
193
|
+
const missing = [];
|
|
194
|
+
const refusedOperatorSteps = [];
|
|
195
|
+
for (const d of pending) {
|
|
196
|
+
if (d.destructive) {
|
|
197
|
+
if (named.has(d.opKey))
|
|
198
|
+
refusedOperatorSteps.push(d.opKey);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (input.yes || named.has(d.opKey))
|
|
202
|
+
accepted.push(d.opKey);
|
|
203
|
+
else
|
|
204
|
+
missing.push(d);
|
|
205
|
+
}
|
|
206
|
+
return { accepted, missing, refusedOperatorSteps };
|
|
207
|
+
}
|
|
208
|
+
/** The exact command that re-runs an update with consent to these changes. */
|
|
209
|
+
export function consentRerunCommand(slug, changes) {
|
|
210
|
+
const keys = changes.filter((d) => !d.destructive).map((d) => d.opKey);
|
|
211
|
+
return `synap templates update ${slug} --accept-data-changes ${keys.join(",")}`;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* What the CLI says when the pod refuses an update for its data changes (409
|
|
215
|
+
* `DATA_CHANGES_NEED_CONSENT`). `person` = `consentNeedsPerson`: the refusal is
|
|
216
|
+
* about WHO ran it. The person may well be at this terminal with an agent key
|
|
217
|
+
* configured, so the hint says how to tell: `synap whoami` must say
|
|
218
|
+
* "Is agent: no" for the agreement to count.
|
|
219
|
+
*/
|
|
220
|
+
export function consentRefusalLines(name, slug, owed, person) {
|
|
221
|
+
const warn = person
|
|
222
|
+
? `${name} was not updated: only a person can agree to its data changes, and this ran with an agent's key. Nothing was written.`
|
|
223
|
+
: `${name} was not updated: it carries data changes you have not agreed to. Nothing was written.`;
|
|
224
|
+
if (!owed.some((d) => !d.destructive))
|
|
225
|
+
return { warn, hints: [] };
|
|
226
|
+
const rerun = consentRerunCommand(slug, owed);
|
|
227
|
+
return {
|
|
228
|
+
warn,
|
|
229
|
+
hints: person
|
|
230
|
+
? [
|
|
231
|
+
`A person runs, in their own terminal: ${rerun}`,
|
|
232
|
+
"Check the key first: `synap whoami` must say Is agent: no.",
|
|
233
|
+
]
|
|
234
|
+
: [`To agree and update: ${rerun}`],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const LIFECYCLES = new Set(["current", "retired", "unlisted", "unknown"]);
|
|
238
|
+
/**
|
|
239
|
+
* Read lifecycle off a Hub `/workspaces` row. `undefined` = the pod sent no
|
|
240
|
+
* lifecycle (older pod): the caller shows exactly what it showed before. A
|
|
241
|
+
* value this CLI does not know reads as `unknown` — never as `current`.
|
|
242
|
+
*/
|
|
243
|
+
export function parseLifecycle(row) {
|
|
244
|
+
const raw = row.lifecycle;
|
|
245
|
+
if (raw === undefined || raw === null)
|
|
246
|
+
return undefined;
|
|
247
|
+
const lifecycle = typeof raw === "string" && LIFECYCLES.has(raw) ? raw : "unknown";
|
|
248
|
+
const str = (v) => (typeof v === "string" && v.trim() ? v.trim() : null);
|
|
249
|
+
return {
|
|
250
|
+
lifecycle,
|
|
251
|
+
replacedBy: str(row.replacedBy),
|
|
252
|
+
retiredReason: str(row.retiredReason),
|
|
253
|
+
warning: str(row.lifecycleWarning),
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* The plain sentence for a template that is not `current`, with the command
|
|
258
|
+
* that acts on it. Null for `current` (nothing to say).
|
|
259
|
+
*/
|
|
260
|
+
export function lifecycleNotice(slug, info) {
|
|
261
|
+
switch (info.lifecycle) {
|
|
262
|
+
case "current":
|
|
263
|
+
return null;
|
|
264
|
+
case "retired":
|
|
265
|
+
return {
|
|
266
|
+
label: info.warning ??
|
|
267
|
+
(info.replacedBy
|
|
268
|
+
? `Retired: ${slug} is replaced by ${info.replacedBy}`
|
|
269
|
+
: `Retired: ${slug} has no replacement`),
|
|
270
|
+
// Retire-into needs a target; with none there is nothing to move into.
|
|
271
|
+
action: info.replacedBy ? `synap templates retire ${slug}` : null,
|
|
272
|
+
};
|
|
273
|
+
case "unlisted":
|
|
274
|
+
return { label: info.warning ?? `No longer in the catalog: ${slug}`, action: null };
|
|
275
|
+
case "unknown":
|
|
276
|
+
return {
|
|
277
|
+
label: `Catalog not fully synced: the pod can't say yet whether ${slug} is still offered`,
|
|
278
|
+
action: null,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Read `overlays` off a Hub `/workspaces` row. `undefined` = the pod sent no
|
|
284
|
+
* such field (an older pod): show exactly what was shown before. `[]` = the
|
|
285
|
+
* space has no overlays. An entry with no lifecycle reads as `unknown`.
|
|
286
|
+
*/
|
|
287
|
+
export function parseOverlays(row) {
|
|
288
|
+
const raw = row.overlays;
|
|
289
|
+
if (!Array.isArray(raw))
|
|
290
|
+
return undefined;
|
|
291
|
+
const out = [];
|
|
292
|
+
for (const item of raw) {
|
|
293
|
+
const o = asObj(item);
|
|
294
|
+
const slug = o ? asStr(o.slug) : null;
|
|
295
|
+
if (!o || !slug)
|
|
296
|
+
continue;
|
|
297
|
+
out.push({
|
|
298
|
+
slug,
|
|
299
|
+
info: parseLifecycle(o) ?? { lifecycle: "unknown", replacedBy: null, retiredReason: null, warning: null },
|
|
300
|
+
replacementHere: o.replacementHere === true,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
return out;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* The notice for an overlay: the SAME label `lifecycleNotice` gives a space
|
|
307
|
+
* (the pod's own sentence first), but never an action — an overlay is not a
|
|
308
|
+
* space, so `synap templates retire` has nothing to move for it.
|
|
309
|
+
*/
|
|
310
|
+
export function overlayNotice(o) {
|
|
311
|
+
const n = lifecycleNotice(o.slug, o.info);
|
|
312
|
+
return n ? { label: n.label, action: null } : null;
|
|
313
|
+
}
|
|
314
|
+
/** An overlay that needs the person: retired, and its replacement is not on the space. */
|
|
315
|
+
export function overlayNeedsAttention(o) {
|
|
316
|
+
return o.info.lifecycle === "retired" && !o.replacementHere;
|
|
317
|
+
}
|
|
318
|
+
const pick = (o, ...keys) => {
|
|
319
|
+
if (!o)
|
|
320
|
+
return undefined;
|
|
321
|
+
for (const k of keys)
|
|
322
|
+
if (o[k] !== undefined)
|
|
323
|
+
return o[k];
|
|
324
|
+
return undefined;
|
|
325
|
+
};
|
|
326
|
+
const asObj = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : undefined;
|
|
327
|
+
const asStr = (v) => (typeof v === "string" && v.trim() ? v.trim() : null);
|
|
328
|
+
const asNum = (v) => (typeof v === "number" && Number.isFinite(v) ? v : null);
|
|
329
|
+
function parseGroups(raw, map) {
|
|
330
|
+
if (!Array.isArray(raw))
|
|
331
|
+
return [];
|
|
332
|
+
return raw.map((r) => (asObj(r) ? map(asObj(r)) : null)).filter((x) => x !== null);
|
|
333
|
+
}
|
|
334
|
+
function kindOf(r) {
|
|
335
|
+
return asStr(pick(r, "kind", "profileSlug", "profile", "slug"));
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Parse the retire-into response defensively. Returns null when the body has
|
|
339
|
+
* no recognisable plan AND no proposal — a caller must then say "the pod's
|
|
340
|
+
* answer couldn't be read", never "nothing to move".
|
|
341
|
+
*/
|
|
342
|
+
export function parseRetireResponse(raw) {
|
|
343
|
+
const body = asObj(raw);
|
|
344
|
+
if (!body)
|
|
345
|
+
return null;
|
|
346
|
+
const planObj = asObj(body.plan) ?? (body.moves !== undefined ? body : undefined);
|
|
347
|
+
let plan = null;
|
|
348
|
+
if (planObj) {
|
|
349
|
+
const source = asObj(planObj.source);
|
|
350
|
+
const target = asObj(planObj.target);
|
|
351
|
+
plan = {
|
|
352
|
+
sourceName: asStr(pick(source, "name", "workspaceName")),
|
|
353
|
+
sourceSlug: asStr(pick(source, "slug", "packageSlug")),
|
|
354
|
+
targetSlug: asStr(pick(target, "slug", "replacedBy")) ?? asStr(planObj.replacedBy),
|
|
355
|
+
targetWorkspaceId: asStr(pick(target, "workspaceId", "id")),
|
|
356
|
+
targetName: asStr(pick(target, "name", "workspaceName")),
|
|
357
|
+
willInstall: pick(target, "willInstall", "install") === true,
|
|
358
|
+
moves: parseGroups(planObj.moves, (r) => {
|
|
359
|
+
const kind = kindOf(r);
|
|
360
|
+
return kind ? { kind, count: asNum(pick(r, "count", "affected")) } : null;
|
|
361
|
+
}),
|
|
362
|
+
stays: parseGroups(planObj.stays, (r) => {
|
|
363
|
+
const kind = kindOf(r);
|
|
364
|
+
return kind
|
|
365
|
+
? { kind, count: asNum(pick(r, "count", "affected")), reason: asStr(r.reason) ?? "no reason given" }
|
|
366
|
+
: null;
|
|
367
|
+
}),
|
|
368
|
+
willArchive: typeof pick(planObj, "willArchive", "archiveSource") === "boolean"
|
|
369
|
+
? pick(planObj, "willArchive", "archiveSource")
|
|
370
|
+
: null,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
const status = asStr(body.status);
|
|
374
|
+
if (status === "proposed" || body.proposalId !== undefined) {
|
|
375
|
+
return {
|
|
376
|
+
kind: "proposed",
|
|
377
|
+
plan,
|
|
378
|
+
proposalId: asStr(body.proposalId),
|
|
379
|
+
reviewUrl: asStr(body.reviewUrl),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
if (!plan)
|
|
383
|
+
return null;
|
|
384
|
+
if (status === "applied" || status === "done" || status === "completed") {
|
|
385
|
+
const archived = typeof body.archived === "boolean" ? body.archived : null;
|
|
386
|
+
const remaining = parseGroups(body.remaining, (r) => {
|
|
387
|
+
const kind = kindOf(r);
|
|
388
|
+
return kind
|
|
389
|
+
? { kind, count: asNum(pick(r, "count", "affected")), reason: asStr(r.reason) ?? "no reason given" }
|
|
390
|
+
: null;
|
|
391
|
+
});
|
|
392
|
+
return { kind: "applied", plan, archived, remaining: remaining.length ? remaining : plan.stays };
|
|
393
|
+
}
|
|
394
|
+
return { kind: "plan", plan };
|
|
395
|
+
}
|
|
396
|
+
function countOf(n) {
|
|
397
|
+
return n === null ? "some" : String(n);
|
|
398
|
+
}
|
|
399
|
+
/** The plan in plain lines (no trailing hints). */
|
|
400
|
+
export function formatRetirePlan(plan) {
|
|
401
|
+
const lines = [];
|
|
402
|
+
const target = plan.targetSlug ?? "(no replacement named)";
|
|
403
|
+
if (plan.targetWorkspaceId) {
|
|
404
|
+
lines.push(`Target: ${target}, already installed${plan.targetName ? ` as "${plan.targetName}"` : ""} (${plan.targetWorkspaceId})`);
|
|
405
|
+
}
|
|
406
|
+
else if (plan.willInstall) {
|
|
407
|
+
lines.push(`Target: ${target}, not installed yet. It will be installed first.`);
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
lines.push(`Target: ${target}`);
|
|
411
|
+
}
|
|
412
|
+
if (plan.moves.length === 0) {
|
|
413
|
+
lines.push("Moves: nothing to move.");
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
lines.push("Moves:");
|
|
417
|
+
for (const m of plan.moves)
|
|
418
|
+
lines.push(` • ${countOf(m.count)} ${m.kind}`);
|
|
419
|
+
}
|
|
420
|
+
if (plan.stays.length > 0) {
|
|
421
|
+
lines.push("Stays in the old space:");
|
|
422
|
+
for (const s of plan.stays)
|
|
423
|
+
lines.push(` • ${countOf(s.count)} ${s.kind}: ${s.reason}`);
|
|
424
|
+
}
|
|
425
|
+
if (plan.willArchive === true)
|
|
426
|
+
lines.push("The old space will be archived once it is empty. Nothing is deleted.");
|
|
427
|
+
else if (plan.willArchive === false)
|
|
428
|
+
lines.push("The old space stays (something remains in it). Nothing is deleted.");
|
|
429
|
+
else
|
|
430
|
+
lines.push("Nothing is deleted.");
|
|
431
|
+
return lines;
|
|
432
|
+
}
|
|
433
|
+
//# sourceMappingURL=template-lifecycle.js.map
|