cool-workflow 0.1.78

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