@synap-core/cli 1.8.0 → 1.11.0
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/dist/commands/agent-chat.d.ts +47 -0
- package/dist/commands/agent-chat.js +250 -0
- package/dist/commands/agent-chat.js.map +1 -0
- package/dist/commands/agent-run.js +3 -4
- package/dist/commands/agent-run.js.map +1 -1
- package/dist/commands/agents.js +85 -46
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/automation.js +2 -1
- package/dist/commands/automation.js.map +1 -1
- package/dist/commands/bridge-setup.d.ts +66 -0
- package/dist/commands/bridge-setup.js +1112 -0
- package/dist/commands/bridge-setup.js.map +1 -0
- package/dist/commands/cap-connections.d.ts +28 -0
- package/dist/commands/cap-connections.js +224 -0
- package/dist/commands/cap-connections.js.map +1 -0
- package/dist/commands/capability.d.ts +89 -0
- package/dist/commands/capability.js +1594 -0
- package/dist/commands/capability.js.map +1 -0
- package/dist/commands/centrality.d.ts +20 -0
- package/dist/commands/centrality.js +95 -0
- package/dist/commands/centrality.js.map +1 -0
- package/dist/commands/connect.d.ts +2 -0
- package/dist/commands/connect.js +16 -35
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/context.js +6 -7
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +1 -0
- package/dist/commands/data-extra.js +41 -14
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +4 -4
- package/dist/commands/data.js +254 -187
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +20 -0
- package/dist/commands/diagnose.js +186 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/digest.d.ts +17 -0
- package/dist/commands/digest.js +122 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/discover.d.ts +2 -0
- package/dist/commands/discover.js +25 -8
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/doc.d.ts +14 -0
- package/dist/commands/doc.js +61 -4
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +21 -0
- package/dist/commands/doctor.js +189 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.js +5 -2
- package/dist/commands/events.js.map +1 -1
- package/dist/commands/explain.d.ts +1 -1
- package/dist/commands/explain.js +18 -15
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/facet.d.ts +29 -0
- package/dist/commands/facet.js +113 -0
- package/dist/commands/facet.js.map +1 -0
- package/dist/commands/graph.js +7 -4
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/import.d.ts +38 -0
- package/dist/commands/import.js +471 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.js +35 -16
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.js +3 -4
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/knowledge.d.ts +8 -0
- package/dist/commands/knowledge.js +308 -33
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/launch.d.ts +50 -0
- package/dist/commands/launch.js +790 -0
- package/dist/commands/launch.js.map +1 -0
- package/dist/commands/lens.d.ts +45 -0
- package/dist/commands/lens.js +386 -0
- package/dist/commands/lens.js.map +1 -0
- package/dist/commands/market-authoring.d.ts +45 -0
- package/dist/commands/market-authoring.js +225 -0
- package/dist/commands/market-authoring.js.map +1 -0
- package/dist/commands/market.d.ts +224 -0
- package/dist/commands/market.js +1643 -0
- package/dist/commands/market.js.map +1 -0
- package/dist/commands/mcp.d.ts +64 -0
- package/dist/commands/mcp.js +265 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/observe.js +14 -11
- package/dist/commands/observe.js.map +1 -1
- package/dist/commands/open.d.ts +21 -4
- package/dist/commands/open.js +45 -4
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/pod.d.ts +100 -0
- package/dist/commands/pod.js +359 -0
- package/dist/commands/pod.js.map +1 -0
- package/dist/commands/pods.d.ts +15 -0
- package/dist/commands/pods.js +233 -17
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.js +43 -3
- package/dist/commands/proposals-actions.js.map +1 -1
- package/dist/commands/purge.d.ts +23 -0
- package/dist/commands/purge.js +148 -0
- package/dist/commands/purge.js.map +1 -0
- package/dist/commands/raycast.d.ts +15 -0
- package/dist/commands/raycast.js +153 -0
- package/dist/commands/raycast.js.map +1 -0
- package/dist/commands/sessions.js +47 -22
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/skill-manage.d.ts +21 -0
- package/dist/commands/skill-manage.js +195 -0
- package/dist/commands/skill-manage.js.map +1 -0
- package/dist/commands/skills-commands.js +2 -1
- package/dist/commands/skills-commands.js.map +1 -1
- package/dist/commands/skills.js +7 -4
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +3 -1
- package/dist/commands/status.js +166 -14
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/statusline.d.ts +24 -0
- package/dist/commands/statusline.js +450 -0
- package/dist/commands/statusline.js.map +1 -0
- package/dist/commands/subscribe.js +2 -2
- package/dist/commands/subscribe.js.map +1 -1
- package/dist/commands/template.d.ts +42 -0
- package/dist/commands/template.js +191 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/tools.d.ts +30 -0
- package/dist/commands/tools.js +315 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/upload.d.ts +30 -0
- package/dist/commands/upload.js +155 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/commands/versions.d.ts +27 -0
- package/dist/commands/versions.js +277 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/commands/view.js +3 -2
- package/dist/commands/view.js.map +1 -1
- package/dist/commands/whoami.d.ts +21 -0
- package/dist/commands/whoami.js +129 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.js +894 -60
- package/dist/index.js.map +1 -1
- package/dist/lib/approval-poll.d.ts +42 -0
- package/dist/lib/approval-poll.js +52 -0
- package/dist/lib/approval-poll.js.map +1 -0
- package/dist/lib/auth.d.ts +29 -6
- package/dist/lib/auth.js +105 -94
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/bundle-version.d.ts +11 -0
- package/dist/lib/bundle-version.js +33 -0
- package/dist/lib/bundle-version.js.map +1 -0
- package/dist/lib/capture-lane.d.ts +30 -12
- package/dist/lib/capture-lane.js +73 -14
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +123 -0
- package/dist/lib/capture-structure.js +57 -0
- package/dist/lib/capture-structure.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +177 -0
- package/dist/lib/cp-packages.js +389 -0
- package/dist/lib/cp-packages.js.map +1 -0
- package/dist/lib/describe-lens.d.ts +46 -0
- package/dist/lib/describe-lens.js +33 -0
- package/dist/lib/describe-lens.js.map +1 -0
- package/dist/lib/hub-client.d.ts +91 -1
- package/dist/lib/hub-client.js +565 -22
- 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/installed.d.ts +51 -0
- package/dist/lib/installed.js +70 -0
- package/dist/lib/installed.js.map +1 -0
- package/dist/lib/next-steps.d.ts +61 -0
- package/dist/lib/next-steps.js +146 -0
- package/dist/lib/next-steps.js.map +1 -0
- package/dist/lib/pod.d.ts +144 -22
- package/dist/lib/pod.js +302 -64
- package/dist/lib/pod.js.map +1 -1
- package/dist/lib/project-ref.d.ts +95 -0
- package/dist/lib/project-ref.js +144 -0
- package/dist/lib/project-ref.js.map +1 -0
- package/dist/lib/project.d.ts +35 -0
- package/dist/lib/project.js +39 -0
- package/dist/lib/project.js.map +1 -0
- package/dist/lib/session-lens.d.ts +33 -0
- package/dist/lib/session-lens.js +76 -0
- package/dist/lib/session-lens.js.map +1 -0
- package/dist/lib/skill-import.d.ts +40 -0
- package/dist/lib/skill-import.js +203 -0
- package/dist/lib/skill-import.js.map +1 -0
- package/dist/lib/skills-installer.d.ts +17 -6
- package/dist/lib/skills-installer.js +133 -19
- package/dist/lib/skills-installer.js.map +1 -1
- package/dist/lib/suite.d.ts +28 -0
- package/dist/lib/suite.js +29 -0
- package/dist/lib/suite.js.map +1 -0
- package/dist/lib/superwhisper-import.d.ts +40 -0
- package/dist/lib/superwhisper-import.js +389 -0
- package/dist/lib/superwhisper-import.js.map +1 -0
- package/dist/lib/targets.d.ts +49 -1
- package/dist/lib/targets.js +420 -288
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/template-file.d.ts +74 -0
- package/dist/lib/template-file.js +140 -0
- package/dist/lib/template-file.js.map +1 -0
- package/dist/lib/unwrapList.d.ts +1 -0
- package/dist/lib/unwrapList.js +20 -0
- package/dist/lib/unwrapList.js.map +1 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +10 -2
- package/dist/utils/logger.js.map +1 -1
- package/node_modules/@synap/hub-rest-client/dist/index.cjs +414 -34
- package/node_modules/@synap/hub-rest-client/dist/index.d.cts +762 -22
- package/node_modules/@synap/hub-rest-client/dist/index.d.ts +762 -22
- package/node_modules/@synap/hub-rest-client/dist/index.js +414 -34
- package/node_modules/@synap/hub-rest-client/package.json +1 -1
- package/node_modules/@synap/hub-rest-client/src/client.ts +525 -37
- package/node_modules/@synap/hub-rest-client/src/index.ts +42 -0
- package/node_modules/@synap/hub-rest-client/src/setup.ts +57 -1
- package/node_modules/@synap/hub-rest-client/src/types.ts +697 -37
- package/package.json +11 -5
- package/skills/agent-os/SKILL.md +218 -0
- package/skills/manifest.json +5 -0
- package/skills/onboard/SKILL.md +193 -0
- package/skills/synap/SKILL.md +1284 -58
- package/skills/synap/_order.txt +37 -0
- package/skills/synap/_skill.yaml +24 -0
- package/skills/synap/authentication.md +10 -0
- package/skills/synap/automations.md +264 -0
- package/skills/synap/capabilities.md +107 -0
- package/skills/synap/capture.md +50 -142
- package/skills/synap/cli-operations.md +107 -0
- package/skills/synap/common-mistakes.md +13 -0
- package/skills/synap/content-os.md +83 -0
- package/skills/synap/creative-loop.md +43 -0
- package/skills/synap/crm.md +117 -0
- package/skills/synap/diagnostics.md +35 -0
- package/skills/synap/digesting-a-channel.md +63 -0
- package/skills/synap/document-embeds.md +123 -0
- package/skills/synap/escalation-ladder.md +71 -0
- package/skills/synap/focus-sessions.md +47 -0
- package/skills/synap/governance-rules.md +64 -0
- package/skills/synap/governance.md +6 -6
- package/skills/synap/graph-gardening.md +21 -0
- package/skills/synap/inline-patterns.md +38 -0
- package/skills/synap/lenses.md +38 -0
- package/skills/synap/linking-principle.md +39 -0
- package/skills/synap/linking.md +1 -0
- package/skills/synap/mental-model.md +45 -0
- package/skills/synap/more.md +7 -0
- package/skills/synap/multi-entity-capture.md +12 -0
- package/skills/synap/next-action.md +37 -0
- package/skills/synap/north-star.md +17 -0
- package/skills/synap/operating-mode-rules.md +45 -0
- package/skills/synap/operating-mode.md +9 -0
- package/skills/synap/quick-reference.md +67 -0
- package/skills/synap/reading.md +43 -0
- package/skills/synap/recap.md +21 -0
- package/skills/synap/reflexes.md +46 -0
- package/skills/synap/response-style.md +21 -0
- package/skills/synap/scope.md +13 -0
- package/skills/synap/showing.md +17 -0
- package/skills/synap/user-model.md +25 -0
- package/skills/synap/viewframe-cells.md +290 -0
- package/skills/synap/work-flow.md +113 -0
- package/skills/synap/worked-examples.md +74 -0
- package/skills/synap/workspace-design.md +45 -0
- package/skills/synap/workspace-edges.md +49 -0
- package/skills/synap/writes.md +213 -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-market/SKILL.md +335 -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 +75 -0
- package/skills/synap-market/discover-and-fetch.md +59 -0
- package/skills/synap-market/governance-and-catalog.md +56 -0
- package/skills/synap-market/install.md +55 -0
- package/skills/synap-market/overview.md +51 -0
- package/skills/synap-schema/SKILL.md +97 -6
- package/skills/synap-schema/_order.txt +13 -0
- package/skills/synap-schema/_skill.yaml +22 -0
- package/skills/synap-schema/before-you-touch.md +14 -0
- package/skills/synap-schema/common-mistakes.md +9 -0
- package/skills/synap-schema/creating-profiles.md +17 -0
- package/skills/synap-schema/discover-profiles.md +24 -0
- package/skills/synap-schema/entity-scope.md +8 -0
- package/skills/synap-schema/extend-vs-create.md +31 -0
- package/skills/synap-schema/more.md +6 -0
- package/skills/synap-schema/overlay-properties.md +22 -0
- package/skills/synap-schema/profiles.md +3 -0
- package/skills/synap-schema/property-defs.md +29 -0
- package/skills/synap-schema/read-before-write.md +50 -0
- package/skills/synap-schema/relations.md +18 -0
- package/skills/synap-schema/worked-example.md +30 -0
- package/skills/synap-ui/SKILL.md +26 -2
- package/skills/synap-ui/_order.txt +13 -0
- package/skills/synap-ui/_skill.yaml +23 -0
- package/skills/synap-ui/ai-companion.md +27 -0
- package/skills/synap-ui/arranging-bento.md +8 -0
- package/skills/synap-ui/before-you-build.md +20 -0
- package/skills/synap-ui/bento-layouts.md +35 -0
- package/skills/synap-ui/common-mistakes.md +10 -0
- package/skills/synap-ui/creating-views.md +26 -0
- package/skills/synap-ui/four-builds.md +24 -0
- package/skills/synap-ui/more.md +7 -0
- package/skills/synap-ui/proposing-vs-extending.md +11 -0
- package/skills/synap-ui/view-list.md +24 -0
- package/skills/synap-ui/views.md +3 -0
- package/skills/synap-ui/worked-example.md +18 -0
- package/skills/synap-ui/workspaces.md +47 -0
- package/templates/automations/bookmark-enrichment.automation.json +44 -0
- package/templates/automations/mail-feed.automation.json +86 -0
- package/templates/automations/url-bookmark-capture.automation.json +70 -0
- package/templates/skills/README.md +21 -0
- package/templates/skills/authoring-automations/SKILL.md +95 -0
- package/templates/skills/authoring-automations/reference/node-matrix.md +49 -0
- package/templates/skills/authoring-capabilities/SKILL.md +93 -0
- package/templates/skills/authoring-capabilities/reference/template-anatomy.md +70 -0
- package/templates/skills/authoring-playbooks/SKILL.md +102 -0
- package/templates/skills/authoring-playbooks/reference/stages-contract.md +35 -0
- package/templates/skills/authoring-playbooks/reference/worked-example.md +64 -0
- package/templates/skills/bookmark-enrichment/SKILL.md +40 -0
- package/templates/skills/coordinating-agents/SKILL.md +32 -0
- package/templates/skills/coordinating-branches/SKILL.md +27 -0
- package/templates/skills/mapping-the-server/SKILL.md +54 -0
- package/templates/skills/reading-client-progress/SKILL.md +65 -0
- package/templates/skills/routing-to-channels/SKILL.md +54 -0
- package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
- package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
- package/templates/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
- package/templates/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
- package/templates/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
- package/templates/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
- package/templates/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
- package/dist/commands/connectors.d.ts +0 -31
- package/dist/commands/connectors.js +0 -276
- package/dist/commands/connectors.js.map +0 -1
- package/dist/commands/finish.d.ts +0 -25
- package/dist/commands/finish.js +0 -274
- package/dist/commands/finish.js.map +0 -1
- package/dist/commands/openclaw.d.ts +0 -40
- package/dist/commands/openclaw.js +0 -1148
- package/dist/commands/openclaw.js.map +0 -1
- package/dist/commands/security-audit.d.ts +0 -12
- package/dist/commands/security-audit.js +0 -100
- package/dist/commands/security-audit.js.map +0 -1
- package/dist/lib/hardening.d.ts +0 -18
- package/dist/lib/hardening.js +0 -214
- package/dist/lib/hardening.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Command } from "commander";
|
|
|
16
16
|
import { readFileSync } from "fs";
|
|
17
17
|
import { fileURLToPath } from "url";
|
|
18
18
|
import { dirname, join } from "path";
|
|
19
|
+
import { bootstrapPodOverride } from "./lib/pod.js";
|
|
19
20
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
21
|
const __dirname = dirname(__filename);
|
|
21
22
|
let version = "0.1.0";
|
|
@@ -31,7 +32,11 @@ program
|
|
|
31
32
|
.name("synap")
|
|
32
33
|
.description("Synap CLI — connect AI agents to your data pod")
|
|
33
34
|
.version(version)
|
|
34
|
-
.showSuggestionAfterError(true)
|
|
35
|
+
.showSuggestionAfterError(true)
|
|
36
|
+
// Global, position-independent: target a saved pod profile for THIS command
|
|
37
|
+
// only (see `synap pods`). Consumed pre-parse by bootstrapPodOverride so it
|
|
38
|
+
// works in any position and overrides the default/env pod for one invocation.
|
|
39
|
+
.option("--pod <name>", "Run this command against a saved pod profile (overrides the default pod for this invocation only)");
|
|
35
40
|
program
|
|
36
41
|
.command("init")
|
|
37
42
|
.description("Full setup: connect to a Synap pod and install the skill")
|
|
@@ -42,6 +47,41 @@ program
|
|
|
42
47
|
const { init } = await import("./commands/init.js");
|
|
43
48
|
await init(opts);
|
|
44
49
|
});
|
|
50
|
+
// ── launch — nothing → a working company (project + domain workspaces) ────────
|
|
51
|
+
// Not a template browser: `--list` shows what's launchable (local, no pod),
|
|
52
|
+
// bare `synap launch` runs the guided one-per-company setup.
|
|
53
|
+
program
|
|
54
|
+
.command("launch")
|
|
55
|
+
.description("Stand up a NEW company/OS on a pod — creates a project + its core workspaces (interactive)")
|
|
56
|
+
.option("--list", "List what can be launched (local templates, no pod needed) and exit")
|
|
57
|
+
.option("--search <query>", "Filter --list by name/description/slug")
|
|
58
|
+
.option("--type <type>", "Filter --list by package type (workspace|capability|skill|workflow|view|cell)")
|
|
59
|
+
.option("--json", "Output as JSON")
|
|
60
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
61
|
+
.option("--api-key <key>", "API key override")
|
|
62
|
+
.action(async (opts) => {
|
|
63
|
+
const { launch } = await import("./commands/launch.js");
|
|
64
|
+
await launch(opts);
|
|
65
|
+
});
|
|
66
|
+
// Hidden: one-shot Discord↔Synap bridge provisioning (dogfood/dev convenience).
|
|
67
|
+
program
|
|
68
|
+
.command("bridge-setup", { hidden: true })
|
|
69
|
+
.description("(hidden) One-shot Discord↔Synap bridge provisioning")
|
|
70
|
+
.option("--client-id <id>", "Discord application (client) id — prints the invite URL")
|
|
71
|
+
.option("--bot-token <token>", "Discord bot token — provisioned into the pod vault")
|
|
72
|
+
.option("--guild-id <id>", "Discord server (guild) id — written to the bridge .env")
|
|
73
|
+
.option("--bridge-dir <path>", "Path to the telegram-discord-bridge repo")
|
|
74
|
+
.option("--workspace-id <uuid>", "Target workspace (default: pod profile's)")
|
|
75
|
+
.option("--proactive-channel <id>", "Discord channel id for the agent's proactive posts")
|
|
76
|
+
.option("--enable-react", "Turn on ✅-react capture")
|
|
77
|
+
.option("--pod <name>", "Pod profile to connect the bridge to (default: prompt)")
|
|
78
|
+
.option("--governance <mode>", "Agent governance preset: safe | normal | crazy (default: prompt)")
|
|
79
|
+
.option("--pod-url <url>", "Synap pod URL (override)")
|
|
80
|
+
.option("--api-key <key>", "Hub Protocol API key (override)")
|
|
81
|
+
.action(async (opts) => {
|
|
82
|
+
const { bridgeSetup } = await import("./commands/bridge-setup.js");
|
|
83
|
+
await bridgeSetup(opts);
|
|
84
|
+
});
|
|
45
85
|
program
|
|
46
86
|
.command("connect")
|
|
47
87
|
.description("Connect an AI surface (Claude Code, Claude Desktop, Cursor, Raycast) to a Synap pod")
|
|
@@ -51,6 +91,8 @@ program
|
|
|
51
91
|
.option("--name <name>", "Pod profile name to save credentials under (default: 'default')")
|
|
52
92
|
.option("--list", "List supported targets and exit")
|
|
53
93
|
.option("--manual-key", "Skip the browser approval flow and paste a key (or provisioning token)")
|
|
94
|
+
.option("--pin-workspace <id>", "Pin the connection to one workspace (default: pod-wide lens)")
|
|
95
|
+
.option("--pin-project <id>", "Pin the connection to one project (composable with --pin-workspace)")
|
|
54
96
|
.action(async (opts) => {
|
|
55
97
|
const { connect } = await import("./commands/connect.js");
|
|
56
98
|
await connect(opts);
|
|
@@ -77,9 +119,19 @@ pods
|
|
|
77
119
|
.command("use <name>")
|
|
78
120
|
.description("Switch active pod and propagate credentials to all agent surfaces")
|
|
79
121
|
.option("--surface <surface>", "Only switch this surface (raycast, claude-code, claude-desktop, cursor)")
|
|
122
|
+
.option("--json", "Output as JSON (incl. nextSteps for agents; full-switch only)")
|
|
80
123
|
.action(async (name, opts) => {
|
|
81
124
|
const { podsUse } = await import("./commands/pods.js");
|
|
82
|
-
await podsUse(name, { surface: opts.surface });
|
|
125
|
+
await podsUse(name, { surface: opts.surface, json: opts.json });
|
|
126
|
+
});
|
|
127
|
+
pods
|
|
128
|
+
.command("update <name> [url]")
|
|
129
|
+
.description("Change a saved pod's URL in place (verifies health + whether the key must be recreated)")
|
|
130
|
+
.option("--url <url>", "New pod URL (alternative to the positional arg)")
|
|
131
|
+
.option("--yes", "Non-interactive: skip prompts (won't recreate a rejected key)")
|
|
132
|
+
.action(async (name, url, opts) => {
|
|
133
|
+
const { podsUpdate } = await import("./commands/pods.js");
|
|
134
|
+
await podsUpdate(name, url, { url: opts.url, yes: opts.yes });
|
|
83
135
|
});
|
|
84
136
|
pods
|
|
85
137
|
.command("remove <name>")
|
|
@@ -99,9 +151,42 @@ pods
|
|
|
99
151
|
program
|
|
100
152
|
.command("status")
|
|
101
153
|
.description("Show Synap pod health and API status")
|
|
102
|
-
.
|
|
154
|
+
.option("--json", "Dump raw status (incl. release/migration detail) as JSON")
|
|
155
|
+
.action(async (opts) => {
|
|
103
156
|
const { status } = await import("./commands/status.js");
|
|
104
|
-
await status();
|
|
157
|
+
await status({ json: opts.json });
|
|
158
|
+
});
|
|
159
|
+
program
|
|
160
|
+
.command("doctor")
|
|
161
|
+
.description("Coherence preflight: pod host resolves, key authenticates, workspace/project exist on THIS pod — catches config drift in one call")
|
|
162
|
+
.option("--json", "Output as JSON")
|
|
163
|
+
.action(async (opts) => {
|
|
164
|
+
const { doctor } = await import("./commands/doctor.js");
|
|
165
|
+
await doctor(opts);
|
|
166
|
+
});
|
|
167
|
+
program
|
|
168
|
+
.command("versions")
|
|
169
|
+
.description("Show LOCAL vs NPM vs CONTROL-PLANE vs POD version drift for workspace-templates, api-types, and capabilities")
|
|
170
|
+
.option("--json", "Output structured {artifacts:[...]} JSON")
|
|
171
|
+
.action(async (opts) => {
|
|
172
|
+
const { versions } = await import("./commands/versions.js");
|
|
173
|
+
await versions({ json: opts.json });
|
|
174
|
+
});
|
|
175
|
+
program
|
|
176
|
+
.command("whoami")
|
|
177
|
+
.description("Show the winning API key's identity/scopes/workspace and flag env-vs-surface key divergence")
|
|
178
|
+
.action(async () => {
|
|
179
|
+
const { whoami } = await import("./commands/whoami.js");
|
|
180
|
+
await whoami();
|
|
181
|
+
});
|
|
182
|
+
// Hidden: compact ANSI line for the Claude Code statusLine (reads stdin JSON).
|
|
183
|
+
program
|
|
184
|
+
.command("statusline", { hidden: true })
|
|
185
|
+
.description("(internal) Compact ANSI status line for Claude Code")
|
|
186
|
+
.option("--refresh", "Refresh the pod cache (run detached in the background)")
|
|
187
|
+
.action(async (opts) => {
|
|
188
|
+
const { statusline } = await import("./commands/statusline.js");
|
|
189
|
+
await statusline({ refresh: opts.refresh });
|
|
105
190
|
});
|
|
106
191
|
program
|
|
107
192
|
.command("update")
|
|
@@ -174,9 +259,57 @@ program
|
|
|
174
259
|
const { connections } = await import("./commands/connections.js");
|
|
175
260
|
await connections();
|
|
176
261
|
});
|
|
262
|
+
// ─── mcp ────────────────────────────────────────────────────────────────────
|
|
263
|
+
// The MCP front door: point any AI client at the pod's /mcp server.
|
|
264
|
+
const mcp = program
|
|
265
|
+
.command("mcp")
|
|
266
|
+
.description("Connect any AI client to your pod's MCP server (the ambient tool layer)");
|
|
267
|
+
mcp
|
|
268
|
+
.command("url")
|
|
269
|
+
.description("Print a ready-to-paste MCP connection (URL + key + snippets) for UI clients like ChatGPT")
|
|
270
|
+
.option("--client <name>", "Name the dedicated agent key after the target client")
|
|
271
|
+
.option("--workspace <id>", "Scope to a specific workspace (omit for pod-wide)")
|
|
272
|
+
.option("--project <id>", "Focus the agent on a project (narrows every tool call; orthogonal to --workspace)")
|
|
273
|
+
.option("--json", "Output as JSON")
|
|
274
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
275
|
+
.option("--api-key <key>", "API key override")
|
|
276
|
+
.action(async (opts) => {
|
|
277
|
+
const { mcpUrl } = await import("./commands/mcp.js");
|
|
278
|
+
await mcpUrl(opts);
|
|
279
|
+
});
|
|
280
|
+
mcp
|
|
281
|
+
.command("verify")
|
|
282
|
+
.description("Health-check: is the pod's /mcp endpoint reachable and the key valid?")
|
|
283
|
+
.option("--workspace <id>", "Scope to a specific workspace")
|
|
284
|
+
.option("--json", "Output as JSON")
|
|
285
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
286
|
+
.option("--api-key <key>", "API key override")
|
|
287
|
+
.action(async (opts) => {
|
|
288
|
+
const { mcpVerify } = await import("./commands/mcp.js");
|
|
289
|
+
await mcpVerify(opts);
|
|
290
|
+
});
|
|
291
|
+
mcp
|
|
292
|
+
.command("connect [client]")
|
|
293
|
+
.description("Write the MCP config for a file-configurable client (Claude Code, Cursor, Desktop, …) — alias of `synap connect`")
|
|
294
|
+
.option("--name <name>", "Pod profile to connect")
|
|
295
|
+
.action(async (client, opts) => {
|
|
296
|
+
const { connect } = await import("./commands/connect.js");
|
|
297
|
+
await connect({ target: client, name: opts.name });
|
|
298
|
+
});
|
|
299
|
+
mcp
|
|
300
|
+
.command("connect-claude")
|
|
301
|
+
.description("Print the claude.ai (web) OAuth connection steps — paste a URL, approve in the browser, done")
|
|
302
|
+
.option("--cp-url <url>", "Control-plane origin override (default: derived from the pod host)")
|
|
303
|
+
.option("--json", "Output as JSON")
|
|
304
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
305
|
+
.option("--api-key <key>", "API key override")
|
|
306
|
+
.action(async (opts) => {
|
|
307
|
+
const { mcpConnectClaudeWeb } = await import("./commands/mcp.js");
|
|
308
|
+
await mcpConnectClaudeWeb(opts);
|
|
309
|
+
});
|
|
177
310
|
program
|
|
178
311
|
.command("login")
|
|
179
|
-
.description("Connect
|
|
312
|
+
.description("Connect your Synap account (private templates) + your pods")
|
|
180
313
|
.option("--reconnect [name]", "Re-authenticate a saved pod without re-entering its URL")
|
|
181
314
|
.action(async (opts) => {
|
|
182
315
|
const chalk = (await import("chalk")).default;
|
|
@@ -200,23 +333,44 @@ program
|
|
|
200
333
|
// Already have pods — show status and offer reconnect if any are unreachable
|
|
201
334
|
const { checkPodHealth } = await import("./lib/pod.js");
|
|
202
335
|
const ora = (await import("ora")).default;
|
|
203
|
-
const spinner = ora("Checking
|
|
336
|
+
const spinner = ora("Checking pods + credentials...").start();
|
|
204
337
|
const checks = await Promise.all(profiles.map(async (p) => {
|
|
205
338
|
const h = await checkPodHealth(p.config.podUrl).catch(() => ({ healthy: false }));
|
|
206
|
-
|
|
339
|
+
// A pod can be HEALTHY (public /health) while the saved key is REVOKED.
|
|
340
|
+
// Validate the actual credential too — otherwise a dead key looks "ok"
|
|
341
|
+
// and the user gets cryptic 401s downstream (the connect trap).
|
|
342
|
+
let keyValid = false;
|
|
343
|
+
if (h.healthy && p.config.hubApiKey) {
|
|
344
|
+
try {
|
|
345
|
+
const res = await fetch(`${p.config.podUrl.replace(/\/$/, "")}/api/hub/auth/status`, {
|
|
346
|
+
headers: { Authorization: `Bearer ${p.config.hubApiKey}` },
|
|
347
|
+
signal: AbortSignal.timeout(6000),
|
|
348
|
+
});
|
|
349
|
+
keyValid = res.ok;
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
keyValid = false;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return { ...p, healthy: h.healthy, keyValid };
|
|
207
356
|
}));
|
|
208
357
|
spinner.stop();
|
|
209
358
|
console.log("\n Configured pods:\n");
|
|
210
359
|
for (const p of checks) {
|
|
211
360
|
const active = p.active ? chalk.green(" ● ") : " ";
|
|
212
|
-
const status = p.healthy
|
|
361
|
+
const status = !p.healthy
|
|
362
|
+
? chalk.red("unreachable")
|
|
363
|
+
: p.keyValid
|
|
364
|
+
? chalk.green("ok")
|
|
365
|
+
: chalk.yellow("key expired");
|
|
213
366
|
console.log(` ${active}${chalk.bold(p.name.padEnd(14))} ${status} ${chalk.dim(p.config.podUrl)}`);
|
|
214
367
|
}
|
|
215
368
|
console.log();
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
369
|
+
// Anything that won't authenticate — unreachable OR a revoked/expired key.
|
|
370
|
+
const needsReconnect = checks.filter((p) => !p.healthy || !p.keyValid);
|
|
371
|
+
if (needsReconnect.length > 0) {
|
|
372
|
+
console.log(chalk.yellow(` ${needsReconnect.length} pod(s) need re-authentication. Refresh credentials:`));
|
|
373
|
+
for (const p of needsReconnect) {
|
|
220
374
|
console.log(chalk.dim(` synap login --reconnect ${p.name}`));
|
|
221
375
|
}
|
|
222
376
|
console.log();
|
|
@@ -226,22 +380,87 @@ program
|
|
|
226
380
|
const active = checks.find((p) => p.active);
|
|
227
381
|
if (active)
|
|
228
382
|
console.log(chalk.dim(` Active: ${active.name} (${active.config.podUrl})`));
|
|
229
|
-
console.log();
|
|
230
|
-
console.log(chalk.dim(" synap pods use <name> — switch active pod"));
|
|
231
|
-
console.log(chalk.dim(" synap pods add — connect another pod"));
|
|
232
383
|
}
|
|
384
|
+
// ── Synap ACCOUNT (control plane) — a FIRST-CLASS half of "login" ──────
|
|
385
|
+
// Pods authenticate DATA access; the ACCOUNT authenticates the control plane
|
|
386
|
+
// (private templates like The Arch, hosted pods, marketplace publishing).
|
|
387
|
+
// They are different credentials, and pods alone never unlock private
|
|
388
|
+
// templates — so this gets its own headed section, not a footnote. `synap
|
|
389
|
+
// launch`'s "private templates after 'synap login'" hint lands HERE.
|
|
390
|
+
const { isLoggedIn: cpLoggedIn, login: cpLogin } = await import("./lib/auth.js");
|
|
391
|
+
console.log("\n Synap account:\n");
|
|
392
|
+
const account = await cpLoggedIn();
|
|
393
|
+
let accountEmail;
|
|
394
|
+
if (account.valid) {
|
|
395
|
+
accountEmail = account.email;
|
|
396
|
+
console.log(` ${chalk.green("●")} ${chalk.bold(account.email ?? "logged in")} ${chalk.dim("— private templates available")}`);
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
console.log(` ${chalk.yellow("○")} ${chalk.bold("not logged in")} ${chalk.dim("— your private templates (e.g. The Arch) are hidden until you log in")}`);
|
|
400
|
+
const prompts = (await import("prompts")).default;
|
|
401
|
+
const { doLogin } = await prompts({
|
|
402
|
+
type: "confirm",
|
|
403
|
+
name: "doLogin",
|
|
404
|
+
message: "Log in to your Synap account now?",
|
|
405
|
+
initial: true,
|
|
406
|
+
});
|
|
407
|
+
if (doLogin) {
|
|
408
|
+
const creds = await cpLogin();
|
|
409
|
+
if (creds?.email) {
|
|
410
|
+
accountEmail = creds.email;
|
|
411
|
+
console.log(chalk.green(` ✓ Logged in as ${creds.email} — private templates unlocked.`));
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
console.log(chalk.dim(" Later: synap login · or synap login --token <token> (synap.live/account/tokens)"));
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
const { renderNextSteps, FLOW } = await import("./lib/next-steps.js");
|
|
419
|
+
renderNextSteps(FLOW.afterLogin(accountEmail));
|
|
233
420
|
});
|
|
234
421
|
// ─── orient ───────────────────────────────────────────────────────────────────
|
|
235
422
|
program
|
|
236
423
|
.command("orient")
|
|
237
|
-
.description("Show
|
|
424
|
+
.description("Show a lightweight lens map: who you are, your projects (companies/initiatives), and workspaces (operational domains)")
|
|
238
425
|
.option("--json", "Output as JSON")
|
|
426
|
+
.option("--details", "Include per-workspace profiles + entity counts (heavier)")
|
|
239
427
|
.option("--pod-url <url>", "Pod URL override")
|
|
240
428
|
.option("--api-key <key>", "API key override")
|
|
241
429
|
.action(async (opts) => {
|
|
242
430
|
const { orient } = await import("./commands/data.js");
|
|
243
431
|
await orient(opts);
|
|
244
432
|
});
|
|
433
|
+
// ─── digest ─────────────────────────────────────────────────────────────────
|
|
434
|
+
// A quick read of what's already in a workspace or project (counts + key
|
|
435
|
+
// entities + summary). Default = the active workspace lens.
|
|
436
|
+
program
|
|
437
|
+
.command("digest")
|
|
438
|
+
.description("Summarize what's in a workspace or project (counts + key entities)")
|
|
439
|
+
.option("--workspace <id|name>", "Workspace to digest (defaults to active workspace lens)")
|
|
440
|
+
.option("--project <id|name>", "Project to digest (cross-cutting lens)")
|
|
441
|
+
.option("--json", "Output raw JSON")
|
|
442
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
443
|
+
.option("--api-key <key>", "API key override")
|
|
444
|
+
.action(async (opts) => {
|
|
445
|
+
const { digest } = await import("./commands/digest.js");
|
|
446
|
+
await digest(opts);
|
|
447
|
+
});
|
|
448
|
+
// ─── diagnose ────────────────────────────────────────────────────────────────
|
|
449
|
+
// See what an AI did across flows: the unified run feed, or one run's activity
|
|
450
|
+
// timeline (for a capture: WHY a facet/entity dropped, with a fixHint).
|
|
451
|
+
program
|
|
452
|
+
.command("diagnose [runId]")
|
|
453
|
+
.description("See what an AI did — the run feed, or one run's activity (why it did what it did)")
|
|
454
|
+
.option("--flow <automation|playbook|capture|session>", "Restrict the feed, or the run's flow (default capture for a runId)")
|
|
455
|
+
.option("--flow-id <id>", "Restrict the feed to one flow's runs (automationId / playbookId)")
|
|
456
|
+
.option("--limit <n>", "Max runs in the feed")
|
|
457
|
+
.option("--json", "Output raw JSON")
|
|
458
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
459
|
+
.option("--api-key <key>", "API key override")
|
|
460
|
+
.action(async (runId, opts) => {
|
|
461
|
+
const { diagnose } = await import("./commands/diagnose.js");
|
|
462
|
+
await diagnose(runId, opts);
|
|
463
|
+
});
|
|
245
464
|
// ─── use ──────────────────────────────────────────────────────────────────────
|
|
246
465
|
program
|
|
247
466
|
.command("use <workspace>")
|
|
@@ -253,20 +472,70 @@ program
|
|
|
253
472
|
const { useWorkspace } = await import("./commands/data.js");
|
|
254
473
|
await useWorkspace(workspace, opts);
|
|
255
474
|
});
|
|
256
|
-
// ───
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
.command("
|
|
262
|
-
.description("
|
|
263
|
-
.option("--
|
|
475
|
+
// ─── project / lens (per-Claude-session scoping) ──────────────────────────────
|
|
476
|
+
const project = program
|
|
477
|
+
.command("project")
|
|
478
|
+
.description("Manage + focus the cross-cutting project lens (a company/initiative): list, new, use, clear");
|
|
479
|
+
project
|
|
480
|
+
.command("list", { isDefault: true })
|
|
481
|
+
.description("List projects on the active pod, with the pinned one marked (bare `synap project` runs this)")
|
|
482
|
+
.option("--json", "Output as JSON (incl. nextSteps for agents)")
|
|
483
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
484
|
+
.option("--api-key <key>", "API key override")
|
|
485
|
+
.action(async (opts) => {
|
|
486
|
+
const { projectList } = await import("./commands/lens.js");
|
|
487
|
+
await projectList(opts);
|
|
488
|
+
});
|
|
489
|
+
project
|
|
490
|
+
.command("new <name>")
|
|
491
|
+
.description("Create a project (a company/initiative) on the active pod, then guide you to pin + add to it")
|
|
492
|
+
.option("--description <text>", "Optional one-line description")
|
|
493
|
+
.option("--json", "Output as JSON (incl. nextSteps for agents)")
|
|
494
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
495
|
+
.option("--api-key <key>", "API key override")
|
|
496
|
+
.action(async (name, opts) => {
|
|
497
|
+
const { projectNew } = await import("./commands/lens.js");
|
|
498
|
+
await projectNew(name, opts);
|
|
499
|
+
});
|
|
500
|
+
project
|
|
501
|
+
.command("use <ref>")
|
|
502
|
+
.description("Pin the active project (durable, like `synap use <workspace>`). Ref = uuid, slug, or <pod>/<slug> — cross-pod refs switch the active pod too")
|
|
503
|
+
.option("--session", "Ephemeral: scope only this Claude Code session, don't persist (cross-pod refs refused)")
|
|
264
504
|
.option("--json", "Output as JSON")
|
|
265
505
|
.option("--pod-url <url>", "Pod URL override")
|
|
266
506
|
.option("--api-key <key>", "API key override")
|
|
267
|
-
.action(async (
|
|
268
|
-
const {
|
|
269
|
-
await
|
|
507
|
+
.action(async (ref, opts) => {
|
|
508
|
+
const { useProject } = await import("./commands/lens.js");
|
|
509
|
+
await useProject(ref, opts);
|
|
510
|
+
});
|
|
511
|
+
project
|
|
512
|
+
.command("clear")
|
|
513
|
+
.description("Clear the active project focus (durable by default)")
|
|
514
|
+
.option("--session", "Ephemeral: clear only this Claude Code session's project")
|
|
515
|
+
.option("--json", "Output as JSON")
|
|
516
|
+
.action(async (opts) => {
|
|
517
|
+
const { clearProject } = await import("./commands/lens.js");
|
|
518
|
+
await clearProject(opts);
|
|
519
|
+
});
|
|
520
|
+
project
|
|
521
|
+
.command("purge <target>")
|
|
522
|
+
.description("HARD teardown: delete a project + its pod-wide-exclusive entities (owner-only, irreversible)")
|
|
523
|
+
.option("--confirm <name>", "Confirm non-interactively by passing the exact project name")
|
|
524
|
+
.option("--yes", "Skip the interactive name prompt (uses the resolved name)")
|
|
525
|
+
.option("--json", "Output raw JSON")
|
|
526
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
527
|
+
.option("--api-key <key>", "API key override")
|
|
528
|
+
.action(async (target, opts) => {
|
|
529
|
+
const { projectPurge } = await import("./commands/purge.js");
|
|
530
|
+
await projectPurge(target, opts);
|
|
531
|
+
});
|
|
532
|
+
program
|
|
533
|
+
.command("lens")
|
|
534
|
+
.description("Show this Claude session's lens (workspace + project + focus session)")
|
|
535
|
+
.option("--json", "Output as JSON")
|
|
536
|
+
.action(async (opts) => {
|
|
537
|
+
const { showLens } = await import("./commands/lens.js");
|
|
538
|
+
await showLens(opts);
|
|
270
539
|
});
|
|
271
540
|
// ─── ask (unified knowledge access) ─────────────────────────────────────────────
|
|
272
541
|
// The ONE read verb. Routes to the right substrate(s) — semantic (entities),
|
|
@@ -277,6 +546,8 @@ program
|
|
|
277
546
|
.option("--workspace <id>", "Scope to a specific workspace (omit for pod-wide)")
|
|
278
547
|
.option("--limit <n>", "Max results per substrate", "10")
|
|
279
548
|
.option("--json", "Output as JSON")
|
|
549
|
+
.option("--session", "Scope retrieval to the active session context")
|
|
550
|
+
.option("--compare", "A/B diagnostic: show baseline vs Horizon rankers side-by-side (read-only, does not change the answer)")
|
|
280
551
|
.option("--pod-url <url>", "Pod URL override")
|
|
281
552
|
.option("--api-key <key>", "API key override")
|
|
282
553
|
.action(async (query, opts) => {
|
|
@@ -294,16 +565,69 @@ program
|
|
|
294
565
|
.option("--why <text>", "Reasoning or context")
|
|
295
566
|
.option("--evidence <text>", "Supporting file path, URL, or code snippet")
|
|
296
567
|
.option("--tags <csv>", "Comma-separated tags e.g. repo:synap-backend,layer:migrations")
|
|
568
|
+
.option("--session", "Link captured knowledge to the active session")
|
|
297
569
|
.option("--global", "GLOBAL lane: pod-wide cross-cutting runbook (→ knowledge_keys), visible in every workspace")
|
|
298
570
|
.option("--key <ns:slug>", "Stable key for a --global runbook (derived from --type + --claim if omitted)")
|
|
299
571
|
.option("--team", "Write to the first product workspace instead of the active workspace")
|
|
300
572
|
.option("--workspace <id>", "Explicit workspace override")
|
|
573
|
+
.option("--project <id|name>", "Pin the capture to a project (id or name) — overrides SYNAP_PROJECT_ID / the session lens")
|
|
301
574
|
.option("--yes", "Skip the y/N confirmation prompt (smart mode)")
|
|
302
575
|
.option("--json", "Output as JSON")
|
|
303
576
|
.action(async (text, opts) => {
|
|
304
577
|
const { captureKnowledge } = await import("./commands/knowledge.js");
|
|
305
578
|
await captureKnowledge({ ...opts, text });
|
|
306
579
|
});
|
|
580
|
+
// ─── import ─────────────────────────────────────────────────────────────────
|
|
581
|
+
// "capture, but for files and URLs." Each input (file/folder/URL) routes through
|
|
582
|
+
// the SAME AI capture pipeline (/capture/structure → /capture/execute), so it
|
|
583
|
+
// inherits entity extraction, the relation graph, and workspace/project routing.
|
|
584
|
+
program
|
|
585
|
+
.command("import <inputs...>")
|
|
586
|
+
.description("Import files, folders, or URLs into the pod (AI capture pipeline, or Superwhisper store-first)")
|
|
587
|
+
.option("--workspace <id|name>", "Override AI workspace routing")
|
|
588
|
+
.option("--project <id|name>", "Override AI project routing")
|
|
589
|
+
.option("--dry-run", "Preview only — do not write")
|
|
590
|
+
.option("--yes", "Skip confirmation / auto-confirm store-first")
|
|
591
|
+
.option("--session", "Link created entities to the active session")
|
|
592
|
+
.option("--json", "Output as JSON")
|
|
593
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
594
|
+
.option("--api-key <key>", "API key override")
|
|
595
|
+
.option("--source <name>", "Adapter: superwhisper (paired meta.json+output.wav store-first)")
|
|
596
|
+
.option("--store-first", "Skip AI structure; store units as pod-wide notes (+ optional audio)")
|
|
597
|
+
.option("--with-audio", "Upload WAV provenance (default on for --source superwhisper --store-first)")
|
|
598
|
+
.option("--no-with-audio", "Transcript-only (no WAV upload)")
|
|
599
|
+
.option("--limit <n>", "Max Superwhisper units to process", (v) => parseInt(v, 10))
|
|
600
|
+
.option("--concurrency <n>", "Parallel unit uploads (1–4)", (v) => parseInt(v, 10))
|
|
601
|
+
.option("--no-resume", "Ignore local import ledger (re-import all)")
|
|
602
|
+
.action(async (inputs, opts) => {
|
|
603
|
+
const { importData } = await import("./commands/import.js");
|
|
604
|
+
await importData(inputs, opts);
|
|
605
|
+
});
|
|
606
|
+
// ─── upload ───────────────────────────────────────────────────────────────────
|
|
607
|
+
// Store a real file (arbitrary bytes) on the pod — the door an AI/CLI needs to
|
|
608
|
+
// persist an actual file, not just text. POSTs multipart to /api/hub/files,
|
|
609
|
+
// which mints a `file` entity for the bytes.
|
|
610
|
+
program
|
|
611
|
+
.command("upload <path>")
|
|
612
|
+
.description("Upload a file (≤10MB) to the pod as a file entity")
|
|
613
|
+
.option("--workspace <id>", "Workspace to store the file in")
|
|
614
|
+
.option("--attach <entityId>", "After upload, link the document to this entity (references relation)")
|
|
615
|
+
.option("--title <title>", "Title for the created document")
|
|
616
|
+
.option("--open", "Open in the Synap desktop app after upload")
|
|
617
|
+
.option("--json", "Output as JSON")
|
|
618
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
619
|
+
.option("--api-key <key>", "API key override")
|
|
620
|
+
.addHelpText("after", `
|
|
621
|
+
Examples:
|
|
622
|
+
synap upload ./report.pdf
|
|
623
|
+
synap upload ./logo.png --title "Brand logo" --workspace <id>
|
|
624
|
+
synap upload ./spec.pdf --attach <entityId>
|
|
625
|
+
synap upload ./report.pdf --open
|
|
626
|
+
`)
|
|
627
|
+
.action(async (path, opts) => {
|
|
628
|
+
const { uploadFile } = await import("./commands/upload.js");
|
|
629
|
+
await uploadFile(path, opts);
|
|
630
|
+
});
|
|
307
631
|
program
|
|
308
632
|
.command("subscribe")
|
|
309
633
|
.description("Stream pod events as NDJSON (long-poll)")
|
|
@@ -346,6 +670,8 @@ program
|
|
|
346
670
|
.option("--json", "Output as JSON (default: human-readable)")
|
|
347
671
|
.option("--profiles", "Show only profiles (use with --json for machine-readable schema)")
|
|
348
672
|
.option("--commands", "Show only the command tree")
|
|
673
|
+
.option("--summary", "List profile kinds without property schemas")
|
|
674
|
+
.option("--profile-slugs <slugs>", "Comma-separated profile slugs to load in full")
|
|
349
675
|
.option("--workspace <id>", "Workspace to query (defaults to active workspace)")
|
|
350
676
|
.action(async (opts) => {
|
|
351
677
|
const { discover } = await import("./commands/discover.js");
|
|
@@ -368,6 +694,18 @@ workspace
|
|
|
368
694
|
const { provisionAgentWorkspace } = await import("./commands/knowledge.js");
|
|
369
695
|
await provisionAgentWorkspace({ ...opts, agentUserId: opts.agentUserId });
|
|
370
696
|
});
|
|
697
|
+
workspace
|
|
698
|
+
.command("purge <target>")
|
|
699
|
+
.description("HARD teardown: delete a workspace + all its entities and blobs (owner-only, irreversible)")
|
|
700
|
+
.option("--confirm <name>", "Confirm non-interactively by passing the exact workspace name")
|
|
701
|
+
.option("--yes", "Skip the interactive name prompt (uses the resolved name)")
|
|
702
|
+
.option("--json", "Output raw JSON")
|
|
703
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
704
|
+
.option("--api-key <key>", "API key override")
|
|
705
|
+
.action(async (target, opts) => {
|
|
706
|
+
const { workspacePurge } = await import("./commands/purge.js");
|
|
707
|
+
await workspacePurge(target, opts);
|
|
708
|
+
});
|
|
371
709
|
// ─── list ─────────────────────────────────────────────────────────────────────
|
|
372
710
|
const list = program
|
|
373
711
|
.command("list")
|
|
@@ -408,6 +746,7 @@ list
|
|
|
408
746
|
.description("List entities on the pod")
|
|
409
747
|
.option("--workspace <id>", "Scope to a workspace (omit for pod-wide)")
|
|
410
748
|
.option("--profile <slug>", "Filter by profile slug (e.g. person, task, note)")
|
|
749
|
+
.option("--role <slug>", "Filter to entities carrying this role (e.g. client, partner)")
|
|
411
750
|
.option("--limit <n>", "Max results", "50")
|
|
412
751
|
.option("--json", "Output as JSON")
|
|
413
752
|
.option("--pod-url <url>", "Pod URL override")
|
|
@@ -428,6 +767,51 @@ program
|
|
|
428
767
|
const { showEntity } = await import("./commands/data-extra.js");
|
|
429
768
|
await showEntity(id, opts);
|
|
430
769
|
});
|
|
770
|
+
// ─── facet ────────────────────────────────────────────────────────────────────
|
|
771
|
+
// Roles — one identity, many roles. A role-profile (client, partner, contact…)
|
|
772
|
+
// attached to an existing entity, never a second entity. Governed writes: an
|
|
773
|
+
// attach/detach may come back "proposed for review" instead of applying live.
|
|
774
|
+
const facet = program
|
|
775
|
+
.command("facet")
|
|
776
|
+
.description("Manage roles attached to an entity (client, partner, contact, …)");
|
|
777
|
+
facet
|
|
778
|
+
.command("attach <entityId> <roleSlug>")
|
|
779
|
+
.description("Attach a role to an entity")
|
|
780
|
+
.option("--property <kv>", "Role property as key=value (repeatable)", collect, [])
|
|
781
|
+
.option("--workspace <id>", "Role's lens (defaults to the active workspace)")
|
|
782
|
+
.option("--json", "Output as JSON")
|
|
783
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
784
|
+
.option("--api-key <key>", "API key override")
|
|
785
|
+
.action(async (entityId, roleSlug, opts) => {
|
|
786
|
+
const { attachFacet } = await import("./commands/facet.js");
|
|
787
|
+
await attachFacet(entityId, roleSlug, opts);
|
|
788
|
+
});
|
|
789
|
+
facet
|
|
790
|
+
.command("list <entityId>")
|
|
791
|
+
.description("List the roles attached to an entity")
|
|
792
|
+
.option("--json", "Output as JSON")
|
|
793
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
794
|
+
.option("--api-key <key>", "API key override")
|
|
795
|
+
.action(async (entityId, opts) => {
|
|
796
|
+
const { listFacets } = await import("./commands/facet.js");
|
|
797
|
+
await listFacets(entityId, opts);
|
|
798
|
+
});
|
|
799
|
+
facet
|
|
800
|
+
.command("detach [facetId]")
|
|
801
|
+
.description("Detach a role — pass the facet id, or --entity <id> --role <slug>")
|
|
802
|
+
.option("--entity <id>", "Entity id (with --role, resolves the facet to detach)")
|
|
803
|
+
.option("--role <slug>", "Role slug (with --entity)")
|
|
804
|
+
.option("--json", "Output as JSON")
|
|
805
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
806
|
+
.option("--api-key <key>", "API key override")
|
|
807
|
+
.action(async (facetId, opts) => {
|
|
808
|
+
if (!facetId && !(opts.entity && opts.role)) {
|
|
809
|
+
console.error("Provide a facet id, or both --entity <id> and --role <slug>.");
|
|
810
|
+
process.exit(1);
|
|
811
|
+
}
|
|
812
|
+
const { detachFacet } = await import("./commands/facet.js");
|
|
813
|
+
await detachFacet(facetId ?? "", opts);
|
|
814
|
+
});
|
|
431
815
|
// ─── proposals ────────────────────────────────────────────────────────────────
|
|
432
816
|
// Governance inbox — pending proposals attributed to this agent.
|
|
433
817
|
const proposals = program
|
|
@@ -603,6 +987,36 @@ skillCmd
|
|
|
603
987
|
const { getSkill } = await import("./commands/skills-commands.js");
|
|
604
988
|
await getSkill(slug, opts);
|
|
605
989
|
});
|
|
990
|
+
skillCmd
|
|
991
|
+
.command("add <source>")
|
|
992
|
+
.description("Add skill(s) to your pod from: bundled · a local path · ~/.claude/skills/ · owner/repo · a git URL")
|
|
993
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
994
|
+
.option("--api-key <key>", "API key override")
|
|
995
|
+
.action(async (source, opts) => {
|
|
996
|
+
const { addSkill } = await import("./commands/skill-manage.js");
|
|
997
|
+
await addSkill(source, opts);
|
|
998
|
+
});
|
|
999
|
+
skillCmd
|
|
1000
|
+
.command("list")
|
|
1001
|
+
.alias("ls")
|
|
1002
|
+
.description("List the instruction skills installed on your pod")
|
|
1003
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1004
|
+
.option("--api-key <key>", "API key override")
|
|
1005
|
+
.option("--debug", "Show resolved credentials")
|
|
1006
|
+
.action(async (opts) => {
|
|
1007
|
+
const { listSkills } = await import("./commands/skill-manage.js");
|
|
1008
|
+
await listSkills(opts);
|
|
1009
|
+
});
|
|
1010
|
+
skillCmd
|
|
1011
|
+
.command("remove <slug>")
|
|
1012
|
+
.alias("rm")
|
|
1013
|
+
.description("Remove a skill from your pod by slug")
|
|
1014
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1015
|
+
.option("--api-key <key>", "API key override")
|
|
1016
|
+
.action(async (slug, opts) => {
|
|
1017
|
+
const { removeSkill } = await import("./commands/skill-manage.js");
|
|
1018
|
+
await removeSkill(slug, opts);
|
|
1019
|
+
});
|
|
606
1020
|
skillCmd
|
|
607
1021
|
.command("sync")
|
|
608
1022
|
.description("Bulk-import local skills from ~/.claude/skills/ into the pod")
|
|
@@ -630,8 +1044,9 @@ skillCmd
|
|
|
630
1044
|
// Paginated entity list — cleaner than `list entities`.
|
|
631
1045
|
program
|
|
632
1046
|
.command("browse [profile]")
|
|
633
|
-
.description("Browse entities in the active workspace, optionally filtered by profile type")
|
|
1047
|
+
.description("Browse entities in the active workspace, optionally filtered by profile type or role")
|
|
634
1048
|
.option("--workspace <id>", "Scope to a specific workspace")
|
|
1049
|
+
.option("--role <slug>", "Filter to entities carrying this role (e.g. client, partner)")
|
|
635
1050
|
.option("--limit <n>", "Max results", "20")
|
|
636
1051
|
.option("--json", "Output as JSON")
|
|
637
1052
|
.option("--pod-url <url>", "Pod URL override")
|
|
@@ -795,6 +1210,35 @@ agents
|
|
|
795
1210
|
const agent = program
|
|
796
1211
|
.command("agent")
|
|
797
1212
|
.description("Run autonomous agent loops against the IS, or schedule recurring goals");
|
|
1213
|
+
agent
|
|
1214
|
+
.command("ask <message>")
|
|
1215
|
+
.description("Send one message to the workspace's deployed agent and print its reply (multi-turn: reuses one thread)")
|
|
1216
|
+
.option("--workspace <id|name>", "Workspace to talk to (uses active workspace/lens if omitted)")
|
|
1217
|
+
.option("--thread <id>", "Target an existing thread/channel id instead of the default CLI chat thread")
|
|
1218
|
+
.option("--new", "Start a fresh thread instead of continuing the persistent CLI chat thread")
|
|
1219
|
+
.option("--agent-type <type>", "Requested agent type hint (backend currently routes to the orchestrator)")
|
|
1220
|
+
.option("--timeout <seconds>", "How long to wait for the agent's reply (default: 90)")
|
|
1221
|
+
.option("--json", "Machine-readable output { ok, reply, threadId, workspaceId }")
|
|
1222
|
+
.option("--pod-url <url>", "Override pod URL")
|
|
1223
|
+
.option("--api-key <key>", "Override API key")
|
|
1224
|
+
.action(async (message, opts) => {
|
|
1225
|
+
const { agentAsk } = await import("./commands/agent-chat.js");
|
|
1226
|
+
await agentAsk({ ...opts, message });
|
|
1227
|
+
});
|
|
1228
|
+
agent
|
|
1229
|
+
.command("chat")
|
|
1230
|
+
.description("Interactive REPL conversation with the workspace's deployed agent")
|
|
1231
|
+
.option("--workspace <id|name>", "Workspace to talk to (uses active workspace/lens if omitted)")
|
|
1232
|
+
.option("--thread <id>", "Target an existing thread/channel id instead of the default CLI chat thread")
|
|
1233
|
+
.option("--new", "Start a fresh thread instead of continuing the persistent CLI chat thread")
|
|
1234
|
+
.option("--agent-type <type>", "Requested agent type hint (backend currently routes to the orchestrator)")
|
|
1235
|
+
.option("--timeout <seconds>", "How long to wait for each reply (default: 90)")
|
|
1236
|
+
.option("--pod-url <url>", "Override pod URL")
|
|
1237
|
+
.option("--api-key <key>", "Override API key")
|
|
1238
|
+
.action(async (opts) => {
|
|
1239
|
+
const { agentChat } = await import("./commands/agent-chat.js");
|
|
1240
|
+
await agentChat(opts);
|
|
1241
|
+
});
|
|
798
1242
|
agent
|
|
799
1243
|
.command("run")
|
|
800
1244
|
.description("Run an autonomous agent toward a goal using the Intelligence Service")
|
|
@@ -926,6 +1370,32 @@ program
|
|
|
926
1370
|
const { graphTraverse } = await import("./commands/graph.js");
|
|
927
1371
|
await graphTraverse(opts);
|
|
928
1372
|
});
|
|
1373
|
+
// ─── centrality ────────────────────────────────────────────────────────────────
|
|
1374
|
+
// Window onto the Phase-3 PageRank centrality signal (entity_centrality):
|
|
1375
|
+
// see if it has populated, and trigger a recompute on demand.
|
|
1376
|
+
const centrality = program
|
|
1377
|
+
.command("centrality")
|
|
1378
|
+
.description("Inspect PageRank centrality (entity_centrality) and trigger a recompute");
|
|
1379
|
+
centrality
|
|
1380
|
+
.command("status", { isDefault: true })
|
|
1381
|
+
.description("Show whether PageRank centrality has populated + the top central entities")
|
|
1382
|
+
.option("--json", "Output as JSON")
|
|
1383
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1384
|
+
.option("--api-key <key>", "API key override")
|
|
1385
|
+
.action(async (opts) => {
|
|
1386
|
+
const { centralityStatus } = await import("./commands/centrality.js");
|
|
1387
|
+
await centralityStatus(opts);
|
|
1388
|
+
});
|
|
1389
|
+
centrality
|
|
1390
|
+
.command("recompute")
|
|
1391
|
+
.description("Enqueue a PageRank centrality recompute (runs in the background)")
|
|
1392
|
+
.option("--json", "Output as JSON")
|
|
1393
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1394
|
+
.option("--api-key <key>", "API key override")
|
|
1395
|
+
.action(async (opts) => {
|
|
1396
|
+
const { centralityRecompute } = await import("./commands/centrality.js");
|
|
1397
|
+
await centralityRecompute(opts);
|
|
1398
|
+
});
|
|
929
1399
|
// ─── events ───────────────────────────────────────────────────────────────────
|
|
930
1400
|
program
|
|
931
1401
|
.command("events")
|
|
@@ -999,15 +1469,24 @@ program
|
|
|
999
1469
|
});
|
|
1000
1470
|
// ─── open ─────────────────────────────────────────────────────────────────────
|
|
1001
1471
|
program
|
|
1002
|
-
.command("open <kind>
|
|
1003
|
-
.description("Open
|
|
1004
|
-
.action(async (
|
|
1005
|
-
if (
|
|
1006
|
-
|
|
1007
|
-
|
|
1472
|
+
.command("open <kind-or-id> [id]")
|
|
1473
|
+
.description("Open in the Synap desktop app. Use: open <kind> <id> or open <id> (auto-resolves type)")
|
|
1474
|
+
.action(async (kindOrId, id) => {
|
|
1475
|
+
if (id) {
|
|
1476
|
+
// open entity|view|cell|document|proposal <id>
|
|
1477
|
+
const validKinds = ["entity", "view", "cell", "document", "proposal"];
|
|
1478
|
+
if (!validKinds.includes(kindOrId)) {
|
|
1479
|
+
console.error(`Unknown kind: "${kindOrId}". Use: ${validKinds.join(" | ")}`);
|
|
1480
|
+
process.exit(1);
|
|
1481
|
+
}
|
|
1482
|
+
const { openInBrowser } = await import("./commands/open.js");
|
|
1483
|
+
await openInBrowser({ kind: kindOrId, id });
|
|
1484
|
+
}
|
|
1485
|
+
else {
|
|
1486
|
+
// open <id> — resolve type automatically
|
|
1487
|
+
const { resolveAndOpen } = await import("./commands/open.js");
|
|
1488
|
+
await resolveAndOpen(kindOrId);
|
|
1008
1489
|
}
|
|
1009
|
-
const { openInBrowser } = await import("./commands/open.js");
|
|
1010
|
-
await openInBrowser({ kind: kind, id });
|
|
1011
1490
|
});
|
|
1012
1491
|
// ─── doc ──────────────────────────────────────────────────────────────────────
|
|
1013
1492
|
const doc = program
|
|
@@ -1054,6 +1533,23 @@ Examples:
|
|
|
1054
1533
|
const { docUpdate } = await import("./commands/doc.js");
|
|
1055
1534
|
await docUpdate(documentId, opts);
|
|
1056
1535
|
});
|
|
1536
|
+
doc
|
|
1537
|
+
.command("reference <url>")
|
|
1538
|
+
.description("Create an external reference document (points at a URL — no bytes stored)")
|
|
1539
|
+
.requiredOption("--title <title>", "Document title")
|
|
1540
|
+
.option("--workspace <id>", "Workspace to create the reference in")
|
|
1541
|
+
.option("--open", "Open in the Synap desktop app after creation")
|
|
1542
|
+
.option("--json", "JSON output")
|
|
1543
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1544
|
+
.option("--api-key <key>", "API key override")
|
|
1545
|
+
.addHelpText("after", `
|
|
1546
|
+
Examples:
|
|
1547
|
+
synap doc reference https://example.com/spec --title "Vendor spec"
|
|
1548
|
+
`)
|
|
1549
|
+
.action(async (url, opts) => {
|
|
1550
|
+
const { docReference } = await import("./commands/doc.js");
|
|
1551
|
+
await docReference(url, opts);
|
|
1552
|
+
});
|
|
1057
1553
|
// ─── cell ─────────────────────────────────────────────────────────────────────
|
|
1058
1554
|
const cell = program
|
|
1059
1555
|
.command("cell")
|
|
@@ -1133,47 +1629,358 @@ program
|
|
|
1133
1629
|
.option("--pod-url <url>", "Pod URL override")
|
|
1134
1630
|
.option("--api-key <key>", "API key override")
|
|
1135
1631
|
.action(async (service, opts) => {
|
|
1136
|
-
const {
|
|
1137
|
-
await
|
|
1138
|
-
});
|
|
1139
|
-
// ───
|
|
1140
|
-
const
|
|
1141
|
-
.command("
|
|
1142
|
-
.description("
|
|
1143
|
-
|
|
1632
|
+
const { toolsConnect } = await import("./commands/tools.js");
|
|
1633
|
+
await toolsConnect(service, opts);
|
|
1634
|
+
});
|
|
1635
|
+
// ─── tools ──────────────────────────────────────────────────────────────────
|
|
1636
|
+
const tools = program
|
|
1637
|
+
.command("tools")
|
|
1638
|
+
.description("Add and manage external service tools and their credentials");
|
|
1639
|
+
tools
|
|
1144
1640
|
.command("list")
|
|
1145
|
-
.description("List available
|
|
1641
|
+
.description("List available tools and their connection status")
|
|
1146
1642
|
.option("--json", "Output as JSON")
|
|
1147
1643
|
.option("--workspace <id>", "Workspace context")
|
|
1148
1644
|
.action(async (opts) => {
|
|
1149
|
-
const {
|
|
1150
|
-
await
|
|
1645
|
+
const { toolsList } = await import("./commands/tools.js");
|
|
1646
|
+
await toolsList(opts);
|
|
1647
|
+
});
|
|
1648
|
+
tools
|
|
1649
|
+
.command("connect <service>")
|
|
1650
|
+
.description("Connect a credential to a tool (via Nango OAuth or vault)")
|
|
1651
|
+
.option("--workspace <id>", "Workspace context")
|
|
1652
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1653
|
+
.option("--api-key <key>", "API key override")
|
|
1654
|
+
.action(async (service, opts) => {
|
|
1655
|
+
const { toolsConnect } = await import("./commands/tools.js");
|
|
1656
|
+
await toolsConnect(service, opts);
|
|
1151
1657
|
});
|
|
1152
|
-
|
|
1658
|
+
tools
|
|
1153
1659
|
.command("sync <provider>")
|
|
1154
|
-
.description("Trigger a manual sync for a connected
|
|
1660
|
+
.description("Trigger a manual sync for a connected tool")
|
|
1155
1661
|
.option("--workspace <id>", "Workspace context")
|
|
1156
1662
|
.action(async (provider, opts) => {
|
|
1157
|
-
const {
|
|
1158
|
-
await
|
|
1663
|
+
const { toolsSync } = await import("./commands/tools.js");
|
|
1664
|
+
await toolsSync(provider, opts);
|
|
1159
1665
|
});
|
|
1160
|
-
|
|
1666
|
+
tools
|
|
1161
1667
|
.command("disconnect <provider>")
|
|
1162
|
-
.description("Revoke a
|
|
1668
|
+
.description("Revoke a tool's connection")
|
|
1163
1669
|
.option("--workspace <id>", "Workspace context")
|
|
1164
1670
|
.option("--force", "Skip confirmation")
|
|
1165
1671
|
.action(async (provider, opts) => {
|
|
1166
|
-
const {
|
|
1167
|
-
await
|
|
1672
|
+
const { toolsDisconnect } = await import("./commands/tools.js");
|
|
1673
|
+
await toolsDisconnect(provider, opts);
|
|
1168
1674
|
});
|
|
1169
|
-
|
|
1675
|
+
tools
|
|
1170
1676
|
.command("schema")
|
|
1171
|
-
.description("Fetch
|
|
1172
|
-
.option("--write-context [path]", "Write to .claude/
|
|
1677
|
+
.description("Fetch tool schema and supported providers (AI context)")
|
|
1678
|
+
.option("--write-context [path]", "Write to .claude/TOOLS_CONTEXT.md")
|
|
1173
1679
|
.option("--json", "Output raw JSON instead of formatted markdown")
|
|
1174
1680
|
.action(async (opts) => {
|
|
1175
|
-
const {
|
|
1176
|
-
await
|
|
1681
|
+
const { toolsSchema } = await import("./commands/tools.js");
|
|
1682
|
+
await toolsSchema(opts);
|
|
1683
|
+
});
|
|
1684
|
+
// ─── pod — unified pod-configuration view ─────────────────────────────────────
|
|
1685
|
+
// `market installed` shows what packages are installed; `pod` answers the
|
|
1686
|
+
// bigger question: what does the WHOLE pod look like — every workspace with
|
|
1687
|
+
// its provenance (marketplace/composed/ad-hoc/orphan), pod-wide vs
|
|
1688
|
+
// per-workspace capabilities/automations/playbooks, and the give/need feed
|
|
1689
|
+
// links between workspaces. Read surface for GET /api/hub/pod/config.
|
|
1690
|
+
const podCmd = program
|
|
1691
|
+
.command("pod")
|
|
1692
|
+
.description("Show the whole configured pod — workspaces (with provenance), capabilities/automations/playbooks, and feed links")
|
|
1693
|
+
.option("--json", "Output the full structured graph as JSON")
|
|
1694
|
+
.option("--orphans", "Only show orphan/ad-hoc workspaces and their template-match suggestions")
|
|
1695
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1696
|
+
.option("--api-key <key>", "API key override")
|
|
1697
|
+
.action(async (opts) => {
|
|
1698
|
+
const { pod } = await import("./commands/pod.js");
|
|
1699
|
+
await pod(opts);
|
|
1700
|
+
});
|
|
1701
|
+
podCmd
|
|
1702
|
+
.command("adopt <workspaceNameOrId>")
|
|
1703
|
+
.description("Link an orphan/ad-hoc workspace (by name or id) to a matching template — makes it version-tracked")
|
|
1704
|
+
.requiredOption("--template <slug>", "The template slug to adopt this workspace into")
|
|
1705
|
+
.option("--json", "Output as JSON")
|
|
1706
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1707
|
+
.option("--api-key <key>", "API key override")
|
|
1708
|
+
.action(async (workspaceNameOrId, _opts, cmd) => {
|
|
1709
|
+
// `--json` collides with the parent `pod` command's own `--json` — same
|
|
1710
|
+
// gap `market install` has (see its comment). Merge across the chain.
|
|
1711
|
+
const opts = cmd.optsWithGlobals();
|
|
1712
|
+
const { podAdopt } = await import("./commands/pod.js");
|
|
1713
|
+
await podAdopt(workspaceNameOrId, opts);
|
|
1714
|
+
});
|
|
1715
|
+
// ─── market — discover + install ANY package type ────────────────────────────
|
|
1716
|
+
// launch is workspace-first (bundled, offline); market reaches every CP package
|
|
1717
|
+
// type (capability/skill/workflow/view/cell/workspace), public or private.
|
|
1718
|
+
const market = program
|
|
1719
|
+
.command("market")
|
|
1720
|
+
.description("Browse + install packages (workspaces, capabilities, skills, workflows, views, cells) into a project")
|
|
1721
|
+
.option("--list", "List and exit (the default action)")
|
|
1722
|
+
.option("--search <query>", "Filter by name/description/slug")
|
|
1723
|
+
.option("--type <type>", "Filter by package type (workspace|capability|skill|workflow|view|cell)")
|
|
1724
|
+
.option("--json", "Output as JSON")
|
|
1725
|
+
.action(async (opts) => {
|
|
1726
|
+
const { market: marketBrowse } = await import("./commands/market.js");
|
|
1727
|
+
await marketBrowse(opts);
|
|
1728
|
+
});
|
|
1729
|
+
market
|
|
1730
|
+
.command("install <slug>")
|
|
1731
|
+
.description("Install a package by slug into a project — workspaces install now; other types route you to the right surface")
|
|
1732
|
+
.option("--project <id>", "Optionally tag the seeded entities to a project (installs are pod-wide by default)")
|
|
1733
|
+
.option("--onto <workspaceId>", "Reconcile this template ONTO an existing workspace (additive) instead of creating a new one")
|
|
1734
|
+
.option("--dry-run", "Preview the create path write-free — report would-create / reuse / conflicts, install nothing")
|
|
1735
|
+
.option("--timeout <seconds>", "How long to wait for the apply to finish (default: 120)")
|
|
1736
|
+
.option("--json", "Output as JSON")
|
|
1737
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1738
|
+
.option("--api-key <key>", "API key override")
|
|
1739
|
+
.action(async (slug, _opts, cmd) => {
|
|
1740
|
+
// `--json` collides with the parent `market` command's own `--json` —
|
|
1741
|
+
// commander then attributes the flag's VALUE to the parent's
|
|
1742
|
+
// `_optionValues`, leaving this action's own `opts` argument `{}` for it
|
|
1743
|
+
// (a real, pre-existing gap: `market install <slug> --json` silently fell
|
|
1744
|
+
// back to human output). `optsWithGlobals()` walks the whole command
|
|
1745
|
+
// chain and merges regardless of which level actually captured the flag.
|
|
1746
|
+
const opts = cmd.optsWithGlobals();
|
|
1747
|
+
const { marketInstall } = await import("./commands/market.js");
|
|
1748
|
+
await marketInstall(slug, opts);
|
|
1749
|
+
});
|
|
1750
|
+
market
|
|
1751
|
+
.command("update [slugs...]")
|
|
1752
|
+
.description("Check installed packages for drift against the catalog, and re-apply the ones that are stale (all with --yes, specific ones with explicit slugs)")
|
|
1753
|
+
.option("--yes", "Apply every available update without prompting (no slugs required)")
|
|
1754
|
+
.option("--dry-run", "Force the preview path — never apply, even with --yes")
|
|
1755
|
+
.option("--timeout <seconds>", "How long to wait for each package's apply to finish (default: 120)")
|
|
1756
|
+
.option("--json", "Output as JSON")
|
|
1757
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1758
|
+
.option("--api-key <key>", "API key override")
|
|
1759
|
+
.action(async (slugs, _opts, cmd) => {
|
|
1760
|
+
// Same parent/child `--json` collision as `market install` — see its comment.
|
|
1761
|
+
const opts = cmd.optsWithGlobals();
|
|
1762
|
+
const { marketUpdate } = await import("./commands/market.js");
|
|
1763
|
+
await marketUpdate(slugs && slugs.length > 0 ? slugs : undefined, opts);
|
|
1764
|
+
});
|
|
1765
|
+
market
|
|
1766
|
+
.command("installed")
|
|
1767
|
+
.description("List packages installed on this pod — a pure read, no writes (pairs with 'market update' to check drift)")
|
|
1768
|
+
.option("--outdated", "Only show packages with an update available")
|
|
1769
|
+
.option("--tree", "Show the composition graph — package → templates → resulting workspaces, marking shared nodes")
|
|
1770
|
+
.option("--layers", "Show the composition graph as a flat DAG — one row per slug, bedrock-first, with true fan-in counts")
|
|
1771
|
+
.option("--json", "Output as JSON")
|
|
1772
|
+
.action(async (_opts, cmd) => {
|
|
1773
|
+
// Same parent/child `--json` collision as `market install` — see its comment.
|
|
1774
|
+
const opts = cmd.optsWithGlobals();
|
|
1775
|
+
const { marketInstalled } = await import("./commands/market.js");
|
|
1776
|
+
await marketInstalled(opts);
|
|
1777
|
+
});
|
|
1778
|
+
// ── Authoring loop: scaffold → validate → publish → unpublish ────────────────
|
|
1779
|
+
market
|
|
1780
|
+
.command("scaffold <slug>")
|
|
1781
|
+
.description("Write a minimal valid <slug>.template.yaml to edit in place (refuses to overwrite)")
|
|
1782
|
+
.option("--json", "Output as JSON")
|
|
1783
|
+
.action(async (slug, _opts, cmd) => {
|
|
1784
|
+
// Same parent/child `--json` collision as `market install` — see its comment.
|
|
1785
|
+
const opts = cmd.optsWithGlobals();
|
|
1786
|
+
const { marketScaffold } = await import("./commands/market-authoring.js");
|
|
1787
|
+
await marketScaffold(slug, opts);
|
|
1788
|
+
});
|
|
1789
|
+
market
|
|
1790
|
+
.command("validate <file>")
|
|
1791
|
+
.description("Validate a local template file against the shared template validator — fast author feedback")
|
|
1792
|
+
.option("--json", "Output the validator result as JSON")
|
|
1793
|
+
.action(async (file, _opts, cmd) => {
|
|
1794
|
+
// Same parent/child `--json` collision as `market install` — see its comment.
|
|
1795
|
+
const opts = cmd.optsWithGlobals();
|
|
1796
|
+
const { marketValidate } = await import("./commands/market-authoring.js");
|
|
1797
|
+
await marketValidate(file, opts);
|
|
1798
|
+
});
|
|
1799
|
+
market
|
|
1800
|
+
.command("publish [file]")
|
|
1801
|
+
.description("Validate then publish a template to the marketplace (private by default) — pass a file, or --from-workspace <id>")
|
|
1802
|
+
.option("--public", "Publish as PUBLIC (default is private)")
|
|
1803
|
+
.option("--private", "Publish as private (the default — stated explicitly)")
|
|
1804
|
+
.option("--from-workspace <id>", "Serialize a live workspace into a template and publish it (instead of a file)")
|
|
1805
|
+
.option("--json", "Output as JSON")
|
|
1806
|
+
.option("--pod-url <url>", "Pod URL override (for --from-workspace)")
|
|
1807
|
+
.option("--api-key <key>", "API key override (for --from-workspace)")
|
|
1808
|
+
.action(async (file, _opts, cmd) => {
|
|
1809
|
+
// Same parent/child `--json` collision as `market install` — see its comment.
|
|
1810
|
+
const opts = cmd.optsWithGlobals();
|
|
1811
|
+
const { marketPublish } = await import("./commands/market-authoring.js");
|
|
1812
|
+
await marketPublish(file, opts);
|
|
1813
|
+
});
|
|
1814
|
+
market
|
|
1815
|
+
.command("unpublish <slug>")
|
|
1816
|
+
.description("Flip a published package back to private (owner only)")
|
|
1817
|
+
.option("--json", "Output as JSON")
|
|
1818
|
+
.action(async (slug, _opts, cmd) => {
|
|
1819
|
+
// Same parent/child `--json` collision as `market install` — see its comment.
|
|
1820
|
+
const opts = cmd.optsWithGlobals();
|
|
1821
|
+
const { marketUnpublish } = await import("./commands/market-authoring.js");
|
|
1822
|
+
await marketUnpublish(slug, opts);
|
|
1823
|
+
});
|
|
1824
|
+
// ─── capability ───────────────────────────────────────────────────────────────
|
|
1825
|
+
const capability = program
|
|
1826
|
+
.command("capability")
|
|
1827
|
+
.alias("cap")
|
|
1828
|
+
.description("The one capability-first root: list, add, enable, connect, show, run a capability pack");
|
|
1829
|
+
capability
|
|
1830
|
+
.command("list")
|
|
1831
|
+
.description("List capabilities — one row per pack, with status, connection, and verbs")
|
|
1832
|
+
.option("--json", "Output as JSON")
|
|
1833
|
+
.option("--workspace <id>", "Workspace context")
|
|
1834
|
+
.action(async (opts) => {
|
|
1835
|
+
const { capabilityList } = await import("./commands/capability.js");
|
|
1836
|
+
await capabilityList(opts);
|
|
1837
|
+
});
|
|
1838
|
+
capability
|
|
1839
|
+
.command("add [name]")
|
|
1840
|
+
.description("Install a capability from the catalog — omit the name to pick from a list")
|
|
1841
|
+
.option("--workspace <id>", "Workspace context")
|
|
1842
|
+
.action(async (name, opts) => {
|
|
1843
|
+
const { capabilityAdd } = await import("./commands/capability.js");
|
|
1844
|
+
await capabilityAdd(name, opts);
|
|
1845
|
+
});
|
|
1846
|
+
capability
|
|
1847
|
+
.command("create [file]")
|
|
1848
|
+
.description("Create a capability from a JSON definition (file path, or pipe JSON via stdin)")
|
|
1849
|
+
.option("--workspace <id>", "Workspace context")
|
|
1850
|
+
.action(async (file, opts) => {
|
|
1851
|
+
const { capabilityCreate } = await import("./commands/capability.js");
|
|
1852
|
+
await capabilityCreate(file, opts);
|
|
1853
|
+
});
|
|
1854
|
+
capability
|
|
1855
|
+
.command("rm <ids...>")
|
|
1856
|
+
.alias("remove")
|
|
1857
|
+
.description("Remove capability container(s) by id or name — member tools/skills untouched")
|
|
1858
|
+
.option("--workspace <id>", "Workspace context")
|
|
1859
|
+
.option("--force", "Skip the confirmation prompt")
|
|
1860
|
+
.action(async (ids, opts) => {
|
|
1861
|
+
const { capabilityRemove } = await import("./commands/capability.js");
|
|
1862
|
+
await capabilityRemove(ids, opts);
|
|
1863
|
+
});
|
|
1864
|
+
capability
|
|
1865
|
+
.command("enable [name]")
|
|
1866
|
+
.description("Turn on a capability — omit the name to pick from a list; ensures its connection, then pick which verbs it can do")
|
|
1867
|
+
.option("--workspace <id>", "Workspace context")
|
|
1868
|
+
.action(async (name, opts) => {
|
|
1869
|
+
const { capabilityEnable } = await import("./commands/capability.js");
|
|
1870
|
+
await capabilityEnable(name, opts);
|
|
1871
|
+
});
|
|
1872
|
+
capability
|
|
1873
|
+
.command("connect [name]")
|
|
1874
|
+
.description("Connect a service — omit the name to pick from connectable services")
|
|
1875
|
+
.option("--workspace <id>", "Workspace context")
|
|
1876
|
+
.action(async (name, opts) => {
|
|
1877
|
+
const { capabilityConnect } = await import("./commands/capability.js");
|
|
1878
|
+
await capabilityConnect(name, opts);
|
|
1879
|
+
});
|
|
1880
|
+
capability
|
|
1881
|
+
.command("disconnect <name>")
|
|
1882
|
+
.description("Disconnect a capability's service — accepts a capability name or a provider id")
|
|
1883
|
+
.option("--workspace <id>", "Workspace context")
|
|
1884
|
+
.option("--force", "Skip confirmation")
|
|
1885
|
+
.action(async (name, opts) => {
|
|
1886
|
+
const { capabilityDisconnect } = await import("./commands/capability.js");
|
|
1887
|
+
await capabilityDisconnect(name, opts);
|
|
1888
|
+
});
|
|
1889
|
+
capability
|
|
1890
|
+
.command("show <name>")
|
|
1891
|
+
.description("Show one capability's full detail: status, connection, verbs, next action")
|
|
1892
|
+
.option("--json", "Output as JSON")
|
|
1893
|
+
.option("--workspace <id>", "Workspace context")
|
|
1894
|
+
.action(async (name, opts) => {
|
|
1895
|
+
const { capabilityShow } = await import("./commands/capability.js");
|
|
1896
|
+
await capabilityShow(name, opts);
|
|
1897
|
+
});
|
|
1898
|
+
capability
|
|
1899
|
+
.command("run <verb> [params...]")
|
|
1900
|
+
.description("Launch a verb — pass inputs as `--key value` flags")
|
|
1901
|
+
.option("--workspace <id>", "Workspace context")
|
|
1902
|
+
.option("--connection <id>", "Run against a specific stored connection id")
|
|
1903
|
+
.option("--for <objId>", "Run against the connection bound to this context object id")
|
|
1904
|
+
.allowUnknownOption()
|
|
1905
|
+
.allowExcessArguments()
|
|
1906
|
+
.action(async (verb, params, opts) => {
|
|
1907
|
+
const { capabilityRun } = await import("./commands/capability.js");
|
|
1908
|
+
await capabilityRun(verb, params, opts);
|
|
1909
|
+
});
|
|
1910
|
+
capability
|
|
1911
|
+
.command("test <verb>")
|
|
1912
|
+
.description("Dry-run a verb (preview side effects without executing)")
|
|
1913
|
+
.option("--workspace <id>", "Workspace context")
|
|
1914
|
+
.action(async (verb, opts) => {
|
|
1915
|
+
const { capabilityTest } = await import("./commands/capability.js");
|
|
1916
|
+
await capabilityTest(verb, opts);
|
|
1917
|
+
});
|
|
1918
|
+
// ─── cap connections ──────────────────────────────────────────────────────────
|
|
1919
|
+
// Manage a capability's stored connections (credentials / OAuth accounts /
|
|
1920
|
+
// context bindings). Nested under `cap` — distinct from the top-level
|
|
1921
|
+
// `synap connections`, which shows agent-surface → pod wiring.
|
|
1922
|
+
const capConnections = capability
|
|
1923
|
+
.command("connections")
|
|
1924
|
+
.alias("conn")
|
|
1925
|
+
.description("Manage a capability's connections: list, add, update, rm");
|
|
1926
|
+
capConnections
|
|
1927
|
+
.command("list <capability>")
|
|
1928
|
+
.description("List a capability's connections (label, kind, default, context, id)")
|
|
1929
|
+
.option("--workspace <id>", "Workspace context")
|
|
1930
|
+
.action(async (capability, opts) => {
|
|
1931
|
+
const { capabilityConnectionsList } = await import("./commands/cap-connections.js");
|
|
1932
|
+
await capabilityConnectionsList(capability, opts);
|
|
1933
|
+
});
|
|
1934
|
+
capConnections
|
|
1935
|
+
.command("add <capability>")
|
|
1936
|
+
.description("Add a connection — prompts for label + masked value unless provided as flags")
|
|
1937
|
+
.option("--label <label>", "Connection label")
|
|
1938
|
+
.option("--value <value>", "Secret / credential value (else prompted, masked)")
|
|
1939
|
+
.option("--context-type <type>", "Context type this connection binds to")
|
|
1940
|
+
.option("--context-id <id>", "Context object id this connection binds to")
|
|
1941
|
+
.option("--account-hint <hint>", "Human-readable account hint (e.g. an email)")
|
|
1942
|
+
.option("--default", "Mark this connection as the capability's default")
|
|
1943
|
+
.option("--workspace <id>", "Workspace context")
|
|
1944
|
+
.action(async (capability, opts) => {
|
|
1945
|
+
const { capabilityConnectionsAdd } = await import("./commands/cap-connections.js");
|
|
1946
|
+
await capabilityConnectionsAdd(capability, opts);
|
|
1947
|
+
});
|
|
1948
|
+
capConnections
|
|
1949
|
+
.command("update <capability> <connectionId>")
|
|
1950
|
+
.description("Update a connection's fields; --rotate (or --value) rotates its secret")
|
|
1951
|
+
.option("--label <label>", "New connection label")
|
|
1952
|
+
.option("--value <value>", "New secret / credential value")
|
|
1953
|
+
.option("--rotate", "Prompt (masked) for a new secret value")
|
|
1954
|
+
.option("--context-type <type>", "New context type")
|
|
1955
|
+
.option("--context-id <id>", "New context object id")
|
|
1956
|
+
.option("--account-hint <hint>", "New account hint")
|
|
1957
|
+
.option("--default", "Mark this connection as the capability's default")
|
|
1958
|
+
.option("--workspace <id>", "Workspace context")
|
|
1959
|
+
.action(async (capability, connectionId, opts) => {
|
|
1960
|
+
const { capabilityConnectionsUpdate } = await import("./commands/cap-connections.js");
|
|
1961
|
+
await capabilityConnectionsUpdate(capability, connectionId, opts);
|
|
1962
|
+
});
|
|
1963
|
+
capConnections
|
|
1964
|
+
.command("rm <capability> <connectionId>")
|
|
1965
|
+
.alias("remove")
|
|
1966
|
+
.description("Remove a connection by id (confirms first)")
|
|
1967
|
+
.option("--workspace <id>", "Workspace context")
|
|
1968
|
+
.action(async (capability, connectionId, opts) => {
|
|
1969
|
+
const { capabilityConnectionsRemove } = await import("./commands/cap-connections.js");
|
|
1970
|
+
await capabilityConnectionsRemove(capability, connectionId, opts);
|
|
1971
|
+
});
|
|
1972
|
+
// ─── raycast ──────────────────────────────────────────────────────────────────
|
|
1973
|
+
const raycast = program
|
|
1974
|
+
.command("raycast")
|
|
1975
|
+
.description("Generate Raycast Script Commands from your enabled capabilities");
|
|
1976
|
+
raycast
|
|
1977
|
+
.command("generate")
|
|
1978
|
+
.description("Emit a Raycast Script Command per enabled runnable verb")
|
|
1979
|
+
.option("--out <dir>", "Output directory (default: ~/.synap/raycast-commands)")
|
|
1980
|
+
.option("--workspace <id>", "Workspace context")
|
|
1981
|
+
.action(async (opts) => {
|
|
1982
|
+
const { raycastGenerate } = await import("./commands/raycast.js");
|
|
1983
|
+
await raycastGenerate(opts);
|
|
1177
1984
|
});
|
|
1178
1985
|
// ─── providers ───────────────────────────────────────────────────────────────
|
|
1179
1986
|
const providers = program
|
|
@@ -1210,5 +2017,32 @@ keys
|
|
|
1210
2017
|
const { keysRotate } = await import("./commands/keys.js");
|
|
1211
2018
|
await keysRotate({});
|
|
1212
2019
|
});
|
|
2020
|
+
// Resolve a global `--pod <name>` before commander parses (it isn't registered
|
|
2021
|
+
// per-command). Fails fast with a clear message on an unknown profile name.
|
|
2022
|
+
try {
|
|
2023
|
+
bootstrapPodOverride(process.argv);
|
|
2024
|
+
}
|
|
2025
|
+
catch (err) {
|
|
2026
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
2027
|
+
process.exit(1);
|
|
2028
|
+
}
|
|
2029
|
+
// Last-resort net. Commander does not await async .action() handlers, so a
|
|
2030
|
+
// command that throws without its own catch becomes an unhandled rejection and
|
|
2031
|
+
// Node dumps a raw stack trace with dist/ paths at the user — e.g.
|
|
2032
|
+
// `synap digest --workspace <inaccessible>` printed the HubError constructor
|
|
2033
|
+
// frame. Render it through the one door instead. Commands that already catch
|
|
2034
|
+
// and render are unaffected: this only fires when nothing else handled it.
|
|
2035
|
+
process.on("unhandledRejection", (err) => {
|
|
2036
|
+
void (async () => {
|
|
2037
|
+
try {
|
|
2038
|
+
const { renderHubError } = await import("./lib/hub-client.js");
|
|
2039
|
+
renderHubError(err);
|
|
2040
|
+
}
|
|
2041
|
+
catch {
|
|
2042
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
2043
|
+
}
|
|
2044
|
+
process.exit(1);
|
|
2045
|
+
})();
|
|
2046
|
+
});
|
|
1213
2047
|
program.parse();
|
|
1214
2048
|
//# sourceMappingURL=index.js.map
|