cool-workflow 0.1.91 → 0.1.93
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +111 -434
- package/apps/architecture-review/app.json +1 -1
- package/apps/architecture-review-fast/app.json +1 -1
- package/apps/architecture-review-fast/workflow.js +15 -2
- package/apps/end-to-end-golden-path/app.json +1 -1
- package/apps/pr-review-fix-ci/app.json +1 -1
- package/apps/release-cut/app.json +1 -1
- package/apps/research-synthesis/app.json +1 -1
- package/apps/research-synthesis/workflow.js +1 -1
- package/dist/capability-core.js +47 -0
- package/dist/capability-registry.js +2 -0
- package/dist/cli/command-surface.js +165 -1352
- package/dist/cli/format.js +56 -0
- package/dist/cli/handlers/audit.js +82 -0
- package/dist/cli/handlers/blackboard.js +81 -0
- package/dist/cli/handlers/candidate.js +40 -0
- package/dist/cli/handlers/clones.js +34 -0
- package/dist/cli/handlers/collaboration.js +61 -0
- package/dist/cli/handlers/eval.js +40 -0
- package/dist/cli/handlers/maintenance.js +107 -0
- package/dist/cli/handlers/multi-agent.js +165 -0
- package/dist/cli/handlers/node.js +41 -0
- package/dist/cli/handlers/operational.js +155 -0
- package/dist/cli/handlers/operator.js +146 -0
- package/dist/cli/handlers/registry.js +68 -0
- package/dist/cli/handlers/run.js +153 -0
- package/dist/cli/handlers/scheduling.js +126 -0
- package/dist/cli/handlers/workbench.js +41 -0
- package/dist/cli/handlers/worker.js +45 -0
- package/dist/cli/io.js +27 -0
- package/dist/cli/run-summary.js +45 -0
- package/dist/commit.js +0 -5
- package/dist/doctor.js +1 -0
- package/dist/execution-backend.js +0 -11
- package/dist/mcp/tool-call.js +2 -0
- package/dist/mcp/tool-definitions.js +8 -0
- package/dist/orchestrator/app-operations.js +205 -0
- package/dist/orchestrator/report.js +6 -1
- package/dist/orchestrator.js +41 -153
- package/dist/state-explosion.js +0 -7
- package/dist/term.js +0 -18
- package/dist/validation.js +0 -21
- package/dist/version.js +1 -1
- package/docs/agent-delegation-drive.7.md +2 -0
- package/docs/canonical-workflow-apps.7.md +12 -0
- package/docs/cli-mcp-parity.7.md +18 -1
- package/docs/contract-migration-tooling.7.md +2 -0
- package/docs/control-plane-scheduling.7.md +2 -0
- package/docs/durable-state-and-locking.7.md +2 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +2 -0
- package/docs/execution-backends.7.md +2 -0
- package/docs/mcp-app-surface.7.md +12 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +2 -0
- package/docs/multi-agent-eval-replay-harness.7.md +2 -0
- package/docs/multi-agent-operator-ux.7.md +2 -0
- package/docs/node-snapshot-diff-replay.7.md +2 -0
- package/docs/observability-cost-accounting.7.md +2 -0
- package/docs/project-index.md +15 -3
- package/docs/real-execution-backends.7.md +2 -0
- package/docs/release-and-migration.7.md +2 -0
- package/docs/release-tooling.7.md +11 -0
- package/docs/run-registry-control-plane.7.md +26 -2
- package/docs/run-retention-reclamation.7.md +2 -0
- package/docs/state-explosion-management.7.md +2 -0
- package/docs/team-collaboration.7.md +2 -0
- package/docs/web-desktop-workbench.7.md +2 -0
- package/manifest/plugin.manifest.json +1 -1
- package/package.json +3 -1
- package/scripts/agents/agent-adapter-core.js +179 -28
- package/scripts/agents/claude-p-agent.js +24 -7
- package/scripts/agents/codex-agent.js +1 -1
- package/scripts/agents/gemini-agent.js +1 -1
- package/scripts/agents/opencode-agent.js +1 -1
- package/scripts/architecture-review-fast.js +19 -5
- package/scripts/bump-version.js +20 -1
- package/scripts/canonical-apps.js +4 -4
- package/scripts/dogfood-release.js +1 -1
- package/scripts/golden-path.js +4 -4
- package/scripts/parity-check.js +9 -1
- package/scripts/release-check.js +5 -1
- package/scripts/sync-readme.js +123 -0
- package/scripts/version-sync-check.js +10 -1
|
@@ -43,22 +43,29 @@ const node_child_process_1 = require("node:child_process");
|
|
|
43
43
|
const readline = __importStar(require("node:readline"));
|
|
44
44
|
const orchestrator_1 = require("../orchestrator");
|
|
45
45
|
const capability_core_1 = require("../capability-core");
|
|
46
|
-
const observability_1 = require("../observability");
|
|
47
|
-
const telemetry_demo_1 = require("../telemetry-demo");
|
|
48
|
-
const run_registry_1 = require("../run-registry");
|
|
49
|
-
const daemon_1 = require("../daemon");
|
|
50
46
|
const scheduler_1 = require("../scheduler");
|
|
51
47
|
const triggers_1 = require("../triggers");
|
|
52
|
-
const
|
|
53
|
-
const
|
|
48
|
+
const io_1 = require("./io");
|
|
49
|
+
const run_summary_1 = require("./run-summary");
|
|
50
|
+
const audit_1 = require("./handlers/audit");
|
|
51
|
+
const candidate_1 = require("./handlers/candidate");
|
|
52
|
+
const operator_1 = require("./handlers/operator");
|
|
53
|
+
const registry_1 = require("./handlers/registry");
|
|
54
|
+
const multi_agent_1 = require("./handlers/multi-agent");
|
|
55
|
+
const run_1 = require("./handlers/run");
|
|
56
|
+
const collaboration_1 = require("./handlers/collaboration");
|
|
57
|
+
const blackboard_1 = require("./handlers/blackboard");
|
|
58
|
+
const eval_1 = require("./handlers/eval");
|
|
59
|
+
const node_1 = require("./handlers/node");
|
|
60
|
+
const maintenance_1 = require("./handlers/maintenance");
|
|
61
|
+
const operational_1 = require("./handlers/operational");
|
|
62
|
+
const scheduling_1 = require("./handlers/scheduling");
|
|
63
|
+
const worker_1 = require("./handlers/worker");
|
|
64
|
+
const clones_1 = require("./handlers/clones");
|
|
65
|
+
const workbench_1 = require("./handlers/workbench");
|
|
54
66
|
const operator_ux_1 = require("../operator-ux");
|
|
55
|
-
const multi_agent_operator_ux_1 = require("../multi-agent-operator-ux");
|
|
56
|
-
const multi_agent_eval_1 = require("../multi-agent-eval");
|
|
57
|
-
const state_explosion_1 = require("../state-explosion");
|
|
58
|
-
const evidence_reasoning_1 = require("../evidence-reasoning");
|
|
59
67
|
const doctor_1 = require("../doctor");
|
|
60
68
|
const orchestrator_2 = require("../orchestrator");
|
|
61
|
-
const reporter_1 = require("../reporter");
|
|
62
69
|
const version_1 = require("../version");
|
|
63
70
|
async function runCli(argv = process.argv.slice(2)) {
|
|
64
71
|
const args = (0, orchestrator_1.parseArgv)(argv);
|
|
@@ -96,6 +103,13 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
96
103
|
process.env.CW_NO_COLOR = "1";
|
|
97
104
|
if (args.options.full)
|
|
98
105
|
process.env.CW_OUTPUT = "full";
|
|
106
|
+
// `cw <verb> --help` / `-h` -> per-command help (the verb's subcommands +
|
|
107
|
+
// one-line summaries), derived from the capability registry. Additive: the
|
|
108
|
+
// bare `cw` / `cw --help` top-level help is handled above.
|
|
109
|
+
if ((args.options.help || args.options.h) && args.command && !args.command.startsWith("-")) {
|
|
110
|
+
process.stdout.write((0, orchestrator_1.formatCommandHelp)(args.command) + "\n");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
99
113
|
// Bare -q / --question -> redirect to quickstart (auto-detect repo/agent/app).
|
|
100
114
|
// CONSUME the positional (shift) so the question never survives as positionals[0]
|
|
101
115
|
// — otherwise the quickstart handler reads it as the app id ("Workflow app not found").
|
|
@@ -113,7 +127,11 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
113
127
|
const scheduler = new scheduler_1.Scheduler(String(args.options.cwd || process.cwd()));
|
|
114
128
|
const triggers = new triggers_1.RoutineTriggerBridge(String(args.options.cwd || process.cwd()));
|
|
115
129
|
switch (args.command) {
|
|
116
|
-
case "help":
|
|
130
|
+
case "help": {
|
|
131
|
+
const [topic] = args.positionals;
|
|
132
|
+
process.stdout.write((topic ? (0, orchestrator_1.formatCommandHelp)(topic) : (0, orchestrator_1.formatHelp)()) + "\n");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
117
135
|
case undefined:
|
|
118
136
|
process.stdout.write((0, orchestrator_1.formatHelp)() + "\n");
|
|
119
137
|
return;
|
|
@@ -141,7 +159,7 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
141
159
|
return;
|
|
142
160
|
}
|
|
143
161
|
case "list":
|
|
144
|
-
printJson(runner.listWorkflows());
|
|
162
|
+
(0, io_1.printJson)(runner.listWorkflows());
|
|
145
163
|
return;
|
|
146
164
|
case "search": {
|
|
147
165
|
const keyword = args.positionals.join(" ");
|
|
@@ -150,8 +168,8 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
150
168
|
const apps = runner.listApps();
|
|
151
169
|
const lower = keyword.toLowerCase();
|
|
152
170
|
const results = apps.filter((a) => a.title.toLowerCase().includes(lower) || a.summary.toLowerCase().includes(lower) || a.id.toLowerCase().includes(lower)).map((a) => ({ id: a.id, title: a.title, summary: a.summary }));
|
|
153
|
-
if (wantsJson(args.options))
|
|
154
|
-
printJson(results);
|
|
171
|
+
if ((0, io_1.wantsJson)(args.options))
|
|
172
|
+
(0, io_1.printJson)(results);
|
|
155
173
|
else
|
|
156
174
|
process.stdout.write(`${(0, orchestrator_2.formatSearchResults)(keyword, results)}\n`);
|
|
157
175
|
return;
|
|
@@ -186,16 +204,16 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
186
204
|
if (!appId)
|
|
187
205
|
throw new Error("Missing workflow app id.\n Tip: list apps with \"cw list\", then \"cw info <id>\" for details");
|
|
188
206
|
const data = runner.showApp(appId);
|
|
189
|
-
if (wantsJson(args.options))
|
|
190
|
-
printJson(data);
|
|
207
|
+
if ((0, io_1.wantsJson)(args.options))
|
|
208
|
+
(0, io_1.printJson)(data);
|
|
191
209
|
else
|
|
192
210
|
process.stdout.write(`${(0, orchestrator_2.formatInfo)(appId, data)}\n`);
|
|
193
211
|
return;
|
|
194
212
|
}
|
|
195
213
|
case "doctor": {
|
|
196
214
|
const report = (0, doctor_1.runDoctor)(args.options, process.env, String(args.options.cwd || process.cwd()));
|
|
197
|
-
if (wantsJson(args.options))
|
|
198
|
-
printJson(report);
|
|
215
|
+
if ((0, io_1.wantsJson)(args.options))
|
|
216
|
+
(0, io_1.printJson)(report);
|
|
199
217
|
else if (args.options.fix)
|
|
200
218
|
process.stdout.write(`${(0, doctor_1.formatDoctorFixes)(report)}\n`);
|
|
201
219
|
else
|
|
@@ -208,33 +226,33 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
208
226
|
const [workflowId] = args.positionals;
|
|
209
227
|
if (!workflowId)
|
|
210
228
|
throw new Error("Missing workflow id.\n Tip: create one with \"cw init my-workflow\" or list with \"cw list\"");
|
|
211
|
-
printJson(runner.init(workflowId, args.options));
|
|
229
|
+
(0, io_1.printJson)(runner.init(workflowId, args.options));
|
|
212
230
|
return;
|
|
213
231
|
}
|
|
214
232
|
case "app": {
|
|
215
233
|
const [subcommand, appIdOrPath] = args.positionals;
|
|
216
234
|
switch (subcommand) {
|
|
217
235
|
case "list":
|
|
218
|
-
printJson(runner.listApps());
|
|
236
|
+
(0, io_1.printJson)(runner.listApps());
|
|
219
237
|
return;
|
|
220
238
|
case "show":
|
|
221
|
-
printJson(runner.showApp(required(appIdOrPath, "app id")));
|
|
239
|
+
(0, io_1.printJson)(runner.showApp((0, io_1.required)(appIdOrPath, "app id")));
|
|
222
240
|
return;
|
|
223
241
|
case "validate": {
|
|
224
|
-
const result = runner.validateApp(required(appIdOrPath, "app path or id"));
|
|
225
|
-
printJson(result);
|
|
242
|
+
const result = runner.validateApp((0, io_1.required)(appIdOrPath, "app path or id"));
|
|
243
|
+
(0, io_1.printJson)(result);
|
|
226
244
|
if (!result.valid)
|
|
227
245
|
process.exitCode = 1;
|
|
228
246
|
return;
|
|
229
247
|
}
|
|
230
248
|
case "init":
|
|
231
|
-
printJson(runner.initApp(required(appIdOrPath, "app id"), args.options));
|
|
249
|
+
(0, io_1.printJson)(runner.initApp((0, io_1.required)(appIdOrPath, "app id"), args.options));
|
|
232
250
|
return;
|
|
233
251
|
case "package":
|
|
234
|
-
printJson(runner.packageApp(required(appIdOrPath, "app id"), args.options));
|
|
252
|
+
(0, io_1.printJson)(runner.packageApp((0, io_1.required)(appIdOrPath, "app id"), args.options));
|
|
235
253
|
return;
|
|
236
254
|
case "run":
|
|
237
|
-
printJson((0, capability_core_1.appRun)(runner, { ...args.options, appId: required(appIdOrPath, "app id") }));
|
|
255
|
+
(0, io_1.printJson)((0, capability_core_1.appRun)(runner, { ...args.options, appId: (0, io_1.required)(appIdOrPath, "app id") }));
|
|
238
256
|
return;
|
|
239
257
|
default:
|
|
240
258
|
throw new Error("Usage: cw.js app list|show|validate|init|package|run [app-id|path]");
|
|
@@ -247,18 +265,18 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
247
265
|
// DELEGATES worker execution to the operator's configured agent backend and
|
|
248
266
|
// fails closed (status=blocked) when none is set. No new executor/scheduler.
|
|
249
267
|
const [appId] = args.positionals;
|
|
250
|
-
const runId = optionalArg(args.options.run) || optionalArg(args.options.runId);
|
|
268
|
+
const runId = (0, io_1.optionalArg)(args.options.run) || (0, io_1.optionalArg)(args.options.runId);
|
|
251
269
|
await promptQuestion(args.options);
|
|
252
270
|
const qs = (0, capability_core_1.quickstart)(runner, { ...args.options, ...(appId ? { appId } : {}), ...(runId ? { runId } : {}) });
|
|
253
|
-
printJson(qs);
|
|
271
|
+
(0, io_1.printJson)(qs);
|
|
254
272
|
const qr = qs;
|
|
255
273
|
// Clean human summary on stderr (TTY-gated, inside the reporter). Suppressed under --json so
|
|
256
274
|
// machine mode emits ONLY the stdout payload — no stderr chrome to parse around. The type
|
|
257
275
|
// guard also skips --check/--preview results (no reportPath of their own). The summary is the
|
|
258
276
|
// COMPACT findings table (re-parsed from each completed worker's cw:result), the report path,
|
|
259
277
|
// and where the per-worker transcripts live — NOT the full prose (that's report.md/--full).
|
|
260
|
-
if (!wantsJson(args.options) && typeof qr.runId === "string" && typeof qr.reportPath === "string") {
|
|
261
|
-
emitRunSummary(runner, args.options, {
|
|
278
|
+
if (!(0, io_1.wantsJson)(args.options) && typeof qr.runId === "string" && typeof qr.reportPath === "string") {
|
|
279
|
+
(0, run_summary_1.emitRunSummary)(runner, args.options, {
|
|
262
280
|
runId: qr.runId,
|
|
263
281
|
reportPath: qr.reportPath,
|
|
264
282
|
status: String(qr.status || ""),
|
|
@@ -283,41 +301,41 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
283
301
|
const [workflowId] = args.positionals;
|
|
284
302
|
if (!workflowId)
|
|
285
303
|
throw new Error("Missing workflow id.\n Tip: plan an architecture review with \"cw plan architecture-review\"");
|
|
286
|
-
printJson((0, capability_core_1.planSummary)(runner, workflowId, args.options));
|
|
304
|
+
(0, io_1.printJson)((0, capability_core_1.planSummary)(runner, workflowId, args.options));
|
|
287
305
|
return;
|
|
288
306
|
}
|
|
289
307
|
case "status":
|
|
290
308
|
if (!args.positionals[0]) {
|
|
291
309
|
const nextActions = (0, operator_ux_1.adviseNoRun)();
|
|
292
|
-
if (wantsJson(args.options))
|
|
293
|
-
printJson({ runId: null, nextActions });
|
|
310
|
+
if ((0, io_1.wantsJson)(args.options))
|
|
311
|
+
(0, io_1.printJson)({ runId: null, nextActions });
|
|
294
312
|
else
|
|
295
313
|
process.stdout.write(`No run selected\n\nNext Action\n${nextActions.map((action) => ` ${action.command}\n reason: ${action.reason}`).join("\n")}\n`);
|
|
296
314
|
}
|
|
297
|
-
else if (wantsJson(args.options))
|
|
298
|
-
printJson(runner.status(args.positionals[0]));
|
|
315
|
+
else if ((0, io_1.wantsJson)(args.options))
|
|
316
|
+
(0, io_1.printJson)(runner.status(args.positionals[0]));
|
|
299
317
|
else {
|
|
300
318
|
const summary = runner.operatorStatus(args.positionals[0]);
|
|
301
319
|
process.stdout.write(`${(args.options.summary || args.options.brief ? (0, operator_ux_1.formatOperatorSummary)(summary) : (0, operator_ux_1.formatOperatorStatus)(summary))}\n`);
|
|
302
320
|
}
|
|
303
321
|
return;
|
|
304
322
|
case "next":
|
|
305
|
-
printJson(runner.next(required(args.positionals[0], "run id"), args.options));
|
|
323
|
+
(0, io_1.printJson)(runner.next((0, io_1.required)(args.positionals[0], "run id"), args.options));
|
|
306
324
|
return;
|
|
307
325
|
case "dispatch":
|
|
308
|
-
printJson(runner.dispatch(required(args.positionals[0], "run id"), args.options));
|
|
326
|
+
(0, io_1.printJson)(runner.dispatch((0, io_1.required)(args.positionals[0], "run id"), args.options));
|
|
309
327
|
return;
|
|
310
328
|
case "result": {
|
|
311
329
|
const [runId, taskId, resultPath] = args.positionals;
|
|
312
|
-
printJson(runner.recordResult(required(runId, "run id"), required(taskId, "task id"), required(resultPath, "result file"), args.options));
|
|
330
|
+
(0, io_1.printJson)(runner.recordResult((0, io_1.required)(runId, "run id"), (0, io_1.required)(taskId, "task id"), (0, io_1.required)(resultPath, "result file"), args.options));
|
|
313
331
|
return;
|
|
314
332
|
}
|
|
315
333
|
case "state": {
|
|
316
334
|
const [subcommand, runId] = args.positionals;
|
|
317
335
|
switch (subcommand) {
|
|
318
336
|
case "check": {
|
|
319
|
-
const report = runner.checkState(required(runId, "run id"), args.options);
|
|
320
|
-
printJson(report);
|
|
337
|
+
const report = runner.checkState((0, io_1.required)(runId, "run id"), args.options);
|
|
338
|
+
(0, io_1.printJson)(report);
|
|
321
339
|
if (report.status === "unsupported")
|
|
322
340
|
process.exitCode = 1;
|
|
323
341
|
return;
|
|
@@ -328,1323 +346,132 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
328
346
|
}
|
|
329
347
|
case "commit":
|
|
330
348
|
if (args.positionals[0] === "summary") {
|
|
331
|
-
const summary = runner.summarizeCommitRecords(required(args.positionals[1], "run id"));
|
|
332
|
-
if (wantsJson(args.options))
|
|
333
|
-
printJson(summary);
|
|
349
|
+
const summary = runner.summarizeCommitRecords((0, io_1.required)(args.positionals[1], "run id"));
|
|
350
|
+
if ((0, io_1.wantsJson)(args.options))
|
|
351
|
+
(0, io_1.printJson)(summary);
|
|
334
352
|
else
|
|
335
353
|
process.stdout.write(`${(0, operator_ux_1.formatCommitSummary)(summary)}\n`);
|
|
336
354
|
return;
|
|
337
355
|
}
|
|
338
|
-
printJson(runner.commit(required(args.positionals[0], "run id"), args.options));
|
|
356
|
+
(0, io_1.printJson)(runner.commit((0, io_1.required)(args.positionals[0], "run id"), args.options));
|
|
339
357
|
return;
|
|
340
|
-
case "report":
|
|
341
|
-
|
|
342
|
-
// `report bundle <run-id>` exports a sealed bundle and self-verifies it;
|
|
343
|
-
// every other `report <run-id>` form prints/inspects a local run's report.
|
|
344
|
-
if (args.positionals[0] === "verify-bundle") {
|
|
345
|
-
const result = (0, capability_core_1.runVerifyReportBundle)(runner, { ...args.options, archive: args.positionals[1] || args.options.archive || args.options.path || args.options.file || args.options.bundle });
|
|
346
|
-
printJson(result);
|
|
347
|
-
// Fail closed: a forged/edited/corrupt bundle verifies false — surface it
|
|
348
|
-
// through the exit code so `cw report verify-bundle <file> && ship` cannot
|
|
349
|
-
// pass on a lie. Mirrors run inspect-archive / telemetry verify.
|
|
350
|
-
if (!result.ok)
|
|
351
|
-
process.exitCode = 1;
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
if (args.positionals[0] === "bundle") {
|
|
355
|
-
const result = (0, capability_core_1.reportBundle)(runner, required(args.positionals[1] || optionalArg(args.options.runId || args.options.run), "run id"), args.options);
|
|
356
|
-
printJson(result);
|
|
357
|
-
// Fail closed: never report a "bundle made" success if the artifact does not
|
|
358
|
-
// self-verify — so `cw report bundle <run> && send-to-client` cannot ship an
|
|
359
|
-
// unverifiable report (e.g. no trust key under --strict-signatures).
|
|
360
|
-
if (!result.ok)
|
|
361
|
-
process.exitCode = 1;
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
const runId = required(args.positionals[0], "run id");
|
|
365
|
-
const report = runner.report(runId);
|
|
366
|
-
if (wantsJson(args.options)) {
|
|
367
|
-
printJson(report);
|
|
368
|
-
}
|
|
369
|
-
else if (args.options.show || args.options.summary) {
|
|
370
|
-
process.stdout.write(`${(0, operator_ux_1.formatOperatorReport)(runner.operatorReport(runId))}\n`);
|
|
371
|
-
process.stdout.write(`\n${(0, state_explosion_1.formatStateExplosionReport)(runner.stateExplosionReport(runId))}\n`);
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
process.stdout.write(`${report.path}\n`);
|
|
375
|
-
}
|
|
358
|
+
case "report":
|
|
359
|
+
(0, operator_1.handleReport)(args, runner);
|
|
376
360
|
return;
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const [subcommand, runId] = args.positionals;
|
|
380
|
-
switch (subcommand) {
|
|
381
|
-
case "status":
|
|
382
|
-
if (wantsJson(args.options))
|
|
383
|
-
printJson(runner.operatorStatus(required(runId, "run id")));
|
|
384
|
-
else {
|
|
385
|
-
const summary = runner.operatorStatus(required(runId, "run id"));
|
|
386
|
-
process.stdout.write(`${(args.options.summary || args.options.brief ? (0, operator_ux_1.formatOperatorSummary)(summary) : (0, operator_ux_1.formatOperatorStatus)(summary))}\n`);
|
|
387
|
-
}
|
|
388
|
-
return;
|
|
389
|
-
case "report":
|
|
390
|
-
if (wantsJson(args.options))
|
|
391
|
-
printJson(runner.operatorReport(required(runId, "run id")));
|
|
392
|
-
else
|
|
393
|
-
process.stdout.write(`${(0, operator_ux_1.formatOperatorReport)(runner.operatorReport(required(runId, "run id")))}\n`);
|
|
394
|
-
return;
|
|
395
|
-
default:
|
|
396
|
-
throw new Error("Usage: cw.js operator status|report <run-id> [--json]");
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
case "graph": {
|
|
400
|
-
const graph = runner.operatorGraph(required(args.positionals[0], "run id"));
|
|
401
|
-
if (wantsJson(args.options))
|
|
402
|
-
printJson(graph);
|
|
403
|
-
else
|
|
404
|
-
process.stdout.write(`${(0, operator_ux_1.formatOperatorGraph)(graph)}\n`);
|
|
361
|
+
case "operator":
|
|
362
|
+
(0, operator_1.handleOperator)(args, runner);
|
|
405
363
|
return;
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const index = runner.summaryRefresh(required(runId, "run id"), args.options);
|
|
454
|
-
if (wantsJson(args.options))
|
|
455
|
-
printJson(index);
|
|
456
|
-
else
|
|
457
|
-
process.stdout.write(`${(0, state_explosion_1.formatStateExplosionReport)(runner.summaryShow(required(runId, "run id")))}\n`);
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
case "show": {
|
|
461
|
-
const report = runner.summaryShow(required(runId, "run id"));
|
|
462
|
-
if (wantsJson(args.options))
|
|
463
|
-
printJson(report);
|
|
464
|
-
else
|
|
465
|
-
process.stdout.write(`${(0, state_explosion_1.formatStateExplosionReport)(report)}\n`);
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
default:
|
|
469
|
-
throw new Error("Usage: cw.js summary refresh|show <run-id> [--json]");
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
case "multi-agent": {
|
|
473
|
-
const [subcommand, runId, id] = args.positionals;
|
|
474
|
-
switch (subcommand) {
|
|
475
|
-
case "status":
|
|
476
|
-
if (wantsJson(args.options))
|
|
477
|
-
printJson(runner.hostMultiAgentStatus(required(runId, "run id")));
|
|
478
|
-
else
|
|
479
|
-
process.stdout.write(`${(0, multi_agent_operator_ux_1.formatMultiAgentOperatorStatus)(runner.multiAgentOperatorStatus(required(runId, "run id")))}\n`);
|
|
480
|
-
return;
|
|
481
|
-
case "step":
|
|
482
|
-
printJson(runner.hostMultiAgentStep(required(runId, "run id"), args.options));
|
|
483
|
-
return;
|
|
484
|
-
case "blackboard":
|
|
485
|
-
printJson(runner.hostMultiAgentBlackboard(required(runId, "run id"), id, args.options));
|
|
486
|
-
return;
|
|
487
|
-
case "score":
|
|
488
|
-
printJson(runner.hostMultiAgentScore(required(runId, "run id"), { ...args.options, candidate: args.options.candidate || args.options.candidateId || id }));
|
|
489
|
-
return;
|
|
490
|
-
case "select":
|
|
491
|
-
printJson(runner.hostMultiAgentSelect(required(runId, "run id"), { ...args.options, candidate: args.options.candidate || args.options.candidateId || id }));
|
|
492
|
-
return;
|
|
493
|
-
case "summary": {
|
|
494
|
-
const summary = runner.multiAgentSummary(required(runId, "run id"));
|
|
495
|
-
if (wantsJson(args.options))
|
|
496
|
-
printJson(summary);
|
|
497
|
-
else
|
|
498
|
-
process.stdout.write(`${(0, operator_ux_1.formatMultiAgentSummary)(summary)}\n`);
|
|
499
|
-
return;
|
|
500
|
-
}
|
|
501
|
-
case "summarize": {
|
|
502
|
-
const report = runner.multiAgentSummarize(required(runId, "run id"));
|
|
503
|
-
if (wantsJson(args.options))
|
|
504
|
-
printJson(report);
|
|
505
|
-
else
|
|
506
|
-
process.stdout.write(`${(0, state_explosion_1.formatStateExplosionReport)(report)}\n`);
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
case "graph": {
|
|
510
|
-
const wantsView = args.options.view || args.options.focus || args.options.depth;
|
|
511
|
-
if (wantsView) {
|
|
512
|
-
const graph = runner.multiAgentGraphView(required(runId, "run id"), args.options);
|
|
513
|
-
if (wantsJson(args.options))
|
|
514
|
-
printJson(graph);
|
|
515
|
-
else
|
|
516
|
-
process.stdout.write(`${(0, state_explosion_1.formatCompactGraph)(graph)}\n`);
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
const graph = runner.multiAgentOperatorGraph(required(runId, "run id"));
|
|
520
|
-
if (wantsJson(args.options))
|
|
521
|
-
printJson(graph);
|
|
522
|
-
else
|
|
523
|
-
process.stdout.write(`${(0, operator_ux_1.formatOperatorGraph)({ runId: required(runId, "run id"), nodes: graph.nodes, edges: graph.edges })}\n`);
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
|
-
case "dependencies": {
|
|
527
|
-
const rows = runner.multiAgentDependencies(required(runId, "run id"));
|
|
528
|
-
if (wantsJson(args.options))
|
|
529
|
-
printJson(rows);
|
|
530
|
-
else
|
|
531
|
-
process.stdout.write(`${(0, multi_agent_operator_ux_1.formatMultiAgentDependencies)(rows)}\n`);
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
case "failures": {
|
|
535
|
-
const rows = runner.multiAgentFailures(required(runId, "run id"));
|
|
536
|
-
if (wantsJson(args.options))
|
|
537
|
-
printJson(rows);
|
|
538
|
-
else
|
|
539
|
-
process.stdout.write(`${(0, multi_agent_operator_ux_1.formatMultiAgentFailures)(rows)}\n`);
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
case "evidence": {
|
|
543
|
-
const rows = runner.multiAgentEvidence(required(runId, "run id"));
|
|
544
|
-
if (wantsJson(args.options))
|
|
545
|
-
printJson(rows);
|
|
546
|
-
else
|
|
547
|
-
process.stdout.write(`${(0, multi_agent_operator_ux_1.formatMultiAgentEvidence)(rows)}\n`);
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
case "reasoning": {
|
|
551
|
-
if (args.options.refresh && !args.options.evidence && !args.options.evidenceId) {
|
|
552
|
-
const index = runner.multiAgentReasoningRefresh(required(runId, "run id"));
|
|
553
|
-
printJson(index);
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
556
|
-
const report = runner.multiAgentReasoning(required(runId, "run id"), { ...args.options, evidence: args.options.evidence || args.options.evidenceId || id });
|
|
557
|
-
if (wantsJson(args.options))
|
|
558
|
-
printJson(report);
|
|
559
|
-
else
|
|
560
|
-
process.stdout.write(`${(0, evidence_reasoning_1.formatEvidenceReasoningReport)(report)}\n`);
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
case "run":
|
|
564
|
-
if (!runId ||
|
|
565
|
-
args.options.topology ||
|
|
566
|
-
args.options.topologyId ||
|
|
567
|
-
args.options.app ||
|
|
568
|
-
args.options.appId ||
|
|
569
|
-
args.options.workflow ||
|
|
570
|
-
args.options.workflowId) {
|
|
571
|
-
printJson(runner.hostMultiAgentRun(runId, args.options));
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
if (id && !args.options.id && !args.options.status)
|
|
575
|
-
printJson(runner.showMultiAgentRun(required(runId, "run id"), id));
|
|
576
|
-
else if (id && args.options.status)
|
|
577
|
-
printJson(runner.transitionMultiAgentRun(required(runId, "run id"), id, args.options));
|
|
578
|
-
else
|
|
579
|
-
printJson(runner.createMultiAgentRun(required(runId, "run id"), args.options));
|
|
580
|
-
return;
|
|
581
|
-
case "show":
|
|
582
|
-
printJson(runner.showMultiAgentRun(required(runId, "run id"), required(id, "multi-agent run id")));
|
|
583
|
-
return;
|
|
584
|
-
case "role":
|
|
585
|
-
if (id && !args.options.id && !args.options["multi-agent-run"] && !args.options.multiAgentRun && !args.options.multiAgentRunId) {
|
|
586
|
-
printJson(runner.showAgentRole(required(runId, "run id"), id));
|
|
587
|
-
}
|
|
588
|
-
else {
|
|
589
|
-
printJson(runner.createAgentRole(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
|
|
590
|
-
}
|
|
591
|
-
return;
|
|
592
|
-
case "group":
|
|
593
|
-
if (id && !args.options.id && !args.options["multi-agent-run"] && !args.options.multiAgentRun && !args.options.multiAgentRunId) {
|
|
594
|
-
printJson(runner.showAgentGroup(required(runId, "run id"), id));
|
|
595
|
-
}
|
|
596
|
-
else {
|
|
597
|
-
printJson(runner.createAgentGroup(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
|
|
598
|
-
}
|
|
599
|
-
return;
|
|
600
|
-
case "membership":
|
|
601
|
-
if (id && !args.options.id && !args.options.group && !args.options.groupId && !args.options["multi-agent-group"]) {
|
|
602
|
-
printJson(runner.showAgentMembership(required(runId, "run id"), id));
|
|
603
|
-
}
|
|
604
|
-
else {
|
|
605
|
-
printJson(runner.assignAgentMembership(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
|
|
606
|
-
}
|
|
607
|
-
return;
|
|
608
|
-
case "fanout":
|
|
609
|
-
if (id && !args.options.id && !args.options.group && !args.options.groupId && !args.options["multi-agent-group"]) {
|
|
610
|
-
printJson(runner.showAgentFanout(required(runId, "run id"), id));
|
|
611
|
-
}
|
|
612
|
-
else {
|
|
613
|
-
printJson(runner.createAgentFanout(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
|
|
614
|
-
}
|
|
615
|
-
return;
|
|
616
|
-
case "fanin":
|
|
617
|
-
if (id && !args.options.id && !args.options.group && !args.options.groupId && !args.options["multi-agent-group"] && !args.options.fanout) {
|
|
618
|
-
printJson(runner.showAgentFanin(required(runId, "run id"), id));
|
|
619
|
-
}
|
|
620
|
-
else {
|
|
621
|
-
printJson(runner.collectAgentFanin(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
|
|
622
|
-
}
|
|
623
|
-
return;
|
|
624
|
-
default:
|
|
625
|
-
throw new Error("Usage: cw.js multi-agent run|status|step|blackboard|score|select|summary|summarize|graph|dependencies|failures|evidence|reasoning|show|role|group|membership|fanout|fanin <run-id> [id]");
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
case "eval": {
|
|
629
|
-
const [subcommand, first, second] = args.positionals;
|
|
630
|
-
let result;
|
|
631
|
-
switch (subcommand) {
|
|
632
|
-
case "snapshot":
|
|
633
|
-
result = runner.evalSnapshot(required(first, "run id"), args.options);
|
|
634
|
-
break;
|
|
635
|
-
case "replay":
|
|
636
|
-
result = runner.evalReplay(required(first, "snapshot id or path"), args.options);
|
|
637
|
-
break;
|
|
638
|
-
case "compare":
|
|
639
|
-
result = runner.evalCompare(required(first, "baseline id or path"), required(second, "replay id or path"));
|
|
640
|
-
break;
|
|
641
|
-
case "score":
|
|
642
|
-
result = runner.evalScore(required(first, "replay id or path"));
|
|
643
|
-
break;
|
|
644
|
-
case "gate":
|
|
645
|
-
result = runner.evalGate(required(first, "suite id or path"));
|
|
646
|
-
if (!wantsJson(args.options) && result.status === "fail")
|
|
647
|
-
process.exitCode = 1;
|
|
648
|
-
break;
|
|
649
|
-
case "report":
|
|
650
|
-
result = runner.evalReport(required(first, "replay id or path"));
|
|
651
|
-
break;
|
|
652
|
-
default:
|
|
653
|
-
throw new Error("Usage: cw.js eval snapshot <run-id> --id <snapshot-id> | replay <snapshot-id-or-path> | compare <baseline-id-or-path> <replay-id-or-path> | score <replay-id-or-path> | gate <suite-id-or-path> | report <replay-id-or-path>");
|
|
654
|
-
}
|
|
655
|
-
if (wantsJson(args.options))
|
|
656
|
-
printJson(result);
|
|
657
|
-
else
|
|
658
|
-
process.stdout.write(`${(0, multi_agent_eval_1.formatMultiAgentEval)(result)}\n`);
|
|
659
|
-
if (subcommand === "gate" && result.status === "fail")
|
|
660
|
-
process.exitCode = 1;
|
|
364
|
+
case "graph":
|
|
365
|
+
(0, operator_1.handleGraph)(args, runner);
|
|
366
|
+
return;
|
|
367
|
+
case "topology":
|
|
368
|
+
(0, operator_1.handleTopology)(args, runner);
|
|
369
|
+
return;
|
|
370
|
+
case "summary":
|
|
371
|
+
(0, operator_1.handleSummary)(args, runner);
|
|
372
|
+
return;
|
|
373
|
+
case "multi-agent":
|
|
374
|
+
(0, multi_agent_1.handleMultiAgent)(args, runner);
|
|
375
|
+
return;
|
|
376
|
+
case "eval":
|
|
377
|
+
(0, eval_1.handleEval)(args, runner);
|
|
378
|
+
return;
|
|
379
|
+
case "blackboard":
|
|
380
|
+
(0, blackboard_1.handleBlackboard)(args, runner);
|
|
381
|
+
return;
|
|
382
|
+
case "coordinator":
|
|
383
|
+
(0, blackboard_1.handleCoordinator)(args, runner);
|
|
384
|
+
return;
|
|
385
|
+
case "sandbox":
|
|
386
|
+
(0, operational_1.handleSandbox)(args, runner);
|
|
387
|
+
return;
|
|
388
|
+
case "backend":
|
|
389
|
+
(0, operational_1.handleBackend)(args, runner);
|
|
390
|
+
return;
|
|
391
|
+
case "contract":
|
|
392
|
+
(0, operational_1.handleContract)(args, runner);
|
|
393
|
+
return;
|
|
394
|
+
case "node":
|
|
395
|
+
(0, node_1.handleNode)(args, runner);
|
|
396
|
+
return;
|
|
397
|
+
case "migration":
|
|
398
|
+
(0, operational_1.handleMigration)(args, runner);
|
|
399
|
+
return;
|
|
400
|
+
case "feedback":
|
|
401
|
+
(0, operational_1.handleFeedback)(args, runner);
|
|
402
|
+
return;
|
|
403
|
+
case "worker":
|
|
404
|
+
(0, worker_1.handleWorker)(args, runner);
|
|
405
|
+
return;
|
|
406
|
+
case "audit":
|
|
407
|
+
(0, audit_1.handleAudit)(args, runner);
|
|
408
|
+
return;
|
|
409
|
+
case "candidate":
|
|
410
|
+
(0, candidate_1.handleCandidate)(args, runner);
|
|
661
411
|
return;
|
|
662
|
-
}
|
|
663
|
-
case "blackboard": {
|
|
664
|
-
const [subcommand, action, runId] = args.positionals;
|
|
665
|
-
switch (subcommand) {
|
|
666
|
-
case "summary":
|
|
667
|
-
printJson(runner.blackboardSummary(required(action, "run id"), args.options));
|
|
668
|
-
return;
|
|
669
|
-
case "summarize": {
|
|
670
|
-
const digest = runner.blackboardSummarize(required(action, "run id"), args.options);
|
|
671
|
-
if (wantsJson(args.options))
|
|
672
|
-
printJson(digest);
|
|
673
|
-
else
|
|
674
|
-
process.stdout.write(`${(0, state_explosion_1.formatBlackboardDigest)(digest)}\n`);
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
case "graph":
|
|
678
|
-
printJson(runner.blackboardGraph(required(action, "run id")));
|
|
679
|
-
return;
|
|
680
|
-
case "resolve":
|
|
681
|
-
printJson(runner.resolveRunBlackboard(required(action, "run id"), args.options));
|
|
682
|
-
return;
|
|
683
|
-
case "topic":
|
|
684
|
-
if (action === "create") {
|
|
685
|
-
printJson(runner.createBlackboardTopic(required(runId, "run id"), args.options));
|
|
686
|
-
return;
|
|
687
|
-
}
|
|
688
|
-
break;
|
|
689
|
-
case "message":
|
|
690
|
-
if (action === "post") {
|
|
691
|
-
printJson(runner.postBlackboardMessage(required(runId, "run id"), args.options));
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
if (action === "list") {
|
|
695
|
-
printJson(runner.listBlackboardMessages(required(runId, "run id"), args.options));
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
break;
|
|
699
|
-
case "context":
|
|
700
|
-
if (action === "put") {
|
|
701
|
-
printJson(runner.putBlackboardContext(required(runId, "run id"), args.options));
|
|
702
|
-
return;
|
|
703
|
-
}
|
|
704
|
-
break;
|
|
705
|
-
case "artifact":
|
|
706
|
-
if (action === "add") {
|
|
707
|
-
printJson(runner.addBlackboardArtifact(required(runId, "run id"), args.options));
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
if (action === "list") {
|
|
711
|
-
printJson(runner.listBlackboardArtifacts(required(runId, "run id"), args.options));
|
|
712
|
-
return;
|
|
713
|
-
}
|
|
714
|
-
break;
|
|
715
|
-
case "snapshot":
|
|
716
|
-
printJson(runner.snapshotBlackboard(required(action, "run id"), args.options));
|
|
717
|
-
return;
|
|
718
|
-
default:
|
|
719
|
-
break;
|
|
720
|
-
}
|
|
721
|
-
throw new Error("Usage: cw.js blackboard summary|summarize|graph|resolve <run-id> | topic create <run-id> | message post|list <run-id> | context put <run-id> | artifact add|list <run-id> | snapshot <run-id>");
|
|
722
|
-
}
|
|
723
|
-
case "coordinator": {
|
|
724
|
-
const [subcommand, runId] = args.positionals;
|
|
725
|
-
switch (subcommand) {
|
|
726
|
-
case "summary":
|
|
727
|
-
printJson(runner.coordinatorSummary(required(runId, "run id"), args.options));
|
|
728
|
-
return;
|
|
729
|
-
case "decision":
|
|
730
|
-
printJson(runner.recordCoordinatorDecision(required(runId, "run id"), args.options));
|
|
731
|
-
return;
|
|
732
|
-
default:
|
|
733
|
-
throw new Error("Usage: cw.js coordinator summary <run-id> | coordinator decision <run-id> --kind <kind> --outcome <outcome> --reason TEXT");
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
case "sandbox": {
|
|
737
|
-
const [subcommand, profileIdOrFile] = args.positionals;
|
|
738
|
-
switch (subcommand) {
|
|
739
|
-
case "list":
|
|
740
|
-
printJson(runner.listSandboxProfiles(args.options));
|
|
741
|
-
return;
|
|
742
|
-
case "show":
|
|
743
|
-
printJson(runner.showSandboxProfile(required(profileIdOrFile, "profile id"), args.options));
|
|
744
|
-
return;
|
|
745
|
-
case "validate": {
|
|
746
|
-
const result = runner.validateSandboxProfile(required(profileIdOrFile, "profile file"), args.options);
|
|
747
|
-
printJson(result);
|
|
748
|
-
if (!result.valid)
|
|
749
|
-
process.exitCode = 1;
|
|
750
|
-
return;
|
|
751
|
-
}
|
|
752
|
-
case "choose":
|
|
753
|
-
case "resolve":
|
|
754
|
-
printJson((0, capability_core_1.sandboxChoose)(runner, { ...args.options, profileId: profileIdOrFile || args.options.profileId }));
|
|
755
|
-
return;
|
|
756
|
-
default:
|
|
757
|
-
throw new Error("Usage: cw.js sandbox list|show|validate|choose|resolve [profile-id|profile-file]");
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
case "backend": {
|
|
761
|
-
const [subcommand, backendId] = args.positionals;
|
|
762
|
-
switch (subcommand) {
|
|
763
|
-
case "list":
|
|
764
|
-
printJson(runner.listBackends(args.options));
|
|
765
|
-
return;
|
|
766
|
-
case "show":
|
|
767
|
-
printJson(runner.showBackend(required(backendId, "backend id"), args.options));
|
|
768
|
-
return;
|
|
769
|
-
case "probe":
|
|
770
|
-
printJson(runner.probeBackend(backendId, args.options));
|
|
771
|
-
return;
|
|
772
|
-
case "agent": {
|
|
773
|
-
// `backend agent config [show]` = read-only; `backend agent config set ...` = mutating.
|
|
774
|
-
const [, , action] = args.positionals;
|
|
775
|
-
if (action === "set") {
|
|
776
|
-
printJson((0, capability_core_1.backendAgentConfigSet)(args.options));
|
|
777
|
-
return;
|
|
778
|
-
}
|
|
779
|
-
printJson((0, capability_core_1.backendAgentConfigShow)(args.options));
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
default:
|
|
783
|
-
throw new Error("Usage: cw.js backend list|show|probe [backend-id] | cw.js backend agent config [show|set] [--agent-command ... --agent-endpoint ... --agent-model ...]");
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
case "contract": {
|
|
787
|
-
const [subcommand, runId, contractId] = args.positionals;
|
|
788
|
-
switch (subcommand) {
|
|
789
|
-
case "show":
|
|
790
|
-
printJson(runner.showContract(required(runId, "run id"), contractId));
|
|
791
|
-
return;
|
|
792
|
-
default:
|
|
793
|
-
throw new Error("Usage: cw.js contract show <run-id> [contract-id]");
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
case "node": {
|
|
797
|
-
const [subcommand, runId, nodeId] = args.positionals;
|
|
798
|
-
switch (subcommand) {
|
|
799
|
-
case "list":
|
|
800
|
-
printJson(runner.listNodes(required(runId, "run id")));
|
|
801
|
-
return;
|
|
802
|
-
case "show":
|
|
803
|
-
printJson(runner.showNode(required(runId, "run id"), required(nodeId, "node id")));
|
|
804
|
-
return;
|
|
805
|
-
case "graph":
|
|
806
|
-
if (wantsJson(args.options))
|
|
807
|
-
printJson(runner.graphNodes(required(runId, "run id")));
|
|
808
|
-
else
|
|
809
|
-
process.stdout.write(`${(0, operator_ux_1.formatOperatorGraph)(runner.operatorGraph(required(runId, "run id")))}\n`);
|
|
810
|
-
return;
|
|
811
|
-
case "snapshot":
|
|
812
|
-
printJson(runner.nodeSnapshot(required(runId, "run id"), required(nodeId, "node id")));
|
|
813
|
-
return;
|
|
814
|
-
case "diff":
|
|
815
|
-
printJson(runner.nodeDiff(required(runId, "run id"), required(nodeId, "baseline snapshot id"), required(args.positionals[3], "candidate snapshot id")));
|
|
816
|
-
return;
|
|
817
|
-
case "replay":
|
|
818
|
-
printJson(runner.nodeReplay(required(runId, "run id"), required(nodeId, "snapshot id")));
|
|
819
|
-
return;
|
|
820
|
-
case "verify": {
|
|
821
|
-
const verdict = runner.nodeReplayVerify(required(runId, "run id"), required(nodeId, "replay id"));
|
|
822
|
-
printJson(verdict);
|
|
823
|
-
if (!verdict.pass)
|
|
824
|
-
process.exitCode = 1;
|
|
825
|
-
return;
|
|
826
|
-
}
|
|
827
|
-
default:
|
|
828
|
-
throw new Error("Usage: cw.js node list|show|graph|snapshot|diff|replay|verify <run-id> [node-id|snapshot-id|replay-id]");
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
case "migration": {
|
|
832
|
-
const [subcommand, target] = args.positionals;
|
|
833
|
-
switch (subcommand) {
|
|
834
|
-
case "list":
|
|
835
|
-
printJson(runner.migrationList());
|
|
836
|
-
return;
|
|
837
|
-
case "check": {
|
|
838
|
-
const report = runner.migrationCheck(required(target, "target (run-id or state/app file)"), args.options);
|
|
839
|
-
printJson(report);
|
|
840
|
-
if (report.status === "unsupported")
|
|
841
|
-
process.exitCode = 1;
|
|
842
|
-
return;
|
|
843
|
-
}
|
|
844
|
-
case "prove": {
|
|
845
|
-
const proof = runner.migrationProve(required(target, "target (run-id or state/app file)"), args.options);
|
|
846
|
-
printJson(proof);
|
|
847
|
-
if (!proof.pass)
|
|
848
|
-
process.exitCode = 1;
|
|
849
|
-
return;
|
|
850
|
-
}
|
|
851
|
-
default:
|
|
852
|
-
throw new Error("Usage: cw.js migration list|check|prove [target] [--contract run-state|workflow-app]");
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
case "feedback": {
|
|
856
|
-
const [subcommand, runId, feedbackId] = args.positionals;
|
|
857
|
-
switch (subcommand) {
|
|
858
|
-
case "list":
|
|
859
|
-
printJson(runner.listFeedback(required(runId, "run id"), args.options));
|
|
860
|
-
return;
|
|
861
|
-
case "show":
|
|
862
|
-
printJson(runner.showFeedback(required(runId, "run id"), required(feedbackId, "feedback id")));
|
|
863
|
-
return;
|
|
864
|
-
case "collect":
|
|
865
|
-
printJson(runner.collectFeedback(required(runId, "run id")));
|
|
866
|
-
return;
|
|
867
|
-
case "summary": {
|
|
868
|
-
const summary = runner.summarizeFeedbackRecords(required(runId, "run id"));
|
|
869
|
-
if (wantsJson(args.options))
|
|
870
|
-
printJson(summary);
|
|
871
|
-
else
|
|
872
|
-
process.stdout.write(`${(0, operator_ux_1.formatFeedbackSummary)(summary)}\n`);
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
case "task":
|
|
876
|
-
printJson(runner.createFeedbackTask(required(runId, "run id"), required(feedbackId, "feedback id"), args.options));
|
|
877
|
-
return;
|
|
878
|
-
case "resolve":
|
|
879
|
-
printJson(runner.resolveFeedback(required(runId, "run id"), required(feedbackId, "feedback id"), args.options));
|
|
880
|
-
return;
|
|
881
|
-
default:
|
|
882
|
-
throw new Error("Usage: cw.js feedback list|show|summary|collect|task|resolve <run-id> [feedback-id]");
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
case "worker": {
|
|
886
|
-
const [subcommand, runId, workerId, resultPath] = args.positionals;
|
|
887
|
-
switch (subcommand) {
|
|
888
|
-
case "list":
|
|
889
|
-
printJson(runner.listWorkers(required(runId, "run id"), args.options));
|
|
890
|
-
return;
|
|
891
|
-
case "summary": {
|
|
892
|
-
const summary = runner.summarizeWorkerRecords(required(runId, "run id"));
|
|
893
|
-
if (wantsJson(args.options))
|
|
894
|
-
printJson(summary);
|
|
895
|
-
else
|
|
896
|
-
process.stdout.write(`${(0, operator_ux_1.formatWorkerSummary)(summary)}\n`);
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
|
-
case "show":
|
|
900
|
-
printJson(runner.showWorker(required(runId, "run id"), required(workerId, "worker id")));
|
|
901
|
-
return;
|
|
902
|
-
case "manifest":
|
|
903
|
-
printJson(runner.showWorkerManifest(required(runId, "run id"), required(workerId, "worker id")));
|
|
904
|
-
return;
|
|
905
|
-
case "output":
|
|
906
|
-
printJson(runner.recordWorkerOutput(required(runId, "run id"), required(workerId, "worker id"), required(resultPath, "result file"), args.options));
|
|
907
|
-
return;
|
|
908
|
-
case "fail":
|
|
909
|
-
printJson(runner.recordWorkerFailure(required(runId, "run id"), required(workerId, "worker id"), String(args.options.message || required(resultPath, "failure message")), args.options));
|
|
910
|
-
return;
|
|
911
|
-
case "validate": {
|
|
912
|
-
// Non-null = a boundary violation: a validate verb must report an invalid
|
|
913
|
-
// verdict through its exit code, not just print it and exit 0.
|
|
914
|
-
const violation = runner.validateWorker(required(runId, "run id"), required(workerId, "worker id"), resultPath);
|
|
915
|
-
printJson(violation);
|
|
916
|
-
if (violation)
|
|
917
|
-
process.exitCode = 1;
|
|
918
|
-
return;
|
|
919
|
-
}
|
|
920
|
-
default:
|
|
921
|
-
throw new Error("Usage: cw.js worker list|summary|show|manifest|output|fail|validate <run-id> [worker-id] [result-file]");
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
case "audit": {
|
|
925
|
-
const [subcommand, runId, id] = args.positionals;
|
|
926
|
-
switch (subcommand) {
|
|
927
|
-
case "summary":
|
|
928
|
-
printJson(runner.auditSummary(required(runId, "run id")));
|
|
929
|
-
return;
|
|
930
|
-
case "verify": {
|
|
931
|
-
const result = (0, capability_core_1.auditVerify)(runner, { ...args.options, runId: required(runId, "run id") });
|
|
932
|
-
printJson(result);
|
|
933
|
-
// Fail-closed: any unverified chain exits non-zero so `cw audit verify
|
|
934
|
-
// <run> && deploy` stops — mirrors the telemetry-verify guard. verifyTrustAudit
|
|
935
|
-
// returns verified:true for a truly absent/empty chain (nothing to prove),
|
|
936
|
-
// so this stays exit 0 there; a FULLY-corrupt log reports present:false but
|
|
937
|
-
// verified:false (corruptLines>0) and must NOT be conflated with absent — the
|
|
938
|
-
// earlier `present && ...` guard let that severe tamper escape (exit 0).
|
|
939
|
-
if (!result.verified)
|
|
940
|
-
process.exitCode = 1;
|
|
941
|
-
return;
|
|
942
|
-
}
|
|
943
|
-
case "worker":
|
|
944
|
-
printJson(runner.workerAudit(required(runId, "run id"), required(id, "worker id")));
|
|
945
|
-
return;
|
|
946
|
-
case "provenance":
|
|
947
|
-
printJson(runner.evidenceProvenance(required(runId, "run id"), args.options));
|
|
948
|
-
return;
|
|
949
|
-
case "multi-agent": {
|
|
950
|
-
const view = runner.auditMultiAgent(required(runId, "run id"));
|
|
951
|
-
if (wantsJson(args.options))
|
|
952
|
-
printJson(view);
|
|
953
|
-
else
|
|
954
|
-
process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
case "policy": {
|
|
958
|
-
const view = runner.auditPolicy(required(runId, "run id"));
|
|
959
|
-
if (wantsJson(args.options))
|
|
960
|
-
printJson(view);
|
|
961
|
-
else
|
|
962
|
-
process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
|
|
963
|
-
return;
|
|
964
|
-
}
|
|
965
|
-
case "role": {
|
|
966
|
-
const view = runner.auditRole(required(runId, "run id"), required(id, "role id"));
|
|
967
|
-
if (wantsJson(args.options))
|
|
968
|
-
printJson(view);
|
|
969
|
-
else
|
|
970
|
-
process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
|
|
971
|
-
return;
|
|
972
|
-
}
|
|
973
|
-
case "blackboard": {
|
|
974
|
-
const view = runner.auditBlackboard(required(runId, "run id"));
|
|
975
|
-
if (wantsJson(args.options))
|
|
976
|
-
printJson(view);
|
|
977
|
-
else
|
|
978
|
-
process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
|
|
979
|
-
return;
|
|
980
|
-
}
|
|
981
|
-
case "judge": {
|
|
982
|
-
const view = runner.auditJudge(required(runId, "run id"));
|
|
983
|
-
if (wantsJson(args.options))
|
|
984
|
-
printJson(view);
|
|
985
|
-
else
|
|
986
|
-
process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
|
|
987
|
-
return;
|
|
988
|
-
}
|
|
989
|
-
case "attest":
|
|
990
|
-
printJson(runner.recordAuditAttestation(required(runId, "run id"), args.options));
|
|
991
|
-
return;
|
|
992
|
-
case "decision":
|
|
993
|
-
printJson(runner.recordAuditDecision(required(runId, "run id"), required(id, "worker id"), args.options));
|
|
994
|
-
return;
|
|
995
|
-
default:
|
|
996
|
-
throw new Error("Usage: cw.js audit summary|worker|provenance|multi-agent|policy|role|blackboard|judge|attest|decision <run-id> [worker-id|role-id]");
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
case "candidate": {
|
|
1000
|
-
const [subcommand, runId, candidateId, reason] = args.positionals;
|
|
1001
|
-
switch (subcommand) {
|
|
1002
|
-
case "list":
|
|
1003
|
-
printJson(runner.listCandidates(required(runId, "run id"), args.options));
|
|
1004
|
-
return;
|
|
1005
|
-
case "show":
|
|
1006
|
-
printJson(runner.showCandidate(required(runId, "run id"), required(candidateId, "candidate id")));
|
|
1007
|
-
return;
|
|
1008
|
-
case "register":
|
|
1009
|
-
printJson(runner.registerCandidate(required(runId, "run id"), args.options));
|
|
1010
|
-
return;
|
|
1011
|
-
case "score":
|
|
1012
|
-
printJson(runner.scoreCandidate(required(runId, "run id"), required(candidateId, "candidate id"), args.options));
|
|
1013
|
-
return;
|
|
1014
|
-
case "rank":
|
|
1015
|
-
printJson(runner.rankCandidates(required(runId, "run id"), args.options));
|
|
1016
|
-
return;
|
|
1017
|
-
case "select":
|
|
1018
|
-
printJson(runner.selectCandidate(required(runId, "run id"), required(candidateId, "candidate id"), args.options));
|
|
1019
|
-
return;
|
|
1020
|
-
case "reject":
|
|
1021
|
-
printJson(runner.rejectCandidate(required(runId, "run id"), required(candidateId, "candidate id"), String(args.options.reason || args.options.message || reason || "rejected")));
|
|
1022
|
-
return;
|
|
1023
|
-
case "summary":
|
|
1024
|
-
if (wantsJson(args.options))
|
|
1025
|
-
printJson(runner.summarizeCandidateOperatorRecords(required(runId, "run id")));
|
|
1026
|
-
else
|
|
1027
|
-
process.stdout.write(`${(0, operator_ux_1.formatCandidateSummary)(runner.summarizeCandidateOperatorRecords(required(runId, "run id")))}\n`);
|
|
1028
|
-
return;
|
|
1029
|
-
default:
|
|
1030
|
-
throw new Error("Usage: cw.js candidate list|show|register|score|rank|select|reject|summary <run-id> [candidate-id]");
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
412
|
// ---- Team Collaboration (v0.1.32) ------------------------------------
|
|
1034
|
-
case "approve":
|
|
1035
|
-
|
|
1036
|
-
printJson(runner.collaborationApprove(required(runId, "run id"), required(targetKind, "target kind (candidate|commit|selection|run|task|node)"), required(targetId, "target id"), args.options));
|
|
413
|
+
case "approve":
|
|
414
|
+
(0, collaboration_1.handleApprove)(args, runner);
|
|
1037
415
|
return;
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
const [targetKind, runId, targetId] = args.positionals;
|
|
1041
|
-
printJson(runner.collaborationReject(required(runId, "run id"), required(targetKind, "target kind (candidate|commit|selection|run|task|node)"), required(targetId, "target id"), args.options));
|
|
416
|
+
case "reject":
|
|
417
|
+
(0, collaboration_1.handleReject)(args, runner);
|
|
1042
418
|
return;
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
if (subcommand === "list") {
|
|
1052
|
-
const result = runner.collaborationCommentList(required(rest[0], "run id"), args.options);
|
|
1053
|
-
if (wantsJson(args.options))
|
|
1054
|
-
printJson(result);
|
|
1055
|
-
else
|
|
1056
|
-
process.stdout.write(`${runner.formatCommentList(result.comments)}\n`);
|
|
1057
|
-
return;
|
|
1058
|
-
}
|
|
1059
|
-
throw new Error("Usage: cw.js comment add <kind> <run-id> <target-id> --body <text> | comment list <run-id> [--json]");
|
|
1060
|
-
}
|
|
1061
|
-
case "handoff": {
|
|
1062
|
-
const [targetKind, runId, targetIdRaw] = args.positionals;
|
|
1063
|
-
const kind = required(targetKind, "target kind (run|task|candidate|commit|node)");
|
|
1064
|
-
const rid = required(runId, "run id");
|
|
1065
|
-
const targetId = targetIdRaw || (kind === "run" ? rid : undefined);
|
|
1066
|
-
printJson(runner.collaborationHandoff(rid, kind, required(targetId, "target id"), args.options));
|
|
419
|
+
case "comment":
|
|
420
|
+
(0, collaboration_1.handleComment)(args, runner);
|
|
421
|
+
return;
|
|
422
|
+
case "handoff":
|
|
423
|
+
(0, collaboration_1.handleHandoff)(args, runner);
|
|
424
|
+
return;
|
|
425
|
+
case "review":
|
|
426
|
+
(0, collaboration_1.handleReview)(args, runner);
|
|
1067
427
|
return;
|
|
1068
|
-
}
|
|
1069
|
-
case "review": {
|
|
1070
|
-
const [subcommand, runId] = args.positionals;
|
|
1071
|
-
if (subcommand === "status") {
|
|
1072
|
-
const report = runner.reviewStatus(required(runId, "run id"), args.options);
|
|
1073
|
-
if (wantsJson(args.options))
|
|
1074
|
-
printJson(report);
|
|
1075
|
-
else
|
|
1076
|
-
process.stdout.write(`${runner.formatReviewStatus(report)}\n`);
|
|
1077
|
-
return;
|
|
1078
|
-
}
|
|
1079
|
-
if (subcommand === "policy") {
|
|
1080
|
-
printJson(runner.reviewPolicy(required(runId, "run id"), args.options));
|
|
1081
|
-
return;
|
|
1082
|
-
}
|
|
1083
|
-
throw new Error("Usage: cw.js review status <run-id> [--json] | review policy <run-id> --required-approvals N --authorized-roles a,b --applies-to commit,selection");
|
|
1084
|
-
}
|
|
1085
428
|
case "loop": {
|
|
1086
|
-
printJson(scheduler.create({ ...args.options, kind: "loop" }));
|
|
429
|
+
(0, io_1.printJson)(scheduler.create({ ...args.options, kind: "loop" }));
|
|
1087
430
|
return;
|
|
1088
431
|
}
|
|
1089
|
-
case "schedule":
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
}
|
|
1128
|
-
await daemon.run();
|
|
1129
|
-
return;
|
|
1130
|
-
}
|
|
1131
|
-
default:
|
|
1132
|
-
throw new Error("Usage: cw.js schedule create|list|delete|due|complete|pause|resume|run-now|history|daemon");
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
case "routine": {
|
|
1136
|
-
const [subcommand, idOrKind, payloadPath] = args.positionals;
|
|
1137
|
-
switch (subcommand) {
|
|
1138
|
-
case "create":
|
|
1139
|
-
printJson(triggers.create(args.options));
|
|
1140
|
-
return;
|
|
1141
|
-
case "list":
|
|
1142
|
-
printJson(triggers.list(args.options.kind ? String(args.options.kind) : undefined));
|
|
1143
|
-
return;
|
|
1144
|
-
case "delete":
|
|
1145
|
-
printJson(triggers.delete(required(idOrKind, "trigger id")));
|
|
1146
|
-
return;
|
|
1147
|
-
case "fire": {
|
|
1148
|
-
const kind = required(idOrKind, "trigger kind");
|
|
1149
|
-
const payload = payloadPath ? JSON.parse(node_fs_1.default.readFileSync(payloadPath, "utf8")) : args.options;
|
|
1150
|
-
printJson(triggers.fire(kind, payload));
|
|
1151
|
-
return;
|
|
1152
|
-
}
|
|
1153
|
-
case "events":
|
|
1154
|
-
printJson(triggers.events(idOrKind));
|
|
1155
|
-
return;
|
|
1156
|
-
default:
|
|
1157
|
-
throw new Error("Usage: cw.js routine create|list|delete|fire|events");
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
case "registry": {
|
|
1161
|
-
const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
|
|
1162
|
-
const [subcommand] = args.positionals;
|
|
1163
|
-
switch (subcommand) {
|
|
1164
|
-
case "refresh": {
|
|
1165
|
-
const report = (0, capability_core_1.runRegistryRefresh)(registry, args.options);
|
|
1166
|
-
if (wantsJson(args.options))
|
|
1167
|
-
printJson(report);
|
|
1168
|
-
else
|
|
1169
|
-
process.stdout.write(`${(0, run_registry_1.formatRegistryReport)(report)}\n`);
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
case "show": {
|
|
1173
|
-
const report = (0, capability_core_1.runRegistryShow)(registry, args.options);
|
|
1174
|
-
if (wantsJson(args.options))
|
|
1175
|
-
printJson(report);
|
|
1176
|
-
else
|
|
1177
|
-
process.stdout.write(`${(0, run_registry_1.formatRegistryReport)(report)}\n`);
|
|
1178
|
-
return;
|
|
1179
|
-
}
|
|
1180
|
-
default:
|
|
1181
|
-
throw new Error("Usage: cw.js registry refresh|show [--scope repo|home] [--json]");
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
case "metrics": {
|
|
1185
|
-
const [subcommand, runId] = args.positionals;
|
|
1186
|
-
switch (subcommand) {
|
|
1187
|
-
case "show": {
|
|
1188
|
-
const report = runner.metricsShow(required(runId, "run id"), args.options);
|
|
1189
|
-
if (wantsJson(args.options))
|
|
1190
|
-
printJson(report);
|
|
1191
|
-
else
|
|
1192
|
-
process.stdout.write(`${(0, observability_1.formatMetricsReport)(report)}\n`);
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
|
-
case "summary": {
|
|
1196
|
-
const report = (0, capability_core_1.metricsSummary)((0, capability_core_1.runRegistryFor)(args.options, runner), runner, args.options);
|
|
1197
|
-
if (wantsJson(args.options))
|
|
1198
|
-
printJson(report);
|
|
1199
|
-
else
|
|
1200
|
-
process.stdout.write(`${(0, observability_1.formatMetricsSummary)(report)}\n`);
|
|
1201
|
-
return;
|
|
1202
|
-
}
|
|
1203
|
-
default:
|
|
1204
|
-
throw new Error("Usage: cw.js metrics show <run-id> | metrics summary [--scope repo|home] [--pricing <path>|default] [--json]");
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
case "run": {
|
|
1208
|
-
// Agent Delegation Drive (v0.1.38): `cw run <app> --drive [--once]` drives a
|
|
1209
|
-
// run end-to-end by delegating each worker to the agent backend. Distinct from
|
|
1210
|
-
// the run-REGISTRY verbs below. `--preview` (or the `run drive <run-id>` form)
|
|
1211
|
-
// is the read-only, deterministic next-step preview.
|
|
1212
|
-
//
|
|
1213
|
-
// A run-REGISTRY subcommand keyword (resume/show/...) must NOT be intercepted
|
|
1214
|
-
// here just because it carries a --drive flag of its own — e.g.
|
|
1215
|
-
// `run resume <id> --drive` is the resume verb's opt-in continuation, not
|
|
1216
|
-
// `run <app=resume> --drive`. Fall through to the switch for those keywords.
|
|
1217
|
-
const runRegistrySubcommand = new Set([
|
|
1218
|
-
"drive", "search", "list", "show", "resume", "archive", "rerun", "export", "import", "verify-import", "inspect-archive"
|
|
1219
|
-
]);
|
|
1220
|
-
if (args.options.drive && !runRegistrySubcommand.has(String(args.positionals[0] || ""))) {
|
|
1221
|
-
const target = args.positionals[0];
|
|
1222
|
-
const runId = optionalArg(args.options.run) || optionalArg(args.options.runId);
|
|
1223
|
-
if (args.options.preview) {
|
|
1224
|
-
printJson((0, capability_core_1.runDrivePreview)(runner, { ...args.options, runId: runId || target }));
|
|
1225
|
-
return;
|
|
1226
|
-
}
|
|
1227
|
-
const driveArgs = { ...args.options };
|
|
1228
|
-
if (runId)
|
|
1229
|
-
driveArgs.runId = runId;
|
|
1230
|
-
else
|
|
1231
|
-
driveArgs.appId = target;
|
|
1232
|
-
const dr = (0, capability_core_1.runDrive)(runner, driveArgs);
|
|
1233
|
-
printJson(dr);
|
|
1234
|
-
if (!wantsJson(args.options)) {
|
|
1235
|
-
emitRunSummary(runner, args.options, {
|
|
1236
|
-
runId: dr.runId,
|
|
1237
|
-
reportPath: dr.reportPath,
|
|
1238
|
-
status: dr.status,
|
|
1239
|
-
statePath: dr.statePath,
|
|
1240
|
-
completedWorkers: dr.completedWorkers,
|
|
1241
|
-
plannedWorkers: dr.plannedWorkers,
|
|
1242
|
-
agentConfigured: dr.agentConfigured
|
|
1243
|
-
});
|
|
1244
|
-
}
|
|
1245
|
-
return;
|
|
1246
|
-
}
|
|
1247
|
-
const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
|
|
1248
|
-
const [subcommand, id] = args.positionals;
|
|
1249
|
-
switch (subcommand) {
|
|
1250
|
-
case "drive": {
|
|
1251
|
-
// `run drive <run-id>` = read-only preview; `--step [--once]` = mutating drive.
|
|
1252
|
-
if (args.options.step) {
|
|
1253
|
-
const driveArgs = { ...args.options };
|
|
1254
|
-
if (id)
|
|
1255
|
-
driveArgs.runId = id;
|
|
1256
|
-
const dr = (0, capability_core_1.runDrive)(runner, driveArgs);
|
|
1257
|
-
printJson(dr);
|
|
1258
|
-
if (!wantsJson(args.options)) {
|
|
1259
|
-
emitRunSummary(runner, args.options, {
|
|
1260
|
-
runId: dr.runId,
|
|
1261
|
-
reportPath: dr.reportPath,
|
|
1262
|
-
status: dr.status,
|
|
1263
|
-
statePath: dr.statePath,
|
|
1264
|
-
completedWorkers: dr.completedWorkers,
|
|
1265
|
-
plannedWorkers: dr.plannedWorkers,
|
|
1266
|
-
agentConfigured: dr.agentConfigured
|
|
1267
|
-
});
|
|
1268
|
-
}
|
|
1269
|
-
return;
|
|
1270
|
-
}
|
|
1271
|
-
printJson((0, capability_core_1.runDrivePreview)(runner, { ...args.options, runId: required(id, "run id") }));
|
|
1272
|
-
return;
|
|
1273
|
-
}
|
|
1274
|
-
case "search": {
|
|
1275
|
-
const result = (0, capability_core_1.runSearch)(registry, args.options);
|
|
1276
|
-
if (wantsJson(args.options))
|
|
1277
|
-
printJson(result);
|
|
1278
|
-
else
|
|
1279
|
-
process.stdout.write(`${(0, run_registry_1.formatRunSearch)(result)}\n`);
|
|
1280
|
-
return;
|
|
1281
|
-
}
|
|
1282
|
-
case "list": {
|
|
1283
|
-
const result = (0, capability_core_1.runList)(registry, args.options);
|
|
1284
|
-
if (wantsJson(args.options))
|
|
1285
|
-
printJson(result);
|
|
1286
|
-
else
|
|
1287
|
-
process.stdout.write(`${(0, run_registry_1.formatRunSearch)(result)}\n`);
|
|
1288
|
-
return;
|
|
1289
|
-
}
|
|
1290
|
-
case "show": {
|
|
1291
|
-
const result = (0, capability_core_1.runShow)(registry, required(id, "run id"), args.options);
|
|
1292
|
-
if (wantsJson(args.options))
|
|
1293
|
-
printJson(result);
|
|
1294
|
-
else
|
|
1295
|
-
process.stdout.write(`${(0, run_registry_1.formatRunShow)(result)}\n`);
|
|
1296
|
-
return;
|
|
1297
|
-
}
|
|
1298
|
-
case "resume": {
|
|
1299
|
-
const result = (0, capability_core_1.runResume)(registry, runner, required(id, "run id"), args.options);
|
|
1300
|
-
if (wantsJson(args.options))
|
|
1301
|
-
printJson(result);
|
|
1302
|
-
else
|
|
1303
|
-
process.stdout.write(`${(0, run_registry_1.formatResume)(result)}\n`);
|
|
1304
|
-
return;
|
|
1305
|
-
}
|
|
1306
|
-
case "archive":
|
|
1307
|
-
printJson((0, capability_core_1.runArchive)(registry, id, args.options));
|
|
1308
|
-
return;
|
|
1309
|
-
case "rerun":
|
|
1310
|
-
printJson((0, capability_core_1.runRerun)(registry, required(id, "run id"), args.options));
|
|
1311
|
-
return;
|
|
1312
|
-
case "export":
|
|
1313
|
-
printJson((0, capability_core_1.runExportArchive)(runner, required(id || optionalArg(args.options.runId || args.options.run), "run id"), args.options));
|
|
1314
|
-
return;
|
|
1315
|
-
case "import":
|
|
1316
|
-
printJson((0, capability_core_1.runImportArchive)(runner, { ...args.options, archive: id || args.options.archive || args.options.path }));
|
|
1317
|
-
return;
|
|
1318
|
-
case "verify-import": {
|
|
1319
|
-
const result = (0, capability_core_1.runVerifyImport)(runner, required(id || optionalArg(args.options.runId || args.options.run), "run id"), args.options);
|
|
1320
|
-
printJson(result);
|
|
1321
|
-
// Fail-closed ONLY behind --strict, so the default exit stays 0
|
|
1322
|
-
// (byte-identical). With --strict, any failed restore check — including
|
|
1323
|
-
// the new trust-audit row — exits 1 for `verify-import && restore`.
|
|
1324
|
-
if (Boolean(args.options.strict) && !result.ok)
|
|
1325
|
-
process.exitCode = 1;
|
|
1326
|
-
return;
|
|
1327
|
-
}
|
|
1328
|
-
case "inspect-archive": {
|
|
1329
|
-
const result = (0, capability_core_1.runInspectArchive)(runner, { ...args.options, archive: id || args.options.archive || args.options.path });
|
|
1330
|
-
printJson(result);
|
|
1331
|
-
// Read-only diagnostic: exit 1 when the archive fails any integrity check,
|
|
1332
|
-
// so `cw run inspect-archive <path> && restore` stops on a bad archive.
|
|
1333
|
-
if (!result.ok)
|
|
1334
|
-
process.exitCode = 1;
|
|
1335
|
-
return;
|
|
1336
|
-
}
|
|
1337
|
-
default:
|
|
1338
|
-
throw new Error("Usage: cw.js run search|list|show|resume|archive|rerun|drive|export|import|verify-import|inspect-archive [run-id|archive] [--scope repo|home] [--json] | cw.js run <app> --drive [--once] [--incremental] [--repo R --question Q]");
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
case "queue": {
|
|
1342
|
-
const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
|
|
1343
|
-
const [subcommand, id] = args.positionals;
|
|
1344
|
-
switch (subcommand) {
|
|
1345
|
-
case "add":
|
|
1346
|
-
printJson((0, capability_core_1.queueAdd)(registry, args.options));
|
|
1347
|
-
return;
|
|
1348
|
-
case "list": {
|
|
1349
|
-
const result = (0, capability_core_1.queueList)(registry, args.options);
|
|
1350
|
-
if (wantsJson(args.options))
|
|
1351
|
-
printJson(result);
|
|
1352
|
-
else
|
|
1353
|
-
process.stdout.write(`${(0, run_registry_1.formatQueueList)(result)}\n`);
|
|
1354
|
-
return;
|
|
1355
|
-
}
|
|
1356
|
-
case "drain":
|
|
1357
|
-
printJson((0, capability_core_1.queueDrain)(registry, args.options));
|
|
1358
|
-
return;
|
|
1359
|
-
case "show":
|
|
1360
|
-
printJson((0, capability_core_1.queueShow)(registry, required(id, "queue id")));
|
|
1361
|
-
return;
|
|
1362
|
-
default:
|
|
1363
|
-
throw new Error("Usage: cw.js queue add|list|drain|show [queue-id] [--repo PATH] [--priority N]");
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
case "sched": {
|
|
1367
|
-
const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
|
|
1368
|
-
const [subcommand, idArg] = args.positionals;
|
|
1369
|
-
switch (subcommand) {
|
|
1370
|
-
case "plan":
|
|
1371
|
-
printJson((0, capability_core_1.schedPlan)(registry, args.options));
|
|
1372
|
-
return;
|
|
1373
|
-
case "lease":
|
|
1374
|
-
printJson((0, capability_core_1.schedLease)(registry, args.options));
|
|
1375
|
-
return;
|
|
1376
|
-
case "release":
|
|
1377
|
-
printJson((0, capability_core_1.schedRelease)(registry, { ...args.options, leaseId: args.options.leaseId || idArg }));
|
|
1378
|
-
return;
|
|
1379
|
-
case "complete":
|
|
1380
|
-
printJson((0, capability_core_1.schedComplete)(registry, { ...args.options, leaseId: args.options.leaseId || idArg }));
|
|
1381
|
-
return;
|
|
1382
|
-
case "reclaim":
|
|
1383
|
-
printJson((0, capability_core_1.schedReclaim)(registry, args.options));
|
|
1384
|
-
return;
|
|
1385
|
-
case "reset":
|
|
1386
|
-
printJson((0, capability_core_1.schedReset)(registry, { ...args.options, id: args.options.id || idArg }));
|
|
1387
|
-
return;
|
|
1388
|
-
case "policy": {
|
|
1389
|
-
const [, action] = args.positionals;
|
|
1390
|
-
if (action === "set") {
|
|
1391
|
-
printJson((0, capability_core_1.schedPolicySet)(registry, args.options));
|
|
1392
|
-
return;
|
|
1393
|
-
}
|
|
1394
|
-
printJson((0, capability_core_1.schedPolicyShow)(registry));
|
|
1395
|
-
return;
|
|
1396
|
-
}
|
|
1397
|
-
default:
|
|
1398
|
-
throw new Error("Usage: cw.js sched plan|lease|release|complete|reclaim|reset|policy [show|set] [id] [--maxConcurrent N --maxAttempts N ...]");
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
case "clones": {
|
|
1402
|
-
// Remote-source clone cache (v0.1.91): `list` inspects the ~/.local/state/cool-workflow
|
|
1403
|
-
// /clones checkouts that `--link`/URL reviews populate; `gc` reclaims them (a TTL sweep,
|
|
1404
|
-
// or --all). Pure filesystem work — no network, no run registry.
|
|
1405
|
-
const [subcommand] = args.positionals;
|
|
1406
|
-
switch (subcommand) {
|
|
1407
|
-
case "list": {
|
|
1408
|
-
const result = (0, capability_core_1.listClones)(args.options);
|
|
1409
|
-
if (wantsJson(args.options))
|
|
1410
|
-
printJson(result);
|
|
1411
|
-
else
|
|
1412
|
-
process.stdout.write(`${formatClonesList(result)}\n`);
|
|
1413
|
-
return;
|
|
1414
|
-
}
|
|
1415
|
-
case "gc": {
|
|
1416
|
-
const result = (0, capability_core_1.gcClones)(args.options);
|
|
1417
|
-
if (wantsJson(args.options))
|
|
1418
|
-
printJson(result);
|
|
1419
|
-
else
|
|
1420
|
-
process.stdout.write(`${formatClonesGc(result)}\n`);
|
|
1421
|
-
return;
|
|
1422
|
-
}
|
|
1423
|
-
default:
|
|
1424
|
-
throw new Error("Usage: cw.js clones list [--json] | clones gc [--older-than-days N] [--all] [--json]");
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
case "gc": {
|
|
1428
|
-
// Run Retention & Provable Reclamation (v0.1.39). `plan` is a pure dry-run
|
|
1429
|
-
// (frees nothing); `run` executes the write-ahead reclamation transaction;
|
|
1430
|
-
// `verify` re-proves a reclaimed run. CW never reclaims by default.
|
|
1431
|
-
const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
|
|
1432
|
-
const [subcommand, id] = args.positionals;
|
|
1433
|
-
switch (subcommand) {
|
|
1434
|
-
case "plan": {
|
|
1435
|
-
const result = (0, capability_core_1.gcPlan)(registry, id, args.options);
|
|
1436
|
-
if (wantsJson(args.options))
|
|
1437
|
-
printJson(result);
|
|
1438
|
-
else
|
|
1439
|
-
process.stdout.write(`${(0, run_registry_1.formatGcPlan)(result)}\n`);
|
|
1440
|
-
return;
|
|
1441
|
-
}
|
|
1442
|
-
case "run": {
|
|
1443
|
-
const result = (0, capability_core_1.gcRun)(registry, id, args.options);
|
|
1444
|
-
if (wantsJson(args.options))
|
|
1445
|
-
printJson(result);
|
|
1446
|
-
else
|
|
1447
|
-
process.stdout.write(`${(0, run_registry_1.formatGcRun)(result)}\n`);
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
case "verify": {
|
|
1451
|
-
const result = (0, capability_core_1.gcVerify)(registry, required(id, "run id"), args.options);
|
|
1452
|
-
if (wantsJson(args.options))
|
|
1453
|
-
printJson(result);
|
|
1454
|
-
else
|
|
1455
|
-
process.stdout.write(`${(0, run_registry_1.formatGcVerify)(result)}\n`);
|
|
1456
|
-
// Fail closed ONLY on a real integrity failure: a run that WAS reclaimed
|
|
1457
|
-
// but no longer re-proves. A not-reclaimed run has nothing to verify
|
|
1458
|
-
// (reclaimed:false/verified:false) and must not be treated as a failure.
|
|
1459
|
-
// LIMIT (honest): a DELETED reclaimed.json reads as reclaimed:false, so
|
|
1460
|
-
// proof-deletion is indistinguishable from never-reclaimed here without
|
|
1461
|
-
// an independent witness (e.g. a trust-audit reclamation event) — a
|
|
1462
|
-
// follow-up. This guard is still strictly better than the prior exit-0.
|
|
1463
|
-
if (result.reclaimed && !result.verified)
|
|
1464
|
-
process.exitCode = 1;
|
|
1465
|
-
return;
|
|
1466
|
-
}
|
|
1467
|
-
default:
|
|
1468
|
-
throw new Error("Usage: cw.js gc plan|run|verify [run-id] [--reclaimAfterArchiveDays N] [--keep-scratch] [--keep-snapshots] [--limit N] [--json]");
|
|
1469
|
-
}
|
|
1470
|
-
}
|
|
1471
|
-
case "history": {
|
|
1472
|
-
const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
|
|
1473
|
-
const result = (0, capability_core_1.runHistory)(registry, args.options);
|
|
1474
|
-
if (wantsJson(args.options))
|
|
1475
|
-
printJson(result);
|
|
1476
|
-
else
|
|
1477
|
-
process.stdout.write(`${(0, run_registry_1.formatHistory)(result)}\n`);
|
|
432
|
+
case "schedule":
|
|
433
|
+
await (0, scheduling_1.handleSchedule)(args, scheduler);
|
|
434
|
+
return;
|
|
435
|
+
case "routine":
|
|
436
|
+
(0, scheduling_1.handleRoutine)(args, triggers);
|
|
437
|
+
return;
|
|
438
|
+
case "registry":
|
|
439
|
+
(0, registry_1.handleRegistry)(args, runner);
|
|
440
|
+
return;
|
|
441
|
+
case "metrics":
|
|
442
|
+
(0, operational_1.handleMetrics)(args, runner);
|
|
443
|
+
return;
|
|
444
|
+
case "run":
|
|
445
|
+
(0, run_1.handleRun)(args, runner);
|
|
446
|
+
return;
|
|
447
|
+
case "queue":
|
|
448
|
+
(0, registry_1.handleQueue)(args, runner);
|
|
449
|
+
return;
|
|
450
|
+
case "sched":
|
|
451
|
+
(0, scheduling_1.handleSched)(args, runner);
|
|
452
|
+
return;
|
|
453
|
+
case "clones":
|
|
454
|
+
(0, clones_1.handleClones)(args);
|
|
455
|
+
return;
|
|
456
|
+
case "gc":
|
|
457
|
+
(0, maintenance_1.handleGc)(args, runner);
|
|
458
|
+
return;
|
|
459
|
+
case "history":
|
|
460
|
+
(0, registry_1.handleHistory)(args, runner);
|
|
461
|
+
return;
|
|
462
|
+
case "telemetry":
|
|
463
|
+
(0, maintenance_1.handleTelemetry)(args, runner);
|
|
464
|
+
return;
|
|
465
|
+
case "demo":
|
|
466
|
+
(0, maintenance_1.handleDemo)(args, runner);
|
|
467
|
+
return;
|
|
468
|
+
case "workbench":
|
|
469
|
+
await (0, workbench_1.handleWorkbench)(args, runner);
|
|
1478
470
|
return;
|
|
1479
|
-
}
|
|
1480
|
-
case "telemetry": {
|
|
1481
|
-
const [subcommand, id] = args.positionals;
|
|
1482
|
-
switch (subcommand) {
|
|
1483
|
-
case "verify": {
|
|
1484
|
-
const result = (0, capability_core_1.telemetryVerify)(runner, { ...args.options, runId: id || args.options.runId || args.options.run });
|
|
1485
|
-
if (wantsJson(args.options))
|
|
1486
|
-
printJson(result);
|
|
1487
|
-
else
|
|
1488
|
-
process.stdout.write(`${(0, telemetry_demo_1.formatTelemetryVerify)(result)}\n`);
|
|
1489
|
-
// Fail closed: a forged/edited/corrupt ledger verifies false — report it
|
|
1490
|
-
// through the exit code so `cw telemetry verify <run> && deploy` cannot
|
|
1491
|
-
// pass on a lie. (Absent ledger = present:false/verified:true -> exit 0.)
|
|
1492
|
-
if (!result.verified)
|
|
1493
|
-
process.exitCode = 1;
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
default:
|
|
1497
|
-
throw new Error("Usage: cw.js telemetry verify <run-id> [--pubkey <pem-or-path>] [--json]");
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
case "demo": {
|
|
1501
|
-
const [subcommand] = args.positionals;
|
|
1502
|
-
switch (subcommand) {
|
|
1503
|
-
case "tamper": {
|
|
1504
|
-
const result = (0, capability_core_1.demoTamper)(runner, args.options);
|
|
1505
|
-
if (wantsJson(args.options))
|
|
1506
|
-
printJson(result);
|
|
1507
|
-
else
|
|
1508
|
-
process.stdout.write(`${(0, telemetry_demo_1.formatTamperDemo)(result)}\n`);
|
|
1509
|
-
// Fail closed: if the proof did not hold (a tamper went undetected),
|
|
1510
|
-
// exit nonzero so the demo can never green a broken guarantee.
|
|
1511
|
-
if (!result.proven)
|
|
1512
|
-
process.exitCode = 1;
|
|
1513
|
-
return;
|
|
1514
|
-
}
|
|
1515
|
-
case "bundle": {
|
|
1516
|
-
const result = (0, capability_core_1.demoBundle)(runner, args.options);
|
|
1517
|
-
if (wantsJson(args.options))
|
|
1518
|
-
printJson(result);
|
|
1519
|
-
else
|
|
1520
|
-
process.stdout.write(`${(0, telemetry_demo_1.formatBundleDemo)(result)}\n`);
|
|
1521
|
-
// Fail closed: a forged bundle that verified would be a regression in the
|
|
1522
|
-
// bundle guarantee — exit nonzero so the demo can never green it.
|
|
1523
|
-
if (!result.proven)
|
|
1524
|
-
process.exitCode = 1;
|
|
1525
|
-
return;
|
|
1526
|
-
}
|
|
1527
|
-
default:
|
|
1528
|
-
throw new Error("Usage: cw.js demo tamper|bundle [--json]");
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
case "workbench": {
|
|
1532
|
-
const [subcommand, runId] = args.positionals;
|
|
1533
|
-
switch (subcommand) {
|
|
1534
|
-
case "view": {
|
|
1535
|
-
// Read-only five-panel view of one run. Same core entry as cw_workbench_view.
|
|
1536
|
-
const view = (0, workbench_1.buildWorkbenchRunView)(runner, required(runId, "run id"));
|
|
1537
|
-
if (wantsJson(args.options))
|
|
1538
|
-
printJson(view);
|
|
1539
|
-
else
|
|
1540
|
-
process.stdout.write(`${formatWorkbenchView(view)}\n`);
|
|
1541
|
-
return;
|
|
1542
|
-
}
|
|
1543
|
-
case "serve": {
|
|
1544
|
-
// The OPTIONAL localhost host. `--once`/`--json` emit the descriptor only
|
|
1545
|
-
// (no server); the default starts the read-only, localhost-only host.
|
|
1546
|
-
if (args.options.once || wantsJson(args.options)) {
|
|
1547
|
-
printJson((0, workbench_1.buildWorkbenchServeDescriptor)(runner, { ...args.options, once: true }));
|
|
1548
|
-
return;
|
|
1549
|
-
}
|
|
1550
|
-
const host = new workbench_host_1.WorkbenchHost({
|
|
1551
|
-
runner,
|
|
1552
|
-
cwd: String(args.options.cwd || process.cwd()),
|
|
1553
|
-
port: Number(args.options.port) || undefined,
|
|
1554
|
-
scope: args.options.scope === "repo" ? "repo" : "home"
|
|
1555
|
-
});
|
|
1556
|
-
await host.run();
|
|
1557
|
-
return;
|
|
1558
|
-
}
|
|
1559
|
-
default:
|
|
1560
|
-
throw new Error("Usage: cw.js workbench serve [--port N] [--once] | view <run-id> [--json]");
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
471
|
default:
|
|
1564
472
|
throw new Error(`Unknown command: ${args.command}${((0, orchestrator_1.suggestCommand)(String(args.command || "")) ? `. Did you mean: ${(0, orchestrator_1.suggestCommand)(String(args.command))}?` : "")}`);
|
|
1565
473
|
}
|
|
1566
474
|
}
|
|
1567
|
-
function required(value, label) {
|
|
1568
|
-
if (!value)
|
|
1569
|
-
throw new Error(`Missing ${label}.\n Tip: find run ids with "cw run list" or create one with "cw quickstart"`);
|
|
1570
|
-
return value;
|
|
1571
|
-
}
|
|
1572
|
-
function optionalArg(value) {
|
|
1573
|
-
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
1574
|
-
}
|
|
1575
|
-
/** Emit the calm end-of-run summary (stderr, TTY-gated inside the reporter): the COMPACT findings
|
|
1576
|
-
* table re-parsed from each completed worker's `cw:result`, the report path, where the per-worker
|
|
1577
|
-
* transcripts live, and — under `--full` — the report inline. Stderr/human-side ONLY: stdout (the
|
|
1578
|
-
* `--json` payload printed just before this) stays byte-exact. Shared by the quickstart and the
|
|
1579
|
-
* two `run --drive` paths so all three render an identical summary. */
|
|
1580
|
-
function emitRunSummary(runner, options, fields) {
|
|
1581
|
-
// Anchor run reads to the run's OWN repo (a drive/quickstart may run cross-directory): the run
|
|
1582
|
-
// dir is <repo>/.cw/runs/<id>/, holding each worker's transcript.md next to its result.md.
|
|
1583
|
-
const runDir = typeof fields.statePath === "string" ? node_path_1.default.dirname(fields.statePath) : undefined;
|
|
1584
|
-
const baseDir = runDir ? node_path_1.default.resolve(runDir, "..", "..", "..") : undefined;
|
|
1585
|
-
const findings = (0, capability_core_1.collectRunFindings)(runner, fields.runId, baseDir);
|
|
1586
|
-
// --full ALSO prints the report inline at run end (the compact table stays the default summary).
|
|
1587
|
-
let fullReport;
|
|
1588
|
-
if (options.full && fields.reportPath && node_fs_1.default.existsSync(fields.reportPath)) {
|
|
1589
|
-
try {
|
|
1590
|
-
fullReport = node_fs_1.default.readFileSync(fields.reportPath, "utf8");
|
|
1591
|
-
}
|
|
1592
|
-
catch { /* best-effort inline */ }
|
|
1593
|
-
}
|
|
1594
|
-
reporter_1.reporter.runSummary({
|
|
1595
|
-
runId: fields.runId,
|
|
1596
|
-
reportPath: fields.reportPath,
|
|
1597
|
-
status: fields.status,
|
|
1598
|
-
completedWorkers: fields.completedWorkers,
|
|
1599
|
-
plannedWorkers: fields.plannedWorkers,
|
|
1600
|
-
agentConfigured: fields.agentConfigured,
|
|
1601
|
-
findings,
|
|
1602
|
-
runDir,
|
|
1603
|
-
fullReport
|
|
1604
|
-
});
|
|
1605
|
-
}
|
|
1606
|
-
function printJson(value) {
|
|
1607
|
-
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
1608
|
-
}
|
|
1609
|
-
function humanBytes(n) {
|
|
1610
|
-
if (n < 1024)
|
|
1611
|
-
return `${n}B`;
|
|
1612
|
-
const units = ["KiB", "MiB", "GiB"];
|
|
1613
|
-
let v = n / 1024;
|
|
1614
|
-
let i = 0;
|
|
1615
|
-
while (v >= 1024 && i < units.length - 1) {
|
|
1616
|
-
v /= 1024;
|
|
1617
|
-
i += 1;
|
|
1618
|
-
}
|
|
1619
|
-
return `${v.toFixed(1)}${units[i]}`;
|
|
1620
|
-
}
|
|
1621
|
-
function formatClonesList(result) {
|
|
1622
|
-
if (result.count === 0)
|
|
1623
|
-
return `No cached remote checkouts in ${result.clonesDir}.`;
|
|
1624
|
-
const rows = result.entries.map((e) => {
|
|
1625
|
-
const when = e.fetchedAt ? e.fetchedAt.replace("T", " ").replace(/\..*$/, "Z") : "unknown";
|
|
1626
|
-
return ` ${e.kind.padEnd(7)} ${humanBytes(e.bytes).padStart(8)} ${when} ${e.url}${e.ref ? `@${e.ref}` : ""}`;
|
|
1627
|
-
});
|
|
1628
|
-
return [
|
|
1629
|
-
`${result.count} cached checkout${result.count === 1 ? "" : "s"} — ${humanBytes(result.totalBytes)} in ${result.clonesDir}`,
|
|
1630
|
-
" KIND SIZE FETCHED SOURCE",
|
|
1631
|
-
...rows,
|
|
1632
|
-
`\nReclaim with: cw clones gc --older-than-days 30 (or --all)`
|
|
1633
|
-
].join("\n");
|
|
1634
|
-
}
|
|
1635
|
-
function formatClonesGc(result) {
|
|
1636
|
-
const scope = result.all ? "all entries" : `entries older than ${result.olderThanDays} day(s)`;
|
|
1637
|
-
if (result.removed.length === 0)
|
|
1638
|
-
return `Nothing to reclaim (${scope}); ${result.keptCount} kept in ${result.clonesDir}.`;
|
|
1639
|
-
const rows = result.removed.map((r) => ` ${humanBytes(r.bytes).padStart(8)} ${r.url}`);
|
|
1640
|
-
return [
|
|
1641
|
-
`Reclaimed ${result.removed.length} checkout${result.removed.length === 1 ? "" : "s"} (${scope}) — freed ${humanBytes(result.freedBytes)}; ${result.keptCount} kept`,
|
|
1642
|
-
...rows
|
|
1643
|
-
].join("\n");
|
|
1644
|
-
}
|
|
1645
|
-
function wantsJson(options) {
|
|
1646
|
-
return Boolean(options.json || options.format === "json");
|
|
1647
|
-
}
|
|
1648
475
|
/** Prompt the user for a question interactively when --question is missing on a TTY. */
|
|
1649
476
|
async function promptQuestion(options) {
|
|
1650
477
|
if (options.question || !process.stdin.isTTY)
|
|
@@ -1659,17 +486,3 @@ async function promptQuestion(options) {
|
|
|
1659
486
|
});
|
|
1660
487
|
});
|
|
1661
488
|
}
|
|
1662
|
-
function formatWorkbenchView(view) {
|
|
1663
|
-
const lines = [
|
|
1664
|
-
`Workbench view ${view.runId} (${view.resolved ? "resolved" : "UNRESOLVED"})`,
|
|
1665
|
-
view.error ? ` error: ${view.error}` : ""
|
|
1666
|
-
].filter(Boolean);
|
|
1667
|
-
for (const [group, panels] of Object.entries(view.panels)) {
|
|
1668
|
-
lines.push(` ${group}:`);
|
|
1669
|
-
for (const [name, panel] of Object.entries(panels)) {
|
|
1670
|
-
const note = panel.status === "present" ? panel.capability : `absent (${panel.error || "unreadable"})`;
|
|
1671
|
-
lines.push(` ${name}: ${panel.status} — ${note}`);
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
return lines.join("\n");
|
|
1675
|
-
}
|