cool-workflow 0.1.83 → 0.1.85

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.
Files changed (60) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +6 -0
  4. package/apps/architecture-review/app.json +1 -1
  5. package/apps/architecture-review-fast/app.json +1 -1
  6. package/apps/end-to-end-golden-path/app.json +1 -1
  7. package/apps/pr-review-fix-ci/app.json +1 -1
  8. package/apps/release-cut/app.json +1 -1
  9. package/apps/research-synthesis/app.json +1 -1
  10. package/dist/capability-core.js +89 -2
  11. package/dist/capability-registry.js +269 -2
  12. package/dist/cli/command-surface.js +1362 -0
  13. package/dist/cli.js +2 -1318
  14. package/dist/mcp-server.js +5 -1452
  15. package/dist/mcp-surface.js +1467 -0
  16. package/dist/run-export.js +139 -1
  17. package/dist/telemetry-demo.js +119 -0
  18. package/dist/types/report-bundle.js +6 -0
  19. package/dist/types.js +1 -0
  20. package/dist/version.js +1 -1
  21. package/dist/worker-accept/acceptance.js +114 -0
  22. package/dist/worker-accept/blackboard-fanout.js +80 -0
  23. package/dist/worker-accept/blackboard-linkage.js +19 -0
  24. package/dist/worker-accept/context.js +2 -0
  25. package/dist/worker-accept/telemetry-ledger.js +116 -0
  26. package/dist/worker-accept/validation.js +77 -0
  27. package/dist/worker-accept/verifier-completion.js +73 -0
  28. package/dist/worker-isolation.js +19 -444
  29. package/docs/agent-delegation-drive.7.md +6 -0
  30. package/docs/cli-mcp-parity.7.md +13 -3
  31. package/docs/contract-migration-tooling.7.md +6 -0
  32. package/docs/control-plane-scheduling.7.md +6 -0
  33. package/docs/durable-state-and-locking.7.md +6 -0
  34. package/docs/evidence-adoption-reasoning-chain.7.md +6 -0
  35. package/docs/execution-backends.7.md +6 -0
  36. package/docs/index.md +1 -0
  37. package/docs/multi-agent-cli-mcp-surface.7.md +6 -0
  38. package/docs/multi-agent-eval-replay-harness.7.md +6 -0
  39. package/docs/multi-agent-operator-ux.7.md +6 -0
  40. package/docs/node-snapshot-diff-replay.7.md +6 -0
  41. package/docs/observability-cost-accounting.7.md +6 -0
  42. package/docs/project-index.md +17 -6
  43. package/docs/real-execution-backends.7.md +6 -0
  44. package/docs/release-and-migration.7.md +6 -0
  45. package/docs/release-tooling.7.md +16 -1
  46. package/docs/report-verifiable-bundle.7.md +123 -0
  47. package/docs/run-registry-control-plane.7.md +6 -0
  48. package/docs/run-retention-reclamation.7.md +6 -0
  49. package/docs/state-explosion-management.7.md +6 -0
  50. package/docs/team-collaboration.7.md +6 -0
  51. package/docs/web-desktop-workbench.7.md +6 -0
  52. package/manifest/plugin.manifest.json +1 -1
  53. package/package.json +1 -1
  54. package/scripts/bump-version.js +9 -1
  55. package/scripts/canonical-apps.js +4 -4
  56. package/scripts/dogfood-release.js +1 -1
  57. package/scripts/golden-path.js +4 -4
  58. package/scripts/parity-check.js +27 -57
  59. package/scripts/release-flow.js +7 -6
  60. package/scripts/sync-project-index.js +1 -1
package/dist/cli.js CHANGED
@@ -1,1324 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
3
  Object.defineProperty(exports, "__esModule", { value: true });
7
- const node_fs_1 = __importDefault(require("node:fs"));
8
- const node_path_1 = __importDefault(require("node:path"));
9
- const orchestrator_1 = require("./orchestrator");
10
- const capability_core_1 = require("./capability-core");
11
- const observability_1 = require("./observability");
12
- const telemetry_demo_1 = require("./telemetry-demo");
13
- const run_registry_1 = require("./run-registry");
14
- const daemon_1 = require("./daemon");
15
- const scheduler_1 = require("./scheduler");
16
- const triggers_1 = require("./triggers");
17
- const workbench_1 = require("./workbench");
18
- const workbench_host_1 = require("./workbench-host");
19
- const operator_ux_1 = require("./operator-ux");
20
- const multi_agent_operator_ux_1 = require("./multi-agent-operator-ux");
21
- const multi_agent_eval_1 = require("./multi-agent-eval");
22
- const state_explosion_1 = require("./state-explosion");
23
- const evidence_reasoning_1 = require("./evidence-reasoning");
24
- const doctor_1 = require("./doctor");
25
- async function main() {
26
- const args = (0, orchestrator_1.parseArgv)(process.argv.slice(2));
27
- const runner = new orchestrator_1.CoolWorkflowRunner({
28
- pluginRoot: node_path_1.default.resolve(__dirname, "..")
29
- });
30
- const scheduler = new scheduler_1.Scheduler(String(args.options.cwd || process.cwd()));
31
- const triggers = new triggers_1.RoutineTriggerBridge(String(args.options.cwd || process.cwd()));
32
- switch (args.command) {
33
- case "help":
34
- case undefined:
35
- process.stdout.write((0, orchestrator_1.formatHelp)());
36
- return;
37
- case "list":
38
- printJson(runner.listWorkflows());
39
- return;
40
- case "doctor": {
41
- const report = (0, doctor_1.runDoctor)(args.options, process.env, String(args.options.cwd || process.cwd()));
42
- if (wantsJson(args.options))
43
- printJson(report);
44
- else
45
- process.stdout.write(`${(0, doctor_1.formatDoctorReport)(report)}\n`);
46
- if (!report.ok)
47
- process.exitCode = 1;
48
- return;
49
- }
50
- case "init": {
51
- const [workflowId] = args.positionals;
52
- if (!workflowId)
53
- throw new Error("Missing workflow id. Example: cw.js init my-workflow");
54
- printJson(runner.init(workflowId, args.options));
55
- return;
56
- }
57
- case "app": {
58
- const [subcommand, appIdOrPath] = args.positionals;
59
- switch (subcommand) {
60
- case "list":
61
- printJson(runner.listApps());
62
- return;
63
- case "show":
64
- printJson(runner.showApp(required(appIdOrPath, "app id")));
65
- return;
66
- case "validate": {
67
- const result = runner.validateApp(required(appIdOrPath, "app path or id"));
68
- printJson(result);
69
- if (!result.valid)
70
- process.exitCode = 1;
71
- return;
72
- }
73
- case "init":
74
- printJson(runner.initApp(required(appIdOrPath, "app id"), args.options));
75
- return;
76
- case "package":
77
- printJson(runner.packageApp(required(appIdOrPath, "app id"), args.options));
78
- return;
79
- case "run":
80
- printJson((0, capability_core_1.appRun)(runner, { ...args.options, appId: required(appIdOrPath, "app id") }));
81
- return;
82
- default:
83
- throw new Error("Usage: cw.js app list|show|validate|init|package|run [app-id|path]");
84
- }
85
- }
86
- case "quickstart":
87
- case "audit-run": {
88
- // ONE-COMMAND first value (v0.1.38+): plan(app) -> run --drive -> report in a
89
- // single invocation. A thin UX wrapper over the EXISTING drive() pipeline — it
90
- // DELEGATES worker execution to the operator's configured agent backend and
91
- // fails closed (status=blocked) when none is set. No new executor/scheduler.
92
- const [appId] = args.positionals;
93
- const runId = optionalArg(args.options.run) || optionalArg(args.options.runId);
94
- printJson((0, capability_core_1.quickstart)(runner, { ...args.options, ...(appId ? { appId } : {}), ...(runId ? { runId } : {}) }));
95
- return;
96
- }
97
- case "plan": {
98
- const [workflowId] = args.positionals;
99
- if (!workflowId)
100
- throw new Error("Missing workflow id. Example: cw.js plan architecture-review");
101
- printJson((0, capability_core_1.planSummary)(runner, workflowId, args.options));
102
- return;
103
- }
104
- case "status":
105
- if (!args.positionals[0]) {
106
- const nextActions = (0, operator_ux_1.adviseNoRun)();
107
- if (wantsJson(args.options))
108
- printJson({ runId: null, nextActions });
109
- else
110
- process.stdout.write(`No run selected\n\nNext Action\n${nextActions.map((action) => ` ${action.command}\n reason: ${action.reason}`).join("\n")}\n`);
111
- }
112
- else if (wantsJson(args.options))
113
- printJson(runner.status(args.positionals[0]));
114
- else
115
- process.stdout.write(`${(0, operator_ux_1.formatOperatorStatus)(runner.operatorStatus(args.positionals[0]))}\n`);
116
- return;
117
- case "next":
118
- printJson(runner.next(required(args.positionals[0], "run id"), args.options));
119
- return;
120
- case "dispatch":
121
- printJson(runner.dispatch(required(args.positionals[0], "run id"), args.options));
122
- return;
123
- case "result": {
124
- const [runId, taskId, resultPath] = args.positionals;
125
- printJson(runner.recordResult(required(runId, "run id"), required(taskId, "task id"), required(resultPath, "result file"), args.options));
126
- return;
127
- }
128
- case "state": {
129
- const [subcommand, runId] = args.positionals;
130
- switch (subcommand) {
131
- case "check": {
132
- const report = runner.checkState(required(runId, "run id"), args.options);
133
- printJson(report);
134
- if (report.status === "unsupported")
135
- process.exitCode = 1;
136
- return;
137
- }
138
- default:
139
- throw new Error("Usage: cw.js state check <run-id> [--state PATH] [--write]");
140
- }
141
- }
142
- case "commit":
143
- if (args.positionals[0] === "summary") {
144
- const summary = runner.summarizeCommitRecords(required(args.positionals[1], "run id"));
145
- if (wantsJson(args.options))
146
- printJson(summary);
147
- else
148
- process.stdout.write(`${(0, operator_ux_1.formatCommitSummary)(summary)}\n`);
149
- return;
150
- }
151
- printJson(runner.commit(required(args.positionals[0], "run id"), args.options));
152
- return;
153
- case "report": {
154
- const runId = required(args.positionals[0], "run id");
155
- const report = runner.report(runId);
156
- if (wantsJson(args.options)) {
157
- printJson(report);
158
- }
159
- else if (args.options.show || args.options.summary) {
160
- process.stdout.write(`${(0, operator_ux_1.formatOperatorReport)(runner.operatorReport(runId))}\n`);
161
- process.stdout.write(`\n${(0, state_explosion_1.formatStateExplosionReport)(runner.stateExplosionReport(runId))}\n`);
162
- }
163
- else {
164
- process.stdout.write(`${report.path}\n`);
165
- }
166
- return;
167
- }
168
- case "operator": {
169
- const [subcommand, runId] = args.positionals;
170
- switch (subcommand) {
171
- case "status":
172
- if (wantsJson(args.options))
173
- printJson(runner.operatorStatus(required(runId, "run id")));
174
- else
175
- process.stdout.write(`${(0, operator_ux_1.formatOperatorStatus)(runner.operatorStatus(required(runId, "run id")))}\n`);
176
- return;
177
- case "report":
178
- if (wantsJson(args.options))
179
- printJson(runner.operatorReport(required(runId, "run id")));
180
- else
181
- process.stdout.write(`${(0, operator_ux_1.formatOperatorReport)(runner.operatorReport(required(runId, "run id")))}\n`);
182
- return;
183
- default:
184
- throw new Error("Usage: cw.js operator status|report <run-id> [--json]");
185
- }
186
- }
187
- case "graph": {
188
- const graph = runner.operatorGraph(required(args.positionals[0], "run id"));
189
- if (wantsJson(args.options))
190
- printJson(graph);
191
- else
192
- process.stdout.write(`${(0, operator_ux_1.formatOperatorGraph)(graph)}\n`);
193
- return;
194
- }
195
- case "topology": {
196
- const [subcommand, first, second] = args.positionals;
197
- switch (subcommand) {
198
- case "list":
199
- printJson(runner.listTopologies());
200
- return;
201
- case "show":
202
- if (second)
203
- printJson(runner.showTopologyRun(required(first, "run id"), second));
204
- else
205
- printJson(runner.showTopology(required(first, "topology id")));
206
- return;
207
- case "validate": {
208
- const result = runner.validateTopology(required(first, "topology id"));
209
- printJson(result);
210
- if (!result.valid)
211
- process.exitCode = 1;
212
- return;
213
- }
214
- case "apply":
215
- printJson(runner.applyTopology(required(first, "run id"), required(second, "topology id"), args.options));
216
- return;
217
- case "summary": {
218
- const summary = runner.topologySummary(required(first, "run id"));
219
- if (wantsJson(args.options))
220
- printJson(summary);
221
- else
222
- process.stdout.write(`${(0, operator_ux_1.formatTopologySummary)(summary)}\n`);
223
- return;
224
- }
225
- case "graph": {
226
- const graph = runner.topologyGraph(required(first, "run id"));
227
- if (wantsJson(args.options))
228
- printJson(graph);
229
- else
230
- process.stdout.write(`${(0, operator_ux_1.formatOperatorGraph)({ runId: required(first, "run id"), nodes: graph.nodes, edges: graph.edges })}\n`);
231
- return;
232
- }
233
- default:
234
- throw new Error("Usage: cw.js topology list|show <topology-id>|show <run-id> <topology-run-id>|validate <topology-id>|apply <run-id> <topology-id>|summary <run-id>|graph <run-id>");
235
- }
236
- }
237
- case "summary": {
238
- const [subcommand, runId] = args.positionals;
239
- switch (subcommand) {
240
- case "refresh": {
241
- const index = runner.summaryRefresh(required(runId, "run id"), args.options);
242
- if (wantsJson(args.options))
243
- printJson(index);
244
- else
245
- process.stdout.write(`${(0, state_explosion_1.formatStateExplosionReport)(runner.summaryShow(required(runId, "run id")))}\n`);
246
- return;
247
- }
248
- case "show": {
249
- const report = runner.summaryShow(required(runId, "run id"));
250
- if (wantsJson(args.options))
251
- printJson(report);
252
- else
253
- process.stdout.write(`${(0, state_explosion_1.formatStateExplosionReport)(report)}\n`);
254
- return;
255
- }
256
- default:
257
- throw new Error("Usage: cw.js summary refresh|show <run-id> [--json]");
258
- }
259
- }
260
- case "multi-agent": {
261
- const [subcommand, runId, id] = args.positionals;
262
- switch (subcommand) {
263
- case "status":
264
- if (wantsJson(args.options))
265
- printJson(runner.hostMultiAgentStatus(required(runId, "run id")));
266
- else
267
- process.stdout.write(`${(0, multi_agent_operator_ux_1.formatMultiAgentOperatorStatus)(runner.multiAgentOperatorStatus(required(runId, "run id")))}\n`);
268
- return;
269
- case "step":
270
- printJson(runner.hostMultiAgentStep(required(runId, "run id"), args.options));
271
- return;
272
- case "blackboard":
273
- printJson(runner.hostMultiAgentBlackboard(required(runId, "run id"), id, args.options));
274
- return;
275
- case "score":
276
- printJson(runner.hostMultiAgentScore(required(runId, "run id"), { ...args.options, candidate: args.options.candidate || args.options.candidateId || id }));
277
- return;
278
- case "select":
279
- printJson(runner.hostMultiAgentSelect(required(runId, "run id"), { ...args.options, candidate: args.options.candidate || args.options.candidateId || id }));
280
- return;
281
- case "summary": {
282
- const summary = runner.multiAgentSummary(required(runId, "run id"));
283
- if (wantsJson(args.options))
284
- printJson(summary);
285
- else
286
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentSummary)(summary)}\n`);
287
- return;
288
- }
289
- case "summarize": {
290
- const report = runner.multiAgentSummarize(required(runId, "run id"));
291
- if (wantsJson(args.options))
292
- printJson(report);
293
- else
294
- process.stdout.write(`${(0, state_explosion_1.formatStateExplosionReport)(report)}\n`);
295
- return;
296
- }
297
- case "graph": {
298
- const wantsView = args.options.view || args.options.focus || args.options.depth;
299
- if (wantsView) {
300
- const graph = runner.multiAgentGraphView(required(runId, "run id"), args.options);
301
- if (wantsJson(args.options))
302
- printJson(graph);
303
- else
304
- process.stdout.write(`${(0, state_explosion_1.formatCompactGraph)(graph)}\n`);
305
- return;
306
- }
307
- const graph = runner.multiAgentOperatorGraph(required(runId, "run id"));
308
- if (wantsJson(args.options))
309
- printJson(graph);
310
- else
311
- process.stdout.write(`${(0, operator_ux_1.formatOperatorGraph)({ runId: required(runId, "run id"), nodes: graph.nodes, edges: graph.edges })}\n`);
312
- return;
313
- }
314
- case "dependencies": {
315
- const rows = runner.multiAgentDependencies(required(runId, "run id"));
316
- if (wantsJson(args.options))
317
- printJson(rows);
318
- else
319
- process.stdout.write(`${(0, multi_agent_operator_ux_1.formatMultiAgentDependencies)(rows)}\n`);
320
- return;
321
- }
322
- case "failures": {
323
- const rows = runner.multiAgentFailures(required(runId, "run id"));
324
- if (wantsJson(args.options))
325
- printJson(rows);
326
- else
327
- process.stdout.write(`${(0, multi_agent_operator_ux_1.formatMultiAgentFailures)(rows)}\n`);
328
- return;
329
- }
330
- case "evidence": {
331
- const rows = runner.multiAgentEvidence(required(runId, "run id"));
332
- if (wantsJson(args.options))
333
- printJson(rows);
334
- else
335
- process.stdout.write(`${(0, multi_agent_operator_ux_1.formatMultiAgentEvidence)(rows)}\n`);
336
- return;
337
- }
338
- case "reasoning": {
339
- if (args.options.refresh && !args.options.evidence && !args.options.evidenceId) {
340
- const index = runner.multiAgentReasoningRefresh(required(runId, "run id"));
341
- printJson(index);
342
- return;
343
- }
344
- const report = runner.multiAgentReasoning(required(runId, "run id"), { ...args.options, evidence: args.options.evidence || args.options.evidenceId || id });
345
- if (wantsJson(args.options))
346
- printJson(report);
347
- else
348
- process.stdout.write(`${(0, evidence_reasoning_1.formatEvidenceReasoningReport)(report)}\n`);
349
- return;
350
- }
351
- case "run":
352
- if (!runId ||
353
- args.options.topology ||
354
- args.options.topologyId ||
355
- args.options.app ||
356
- args.options.appId ||
357
- args.options.workflow ||
358
- args.options.workflowId) {
359
- printJson(runner.hostMultiAgentRun(runId, args.options));
360
- return;
361
- }
362
- if (id && !args.options.id && !args.options.status)
363
- printJson(runner.showMultiAgentRun(required(runId, "run id"), id));
364
- else if (id && args.options.status)
365
- printJson(runner.transitionMultiAgentRun(required(runId, "run id"), id, args.options));
366
- else
367
- printJson(runner.createMultiAgentRun(required(runId, "run id"), args.options));
368
- return;
369
- case "show":
370
- printJson(runner.showMultiAgentRun(required(runId, "run id"), required(id, "multi-agent run id")));
371
- return;
372
- case "role":
373
- if (id && !args.options.id && !args.options["multi-agent-run"] && !args.options.multiAgentRun && !args.options.multiAgentRunId) {
374
- printJson(runner.showAgentRole(required(runId, "run id"), id));
375
- }
376
- else {
377
- printJson(runner.createAgentRole(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
378
- }
379
- return;
380
- case "group":
381
- if (id && !args.options.id && !args.options["multi-agent-run"] && !args.options.multiAgentRun && !args.options.multiAgentRunId) {
382
- printJson(runner.showAgentGroup(required(runId, "run id"), id));
383
- }
384
- else {
385
- printJson(runner.createAgentGroup(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
386
- }
387
- return;
388
- case "membership":
389
- if (id && !args.options.id && !args.options.group && !args.options.groupId && !args.options["multi-agent-group"]) {
390
- printJson(runner.showAgentMembership(required(runId, "run id"), id));
391
- }
392
- else {
393
- printJson(runner.assignAgentMembership(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
394
- }
395
- return;
396
- case "fanout":
397
- if (id && !args.options.id && !args.options.group && !args.options.groupId && !args.options["multi-agent-group"]) {
398
- printJson(runner.showAgentFanout(required(runId, "run id"), id));
399
- }
400
- else {
401
- printJson(runner.createAgentFanout(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
402
- }
403
- return;
404
- case "fanin":
405
- if (id && !args.options.id && !args.options.group && !args.options.groupId && !args.options["multi-agent-group"] && !args.options.fanout) {
406
- printJson(runner.showAgentFanin(required(runId, "run id"), id));
407
- }
408
- else {
409
- printJson(runner.collectAgentFanin(required(runId, "run id"), { ...args.options, id: args.options.id || id }));
410
- }
411
- return;
412
- default:
413
- 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]");
414
- }
415
- }
416
- case "eval": {
417
- const [subcommand, first, second] = args.positionals;
418
- let result;
419
- switch (subcommand) {
420
- case "snapshot":
421
- result = runner.evalSnapshot(required(first, "run id"), args.options);
422
- break;
423
- case "replay":
424
- result = runner.evalReplay(required(first, "snapshot id or path"), args.options);
425
- break;
426
- case "compare":
427
- result = runner.evalCompare(required(first, "baseline id or path"), required(second, "replay id or path"));
428
- break;
429
- case "score":
430
- result = runner.evalScore(required(first, "replay id or path"));
431
- break;
432
- case "gate":
433
- result = runner.evalGate(required(first, "suite id or path"));
434
- if (!wantsJson(args.options) && result.status === "fail")
435
- process.exitCode = 1;
436
- break;
437
- case "report":
438
- result = runner.evalReport(required(first, "replay id or path"));
439
- break;
440
- default:
441
- 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>");
442
- }
443
- if (wantsJson(args.options))
444
- printJson(result);
445
- else
446
- process.stdout.write(`${(0, multi_agent_eval_1.formatMultiAgentEval)(result)}\n`);
447
- if (subcommand === "gate" && result.status === "fail")
448
- process.exitCode = 1;
449
- return;
450
- }
451
- case "blackboard": {
452
- const [subcommand, action, runId] = args.positionals;
453
- switch (subcommand) {
454
- case "summary":
455
- printJson(runner.blackboardSummary(required(action, "run id"), args.options));
456
- return;
457
- case "summarize": {
458
- const digest = runner.blackboardSummarize(required(action, "run id"), args.options);
459
- if (wantsJson(args.options))
460
- printJson(digest);
461
- else
462
- process.stdout.write(`${(0, state_explosion_1.formatBlackboardDigest)(digest)}\n`);
463
- return;
464
- }
465
- case "graph":
466
- printJson(runner.blackboardGraph(required(action, "run id")));
467
- return;
468
- case "resolve":
469
- printJson(runner.resolveRunBlackboard(required(action, "run id"), args.options));
470
- return;
471
- case "topic":
472
- if (action === "create") {
473
- printJson(runner.createBlackboardTopic(required(runId, "run id"), args.options));
474
- return;
475
- }
476
- break;
477
- case "message":
478
- if (action === "post") {
479
- printJson(runner.postBlackboardMessage(required(runId, "run id"), args.options));
480
- return;
481
- }
482
- if (action === "list") {
483
- printJson(runner.listBlackboardMessages(required(runId, "run id"), args.options));
484
- return;
485
- }
486
- break;
487
- case "context":
488
- if (action === "put") {
489
- printJson(runner.putBlackboardContext(required(runId, "run id"), args.options));
490
- return;
491
- }
492
- break;
493
- case "artifact":
494
- if (action === "add") {
495
- printJson(runner.addBlackboardArtifact(required(runId, "run id"), args.options));
496
- return;
497
- }
498
- if (action === "list") {
499
- printJson(runner.listBlackboardArtifacts(required(runId, "run id"), args.options));
500
- return;
501
- }
502
- break;
503
- case "snapshot":
504
- printJson(runner.snapshotBlackboard(required(action, "run id"), args.options));
505
- return;
506
- default:
507
- break;
508
- }
509
- 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>");
510
- }
511
- case "coordinator": {
512
- const [subcommand, runId] = args.positionals;
513
- switch (subcommand) {
514
- case "summary":
515
- printJson(runner.coordinatorSummary(required(runId, "run id"), args.options));
516
- return;
517
- case "decision":
518
- printJson(runner.recordCoordinatorDecision(required(runId, "run id"), args.options));
519
- return;
520
- default:
521
- throw new Error("Usage: cw.js coordinator summary <run-id> | coordinator decision <run-id> --kind <kind> --outcome <outcome> --reason TEXT");
522
- }
523
- }
524
- case "sandbox": {
525
- const [subcommand, profileIdOrFile] = args.positionals;
526
- switch (subcommand) {
527
- case "list":
528
- printJson(runner.listSandboxProfiles(args.options));
529
- return;
530
- case "show":
531
- printJson(runner.showSandboxProfile(required(profileIdOrFile, "profile id"), args.options));
532
- return;
533
- case "validate": {
534
- const result = runner.validateSandboxProfile(required(profileIdOrFile, "profile file"), args.options);
535
- printJson(result);
536
- if (!result.valid)
537
- process.exitCode = 1;
538
- return;
539
- }
540
- case "choose":
541
- case "resolve":
542
- printJson((0, capability_core_1.sandboxChoose)(runner, { ...args.options, profileId: profileIdOrFile || args.options.profileId }));
543
- return;
544
- default:
545
- throw new Error("Usage: cw.js sandbox list|show|validate|choose|resolve [profile-id|profile-file]");
546
- }
547
- }
548
- case "backend": {
549
- const [subcommand, backendId] = args.positionals;
550
- switch (subcommand) {
551
- case "list":
552
- printJson(runner.listBackends(args.options));
553
- return;
554
- case "show":
555
- printJson(runner.showBackend(required(backendId, "backend id"), args.options));
556
- return;
557
- case "probe":
558
- printJson(runner.probeBackend(backendId, args.options));
559
- return;
560
- case "agent": {
561
- // `backend agent config [show]` = read-only; `backend agent config set ...` = mutating.
562
- const [, , action] = args.positionals;
563
- if (action === "set") {
564
- printJson((0, capability_core_1.backendAgentConfigSet)(args.options));
565
- return;
566
- }
567
- printJson((0, capability_core_1.backendAgentConfigShow)(args.options));
568
- return;
569
- }
570
- default:
571
- 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 ...]");
572
- }
573
- }
574
- case "contract": {
575
- const [subcommand, runId, contractId] = args.positionals;
576
- switch (subcommand) {
577
- case "show":
578
- printJson(runner.showContract(required(runId, "run id"), contractId));
579
- return;
580
- default:
581
- throw new Error("Usage: cw.js contract show <run-id> [contract-id]");
582
- }
583
- }
584
- case "node": {
585
- const [subcommand, runId, nodeId] = args.positionals;
586
- switch (subcommand) {
587
- case "list":
588
- printJson(runner.listNodes(required(runId, "run id")));
589
- return;
590
- case "show":
591
- printJson(runner.showNode(required(runId, "run id"), required(nodeId, "node id")));
592
- return;
593
- case "graph":
594
- if (wantsJson(args.options))
595
- printJson(runner.graphNodes(required(runId, "run id")));
596
- else
597
- process.stdout.write(`${(0, operator_ux_1.formatOperatorGraph)(runner.operatorGraph(required(runId, "run id")))}\n`);
598
- return;
599
- case "snapshot":
600
- printJson(runner.nodeSnapshot(required(runId, "run id"), required(nodeId, "node id")));
601
- return;
602
- case "diff":
603
- printJson(runner.nodeDiff(required(runId, "run id"), required(nodeId, "baseline snapshot id"), required(args.positionals[3], "candidate snapshot id")));
604
- return;
605
- case "replay":
606
- printJson(runner.nodeReplay(required(runId, "run id"), required(nodeId, "snapshot id")));
607
- return;
608
- case "verify": {
609
- const verdict = runner.nodeReplayVerify(required(runId, "run id"), required(nodeId, "replay id"));
610
- printJson(verdict);
611
- if (!verdict.pass)
612
- process.exitCode = 1;
613
- return;
614
- }
615
- default:
616
- throw new Error("Usage: cw.js node list|show|graph|snapshot|diff|replay|verify <run-id> [node-id|snapshot-id|replay-id]");
617
- }
618
- }
619
- case "migration": {
620
- const [subcommand, target] = args.positionals;
621
- switch (subcommand) {
622
- case "list":
623
- printJson(runner.migrationList());
624
- return;
625
- case "check": {
626
- const report = runner.migrationCheck(required(target, "target (run-id or state/app file)"), args.options);
627
- printJson(report);
628
- if (report.status === "unsupported")
629
- process.exitCode = 1;
630
- return;
631
- }
632
- case "prove": {
633
- const proof = runner.migrationProve(required(target, "target (run-id or state/app file)"), args.options);
634
- printJson(proof);
635
- if (!proof.pass)
636
- process.exitCode = 1;
637
- return;
638
- }
639
- default:
640
- throw new Error("Usage: cw.js migration list|check|prove [target] [--contract run-state|workflow-app]");
641
- }
642
- }
643
- case "feedback": {
644
- const [subcommand, runId, feedbackId] = args.positionals;
645
- switch (subcommand) {
646
- case "list":
647
- printJson(runner.listFeedback(required(runId, "run id"), args.options));
648
- return;
649
- case "show":
650
- printJson(runner.showFeedback(required(runId, "run id"), required(feedbackId, "feedback id")));
651
- return;
652
- case "collect":
653
- printJson(runner.collectFeedback(required(runId, "run id")));
654
- return;
655
- case "summary": {
656
- const summary = runner.summarizeFeedbackRecords(required(runId, "run id"));
657
- if (wantsJson(args.options))
658
- printJson(summary);
659
- else
660
- process.stdout.write(`${(0, operator_ux_1.formatFeedbackSummary)(summary)}\n`);
661
- return;
662
- }
663
- case "task":
664
- printJson(runner.createFeedbackTask(required(runId, "run id"), required(feedbackId, "feedback id"), args.options));
665
- return;
666
- case "resolve":
667
- printJson(runner.resolveFeedback(required(runId, "run id"), required(feedbackId, "feedback id"), args.options));
668
- return;
669
- default:
670
- throw new Error("Usage: cw.js feedback list|show|summary|collect|task|resolve <run-id> [feedback-id]");
671
- }
672
- }
673
- case "worker": {
674
- const [subcommand, runId, workerId, resultPath] = args.positionals;
675
- switch (subcommand) {
676
- case "list":
677
- printJson(runner.listWorkers(required(runId, "run id"), args.options));
678
- return;
679
- case "summary": {
680
- const summary = runner.summarizeWorkerRecords(required(runId, "run id"));
681
- if (wantsJson(args.options))
682
- printJson(summary);
683
- else
684
- process.stdout.write(`${(0, operator_ux_1.formatWorkerSummary)(summary)}\n`);
685
- return;
686
- }
687
- case "show":
688
- printJson(runner.showWorker(required(runId, "run id"), required(workerId, "worker id")));
689
- return;
690
- case "manifest":
691
- printJson(runner.showWorkerManifest(required(runId, "run id"), required(workerId, "worker id")));
692
- return;
693
- case "output":
694
- printJson(runner.recordWorkerOutput(required(runId, "run id"), required(workerId, "worker id"), required(resultPath, "result file"), args.options));
695
- return;
696
- case "fail":
697
- printJson(runner.recordWorkerFailure(required(runId, "run id"), required(workerId, "worker id"), String(args.options.message || required(resultPath, "failure message")), args.options));
698
- return;
699
- case "validate": {
700
- // Non-null = a boundary violation: a validate verb must report an invalid
701
- // verdict through its exit code, not just print it and exit 0.
702
- const violation = runner.validateWorker(required(runId, "run id"), required(workerId, "worker id"), resultPath);
703
- printJson(violation);
704
- if (violation)
705
- process.exitCode = 1;
706
- return;
707
- }
708
- default:
709
- throw new Error("Usage: cw.js worker list|summary|show|manifest|output|fail|validate <run-id> [worker-id] [result-file]");
710
- }
711
- }
712
- case "audit": {
713
- const [subcommand, runId, id] = args.positionals;
714
- switch (subcommand) {
715
- case "summary":
716
- printJson(runner.auditSummary(required(runId, "run id")));
717
- return;
718
- case "verify": {
719
- const result = (0, capability_core_1.auditVerify)(runner, { ...args.options, runId: required(runId, "run id") });
720
- printJson(result);
721
- // Fail-closed: any unverified chain exits non-zero so `cw audit verify
722
- // <run> && deploy` stops — mirrors the telemetry-verify guard. verifyTrustAudit
723
- // returns verified:true for a truly absent/empty chain (nothing to prove),
724
- // so this stays exit 0 there; a FULLY-corrupt log reports present:false but
725
- // verified:false (corruptLines>0) and must NOT be conflated with absent — the
726
- // earlier `present && ...` guard let that severe tamper escape (exit 0).
727
- if (!result.verified)
728
- process.exitCode = 1;
729
- return;
730
- }
731
- case "worker":
732
- printJson(runner.workerAudit(required(runId, "run id"), required(id, "worker id")));
733
- return;
734
- case "provenance":
735
- printJson(runner.evidenceProvenance(required(runId, "run id"), args.options));
736
- return;
737
- case "multi-agent": {
738
- const view = runner.auditMultiAgent(required(runId, "run id"));
739
- if (wantsJson(args.options))
740
- printJson(view);
741
- else
742
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
743
- return;
744
- }
745
- case "policy": {
746
- const view = runner.auditPolicy(required(runId, "run id"));
747
- if (wantsJson(args.options))
748
- printJson(view);
749
- else
750
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
751
- return;
752
- }
753
- case "role": {
754
- const view = runner.auditRole(required(runId, "run id"), required(id, "role id"));
755
- if (wantsJson(args.options))
756
- printJson(view);
757
- else
758
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
759
- return;
760
- }
761
- case "blackboard": {
762
- const view = runner.auditBlackboard(required(runId, "run id"));
763
- if (wantsJson(args.options))
764
- printJson(view);
765
- else
766
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
767
- return;
768
- }
769
- case "judge": {
770
- const view = runner.auditJudge(required(runId, "run id"));
771
- if (wantsJson(args.options))
772
- printJson(view);
773
- else
774
- process.stdout.write(`${(0, operator_ux_1.formatMultiAgentTrustAudit)(view)}\n`);
775
- return;
776
- }
777
- case "attest":
778
- printJson(runner.recordAuditAttestation(required(runId, "run id"), args.options));
779
- return;
780
- case "decision":
781
- printJson(runner.recordAuditDecision(required(runId, "run id"), required(id, "worker id"), args.options));
782
- return;
783
- default:
784
- throw new Error("Usage: cw.js audit summary|worker|provenance|multi-agent|policy|role|blackboard|judge|attest|decision <run-id> [worker-id|role-id]");
785
- }
786
- }
787
- case "candidate": {
788
- const [subcommand, runId, candidateId, reason] = args.positionals;
789
- switch (subcommand) {
790
- case "list":
791
- printJson(runner.listCandidates(required(runId, "run id"), args.options));
792
- return;
793
- case "show":
794
- printJson(runner.showCandidate(required(runId, "run id"), required(candidateId, "candidate id")));
795
- return;
796
- case "register":
797
- printJson(runner.registerCandidate(required(runId, "run id"), args.options));
798
- return;
799
- case "score":
800
- printJson(runner.scoreCandidate(required(runId, "run id"), required(candidateId, "candidate id"), args.options));
801
- return;
802
- case "rank":
803
- printJson(runner.rankCandidates(required(runId, "run id"), args.options));
804
- return;
805
- case "select":
806
- printJson(runner.selectCandidate(required(runId, "run id"), required(candidateId, "candidate id"), args.options));
807
- return;
808
- case "reject":
809
- printJson(runner.rejectCandidate(required(runId, "run id"), required(candidateId, "candidate id"), String(args.options.reason || args.options.message || reason || "rejected")));
810
- return;
811
- case "summary":
812
- if (wantsJson(args.options))
813
- printJson(runner.summarizeCandidateOperatorRecords(required(runId, "run id")));
814
- else
815
- process.stdout.write(`${(0, operator_ux_1.formatCandidateSummary)(runner.summarizeCandidateOperatorRecords(required(runId, "run id")))}\n`);
816
- return;
817
- default:
818
- throw new Error("Usage: cw.js candidate list|show|register|score|rank|select|reject|summary <run-id> [candidate-id]");
819
- }
820
- }
821
- // ---- Team Collaboration (v0.1.32) ------------------------------------
822
- case "approve": {
823
- const [targetKind, runId, targetId] = args.positionals;
824
- printJson(runner.collaborationApprove(required(runId, "run id"), required(targetKind, "target kind (candidate|commit|selection|run|task|node)"), required(targetId, "target id"), args.options));
825
- return;
826
- }
827
- case "reject": {
828
- const [targetKind, runId, targetId] = args.positionals;
829
- printJson(runner.collaborationReject(required(runId, "run id"), required(targetKind, "target kind (candidate|commit|selection|run|task|node)"), required(targetId, "target id"), args.options));
830
- return;
831
- }
832
- case "comment": {
833
- const [subcommand, ...rest] = args.positionals;
834
- if (subcommand === "add") {
835
- const [targetKind, runId, targetId] = rest;
836
- printJson(runner.collaborationComment(required(runId, "run id"), required(targetKind, "target kind"), required(targetId, "target id"), args.options));
837
- return;
838
- }
839
- if (subcommand === "list") {
840
- const result = runner.collaborationCommentList(required(rest[0], "run id"), args.options);
841
- if (wantsJson(args.options))
842
- printJson(result);
843
- else
844
- process.stdout.write(`${runner.formatCommentList(result.comments)}\n`);
845
- return;
846
- }
847
- throw new Error("Usage: cw.js comment add <kind> <run-id> <target-id> --body <text> | comment list <run-id> [--json]");
848
- }
849
- case "handoff": {
850
- const [targetKind, runId, targetIdRaw] = args.positionals;
851
- const kind = required(targetKind, "target kind (run|task|candidate|commit|node)");
852
- const rid = required(runId, "run id");
853
- const targetId = targetIdRaw || (kind === "run" ? rid : undefined);
854
- printJson(runner.collaborationHandoff(rid, kind, required(targetId, "target id"), args.options));
855
- return;
856
- }
857
- case "review": {
858
- const [subcommand, runId] = args.positionals;
859
- if (subcommand === "status") {
860
- const report = runner.reviewStatus(required(runId, "run id"), args.options);
861
- if (wantsJson(args.options))
862
- printJson(report);
863
- else
864
- process.stdout.write(`${runner.formatReviewStatus(report)}\n`);
865
- return;
866
- }
867
- if (subcommand === "policy") {
868
- printJson(runner.reviewPolicy(required(runId, "run id"), args.options));
869
- return;
870
- }
871
- 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");
872
- }
873
- case "loop": {
874
- printJson(scheduler.create({ ...args.options, kind: "loop" }));
875
- return;
876
- }
877
- case "schedule": {
878
- const [subcommand, id] = args.positionals;
879
- switch (subcommand) {
880
- case "create":
881
- printJson(scheduler.create(args.options));
882
- return;
883
- case "list":
884
- printJson(scheduler.list(args.options.status ? String(args.options.status) : undefined));
885
- return;
886
- case "delete":
887
- printJson(scheduler.delete(required(id, "schedule id")));
888
- return;
889
- case "due":
890
- printJson(scheduler.due());
891
- return;
892
- case "complete":
893
- printJson(scheduler.complete(required(id, "schedule id"), args.options));
894
- return;
895
- case "pause":
896
- printJson(scheduler.pause(required(id, "schedule id")));
897
- return;
898
- case "resume":
899
- printJson(scheduler.resume(required(id, "schedule id")));
900
- return;
901
- case "run-now":
902
- printJson(scheduler.runNow(required(id, "schedule id")));
903
- return;
904
- case "history":
905
- printJson(scheduler.history(id));
906
- return;
907
- case "daemon": {
908
- const daemon = new daemon_1.DesktopSchedulerDaemon({
909
- cwd: String(args.options.cwd || process.cwd()),
910
- intervalSeconds: Number(args.options.intervalSeconds || args.options.interval || 60)
911
- });
912
- if (args.options.once) {
913
- printJson(daemon.tick());
914
- return;
915
- }
916
- await daemon.run();
917
- return;
918
- }
919
- default:
920
- throw new Error("Usage: cw.js schedule create|list|delete|due|complete|pause|resume|run-now|history|daemon");
921
- }
922
- }
923
- case "routine": {
924
- const [subcommand, idOrKind, payloadPath] = args.positionals;
925
- switch (subcommand) {
926
- case "create":
927
- printJson(triggers.create(args.options));
928
- return;
929
- case "list":
930
- printJson(triggers.list(args.options.kind ? String(args.options.kind) : undefined));
931
- return;
932
- case "delete":
933
- printJson(triggers.delete(required(idOrKind, "trigger id")));
934
- return;
935
- case "fire": {
936
- const kind = required(idOrKind, "trigger kind");
937
- const payload = payloadPath ? JSON.parse(node_fs_1.default.readFileSync(payloadPath, "utf8")) : args.options;
938
- printJson(triggers.fire(kind, payload));
939
- return;
940
- }
941
- case "events":
942
- printJson(triggers.events(idOrKind));
943
- return;
944
- default:
945
- throw new Error("Usage: cw.js routine create|list|delete|fire|events");
946
- }
947
- }
948
- case "registry": {
949
- const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
950
- const [subcommand] = args.positionals;
951
- switch (subcommand) {
952
- case "refresh": {
953
- const report = (0, capability_core_1.runRegistryRefresh)(registry, args.options);
954
- if (wantsJson(args.options))
955
- printJson(report);
956
- else
957
- process.stdout.write(`${(0, run_registry_1.formatRegistryReport)(report)}\n`);
958
- return;
959
- }
960
- case "show": {
961
- const report = (0, capability_core_1.runRegistryShow)(registry, args.options);
962
- if (wantsJson(args.options))
963
- printJson(report);
964
- else
965
- process.stdout.write(`${(0, run_registry_1.formatRegistryReport)(report)}\n`);
966
- return;
967
- }
968
- default:
969
- throw new Error("Usage: cw.js registry refresh|show [--scope repo|home] [--json]");
970
- }
971
- }
972
- case "metrics": {
973
- const [subcommand, runId] = args.positionals;
974
- switch (subcommand) {
975
- case "show": {
976
- const report = runner.metricsShow(required(runId, "run id"), args.options);
977
- if (wantsJson(args.options))
978
- printJson(report);
979
- else
980
- process.stdout.write(`${(0, observability_1.formatMetricsReport)(report)}\n`);
981
- return;
982
- }
983
- case "summary": {
984
- const report = (0, capability_core_1.metricsSummary)((0, capability_core_1.runRegistryFor)(args.options, runner), runner, args.options);
985
- if (wantsJson(args.options))
986
- printJson(report);
987
- else
988
- process.stdout.write(`${(0, observability_1.formatMetricsSummary)(report)}\n`);
989
- return;
990
- }
991
- default:
992
- throw new Error("Usage: cw.js metrics show <run-id> | metrics summary [--scope repo|home] [--pricing <path>|default] [--json]");
993
- }
994
- }
995
- case "run": {
996
- // Agent Delegation Drive (v0.1.38): `cw run <app> --drive [--once]` drives a
997
- // run end-to-end by delegating each worker to the agent backend. Distinct from
998
- // the run-REGISTRY verbs below. `--preview` (or the `run drive <run-id>` form)
999
- // is the read-only, deterministic next-step preview.
1000
- //
1001
- // A run-REGISTRY subcommand keyword (resume/show/...) must NOT be intercepted
1002
- // here just because it carries a --drive flag of its own — e.g.
1003
- // `run resume <id> --drive` is the resume verb's opt-in continuation, not
1004
- // `run <app=resume> --drive`. Fall through to the switch for those keywords.
1005
- const runRegistrySubcommand = new Set([
1006
- "drive", "search", "list", "show", "resume", "archive", "rerun", "export", "import", "verify-import", "inspect-archive"
1007
- ]);
1008
- if (args.options.drive && !runRegistrySubcommand.has(String(args.positionals[0] || ""))) {
1009
- const target = args.positionals[0];
1010
- const runId = optionalArg(args.options.run) || optionalArg(args.options.runId);
1011
- if (args.options.preview) {
1012
- printJson((0, capability_core_1.runDrivePreview)(runner, { ...args.options, runId: runId || target }));
1013
- return;
1014
- }
1015
- const driveArgs = { ...args.options };
1016
- if (runId)
1017
- driveArgs.runId = runId;
1018
- else
1019
- driveArgs.appId = target;
1020
- printJson((0, capability_core_1.runDrive)(runner, driveArgs));
1021
- return;
1022
- }
1023
- const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
1024
- const [subcommand, id] = args.positionals;
1025
- switch (subcommand) {
1026
- case "drive": {
1027
- // `run drive <run-id>` = read-only preview; `--step [--once]` = mutating drive.
1028
- if (args.options.step) {
1029
- const driveArgs = { ...args.options };
1030
- if (id)
1031
- driveArgs.runId = id;
1032
- printJson((0, capability_core_1.runDrive)(runner, driveArgs));
1033
- return;
1034
- }
1035
- printJson((0, capability_core_1.runDrivePreview)(runner, { ...args.options, runId: required(id, "run id") }));
1036
- return;
1037
- }
1038
- case "search": {
1039
- const result = (0, capability_core_1.runSearch)(registry, args.options);
1040
- if (wantsJson(args.options))
1041
- printJson(result);
1042
- else
1043
- process.stdout.write(`${(0, run_registry_1.formatRunSearch)(result)}\n`);
1044
- return;
1045
- }
1046
- case "list": {
1047
- const result = (0, capability_core_1.runList)(registry, args.options);
1048
- if (wantsJson(args.options))
1049
- printJson(result);
1050
- else
1051
- process.stdout.write(`${(0, run_registry_1.formatRunSearch)(result)}\n`);
1052
- return;
1053
- }
1054
- case "show": {
1055
- const result = (0, capability_core_1.runShow)(registry, required(id, "run id"), args.options);
1056
- if (wantsJson(args.options))
1057
- printJson(result);
1058
- else
1059
- process.stdout.write(`${(0, run_registry_1.formatRunShow)(result)}\n`);
1060
- return;
1061
- }
1062
- case "resume": {
1063
- const result = (0, capability_core_1.runResume)(registry, runner, required(id, "run id"), args.options);
1064
- if (wantsJson(args.options))
1065
- printJson(result);
1066
- else
1067
- process.stdout.write(`${(0, run_registry_1.formatResume)(result)}\n`);
1068
- return;
1069
- }
1070
- case "archive":
1071
- printJson((0, capability_core_1.runArchive)(registry, id, args.options));
1072
- return;
1073
- case "rerun":
1074
- printJson((0, capability_core_1.runRerun)(registry, required(id, "run id"), args.options));
1075
- return;
1076
- case "export":
1077
- printJson((0, capability_core_1.runExportArchive)(runner, required(id || optionalArg(args.options.runId || args.options.run), "run id"), args.options));
1078
- return;
1079
- case "import":
1080
- printJson((0, capability_core_1.runImportArchive)(runner, { ...args.options, archive: id || args.options.archive || args.options.path }));
1081
- return;
1082
- case "verify-import": {
1083
- const result = (0, capability_core_1.runVerifyImport)(runner, required(id || optionalArg(args.options.runId || args.options.run), "run id"), args.options);
1084
- printJson(result);
1085
- // Fail-closed ONLY behind --strict, so the default exit stays 0
1086
- // (byte-identical). With --strict, any failed restore check — including
1087
- // the new trust-audit row — exits 1 for `verify-import && restore`.
1088
- if (Boolean(args.options.strict) && !result.ok)
1089
- process.exitCode = 1;
1090
- return;
1091
- }
1092
- case "inspect-archive": {
1093
- const result = (0, capability_core_1.runInspectArchive)(runner, { ...args.options, archive: id || args.options.archive || args.options.path });
1094
- printJson(result);
1095
- // Read-only diagnostic: exit 1 when the archive fails any integrity check,
1096
- // so `cw run inspect-archive <path> && restore` stops on a bad archive.
1097
- if (!result.ok)
1098
- process.exitCode = 1;
1099
- return;
1100
- }
1101
- default:
1102
- 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] [--repo R --question Q]");
1103
- }
1104
- }
1105
- case "queue": {
1106
- const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
1107
- const [subcommand, id] = args.positionals;
1108
- switch (subcommand) {
1109
- case "add":
1110
- printJson((0, capability_core_1.queueAdd)(registry, args.options));
1111
- return;
1112
- case "list": {
1113
- const result = (0, capability_core_1.queueList)(registry, args.options);
1114
- if (wantsJson(args.options))
1115
- printJson(result);
1116
- else
1117
- process.stdout.write(`${(0, run_registry_1.formatQueueList)(result)}\n`);
1118
- return;
1119
- }
1120
- case "drain":
1121
- printJson((0, capability_core_1.queueDrain)(registry, args.options));
1122
- return;
1123
- case "show":
1124
- printJson((0, capability_core_1.queueShow)(registry, required(id, "queue id")));
1125
- return;
1126
- default:
1127
- throw new Error("Usage: cw.js queue add|list|drain|show [queue-id] [--repo PATH] [--priority N]");
1128
- }
1129
- }
1130
- case "sched": {
1131
- const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
1132
- const [subcommand, idArg] = args.positionals;
1133
- switch (subcommand) {
1134
- case "plan":
1135
- printJson((0, capability_core_1.schedPlan)(registry, args.options));
1136
- return;
1137
- case "lease":
1138
- printJson((0, capability_core_1.schedLease)(registry, args.options));
1139
- return;
1140
- case "release":
1141
- printJson((0, capability_core_1.schedRelease)(registry, { ...args.options, leaseId: args.options.leaseId || idArg }));
1142
- return;
1143
- case "complete":
1144
- printJson((0, capability_core_1.schedComplete)(registry, { ...args.options, leaseId: args.options.leaseId || idArg }));
1145
- return;
1146
- case "reclaim":
1147
- printJson((0, capability_core_1.schedReclaim)(registry, args.options));
1148
- return;
1149
- case "reset":
1150
- printJson((0, capability_core_1.schedReset)(registry, { ...args.options, id: args.options.id || idArg }));
1151
- return;
1152
- case "policy": {
1153
- const [, action] = args.positionals;
1154
- if (action === "set") {
1155
- printJson((0, capability_core_1.schedPolicySet)(registry, args.options));
1156
- return;
1157
- }
1158
- printJson((0, capability_core_1.schedPolicyShow)(registry));
1159
- return;
1160
- }
1161
- default:
1162
- throw new Error("Usage: cw.js sched plan|lease|release|complete|reclaim|reset|policy [show|set] [id] [--maxConcurrent N --maxAttempts N ...]");
1163
- }
1164
- }
1165
- case "gc": {
1166
- // Run Retention & Provable Reclamation (v0.1.39). `plan` is a pure dry-run
1167
- // (frees nothing); `run` executes the write-ahead reclamation transaction;
1168
- // `verify` re-proves a reclaimed run. CW never reclaims by default.
1169
- const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
1170
- const [subcommand, id] = args.positionals;
1171
- switch (subcommand) {
1172
- case "plan": {
1173
- const result = (0, capability_core_1.gcPlan)(registry, id, args.options);
1174
- if (wantsJson(args.options))
1175
- printJson(result);
1176
- else
1177
- process.stdout.write(`${(0, run_registry_1.formatGcPlan)(result)}\n`);
1178
- return;
1179
- }
1180
- case "run": {
1181
- const result = (0, capability_core_1.gcRun)(registry, id, args.options);
1182
- if (wantsJson(args.options))
1183
- printJson(result);
1184
- else
1185
- process.stdout.write(`${(0, run_registry_1.formatGcRun)(result)}\n`);
1186
- return;
1187
- }
1188
- case "verify": {
1189
- const result = (0, capability_core_1.gcVerify)(registry, required(id, "run id"), args.options);
1190
- if (wantsJson(args.options))
1191
- printJson(result);
1192
- else
1193
- process.stdout.write(`${(0, run_registry_1.formatGcVerify)(result)}\n`);
1194
- // Fail closed ONLY on a real integrity failure: a run that WAS reclaimed
1195
- // but no longer re-proves. A not-reclaimed run has nothing to verify
1196
- // (reclaimed:false/verified:false) and must not be treated as a failure.
1197
- // LIMIT (honest): a DELETED reclaimed.json reads as reclaimed:false, so
1198
- // proof-deletion is indistinguishable from never-reclaimed here without
1199
- // an independent witness (e.g. a trust-audit reclamation event) — a
1200
- // follow-up. This guard is still strictly better than the prior exit-0.
1201
- if (result.reclaimed && !result.verified)
1202
- process.exitCode = 1;
1203
- return;
1204
- }
1205
- default:
1206
- throw new Error("Usage: cw.js gc plan|run|verify [run-id] [--reclaimAfterArchiveDays N] [--keep-scratch] [--keep-snapshots] [--limit N] [--json]");
1207
- }
1208
- }
1209
- case "history": {
1210
- const registry = (0, capability_core_1.runRegistryFor)(args.options, runner);
1211
- const result = (0, capability_core_1.runHistory)(registry, args.options);
1212
- if (wantsJson(args.options))
1213
- printJson(result);
1214
- else
1215
- process.stdout.write(`${(0, run_registry_1.formatHistory)(result)}\n`);
1216
- return;
1217
- }
1218
- case "telemetry": {
1219
- const [subcommand, id] = args.positionals;
1220
- switch (subcommand) {
1221
- case "verify": {
1222
- const result = (0, capability_core_1.telemetryVerify)(runner, { ...args.options, runId: id || args.options.runId || args.options.run });
1223
- if (wantsJson(args.options))
1224
- printJson(result);
1225
- else
1226
- process.stdout.write(`${(0, telemetry_demo_1.formatTelemetryVerify)(result)}\n`);
1227
- // Fail closed: a forged/edited/corrupt ledger verifies false — report it
1228
- // through the exit code so `cw telemetry verify <run> && deploy` cannot
1229
- // pass on a lie. (Absent ledger = present:false/verified:true -> exit 0.)
1230
- if (!result.verified)
1231
- process.exitCode = 1;
1232
- return;
1233
- }
1234
- default:
1235
- throw new Error("Usage: cw.js telemetry verify <run-id> [--pubkey <pem-or-path>] [--json]");
1236
- }
1237
- }
1238
- case "demo": {
1239
- const [subcommand] = args.positionals;
1240
- switch (subcommand) {
1241
- case "tamper": {
1242
- const result = (0, capability_core_1.demoTamper)(runner, args.options);
1243
- if (wantsJson(args.options))
1244
- printJson(result);
1245
- else
1246
- process.stdout.write(`${(0, telemetry_demo_1.formatTamperDemo)(result)}\n`);
1247
- // Fail closed: if the proof did not hold (a tamper went undetected),
1248
- // exit nonzero so the demo can never green a broken guarantee.
1249
- if (!result.proven)
1250
- process.exitCode = 1;
1251
- return;
1252
- }
1253
- default:
1254
- throw new Error("Usage: cw.js demo tamper [--json]");
1255
- }
1256
- }
1257
- case "workbench": {
1258
- const [subcommand, runId] = args.positionals;
1259
- switch (subcommand) {
1260
- case "view": {
1261
- // Read-only five-panel view of one run. Same core entry as cw_workbench_view.
1262
- const view = (0, workbench_1.buildWorkbenchRunView)(runner, required(runId, "run id"));
1263
- if (wantsJson(args.options))
1264
- printJson(view);
1265
- else
1266
- process.stdout.write(`${formatWorkbenchView(view)}\n`);
1267
- return;
1268
- }
1269
- case "serve": {
1270
- // The OPTIONAL localhost host. `--once`/`--json` emit the descriptor only
1271
- // (no server); the default starts the read-only, localhost-only host.
1272
- if (args.options.once || wantsJson(args.options)) {
1273
- printJson((0, workbench_1.buildWorkbenchServeDescriptor)(runner, { ...args.options, once: true }));
1274
- return;
1275
- }
1276
- const host = new workbench_host_1.WorkbenchHost({
1277
- runner,
1278
- cwd: String(args.options.cwd || process.cwd()),
1279
- port: Number(args.options.port) || undefined,
1280
- scope: args.options.scope === "repo" ? "repo" : "home"
1281
- });
1282
- await host.run();
1283
- return;
1284
- }
1285
- default:
1286
- throw new Error("Usage: cw.js workbench serve [--port N] [--once] | view <run-id> [--json]");
1287
- }
1288
- }
1289
- default:
1290
- throw new Error(`Unknown command: ${args.command}`);
1291
- }
1292
- }
1293
- function required(value, label) {
1294
- if (!value)
1295
- throw new Error(`Missing ${label}. Run "cw.js help" for usage.`);
1296
- return value;
1297
- }
1298
- function optionalArg(value) {
1299
- return typeof value === "string" && value.trim() ? value.trim() : undefined;
1300
- }
1301
- function printJson(value) {
1302
- process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
1303
- }
1304
- function wantsJson(options) {
1305
- return Boolean(options.json || options.format === "json");
1306
- }
1307
- function formatWorkbenchView(view) {
1308
- const lines = [
1309
- `Workbench view ${view.runId} (${view.resolved ? "resolved" : "UNRESOLVED"})`,
1310
- view.error ? ` error: ${view.error}` : ""
1311
- ].filter(Boolean);
1312
- for (const [group, panels] of Object.entries(view.panels)) {
1313
- lines.push(` ${group}:`);
1314
- for (const [name, panel] of Object.entries(panels)) {
1315
- const note = panel.status === "present" ? panel.capability : `absent (${panel.error || "unreadable"})`;
1316
- lines.push(` ${name}: ${panel.status} — ${note}`);
1317
- }
1318
- }
1319
- return lines.join("\n");
1320
- }
1321
- main().catch((error) => {
4
+ const command_surface_1 = require("./cli/command-surface");
5
+ (0, command_surface_1.runCli)(process.argv.slice(2)).catch((error) => {
1322
6
  const message = error instanceof Error ? error.message : String(error);
1323
7
  process.stderr.write(`cw: ${message}\n`);
1324
8
  process.exitCode = 1;