cool-workflow 0.2.2 → 0.2.4

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 (141) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/apps/architecture-review/app.json +1 -1
  4. package/apps/architecture-review-fast/app.json +1 -1
  5. package/apps/end-to-end-golden-path/app.json +1 -1
  6. package/apps/pr-review-fix-ci/app.json +1 -1
  7. package/apps/release-cut/app.json +1 -1
  8. package/apps/research-synthesis/app.json +1 -1
  9. package/dist/cli/dispatch.js +13 -6
  10. package/dist/cli/entry.js +41 -1
  11. package/dist/cli/io.js +12 -22
  12. package/dist/cli/parseargv.js +1 -0
  13. package/dist/core/capability-data.js +3 -2
  14. package/dist/core/format/completion.js +68 -0
  15. package/dist/core/format/help.js +31 -6
  16. package/dist/core/format/safe-json.js +73 -0
  17. package/dist/core/format/state-explosion-text.js +1 -1
  18. package/dist/core/multi-agent/candidate-scoring.js +5 -1
  19. package/dist/core/multi-agent/collaboration.js +3 -3
  20. package/dist/core/multi-agent/coordinator.js +5 -5
  21. package/dist/core/multi-agent/runtime.js +4 -4
  22. package/dist/core/multi-agent/topology.js +3 -3
  23. package/dist/core/pipeline/dispatch.js +18 -4
  24. package/dist/core/pipeline/drive-decide.js +2 -1
  25. package/dist/core/state/migrations.js +16 -1
  26. package/dist/core/state/state-explosion/digest.js +13 -13
  27. package/dist/core/state/state-explosion/graph.js +17 -11
  28. package/dist/core/state/state-explosion/report.js +6 -6
  29. package/dist/core/util/cli-args.js +33 -0
  30. package/dist/core/util/numeric-flag.js +40 -0
  31. package/dist/core/version.js +1 -1
  32. package/dist/mcp/server.js +99 -11
  33. package/dist/shell/audit-cli.js +57 -25
  34. package/dist/shell/coordinator-io.js +73 -13
  35. package/dist/shell/dispatch.js +1 -1
  36. package/dist/shell/doctor.js +80 -1
  37. package/dist/shell/drive.js +251 -49
  38. package/dist/shell/eval-text.js +2 -2
  39. package/dist/shell/evidence-reasoning.js +4 -4
  40. package/dist/shell/execution-backend/agent.js +30 -2
  41. package/dist/shell/execution-backend/container.js +4 -1
  42. package/dist/shell/execution-backend/local.js +19 -11
  43. package/dist/shell/feedback-cli.js +6 -6
  44. package/dist/shell/fs-atomic.js +218 -29
  45. package/dist/shell/man-cli.js +6 -0
  46. package/dist/shell/metrics-cli.js +2 -1
  47. package/dist/shell/multi-agent-cli.js +367 -323
  48. package/dist/shell/multi-agent-host.js +9 -9
  49. package/dist/shell/multi-agent-operator-ux.js +80 -38
  50. package/dist/shell/node-store.js +10 -4
  51. package/dist/shell/observability.js +1 -1
  52. package/dist/shell/operator-ux-text.js +22 -22
  53. package/dist/shell/operator-ux.js +15 -14
  54. package/dist/shell/orchestrator.js +49 -38
  55. package/dist/shell/pipeline-cli.js +107 -42
  56. package/dist/shell/reclamation-io.js +88 -10
  57. package/dist/shell/registry-cli.js +23 -17
  58. package/dist/shell/remote-source.js +13 -8
  59. package/dist/shell/report-cli.js +45 -0
  60. package/dist/shell/report.js +2 -1
  61. package/dist/shell/run-registry-io.js +78 -19
  62. package/dist/shell/run-store.js +74 -2
  63. package/dist/shell/scheduling-io.js +12 -13
  64. package/dist/shell/state-cli.js +2 -7
  65. package/dist/shell/state-explosion-cli.js +17 -9
  66. package/dist/shell/topology-io.js +36 -5
  67. package/dist/shell/trust-audit.js +224 -22
  68. package/dist/shell/trust-policy-io.js +1 -1
  69. package/dist/shell/worker-cli.js +35 -31
  70. package/dist/shell/workflow-app-loader.js +67 -1
  71. package/dist/wiring/capability-table/basics.js +33 -8
  72. package/dist/wiring/capability-table/exec-backend.js +28 -19
  73. package/dist/wiring/capability-table/multi-agent.js +187 -180
  74. package/dist/wiring/capability-table/parity.js +1 -0
  75. package/dist/wiring/capability-table/pipeline.js +64 -52
  76. package/dist/wiring/capability-table/registry-core.js +30 -11
  77. package/dist/wiring/capability-table/reporting.js +147 -106
  78. package/dist/wiring/capability-table/scheduling-registry.js +201 -167
  79. package/dist/wiring/capability-table/state.js +59 -51
  80. package/dist/wiring/capability-table/trust-ledger.js +52 -28
  81. package/dist/wiring/capability-table/workflow-apps.js +85 -70
  82. package/docs/agent-delegation-drive.7.md +4 -0
  83. package/docs/candidate-scoring.7.md +1 -1
  84. package/docs/canonical-workflow-apps.7.md +7 -7
  85. package/docs/cli-mcp-parity.7.md +26 -16
  86. package/docs/contract-migration-tooling.7.md +4 -0
  87. package/docs/control-plane-scheduling.7.md +4 -0
  88. package/docs/coordinator-blackboard.7.md +17 -17
  89. package/docs/dogfood-one-real-repo.7.md +11 -11
  90. package/docs/durable-state-and-locking.7.md +4 -0
  91. package/docs/end-to-end-golden-path.7.md +14 -14
  92. package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
  93. package/docs/execution-backends.7.md +4 -0
  94. package/docs/getting-started.md +37 -37
  95. package/docs/multi-agent-cli-mcp-surface.7.md +21 -17
  96. package/docs/multi-agent-eval-replay-harness.7.md +17 -13
  97. package/docs/multi-agent-operator-ux.7.md +23 -19
  98. package/docs/multi-agent-runtime-core.7.md +22 -22
  99. package/docs/multi-agent-topologies.7.md +6 -6
  100. package/docs/multi-agent-trust-policy-audit.7.md +11 -11
  101. package/docs/node-snapshot-diff-replay.7.md +4 -0
  102. package/docs/observability-cost-accounting.7.md +4 -0
  103. package/docs/operator-ux.7.md +34 -34
  104. package/docs/pipeline-runner.7.md +4 -4
  105. package/docs/project-index.md +31 -4
  106. package/docs/real-execution-backends.7.md +4 -0
  107. package/docs/release-and-migration.7.md +5 -1
  108. package/docs/release-tooling.7.md +22 -0
  109. package/docs/routines.md +4 -4
  110. package/docs/run-registry-control-plane.7.md +23 -19
  111. package/docs/run-retention-reclamation.7.md +24 -3
  112. package/docs/scheduled-tasks.md +14 -14
  113. package/docs/security-trust-hardening.7.md +15 -15
  114. package/docs/state-explosion-management.7.md +14 -10
  115. package/docs/team-collaboration.7.md +4 -0
  116. package/docs/trust-audit-anchor.7.md +4 -0
  117. package/docs/unix-principles.md +3 -1
  118. package/docs/verifier-gated-commit.7.md +1 -1
  119. package/docs/web-desktop-workbench.7.md +4 -0
  120. package/docs/workflow-app-framework.7.md +13 -13
  121. package/manifest/plugin.manifest.json +1 -1
  122. package/package.json +3 -2
  123. package/scripts/agents/claude-p-agent.js +2 -2
  124. package/scripts/block-unapproved-tag.sh +42 -6
  125. package/scripts/bump-version.js +27 -10
  126. package/scripts/canonical-apps.js +4 -4
  127. package/scripts/children/batch-delegate-child.js +52 -2
  128. package/scripts/dogfood-release.js +1 -1
  129. package/scripts/fake-date-for-reproduction.js +44 -0
  130. package/scripts/golden-path.js +4 -4
  131. package/scripts/purity-baseline.json +0 -27
  132. package/scripts/release-flow.js +194 -13
  133. package/scripts/release-oneclick.js +407 -0
  134. package/scripts/verdict-keygen.js +83 -0
  135. package/scripts/verify-bump-reproduction.sh +148 -0
  136. package/scripts/verify-verdict-signature.js +61 -0
  137. package/scripts/version-sync-check.js +39 -22
  138. package/skills/cool-workflow/SKILL.md +9 -9
  139. package/skills/cool-workflow/references/commands.md +89 -88
  140. package/ui/workbench/app.css +37 -1
  141. package/ui/workbench/app.js +124 -6
@@ -6,9 +6,17 @@
6
6
  // sed, not retyped).
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  const registry_core_1 = require("./registry-core");
9
- const io_1 = require("../../cli/io");
10
- const state_cli_1 = require("../../shell/state-cli");
11
- const app_run_cli_1 = require("../../shell/app-run-cli");
9
+ const cli_args_1 = require("../../core/util/cli-args");
10
+ // This whole module is required unconditionally at startup for EVERY
11
+ // command (see wiring/capability-table/index.ts) — loading `next`'s and
12
+ // `app.run`'s shell modules lazily, inside the handler that actually
13
+ // calls them, keeps other commands from paying their load cost.
14
+ function loadStateCli() {
15
+ return require("../../shell/state-cli");
16
+ }
17
+ function loadAppRunCli() {
18
+ return require("../../shell/app-run-cli");
19
+ }
12
20
  // MILESTONE 12 (workflow-apps). Handler BODIES live in
13
21
  // shell/workflow-app-loader.ts (impure — they scan apps/*/app.json +
14
22
  // workflows/*.workflow.js on disk and `require()` each entrypoint); this
@@ -17,36 +25,43 @@ const app_run_cli_1 = require("../../shell/app-run-cli");
17
25
  // (jsonMode "default") even without --json, and its handler sets
18
26
  // exitCode 1 on `valid:false` — both the "not found" id case and a
19
27
  // structurally-broken manifest case fail this same way.
20
- const workflow_app_loader_1 = require("../../shell/workflow-app-loader");
28
+ // Loaded lazily so the app.* handlers below pay this module's load cost
29
+ // only when actually invoked, not on every CLI/MCP startup.
30
+ function loadWorkflowAppLoader() {
31
+ return require("../../shell/workflow-app-loader");
32
+ }
21
33
  const help_1 = require("../../core/format/help");
22
- const man_cli_1 = require("../../shell/man-cli");
34
+ // Loaded lazily so only the `man` handler below pays its load cost.
35
+ function loadManCli() {
36
+ return require("../../shell/man-cli");
37
+ }
23
38
  (0, registry_core_1.attachCliBinding)("app.list", {
24
39
  path: ["app", "list"],
25
40
  jsonMode: "default",
26
- handler: () => ({ json: (0, workflow_app_loader_1.listWorkflowApps)() }),
41
+ handler: () => ({ json: loadWorkflowAppLoader().listWorkflowApps() }),
27
42
  });
28
- registry_core_1.REGISTRY_BY_CAPABILITY.get("app.list").mcp.handler = () => (0, workflow_app_loader_1.listWorkflowApps)();
43
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.list").mcp.handler = () => loadWorkflowAppLoader().listWorkflowApps();
29
44
  (0, registry_core_1.attachCliBinding)("app.show", {
30
45
  path: ["app", "show"],
31
46
  jsonMode: "default",
32
- handler: (args) => ({ json: (0, workflow_app_loader_1.showWorkflowApp)((0, io_1.required)(args.positionals[0], "workflow app id")) }),
47
+ handler: (args) => ({ json: loadWorkflowAppLoader().showWorkflowApp((0, cli_args_1.required)(args.positionals[0], "workflow app id")) }),
33
48
  });
34
- registry_core_1.REGISTRY_BY_CAPABILITY.get("app.show").mcp.handler = (args) => (0, workflow_app_loader_1.showWorkflowApp)((0, io_1.required)((0, io_1.optionalArg)(args.appId), "workflow app id"));
49
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.show").mcp.handler = (args) => loadWorkflowAppLoader().showWorkflowApp((0, cli_args_1.required)((0, cli_args_1.optionalArg)(args.appId), "workflow app id"));
35
50
  (0, registry_core_1.attachCliBinding)("app.validate", {
36
51
  path: ["app", "validate"],
37
52
  jsonMode: "default",
38
53
  handler: (args) => {
39
- const result = (0, workflow_app_loader_1.validateWorkflowAppTarget)((0, io_1.required)(args.positionals[0], "workflow app path or id"));
54
+ const result = loadWorkflowAppLoader().validateWorkflowAppTarget((0, cli_args_1.required)(args.positionals[0], "workflow app path or id"));
40
55
  return { json: result, exitCode: result.valid ? undefined : 1 };
41
56
  },
42
57
  });
43
- registry_core_1.REGISTRY_BY_CAPABILITY.get("app.validate").mcp.handler = (args) => (0, workflow_app_loader_1.validateWorkflowAppTarget)((0, io_1.required)((0, io_1.optionalArg)(args.target ?? args.appId), "workflow app path or id"));
58
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.validate").mcp.handler = (args) => loadWorkflowAppLoader().validateWorkflowAppTarget((0, cli_args_1.required)((0, cli_args_1.optionalArg)(args.target ?? args.appId), "workflow app path or id"));
44
59
  (0, registry_core_1.attachCliBinding)("app.init", {
45
60
  path: ["app", "init"],
46
61
  jsonMode: "default",
47
- handler: (args) => ({ json: (0, workflow_app_loader_1.initWorkflowApp)((0, io_1.required)(args.positionals[0], "app id"), args.options) }),
62
+ handler: (args) => ({ json: loadWorkflowAppLoader().initWorkflowApp((0, cli_args_1.required)(args.positionals[0], "app id"), args.options) }),
48
63
  });
49
- registry_core_1.REGISTRY_BY_CAPABILITY.get("app.init").mcp.handler = (args) => (0, workflow_app_loader_1.initWorkflowApp)((0, io_1.required)((0, io_1.optionalArg)(args.appId), "app id"), args);
64
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.init").mcp.handler = (args) => loadWorkflowAppLoader().initWorkflowApp((0, cli_args_1.required)((0, cli_args_1.optionalArg)(args.appId), "app id"), args);
50
65
  // `cw init <id>` — the standalone scaffold verb. v2 folds `init` into
51
66
  // `app.init` (the old build's legacy `.workflow.js` scaffold is gone), so
52
67
  // both surfaces route through initWorkflowApp, same as `cw app init`. The
@@ -56,15 +71,15 @@ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.init").mcp.handler = (args) => (
56
71
  (0, registry_core_1.attachCliBinding)("init", {
57
72
  path: ["init"],
58
73
  jsonMode: "default",
59
- handler: (args) => ({ json: (0, workflow_app_loader_1.initWorkflowApp)((0, io_1.required)((0, io_1.optionalArg)(args.positionals[0]), "workflow id"), args.options) }),
74
+ handler: (args) => ({ json: loadWorkflowAppLoader().initWorkflowApp((0, cli_args_1.required)((0, cli_args_1.optionalArg)(args.positionals[0]), "workflow id"), args.options) }),
60
75
  });
61
- registry_core_1.REGISTRY_BY_CAPABILITY.get("init").mcp.handler = (args) => (0, workflow_app_loader_1.initWorkflowApp)((0, io_1.required)((0, io_1.optionalArg)(args.workflowId ?? args.appId), "workflow id"), args);
76
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("init").mcp.handler = (args) => loadWorkflowAppLoader().initWorkflowApp((0, cli_args_1.required)((0, cli_args_1.optionalArg)(args.workflowId ?? args.appId), "workflow id"), args);
62
77
  (0, registry_core_1.attachCliBinding)("app.package", {
63
78
  path: ["app", "package"],
64
79
  jsonMode: "default",
65
- handler: (args) => ({ json: (0, workflow_app_loader_1.packageWorkflowApp)((0, io_1.required)(args.positionals[0], "app id"), args.options) }),
80
+ handler: (args) => ({ json: loadWorkflowAppLoader().packageWorkflowApp((0, cli_args_1.required)(args.positionals[0], "app id"), args.options) }),
66
81
  });
67
- registry_core_1.REGISTRY_BY_CAPABILITY.get("app.package").mcp.handler = (args) => (0, workflow_app_loader_1.packageWorkflowApp)((0, io_1.required)((0, io_1.optionalArg)(args.appId), "app id"), args);
82
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.package").mcp.handler = (args) => loadWorkflowAppLoader().packageWorkflowApp((0, cli_args_1.required)((0, cli_args_1.optionalArg)(args.appId), "app id"), args);
68
83
  // `cw app run <app-id>` — plan+drive+report an app in one call. 2-token
69
84
  // cli.path found before the ["app"] usage catch-all; `appRunCli` reads the
70
85
  // app id from `appId`, so the first positional after "run" is forwarded as
@@ -72,7 +87,7 @@ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.package").mcp.handler = (args) =
72
87
  (0, registry_core_1.attachCliBinding)("app.run", {
73
88
  path: ["app", "run"],
74
89
  jsonMode: "default",
75
- handler: (args) => ({ json: (0, app_run_cli_1.appRunCli)({ ...args.options, appId: (0, io_1.required)(args.positionals[0], "app id") }) }),
90
+ handler: (args) => ({ json: loadAppRunCli().appRunCli({ ...args.options, appId: (0, cli_args_1.required)(args.positionals[0], "app id") }) }),
76
91
  });
77
92
  // A 1-token `["app"]` row that exists ONLY to own the fixed usage string
78
93
  // for an unrecognized `app` subcommand (`app run` is not yet CLI-wired at
@@ -88,7 +103,7 @@ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.package").mcp.handler = (args) =
88
103
  jsonMode: "default",
89
104
  hiddenFromHelp: true,
90
105
  handler: () => {
91
- throw new Error("Usage: cw.js app list|show|validate|init|package|run [app-id|path]");
106
+ throw new Error("Usage: cw app list|show|validate|init|package|run [app-id|path]");
92
107
  },
93
108
  }, "app.usage exists only to own the fixed usage-error text for an unrecognized app subcommand; every real app.* action is its own capability row above.");
94
109
  // ---------------------------------------------------------------------
@@ -100,188 +115,188 @@ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.package").mcp.handler = (args) =
100
115
  // only ever reached when no 2-token real row for that family matched.
101
116
  // `hiddenFromHelp` keeps each off its own `cw help <verb>` line.
102
117
  // ---------------------------------------------------------------------
103
- (0, registry_core_1.addCliOnlyCapability)("sandbox.usage", "cw.js sandbox list|show|validate|choose|resolve [profile-id|profile-file]", {
118
+ (0, registry_core_1.addCliOnlyCapability)("sandbox.usage", "cw sandbox list|show|validate|choose|resolve [profile-id|profile-file]", {
104
119
  path: ["sandbox"],
105
120
  jsonMode: "default",
106
121
  hiddenFromHelp: true,
107
122
  handler: () => {
108
- throw new Error("Usage: cw.js sandbox list|show|validate|choose|resolve [profile-id|profile-file]");
123
+ throw new Error("Usage: cw sandbox list|show|validate|choose|resolve [profile-id|profile-file]");
109
124
  },
110
125
  }, "sandbox.usage exists only to own the fixed usage-error text for an unrecognized sandbox subcommand; every real sandbox.* action is its own capability row above.");
111
- (0, registry_core_1.addCliOnlyCapability)("state.usage", "cw.js state check <run-id> [--state PATH] [--write]", {
126
+ (0, registry_core_1.addCliOnlyCapability)("state.usage", "cw state check <run-id> [--state PATH] [--write]", {
112
127
  path: ["state"],
113
128
  jsonMode: "default",
114
129
  hiddenFromHelp: true,
115
130
  handler: () => {
116
- throw new Error("Usage: cw.js state check <run-id> [--state PATH] [--write]");
131
+ throw new Error("Usage: cw state check <run-id> [--state PATH] [--write]");
117
132
  },
118
133
  }, "state.usage exists only to own the fixed usage-error text for an unrecognized state subcommand; every real state.* action is its own capability row above.");
119
- (0, registry_core_1.addCliOnlyCapability)("audit.usage", "cw.js audit summary|worker|provenance|multi-agent|policy|role|blackboard|judge|attest|decision <run-id> [worker-id|role-id]", {
134
+ (0, registry_core_1.addCliOnlyCapability)("audit.usage", "cw audit summary|worker|provenance|multi-agent|policy|role|blackboard|judge|attest|decision <run-id> [worker-id|role-id]", {
120
135
  path: ["audit"],
121
136
  jsonMode: "default",
122
137
  hiddenFromHelp: true,
123
138
  handler: () => {
124
- throw new Error("Usage: cw.js audit summary|worker|provenance|multi-agent|policy|role|blackboard|judge|attest|decision <run-id> [worker-id|role-id]");
139
+ throw new Error("Usage: cw audit summary|worker|provenance|multi-agent|policy|role|blackboard|judge|attest|decision <run-id> [worker-id|role-id]");
125
140
  },
126
141
  }, "audit.usage exists only to own the fixed usage-error text for an unrecognized audit subcommand; every real audit.* action is its own capability row above.");
127
- (0, registry_core_1.addCliOnlyCapability)("blackboard.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>", {
142
+ (0, registry_core_1.addCliOnlyCapability)("blackboard.usage", "cw 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>", {
128
143
  path: ["blackboard"],
129
144
  jsonMode: "default",
130
145
  hiddenFromHelp: true,
131
146
  handler: () => {
132
- 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>");
147
+ throw new Error("Usage: cw 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>");
133
148
  },
134
149
  }, "blackboard.usage exists only to own the fixed usage-error text for an unrecognized blackboard subcommand; every real blackboard.* action is its own capability row above.");
135
- (0, registry_core_1.addCliOnlyCapability)("candidate.usage", "cw.js candidate list|show|register|score|rank|select|reject|summary <run-id> [candidate-id]", {
150
+ (0, registry_core_1.addCliOnlyCapability)("candidate.usage", "cw candidate list|show|register|score|rank|select|reject|summary <run-id> [candidate-id]", {
136
151
  path: ["candidate"],
137
152
  jsonMode: "default",
138
153
  hiddenFromHelp: true,
139
154
  handler: () => {
140
- throw new Error("Usage: cw.js candidate list|show|register|score|rank|select|reject|summary <run-id> [candidate-id]");
155
+ throw new Error("Usage: cw candidate list|show|register|score|rank|select|reject|summary <run-id> [candidate-id]");
141
156
  },
142
157
  }, "candidate.usage exists only to own the fixed usage-error text for an unrecognized candidate subcommand; every real candidate.* action is its own capability row above.");
143
- (0, registry_core_1.addCliOnlyCapability)("comment.usage", "cw.js comment add <kind> <run-id> <target-id> --body <text> | comment list <run-id> [--json]", {
158
+ (0, registry_core_1.addCliOnlyCapability)("comment.usage", "cw comment add <kind> <run-id> <target-id> --body <text> | comment list <run-id> [--json]", {
144
159
  path: ["comment"],
145
160
  jsonMode: "default",
146
161
  hiddenFromHelp: true,
147
162
  handler: () => {
148
- throw new Error("Usage: cw.js comment add <kind> <run-id> <target-id> --body <text> | comment list <run-id> [--json]");
163
+ throw new Error("Usage: cw comment add <kind> <run-id> <target-id> --body <text> | comment list <run-id> [--json]");
149
164
  },
150
165
  }, "comment.usage exists only to own the fixed usage-error text for an unrecognized comment subcommand; every real comment.* action is its own capability row above.");
151
- (0, registry_core_1.addCliOnlyCapability)("eval.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>", {
166
+ (0, registry_core_1.addCliOnlyCapability)("eval.usage", "cw 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>", {
152
167
  path: ["eval"],
153
168
  jsonMode: "default",
154
169
  hiddenFromHelp: true,
155
170
  handler: () => {
156
- 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>");
171
+ throw new Error("Usage: cw 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>");
157
172
  },
158
173
  }, "eval.usage exists only to own the fixed usage-error text for an unrecognized eval subcommand; every real eval.* action is its own capability row above.");
159
- (0, registry_core_1.addCliOnlyCapability)("telemetry.usage", "cw.js telemetry verify <run-id> [--pubkey <pem-or-path>] [--json]", {
174
+ (0, registry_core_1.addCliOnlyCapability)("telemetry.usage", "cw telemetry verify <run-id> [--pubkey <pem-or-path>] [--json]", {
160
175
  path: ["telemetry"],
161
176
  jsonMode: "default",
162
177
  hiddenFromHelp: true,
163
178
  handler: () => {
164
- throw new Error("Usage: cw.js telemetry verify <run-id> [--pubkey <pem-or-path>] [--json]");
179
+ throw new Error("Usage: cw telemetry verify <run-id> [--pubkey <pem-or-path>] [--json]");
165
180
  },
166
181
  }, "telemetry.usage exists only to own the fixed usage-error text for an unrecognized telemetry subcommand; every real telemetry.* action is its own capability row above.");
167
- (0, registry_core_1.addCliOnlyCapability)("demo.usage", "cw.js demo tamper|bundle [--json]", {
182
+ (0, registry_core_1.addCliOnlyCapability)("demo.usage", "cw demo tamper|bundle [--json]", {
168
183
  path: ["demo"],
169
184
  jsonMode: "default",
170
185
  hiddenFromHelp: true,
171
186
  handler: () => {
172
- throw new Error("Usage: cw.js demo tamper|bundle [--json]");
187
+ throw new Error("Usage: cw demo tamper|bundle [--json]");
173
188
  },
174
189
  }, "demo.usage exists only to own the fixed usage-error text for an unrecognized demo subcommand; every real demo.* action is its own capability row above.");
175
- (0, registry_core_1.addCliOnlyCapability)("multi-agent.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]", {
190
+ (0, registry_core_1.addCliOnlyCapability)("multi-agent.usage", "cw multi-agent run|status|step|blackboard|score|select|summary|summarize|graph|dependencies|failures|evidence|reasoning|show|role|group|membership|fanout|fanin <run-id> [id]", {
176
191
  path: ["multi-agent"],
177
192
  jsonMode: "default",
178
193
  hiddenFromHelp: true,
179
194
  handler: () => {
180
- 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]");
195
+ throw new Error("Usage: cw multi-agent run|status|step|blackboard|score|select|summary|summarize|graph|dependencies|failures|evidence|reasoning|show|role|group|membership|fanout|fanin <run-id> [id]");
181
196
  },
182
197
  }, "multi-agent.usage exists only to own the fixed usage-error text for an unrecognized multi-agent subcommand; every real multi-agent.* action is its own capability row above.");
183
- (0, registry_core_1.addCliOnlyCapability)("node.usage", "cw.js node list|show|graph|snapshot|diff|replay|verify <run-id> [node-id|snapshot-id|replay-id]", {
198
+ (0, registry_core_1.addCliOnlyCapability)("node.usage", "cw node list|show|graph|snapshot|diff|replay|verify <run-id> [node-id|snapshot-id|replay-id]", {
184
199
  path: ["node"],
185
200
  jsonMode: "default",
186
201
  hiddenFromHelp: true,
187
202
  handler: () => {
188
- throw new Error("Usage: cw.js node list|show|graph|snapshot|diff|replay|verify <run-id> [node-id|snapshot-id|replay-id]");
203
+ throw new Error("Usage: cw node list|show|graph|snapshot|diff|replay|verify <run-id> [node-id|snapshot-id|replay-id]");
189
204
  },
190
205
  }, "node.usage exists only to own the fixed usage-error text for an unrecognized node subcommand; every real node.* action is its own capability row above.");
191
- (0, registry_core_1.addCliOnlyCapability)("backend.usage", "cw.js backend list|show|probe [backend-id] | cw.js backend agent config [show|set] [--agent-command ... --agent-endpoint ... --agent-model ...]", {
206
+ (0, registry_core_1.addCliOnlyCapability)("backend.usage", "cw backend list|show|probe [backend-id] | cw backend agent config [show|set] [--agent-command ... --agent-endpoint ... --agent-model ...]", {
192
207
  path: ["backend"],
193
208
  jsonMode: "default",
194
209
  hiddenFromHelp: true,
195
210
  handler: () => {
196
- 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 ...]");
211
+ throw new Error("Usage: cw backend list|show|probe [backend-id] | cw backend agent config [show|set] [--agent-command ... --agent-endpoint ... --agent-model ...]");
197
212
  },
198
213
  }, "backend.usage exists only to own the fixed usage-error text for an unrecognized backend subcommand; every real backend.* action is its own capability row above.");
199
- (0, registry_core_1.addCliOnlyCapability)("contract.usage", "cw.js contract show <run-id> [contract-id]", {
214
+ (0, registry_core_1.addCliOnlyCapability)("contract.usage", "cw contract show <run-id> [contract-id]", {
200
215
  path: ["contract"],
201
216
  jsonMode: "default",
202
217
  hiddenFromHelp: true,
203
218
  handler: () => {
204
- throw new Error("Usage: cw.js contract show <run-id> [contract-id]");
219
+ throw new Error("Usage: cw contract show <run-id> [contract-id]");
205
220
  },
206
221
  }, "contract.usage exists only to own the fixed usage-error text for an unrecognized contract subcommand; every real contract.* action is its own capability row above.");
207
- (0, registry_core_1.addCliOnlyCapability)("migration.usage", "cw.js migration list|check|prove [target] [--contract run-state|workflow-app]", {
222
+ (0, registry_core_1.addCliOnlyCapability)("migration.usage", "cw migration list|check|prove [target] [--contract run-state|workflow-app]", {
208
223
  path: ["migration"],
209
224
  jsonMode: "default",
210
225
  hiddenFromHelp: true,
211
226
  handler: () => {
212
- throw new Error("Usage: cw.js migration list|check|prove [target] [--contract run-state|workflow-app]");
227
+ throw new Error("Usage: cw migration list|check|prove [target] [--contract run-state|workflow-app]");
213
228
  },
214
229
  }, "migration.usage exists only to own the fixed usage-error text for an unrecognized migration subcommand; every real migration.* action is its own capability row above.");
215
- (0, registry_core_1.addCliOnlyCapability)("feedback.usage", "cw.js feedback list|show|summary|collect|task|resolve <run-id> [feedback-id]", {
230
+ (0, registry_core_1.addCliOnlyCapability)("feedback.usage", "cw feedback list|show|summary|collect|task|resolve <run-id> [feedback-id]", {
216
231
  path: ["feedback"],
217
232
  jsonMode: "default",
218
233
  hiddenFromHelp: true,
219
234
  handler: () => {
220
- throw new Error("Usage: cw.js feedback list|show|summary|collect|task|resolve <run-id> [feedback-id]");
235
+ throw new Error("Usage: cw feedback list|show|summary|collect|task|resolve <run-id> [feedback-id]");
221
236
  },
222
237
  }, "feedback.usage exists only to own the fixed usage-error text for an unrecognized feedback subcommand; every real feedback.* action is its own capability row above.");
223
- (0, registry_core_1.addCliOnlyCapability)("metrics.usage", "cw.js metrics show <run-id> | metrics summary [--scope repo|home] [--pricing <path>|default] [--limit N] [--json]", {
238
+ (0, registry_core_1.addCliOnlyCapability)("metrics.usage", "cw metrics show <run-id> | metrics summary [--scope repo|home] [--pricing <path>|default] [--limit N] [--json]", {
224
239
  path: ["metrics"],
225
240
  jsonMode: "default",
226
241
  hiddenFromHelp: true,
227
242
  handler: () => {
228
- throw new Error("Usage: cw.js metrics show <run-id> | metrics summary [--scope repo|home] [--pricing <path>|default] [--limit N] [--json]");
243
+ throw new Error("Usage: cw metrics show <run-id> | metrics summary [--scope repo|home] [--pricing <path>|default] [--limit N] [--json]");
229
244
  },
230
245
  }, "metrics.usage exists only to own the fixed usage-error text for an unrecognized metrics subcommand; every real metrics.* action is its own capability row above.");
231
- (0, registry_core_1.addCliOnlyCapability)("operator.usage", "cw.js operator status|report <run-id> [--json]", {
246
+ (0, registry_core_1.addCliOnlyCapability)("operator.usage", "cw operator status|report <run-id> [--json]", {
232
247
  path: ["operator"],
233
248
  jsonMode: "default",
234
249
  hiddenFromHelp: true,
235
250
  handler: () => {
236
- throw new Error("Usage: cw.js operator status|report <run-id> [--json]");
251
+ throw new Error("Usage: cw operator status|report <run-id> [--json]");
237
252
  },
238
253
  }, "operator.usage exists only to own the fixed usage-error text for an unrecognized operator subcommand; every real operator.* action is its own capability row above.");
239
- (0, registry_core_1.addCliOnlyCapability)("topology.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>", {
254
+ (0, registry_core_1.addCliOnlyCapability)("topology.usage", "cw 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>", {
240
255
  path: ["topology"],
241
256
  jsonMode: "default",
242
257
  hiddenFromHelp: true,
243
258
  handler: () => {
244
- 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>");
259
+ throw new Error("Usage: cw 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>");
245
260
  },
246
261
  }, "topology.usage exists only to own the fixed usage-error text for an unrecognized topology subcommand; every real topology.* action is its own capability row above.");
247
- (0, registry_core_1.addCliOnlyCapability)("summary.usage", "cw.js summary refresh|show <run-id> [--json]", {
262
+ (0, registry_core_1.addCliOnlyCapability)("summary.usage", "cw summary refresh|show <run-id> [--json]", {
248
263
  path: ["summary"],
249
264
  jsonMode: "default",
250
265
  hiddenFromHelp: true,
251
266
  handler: () => {
252
- throw new Error("Usage: cw.js summary refresh|show <run-id> [--json]");
267
+ throw new Error("Usage: cw summary refresh|show <run-id> [--json]");
253
268
  },
254
269
  }, "summary.usage exists only to own the fixed usage-error text for an unrecognized summary subcommand; every real summary.* action is its own capability row above.");
255
- (0, registry_core_1.addCliOnlyCapability)("workbench.usage", "cw.js workbench serve [--port N] [--once] [--require-token] | view <run-id> [--json]", {
270
+ (0, registry_core_1.addCliOnlyCapability)("workbench.usage", "cw workbench serve [--port N] [--once] [--require-token] | view <run-id> [--json]", {
256
271
  path: ["workbench"],
257
272
  jsonMode: "default",
258
273
  hiddenFromHelp: true,
259
274
  handler: () => {
260
- throw new Error("Usage: cw.js workbench serve [--port N] [--once] [--require-token] | view <run-id> [--json]");
275
+ throw new Error("Usage: cw workbench serve [--port N] [--once] [--require-token] | view <run-id> [--json]");
261
276
  },
262
277
  }, "workbench.usage exists only to own the fixed usage-error text for an unrecognized workbench subcommand; every real workbench.* action is its own capability row above.");
263
- (0, registry_core_1.addCliOnlyCapability)("worker.usage", "cw.js worker list|summary|show|manifest|output|fail|validate <run-id> [worker-id] [result-file]", {
278
+ (0, registry_core_1.addCliOnlyCapability)("worker.usage", "cw worker list|summary|show|manifest|output|fail|validate <run-id> [worker-id] [result-file]", {
264
279
  path: ["worker"],
265
280
  jsonMode: "default",
266
281
  hiddenFromHelp: true,
267
282
  handler: () => {
268
- throw new Error("Usage: cw.js worker list|summary|show|manifest|output|fail|validate <run-id> [worker-id] [result-file]");
283
+ throw new Error("Usage: cw worker list|summary|show|manifest|output|fail|validate <run-id> [worker-id] [result-file]");
269
284
  },
270
285
  }, "worker.usage exists only to own the fixed usage-error text for an unrecognized worker subcommand; every real worker.* action is its own capability row above.");
271
- (0, registry_core_1.addCliOnlyCapability)("review.usage", "cw.js review status <run-id> [--json] | review policy <run-id> --required-approvals N --authorized-roles a,b --applies-to commit,selection", {
286
+ (0, registry_core_1.addCliOnlyCapability)("review.usage", "cw review status <run-id> [--json] | review policy <run-id> --required-approvals N --authorized-roles a,b --applies-to commit,selection", {
272
287
  path: ["review"],
273
288
  jsonMode: "default",
274
289
  hiddenFromHelp: true,
275
290
  handler: () => {
276
- 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");
291
+ throw new Error("Usage: cw review status <run-id> [--json] | review policy <run-id> --required-approvals N --authorized-roles a,b --applies-to commit,selection");
277
292
  },
278
293
  }, "review.usage exists only to own the fixed usage-error text for an unrecognized review subcommand; every real review.* action is its own capability row above.");
279
- (0, registry_core_1.addCliOnlyCapability)("coordinator.usage", "cw.js coordinator summary <run-id> | coordinator decision <run-id> --kind <kind> --outcome <outcome> --reason TEXT", {
294
+ (0, registry_core_1.addCliOnlyCapability)("coordinator.usage", "cw coordinator summary <run-id> | coordinator decision <run-id> --kind <kind> --outcome <outcome> --reason TEXT", {
280
295
  path: ["coordinator"],
281
296
  jsonMode: "default",
282
297
  hiddenFromHelp: true,
283
298
  handler: () => {
284
- throw new Error("Usage: cw.js coordinator summary <run-id> | coordinator decision <run-id> --kind <kind> --outcome <outcome> --reason TEXT");
299
+ throw new Error("Usage: cw coordinator summary <run-id> | coordinator decision <run-id> --kind <kind> --outcome <outcome> --reason TEXT");
285
300
  },
286
301
  }, "coordinator.usage exists only to own the fixed usage-error text for an unrecognized coordinator subcommand; every real coordinator.* action is its own capability row above.");
287
302
  // ---- man (CLI-only; raw manual-page bytes to stdout, no MCP peer) -----
@@ -305,7 +320,7 @@ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.package").mcp.handler = (args) =
305
320
  if (!topic) {
306
321
  throw new Error("Missing topic.\n Tip: cw man release-tooling for the release tooling manual.");
307
322
  }
308
- process.stdout.write((0, man_cli_1.readManPage)(topic));
323
+ process.stdout.write(loadManCli().readManPage(topic));
309
324
  return {};
310
325
  },
311
326
  }, "man is a CLI-only raw-file reader over docs/; the old build never gave it an MCP peer.");
@@ -314,8 +329,8 @@ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.package").mcp.handler = (args) =
314
329
  path: ["info"],
315
330
  jsonMode: "flag",
316
331
  handler: (args) => {
317
- const appId = (0, io_1.required)(args.positionals[0], "workflow app id");
318
- const data = (0, workflow_app_loader_1.showWorkflowApp)(appId);
332
+ const appId = (0, cli_args_1.required)(args.positionals[0], "workflow app id");
333
+ const data = loadWorkflowAppLoader().showWorkflowApp(appId);
319
334
  return { json: data, text: `${(0, help_1.formatInfo)(appId, data)}\n` };
320
335
  },
321
336
  }, "info is a CLI-only convenience card over app.show; the old build never gave it an MCP peer.");
@@ -336,9 +351,9 @@ registry_core_1.REGISTRY_BY_CAPABILITY.get("app.package").mcp.handler = (args) =
336
351
  (0, registry_core_1.attachCliBinding)("next", {
337
352
  path: ["next"],
338
353
  jsonMode: "default",
339
- handler: (args) => ({ json: (0, state_cli_1.nextCli)((0, io_1.required)((0, io_1.optionalArg)(args.positionals[0]), "run id"), args.options) }),
354
+ handler: (args) => ({ json: loadStateCli().nextCli((0, cli_args_1.required)((0, cli_args_1.optionalArg)(args.positionals[0]), "run id"), args.options) }),
340
355
  });
341
- registry_core_1.REGISTRY_BY_CAPABILITY.get("next").mcp.handler = (args) => (0, state_cli_1.nextCli)((0, io_1.required)((0, io_1.optionalArg)(args.runId), "run id"), args);
356
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("next").mcp.handler = (args) => loadStateCli().nextCli((0, cli_args_1.required)((0, cli_args_1.optionalArg)(args.runId), "run id"), args);
342
357
  // `ledger.propose`/`.review`/`.verify`/`.apply`/`.list` are documented
343
358
  // payload-probe opt-outs in the old build (each mints a fresh timestamped/
344
359
  // digested entry, or reads args that arrive by --file/stdin on the CLI vs
@@ -419,3 +419,7 @@ The one-command `cw -q` headline now routes the question and defaults the repo t
419
419
  0.2.1
420
420
 
421
421
  0.2.2
422
+
423
+ 0.2.3
424
+
425
+ 0.2.4
@@ -80,7 +80,7 @@ Operators can record an unverified selection only with a clear option. That
80
80
  records selection state but does not make the candidate into committed state.
81
81
 
82
82
  Committed state has a harder rule. A candidate can be moved up by
83
- `cw.js commit --candidate` or `cw.js commit --selection` only when it has score
83
+ `cw commit --candidate` or `cw commit --selection` only when it has score
84
84
  evidence, a verified selection, and a linked verifier node with evidence.
85
85
  Rejected, failed, unscored, unselected, and unverified candidates are stopped
86
86
  and produce ErrorFeedback.
@@ -21,7 +21,7 @@ Map out a repository architecture, weigh the risks, check the important
21
21
  findings, and put together an evidence-backed verdict.
22
22
 
23
23
  ```bash
24
- node scripts/cw.js plan architecture-review \
24
+ cw plan architecture-review \
25
25
  --repo /path/to/repo \
26
26
  --question "Is this architecture sound?" \
27
27
  --invariant "public API stays stable" \
@@ -72,7 +72,7 @@ you can act on, patch when `--mode fix` is allowed, check the outcomes, and
72
72
  give a short account with evidence.
73
73
 
74
74
  ```bash
75
- node scripts/cw.js plan pr-review-fix-ci \
75
+ cw plan pr-review-fix-ci \
76
76
  --repo /path/to/repo \
77
77
  --pr 123 \
78
78
  --base main \
@@ -86,7 +86,7 @@ Get a release ready with checklist discipline: version checks, changelog, tests,
86
86
  packaging, release notes, and a last verification.
87
87
 
88
88
  ```bash
89
- node scripts/cw.js plan release-cut \
89
+ cw plan release-cut \
90
90
  --repo /path/to/repo \
91
91
  --version 0.1.13 \
92
92
  --previousVersion 0.1.11 \
@@ -104,7 +104,7 @@ papers — not only a git code repo. The working directory is the corpus,
104
104
  so the agent can back its answer with your own files.
105
105
 
106
106
  ```bash
107
- node scripts/cw.js plan research-synthesis \
107
+ cw plan research-synthesis \
108
108
  --cwd /tmp/research-run \
109
109
  --question "What does the evidence support?" \
110
110
  --source "official-docs" \
@@ -179,8 +179,8 @@ easy to inspect, and useful.
179
179
  Use the Operator UX commands to look at any canonical app run:
180
180
 
181
181
  ```bash
182
- node scripts/cw.js status <run-id>
183
- node scripts/cw.js graph <run-id>
184
- node scripts/cw.js report <run-id> --summary
182
+ cw status <run-id>
183
+ cw graph <run-id>
184
+ cw report <run-id> --summary
185
185
  ```
186
186
  0.1.51
@@ -1,7 +1,7 @@
1
1
  # CLI ↔ MCP Parity
2
2
 
3
3
  CW v0.1.27 adds CLI ↔ MCP Parity. CW has two front doors. The CLI
4
- (`node scripts/cw.js ...`, `dist/cli.js`) is built for human speed: short,
4
+ (`cw ...`, `dist/cli.js`) is built for human speed: short,
5
5
  easy-to-read text with exit codes that have clear sense. The MCP server
6
6
  (`cw_*` JSON-RPC tools) is built for machine context: full, fixed, ordered JSON.
7
7
  This release makes the two doors two views of one body of data — named, made from
@@ -82,7 +82,7 @@ relationship. `identical` means `cw <cmd> --json` is equal to the `cw_<tool>`
82
82
  payload; `projected` means a declared divergence with a reason; `cli-only` marks
83
83
  a surface-specific capability with a recorded reason. The matrix is
84
84
  <!-- gen:parity:count -->
85
- machine-complete by design: 239 capabilities, 197 MCP tools.
85
+ machine-complete by design: 241 capabilities, 198 MCP tools.
86
86
  <!-- /gen:parity:count -->
87
87
 
88
88
  <!-- gen:parity:table -->
@@ -172,6 +172,7 @@ machine-complete by design: 239 capabilities, 197 MCP tools.
172
172
  | `coordinator.decision` | `cw coordinator decision` | `cw_coordinator_decision` | `coordinator.decision` | both | identical |
173
173
  | `audit.summary` | `cw audit summary` | `cw_audit_summary` | `audit.summary` | both | identical |
174
174
  | `audit.verify` | `cw audit verify` | `cw_audit_verify` | `audit.verify` | both | identical |
175
+ | `audit.repair` | `cw audit repair` | `cw_audit_repair` | `audit.repair` | both | identical |
175
176
  | `audit.worker` | `cw audit worker` | `cw_audit_worker` | `audit.worker` | both | identical |
176
177
  | `audit.provenance` | `cw audit provenance` | `cw_audit_provenance` | `audit.provenance` | both | identical |
177
178
  | `audit.multi-agent` | `cw audit multi-agent` | `cw_audit_multi_agent` | `audit.multi-agent` | both | identical |
@@ -286,6 +287,7 @@ machine-complete by design: 239 capabilities, 197 MCP tools.
286
287
  | `history` | `cw history` | `cw_history` | `history` | both | identical |
287
288
  | `audit.head` | `cw audit head` | `cw_audit_head` | `audit.head` | both | identical |
288
289
  | `version` | `cw version` | `—` | `version` | cli-only | cli-only |
290
+ | `completion` | `cw completion` | `—` | `completion` | cli-only | cli-only |
289
291
  | `search` | `cw search` | `—` | `search` | cli-only | cli-only |
290
292
  | `doctor` | `cw doctor` | `—` | `doctor` | cli-only | cli-only |
291
293
  | `fix` | `cw fix` | `—` | `fix` | cli-only | cli-only |
@@ -341,9 +343,10 @@ A capability may be on one surface only, but never without word of it — it mus
341
343
  carry a recorded reason in the registry.
342
344
 
343
345
  <!-- gen:parity:cliOnly -->
344
- 42 capabilities are CLI-only:
346
+ 43 capabilities are CLI-only:
345
347
 
346
348
  - `version` — version is a local, no-run-state print; the old build never gave it an MCP peer.
349
+ - `completion` — shell-completion output is a script for the user's OWN shell to source, not data an MCP client could use — CLI-only, same reasoning as doctor/fix.
347
350
  - `search` — CLI-only discovery helper over the same real app data cw list shows; no MCP client needs a free-text search tool alongside cw_list's structured output.
348
351
  - `doctor` — Environment diagnostics are inherently local to the CLI host — Node version, $PATH, $CW_HOME/cwd writability. An MCP client diagnosing the server process's environment is not meaningful; agents already receive the same readiness facts in their typed results (e.g. status: blocked, agentConfigured). Inspired by `brew doctor`.
349
352
  - `fix` — Environment fix commands are local diagnostics, same reasoning as doctor.
@@ -426,19 +429,22 @@ Parity is checked by `scripts/parity-check.js --check`, run by
426
429
  the registry, lists the live CLI commands and MCP tools, and fails closed on any
427
430
  of the rules above.
428
431
 
429
- The CLI dispatcher (`src/cli/command-surface.ts`) is being decomposed out of one
430
- large `switch` into per-command handler modules under `src/cli/handlers/`
431
- (`handle<Group>(args, runner)`), with `command-surface.ts` left as the thin
432
- router; shared helpers live in `src/cli/io.ts` (arg/JSON) and `src/cli/format.ts`
433
- (render). Carved so far: `workbench`, `clones`, `audit`, `worker`, `schedule`, `routine`,
434
- `sched`, `registry`, `queue`, `history`, `report`, `operator`, `graph`,
435
- `topology`, `summary`, `multi-agent`, `run`, `approve`, `reject`, `comment`,
436
- `handoff`, `review`, `blackboard`, `coordinator`, `eval`, `node`, `gc`,
437
- `telemetry`, `demo`, `feedback`, `metrics`, `migration`, `sandbox`, `backend`,
438
- `contract`, `candidate`. This is a pure code-move
439
- the command surface is unchanged and the parity scanner reads
440
- `dist/cli/handlers/*` so a subcommand `case` in a handler module still counts as a
441
- live CLI token.
432
+ The CLI dispatch surface is table-driven, not a hand-kept `switch`. The source
433
+ tree is small: `src/cli/entry.ts` (process entry), `src/cli/parseargv.ts`
434
+ (argv reading), `src/cli/dispatch.ts` (the one dispatcher), and `src/cli/io.ts`
435
+ (output helpers: `printJson`, `styledHelp`). `dispatch(args)` looks the parsed
436
+ command up in the capability table (`src/core/capability-table.ts`, put
437
+ together from the slices under `src/wiring/capability-table/`) and runs that
438
+ row's `cli.handler` a new capability is a new table row, never a new `case`.
439
+ The shared arg helpers (`required`, `optionalArg`, `wantsJson`) live in
440
+ `src/core/util/cli-args.ts`, a pure module used by the CLI and MCP sides of
441
+ every wiring slice; they were moved out of `cli/io.ts` because the purity
442
+ gate's layer rule says `wiring/` may not take imports from `cli/`. The parity
443
+ scanner works the same way: `cliDispatchTokens()` gets the live token list
444
+ straight from the registry's CLI capabilities (`cli.caseTokens` when a row
445
+ names more than one first token, else `cli.path`), then makes sure each
446
+ declared path resolves through the live dispatcher — there is no grep over
447
+ built dispatch source.
442
448
 
443
449
  `test/cli-mcp-parity-smoke.js` proves the contract from end to end. It checks
444
450
  registry ⇄ CLI ⇄ MCP coverage (every declared capability is found on its declared
@@ -633,3 +639,7 @@ CLI golden-path fixes: `cw -q "…"` routes the question (was read as an app id
633
639
  0.2.1
634
640
 
635
641
  0.2.2
642
+
643
+ 0.2.3
644
+
645
+ 0.2.4
@@ -179,3 +179,7 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
179
179
  0.2.1
180
180
 
181
181
  0.2.2
182
+
183
+ 0.2.3
184
+
185
+ 0.2.4
@@ -163,3 +163,7 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
163
163
  0.2.1
164
164
 
165
165
  0.2.2
166
+
167
+ 0.2.3
168
+
169
+ 0.2.4
@@ -119,18 +119,18 @@ required role memberships have no blackboard message or artifact refs.
119
119
  ## CLI
120
120
 
121
121
  ```bash
122
- node scripts/cw.js blackboard summary <run-id>
123
- node scripts/cw.js blackboard graph <run-id>
124
- node scripts/cw.js blackboard resolve <run-id> --id bb --title "Shared state"
125
- node scripts/cw.js blackboard topic create <run-id> --id topic --title "Synthesis"
126
- node scripts/cw.js blackboard message post <run-id> --topic topic --body "..."
127
- node scripts/cw.js blackboard message list <run-id> [--topic topic]
128
- node scripts/cw.js blackboard context put <run-id> --topic topic --kind fact --key k --value v
129
- node scripts/cw.js blackboard artifact add <run-id> --topic topic --path result.md --kind worker-result
130
- node scripts/cw.js blackboard artifact list <run-id>
131
- node scripts/cw.js blackboard snapshot <run-id>
132
- node scripts/cw.js coordinator summary <run-id>
133
- node scripts/cw.js coordinator decision <run-id> --kind conflict-resolution --outcome accepted --reason "..."
122
+ cw blackboard summary <run-id>
123
+ cw blackboard graph <run-id>
124
+ cw blackboard resolve <run-id> --id bb --title "Shared state"
125
+ cw blackboard topic create <run-id> --id topic --title "Synthesis"
126
+ cw blackboard message post <run-id> --topic topic --body "..."
127
+ cw blackboard message list <run-id> [--topic topic]
128
+ cw blackboard context put <run-id> --topic topic --kind fact --key k --value v
129
+ cw blackboard artifact add <run-id> --topic topic --path result.md --kind worker-result
130
+ cw blackboard artifact list <run-id>
131
+ cw blackboard snapshot <run-id>
132
+ cw coordinator summary <run-id>
133
+ cw coordinator decision <run-id> --kind conflict-resolution --outcome accepted --reason "..."
134
134
  ```
135
135
 
136
136
  The CLI gives JSON by default for focused blackboard and coordinator
@@ -167,11 +167,11 @@ suggested action.
167
167
  Use:
168
168
 
169
169
  ```bash
170
- node scripts/cw.js status <run-id>
171
- node scripts/cw.js graph <run-id>
172
- node scripts/cw.js report <run-id> --show
173
- node scripts/cw.js audit summary <run-id>
174
- node scripts/cw.js audit provenance <run-id>
170
+ cw status <run-id>
171
+ cw graph <run-id>
172
+ cw report <run-id> --show
173
+ cw audit summary <run-id>
174
+ cw audit provenance <run-id>
175
175
  ```
176
176
 
177
177
  ## Migration