@synap-core/cli 1.6.1 → 1.8.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-run.d.ts +47 -0
- package/dist/commands/agent-run.js +302 -0
- package/dist/commands/agent-run.js.map +1 -0
- package/dist/commands/artifact.d.ts +26 -0
- package/dist/commands/artifact.js +76 -0
- package/dist/commands/artifact.js.map +1 -0
- package/dist/commands/automation.d.ts +47 -0
- package/dist/commands/automation.js +600 -0
- package/dist/commands/automation.js.map +1 -0
- package/dist/commands/cell.d.ts +55 -0
- package/dist/commands/cell.js +277 -0
- package/dist/commands/cell.js.map +1 -0
- package/dist/commands/connect.js +41 -7
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connections.js +0 -16
- package/dist/commands/connections.js.map +1 -1
- package/dist/commands/connectors.d.ts +31 -0
- package/dist/commands/connectors.js +276 -0
- package/dist/commands/connectors.js.map +1 -0
- package/dist/commands/context.d.ts +22 -0
- package/dist/commands/context.js +151 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/data-extra.d.ts +13 -0
- package/dist/commands/data-extra.js +161 -0
- package/dist/commands/data-extra.js.map +1 -0
- package/dist/commands/data.d.ts +13 -9
- package/dist/commands/data.js +220 -109
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/discover.d.ts +18 -0
- package/dist/commands/discover.js +71 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/doc.d.ts +39 -0
- package/dist/commands/doc.js +130 -0
- package/dist/commands/doc.js.map +1 -0
- package/dist/commands/events.d.ts +26 -0
- package/dist/commands/events.js +68 -0
- package/dist/commands/events.js.map +1 -0
- package/dist/commands/explain.d.ts +21 -0
- package/dist/commands/explain.js +248 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/graph.d.ts +18 -0
- package/dist/commands/graph.js +73 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/home.d.ts +12 -0
- package/dist/commands/home.js +54 -0
- package/dist/commands/home.js.map +1 -0
- package/dist/commands/init.d.ts +0 -2
- package/dist/commands/init.js +62 -102
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.d.ts +9 -0
- package/dist/commands/keys.js +79 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/knowledge.d.ts +32 -18
- package/dist/commands/knowledge.js +303 -53
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/observe.d.ts +9 -0
- package/dist/commands/observe.js +90 -0
- package/dist/commands/observe.js.map +1 -0
- package/dist/commands/open.d.ts +15 -0
- package/dist/commands/open.js +44 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/pods.d.ts +5 -0
- package/dist/commands/pods.js +85 -37
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.d.ts +7 -0
- package/dist/commands/proposals-actions.js +40 -0
- package/dist/commands/proposals-actions.js.map +1 -0
- package/dist/commands/providers.d.ts +38 -0
- package/dist/commands/providers.js +170 -0
- package/dist/commands/providers.js.map +1 -0
- package/dist/commands/sessions.d.ts +31 -0
- package/dist/commands/sessions.js +224 -0
- package/dist/commands/sessions.js.map +1 -0
- package/dist/commands/skills-commands.d.ts +26 -0
- package/dist/commands/skills-commands.js +186 -0
- package/dist/commands/skills-commands.js.map +1 -0
- package/dist/commands/skills.d.ts +26 -0
- package/dist/commands/skills.js +195 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/status.js +68 -30
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/subscribe.d.ts +19 -0
- package/dist/commands/subscribe.js +91 -0
- package/dist/commands/subscribe.js.map +1 -0
- package/dist/commands/view.d.ts +57 -0
- package/dist/commands/view.js +194 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +823 -206
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-templates.d.ts +25 -0
- package/dist/lib/agent-templates.js +148 -0
- package/dist/lib/agent-templates.js.map +1 -0
- package/dist/lib/agents-config.d.ts +4 -1
- package/dist/lib/agents-config.js +19 -2
- package/dist/lib/agents-config.js.map +1 -1
- package/dist/lib/capture-lane.d.ts +49 -0
- package/dist/lib/capture-lane.js +79 -0
- package/dist/lib/capture-lane.js.map +1 -0
- package/dist/lib/hub-client.d.ts +14 -0
- package/dist/lib/hub-client.js +45 -3
- package/dist/lib/hub-client.js.map +1 -1
- package/dist/lib/pod.d.ts +22 -1
- package/dist/lib/pod.js +32 -2
- package/dist/lib/pod.js.map +1 -1
- package/dist/lib/skills-installer.d.ts +1 -1
- package/dist/lib/skills-installer.js +1 -1
- package/dist/lib/skills-installer.js.map +1 -1
- package/dist/lib/targets.d.ts +17 -1
- package/dist/lib/targets.js +744 -70
- package/dist/lib/targets.js.map +1 -1
- package/node_modules/@synap/hub-rest-client/dist/index.cjs +881 -0
- package/node_modules/@synap/hub-rest-client/dist/index.d.cts +907 -0
- package/node_modules/@synap/hub-rest-client/dist/index.d.ts +907 -0
- package/node_modules/@synap/hub-rest-client/dist/index.js +851 -0
- package/node_modules/@synap/hub-rest-client/package.json +45 -0
- package/node_modules/@synap/hub-rest-client/src/client.ts +1143 -0
- package/node_modules/@synap/hub-rest-client/src/errors.ts +30 -0
- package/node_modules/@synap/hub-rest-client/src/index.ts +111 -0
- package/node_modules/@synap/hub-rest-client/src/setup.ts +77 -0
- package/node_modules/@synap/hub-rest-client/src/types.ts +639 -0
- package/package.json +9 -2
- package/skills/synap/SKILL.md +374 -100
- package/skills/synap-ui/SKILL.md +12 -9
- package/dist/lib/templates.d.ts +0 -11
- package/dist/lib/templates.js +0 -13
- package/dist/lib/templates.js.map +0 -1
- package/dist/templates/agent-os.json +0 -3090
package/dist/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @synap/cli — Connect
|
|
3
|
+
* @synap/cli — Connect AI agents to your Synap data pod
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
6
|
* npx @synap/cli init Full setup: detect, harden, connect, install
|
|
7
|
-
* npx @synap/cli connect Connect
|
|
8
|
-
* npx @synap/cli
|
|
9
|
-
* npx @synap/cli status Show pod + OpenClaw health
|
|
7
|
+
* npx @synap/cli connect Connect an AI surface to a Synap pod
|
|
8
|
+
* npx @synap/cli status Show pod health and API status
|
|
10
9
|
* npx @synap/cli update Update skill + check for CLI updates
|
|
11
10
|
*
|
|
12
11
|
* Or install globally:
|
|
@@ -30,33 +29,23 @@ catch {
|
|
|
30
29
|
const program = new Command();
|
|
31
30
|
program
|
|
32
31
|
.name("synap")
|
|
33
|
-
.description("Synap CLI — connect
|
|
34
|
-
.version(version)
|
|
32
|
+
.description("Synap CLI — connect AI agents to your data pod")
|
|
33
|
+
.version(version)
|
|
34
|
+
.showSuggestionAfterError(true);
|
|
35
35
|
program
|
|
36
36
|
.command("init")
|
|
37
|
-
.description("Full setup:
|
|
37
|
+
.description("Full setup: connect to a Synap pod and install the skill")
|
|
38
38
|
.option("--pod-url <url>", "Synap pod URL (skip pod choice prompt)")
|
|
39
39
|
.option("--api-key <key>", "Hub Protocol API key (skip key generation)")
|
|
40
|
-
.option("--skip-security", "Skip security hardening step")
|
|
41
40
|
.option("--skip-is", "Skip Intelligence Service provider setup")
|
|
42
41
|
.action(async (opts) => {
|
|
43
42
|
const { init } = await import("./commands/init.js");
|
|
44
43
|
await init(opts);
|
|
45
44
|
});
|
|
46
|
-
program
|
|
47
|
-
.command("finish")
|
|
48
|
-
.description("One-shot post-install: skill, AI key, public domain, IS")
|
|
49
|
-
.option("--skip-is", "Skip Intelligence Service provider setup")
|
|
50
|
-
.option("--skip-ai-key", "Skip AI provider key setup")
|
|
51
|
-
.option("--skip-domain", "Skip public domain exposure")
|
|
52
|
-
.action(async (opts) => {
|
|
53
|
-
const { finish } = await import("./commands/finish.js");
|
|
54
|
-
await finish(opts);
|
|
55
|
-
});
|
|
56
45
|
program
|
|
57
46
|
.command("connect")
|
|
58
|
-
.description("Connect an AI surface (Claude Code, Claude Desktop, Cursor, Raycast
|
|
59
|
-
.option("--target <name>", "AI surface: claude-code | claude-desktop | cursor | raycast |
|
|
47
|
+
.description("Connect an AI surface (Claude Code, Claude Desktop, Cursor, Raycast) to a Synap pod")
|
|
48
|
+
.option("--target <name>", "AI surface: claude-code | claude-desktop | cursor | raycast | custom")
|
|
60
49
|
.option("--pod-url <url>", "Synap pod URL")
|
|
61
50
|
.option("--api-key <key>", "Hub Protocol API key")
|
|
62
51
|
.option("--name <name>", "Pod profile name to save credentials under (default: 'default')")
|
|
@@ -87,7 +76,7 @@ pods
|
|
|
87
76
|
pods
|
|
88
77
|
.command("use <name>")
|
|
89
78
|
.description("Switch active pod and propagate credentials to all agent surfaces")
|
|
90
|
-
.option("--surface <surface>", "Only switch this surface (raycast, claude-code, claude-desktop, cursor
|
|
79
|
+
.option("--surface <surface>", "Only switch this surface (raycast, claude-code, claude-desktop, cursor)")
|
|
91
80
|
.action(async (name, opts) => {
|
|
92
81
|
const { podsUse } = await import("./commands/pods.js");
|
|
93
82
|
await podsUse(name, { surface: opts.surface });
|
|
@@ -100,19 +89,16 @@ pods
|
|
|
100
89
|
const { podsRemove } = await import("./commands/pods.js");
|
|
101
90
|
await podsRemove(name);
|
|
102
91
|
});
|
|
103
|
-
|
|
104
|
-
.command("
|
|
105
|
-
.
|
|
106
|
-
.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
.action(async (opts) => {
|
|
110
|
-
const { securityAudit } = await import("./commands/security-audit.js");
|
|
111
|
-
await securityAudit(opts);
|
|
92
|
+
pods
|
|
93
|
+
.command("reconnect [name]")
|
|
94
|
+
.description("Re-authenticate a saved pod (refresh API key without re-entering the URL)")
|
|
95
|
+
.action(async (name) => {
|
|
96
|
+
const { podsReconnect } = await import("./commands/pods.js");
|
|
97
|
+
await podsReconnect(name);
|
|
112
98
|
});
|
|
113
99
|
program
|
|
114
100
|
.command("status")
|
|
115
|
-
.description("Show Synap pod and
|
|
101
|
+
.description("Show Synap pod health and API status")
|
|
116
102
|
.action(async () => {
|
|
117
103
|
const { status } = await import("./commands/status.js");
|
|
118
104
|
await status();
|
|
@@ -126,101 +112,6 @@ program
|
|
|
126
112
|
const { update } = await import("./commands/update.js");
|
|
127
113
|
await update(opts);
|
|
128
114
|
});
|
|
129
|
-
const oc = program
|
|
130
|
-
.command("openclaw")
|
|
131
|
-
.alias("oc")
|
|
132
|
-
.description("Access, configure, and connect OpenClaw");
|
|
133
|
-
oc
|
|
134
|
-
.command("status", { isDefault: true })
|
|
135
|
-
.description("Overview: gateway status, AI key, skill, how to connect")
|
|
136
|
-
.action(async () => {
|
|
137
|
-
const { openclawOverview } = await import("./commands/openclaw.js");
|
|
138
|
-
await openclawOverview();
|
|
139
|
-
});
|
|
140
|
-
oc
|
|
141
|
-
.command("dashboard")
|
|
142
|
-
.alias("dash")
|
|
143
|
-
.description("Open the OpenClaw web UI (or print SSH tunnel instructions for remote servers)")
|
|
144
|
-
.action(async () => {
|
|
145
|
-
const { openclawDashboard } = await import("./commands/openclaw.js");
|
|
146
|
-
openclawDashboard();
|
|
147
|
-
});
|
|
148
|
-
oc
|
|
149
|
-
.command("connect")
|
|
150
|
-
.description("Show MCP client configs for Claude Desktop, Cursor, Windsurf")
|
|
151
|
-
.option("--client <name>", "Specific client: claude, cursor, windsurf")
|
|
152
|
-
.action(async (opts) => {
|
|
153
|
-
const { openclawConnect } = await import("./commands/openclaw.js");
|
|
154
|
-
await openclawConnect(opts);
|
|
155
|
-
});
|
|
156
|
-
oc
|
|
157
|
-
.command("configure")
|
|
158
|
-
.alias("config")
|
|
159
|
-
.description("Set AI provider API key via OpenClaw's own config system")
|
|
160
|
-
.option("-i, --interactive", "Run OpenClaw's own interactive wizard")
|
|
161
|
-
.option("--provider <name>", "Provider: anthropic | openai | google")
|
|
162
|
-
.option("--key <key>", "API key (non-interactive)")
|
|
163
|
-
.option("--model <id>", "Model id (e.g. anthropic/claude-sonnet-4-6)")
|
|
164
|
-
.option("--show", "Print the current config")
|
|
165
|
-
.action(async (opts) => {
|
|
166
|
-
const { openclawConfigure } = await import("./commands/openclaw.js");
|
|
167
|
-
await openclawConfigure(opts);
|
|
168
|
-
});
|
|
169
|
-
oc
|
|
170
|
-
.command("token")
|
|
171
|
-
.description("Print the OpenClaw gateway token (for MCP clients)")
|
|
172
|
-
.option("--copy", "Copy to clipboard instead of printing")
|
|
173
|
-
.option("--for <client>", "Print a pre-filled MCP config (claude, cursor, windsurf)")
|
|
174
|
-
.action(async (opts) => {
|
|
175
|
-
const { openclawToken } = await import("./commands/openclaw.js");
|
|
176
|
-
openclawToken(opts);
|
|
177
|
-
});
|
|
178
|
-
oc
|
|
179
|
-
.command("doctor")
|
|
180
|
-
.description("Run OpenClaw's diagnostic (openclaw doctor)")
|
|
181
|
-
.option("--fix", "Auto-fix detected issues")
|
|
182
|
-
.action(async (opts) => {
|
|
183
|
-
const { openclawDoctor } = await import("./commands/openclaw.js");
|
|
184
|
-
openclawDoctor(opts);
|
|
185
|
-
});
|
|
186
|
-
oc
|
|
187
|
-
.command("logs")
|
|
188
|
-
.description("Tail OpenClaw container logs")
|
|
189
|
-
.option("-n, --lines <n>", "Number of log lines", "50")
|
|
190
|
-
.option("-f, --follow", "Follow log output")
|
|
191
|
-
.action(async (opts) => {
|
|
192
|
-
const { openclawLogs } = await import("./commands/openclaw.js");
|
|
193
|
-
openclawLogs({ lines: opts.lines ? parseInt(opts.lines, 10) : 50, follow: opts.follow });
|
|
194
|
-
});
|
|
195
|
-
oc
|
|
196
|
-
.command("restart")
|
|
197
|
-
.description("Restart the OpenClaw container")
|
|
198
|
-
.action(async () => {
|
|
199
|
-
const { openclawRestart } = await import("./commands/openclaw.js");
|
|
200
|
-
await openclawRestart();
|
|
201
|
-
});
|
|
202
|
-
oc
|
|
203
|
-
.command("setup-domain")
|
|
204
|
-
.description("Expose the OpenClaw dashboard via a public HTTPS subdomain (Caddy)")
|
|
205
|
-
.action(async () => {
|
|
206
|
-
const { openclawSetupDomain } = await import("./commands/openclaw.js");
|
|
207
|
-
openclawSetupDomain();
|
|
208
|
-
});
|
|
209
|
-
oc
|
|
210
|
-
.command("connections")
|
|
211
|
-
.alias("conn")
|
|
212
|
-
.description("Unified view: AI providers, skills, channels, MCP clients")
|
|
213
|
-
.action(async () => {
|
|
214
|
-
const { openclawConnections } = await import("./commands/openclaw.js");
|
|
215
|
-
openclawConnections();
|
|
216
|
-
});
|
|
217
|
-
oc
|
|
218
|
-
.command("open [section]")
|
|
219
|
-
.description("Open the OpenClaw dashboard (optionally at a section: channels, skills, config, chat, sessions, logs)")
|
|
220
|
-
.action(async (section) => {
|
|
221
|
-
const { openclawOpen } = await import("./commands/openclaw.js");
|
|
222
|
-
openclawOpen(section);
|
|
223
|
-
});
|
|
224
115
|
// ─── infra ────────────────────────────────────────────────────────────────────
|
|
225
116
|
const infra = program
|
|
226
117
|
.command("infra")
|
|
@@ -278,60 +169,66 @@ program
|
|
|
278
169
|
program
|
|
279
170
|
.command("connections")
|
|
280
171
|
.alias("conn")
|
|
281
|
-
.description("Show which pod each agent surface (Claude Code, Desktop, Cursor,
|
|
172
|
+
.description("Show which pod each agent surface (Claude Code, Desktop, Cursor, Raycast) is connected to")
|
|
282
173
|
.action(async () => {
|
|
283
174
|
const { connections } = await import("./commands/connections.js");
|
|
284
175
|
await connections();
|
|
285
176
|
});
|
|
286
177
|
program
|
|
287
178
|
.command("login")
|
|
288
|
-
.description("
|
|
289
|
-
.option("--
|
|
179
|
+
.description("Connect to a Synap pod (self-hosted or managed)")
|
|
180
|
+
.option("--reconnect [name]", "Re-authenticate a saved pod without re-entering its URL")
|
|
290
181
|
.action(async (opts) => {
|
|
291
182
|
const chalk = (await import("chalk")).default;
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
if (creds) {
|
|
299
|
-
spinner.succeed(`Authenticated as ${creds.email}`);
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
spinner.fail("Token is invalid or expired. Get a token at https://synap.live/account/tokens");
|
|
303
|
-
}
|
|
183
|
+
const { listPodProfiles } = await import("./lib/pod.js");
|
|
184
|
+
// --reconnect: delegate to reconnect flow
|
|
185
|
+
if (opts.reconnect !== undefined) {
|
|
186
|
+
const name = typeof opts.reconnect === "string" ? opts.reconnect : undefined;
|
|
187
|
+
const { podsReconnect } = await import("./commands/pods.js");
|
|
188
|
+
await podsReconnect(name);
|
|
304
189
|
return;
|
|
305
190
|
}
|
|
306
|
-
const
|
|
307
|
-
if (
|
|
308
|
-
|
|
191
|
+
const profiles = listPodProfiles();
|
|
192
|
+
if (profiles.length === 0) {
|
|
193
|
+
// No pod saved — guide to pods add
|
|
194
|
+
console.log(chalk.dim(" No pod configured yet."));
|
|
195
|
+
console.log(chalk.blue(" Adding a new pod...\n"));
|
|
196
|
+
const { podsAdd } = await import("./commands/pods.js");
|
|
197
|
+
await podsAdd();
|
|
309
198
|
return;
|
|
310
199
|
}
|
|
311
|
-
|
|
312
|
-
const
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
200
|
+
// Already have pods — show status and offer reconnect if any are unreachable
|
|
201
|
+
const { checkPodHealth } = await import("./lib/pod.js");
|
|
202
|
+
const ora = (await import("ora")).default;
|
|
203
|
+
const spinner = ora("Checking pod health...").start();
|
|
204
|
+
const checks = await Promise.all(profiles.map(async (p) => {
|
|
205
|
+
const h = await checkPodHealth(p.config.podUrl).catch(() => ({ healthy: false }));
|
|
206
|
+
return { ...p, healthy: h.healthy };
|
|
207
|
+
}));
|
|
208
|
+
spinner.stop();
|
|
209
|
+
console.log("\n Configured pods:\n");
|
|
210
|
+
for (const p of checks) {
|
|
211
|
+
const active = p.active ? chalk.green(" ● ") : " ";
|
|
212
|
+
const status = p.healthy ? chalk.green("ok") : chalk.red("unreachable");
|
|
213
|
+
console.log(` ${active}${chalk.bold(p.name.padEnd(14))} ${status} ${chalk.dim(p.config.podUrl)}`);
|
|
320
214
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
.
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
logout();
|
|
330
|
-
if (creds) {
|
|
331
|
-
console.log(chalk.green(` Logged out (was: ${creds.email})`));
|
|
215
|
+
console.log();
|
|
216
|
+
const unreachable = checks.filter((p) => !p.healthy);
|
|
217
|
+
if (unreachable.length > 0) {
|
|
218
|
+
console.log(chalk.yellow(` ${unreachable.length} pod(s) unreachable. To refresh credentials:`));
|
|
219
|
+
for (const p of unreachable) {
|
|
220
|
+
console.log(chalk.dim(` synap login --reconnect ${p.name}`));
|
|
221
|
+
}
|
|
222
|
+
console.log();
|
|
332
223
|
}
|
|
333
224
|
else {
|
|
334
|
-
console.log(chalk.
|
|
225
|
+
console.log(chalk.green(" All pods healthy."));
|
|
226
|
+
const active = checks.find((p) => p.active);
|
|
227
|
+
if (active)
|
|
228
|
+
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"));
|
|
335
232
|
}
|
|
336
233
|
});
|
|
337
234
|
// ─── orient ───────────────────────────────────────────────────────────────────
|
|
@@ -356,68 +253,103 @@ program
|
|
|
356
253
|
const { useWorkspace } = await import("./commands/data.js");
|
|
357
254
|
await useWorkspace(workspace, opts);
|
|
358
255
|
});
|
|
359
|
-
// ───
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
.option("--workspace <id>", "Scope to a specific workspace")
|
|
364
|
-
.option("--type <type>", "Filter: entity | doc | view")
|
|
365
|
-
.option("--limit <n>", "Max results", "20")
|
|
366
|
-
.option("--json", "Output as JSON")
|
|
367
|
-
.option("--pod-url <url>", "Pod URL override")
|
|
368
|
-
.option("--api-key <key>", "API key override")
|
|
369
|
-
.action(async (query, opts) => {
|
|
370
|
-
const { searchData } = await import("./commands/data.js");
|
|
371
|
-
await searchData(query, opts);
|
|
372
|
-
});
|
|
373
|
-
// ─── remember / recall ────────────────────────────────────────────────────────
|
|
256
|
+
// ─── note ─────────────────────────────────────────────────────────────────────
|
|
257
|
+
// Quick `note` entity. The one canonical READ verb is `ask`; the one canonical
|
|
258
|
+
// structured-WRITE verb is `capture`. (search / recall / remember removed — they
|
|
259
|
+
// were redundant doors `ask`/`capture`/`note` already cover.)
|
|
374
260
|
program
|
|
375
|
-
.command("
|
|
376
|
-
.description("
|
|
377
|
-
.option("--context <entity-id>", "Link
|
|
261
|
+
.command("note <text>")
|
|
262
|
+
.description("Quick freeform note → note entity (for structured learnings use `synap capture`)")
|
|
263
|
+
.option("--context <entity-id>", "Link this note to an entity")
|
|
378
264
|
.option("--json", "Output as JSON")
|
|
379
265
|
.option("--pod-url <url>", "Pod URL override")
|
|
380
266
|
.option("--api-key <key>", "API key override")
|
|
381
267
|
.action(async (text, opts) => {
|
|
382
|
-
const {
|
|
383
|
-
await
|
|
268
|
+
const { noteData } = await import("./commands/data.js");
|
|
269
|
+
await noteData(text, opts);
|
|
384
270
|
});
|
|
271
|
+
// ─── ask (unified knowledge access) ─────────────────────────────────────────────
|
|
272
|
+
// The ONE read verb. Routes to the right substrate(s) — semantic (entities),
|
|
273
|
+
// procedural (how-to docs), episodic (captures) — and returns a glass-box answer.
|
|
385
274
|
program
|
|
386
|
-
.command("
|
|
387
|
-
.description("
|
|
388
|
-
.option("--
|
|
389
|
-
.option("--
|
|
390
|
-
.option("--tags <csv>", "Filter by tags e.g. repo:synap-backend (--structured only)")
|
|
391
|
-
.option("--workspace <id>", "Workspace to search (--structured only, defaults to active)")
|
|
392
|
-
.option("--limit <n>", "Max results", "10")
|
|
275
|
+
.command("ask <query>")
|
|
276
|
+
.description("Ask your pod anything — routes to the right knowledge substrate(s) and shows which answered")
|
|
277
|
+
.option("--workspace <id>", "Scope to a specific workspace (omit for pod-wide)")
|
|
278
|
+
.option("--limit <n>", "Max results per substrate", "10")
|
|
393
279
|
.option("--json", "Output as JSON")
|
|
394
280
|
.option("--pod-url <url>", "Pod URL override")
|
|
395
281
|
.option("--api-key <key>", "API key override")
|
|
396
282
|
.action(async (query, opts) => {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
await recallStructured(query, opts);
|
|
400
|
-
}
|
|
401
|
-
else {
|
|
402
|
-
const { recallData } = await import("./commands/data.js");
|
|
403
|
-
await recallData(query, opts);
|
|
404
|
-
}
|
|
283
|
+
const { askKnowledge } = await import("./commands/data.js");
|
|
284
|
+
await askKnowledge(query, opts);
|
|
405
285
|
});
|
|
406
286
|
// ─── capture ──────────────────────────────────────────────────────────────────
|
|
407
287
|
// Uses the active pod + workspace from config (set via `synap pods use` /
|
|
408
288
|
// `synap use` / `synap workspace provision-agent`). No auth flags needed.
|
|
409
289
|
program
|
|
410
|
-
.command("capture")
|
|
411
|
-
.description("Capture
|
|
412
|
-
.
|
|
413
|
-
.
|
|
290
|
+
.command("capture [text]")
|
|
291
|
+
.description("Capture knowledge: smart `capture \"<free text>\"` (AI structures it) OR typed `capture --type gotcha --claim \"…\"`")
|
|
292
|
+
.option("--type <type>", "Typed mode: gotcha|lesson|decision|reference")
|
|
293
|
+
.option("--claim <text>", "Typed mode: one-line assertion (required with --type)")
|
|
414
294
|
.option("--why <text>", "Reasoning or context")
|
|
415
295
|
.option("--evidence <text>", "Supporting file path, URL, or code snippet")
|
|
416
296
|
.option("--tags <csv>", "Comma-separated tags e.g. repo:synap-backend,layer:migrations")
|
|
297
|
+
.option("--global", "GLOBAL lane: pod-wide cross-cutting runbook (→ knowledge_keys), visible in every workspace")
|
|
298
|
+
.option("--key <ns:slug>", "Stable key for a --global runbook (derived from --type + --claim if omitted)")
|
|
299
|
+
.option("--team", "Write to the first product workspace instead of the active workspace")
|
|
300
|
+
.option("--workspace <id>", "Explicit workspace override")
|
|
301
|
+
.option("--yes", "Skip the y/N confirmation prompt (smart mode)")
|
|
417
302
|
.option("--json", "Output as JSON")
|
|
418
|
-
.action(async (opts) => {
|
|
303
|
+
.action(async (text, opts) => {
|
|
419
304
|
const { captureKnowledge } = await import("./commands/knowledge.js");
|
|
420
|
-
await captureKnowledge(opts);
|
|
305
|
+
await captureKnowledge({ ...opts, text });
|
|
306
|
+
});
|
|
307
|
+
program
|
|
308
|
+
.command("subscribe")
|
|
309
|
+
.description("Stream pod events as NDJSON (long-poll)")
|
|
310
|
+
.option("--event <pattern>", "Filter by event type pattern (e.g. proposal.*)")
|
|
311
|
+
.option("--limit <n>", "Events per poll", "20")
|
|
312
|
+
.option("--json", "NDJSON output")
|
|
313
|
+
.option("--pod-url <url>")
|
|
314
|
+
.option("--api-key <key>")
|
|
315
|
+
.action(async (opts) => {
|
|
316
|
+
const { subscribeEvents } = await import("./commands/subscribe.js");
|
|
317
|
+
await subscribeEvents(opts);
|
|
318
|
+
});
|
|
319
|
+
program
|
|
320
|
+
.command("home")
|
|
321
|
+
.description("Show the active workspace's home bento layout (what cells are on screen)")
|
|
322
|
+
.option("--workspace <id>", "Workspace to read (defaults to active workspace)")
|
|
323
|
+
.option("--json", "Output as JSON")
|
|
324
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
325
|
+
.option("--api-key <key>", "API key override")
|
|
326
|
+
.action(async (opts) => {
|
|
327
|
+
const { showHome } = await import("./commands/home.js");
|
|
328
|
+
await showHome(opts);
|
|
329
|
+
});
|
|
330
|
+
program
|
|
331
|
+
.command("context")
|
|
332
|
+
.description("Session-start context: knowledge, proposals, tasks, active sessions")
|
|
333
|
+
.option("--repo <name>", "Filter knowledge by repo tag")
|
|
334
|
+
.option("--limit <n>", "Entries per section", "5")
|
|
335
|
+
.option("--json", "NDJSON output")
|
|
336
|
+
.option("--workspace <id>", "Override workspace")
|
|
337
|
+
.option("--pod-url <url>")
|
|
338
|
+
.option("--api-key <key>")
|
|
339
|
+
.action(async (opts) => {
|
|
340
|
+
const { contextSummary } = await import("./commands/context.js");
|
|
341
|
+
await contextSummary(opts);
|
|
342
|
+
});
|
|
343
|
+
program
|
|
344
|
+
.command("discover")
|
|
345
|
+
.description("Runtime discovery: entity profiles with property schemas + CLI command tree")
|
|
346
|
+
.option("--json", "Output as JSON (default: human-readable)")
|
|
347
|
+
.option("--profiles", "Show only profiles (use with --json for machine-readable schema)")
|
|
348
|
+
.option("--commands", "Show only the command tree")
|
|
349
|
+
.option("--workspace <id>", "Workspace to query (defaults to active workspace)")
|
|
350
|
+
.action(async (opts) => {
|
|
351
|
+
const { discover } = await import("./commands/discover.js");
|
|
352
|
+
await discover(opts);
|
|
421
353
|
});
|
|
422
354
|
// ─── workspace ────────────────────────────────────────────────────────────────
|
|
423
355
|
// Context setup commands. Run once to configure the session — all subsequent
|
|
@@ -459,6 +391,18 @@ list
|
|
|
459
391
|
const { listProfiles } = await import("./commands/data.js");
|
|
460
392
|
await listProfiles(opts);
|
|
461
393
|
});
|
|
394
|
+
list
|
|
395
|
+
.command("views")
|
|
396
|
+
.description("List views in a workspace (whiteboard, kanban, bento, …)")
|
|
397
|
+
.option("--type <type>", "Filter by view type (e.g. whiteboard, kanban, calendar)")
|
|
398
|
+
.option("--workspace <id>", "Workspace (defaults to active)")
|
|
399
|
+
.option("--json", "Output as JSON")
|
|
400
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
401
|
+
.option("--api-key <key>", "API key override")
|
|
402
|
+
.action(async (opts) => {
|
|
403
|
+
const { viewList } = await import("./commands/view.js");
|
|
404
|
+
await viewList(opts);
|
|
405
|
+
});
|
|
462
406
|
list
|
|
463
407
|
.command("entities")
|
|
464
408
|
.description("List entities on the pod")
|
|
@@ -472,6 +416,259 @@ list
|
|
|
472
416
|
const { listEntities } = await import("./commands/data.js");
|
|
473
417
|
await listEntities(opts);
|
|
474
418
|
});
|
|
419
|
+
// ─── show ─────────────────────────────────────────────────────────────────────
|
|
420
|
+
// Entity detail + its relations — one command to understand any node in the graph.
|
|
421
|
+
program
|
|
422
|
+
.command("show <id>")
|
|
423
|
+
.description("Show an entity with its properties and all linked relations")
|
|
424
|
+
.option("--json", "Output as JSON")
|
|
425
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
426
|
+
.option("--api-key <key>", "API key override")
|
|
427
|
+
.action(async (id, opts) => {
|
|
428
|
+
const { showEntity } = await import("./commands/data-extra.js");
|
|
429
|
+
await showEntity(id, opts);
|
|
430
|
+
});
|
|
431
|
+
// ─── proposals ────────────────────────────────────────────────────────────────
|
|
432
|
+
// Governance inbox — pending proposals attributed to this agent.
|
|
433
|
+
const proposals = program
|
|
434
|
+
.command("proposals")
|
|
435
|
+
.description("Review and act on governance proposals");
|
|
436
|
+
proposals
|
|
437
|
+
.command("list", { isDefault: true })
|
|
438
|
+
.description("List pending governance proposals for this agent")
|
|
439
|
+
.option("--workspace <id>", "Scope to a specific workspace")
|
|
440
|
+
.option("--limit <n>", "Max results", "20")
|
|
441
|
+
.option("--json", "Output as JSON")
|
|
442
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
443
|
+
.option("--api-key <key>", "API key override")
|
|
444
|
+
.action(async (opts) => {
|
|
445
|
+
const { listProposals } = await import("./commands/data-extra.js");
|
|
446
|
+
await listProposals(opts);
|
|
447
|
+
});
|
|
448
|
+
proposals
|
|
449
|
+
.command("approve <id>")
|
|
450
|
+
.description("Approve a pending proposal")
|
|
451
|
+
.option("--reason <text>", "Optional approval note")
|
|
452
|
+
.option("--json", "Output as JSON")
|
|
453
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
454
|
+
.option("--api-key <key>", "API key override")
|
|
455
|
+
.action(async (id, opts) => {
|
|
456
|
+
const { approveProposal } = await import("./commands/proposals-actions.js");
|
|
457
|
+
await approveProposal(id, opts);
|
|
458
|
+
});
|
|
459
|
+
proposals
|
|
460
|
+
.command("reject <id>")
|
|
461
|
+
.description("Reject a pending proposal")
|
|
462
|
+
.option("--reason <text>", "Rejection reason")
|
|
463
|
+
.option("--json", "Output as JSON")
|
|
464
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
465
|
+
.option("--api-key <key>", "API key override")
|
|
466
|
+
.action(async (id, opts) => {
|
|
467
|
+
const { rejectProposal } = await import("./commands/proposals-actions.js");
|
|
468
|
+
await rejectProposal(id, opts);
|
|
469
|
+
});
|
|
470
|
+
// ─── session ──────────────────────────────────────────────────────────────────
|
|
471
|
+
// Focus sessions — goal-bound work rooms tracked on the pod.
|
|
472
|
+
// AI agents: use start_session to begin, update_session to report progress,
|
|
473
|
+
// update_session({status:"closed"}) to finish. Sessions link goals, context,
|
|
474
|
+
// plans, execution logs, and verification reports together.
|
|
475
|
+
const session = program
|
|
476
|
+
.command("session")
|
|
477
|
+
.description("Manage focus sessions (goal-bound AI work rooms)");
|
|
478
|
+
session
|
|
479
|
+
.command("start")
|
|
480
|
+
.description("Start a new focus session and return its ID")
|
|
481
|
+
.requiredOption("--goal <text>", "What this session is working toward")
|
|
482
|
+
.option("--workspace <id>", "Workspace that owns the session")
|
|
483
|
+
.option("--task-id <id>", "Link session to an existing task entity")
|
|
484
|
+
.option("--json", "Output as JSON")
|
|
485
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
486
|
+
.option("--api-key <key>", "API key override")
|
|
487
|
+
.action(async (opts) => {
|
|
488
|
+
const { startSession } = await import("./commands/sessions.js");
|
|
489
|
+
await startSession(opts);
|
|
490
|
+
});
|
|
491
|
+
session
|
|
492
|
+
.command("list", { isDefault: true })
|
|
493
|
+
.description("List focus sessions in the active workspace")
|
|
494
|
+
.option("--workspace <id>", "Scope to a specific workspace")
|
|
495
|
+
.option("--status <status>", "Filter by status: active | paused | closed")
|
|
496
|
+
.option("--limit <n>", "Max results", "20")
|
|
497
|
+
.option("--json", "Output as JSON")
|
|
498
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
499
|
+
.option("--api-key <key>", "API key override")
|
|
500
|
+
.action(async (opts) => {
|
|
501
|
+
const { listSessions } = await import("./commands/sessions.js");
|
|
502
|
+
await listSessions(opts);
|
|
503
|
+
});
|
|
504
|
+
session
|
|
505
|
+
.command("get <id>")
|
|
506
|
+
.description("Show details for a specific focus session")
|
|
507
|
+
.option("--workspace <id>", "Workspace that owns the session (required for scoped fetch)")
|
|
508
|
+
.option("--json", "Output as JSON")
|
|
509
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
510
|
+
.option("--api-key <key>", "API key override")
|
|
511
|
+
.action(async (id, opts) => {
|
|
512
|
+
const { getSession } = await import("./commands/sessions.js");
|
|
513
|
+
await getSession(id, opts);
|
|
514
|
+
});
|
|
515
|
+
session
|
|
516
|
+
.command("update <id>")
|
|
517
|
+
.description("Update progress or status of a focus session")
|
|
518
|
+
.requiredOption("--workspace <id>", "Workspace that owns the session")
|
|
519
|
+
.option("--progress <0-100>", "Progress percentage")
|
|
520
|
+
.option("--status <status>", "New status: active | paused")
|
|
521
|
+
.option("--goal <text>", "Revised goal")
|
|
522
|
+
.option("--json", "Output as JSON")
|
|
523
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
524
|
+
.option("--api-key <key>", "API key override")
|
|
525
|
+
.action(async (id, opts) => {
|
|
526
|
+
const { updateSession } = await import("./commands/sessions.js");
|
|
527
|
+
await updateSession(id, opts);
|
|
528
|
+
});
|
|
529
|
+
session
|
|
530
|
+
.command("close <id>")
|
|
531
|
+
.description("Close a focus session and optionally attach a recap")
|
|
532
|
+
.requiredOption("--workspace <id>", "Workspace that owns the session")
|
|
533
|
+
.option("--recap <text>", "Short summary of what was accomplished")
|
|
534
|
+
.option("--json", "Output as JSON")
|
|
535
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
536
|
+
.option("--api-key <key>", "API key override")
|
|
537
|
+
.action(async (id, opts) => {
|
|
538
|
+
const { closeSession } = await import("./commands/sessions.js");
|
|
539
|
+
await closeSession(id, opts);
|
|
540
|
+
});
|
|
541
|
+
session
|
|
542
|
+
.command("attach <id>")
|
|
543
|
+
.description("Attach a session to this terminal — all hub calls tag X-Session-Id until detached")
|
|
544
|
+
.option("--json", "Output as JSON")
|
|
545
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
546
|
+
.option("--api-key <key>", "API key override")
|
|
547
|
+
.action(async (id, opts) => {
|
|
548
|
+
const { attachSession } = await import("./commands/sessions.js");
|
|
549
|
+
await attachSession(id, opts);
|
|
550
|
+
});
|
|
551
|
+
session
|
|
552
|
+
.command("detach")
|
|
553
|
+
.description("Remove the active session from this terminal")
|
|
554
|
+
.option("--json", "Output as JSON")
|
|
555
|
+
.action(async (opts) => {
|
|
556
|
+
const { detachSession } = await import("./commands/sessions.js");
|
|
557
|
+
detachSession(opts);
|
|
558
|
+
});
|
|
559
|
+
session
|
|
560
|
+
.command("current")
|
|
561
|
+
.description("Show the active session for this terminal (from .synap-session or SYNAP_SESSION_ID)")
|
|
562
|
+
.option("--json", "Output as JSON")
|
|
563
|
+
.action(async (opts) => {
|
|
564
|
+
const { sessionStatus } = await import("./commands/sessions.js");
|
|
565
|
+
sessionStatus(opts);
|
|
566
|
+
});
|
|
567
|
+
// ─── skill ────────────────────────────────────────────────────────────────────
|
|
568
|
+
// Autonomous workspace session skills — context gathering, task planning, etc.
|
|
569
|
+
const skillCmd = program
|
|
570
|
+
.command("skill")
|
|
571
|
+
.description("Execute a skill in an autonomous workspace session")
|
|
572
|
+
.action(() => {
|
|
573
|
+
skillCmd.help();
|
|
574
|
+
});
|
|
575
|
+
skillCmd
|
|
576
|
+
.command("gather-context")
|
|
577
|
+
.description("Gather pod KG + local context (CLAUDE.md, .claude/kg-verify) for a session")
|
|
578
|
+
.option("--session <id>", "Focus session ID (required)")
|
|
579
|
+
.option("--workspace <id>", "Workspace ID (defaults to active workspace)")
|
|
580
|
+
.option("--json", "Output as JSON")
|
|
581
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
582
|
+
.option("--api-key <key>", "API key override")
|
|
583
|
+
.allowUnknownOption()
|
|
584
|
+
.action(async (opts) => {
|
|
585
|
+
const { gatherContext } = await import("./commands/skills.js");
|
|
586
|
+
await gatherContext(opts);
|
|
587
|
+
});
|
|
588
|
+
skillCmd
|
|
589
|
+
.command("suggest <topic>")
|
|
590
|
+
.description("Search the skill knowledge base by topic or keyword")
|
|
591
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
592
|
+
.option("--api-key <key>", "API key override")
|
|
593
|
+
.action(async (topic, opts) => {
|
|
594
|
+
const { suggestSkills } = await import("./commands/skills-commands.js");
|
|
595
|
+
await suggestSkills(topic, opts);
|
|
596
|
+
});
|
|
597
|
+
skillCmd
|
|
598
|
+
.command("get <slug>")
|
|
599
|
+
.description("Fetch a skill from the knowledge base by slug and print its body")
|
|
600
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
601
|
+
.option("--api-key <key>", "API key override")
|
|
602
|
+
.action(async (slug, opts) => {
|
|
603
|
+
const { getSkill } = await import("./commands/skills-commands.js");
|
|
604
|
+
await getSkill(slug, opts);
|
|
605
|
+
});
|
|
606
|
+
skillCmd
|
|
607
|
+
.command("sync")
|
|
608
|
+
.description("Bulk-import local skills from ~/.claude/skills/ into the pod")
|
|
609
|
+
.option("--from <path>", "Skills directory path (default: ~/.claude/skills)")
|
|
610
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
611
|
+
.option("--api-key <key>", "API key override")
|
|
612
|
+
.action(async (opts) => {
|
|
613
|
+
const { syncSkills } = await import("./commands/skills-commands.js");
|
|
614
|
+
await syncSkills(opts);
|
|
615
|
+
});
|
|
616
|
+
skillCmd
|
|
617
|
+
.command("verify-code")
|
|
618
|
+
.description("Run the project's type-check/test gate and store the result on the session")
|
|
619
|
+
.requiredOption("--session <id>", "Focus session ID")
|
|
620
|
+
.requiredOption("--workspace <id>", "Workspace that owns the session")
|
|
621
|
+
.requiredOption("--cmd <command>", "Gate command to run (e.g. 'pnpm type-check')")
|
|
622
|
+
.option("--json", "Output as JSON")
|
|
623
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
624
|
+
.option("--api-key <key>", "API key override")
|
|
625
|
+
.action(async (opts) => {
|
|
626
|
+
const { verifyCode } = await import("./commands/skills.js");
|
|
627
|
+
await verifyCode(opts);
|
|
628
|
+
});
|
|
629
|
+
// ─── browse ───────────────────────────────────────────────────────────────────
|
|
630
|
+
// Paginated entity list — cleaner than `list entities`.
|
|
631
|
+
program
|
|
632
|
+
.command("browse [profile]")
|
|
633
|
+
.description("Browse entities in the active workspace, optionally filtered by profile type")
|
|
634
|
+
.option("--workspace <id>", "Scope to a specific workspace")
|
|
635
|
+
.option("--limit <n>", "Max results", "20")
|
|
636
|
+
.option("--json", "Output as JSON")
|
|
637
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
638
|
+
.option("--api-key <key>", "API key override")
|
|
639
|
+
.action(async (profile, opts) => {
|
|
640
|
+
const { browseEntities } = await import("./commands/data-extra.js");
|
|
641
|
+
await browseEntities({ ...opts, profile });
|
|
642
|
+
});
|
|
643
|
+
// ─── observe ──────────────────────────────────────────────────────────────────
|
|
644
|
+
// AI-maintained user model — write and query pod-scoped user observations.
|
|
645
|
+
const observe = program
|
|
646
|
+
.command("observe")
|
|
647
|
+
.description("Write and recall pod-wide user observations (AI-maintained user model)");
|
|
648
|
+
observe
|
|
649
|
+
.command("write <text>", { isDefault: true })
|
|
650
|
+
.description("Record an observation about the user (pod-scoped, AI-maintained)")
|
|
651
|
+
.option("--category <cat>", "working_style | communication | focus | technical | preference", "preference")
|
|
652
|
+
.option("--confidence <n>", "Confidence score 0-1", "0.5")
|
|
653
|
+
.option("--json", "Output as JSON")
|
|
654
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
655
|
+
.option("--api-key <key>", "API key override")
|
|
656
|
+
.action(async (text, opts) => {
|
|
657
|
+
const { observeWrite } = await import("./commands/observe.js");
|
|
658
|
+
await observeWrite(text, opts);
|
|
659
|
+
});
|
|
660
|
+
observe
|
|
661
|
+
.command("recall <query>")
|
|
662
|
+
.description("Search recorded user observations")
|
|
663
|
+
.option("--category <cat>", "Filter by category")
|
|
664
|
+
.option("--limit <n>", "Max results", "10")
|
|
665
|
+
.option("--json", "Output as JSON")
|
|
666
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
667
|
+
.option("--api-key <key>", "API key override")
|
|
668
|
+
.action(async (query, opts) => {
|
|
669
|
+
const { observeRecall } = await import("./commands/observe.js");
|
|
670
|
+
await observeRecall(query, opts);
|
|
671
|
+
});
|
|
475
672
|
// ─── get ──────────────────────────────────────────────────────────────────────
|
|
476
673
|
const get = program
|
|
477
674
|
.command("get")
|
|
@@ -527,6 +724,7 @@ set
|
|
|
527
724
|
.command("entity <id>")
|
|
528
725
|
.description("Update entity properties")
|
|
529
726
|
.requiredOption("--props <json>", "Properties as JSON string")
|
|
727
|
+
.option("--workspace <id>", "Workspace ID (sent in PATCH body so workspace-scoped automations fire)")
|
|
530
728
|
.option("--json", "Output as JSON")
|
|
531
729
|
.option("--pod-url <url>", "Pod URL override")
|
|
532
730
|
.option("--api-key <key>", "API key override")
|
|
@@ -593,5 +791,424 @@ agents
|
|
|
593
791
|
const { agentsInfo } = await import("./commands/agents.js");
|
|
594
792
|
agentsInfo(name);
|
|
595
793
|
});
|
|
794
|
+
// ─── agent (autonomous runner) ───────────────────────────────────────────────
|
|
795
|
+
const agent = program
|
|
796
|
+
.command("agent")
|
|
797
|
+
.description("Run autonomous agent loops against the IS, or schedule recurring goals");
|
|
798
|
+
agent
|
|
799
|
+
.command("run")
|
|
800
|
+
.description("Run an autonomous agent toward a goal using the Intelligence Service")
|
|
801
|
+
.requiredOption("--goal <text>", "What the agent should accomplish")
|
|
802
|
+
.option("--persona <type>", "researcher | assistant | developer (default: researcher)")
|
|
803
|
+
.option("--model <model>", "IS model alias, e.g. synap/advanced (default: synap/advanced)")
|
|
804
|
+
.option("--workspace <id>", "Workspace to store results in (uses active workspace if omitted)")
|
|
805
|
+
.option("--max-steps <n>", "Max reasoning steps before auto-saving (default: 12)", parseInt)
|
|
806
|
+
.option("--dry-run", "Print config without running")
|
|
807
|
+
.option("--pod-url <url>", "Override pod URL")
|
|
808
|
+
.option("--api-key <key>", "Override API key")
|
|
809
|
+
.action(async (opts) => {
|
|
810
|
+
const { agentRun } = await import("./commands/agent-run.js");
|
|
811
|
+
await agentRun(opts);
|
|
812
|
+
});
|
|
813
|
+
agent
|
|
814
|
+
.command("schedule")
|
|
815
|
+
.description("Add, list, or remove recurring agent schedules")
|
|
816
|
+
.option("--goal <text>", "Goal for the scheduled agent")
|
|
817
|
+
.option("--name <label>", "Name for this schedule (required when adding)")
|
|
818
|
+
.option("--every <interval>", "hourly | daily | weekly")
|
|
819
|
+
.option("--persona <type>", "researcher | assistant | developer (default: researcher)")
|
|
820
|
+
.option("--model <model>", "IS model alias (default: synap/advanced)")
|
|
821
|
+
.option("--workspace <id>", "Workspace to store results in")
|
|
822
|
+
.option("--run-now", "Also run immediately after creating the schedule")
|
|
823
|
+
.option("--list", "List all configured schedules")
|
|
824
|
+
.option("--remove <name>", "Remove a schedule by name")
|
|
825
|
+
.option("--pod-url <url>", "Override pod URL")
|
|
826
|
+
.option("--api-key <key>", "Override API key")
|
|
827
|
+
.action(async (opts) => {
|
|
828
|
+
const { agentSchedule } = await import("./commands/agent-run.js");
|
|
829
|
+
await agentSchedule(opts);
|
|
830
|
+
});
|
|
831
|
+
agent
|
|
832
|
+
.command("tick")
|
|
833
|
+
.description("Check due schedules and run them — wire this to crontab: `0 * * * * synap agent tick`")
|
|
834
|
+
.option("--dry-run", "Show what would run without executing")
|
|
835
|
+
.option("--pod-url <url>", "Override pod URL")
|
|
836
|
+
.option("--api-key <key>", "Override API key")
|
|
837
|
+
.action(async (opts) => {
|
|
838
|
+
const { agentTick } = await import("./commands/agent-run.js");
|
|
839
|
+
await agentTick(opts);
|
|
840
|
+
});
|
|
841
|
+
// ─── automation ──────────────────────────────────────────────────────────────
|
|
842
|
+
function collect(val, prev) { return [...prev, val]; }
|
|
843
|
+
const automation = program
|
|
844
|
+
.command("automation")
|
|
845
|
+
.description("Create, manage, and inspect pod automations");
|
|
846
|
+
automation
|
|
847
|
+
.command("list")
|
|
848
|
+
.description("List automations on the pod")
|
|
849
|
+
.option("--workspace <id>", "Filter by workspace")
|
|
850
|
+
.option("--status <status>", "Filter by status (active|draft|paused|error)")
|
|
851
|
+
.option("--json", "Output raw JSON")
|
|
852
|
+
.action(async (opts) => {
|
|
853
|
+
const { automationList } = await import("./commands/automation.js");
|
|
854
|
+
await automationList(opts);
|
|
855
|
+
});
|
|
856
|
+
automation
|
|
857
|
+
.command("describe <id>")
|
|
858
|
+
.description("Show full details of an automation")
|
|
859
|
+
.option("--workspace <id>")
|
|
860
|
+
.option("--json")
|
|
861
|
+
.action(async (id, opts) => {
|
|
862
|
+
const { automationDescribe } = await import("./commands/automation.js");
|
|
863
|
+
await automationDescribe(id, opts);
|
|
864
|
+
});
|
|
865
|
+
automation
|
|
866
|
+
.command("create")
|
|
867
|
+
.description("Create an automation (quick flags or --from file.yaml)")
|
|
868
|
+
.option("--name <name>", "Automation name (required in quick mode)")
|
|
869
|
+
.option("--trigger <spec>", "event:<pattern> | cron:<expr> | webhook | manual")
|
|
870
|
+
.option("--filter <kv>", "key=value filter (event triggers, repeatable)", collect, [])
|
|
871
|
+
.option("--action <type>", "notify | channel-message | none (default: none)")
|
|
872
|
+
.option("--message <text>", "Message content for notify/channel-message")
|
|
873
|
+
.option("--channel <id>", "Channel ID for channel-message action")
|
|
874
|
+
.option("--status <status>", "draft (default) | active")
|
|
875
|
+
.option("--description <text>", "Description")
|
|
876
|
+
.option("--workspace <id>", "Workspace ID")
|
|
877
|
+
.option("--from <file>", "Create from YAML/JSON file instead of flags")
|
|
878
|
+
.action(async (opts) => {
|
|
879
|
+
const { automationCreate } = await import("./commands/automation.js");
|
|
880
|
+
await automationCreate(opts);
|
|
881
|
+
});
|
|
882
|
+
automation
|
|
883
|
+
.command("enable <id>")
|
|
884
|
+
.description("Activate an automation")
|
|
885
|
+
.option("--workspace <id>")
|
|
886
|
+
.action(async (id, opts) => {
|
|
887
|
+
const { automationEnable } = await import("./commands/automation.js");
|
|
888
|
+
await automationEnable(id, opts);
|
|
889
|
+
});
|
|
890
|
+
automation
|
|
891
|
+
.command("disable <id>")
|
|
892
|
+
.description("Pause an automation")
|
|
893
|
+
.option("--workspace <id>")
|
|
894
|
+
.action(async (id, opts) => {
|
|
895
|
+
const { automationDisable } = await import("./commands/automation.js");
|
|
896
|
+
await automationDisable(id, opts);
|
|
897
|
+
});
|
|
898
|
+
automation
|
|
899
|
+
.command("delete <id>")
|
|
900
|
+
.description("Delete an automation")
|
|
901
|
+
.option("--workspace <id>")
|
|
902
|
+
.option("--force", "Skip confirmation prompt")
|
|
903
|
+
.action(async (id, opts) => {
|
|
904
|
+
const { automationDelete } = await import("./commands/automation.js");
|
|
905
|
+
await automationDelete(id, opts);
|
|
906
|
+
});
|
|
907
|
+
automation
|
|
908
|
+
.command("schema")
|
|
909
|
+
.description("Fetch the automation DSL schema from the pod (AI context)")
|
|
910
|
+
.option("--write-context [path]", "Write markdown context file for Claude Code")
|
|
911
|
+
.option("--json", "Output raw JSON instead of formatted markdown")
|
|
912
|
+
.action(async (opts) => {
|
|
913
|
+
const { automationSchema } = await import("./commands/automation.js");
|
|
914
|
+
await automationSchema(opts);
|
|
915
|
+
});
|
|
916
|
+
// ─── graph ────────────────────────────────────────────────────────────────────
|
|
917
|
+
program
|
|
918
|
+
.command("graph")
|
|
919
|
+
.description("Low-level BFS graph traversal from an entity (prefer `synap ask` — graph is one of its signals)")
|
|
920
|
+
.requiredOption("--entity <id>", "Start entity ID")
|
|
921
|
+
.option("--depth <n>", "Traversal depth (max 3)", "2")
|
|
922
|
+
.option("--json", "Raw JSON output")
|
|
923
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
924
|
+
.option("--api-key <key>", "API key override")
|
|
925
|
+
.action(async (opts) => {
|
|
926
|
+
const { graphTraverse } = await import("./commands/graph.js");
|
|
927
|
+
await graphTraverse(opts);
|
|
928
|
+
});
|
|
929
|
+
// ─── events ───────────────────────────────────────────────────────────────────
|
|
930
|
+
program
|
|
931
|
+
.command("events")
|
|
932
|
+
.description("Show event chain for an entity or recent pod events")
|
|
933
|
+
.option("--entity <id>", "Filter by entity ID (subjectId)")
|
|
934
|
+
.option("--limit <n>", "Number of events", "20")
|
|
935
|
+
.option("--json", "Raw JSON output")
|
|
936
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
937
|
+
.option("--api-key <key>", "API key override")
|
|
938
|
+
.action(async (opts) => {
|
|
939
|
+
const { listEvents } = await import("./commands/events.js");
|
|
940
|
+
await listEvents(opts);
|
|
941
|
+
});
|
|
942
|
+
// ─── view ─────────────────────────────────────────────────────────────────────
|
|
943
|
+
const view = program
|
|
944
|
+
.command("view")
|
|
945
|
+
.description("Manage views");
|
|
946
|
+
view
|
|
947
|
+
.command("create")
|
|
948
|
+
.description("Create a view (table, kanban, bento, …)")
|
|
949
|
+
.requiredOption("--type <type>", "View type: table|kanban|bento|list|grid|gallery|calendar|masonry|flow|matrix|branch_tree|whiteboard")
|
|
950
|
+
.option("--profile <slug>", "Entity profile to display (passed as profileId)")
|
|
951
|
+
.option("--name <name>", "View name")
|
|
952
|
+
.option("--workspace <id>", "Workspace ID")
|
|
953
|
+
.option("--json", "JSON output")
|
|
954
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
955
|
+
.option("--api-key <key>", "API key override")
|
|
956
|
+
.action(async (opts) => {
|
|
957
|
+
const { viewCreate } = await import("./commands/view.js");
|
|
958
|
+
await viewCreate(opts);
|
|
959
|
+
});
|
|
960
|
+
view
|
|
961
|
+
.command("list", { isDefault: true })
|
|
962
|
+
.description("List views in the active workspace")
|
|
963
|
+
.option("--type <type>", "Filter by view type (e.g. whiteboard, kanban, calendar)")
|
|
964
|
+
.option("--workspace <id>", "Workspace ID")
|
|
965
|
+
.option("--json", "JSON output")
|
|
966
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
967
|
+
.option("--api-key <key>", "API key override")
|
|
968
|
+
.action(async (opts) => {
|
|
969
|
+
const { viewList } = await import("./commands/view.js");
|
|
970
|
+
await viewList(opts);
|
|
971
|
+
});
|
|
972
|
+
view
|
|
973
|
+
.command("arrange <viewId>")
|
|
974
|
+
.description("Replace the widget arrangement of a bento view")
|
|
975
|
+
.option("--file <path>", "JSON file containing widget layout (array or { widgets: [...] })")
|
|
976
|
+
.option("--workspace <id>", "Workspace ID")
|
|
977
|
+
.option("--json", "JSON output")
|
|
978
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
979
|
+
.option("--api-key <key>", "API key override")
|
|
980
|
+
.addHelpText("after", `
|
|
981
|
+
Examples:
|
|
982
|
+
synap view arrange <viewId> --file layout.json
|
|
983
|
+
echo '[{"id":"w1","kind":"widget","x":0,"y":0,"w":6,"h":4}]' | synap view arrange <viewId>
|
|
984
|
+
|
|
985
|
+
Layout format (array of BentoWidget):
|
|
986
|
+
[{ "id": "<widgetId>", "kind": "widget|view|entity", "x": 0, "y": 0, "w": 6, "h": 4, "config": {} }]
|
|
987
|
+
`)
|
|
988
|
+
.action(async (viewId, opts) => {
|
|
989
|
+
const { viewArrange } = await import("./commands/view.js");
|
|
990
|
+
await viewArrange(viewId, opts);
|
|
991
|
+
});
|
|
992
|
+
// ─── explain ──────────────────────────────────────────────────────────────────
|
|
993
|
+
program
|
|
994
|
+
.command("explain [topic]")
|
|
995
|
+
.description("Full capability map — what Synap can do and how (no network required)")
|
|
996
|
+
.action(async (topic) => {
|
|
997
|
+
const { explain } = await import("./commands/explain.js");
|
|
998
|
+
await explain({ topic });
|
|
999
|
+
});
|
|
1000
|
+
// ─── open ─────────────────────────────────────────────────────────────────────
|
|
1001
|
+
program
|
|
1002
|
+
.command("open <kind> <id>")
|
|
1003
|
+
.description("Open an entity, view, cell, or document in the Synap desktop app")
|
|
1004
|
+
.action(async (kind, id) => {
|
|
1005
|
+
if (kind !== "entity" && kind !== "view" && kind !== "cell" && kind !== "document") {
|
|
1006
|
+
console.error(`Unknown kind: "${kind}". Use: entity | view | cell | document`);
|
|
1007
|
+
process.exit(1);
|
|
1008
|
+
}
|
|
1009
|
+
const { openInBrowser } = await import("./commands/open.js");
|
|
1010
|
+
await openInBrowser({ kind: kind, id });
|
|
1011
|
+
});
|
|
1012
|
+
// ─── doc ──────────────────────────────────────────────────────────────────────
|
|
1013
|
+
const doc = program
|
|
1014
|
+
.command("doc")
|
|
1015
|
+
.description("Create and update markdown documents on the pod");
|
|
1016
|
+
doc
|
|
1017
|
+
.command("create")
|
|
1018
|
+
.description("Create a new markdown document")
|
|
1019
|
+
.requiredOption("--title <title>", "Document title")
|
|
1020
|
+
.option("--content <text>", "Markdown content (inline)")
|
|
1021
|
+
.option("--file <path>", "Read content from a file")
|
|
1022
|
+
.option("--workspace <id>", "Workspace to create the document in")
|
|
1023
|
+
.option("--open", "Open in the Synap desktop app after creation")
|
|
1024
|
+
.option("--json", "JSON output")
|
|
1025
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1026
|
+
.option("--api-key <key>", "API key override")
|
|
1027
|
+
.addHelpText("after", `
|
|
1028
|
+
Examples:
|
|
1029
|
+
synap doc create --title "My Notes" --content "# Hello"
|
|
1030
|
+
synap doc create --title "My Notes" --file ./notes.md --open
|
|
1031
|
+
echo "# Draft" | synap doc create --title "Draft"
|
|
1032
|
+
`)
|
|
1033
|
+
.action(async (opts) => {
|
|
1034
|
+
const { docCreate } = await import("./commands/doc.js");
|
|
1035
|
+
await docCreate(opts);
|
|
1036
|
+
});
|
|
1037
|
+
doc
|
|
1038
|
+
.command("update <documentId>")
|
|
1039
|
+
.description("Update a document's content (full replacement, proposal-gated)")
|
|
1040
|
+
.option("--content <text>", "New markdown content (inline)")
|
|
1041
|
+
.option("--file <path>", "Read new content from a file")
|
|
1042
|
+
.option("--title <title>", "Update document title (requires --content too)")
|
|
1043
|
+
.option("--open", "Open in the Synap desktop app after update")
|
|
1044
|
+
.option("--json", "JSON output")
|
|
1045
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1046
|
+
.option("--api-key <key>", "API key override")
|
|
1047
|
+
.addHelpText("after", `
|
|
1048
|
+
Examples:
|
|
1049
|
+
synap doc update <id> --content "# Updated"
|
|
1050
|
+
synap doc update <id> --file ./notes.md
|
|
1051
|
+
cat notes.md | synap doc update <id>
|
|
1052
|
+
`)
|
|
1053
|
+
.action(async (documentId, opts) => {
|
|
1054
|
+
const { docUpdate } = await import("./commands/doc.js");
|
|
1055
|
+
await docUpdate(documentId, opts);
|
|
1056
|
+
});
|
|
1057
|
+
// ─── cell ─────────────────────────────────────────────────────────────────────
|
|
1058
|
+
const cell = program
|
|
1059
|
+
.command("cell")
|
|
1060
|
+
.description("Define and bundle frame cells for the Synap runtime");
|
|
1061
|
+
cell
|
|
1062
|
+
.command("define")
|
|
1063
|
+
.description("Create or update a frame cell on the pod from ESM source")
|
|
1064
|
+
.requiredOption("--name <name>", "Cell display name")
|
|
1065
|
+
.option("--file <path>", "ESM source file (or pipe stdin)")
|
|
1066
|
+
.option("--type-key <key>", "Explicit typeKey (default: generated:<slug>)")
|
|
1067
|
+
.option("--deps <json>", 'Dependency map JSON, e.g. \'{"recharts":"2.12.0"}\' (sent in payload; backend support pending)')
|
|
1068
|
+
.option("--workspace <id>", "Workspace to scope the cell to (omit for pod-global)")
|
|
1069
|
+
.option("--description <text>", "Short description")
|
|
1070
|
+
.option("--open", "Open in the Synap desktop app after define")
|
|
1071
|
+
.option("--json", "JSON output")
|
|
1072
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1073
|
+
.option("--api-key <key>", "API key override")
|
|
1074
|
+
.addHelpText("after", `
|
|
1075
|
+
Examples:
|
|
1076
|
+
synap cell define --name "Revenue Chart" --file ./chart.js
|
|
1077
|
+
synap cell define --name "Revenue Chart" --file ./chart.js --deps '{"recharts":"2.12.0"}'
|
|
1078
|
+
cat chart.js | synap cell define --name "Revenue Chart"
|
|
1079
|
+
`)
|
|
1080
|
+
.action(async (opts) => {
|
|
1081
|
+
const { cellDefine } = await import("./commands/cell.js");
|
|
1082
|
+
await cellDefine(opts);
|
|
1083
|
+
});
|
|
1084
|
+
cell
|
|
1085
|
+
.command("build <entry>")
|
|
1086
|
+
.description("Bundle a multi-file cell/app into a single ESM module the runtime expects")
|
|
1087
|
+
.option("--out <file>", "Output file path (default: <entry>.bundle.js)")
|
|
1088
|
+
.option("--define", "Chain into cell define after bundling (requires --name)")
|
|
1089
|
+
.option("--name <name>", "Cell name (required with --define)")
|
|
1090
|
+
.option("--type-key <key>", "Explicit typeKey (used with --define)")
|
|
1091
|
+
.option("--deps <json>", "Override dependency versions as JSON, e.g. '{\"react\":\"18.3.0\"}'")
|
|
1092
|
+
.option("--workspace <id>", "Workspace (used with --define)")
|
|
1093
|
+
.option("--description <text>", "Description (used with --define)")
|
|
1094
|
+
.option("--open", "Open in browser after define (used with --define)")
|
|
1095
|
+
.option("--json", "JSON output")
|
|
1096
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1097
|
+
.option("--api-key <key>", "API key override")
|
|
1098
|
+
.addHelpText("after", `
|
|
1099
|
+
Output: a single ESM file. Bare imports (react, recharts, …) are externalized
|
|
1100
|
+
and emitted as a deps map. At runtime Synap resolves them via esm.sh importmap.
|
|
1101
|
+
|
|
1102
|
+
Examples:
|
|
1103
|
+
synap cell build ./src/chart.tsx --out ./dist/chart.js
|
|
1104
|
+
synap cell build ./src/chart.tsx --out ./dist/chart.js --define --name "Revenue Chart"
|
|
1105
|
+
`)
|
|
1106
|
+
.action(async (entry, opts) => {
|
|
1107
|
+
const { cellBuild } = await import("./commands/cell.js");
|
|
1108
|
+
await cellBuild(entry, opts);
|
|
1109
|
+
});
|
|
1110
|
+
// ─── artifact ─────────────────────────────────────────────────────────────────
|
|
1111
|
+
const artifact = program
|
|
1112
|
+
.command("artifact")
|
|
1113
|
+
.description("Create and manage HTML artifacts as Synap documents");
|
|
1114
|
+
artifact
|
|
1115
|
+
.command("create")
|
|
1116
|
+
.description("Create an HTML artifact from a local file")
|
|
1117
|
+
.requiredOption("--html <file>", "HTML file to upload")
|
|
1118
|
+
.option("--name <name>", "Document title (default: filename)")
|
|
1119
|
+
.option("--workspace <id>", "Workspace context")
|
|
1120
|
+
.option("--open", "Open in the Synap desktop app after creation")
|
|
1121
|
+
.option("--json", "JSON output")
|
|
1122
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1123
|
+
.option("--api-key <key>", "API key override")
|
|
1124
|
+
.action(async (opts) => {
|
|
1125
|
+
const { artifactCreate } = await import("./commands/artifact.js");
|
|
1126
|
+
await artifactCreate(opts);
|
|
1127
|
+
});
|
|
1128
|
+
// ─── connect (top-level shorthand) ───────────────────────────────────────────
|
|
1129
|
+
program
|
|
1130
|
+
.command("connect-service [service]")
|
|
1131
|
+
.description("Connect an external service (Google, GitHub, Notion, Linear, Slack, …)")
|
|
1132
|
+
.option("--workspace <id>", "Workspace context")
|
|
1133
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1134
|
+
.option("--api-key <key>", "API key override")
|
|
1135
|
+
.action(async (service, opts) => {
|
|
1136
|
+
const { connectorsConnect } = await import("./commands/connectors.js");
|
|
1137
|
+
await connectorsConnect(service, opts);
|
|
1138
|
+
});
|
|
1139
|
+
// ─── connectors ──────────────────────────────────────────────────────────────
|
|
1140
|
+
const connectors = program
|
|
1141
|
+
.command("connectors")
|
|
1142
|
+
.description("Manage pod connector integrations (Nango-powered)");
|
|
1143
|
+
connectors
|
|
1144
|
+
.command("list")
|
|
1145
|
+
.description("List available connectors and connection status")
|
|
1146
|
+
.option("--json", "Output as JSON")
|
|
1147
|
+
.option("--workspace <id>", "Workspace context")
|
|
1148
|
+
.action(async (opts) => {
|
|
1149
|
+
const { connectorsList } = await import("./commands/connectors.js");
|
|
1150
|
+
await connectorsList(opts);
|
|
1151
|
+
});
|
|
1152
|
+
connectors
|
|
1153
|
+
.command("sync <provider>")
|
|
1154
|
+
.description("Trigger a manual sync for a connected provider")
|
|
1155
|
+
.option("--workspace <id>", "Workspace context")
|
|
1156
|
+
.action(async (provider, opts) => {
|
|
1157
|
+
const { connectorsSync } = await import("./commands/connectors.js");
|
|
1158
|
+
await connectorsSync(provider, opts);
|
|
1159
|
+
});
|
|
1160
|
+
connectors
|
|
1161
|
+
.command("disconnect <provider>")
|
|
1162
|
+
.description("Revoke a connector connection")
|
|
1163
|
+
.option("--workspace <id>", "Workspace context")
|
|
1164
|
+
.option("--force", "Skip confirmation")
|
|
1165
|
+
.action(async (provider, opts) => {
|
|
1166
|
+
const { connectorsDisconnect } = await import("./commands/connectors.js");
|
|
1167
|
+
await connectorsDisconnect(provider, opts);
|
|
1168
|
+
});
|
|
1169
|
+
connectors
|
|
1170
|
+
.command("schema")
|
|
1171
|
+
.description("Fetch connector schema and supported providers (AI context)")
|
|
1172
|
+
.option("--write-context [path]", "Write to .claude/CONNECTOR_CONTEXT.md")
|
|
1173
|
+
.option("--json", "Output raw JSON instead of formatted markdown")
|
|
1174
|
+
.action(async (opts) => {
|
|
1175
|
+
const { connectorsSchema } = await import("./commands/connectors.js");
|
|
1176
|
+
await connectorsSchema(opts);
|
|
1177
|
+
});
|
|
1178
|
+
// ─── providers ───────────────────────────────────────────────────────────────
|
|
1179
|
+
const providers = program
|
|
1180
|
+
.command("providers")
|
|
1181
|
+
.description("Discover AI providers from the pod and configure local tools");
|
|
1182
|
+
providers
|
|
1183
|
+
.command("list", { isDefault: true })
|
|
1184
|
+
.description("Show enabled AI providers and their models")
|
|
1185
|
+
.option("--json", "Output as JSON")
|
|
1186
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1187
|
+
.option("--api-key <key>", "API key override")
|
|
1188
|
+
.action(async (opts) => {
|
|
1189
|
+
const { providersList } = await import("./commands/providers.js");
|
|
1190
|
+
await providersList(opts);
|
|
1191
|
+
});
|
|
1192
|
+
providers
|
|
1193
|
+
.command("pull")
|
|
1194
|
+
.description("Write pod provider config to a local AI tool (opencode, aider)")
|
|
1195
|
+
.option("--target <name>", "Target tool: opencode | aider")
|
|
1196
|
+
.option("--pod-url <url>", "Pod URL override")
|
|
1197
|
+
.option("--api-key <key>", "API key override")
|
|
1198
|
+
.action(async (opts) => {
|
|
1199
|
+
const { providersPull } = await import("./commands/providers.js");
|
|
1200
|
+
await providersPull(opts);
|
|
1201
|
+
});
|
|
1202
|
+
// ─── keys ────────────────────────────────────────────────────────────────────
|
|
1203
|
+
const keys = program
|
|
1204
|
+
.command("keys")
|
|
1205
|
+
.description("Manage pod API keys");
|
|
1206
|
+
keys
|
|
1207
|
+
.command("rotate")
|
|
1208
|
+
.description("Rotate your CLI key to pick up the latest scope set")
|
|
1209
|
+
.action(async () => {
|
|
1210
|
+
const { keysRotate } = await import("./commands/keys.js");
|
|
1211
|
+
await keysRotate({});
|
|
1212
|
+
});
|
|
596
1213
|
program.parse();
|
|
597
1214
|
//# sourceMappingURL=index.js.map
|