@synap-core/cli 1.11.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 +218 -168
- 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 +1 -13
- 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 +7 -1
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +34 -0
- package/dist/commands/data-extra.js +193 -23
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +120 -2
- package/dist/commands/data.js +293 -20
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +66 -4
- package/dist/commands/diagnose.js +285 -28
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/doc.d.ts +11 -4
- package/dist/commands/doc.js +39 -14
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +112 -3
- package/dist/commands/doctor.js +657 -32
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain.js +5 -5
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/import.d.ts +368 -13
- package/dist/commands/import.js +1064 -54
- 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 +22 -6
- package/dist/commands/knowledge.js +117 -55
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/lens.d.ts +37 -1
- package/dist/commands/lens.js +192 -71
- package/dist/commands/lens.js.map +1 -1
- package/dist/commands/market-authoring.d.ts +29 -2
- package/dist/commands/market-authoring.js +348 -7
- package/dist/commands/market-authoring.js.map +1 -1
- 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 +400 -16
- package/dist/commands/market.js +1802 -146
- package/dist/commands/market.js.map +1 -1
- package/dist/commands/mcp.d.ts +60 -25
- package/dist/commands/mcp.js +251 -64
- 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 +5 -0
- package/dist/commands/pods.js +97 -116
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.d.ts +62 -0
- package/dist/commands/proposals-actions.js +143 -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 +478 -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 +16 -0
- 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 +41 -3
- package/dist/commands/upload.js +120 -18
- package/dist/commands/upload.js.map +1 -1
- 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 +900 -180
- 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 +6 -5
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +230 -11
- package/dist/lib/capture-structure.js +251 -13
- package/dist/lib/capture-structure.js.map +1 -1
- 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 +167 -11
- package/dist/lib/cp-packages.js +253 -21
- 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 +29 -8
- package/dist/lib/hub-client.js +328 -55
- package/dist/lib/hub-client.js.map +1 -1
- 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 +66 -112
- package/dist/lib/pod.js +134 -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 +4 -0
- package/dist/lib/template-file.js.map +1 -1
- 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 +23 -17
- package/skills/README.md +12 -10
- package/skills/agent-os/SKILL.md +214 -99
- package/skills/manifest.json +1 -1
- package/skills/onboard/SKILL.md +55 -26
- package/skills/synap/README.md +5 -8
- package/skills/synap/SKILL.md +1086 -283
- 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 +5 -0
- package/skills/synap/cli-operations.md +24 -18
- package/skills/synap/concepts.md +28 -0
- package/skills/synap/content-os.md +10 -1
- package/skills/synap/creative-loop.md +15 -10
- package/skills/synap/crm.md +21 -52
- 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 +17 -15
- 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 +4 -5
- package/skills/synap/workspace-design.md +14 -10
- package/skills/synap/writes.md +97 -24
- package/skills/synap/writing-titles.md +63 -0
- package/skills/synap-app/SKILL.md +2 -2
- package/skills/synap-app/_skill.yaml +1 -1
- package/skills/synap-app/install-commands.md +1 -1
- 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 +306 -16
- package/skills/synap-market/_skill.yaml +1 -1
- package/skills/synap-market/author-and-publish.md +145 -8
- package/skills/synap-market/governance-and-catalog.md +7 -0
- package/skills/synap-market/install.md +79 -1
- package/skills/synap-market/overview.md +74 -6
- 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/commands/template.d.ts +0 -42
- package/dist/commands/template.js +0 -191
- package/dist/commands/template.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
- package/node_modules/@synap/hub-rest-client/dist/index.cjs +0 -1261
- package/node_modules/@synap/hub-rest-client/dist/index.d.cts +0 -1647
- package/node_modules/@synap/hub-rest-client/dist/index.d.ts +0 -1647
- package/node_modules/@synap/hub-rest-client/dist/index.js +0 -1231
- package/node_modules/@synap/hub-rest-client/package.json +0 -45
- package/node_modules/@synap/hub-rest-client/src/client.ts +0 -1631
- package/node_modules/@synap/hub-rest-client/src/errors.ts +0 -30
- package/node_modules/@synap/hub-rest-client/src/index.ts +0 -153
- package/node_modules/@synap/hub-rest-client/src/setup.ts +0 -133
- package/node_modules/@synap/hub-rest-client/src/types.ts +0 -1299
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import chalk from "chalk";
|
|
16
16
|
import ora from "ora";
|
|
17
17
|
import prompts from "prompts";
|
|
18
|
-
import {
|
|
18
|
+
import { openExternalUrl } from "../lib/safe-open.js";
|
|
19
19
|
import { readFileSync } from "node:fs";
|
|
20
20
|
import { resolveHubConfig, hubGet, hubPost, hubDelete, HubError, renderHubError } from "../lib/hub-client.js";
|
|
21
21
|
import { unwrapList } from "../lib/unwrapList.js";
|
|
@@ -231,7 +231,12 @@ function accountLabel(account) {
|
|
|
231
231
|
const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(account);
|
|
232
232
|
return isUuid ? null : account;
|
|
233
233
|
}
|
|
234
|
-
/**
|
|
234
|
+
/**
|
|
235
|
+
* A USABLE pack: name + its verbs grouped by exec-mode as compact NAME lists.
|
|
236
|
+
* The full `--param` signature is NOT dumped per verb here — that turned a pack
|
|
237
|
+
* with 20+ verbs into an unscannable wall. The list answers "what can this do?";
|
|
238
|
+
* `synap cap show <verb>` gives the exact run command for the one you pick.
|
|
239
|
+
*/
|
|
235
240
|
function renderUsable(card) {
|
|
236
241
|
const label = accountLabel(card.connection?.account);
|
|
237
242
|
const acct = label
|
|
@@ -239,13 +244,19 @@ function renderUsable(card) {
|
|
|
239
244
|
: card.connection?.provider
|
|
240
245
|
? chalk.dim(` · ${card.connection.provider} connected`)
|
|
241
246
|
: "";
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
const runnable = card.verbs.filter((x) => x.runnable);
|
|
248
|
+
const instant = runnable.filter((v) => v.type === "read");
|
|
249
|
+
const approval = runnable.filter((v) => v.type !== "read");
|
|
250
|
+
const count = chalk.dim(` · ${runnable.length} verb${runnable.length === 1 ? "" : "s"}` +
|
|
251
|
+
(approval.length ? `, ${approval.length} need approval` : ""));
|
|
252
|
+
console.log(` ${chalk.green("●")} ${chalk.bold(card.name)}${acct}${count}`);
|
|
253
|
+
if (instant.length > 0) {
|
|
254
|
+
console.log(` ${chalk.green("▸")} ${chalk.dim("instant ")} ` +
|
|
255
|
+
instant.map((v) => chalk.cyan(v.verbId)).join(" "));
|
|
256
|
+
}
|
|
257
|
+
if (approval.length > 0) {
|
|
258
|
+
console.log(` ${chalk.yellow("✋")} ${chalk.dim("approval")} ` +
|
|
259
|
+
approval.map((v) => chalk.cyan(v.verbId)).join(" "));
|
|
249
260
|
}
|
|
250
261
|
const off = card.verbs.filter((v) => !v.runnable);
|
|
251
262
|
if (off.length > 0) {
|
|
@@ -257,6 +268,12 @@ function renderUsable(card) {
|
|
|
257
268
|
function renderSetup(card) {
|
|
258
269
|
console.log(` ${chalk.yellow("◌")} ${chalk.bold(card.name)} ${chalk.dim(statusSummary(card))}`);
|
|
259
270
|
console.log(` ${chalk.cyan("→")} ${card.nextAction.hint || `synap cap enable "${card.name}"`}`);
|
|
271
|
+
// An expired connection reads as "needs a step", but the fix is a RECONNECT, not
|
|
272
|
+
// an enable — show the exact command so the hint's "Reconnect …" prose is
|
|
273
|
+
// actionable (the state word tells WHAT, this tells HOW).
|
|
274
|
+
if (card.connection?.state === "expired") {
|
|
275
|
+
console.log(` ${chalk.dim(`synap cap connect "${card.name}" --reconnect`)}`);
|
|
276
|
+
}
|
|
260
277
|
}
|
|
261
278
|
/** An AVAILABLE pack: one line — name · what it offers · add command. */
|
|
262
279
|
function renderAvailable(card) {
|
|
@@ -280,7 +297,7 @@ export async function capabilityList(opts) {
|
|
|
280
297
|
cfg = await resolveHubConfig();
|
|
281
298
|
}
|
|
282
299
|
catch (err) {
|
|
283
|
-
|
|
300
|
+
renderHubError(err);
|
|
284
301
|
process.exit(1);
|
|
285
302
|
}
|
|
286
303
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -297,7 +314,7 @@ export async function capabilityList(opts) {
|
|
|
297
314
|
return;
|
|
298
315
|
}
|
|
299
316
|
spinner?.fail(chalk.red("Failed to fetch capabilities"));
|
|
300
|
-
|
|
317
|
+
renderHubError(err);
|
|
301
318
|
process.exit(1);
|
|
302
319
|
}
|
|
303
320
|
if (opts.json) {
|
|
@@ -349,18 +366,8 @@ export async function capabilityList(opts) {
|
|
|
349
366
|
// ── Connection sub-flow (shared by enable + connect) ────────────────────────
|
|
350
367
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
351
368
|
function openBrowser(url) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
? `open "${url}"`
|
|
355
|
-
: platform === "win32"
|
|
356
|
-
? `start "" "${url}"`
|
|
357
|
-
: `xdg-open "${url}"`;
|
|
358
|
-
try {
|
|
359
|
-
exec(cmd);
|
|
360
|
-
}
|
|
361
|
-
catch {
|
|
362
|
-
// silently ignore — caller already prints the URL
|
|
363
|
-
}
|
|
369
|
+
// argv only, http(s) only — never a shell string (`safe-open.ts`).
|
|
370
|
+
openExternalUrl(url);
|
|
364
371
|
}
|
|
365
372
|
/** Short host label for a pod (for picker headers: "→ pod.perso…"). */
|
|
366
373
|
function podHostLabel(cfg) {
|
|
@@ -394,14 +401,117 @@ async function pollUntilConnected(cfg, provider, workspaceId, timeoutMs = 180_00
|
|
|
394
401
|
}
|
|
395
402
|
return null;
|
|
396
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* The ONE "connect a provider" path: resolve `/connectors/connect`, open the
|
|
406
|
+
* browser on the returned `redirectUrl`, and poll (self-completing door) until
|
|
407
|
+
* the provider flips to `connected`. Shared by the capability-card flow
|
|
408
|
+
* (`ensureConnection`) and the raw-provider discovery picker
|
|
409
|
+
* (`capabilityConnect` with no name), so both reach the identical endpoint,
|
|
410
|
+
* status handling, browser-open and poll semantics.
|
|
411
|
+
*
|
|
412
|
+
* `cardName` is the discriminator: when present the caller is connecting on
|
|
413
|
+
* behalf of a capability card, which enables the card-aware `provider_required`
|
|
414
|
+
* / `provider_unavailable` branches and the named re-run + timeout hints. The
|
|
415
|
+
* raw-picker path already holds an explicit provider id, so those branches do
|
|
416
|
+
* not apply to it — it goes straight from `connected` to the `redirectUrl`
|
|
417
|
+
* check, exactly as before.
|
|
418
|
+
*
|
|
419
|
+
* `displayName` is the local fallback name: the provider's list label for the
|
|
420
|
+
* raw picker, the provider id for the card flow (a card has no separate label).
|
|
421
|
+
*/
|
|
422
|
+
async function connectProviderOAuth(cfg, provider, workspaceId, ctx) {
|
|
423
|
+
const isCard = ctx.cardName !== undefined;
|
|
424
|
+
// Card flow prefers the server's displayName (falling back to the provider
|
|
425
|
+
// id); the raw picker uses its own list label verbatim.
|
|
426
|
+
const name = (r) => isCard ? String(r.displayName ?? ctx.displayName) : ctx.displayName;
|
|
427
|
+
const spinner = ora({
|
|
428
|
+
text: isCard ? `Resolving ${chalk.bold(provider)} connection…` : `Connecting ${chalk.bold(ctx.displayName)}…`,
|
|
429
|
+
color: "cyan",
|
|
430
|
+
}).start();
|
|
431
|
+
let res;
|
|
432
|
+
try {
|
|
433
|
+
const body = { provider };
|
|
434
|
+
if (workspaceId)
|
|
435
|
+
body.workspaceId = workspaceId;
|
|
436
|
+
if (ctx.forceReauth)
|
|
437
|
+
body.forceReauth = true;
|
|
438
|
+
res = (await hubPost("/connectors/connect", body, cfg));
|
|
439
|
+
spinner.stop();
|
|
440
|
+
}
|
|
441
|
+
catch (err) {
|
|
442
|
+
if (isCard)
|
|
443
|
+
spinner.fail(chalk.red("Failed to resolve connection"));
|
|
444
|
+
else
|
|
445
|
+
spinner.stop();
|
|
446
|
+
renderHubError(err);
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
const status = String(res.status);
|
|
450
|
+
if (status === "connected") {
|
|
451
|
+
// Both flows prefer the server's displayName here (falling back locally).
|
|
452
|
+
log.success(`${res.displayName ?? ctx.displayName} is already connected.`);
|
|
453
|
+
return true;
|
|
454
|
+
}
|
|
455
|
+
if (isCard && status === "provider_required") {
|
|
456
|
+
log.warn(`Couldn't resolve a single provider for ${ctx.cardName}.`);
|
|
457
|
+
log.dim(`Connect it directly: synap cap connect "${ctx.cardName}"`);
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
if (isCard && status === "provider_unavailable") {
|
|
461
|
+
// The pod can't offer this provider (not declared / unreachable / malformed).
|
|
462
|
+
// The server message already names the real cause + remedy — print it as-is.
|
|
463
|
+
// No browser, and no "re-run connect": re-running cannot fix a server-side gap.
|
|
464
|
+
log.warn(`${ctx.cardName} is unavailable on this pod.`);
|
|
465
|
+
if (res.message)
|
|
466
|
+
log.dim(String(res.message));
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
// setup_required (or any status this CLI doesn't know) → only ever open a
|
|
470
|
+
// browser when the server actually handed us a URL. An older/newer pod that
|
|
471
|
+
// returns a status we don't handle must NOT send the user to "undefined".
|
|
472
|
+
const redirectUrl = typeof res.redirectUrl === "string" && res.redirectUrl.length > 0 ? res.redirectUrl : null;
|
|
473
|
+
if (!redirectUrl) {
|
|
474
|
+
log.warn(`Couldn't start a connection for ${name(res)}.`);
|
|
475
|
+
if (res.message)
|
|
476
|
+
log.dim(String(res.message));
|
|
477
|
+
else if (isCard)
|
|
478
|
+
log.dim(`The pod returned status "${status}" with no connect URL. Check the pod's connector configuration.`);
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
log.heading(`Connect ${name(res)}`);
|
|
482
|
+
console.log();
|
|
483
|
+
console.log(` Opening OAuth flow in your browser…`);
|
|
484
|
+
console.log(` ${chalk.dim("If it didn't open, paste this URL:")}`);
|
|
485
|
+
console.log(` ${chalk.underline(chalk.cyan(redirectUrl))}`);
|
|
486
|
+
console.log();
|
|
487
|
+
openBrowser(redirectUrl);
|
|
488
|
+
const waitSpinner = ora({ text: "Waiting for you to finish in the browser…", color: "cyan" }).start();
|
|
489
|
+
const connected = await pollUntilConnected(cfg, provider, workspaceId);
|
|
490
|
+
if (connected) {
|
|
491
|
+
waitSpinner.succeed(chalk.green(`Connected ${chalk.bold(name(connected))}!`));
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
waitSpinner.stop();
|
|
495
|
+
log.dim(isCard
|
|
496
|
+
? `Didn't detect a connection yet — finish the browser flow, then re-run \`synap cap enable "${ctx.cardName}"\`.`
|
|
497
|
+
: `Didn't detect a connection yet — finish the browser flow, then re-run.`);
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
397
500
|
/**
|
|
398
501
|
* Ensure a capability's required connection is satisfied. Provider (nango://) →
|
|
399
502
|
* OAuth open + poll. Vault (vault://) → prompt for the key, POST /vault/secrets.
|
|
400
503
|
* Returns true when the connection is (now) satisfied, false otherwise.
|
|
401
504
|
*/
|
|
402
|
-
async function ensureConnection(cfg, workspaceId, card
|
|
505
|
+
async function ensureConnection(cfg, workspaceId, card,
|
|
506
|
+
// Force a re-auth even when the card reports `state === "connected"`. The card
|
|
507
|
+
// reflects a connection RECORD's existence, not its token's HEALTH, so an
|
|
508
|
+
// expired/revoked token still reads "connected" — only a forced fresh OAuth
|
|
509
|
+
// fixes it. Threaded to the provider door as `forceReauth`.
|
|
510
|
+
forceReconnect = false) {
|
|
403
511
|
const conn = card.connection;
|
|
404
|
-
if (!conn || !conn.required
|
|
512
|
+
if (!conn || !conn.required)
|
|
513
|
+
return true;
|
|
514
|
+
if (conn.state === "connected" && !forceReconnect)
|
|
405
515
|
return true;
|
|
406
516
|
// NOTE: `state === "unavailable"` is deliberately NOT short-circuited here.
|
|
407
517
|
// Resolving the door is not an OAuth attempt — it returns 200 with the pod's
|
|
@@ -442,70 +552,19 @@ async function ensureConnection(cfg, workspaceId, card) {
|
|
|
442
552
|
}
|
|
443
553
|
catch (err) {
|
|
444
554
|
spinner.fail(chalk.red("Failed to store credential"));
|
|
445
|
-
|
|
555
|
+
renderHubError(err);
|
|
446
556
|
return false;
|
|
447
557
|
}
|
|
448
558
|
}
|
|
449
559
|
// ── Provider OAuth (nango://) — open + poll ───────────────────────────────
|
|
450
560
|
const provider = conn.provider ?? card.key;
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
spinner.fail(chalk.red("Failed to resolve connection"));
|
|
459
|
-
log.error(err.message);
|
|
460
|
-
return false;
|
|
461
|
-
}
|
|
462
|
-
const status = String(res.status);
|
|
463
|
-
if (status === "connected") {
|
|
464
|
-
log.success(`${res.displayName ?? provider} is already connected.`);
|
|
465
|
-
return true;
|
|
466
|
-
}
|
|
467
|
-
if (status === "provider_required") {
|
|
468
|
-
log.warn(`Couldn't resolve a single provider for ${card.name}.`);
|
|
469
|
-
log.dim(`Connect it directly: synap cap connect "${card.name}"`);
|
|
470
|
-
return false;
|
|
471
|
-
}
|
|
472
|
-
if (status === "provider_unavailable") {
|
|
473
|
-
// The pod can't offer this provider (not declared / unreachable / malformed).
|
|
474
|
-
// The server message already names the real cause + remedy — print it as-is.
|
|
475
|
-
// No browser, and no "re-run connect": re-running cannot fix a server-side gap.
|
|
476
|
-
log.warn(`${card.name} is unavailable on this pod.`);
|
|
477
|
-
if (res.message)
|
|
478
|
-
log.dim(String(res.message));
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
|
-
// setup_required (or any status this CLI doesn't know) → only ever open a
|
|
482
|
-
// browser when the server actually handed us a URL. An older/newer pod that
|
|
483
|
-
// returns a status we don't handle must NOT send the user to "undefined".
|
|
484
|
-
const redirectUrl = typeof res.redirectUrl === "string" && res.redirectUrl.length > 0 ? res.redirectUrl : null;
|
|
485
|
-
if (!redirectUrl) {
|
|
486
|
-
log.warn(`Couldn't start a connection for ${res.displayName ?? provider}.`);
|
|
487
|
-
if (res.message)
|
|
488
|
-
log.dim(String(res.message));
|
|
489
|
-
else
|
|
490
|
-
log.dim(`The pod returned status "${status}" with no connect URL. Check the pod's connector configuration.`);
|
|
491
|
-
return false;
|
|
492
|
-
}
|
|
493
|
-
log.heading(`Connect ${res.displayName ?? provider}`);
|
|
494
|
-
console.log();
|
|
495
|
-
console.log(` Opening OAuth flow in your browser…`);
|
|
496
|
-
console.log(` ${chalk.dim("If it didn't open, paste this URL:")}`);
|
|
497
|
-
console.log(` ${chalk.underline(chalk.cyan(redirectUrl))}`);
|
|
498
|
-
console.log();
|
|
499
|
-
openBrowser(redirectUrl);
|
|
500
|
-
const waitSpinner = ora({ text: "Waiting for you to finish in the browser…", color: "cyan" }).start();
|
|
501
|
-
const connected = await pollUntilConnected(cfg, provider, workspaceId);
|
|
502
|
-
if (connected) {
|
|
503
|
-
waitSpinner.succeed(chalk.green(`Connected ${chalk.bold(String(connected.displayName ?? provider))}!`));
|
|
504
|
-
return true;
|
|
505
|
-
}
|
|
506
|
-
waitSpinner.stop();
|
|
507
|
-
log.dim(`Didn't detect a connection yet — finish the browser flow, then re-run \`synap cap enable "${card.name}"\`.`);
|
|
508
|
-
return false;
|
|
561
|
+
return connectProviderOAuth(cfg, provider, workspaceId, {
|
|
562
|
+
// A card has no separate display name — the provider id is the fallback the
|
|
563
|
+
// server's displayName (when sent) takes precedence over.
|
|
564
|
+
displayName: provider,
|
|
565
|
+
cardName: card.name,
|
|
566
|
+
forceReauth: forceReconnect,
|
|
567
|
+
});
|
|
509
568
|
}
|
|
510
569
|
/**
|
|
511
570
|
* Prompt for a template's REQUIRED install params (masked for secrets). Returns
|
|
@@ -565,58 +624,9 @@ async function applyTemplateWithParams(cfg, card, workspaceId, params, verb) {
|
|
|
565
624
|
}
|
|
566
625
|
catch (err) {
|
|
567
626
|
spinner.fail(chalk.red(`Failed to ${verb.toLowerCase()} ${card.name}`));
|
|
568
|
-
log.error(err.message);
|
|
569
|
-
return false;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Connect a RAW provider chosen from the discovery picker (not tied to a
|
|
574
|
-
* capability card): start OAuth via `/connectors/connect`, open the browser, and
|
|
575
|
-
* poll until it flips to connected. Same door + poll the card flow uses.
|
|
576
|
-
*/
|
|
577
|
-
async function connectProviderFlow(cfg, provider, displayName, workspaceId) {
|
|
578
|
-
const spinner = ora({ text: `Connecting ${chalk.bold(displayName)}…`, color: "cyan" }).start();
|
|
579
|
-
let res;
|
|
580
|
-
try {
|
|
581
|
-
const body = { provider };
|
|
582
|
-
if (workspaceId)
|
|
583
|
-
body.workspaceId = workspaceId;
|
|
584
|
-
res = (await hubPost("/connectors/connect", body, cfg));
|
|
585
|
-
spinner.stop();
|
|
586
|
-
}
|
|
587
|
-
catch (err) {
|
|
588
|
-
spinner.stop();
|
|
589
627
|
renderHubError(err);
|
|
590
628
|
return false;
|
|
591
629
|
}
|
|
592
|
-
if (String(res.status) === "connected") {
|
|
593
|
-
log.success(`${res.displayName ?? displayName} is already connected.`);
|
|
594
|
-
return true;
|
|
595
|
-
}
|
|
596
|
-
const redirectUrl = typeof res.redirectUrl === "string" && res.redirectUrl.length > 0 ? res.redirectUrl : null;
|
|
597
|
-
if (!redirectUrl) {
|
|
598
|
-
log.warn(`Couldn't start a connection for ${displayName}.`);
|
|
599
|
-
// Covers provider_unavailable too — the server message names the real cause.
|
|
600
|
-
if (res.message)
|
|
601
|
-
log.dim(String(res.message));
|
|
602
|
-
return false;
|
|
603
|
-
}
|
|
604
|
-
log.heading(`Connect ${displayName}`);
|
|
605
|
-
console.log();
|
|
606
|
-
console.log(` Opening OAuth flow in your browser…`);
|
|
607
|
-
console.log(` ${chalk.dim("If it didn't open, paste this URL:")}`);
|
|
608
|
-
console.log(` ${chalk.underline(chalk.cyan(redirectUrl))}`);
|
|
609
|
-
console.log();
|
|
610
|
-
openBrowser(redirectUrl);
|
|
611
|
-
const waitSpinner = ora({ text: "Waiting for you to finish in the browser…", color: "cyan" }).start();
|
|
612
|
-
const connected = await pollUntilConnected(cfg, provider, workspaceId);
|
|
613
|
-
if (connected) {
|
|
614
|
-
waitSpinner.succeed(chalk.green(`Connected ${chalk.bold(displayName)}!`));
|
|
615
|
-
return true;
|
|
616
|
-
}
|
|
617
|
-
waitSpinner.stop();
|
|
618
|
-
log.dim(`Didn't detect a connection yet — finish the browser flow, then re-run.`);
|
|
619
|
-
return false;
|
|
620
630
|
}
|
|
621
631
|
export async function capabilityAdd(name, opts) {
|
|
622
632
|
let cfg;
|
|
@@ -624,7 +634,7 @@ export async function capabilityAdd(name, opts) {
|
|
|
624
634
|
cfg = await resolveHubConfig();
|
|
625
635
|
}
|
|
626
636
|
catch (err) {
|
|
627
|
-
|
|
637
|
+
renderHubError(err);
|
|
628
638
|
process.exit(1);
|
|
629
639
|
}
|
|
630
640
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -644,7 +654,7 @@ export async function capabilityAdd(name, opts) {
|
|
|
644
654
|
return;
|
|
645
655
|
}
|
|
646
656
|
spinner.fail(chalk.red("Failed to fetch catalog"));
|
|
647
|
-
|
|
657
|
+
renderHubError(err);
|
|
648
658
|
process.exit(1);
|
|
649
659
|
}
|
|
650
660
|
// No name given → open an interactive picker over the AVAILABLE (not-yet-
|
|
@@ -750,7 +760,7 @@ export async function capabilityAdd(name, opts) {
|
|
|
750
760
|
}
|
|
751
761
|
catch (err) {
|
|
752
762
|
addSpinner.fail(chalk.red(`Failed to add ${card.name}`));
|
|
753
|
-
|
|
763
|
+
renderHubError(err);
|
|
754
764
|
process.exit(1);
|
|
755
765
|
}
|
|
756
766
|
}
|
|
@@ -762,6 +772,21 @@ export async function capabilityAdd(name, opts) {
|
|
|
762
772
|
catch {
|
|
763
773
|
// best-effort — the add already succeeded
|
|
764
774
|
}
|
|
775
|
+
// CONNECT-first: a provider capability that isn't connected yet runs the OAuth
|
|
776
|
+
// flow now, so `cap add` is the ONE happy-path door (apply → connect → enable
|
|
777
|
+
// reads). `ensureConnection` is the shared provider+OAuth path; a failed or
|
|
778
|
+
// timed-out OAuth returns false and leaves the card un-connected — recover
|
|
779
|
+
// with `synap cap connect "<name>"`. No-connection / already-connected cards
|
|
780
|
+
// skip this.
|
|
781
|
+
if (after?.connection?.required && after.connection.state !== "connected") {
|
|
782
|
+
await ensureConnection(cfg, workspaceId, after);
|
|
783
|
+
try {
|
|
784
|
+
after = findCard(await fetchCatalog(cfg, workspaceId), card.name) ?? after;
|
|
785
|
+
}
|
|
786
|
+
catch {
|
|
787
|
+
// keep the pre-connect card
|
|
788
|
+
}
|
|
789
|
+
}
|
|
765
790
|
// AUTO-ENABLE the read verbs, so install is ONE step, not two. Reads are the
|
|
766
791
|
// `auto`-governance, no-side-effect verbs — safe to turn on without asking.
|
|
767
792
|
// Write/action verbs stay OFF (they ask approval per run); enable them later
|
|
@@ -821,7 +846,7 @@ export async function capabilityEnable(name, opts) {
|
|
|
821
846
|
cfg = await resolveHubConfig();
|
|
822
847
|
}
|
|
823
848
|
catch (err) {
|
|
824
|
-
|
|
849
|
+
renderHubError(err);
|
|
825
850
|
process.exit(1);
|
|
826
851
|
}
|
|
827
852
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -841,7 +866,7 @@ export async function capabilityEnable(name, opts) {
|
|
|
841
866
|
catalogNeedsDeploy();
|
|
842
867
|
return;
|
|
843
868
|
}
|
|
844
|
-
|
|
869
|
+
renderHubError(err);
|
|
845
870
|
process.exit(1);
|
|
846
871
|
}
|
|
847
872
|
if (cards.length === 0) {
|
|
@@ -901,7 +926,7 @@ export async function capabilityEnable(name, opts) {
|
|
|
901
926
|
return;
|
|
902
927
|
}
|
|
903
928
|
spinner.fail(chalk.red("Failed to fetch catalog"));
|
|
904
|
-
|
|
929
|
+
renderHubError(err);
|
|
905
930
|
process.exit(1);
|
|
906
931
|
}
|
|
907
932
|
if (!card) {
|
|
@@ -1000,7 +1025,7 @@ export async function capabilityEnable(name, opts) {
|
|
|
1000
1025
|
}
|
|
1001
1026
|
catch (err) {
|
|
1002
1027
|
work.fail(chalk.red("Failed while applying your selection"));
|
|
1003
|
-
|
|
1028
|
+
renderHubError(err);
|
|
1004
1029
|
process.exit(1);
|
|
1005
1030
|
}
|
|
1006
1031
|
// (d) Report what changed + an example run.
|
|
@@ -1021,7 +1046,7 @@ export async function capabilityConnect(name, opts) {
|
|
|
1021
1046
|
cfg = await resolveHubConfig();
|
|
1022
1047
|
}
|
|
1023
1048
|
catch (err) {
|
|
1024
|
-
|
|
1049
|
+
renderHubError(err);
|
|
1025
1050
|
process.exit(1);
|
|
1026
1051
|
}
|
|
1027
1052
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -1042,7 +1067,7 @@ export async function capabilityConnect(name, opts) {
|
|
|
1042
1067
|
}
|
|
1043
1068
|
catch (err) {
|
|
1044
1069
|
spin.stop();
|
|
1045
|
-
|
|
1070
|
+
renderHubError(err);
|
|
1046
1071
|
log.dim("Couldn't reach the pod's connector service.");
|
|
1047
1072
|
return;
|
|
1048
1073
|
}
|
|
@@ -1062,18 +1087,22 @@ export async function capabilityConnect(name, opts) {
|
|
|
1062
1087
|
}
|
|
1063
1088
|
const connectable = providers.filter((p) => !p.connected);
|
|
1064
1089
|
const connected = providers.filter((p) => p.connected);
|
|
1065
|
-
|
|
1090
|
+
// --reconnect: the point is to re-auth an ALREADY-connected (but expired)
|
|
1091
|
+
// service, so connected rows become selectable (a fresh OAuth) rather than
|
|
1092
|
+
// disabled, and "everything already connected" is no longer a dead end.
|
|
1093
|
+
if (connectable.length === 0 && !opts.reconnect) {
|
|
1066
1094
|
log.heading("Everything connectable here is already connected.");
|
|
1067
1095
|
for (const p of connected)
|
|
1068
1096
|
log.dim(` ${chalk.green("✓")} ${p.displayName ?? p.provider}`);
|
|
1097
|
+
log.dim("Reconnect an expired one: synap cap connect --reconnect");
|
|
1069
1098
|
return;
|
|
1070
1099
|
}
|
|
1071
1100
|
const answer = await prompts({
|
|
1072
1101
|
type: "select",
|
|
1073
1102
|
name: "id",
|
|
1074
|
-
message:
|
|
1075
|
-
// Connectable first; already-connected
|
|
1076
|
-
//
|
|
1103
|
+
message: `${opts.reconnect ? "Reconnect" : "Connect"} a service ${chalk.dim(`→ ${podHostLabel(cfg)}`)}`,
|
|
1104
|
+
// Connectable first; already-connected grouped at the end — disabled in the
|
|
1105
|
+
// normal flow, but SELECTABLE (for a forced re-auth) under --reconnect.
|
|
1077
1106
|
choices: [
|
|
1078
1107
|
...connectable.map((p) => ({
|
|
1079
1108
|
title: p.displayName ?? p.provider,
|
|
@@ -1081,9 +1110,9 @@ export async function capabilityConnect(name, opts) {
|
|
|
1081
1110
|
})),
|
|
1082
1111
|
...connected.map((p) => ({
|
|
1083
1112
|
title: `${p.displayName ?? p.provider} ${chalk.green("✓ connected")}`,
|
|
1084
|
-
description: "already connected",
|
|
1113
|
+
description: opts.reconnect ? "re-authenticate" : "already connected",
|
|
1085
1114
|
value: p.id,
|
|
1086
|
-
disabled:
|
|
1115
|
+
disabled: !opts.reconnect,
|
|
1087
1116
|
})),
|
|
1088
1117
|
],
|
|
1089
1118
|
});
|
|
@@ -1092,7 +1121,10 @@ export async function capabilityConnect(name, opts) {
|
|
|
1092
1121
|
return;
|
|
1093
1122
|
}
|
|
1094
1123
|
const chosen = providers.find((p) => p.id === answer.id);
|
|
1095
|
-
const ok = await
|
|
1124
|
+
const ok = await connectProviderOAuth(cfg, chosen.id, workspaceId, {
|
|
1125
|
+
displayName: chosen.displayName ?? chosen.provider,
|
|
1126
|
+
forceReauth: opts.reconnect ?? false,
|
|
1127
|
+
});
|
|
1096
1128
|
// A connect that did not connect must not report success to a caller/script.
|
|
1097
1129
|
if (!ok)
|
|
1098
1130
|
process.exit(1);
|
|
@@ -1111,7 +1143,7 @@ export async function capabilityConnect(name, opts) {
|
|
|
1111
1143
|
return;
|
|
1112
1144
|
}
|
|
1113
1145
|
spinner.fail(chalk.red("Failed to fetch catalog"));
|
|
1114
|
-
|
|
1146
|
+
renderHubError(err);
|
|
1115
1147
|
process.exit(1);
|
|
1116
1148
|
}
|
|
1117
1149
|
if (!card) {
|
|
@@ -1124,7 +1156,11 @@ export async function capabilityConnect(name, opts) {
|
|
|
1124
1156
|
log.dim(`Enable its verbs: synap cap enable "${card.name}"`);
|
|
1125
1157
|
return;
|
|
1126
1158
|
}
|
|
1127
|
-
|
|
1159
|
+
if (opts.reconnect) {
|
|
1160
|
+
log.heading(`Reconnecting ${card.name}`);
|
|
1161
|
+
log.dim("Forcing a fresh sign-in — your previous access had expired or was revoked.");
|
|
1162
|
+
}
|
|
1163
|
+
const ok = await ensureConnection(cfg, workspaceId, card, opts.reconnect ?? false);
|
|
1128
1164
|
if (!ok)
|
|
1129
1165
|
process.exit(1);
|
|
1130
1166
|
log.dim(`Now enable its verbs: synap cap enable "${card.name}"`);
|
|
@@ -1147,7 +1183,7 @@ export async function capabilityDisconnect(name, opts) {
|
|
|
1147
1183
|
cfg = await resolveHubConfig();
|
|
1148
1184
|
}
|
|
1149
1185
|
catch (err) {
|
|
1150
|
-
|
|
1186
|
+
renderHubError(err);
|
|
1151
1187
|
process.exit(1);
|
|
1152
1188
|
}
|
|
1153
1189
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -1231,7 +1267,7 @@ export async function capabilityShow(name, opts) {
|
|
|
1231
1267
|
cfg = await resolveHubConfig();
|
|
1232
1268
|
}
|
|
1233
1269
|
catch (err) {
|
|
1234
|
-
|
|
1270
|
+
renderHubError(err);
|
|
1235
1271
|
process.exit(1);
|
|
1236
1272
|
}
|
|
1237
1273
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -1248,7 +1284,7 @@ export async function capabilityShow(name, opts) {
|
|
|
1248
1284
|
return;
|
|
1249
1285
|
}
|
|
1250
1286
|
spinner?.fail(chalk.red("Failed to fetch catalog"));
|
|
1251
|
-
|
|
1287
|
+
renderHubError(err);
|
|
1252
1288
|
process.exit(1);
|
|
1253
1289
|
}
|
|
1254
1290
|
if (!card) {
|
|
@@ -1269,20 +1305,34 @@ export async function capabilityShow(name, opts) {
|
|
|
1269
1305
|
const c = card.connection;
|
|
1270
1306
|
// `unavailable` is dim, not red: it isn't the user's fault and isn't fixable
|
|
1271
1307
|
// by connecting — red reads as "you have a missing credential to go fix".
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1308
|
+
// Unverified: the pod could not actually check (a broker/list fault), not a
|
|
1309
|
+
// checked absence. Render distinctly from a plain "missing" — that would
|
|
1310
|
+
// falsely claim "you never connected this".
|
|
1311
|
+
const stateColor = c.unverified
|
|
1312
|
+
? chalk.yellow
|
|
1313
|
+
: c.state === "connected"
|
|
1314
|
+
? chalk.green
|
|
1315
|
+
: c.state === "expired"
|
|
1316
|
+
? chalk.yellow
|
|
1317
|
+
: c.state === "unavailable"
|
|
1318
|
+
? chalk.dim
|
|
1319
|
+
: chalk.red;
|
|
1320
|
+
const stateLabel = c.unverified ? "couldn't check" : c.state;
|
|
1279
1321
|
const parts = [
|
|
1280
1322
|
c.kind ?? "connection",
|
|
1281
1323
|
c.provider ? chalk.dim(`(${c.provider})`) : "",
|
|
1282
1324
|
c.account ? chalk.dim(c.account) : "",
|
|
1283
|
-
stateColor(
|
|
1325
|
+
stateColor(stateLabel),
|
|
1284
1326
|
].filter(Boolean);
|
|
1285
1327
|
console.log(` ${chalk.bold("Connection")} ${parts.join(" ")}`);
|
|
1328
|
+
// Expired = previously connected, token now dead. Surface the exact command to
|
|
1329
|
+
// fix it — the state word alone tells WHAT, not HOW (the user's original ask).
|
|
1330
|
+
if (c.state === "expired") {
|
|
1331
|
+
console.log(` ${chalk.yellow("→")} its access expired — reconnect: synap cap connect "${card.name}" --reconnect`);
|
|
1332
|
+
}
|
|
1333
|
+
else if (c.unverified) {
|
|
1334
|
+
console.log(` ${chalk.yellow("→")} ${c.unverified.message || c.unverified.reason} — retry: synap cap show "${card.name}"`);
|
|
1335
|
+
}
|
|
1286
1336
|
}
|
|
1287
1337
|
else {
|
|
1288
1338
|
console.log(` ${chalk.bold("Connection")} ${chalk.dim("none required")}`);
|
|
@@ -1317,7 +1367,7 @@ export async function capabilityRun(verb, params, opts) {
|
|
|
1317
1367
|
cfg = await resolveHubConfig();
|
|
1318
1368
|
}
|
|
1319
1369
|
catch (err) {
|
|
1320
|
-
|
|
1370
|
+
renderHubError(err);
|
|
1321
1371
|
process.exit(1);
|
|
1322
1372
|
}
|
|
1323
1373
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -1395,7 +1445,7 @@ export async function capabilityTest(verb, opts) {
|
|
|
1395
1445
|
cfg = await resolveHubConfig();
|
|
1396
1446
|
}
|
|
1397
1447
|
catch (err) {
|
|
1398
|
-
|
|
1448
|
+
renderHubError(err);
|
|
1399
1449
|
process.exit(1);
|
|
1400
1450
|
}
|
|
1401
1451
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -1406,7 +1456,7 @@ export async function capabilityTest(verb, opts) {
|
|
|
1406
1456
|
}
|
|
1407
1457
|
catch (err) {
|
|
1408
1458
|
spinner.fail(chalk.red("Failed to resolve capability"));
|
|
1409
|
-
|
|
1459
|
+
renderHubError(err);
|
|
1410
1460
|
process.exit(1);
|
|
1411
1461
|
}
|
|
1412
1462
|
if (!skillId) {
|
|
@@ -1422,7 +1472,7 @@ export async function capabilityTest(verb, opts) {
|
|
|
1422
1472
|
}
|
|
1423
1473
|
catch (err) {
|
|
1424
1474
|
spinner.fail(chalk.red(`Dry-run failed for ${verb}`));
|
|
1425
|
-
|
|
1475
|
+
renderHubError(err);
|
|
1426
1476
|
process.exit(1);
|
|
1427
1477
|
}
|
|
1428
1478
|
log.heading(`Dry-run preview — ${chalk.bold(verb)}`);
|
|
@@ -1458,7 +1508,7 @@ export async function capabilityCreate(file, opts) {
|
|
|
1458
1508
|
cfg = await resolveHubConfig();
|
|
1459
1509
|
}
|
|
1460
1510
|
catch (err) {
|
|
1461
|
-
|
|
1511
|
+
renderHubError(err);
|
|
1462
1512
|
process.exit(1);
|
|
1463
1513
|
}
|
|
1464
1514
|
const workspaceId = requireWorkspace(opts, cfg);
|
|
@@ -1501,7 +1551,7 @@ export async function capabilityCreate(file, opts) {
|
|
|
1501
1551
|
}
|
|
1502
1552
|
catch (err) {
|
|
1503
1553
|
spinner.fail(chalk.red("Failed to create capability"));
|
|
1504
|
-
|
|
1554
|
+
renderHubError(err);
|
|
1505
1555
|
process.exit(1);
|
|
1506
1556
|
}
|
|
1507
1557
|
const created = (res.created ?? {});
|