cool-workflow 0.2.1 → 0.2.3

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 (156) 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 +29 -91
  10. package/dist/cli/entry.js +41 -1
  11. package/dist/cli/io.js +6 -2
  12. package/dist/cli/parseargv.js +6 -2
  13. package/dist/core/capability-data.js +271 -0
  14. package/dist/core/capability-table.js +16 -3504
  15. package/dist/core/format/completion.js +68 -0
  16. package/dist/core/format/help.js +50 -8
  17. package/dist/core/format/safe-json.js +73 -0
  18. package/dist/core/format/state-explosion-text.js +1 -1
  19. package/dist/core/multi-agent/candidate-scoring.js +5 -1
  20. package/dist/core/multi-agent/collaboration.js +6 -5
  21. package/dist/core/multi-agent/coordinator.js +9 -8
  22. package/dist/core/multi-agent/runtime.js +4 -4
  23. package/dist/core/multi-agent/topology.js +3 -3
  24. package/dist/core/pipeline/commit-gate.js +2 -1
  25. package/dist/core/pipeline/dispatch.js +18 -4
  26. package/dist/core/pipeline/drive-decide.js +2 -1
  27. package/dist/core/state/migrations.js +16 -1
  28. package/dist/core/state/state-explosion/digest.js +16 -15
  29. package/dist/core/state/state-explosion/graph.js +26 -19
  30. package/dist/core/state/state-explosion/helpers.js +2 -1
  31. package/dist/core/state/state-explosion/report.js +6 -6
  32. package/dist/core/trust/ledger.js +2 -1
  33. package/dist/core/types/execution-backend.js +18 -0
  34. package/dist/core/types/observability.js +7 -0
  35. package/dist/core/util/collate.js +23 -0
  36. package/dist/core/util/numeric-flag.js +40 -0
  37. package/dist/core/version.js +1 -1
  38. package/dist/mcp/server.js +99 -11
  39. package/dist/shell/audit-cli.js +99 -23
  40. package/dist/shell/commit-summary.js +2 -1
  41. package/dist/shell/coordinator-io.js +73 -13
  42. package/dist/shell/dispatch.js +1 -1
  43. package/dist/shell/doctor.js +80 -1
  44. package/dist/shell/drive.js +269 -59
  45. package/dist/shell/eval-text.js +2 -2
  46. package/dist/shell/evidence-reasoning.js +8 -7
  47. package/dist/shell/execution-backend/agent.js +20 -1
  48. package/dist/shell/execution-backend/container.js +4 -1
  49. package/dist/shell/execution-backend/local.js +4 -1
  50. package/dist/shell/execution-backend/registry.js +2 -1
  51. package/dist/shell/execution-backend/types.js +0 -9
  52. package/dist/shell/feedback-cli.js +6 -6
  53. package/dist/shell/fs-atomic.js +232 -30
  54. package/dist/shell/man-cli.js +6 -0
  55. package/dist/shell/metrics-cli.js +2 -1
  56. package/dist/shell/multi-agent-cli.js +367 -323
  57. package/dist/shell/multi-agent-host.js +9 -9
  58. package/dist/shell/multi-agent-operator-ux.js +82 -39
  59. package/dist/shell/node-store.js +10 -4
  60. package/dist/shell/observability.js +13 -12
  61. package/dist/shell/onramp.js +17 -1
  62. package/dist/shell/operator-ux-text.js +24 -23
  63. package/dist/shell/operator-ux.js +22 -20
  64. package/dist/shell/orchestrator.js +49 -38
  65. package/dist/shell/pipeline-cli.js +168 -111
  66. package/dist/shell/reclamation-io.js +16 -5
  67. package/dist/shell/registry-cli.js +19 -17
  68. package/dist/shell/remote-source.js +13 -8
  69. package/dist/shell/report-cli.js +45 -0
  70. package/dist/shell/report.js +4 -2
  71. package/dist/shell/run-registry-io.js +77 -19
  72. package/dist/shell/run-store.js +91 -2
  73. package/dist/shell/scheduling-io.js +12 -13
  74. package/dist/shell/state-cli.js +2 -7
  75. package/dist/shell/state-explosion-cli.js +19 -10
  76. package/dist/shell/topology-io.js +38 -6
  77. package/dist/shell/trust-audit.js +264 -23
  78. package/dist/shell/trust-policy-io.js +1 -1
  79. package/dist/shell/worker-cli.js +41 -29
  80. package/dist/shell/worker-isolation.js +34 -9
  81. package/dist/shell/workflow-app-loader.js +3 -2
  82. package/dist/wiring/capability-table/basics.js +91 -0
  83. package/dist/wiring/capability-table/exec-backend.js +171 -0
  84. package/dist/wiring/capability-table/index.js +42 -0
  85. package/dist/wiring/capability-table/multi-agent.js +630 -0
  86. package/dist/wiring/capability-table/parity.js +467 -0
  87. package/dist/wiring/capability-table/pipeline.js +292 -0
  88. package/dist/wiring/capability-table/registry-core.js +208 -0
  89. package/dist/wiring/capability-table/reporting.js +435 -0
  90. package/dist/wiring/capability-table/scheduling-registry.js +592 -0
  91. package/dist/wiring/capability-table/state.js +181 -0
  92. package/dist/wiring/capability-table/trust-ledger.js +158 -0
  93. package/dist/wiring/capability-table/workflow-apps.js +381 -0
  94. package/docs/agent-delegation-drive.7.md +4 -0
  95. package/docs/candidate-scoring.7.md +1 -1
  96. package/docs/canonical-workflow-apps.7.md +7 -7
  97. package/docs/cli-mcp-parity.7.md +13 -3
  98. package/docs/contract-migration-tooling.7.md +4 -0
  99. package/docs/control-plane-scheduling.7.md +4 -0
  100. package/docs/coordinator-blackboard.7.md +17 -17
  101. package/docs/dogfood-one-real-repo.7.md +11 -11
  102. package/docs/durable-state-and-locking.7.md +24 -0
  103. package/docs/end-to-end-golden-path.7.md +14 -14
  104. package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
  105. package/docs/execution-backends.7.md +4 -0
  106. package/docs/getting-started.md +37 -37
  107. package/docs/index.md +1 -0
  108. package/docs/multi-agent-cli-mcp-surface.7.md +21 -17
  109. package/docs/multi-agent-eval-replay-harness.7.md +17 -13
  110. package/docs/multi-agent-operator-ux.7.md +23 -19
  111. package/docs/multi-agent-runtime-core.7.md +22 -22
  112. package/docs/multi-agent-topologies.7.md +6 -6
  113. package/docs/multi-agent-trust-policy-audit.7.md +11 -11
  114. package/docs/node-snapshot-diff-replay.7.md +4 -0
  115. package/docs/observability-cost-accounting.7.md +4 -0
  116. package/docs/operator-ux.7.md +34 -34
  117. package/docs/pipeline-runner.7.md +4 -4
  118. package/docs/project-index.md +48 -5
  119. package/docs/real-execution-backends.7.md +4 -0
  120. package/docs/release-and-migration.7.md +5 -1
  121. package/docs/release-tooling.7.md +4 -0
  122. package/docs/routines.md +4 -4
  123. package/docs/run-registry-control-plane.7.md +23 -19
  124. package/docs/run-retention-reclamation.7.md +4 -0
  125. package/docs/scheduled-tasks.md +14 -14
  126. package/docs/security-trust-hardening.7.md +43 -13
  127. package/docs/state-explosion-management.7.md +14 -10
  128. package/docs/team-collaboration.7.md +4 -0
  129. package/docs/trust-audit-anchor.7.md +71 -0
  130. package/docs/unix-principles.md +3 -1
  131. package/docs/verifier-gated-commit.7.md +1 -1
  132. package/docs/web-desktop-workbench.7.md +4 -0
  133. package/docs/workflow-app-framework.7.md +13 -13
  134. package/manifest/plugin.manifest.json +1 -1
  135. package/package.json +4 -2
  136. package/scripts/agents/claude-p-agent.js +2 -2
  137. package/scripts/block-unapproved-tag.sh +23 -2
  138. package/scripts/bump-version.js +24 -2
  139. package/scripts/canonical-apps.js +4 -4
  140. package/scripts/children/batch-delegate-child.js +52 -2
  141. package/scripts/dogfood-release.js +1 -1
  142. package/scripts/fake-date-for-reproduction.js +44 -0
  143. package/scripts/golden-path.js +4 -4
  144. package/scripts/purity-baseline.json +71 -0
  145. package/scripts/purity-gate.js +239 -0
  146. package/scripts/release-check.js +8 -1
  147. package/scripts/release-flow.js +57 -1
  148. package/scripts/verdict-keygen.js +83 -0
  149. package/scripts/verify-bump-reproduction.sh +148 -0
  150. package/scripts/verify-verdict-signature.js +61 -0
  151. package/scripts/version-sync-check.js +33 -12
  152. package/skills/cool-workflow/SKILL.md +9 -9
  153. package/skills/cool-workflow/references/commands.md +89 -88
  154. package/ui/workbench/app.css +37 -1
  155. package/ui/workbench/app.js +124 -6
  156. package/workflows/README.md +19 -0
@@ -0,0 +1,592 @@
1
+ "use strict";
2
+ // wiring/capability-table/scheduling-registry.ts — MILESTONE 10
3
+ // (scheduling, registry, gc/reclamation, orphans, clones) CLI bindings:
4
+ // schedule *, cw loop, routine *, sched *, registry *, queue *, run *
5
+ // (list/show/search/rerun/resume/archive), history, gc *, orphans *,
6
+ // clones *. Split out of core/capability-table.ts, byte-for-byte
7
+ // (extracted with sed, not retyped).
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const registry_core_1 = require("./registry-core");
10
+ const io_1 = require("../../cli/io");
11
+ // MILESTONE 10 (scheduling, registry, gc/reclamation, orphans, clones)
12
+ // CLI bindings: schedule *, cw loop, routine *, sched *, registry *,
13
+ // queue *, gc *, orphans *, clones *, run search|list|show|resume|
14
+ // archive|rerun, history. Handler BODIES live in shell/registry-cli.ts,
15
+ // shell/scheduler-io.ts, shell/scheduling-io.ts, shell/reclamation-io.ts,
16
+ // shell/run-registry-io.ts (impure — disk-scanning IO); this table only
17
+ // wires argv shape -> handler call, per cli/dispatch.ts's generic
18
+ // executor contract. Usage-error strings are copied byte-for-byte from
19
+ // the old build's handlers/{scheduling,registry,maintenance,orphans,
20
+ // clones}.ts.
21
+ // ---------------------------------------------------------------------
22
+ // This whole module is required unconditionally at CLI/MCP startup for
23
+ // EVERY command; loading these 4 shell modules lazily (only inside the
24
+ // handler that actually calls into them) keeps that load cost off every
25
+ // invocation that never touches schedule/routine/sched/registry/queue/
26
+ // gc/orphans/clones/run/history.
27
+ function loadRegistryCli() {
28
+ return require("../../shell/registry-cli");
29
+ }
30
+ function loadReclamationIo() {
31
+ return require("../../shell/reclamation-io");
32
+ }
33
+ function loadRunRegistryIo() {
34
+ return require("../../shell/run-registry-io");
35
+ }
36
+ function loadSchedulingIo() {
37
+ return require("../../shell/scheduling-io");
38
+ }
39
+ function firstPositionalArg(args, index = 0) {
40
+ return args.positionals[index];
41
+ }
42
+ // ---- schedule (+ cw loop) ----------------------------------------------
43
+ (0, registry_core_1.addCliOnlyCapability)("loop", 'cw loop — sugar for "schedule create --kind loop".', {
44
+ path: ["loop"],
45
+ jsonMode: "default",
46
+ handler: (args) => ({ json: loadRegistryCli().scheduleCreateCli({ ...args.options, kind: "loop" }) }),
47
+ }, "loop is CLI-only sugar over schedule.create; the old build never gave it an MCP tool of its own (SPEC/scheduling-registry.md section I).");
48
+ (0, registry_core_1.addCliOnlyCapability)("schedule", "cw schedule create|list|delete|due|complete|pause|resume|run-now|history|daemon — the wall-clock scheduler.", {
49
+ path: ["schedule"],
50
+ jsonMode: "default",
51
+ hiddenFromHelp: true,
52
+ handler: (args) => {
53
+ const [subcommand, id] = args.positionals;
54
+ const registryCli = loadRegistryCli();
55
+ switch (subcommand) {
56
+ case "create":
57
+ return { json: registryCli.scheduleCreateCli(args.options) };
58
+ case "list":
59
+ return { json: registryCli.scheduleListCli(args.options) };
60
+ case "delete":
61
+ return { json: registryCli.scheduleDeleteCli((0, io_1.required)(id, "schedule id"), args.options) };
62
+ case "due":
63
+ return { json: registryCli.scheduleDueCli(args.options) };
64
+ case "complete":
65
+ return { json: registryCli.scheduleCompleteCli((0, io_1.required)(id, "schedule id"), args.options) };
66
+ case "pause":
67
+ return { json: registryCli.schedulePauseCli((0, io_1.required)(id, "schedule id"), args.options) };
68
+ case "resume":
69
+ return { json: registryCli.scheduleResumeCli((0, io_1.required)(id, "schedule id"), args.options) };
70
+ case "run-now":
71
+ return { json: registryCli.scheduleRunNowCli((0, io_1.required)(id, "schedule id"), args.options) };
72
+ case "history":
73
+ return { json: registryCli.scheduleHistoryCli(id, args.options) };
74
+ case "daemon": {
75
+ if (args.options.once)
76
+ return { json: registryCli.scheduleDaemonTickCli(args.options) };
77
+ // Never returns (matches the old build's forever daemon loop);
78
+ // the process stays alive via the DesktopSchedulerDaemon's own
79
+ // setInterval, printing one tick line per interval.
80
+ void registryCli.scheduleDaemonRunForever(args.options);
81
+ return {};
82
+ }
83
+ default:
84
+ throw new Error("Usage: cw schedule create|list|delete|due|complete|pause|resume|run-now|history|daemon");
85
+ }
86
+ },
87
+ }, "cw schedule is the desktop wall-clock scheduler; SPEC/mcp.md declares its MCP peers per verb (cw_schedule_*), each wired below.");
88
+ // GAP #24: the cw_schedule_* MCP peers were declared but left on the
89
+ // notYetImplemented placeholder (the "each wired below" comment was never
90
+ // satisfied). Mirror the CLI switch's shell fns; arg-name reads (id/status)
91
+ // copied from the old build's mcp/tool-call.ts scheduler arms.
92
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.create").mcp.handler = (args) => loadRegistryCli().scheduleCreateCli(args);
93
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.list").mcp.handler = (args) => loadRegistryCli().scheduleListCli(args);
94
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.due").mcp.handler = (args) => loadRegistryCli().scheduleDueCli(args);
95
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.complete").mcp.handler = (args) => loadRegistryCli().scheduleCompleteCli((0, io_1.required)((0, io_1.optionalArg)(args.id), "schedule id"), args);
96
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.pause").mcp.handler = (args) => loadRegistryCli().schedulePauseCli((0, io_1.required)((0, io_1.optionalArg)(args.id), "schedule id"), args);
97
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.resume").mcp.handler = (args) => loadRegistryCli().scheduleResumeCli((0, io_1.required)((0, io_1.optionalArg)(args.id), "schedule id"), args);
98
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.run-now").mcp.handler = (args) => loadRegistryCli().scheduleRunNowCli((0, io_1.required)((0, io_1.optionalArg)(args.id), "schedule id"), args);
99
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.history").mcp.handler = (args) => loadRegistryCli().scheduleHistoryCli((0, io_1.optionalArg)(args.id), args);
100
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("schedule.delete").mcp.handler = (args) => loadRegistryCli().scheduleDeleteCli((0, io_1.required)((0, io_1.optionalArg)(args.id), "schedule id"), args);
101
+ // Each `schedule <verb>` sub-action is its own two-token cli row (found
102
+ // before the ["schedule"] catch-all per the reversed candidate order), so
103
+ // each capability is a real both-surface dual-bound row. Same shell fns and
104
+ // [subcommand, id] positional mapping as the catch-all switch above.
105
+ // `hiddenFromHelp` keeps `cw help schedule`'s rows coming from the single
106
+ // literal COMMAND_HELP_ROWS.schedule block.
107
+ (0, registry_core_1.attachCliBinding)("schedule.create", { path: ["schedule", "create"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().scheduleCreateCli(args.options) }) });
108
+ (0, registry_core_1.attachCliBinding)("schedule.list", { path: ["schedule", "list"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().scheduleListCli(args.options) }) });
109
+ (0, registry_core_1.attachCliBinding)("schedule.delete", { path: ["schedule", "delete"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().scheduleDeleteCli((0, io_1.required)(args.positionals[0], "schedule id"), args.options) }) });
110
+ (0, registry_core_1.attachCliBinding)("schedule.due", { path: ["schedule", "due"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().scheduleDueCli(args.options) }) });
111
+ (0, registry_core_1.attachCliBinding)("schedule.complete", { path: ["schedule", "complete"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().scheduleCompleteCli((0, io_1.required)(args.positionals[0], "schedule id"), args.options) }) });
112
+ (0, registry_core_1.attachCliBinding)("schedule.pause", { path: ["schedule", "pause"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().schedulePauseCli((0, io_1.required)(args.positionals[0], "schedule id"), args.options) }) });
113
+ (0, registry_core_1.attachCliBinding)("schedule.resume", { path: ["schedule", "resume"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().scheduleResumeCli((0, io_1.required)(args.positionals[0], "schedule id"), args.options) }) });
114
+ (0, registry_core_1.attachCliBinding)("schedule.run-now", { path: ["schedule", "run-now"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().scheduleRunNowCli((0, io_1.required)(args.positionals[0], "schedule id"), args.options) }) });
115
+ (0, registry_core_1.attachCliBinding)("schedule.history", { path: ["schedule", "history"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().scheduleHistoryCli(args.positionals[0], args.options) }) });
116
+ // ---- routine ------------------------------------------------------------
117
+ (0, registry_core_1.addCliOnlyCapability)("routine", "cw routine create|list|delete|fire|events — API/GitHub-style triggers.", {
118
+ path: ["routine"],
119
+ jsonMode: "default",
120
+ hiddenFromHelp: true,
121
+ handler: (args) => {
122
+ const [subcommand, idOrKind, payloadPath] = args.positionals;
123
+ const registryCli = loadRegistryCli();
124
+ switch (subcommand) {
125
+ case "create":
126
+ return { json: registryCli.routineCreateCli(args.options) };
127
+ case "list":
128
+ return { json: registryCli.routineListCli(args.options) };
129
+ case "delete":
130
+ return { json: registryCli.routineDeleteCli((0, io_1.required)(idOrKind, "trigger id"), args.options) };
131
+ case "fire": {
132
+ const kind = (0, io_1.required)(idOrKind, "trigger kind");
133
+ const payload = registryCli.resolveRoutineFirePayload(payloadPath, args.options);
134
+ return { json: registryCli.routineFireCli(kind, payload, args.options) };
135
+ }
136
+ case "events":
137
+ return { json: registryCli.routineEventsCli(idOrKind, args.options) };
138
+ default:
139
+ throw new Error("Usage: cw routine create|list|delete|fire|events");
140
+ }
141
+ },
142
+ }, "cw routine is the API/GitHub-style trigger bridge; SPEC/mcp.md declares its MCP peers per verb (cw_routine_*), each wired below.");
143
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("routine.create").mcp.handler = (args) => loadRegistryCli().routineCreateCli(args);
144
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("routine.list").mcp.handler = (args) => loadRegistryCli().routineListCli(args);
145
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("routine.delete").mcp.handler = (args) => loadRegistryCli().routineDeleteCli((0, io_1.required)((0, io_1.optionalArg)(args.id), "trigger id"), args);
146
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("routine.fire").mcp.handler = (args) => loadRegistryCli().routineFireCli((0, io_1.required)((0, io_1.optionalArg)(args.kind), "trigger kind"), args.payload, args);
147
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("routine.events").mcp.handler = (args) => loadRegistryCli().routineEventsCli((0, io_1.optionalArg)(args.id), args);
148
+ // Each `routine <verb>` sub-action is its own two-token cli row. The
149
+ // catch-all read [subcommand, idOrKind, payloadPath], so after the
150
+ // dispatcher consumes the sub-verb positionals[0]=idOrKind,
151
+ // positionals[1]=payloadPath. `hiddenFromHelp` keeps `cw help routine`'s
152
+ // rows coming from the single literal COMMAND_HELP_ROWS.routine block.
153
+ (0, registry_core_1.attachCliBinding)("routine.create", { path: ["routine", "create"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().routineCreateCli(args.options) }) });
154
+ (0, registry_core_1.attachCliBinding)("routine.list", { path: ["routine", "list"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().routineListCli(args.options) }) });
155
+ (0, registry_core_1.attachCliBinding)("routine.delete", { path: ["routine", "delete"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().routineDeleteCli((0, io_1.required)(args.positionals[0], "trigger id"), args.options) }) });
156
+ (0, registry_core_1.attachCliBinding)("routine.fire", {
157
+ path: ["routine", "fire"],
158
+ jsonMode: "default",
159
+ hiddenFromHelp: true,
160
+ handler: (args) => {
161
+ const kind = (0, io_1.required)(args.positionals[0], "trigger kind");
162
+ const payloadPath = args.positionals[1];
163
+ const registryCli = loadRegistryCli();
164
+ const payload = registryCli.resolveRoutineFirePayload(payloadPath, args.options);
165
+ return { json: registryCli.routineFireCli(kind, payload, args.options) };
166
+ },
167
+ });
168
+ (0, registry_core_1.attachCliBinding)("routine.events", { path: ["routine", "events"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadRegistryCli().routineEventsCli(args.positionals[0], args.options) }) });
169
+ // ---- sched (control-plane leases over the durable queue) ---------------
170
+ (0, registry_core_1.addCliOnlyCapability)("sched", "cw sched plan|lease|release|complete|reclaim|reset|policy [show|set] — control-plane lease scheduling over the durable queue.", {
171
+ path: ["sched"],
172
+ jsonMode: "default",
173
+ hiddenFromHelp: true,
174
+ handler: (args) => {
175
+ const [subcommand, idArg] = args.positionals;
176
+ const schedulingIo = loadSchedulingIo();
177
+ switch (subcommand) {
178
+ case "plan":
179
+ return { json: schedulingIo.schedPlanCli(args.options) };
180
+ case "lease":
181
+ return { json: schedulingIo.schedLeaseCli(args.options) };
182
+ case "release":
183
+ return { json: schedulingIo.schedReleaseCli(String(args.options.leaseId || idArg || ""), args.options) };
184
+ case "complete":
185
+ return { json: schedulingIo.schedCompleteCli(String(args.options.leaseId || idArg || ""), args.options) };
186
+ case "reclaim":
187
+ return { json: schedulingIo.schedReclaimCli(args.options) };
188
+ case "reset":
189
+ return { json: schedulingIo.schedResetCli(String(args.options.id || idArg || ""), args.options) };
190
+ case "policy": {
191
+ const action = args.positionals[1];
192
+ if (action === "set")
193
+ return { json: schedulingIo.schedPolicySetCli(args.options) };
194
+ return { json: schedulingIo.schedPolicyShowCli(args.options) };
195
+ }
196
+ default:
197
+ throw new Error("Usage: cw sched plan|lease|release|complete|reclaim|reset|policy [show|set] [id] [--maxConcurrent N --maxAttempts N ...]");
198
+ }
199
+ },
200
+ }, "cw sched is the durable-queue lease scheduler; SPEC/mcp.md declares its MCP peers per verb (cw_sched_*), each wired below.");
201
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("sched.plan").mcp.handler = (args) => loadSchedulingIo().schedPlanCli(args);
202
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("sched.lease").mcp.handler = (args) => loadSchedulingIo().schedLeaseCli(args);
203
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("sched.release").mcp.handler = (args) => loadSchedulingIo().schedReleaseCli(String(args.leaseId || ""), args);
204
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("sched.complete").mcp.handler = (args) => loadSchedulingIo().schedCompleteCli(String(args.leaseId || ""), args);
205
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("sched.reclaim").mcp.handler = (args) => loadSchedulingIo().schedReclaimCli(args);
206
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("sched.reset").mcp.handler = (args) => loadSchedulingIo().schedResetCli(String(args.id || ""), args);
207
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("sched.policy.show").mcp.handler = (args) => loadSchedulingIo().schedPolicyShowCli(args);
208
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("sched.policy.set").mcp.handler = (args) => loadSchedulingIo().schedPolicySetCli(args);
209
+ // Each `sched <verb>` sub-action is its own two-token cli row. The
210
+ // catch-all read [subcommand, idArg]; after the dispatcher consumes the
211
+ // sub-verb, positionals[0]=idArg (release/complete read --leaseId or that
212
+ // positional; reset reads --id or that positional). `sched.policy.show`/
213
+ // `.set` share the ["sched","policy"] path with the [show|set] action read
214
+ // from the first positional (like blackboard.message.post/list).
215
+ // `hiddenFromHelp` keeps `cw help sched`'s rows coming from the single
216
+ // literal COMMAND_HELP_ROWS.sched block.
217
+ (0, registry_core_1.attachCliBinding)("sched.plan", { path: ["sched", "plan"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadSchedulingIo().schedPlanCli(args.options) }) });
218
+ (0, registry_core_1.attachCliBinding)("sched.lease", { path: ["sched", "lease"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadSchedulingIo().schedLeaseCli(args.options) }) });
219
+ (0, registry_core_1.attachCliBinding)("sched.release", { path: ["sched", "release"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadSchedulingIo().schedReleaseCli(String(args.options.leaseId || args.positionals[0] || ""), args.options) }) });
220
+ (0, registry_core_1.attachCliBinding)("sched.complete", { path: ["sched", "complete"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadSchedulingIo().schedCompleteCli(String(args.options.leaseId || args.positionals[0] || ""), args.options) }) });
221
+ (0, registry_core_1.attachCliBinding)("sched.reclaim", { path: ["sched", "reclaim"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadSchedulingIo().schedReclaimCli(args.options) }) });
222
+ (0, registry_core_1.attachCliBinding)("sched.reset", { path: ["sched", "reset"], jsonMode: "default", hiddenFromHelp: true, handler: (args) => ({ json: loadSchedulingIo().schedResetCli(String(args.options.id || args.positionals[0] || ""), args.options) }) });
223
+ function schedPolicyHandler(args) {
224
+ const action = args.positionals[0];
225
+ const schedulingIo = loadSchedulingIo();
226
+ if (action === "set")
227
+ return { json: schedulingIo.schedPolicySetCli(args.options) };
228
+ return { json: schedulingIo.schedPolicyShowCli(args.options) };
229
+ }
230
+ (0, registry_core_1.attachCliBinding)("sched.policy.show", { path: ["sched", "policy"], helpPath: ["sched", "policy"], jsonMode: "default", hiddenFromHelp: true, handler: schedPolicyHandler });
231
+ (0, registry_core_1.attachCliBinding)("sched.policy.set", { path: ["sched", "policy"], helpPath: ["sched", "policy"], jsonMode: "default", hiddenFromHelp: true, handler: schedPolicyHandler });
232
+ // ---- registry (refresh|show) --------------------------------------------
233
+ (0, registry_core_1.addCliOnlyCapability)("registry", "cw registry refresh|show [--scope repo|home] [--json] — the derived run registry index.", {
234
+ path: ["registry"],
235
+ jsonMode: "flag",
236
+ hiddenFromHelp: true,
237
+ handler: (args) => {
238
+ const subcommand = firstPositionalArg(args);
239
+ const registryCli = loadRegistryCli();
240
+ let report;
241
+ if (subcommand === "refresh")
242
+ report = registryCli.registryRefreshCli(args.options);
243
+ else if (subcommand === "show")
244
+ report = registryCli.registryShowCli(args.options);
245
+ else
246
+ throw new Error("Usage: cw registry refresh|show [--scope repo|home] [--json]");
247
+ return { json: report, text: loadRunRegistryIo().formatRegistryReport(report) };
248
+ },
249
+ }, "cw registry is the derived run-registry index; SPEC/mcp.md declares its MCP peers (cw_registry_refresh|show), each wired below.");
250
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("registry.refresh").mcp.handler = (args) => loadRegistryCli().registryRefreshCli(args);
251
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("registry.show").mcp.handler = (args) => loadRegistryCli().registryShowCli(args);
252
+ // `registry.refresh`/`registry.show` each carry their own two-token
253
+ // cli.path (found before the ["registry"] catch-all). `hiddenFromHelp`
254
+ // keeps `cw help registry`'s rows coming from the single literal
255
+ // COMMAND_HELP_ROWS.registry block. Both are read/derive verbs, so they
256
+ // stay in the payload-identity probe (classified deferred until a
257
+ // bootstrap fixture seeds a registry index).
258
+ (0, registry_core_1.attachCliBinding)("registry.refresh", {
259
+ path: ["registry", "refresh"],
260
+ jsonMode: "flag",
261
+ hiddenFromHelp: true,
262
+ handler: (args) => {
263
+ const report = loadRegistryCli().registryRefreshCli(args.options);
264
+ return (0, io_1.wantsJson)(args.options) ? { json: report } : { json: report, text: loadRunRegistryIo().formatRegistryReport(report) };
265
+ },
266
+ });
267
+ (0, registry_core_1.attachCliBinding)("registry.show", {
268
+ path: ["registry", "show"],
269
+ jsonMode: "flag",
270
+ hiddenFromHelp: true,
271
+ handler: (args) => {
272
+ const report = loadRegistryCli().registryShowCli(args.options);
273
+ return (0, io_1.wantsJson)(args.options) ? { json: report } : { json: report, text: loadRunRegistryIo().formatRegistryReport(report) };
274
+ },
275
+ });
276
+ // ---- queue (add|list|drain|show) ----------------------------------------
277
+ (0, registry_core_1.addCliOnlyCapability)("queue", "cw queue add|list|drain|show [queue-id] [--repo PATH] [--priority N] — the durable run queue.", {
278
+ path: ["queue"],
279
+ jsonMode: "flag",
280
+ hiddenFromHelp: true,
281
+ handler: (args) => {
282
+ const [subcommand, id] = args.positionals;
283
+ const registryCli = loadRegistryCli();
284
+ switch (subcommand) {
285
+ case "add":
286
+ return { json: registryCli.queueAddCli(args.options) };
287
+ case "list": {
288
+ const result = registryCli.queueListCli(args.options);
289
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: loadRunRegistryIo().formatQueueList(result) };
290
+ }
291
+ case "drain":
292
+ return { json: registryCli.queueDrainCli(args.options) };
293
+ case "show":
294
+ return { json: registryCli.queueShowCli((0, io_1.required)(id, "queue id"), args.options) };
295
+ default:
296
+ throw new Error("Usage: cw queue add|list|drain|show [queue-id] [--repo PATH] [--priority N]");
297
+ }
298
+ },
299
+ }, "cw queue is the durable run queue; SPEC/mcp.md declares its MCP peers (cw_queue_add|list|drain|show), each wired below.");
300
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("queue.add").mcp.handler = (args) => loadRegistryCli().queueAddCli(args);
301
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("queue.list").mcp.handler = (args) => loadRegistryCli().queueListCli(args);
302
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("queue.drain").mcp.handler = (args) => loadRegistryCli().queueDrainCli(args);
303
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("queue.show").mcp.handler = (args) => loadRegistryCli().queueShowCli((0, io_1.required)((0, io_1.optionalArg)(args.id), "queue id"), args);
304
+ // `queue add|list|drain|show` each carry their own two-token cli.path
305
+ // (found before the ["queue"] catch-all). `hiddenFromHelp` keeps `cw help
306
+ // queue`'s rows coming from the single literal COMMAND_HELP_ROWS.queue
307
+ // block. `queue.list` is jsonMode "flag" (human table by default); the
308
+ // others are always-JSON "default", matching the old build's registry.
309
+ (0, registry_core_1.attachCliBinding)("queue.add", {
310
+ path: ["queue", "add"],
311
+ jsonMode: "default",
312
+ hiddenFromHelp: true,
313
+ handler: (args) => ({ json: loadRegistryCli().queueAddCli(args.options) }),
314
+ });
315
+ (0, registry_core_1.attachCliBinding)("queue.list", {
316
+ path: ["queue", "list"],
317
+ jsonMode: "flag",
318
+ hiddenFromHelp: true,
319
+ handler: (args) => {
320
+ const result = loadRegistryCli().queueListCli(args.options);
321
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: loadRunRegistryIo().formatQueueList(result) };
322
+ },
323
+ });
324
+ (0, registry_core_1.attachCliBinding)("queue.drain", {
325
+ path: ["queue", "drain"],
326
+ jsonMode: "default",
327
+ hiddenFromHelp: true,
328
+ handler: (args) => ({ json: loadRegistryCli().queueDrainCli(args.options) }),
329
+ });
330
+ (0, registry_core_1.attachCliBinding)("queue.show", {
331
+ path: ["queue", "show"],
332
+ jsonMode: "default",
333
+ hiddenFromHelp: true,
334
+ handler: (args) => ({ json: loadRegistryCli().queueShowCli((0, io_1.required)(args.positionals[0], "queue id"), args.options) }),
335
+ });
336
+ // ---- gc (plan|run|verify) ------------------------------------------------
337
+ (0, registry_core_1.addCliOnlyCapability)("gc", "cw gc plan|run|verify [run-id] [--reclaimAfterArchiveDays N] [--keep-scratch] [--keep-snapshots] [--limit N] [--json] — run retention & provable reclamation.", {
338
+ path: ["gc"],
339
+ jsonMode: "flag",
340
+ hiddenFromHelp: true,
341
+ handler: (args) => {
342
+ const [subcommand, id] = args.positionals;
343
+ const registryCli = loadRegistryCli();
344
+ const reclamationIo = loadReclamationIo();
345
+ switch (subcommand) {
346
+ case "plan": {
347
+ const result = registryCli.gcPlanCli(id, args.options);
348
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: reclamationIo.formatGcPlan(result) };
349
+ }
350
+ case "run": {
351
+ const result = registryCli.gcRunCli(id, args.options);
352
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: reclamationIo.formatGcRun(result) };
353
+ }
354
+ case "verify": {
355
+ const result = registryCli.gcVerifyCli((0, io_1.required)(id, "run id"), args.options);
356
+ const text = reclamationIo.formatGcVerify(result);
357
+ return { json: result, text, exitCode: result.reclaimed && !result.verified ? 1 : undefined };
358
+ }
359
+ default:
360
+ throw new Error("Usage: cw gc plan|run|verify [run-id] [--reclaimAfterArchiveDays N] [--keep-scratch] [--keep-snapshots] [--limit N] [--json]");
361
+ }
362
+ },
363
+ }, "cw gc is run retention & provable reclamation; SPEC/mcp.md declares its MCP peers (cw_gc_plan|run|verify), each wired below.");
364
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("gc.plan").mcp.handler = (args) => loadRegistryCli().gcPlanCli((0, io_1.optionalArg)(args.runId), args);
365
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("gc.run").mcp.handler = (args) => loadRegistryCli().gcRunCli((0, io_1.optionalArg)(args.runId), args);
366
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("gc.verify").mcp.handler = (args) => loadRegistryCli().gcVerifyCli((0, io_1.required)((0, io_1.optionalArg)(args.runId), "run id"), args);
367
+ // PARITY: `gc.run` frees disk and appends a tombstone; both surfaces run
368
+ // the identical transaction but the payload reports now-derived
369
+ // bytesFreed/tombstone, so it is a documented opt-out, not drift.
370
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("gc.run").payloadIdentical = false;
371
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("gc.run").reason =
372
+ "Mutating: frees disk and appends a tombstone; both surfaces perform the identical transaction but the payload reports now-derived bytesFreed/tombstone.";
373
+ // PARITY: `gc.plan`/`gc.verify` now ALSO carry their own two-token
374
+ // cli.path ["gc","plan"]/["gc","verify"], same as the old build's
375
+ // registry rows and the same reversed-candidate-order pattern used for
376
+ // run.drive/run.search above: findCapabilityByCliPath tries the 2-token
377
+ // candidate before the 1-token ["gc"] catch-all row, so these rows — not
378
+ // the "gc" capability's combined switch — now serve `cw gc plan`/`cw gc
379
+ // verify`. Same functions, same output; only which row answers the
380
+ // dispatch changes, so both become real both-surface, dual-bound
381
+ // capabilities for the payload-identity probe. `gc.run` stays reachable
382
+ // only via the ["gc"] catch-all (it is a documented payload-probe
383
+ // opt-out above, so it does not need its own dual-bound row).
384
+ // `hiddenFromHelp` keeps `cw help gc`'s rows coming from the single
385
+ // literal COMMAND_HELP_ROWS.gc entries, same as `gc.run` below — without
386
+ // it these rows double-print alongside those literal rows (a rebuild
387
+ // regression the old build's `docs/rebuild/SPEC/cli-help/gc.txt` ground
388
+ // truth does not show; fixed here to match `gc.run`'s existing pattern).
389
+ (0, registry_core_1.attachCliBinding)("gc.plan", {
390
+ path: ["gc", "plan"],
391
+ jsonMode: "flag",
392
+ hiddenFromHelp: true,
393
+ handler: (args) => {
394
+ const result = loadRegistryCli().gcPlanCli(args.positionals[0], args.options);
395
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: loadReclamationIo().formatGcPlan(result) };
396
+ },
397
+ });
398
+ (0, registry_core_1.attachCliBinding)("gc.verify", {
399
+ path: ["gc", "verify"],
400
+ jsonMode: "flag",
401
+ hiddenFromHelp: true,
402
+ handler: (args) => {
403
+ const result = loadRegistryCli().gcVerifyCli((0, io_1.required)(args.positionals[0], "run id"), args.options);
404
+ const text = loadReclamationIo().formatGcVerify(result);
405
+ return { json: result, text, exitCode: result.reclaimed && !result.verified ? 1 : undefined };
406
+ },
407
+ });
408
+ // `gc.run` also carries its own two-token cli.path ["gc","run"], same
409
+ // reversed-candidate-order pattern as gc.plan/gc.verify. It stays a
410
+ // documented payload-probe opt-out (mutating reclamation), so this row
411
+ // only satisfies the both-surface "cli + mcp" pairing — it does not join
412
+ // the payload-identity probe. `hiddenFromHelp` keeps `cw help gc`'s row
413
+ // coming from the single literal COMMAND_HELP_ROWS.gc entry.
414
+ (0, registry_core_1.attachCliBinding)("gc.run", {
415
+ path: ["gc", "run"],
416
+ jsonMode: "flag",
417
+ hiddenFromHelp: true,
418
+ handler: (args) => {
419
+ const result = loadRegistryCli().gcRunCli(args.positionals[0], args.options);
420
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: loadReclamationIo().formatGcRun(result) };
421
+ },
422
+ });
423
+ // ---- orphans (list|gc) ---------------------------------------------------
424
+ (0, registry_core_1.addCliOnlyCapability)("orphans", "cw orphans list|gc — reclaim run directories a killed process never registered (no state.json).", {
425
+ path: ["orphans"],
426
+ jsonMode: "flag",
427
+ hiddenFromHelp: true,
428
+ handler: (args) => {
429
+ const subcommand = firstPositionalArg(args);
430
+ const registryCli = loadRegistryCli();
431
+ const reclamationIo = loadReclamationIo();
432
+ switch (subcommand) {
433
+ case "list": {
434
+ const result = registryCli.orphansListCli(args.options);
435
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: reclamationIo.formatOrphanRunsList(result) };
436
+ }
437
+ case "gc": {
438
+ const result = registryCli.orphansGcCli(args.options);
439
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: reclamationIo.formatOrphanRunsGc(result) };
440
+ }
441
+ default:
442
+ throw new Error("Usage: cw orphans list [--scope repo|home] [--json] | orphans gc [--scope repo|home] [--min-age-minutes N] [--all] [--json] (scope defaults to home: every registered repo)");
443
+ }
444
+ },
445
+ }, "cw orphans reclaims killed-process run dirs with no state.json; SPEC/mcp.md declares its MCP peers (cw_orphans_list|gc), each wired below.");
446
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("orphans.list").mcp.handler = (args) => loadRegistryCli().orphansListCli(args);
447
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("orphans.gc").mcp.handler = (args) => loadRegistryCli().orphansGcCli(args);
448
+ // `orphans.list`/`orphans.gc` each carry their own two-token cli.path
449
+ // (found before the ["orphans"] catch-all per the reversed-candidate
450
+ // order), so both are real both-surface dual-bound rows. `hiddenFromHelp`
451
+ // keeps `cw help orphans`'s rows coming from the single literal
452
+ // COMMAND_HELP_ROWS.orphans block. `orphans.gc` is a documented
453
+ // payload-probe opt-out (mutating sweep, now-derived freedBytes/removed),
454
+ // same as gc.run/clones.gc.
455
+ (0, registry_core_1.attachCliBinding)("orphans.list", {
456
+ path: ["orphans", "list"],
457
+ jsonMode: "flag",
458
+ hiddenFromHelp: true,
459
+ handler: (args) => {
460
+ const result = loadRegistryCli().orphansListCli(args.options);
461
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: loadReclamationIo().formatOrphanRunsList(result) };
462
+ },
463
+ });
464
+ (0, registry_core_1.attachCliBinding)("orphans.gc", {
465
+ path: ["orphans", "gc"],
466
+ jsonMode: "flag",
467
+ hiddenFromHelp: true,
468
+ handler: (args) => {
469
+ const result = loadRegistryCli().orphansGcCli(args.options);
470
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: loadReclamationIo().formatOrphanRunsGc(result) };
471
+ },
472
+ });
473
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("orphans.gc").payloadIdentical = false;
474
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("orphans.gc").reason =
475
+ "Mutating: removes orphan run directories and reports now-derived freedBytes/removed; both surfaces perform the identical sweep.";
476
+ // ---- clones (list|gc) ------------------------------------------------------
477
+ (0, registry_core_1.addCliOnlyCapability)("clones", "cw clones list|gc [--older-than-days N] [--all] — the cached remote-source checkout cache.", {
478
+ path: ["clones"],
479
+ jsonMode: "flag",
480
+ hiddenFromHelp: true,
481
+ handler: (args) => {
482
+ const subcommand = firstPositionalArg(args);
483
+ const registryCli = loadRegistryCli();
484
+ const reclamationIo = loadReclamationIo();
485
+ switch (subcommand) {
486
+ case "list": {
487
+ const result = registryCli.clonesListCli();
488
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: reclamationIo.formatClonesList(result) };
489
+ }
490
+ case "gc": {
491
+ const result = registryCli.clonesGcCli(args.options);
492
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: reclamationIo.formatClonesGc(result) };
493
+ }
494
+ default:
495
+ throw new Error("Usage: cw clones list [--json] | clones gc [--older-than-days N] [--all] [--json]");
496
+ }
497
+ },
498
+ }, "cw clones is the cached remote-source checkout cache; SPEC/mcp.md declares its MCP peers (cw_clones_list|gc), each wired below.");
499
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("clones.list").mcp.handler = () => loadRegistryCli().clonesListCli();
500
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("clones.gc").mcp.handler = (args) => loadRegistryCli().clonesGcCli(args);
501
+ // `clones.list`/`clones.gc` each carry their own two-token cli.path (found
502
+ // before the ["clones"] catch-all). `hiddenFromHelp` keeps the byte-pinned
503
+ // `cw help clones` fixture's rows coming from the single literal
504
+ // COMMAND_HELP_ROWS.clones block. `clones.gc` is a documented payload-probe
505
+ // opt-out (mutating sweep), same as gc.run/orphans.gc.
506
+ (0, registry_core_1.attachCliBinding)("clones.list", {
507
+ path: ["clones", "list"],
508
+ jsonMode: "flag",
509
+ hiddenFromHelp: true,
510
+ handler: (args) => {
511
+ const result = loadRegistryCli().clonesListCli();
512
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: loadReclamationIo().formatClonesList(result) };
513
+ },
514
+ });
515
+ (0, registry_core_1.attachCliBinding)("clones.gc", {
516
+ path: ["clones", "gc"],
517
+ jsonMode: "flag",
518
+ hiddenFromHelp: true,
519
+ handler: (args) => {
520
+ const result = loadRegistryCli().clonesGcCli(args.options);
521
+ return (0, io_1.wantsJson)(args.options) ? { json: result } : { json: result, text: loadReclamationIo().formatClonesGc(result) };
522
+ },
523
+ });
524
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("clones.gc").payloadIdentical = false;
525
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("clones.gc").reason =
526
+ "Mutating: removes cache directories and reports now-derived freedBytes/removed; both surfaces perform the identical reclamation.";
527
+ // ---- run search|list|show|resume|archive|rerun (2-token rows, found
528
+ // BEFORE the 1-token run.drive.step row per dispatchTable's reversed
529
+ // candidate order — see that row's own comment for why the run-registry
530
+ // keyword guard set still lists these words) --------------------------
531
+ (0, registry_core_1.attachCliBinding)("run.search", {
532
+ path: ["run", "search"],
533
+ jsonMode: "flag",
534
+ handler: (args) => {
535
+ const result = loadRegistryCli().runSearchCli(args.options);
536
+ return { json: result, text: loadRunRegistryIo().formatRunSearch(result) };
537
+ },
538
+ });
539
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("run.search").mcp.handler = (args) => loadRegistryCli().runSearchCli(args);
540
+ (0, registry_core_1.attachCliBinding)("run.list", {
541
+ path: ["run", "list"],
542
+ jsonMode: "flag",
543
+ handler: (args) => {
544
+ const result = loadRegistryCli().runListCli(args.options);
545
+ return { json: result, text: loadRunRegistryIo().formatRunSearch(result) };
546
+ },
547
+ });
548
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("run.list").mcp.handler = (args) => loadRegistryCli().runListCli(args);
549
+ (0, registry_core_1.attachCliBinding)("run.show", {
550
+ path: ["run", "show"],
551
+ jsonMode: "flag",
552
+ handler: (args) => {
553
+ const runId = (0, io_1.required)(args.positionals[0], "run id");
554
+ const result = loadRegistryCli().runShowCli(runId, args.options);
555
+ return { json: result, text: loadRunRegistryIo().formatRunShow(result) };
556
+ },
557
+ });
558
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("run.show").mcp.handler = (args) => loadRegistryCli().runShowCli((0, io_1.required)((0, io_1.optionalArg)(args.runId), "run id"), args);
559
+ (0, registry_core_1.attachCliBinding)("run.resume", {
560
+ path: ["run", "resume"],
561
+ jsonMode: "flag",
562
+ handler: async (args) => {
563
+ const runId = (0, io_1.required)(args.positionals[0], "run id");
564
+ const runRegistryIo = loadRunRegistryIo();
565
+ const result = await loadRegistryCli().runResumeCli(runId, args.options);
566
+ return { json: result, text: runRegistryIo.formatResume(result) };
567
+ },
568
+ });
569
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("run.resume").mcp.handler = (args) => loadRegistryCli().runResumeCli((0, io_1.required)((0, io_1.optionalArg)(args.runId), "run id"), args);
570
+ (0, registry_core_1.attachCliBinding)("run.archive", {
571
+ path: ["run", "archive"],
572
+ jsonMode: "default",
573
+ handler: (args) => ({ json: loadRegistryCli().runArchiveCli((0, io_1.optionalArg)(args.positionals[0]), args.options) }),
574
+ });
575
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("run.archive").mcp.handler = (args) => loadRegistryCli().runArchiveCli((0, io_1.optionalArg)(args.runId), args);
576
+ (0, registry_core_1.attachCliBinding)("run.rerun", {
577
+ path: ["run", "rerun"],
578
+ jsonMode: "default",
579
+ handler: (args) => ({ json: loadRegistryCli().runRerunCli((0, io_1.required)(args.positionals[0], "run id"), args.options) }),
580
+ });
581
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("run.rerun").mcp.handler = (args) => loadRegistryCli().runRerunCli((0, io_1.required)((0, io_1.optionalArg)(args.runId), "run id"), args);
582
+ // ---- history ---------------------------------------------------------
583
+ (0, registry_core_1.attachCliBinding)("history", {
584
+ path: ["history"],
585
+ jsonMode: "flag",
586
+ handler: (args) => {
587
+ const result = loadRegistryCli().historyCli(args.options);
588
+ return { json: result, text: loadRunRegistryIo().formatHistory(result) };
589
+ },
590
+ });
591
+ registry_core_1.REGISTRY_BY_CAPABILITY.get("history").mcp.handler = (args) => loadRegistryCli().historyCli(args);
592
+ // ---------------------------------------------------------------------