cool-workflow 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.gemini-plugin/mcp.json +10 -0
- package/.gemini-plugin/plugin.json +40 -0
- package/.opencode-plugin/mcp.json +10 -0
- package/.opencode-plugin/plugin.json +40 -0
- package/README.md +202 -48
- package/apps/architecture-review/app.json +1 -1
- package/apps/architecture-review-fast/app.json +1 -1
- package/apps/end-to-end-golden-path/app.json +1 -1
- package/apps/pr-review-fix-ci/app.json +1 -1
- package/apps/release-cut/app.json +1 -1
- package/apps/research-synthesis/app.json +1 -1
- package/dist/cli/dispatch.js +33 -4
- package/dist/cli/entry.js +11 -19
- package/dist/cli/global-flags.js +113 -0
- package/dist/cli/io.js +6 -20
- package/dist/cli/parseargv.js +7 -1
- package/dist/core/capability-data.js +339 -10
- package/dist/core/format/help.js +80 -4
- package/dist/core/format/recovery-hint.js +32 -0
- package/dist/core/multi-agent/collaboration.js +35 -6
- package/dist/core/multi-agent/runtime.js +7 -0
- package/dist/core/multi-agent/trust-policy.js +7 -1
- package/dist/core/pipeline/contract.js +7 -0
- package/dist/core/pipeline/error-feedback.js +2 -2
- package/dist/core/trust/evidence-grounding.js +13 -1
- package/dist/core/util/cli-args.js +55 -0
- package/dist/core/version.js +1 -1
- package/dist/mcp/dispatch.js +22 -2
- package/dist/mcp/server.js +124 -13
- package/dist/mcp-server.js +20 -0
- package/dist/shell/commit.js +8 -2
- package/dist/shell/coordinator-io.js +73 -1
- package/dist/shell/drive.js +129 -64
- package/dist/shell/error-feedback-io.js +6 -0
- package/dist/shell/execution-backend/agent.js +205 -24
- package/dist/shell/execution-backend/container.js +44 -10
- package/dist/shell/execution-backend/local.js +47 -10
- package/dist/shell/fs-atomic.js +93 -12
- package/dist/shell/ledger-cli.js +9 -2
- package/dist/shell/multi-agent-cli.js +5 -1
- package/dist/shell/onramp.js +48 -5
- package/dist/shell/pipeline-cli.js +20 -2
- package/dist/shell/pipeline.js +2 -1
- package/dist/shell/reclamation-io.js +76 -7
- package/dist/shell/registry-cli.js +4 -0
- package/dist/shell/run-export.js +52 -4
- package/dist/shell/run-registry-io.js +1 -0
- package/dist/shell/run-store.js +156 -0
- package/dist/shell/scheduler-io.js +101 -10
- package/dist/shell/telemetry-ledger-io.js +36 -24
- package/dist/shell/trust-audit.js +104 -10
- package/dist/shell/workbench-host.js +121 -10
- package/dist/shell/workbench.js +79 -5
- package/dist/shell/worker-isolation.js +1 -1
- package/dist/shell/workflow-app-loader.js +67 -1
- package/dist/wiring/capability-table/basics.js +7 -2
- package/dist/wiring/capability-table/exec-backend.js +42 -24
- package/dist/wiring/capability-table/multi-agent.js +69 -69
- package/dist/wiring/capability-table/pipeline.js +60 -28
- package/dist/wiring/capability-table/registry-core.js +29 -6
- package/dist/wiring/capability-table/reporting.js +45 -39
- package/dist/wiring/capability-table/scheduling-registry.js +66 -60
- package/dist/wiring/capability-table/state.js +34 -34
- package/dist/wiring/capability-table/trust-ledger.js +66 -24
- package/dist/wiring/capability-table/workflow-apps.js +15 -15
- package/docs/agent-delegation-drive.7.md +17 -0
- package/docs/cli-mcp-parity.7.md +43 -13
- package/docs/contract-migration-tooling.7.md +4 -0
- package/docs/control-plane-scheduling.7.md +38 -0
- package/docs/cross-agent-ledger.7.md +20 -8
- package/docs/durable-state-and-locking.7.md +4 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
- package/docs/execution-backends.7.md +4 -0
- package/docs/fix.7.md +4 -4
- package/docs/getting-started.md +40 -32
- package/docs/index.md +17 -0
- package/docs/launch/demo.tape +4 -3
- package/docs/mcp-app-surface.7.md +6 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
- package/docs/multi-agent-eval-replay-harness.7.md +4 -0
- package/docs/multi-agent-operator-ux.7.md +4 -0
- package/docs/node-snapshot-diff-replay.7.md +4 -0
- package/docs/observability-cost-accounting.7.md +4 -0
- package/docs/project-index.md +43 -9
- package/docs/real-execution-backends.7.md +4 -0
- package/docs/release-and-migration.7.md +4 -0
- package/docs/release-tooling.7.md +22 -0
- package/docs/routine.7.md +22 -0
- package/docs/run-registry-control-plane.7.md +4 -0
- package/docs/run-retention-reclamation.7.md +28 -3
- package/docs/state-explosion-management.7.md +4 -0
- package/docs/team-collaboration.7.md +4 -0
- package/docs/trust-audit-anchor.7.md +4 -0
- package/docs/web-desktop-workbench.7.md +26 -2
- package/docs/workflow-app-framework.7.md +31 -0
- package/manifest/plugin.manifest.json +1 -1
- package/manifest/source-context-profiles.json +4 -3
- package/package.json +5 -2
- package/scripts/agents/agent-adapter-core.js +26 -0
- package/scripts/agents/claude-p-agent.js +4 -1
- package/scripts/agents/codex-agent.js +4 -0
- package/scripts/agents/cw-attest-wrap.js +1 -1
- package/scripts/agents/gemini-agent.js +4 -0
- package/scripts/agents/opencode-agent.js +5 -0
- package/scripts/block-unapproved-tag.js +160 -0
- package/scripts/bump-version.js +27 -10
- package/scripts/canonical-apps.js +4 -4
- package/scripts/children/batch-delegate-child.js +72 -4
- package/scripts/children/http-batch-delegate-child.js +132 -0
- package/scripts/children/http-delegate-child.js +8 -0
- package/scripts/dogfood-release.js +2 -2
- package/scripts/fake-date-for-reproduction.js +1 -1
- package/scripts/golden-path.js +4 -4
- package/scripts/lang-policy-check.js +82 -0
- package/scripts/purity-baseline.json +0 -30
- package/scripts/purity-gate.js +16 -3
- package/scripts/release-check.js +2 -1
- package/scripts/release-flow.js +264 -41
- package/scripts/release-gate.js +184 -0
- package/scripts/release-oneclick.js +438 -0
- package/scripts/release-tags.js +47 -0
- package/scripts/verdict-keygen.js +2 -2
- package/scripts/verify-bump-reproduction.js +193 -0
- package/scripts/verify-verdict-signature.js +1 -1
- package/scripts/version-sync-check.js +39 -22
- package/ui/workbench/app.css +41 -9
- package/ui/workbench/app.js +160 -27
- package/ui/workbench/index.html +2 -2
- package/docs/agent-framework.md +0 -177
- package/docs/designs/handoff-ledger.md +0 -145
- package/docs/dogfood/resume-drive-real-agent-2026-06-14.md +0 -40
- package/docs/launch/launch-kit.md +0 -195
- package/docs/launch/pre-launch-checklist.md +0 -53
- package/docs/readme-v0.1.87-full.md +0 -301
- package/docs/routines.md +0 -101
- package/docs/scheduled-tasks.md +0 -80
- package/scripts/agents/claude-p-agent.sh +0 -9
- package/scripts/block-unapproved-tag.sh +0 -60
- package/scripts/release-gate.sh +0 -94
- package/scripts/verify-bump-reproduction.sh +0 -148
- package/scripts/verify-container-selfref.js +0 -64
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
// capability is APPENDED after the transcript's last row (never inserted),
|
|
34
34
|
// so every existing position keeps its pinned order.
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.MCP_TOOL_DATA = exports.PROPERTY_OVERRIDES = exports.CapabilityNotImplementedError = void 0;
|
|
36
|
+
exports.MCP_TOOL_DATA = exports.MCP_TOOL_ANNOTATIONS = exports.COMMON_PROPERTY_TYPES = exports.PROPERTY_OVERRIDES = exports.CapabilityNotImplementedError = void 0;
|
|
37
37
|
exports.notYetImplemented = notYetImplemented;
|
|
38
38
|
exports.stringProperty = stringProperty;
|
|
39
39
|
/** Thrown by every not-yet-wired MCP tool handler. Never hit by this
|
|
@@ -55,8 +55,9 @@ function stringProperty(name) {
|
|
|
55
55
|
return { type: "string", description: name };
|
|
56
56
|
}
|
|
57
57
|
/** SPEC/mcp.md's two hand-written property-shape exceptions (see that
|
|
58
|
-
* file's "All 196 MCP tools" section header note):
|
|
59
|
-
*
|
|
58
|
+
* file's "All 196 MCP tools" section header note): these two properties
|
|
59
|
+
* win over `COMMON_PROPERTY_TYPES` below, since each is a one-off shape
|
|
60
|
+
* tied to its own tool, not a shape shared by the property name at large. */
|
|
60
61
|
exports.PROPERTY_OVERRIDES = {
|
|
61
62
|
cw_commit: {
|
|
62
63
|
allowUnverifiedCheckpoint: {
|
|
@@ -68,11 +69,339 @@ exports.PROPERTY_OVERRIDES = {
|
|
|
68
69
|
payload: { type: "object", description: "Event payload" },
|
|
69
70
|
},
|
|
70
71
|
};
|
|
72
|
+
/** A real type and a true, short, one-sentence description for every
|
|
73
|
+
* property name used anywhere in `MCP_TOOL_DATA` below, keyed by the
|
|
74
|
+
* PROPERTY NAME (not the tool name) — the same name means the same
|
|
75
|
+
* thing on every tool that uses it. `mcpToolDefinitions()` in
|
|
76
|
+
* wiring/capability-table/registry-core.ts looks a property up here
|
|
77
|
+
* only when `PROPERTY_OVERRIDES` has no entry for it on that tool; a
|
|
78
|
+
* name not found in either table falls back to the plain
|
|
79
|
+
* `stringProperty` form (there should be very few of those — the two
|
|
80
|
+
* names left out here, `allowUnverifiedCheckpoint` and `payload`, are
|
|
81
|
+
* already covered by `PROPERTY_OVERRIDES` on their one tool each). */
|
|
82
|
+
exports.COMMON_PROPERTY_TYPES = {
|
|
83
|
+
action: { type: "string", description: "which action to run" },
|
|
84
|
+
actor: { type: "string", description: "the name of the actor doing this" },
|
|
85
|
+
actorKind: { type: "string", description: "the kind of actor, such as agent or human" },
|
|
86
|
+
agentCommand: { type: "string", description: "the command template used to run the agent" },
|
|
87
|
+
agentEndpoint: { type: "string", description: "the network address of the agent service" },
|
|
88
|
+
agentModel: { type: "string", description: "the name of the agent model to use" },
|
|
89
|
+
all: { type: "boolean", description: "when true, act on every item, not only old ones" },
|
|
90
|
+
allowSelfApproval: { type: "boolean", description: "when true, let an actor approve their own work" },
|
|
91
|
+
allowUnverified: { type: "boolean", description: "when true, skip the check that needs a verifier" },
|
|
92
|
+
app: { type: "string", description: "the workflow app's id" },
|
|
93
|
+
appId: { type: "string", description: "the workflow app's id" },
|
|
94
|
+
appliesTo: { type: "string", description: "what this policy rule applies to" },
|
|
95
|
+
archive: { type: "string", description: "the path to the run archive file" },
|
|
96
|
+
artifact: { type: "object", description: "an artifact reference to attach as proof" },
|
|
97
|
+
attestation: { type: "string", description: "the attestation text or id for this actor" },
|
|
98
|
+
attested: { type: "boolean", description: "when true, mark the actor as host-attested" },
|
|
99
|
+
authorizedRoles: { type: "array", description: "the list of role names allowed to approve" },
|
|
100
|
+
backend: { type: "string", description: "the name of the execution backend" },
|
|
101
|
+
backendId: { type: "string", description: "the id of the execution backend" },
|
|
102
|
+
backoffBaseMs: { type: "number", description: "the starting wait time, in milliseconds, before a retry" },
|
|
103
|
+
backoffCapMs: { type: "number", description: "the largest wait time, in milliseconds, before a retry" },
|
|
104
|
+
backoffFactor: { type: "number", description: "the number the wait time is multiplied by after each retry" },
|
|
105
|
+
baseline: { type: "string", description: "the baseline snapshot's id" },
|
|
106
|
+
baselinePath: { type: "string", description: "the file path to the baseline snapshot" },
|
|
107
|
+
baselineSnapshotId: { type: "string", description: "the id of the baseline snapshot" },
|
|
108
|
+
blackboardId: { type: "string", description: "the id of the blackboard" },
|
|
109
|
+
body: { type: "string", description: "the text body of the message" },
|
|
110
|
+
bundle: { type: "string", description: "the path to the run bundle file" },
|
|
111
|
+
by: { type: "string", description: "the name of the actor who did this" },
|
|
112
|
+
candidate: { type: "string", description: "the candidate's id" },
|
|
113
|
+
candidateId: { type: "string", description: "the candidate's id" },
|
|
114
|
+
candidateSnapshotId: { type: "string", description: "the id of the candidate snapshot" },
|
|
115
|
+
code: { type: "string", description: "a short error or status code" },
|
|
116
|
+
collectInitialFanin: { type: "boolean", description: "when true, collect the first fan-in step right away" },
|
|
117
|
+
command: { type: "string", description: "the command that was run or checked" },
|
|
118
|
+
commit: { type: "string", description: "the commit's id" },
|
|
119
|
+
commitId: { type: "string", description: "the commit's id" },
|
|
120
|
+
concurrency: { type: "number", description: "the largest number of steps to run at once" },
|
|
121
|
+
contract: { type: "string", description: "the pipeline contract's id" },
|
|
122
|
+
contractId: { type: "string", description: "the pipeline contract's id" },
|
|
123
|
+
criteria: { type: "array", description: "the list of scoring criteria" },
|
|
124
|
+
criterion: { type: "string", description: "one scoring criterion's name" },
|
|
125
|
+
cron: { type: "string", description: "the cron schedule text" },
|
|
126
|
+
cwd: { type: "string", description: "the working directory to run in" },
|
|
127
|
+
debateRounds: { type: "number", description: "the number of debate rounds to run" },
|
|
128
|
+
delayMinutes: { type: "number", description: "the number of minutes to wait before the task runs" },
|
|
129
|
+
depth: { type: "number", description: "how many levels deep to read" },
|
|
130
|
+
description: { type: "string", description: "a short text that describes this item" },
|
|
131
|
+
diff: { type: "string", description: "the change text (diff) for this proposal" },
|
|
132
|
+
dir: { type: "string", description: "the path to one ledger directory" },
|
|
133
|
+
directory: { type: "string", description: "the directory path to write into" },
|
|
134
|
+
dirs: { type: "array", description: "the list of ledger directory paths" },
|
|
135
|
+
dispatchId: { type: "string", description: "the id of the dispatch record" },
|
|
136
|
+
displayName: { type: "string", description: "the actor's human-readable name" },
|
|
137
|
+
entry: { type: "string", description: "the ledger entry to check" },
|
|
138
|
+
env: { type: "object", description: "the environment variables for this step" },
|
|
139
|
+
evidence: { type: "array", description: "the list of evidence items backing this claim" },
|
|
140
|
+
expectCount: { type: "number", description: "the event count the chain must match" },
|
|
141
|
+
expectHead: { type: "string", description: "the head hash the chain must match" },
|
|
142
|
+
expectedArtifact: { type: "string", description: "the artifact this role is expected to produce" },
|
|
143
|
+
extractReport: { type: "boolean", description: "when true, also pull the plain report out of the bundle" },
|
|
144
|
+
failed: { type: "boolean", description: "when true, mark the lease as failed" },
|
|
145
|
+
faninId: { type: "string", description: "the id of the fan-in record" },
|
|
146
|
+
faninObligation: { type: "string", description: "what this role must supply at fan-in time" },
|
|
147
|
+
fanoutId: { type: "string", description: "the id of the fan-out record" },
|
|
148
|
+
feedbackId: { type: "string", description: "the id of the feedback record" },
|
|
149
|
+
file: { type: "string", description: "the path to the archive file" },
|
|
150
|
+
files: { type: "array", description: "the list of file paths this change touches" },
|
|
151
|
+
findings: { type: "array", description: "the list of review findings" },
|
|
152
|
+
focus: { type: "string", description: "the node id to center the view on" },
|
|
153
|
+
from: { type: "string", description: "the actor this comes from" },
|
|
154
|
+
groupId: { type: "string", description: "the id of the agent group" },
|
|
155
|
+
hostEnforced: { type: "boolean", description: "when true, the host, not the agent, enforced the sandbox rule" },
|
|
156
|
+
id: { type: "string", description: "the id of this item" },
|
|
157
|
+
includeArchived: { type: "boolean", description: "when true, also list archived runs" },
|
|
158
|
+
includeRejected: { type: "boolean", description: "when true, also list rejected candidates" },
|
|
159
|
+
inputs: { type: "object", description: "the structured input values for the app" },
|
|
160
|
+
intervalMinutes: { type: "number", description: "how often, in minutes, the task should repeat" },
|
|
161
|
+
judgeCount: { type: "number", description: "the number of judge agents to use" },
|
|
162
|
+
keepCommits: { type: "number", description: "the number of recent commits to keep" },
|
|
163
|
+
keepScratch: { type: "boolean", description: "when true, keep scratch files instead of freeing them" },
|
|
164
|
+
keepSnapshots: { type: "number", description: "the number of recent snapshots to keep" },
|
|
165
|
+
key: { type: "string", description: "the context frame's key" },
|
|
166
|
+
kind: { type: "string", description: "the kind of this item" },
|
|
167
|
+
leaseId: { type: "string", description: "the id of the queue lease" },
|
|
168
|
+
leaseTtlMs: { type: "number", description: "how long, in milliseconds, a lease stays valid" },
|
|
169
|
+
limit: { type: "number", description: "the largest number of items to return" },
|
|
170
|
+
locator: { type: "string", description: "where to find the artifact (a path or url)" },
|
|
171
|
+
mapperCount: { type: "number", description: "the number of mapper agents to use" },
|
|
172
|
+
match: { type: "string", description: "the text pattern used to match trigger events" },
|
|
173
|
+
max: { type: "number", description: "the largest allowed score" },
|
|
174
|
+
maxAttempts: { type: "number", description: "the largest number of retry attempts allowed" },
|
|
175
|
+
maxConcurrent: { type: "number", description: "the largest number of runs allowed at once" },
|
|
176
|
+
maxTotal: { type: "number", description: "the largest total score allowed" },
|
|
177
|
+
membershipId: { type: "string", description: "the id of the agent membership record" },
|
|
178
|
+
message: { type: "string", description: "the message text" },
|
|
179
|
+
minAgeMinutes: { type: "number", description: "the least age, in minutes, an item must have" },
|
|
180
|
+
minNormalized: { type: "number", description: "the least normalized score a candidate must have" },
|
|
181
|
+
multiAgentRun: { type: "string", description: "the multi-agent run's id" },
|
|
182
|
+
multiAgentRunId: { type: "string", description: "the multi-agent run's id" },
|
|
183
|
+
network: { type: "string", description: "the network access rule that was checked" },
|
|
184
|
+
node: { type: "string", description: "the state node's id" },
|
|
185
|
+
nodeId: { type: "string", description: "the state node's id" },
|
|
186
|
+
note: { type: "string", description: "a short free-text note" },
|
|
187
|
+
notes: { type: "string", description: "free-text notes about this score" },
|
|
188
|
+
now: { type: "string", description: "the time to treat as \"now\", for a stable, repeatable result" },
|
|
189
|
+
objective: { type: "string", description: "the goal text for this multi-agent run" },
|
|
190
|
+
offset: { type: "number", description: "how many items to skip before returning results" },
|
|
191
|
+
olderThanDays: { type: "number", description: "the least age, in days, an item must have" },
|
|
192
|
+
once: { type: "boolean", description: "when true, run only one step, then stop" },
|
|
193
|
+
outcome: { type: "string", description: "the decision's outcome" },
|
|
194
|
+
output: { type: "string", description: "the output file path to write" },
|
|
195
|
+
parent: { type: "string", description: "the id of the parent item this replies to" },
|
|
196
|
+
path: { type: "string", description: "a file path" },
|
|
197
|
+
phase: { type: "string", description: "the phase name for this agent group" },
|
|
198
|
+
port: { type: "number", description: "the network port to use" },
|
|
199
|
+
pricing: { type: "string", description: "the pricing table to use for cost figures" },
|
|
200
|
+
priority: { type: "number", description: "the queue order priority" },
|
|
201
|
+
profileFile: { type: "string", description: "the path to the sandbox profile file" },
|
|
202
|
+
profileId: { type: "string", description: "the id of the sandbox profile" },
|
|
203
|
+
prompt: { type: "string", description: "the prompt text for this task" },
|
|
204
|
+
pubkey: { type: "string", description: "the public key used to check a signature" },
|
|
205
|
+
question: { type: "string", description: "the question that starts the run" },
|
|
206
|
+
rationale: { type: "string", description: "the reason behind this decision" },
|
|
207
|
+
reason: { type: "string", description: "a short text that explains why" },
|
|
208
|
+
reclaimAfterArchiveDays: { type: "number", description: "how many days after archive before a run can be freed" },
|
|
209
|
+
refresh: { type: "boolean", description: "when true, rebuild the result instead of reading a cached one" },
|
|
210
|
+
replay: { type: "string", description: "the replay's id" },
|
|
211
|
+
replayId: { type: "string", description: "the replay's id" },
|
|
212
|
+
replayPath: { type: "string", description: "the file path to the replay" },
|
|
213
|
+
replyTo: { type: "string", description: "the id of the message this replies to" },
|
|
214
|
+
repo: { type: "string", description: "the path to the repo" },
|
|
215
|
+
requireAttestedActor: { type: "boolean", description: "when true, only let an attested actor approve" },
|
|
216
|
+
requireEvidence: { type: "boolean", description: "when true, require evidence before a candidate can rank" },
|
|
217
|
+
requireToken: { type: "boolean", description: "when true, require a token to reach the host" },
|
|
218
|
+
requireVerifierGate: { type: "boolean", description: "when true, require the verifier gate to pass first" },
|
|
219
|
+
requiredApprovals: { type: "number", description: "the number of approvals a target needs" },
|
|
220
|
+
requiredEvidence: { type: "array", description: "the list of evidence kinds this role must supply" },
|
|
221
|
+
requiredRole: { type: "string", description: "the role name that must be present at fan-in" },
|
|
222
|
+
responsibility: { type: "string", description: "what this role is responsible for" },
|
|
223
|
+
resultNode: { type: "string", description: "the id of the node holding the result" },
|
|
224
|
+
resultPath: { type: "string", description: "the file path to the result" },
|
|
225
|
+
retryable: { type: "boolean", description: "when true, mark this failure as safe to retry" },
|
|
226
|
+
role: { type: "string", description: "the actor's role name" },
|
|
227
|
+
roleId: { type: "string", description: "the agent role's id" },
|
|
228
|
+
runId: { type: "string", description: "the run's id" },
|
|
229
|
+
sandbox: { type: "string", description: "the sandbox profile choice" },
|
|
230
|
+
sandboxChoice: { type: "string", description: "the sandbox profile choice" },
|
|
231
|
+
sandboxProfile: { type: "string", description: "the sandbox profile's id" },
|
|
232
|
+
sandboxProfileHint: { type: "string", description: "a hint for which sandbox profile this role should use" },
|
|
233
|
+
sandboxProfileId: { type: "string", description: "the sandbox profile's id" },
|
|
234
|
+
scope: { type: "string", description: "which repos to search, such as this repo or all repos" },
|
|
235
|
+
score: { type: "string", description: "the score's id" },
|
|
236
|
+
scoreId: { type: "string", description: "the score's id" },
|
|
237
|
+
scorer: { type: "string", description: "the name of the actor giving this score" },
|
|
238
|
+
selectedBy: { type: "string", description: "the actor who made the selection" },
|
|
239
|
+
selection: { type: "string", description: "the selection's id" },
|
|
240
|
+
since: { type: "string", description: "the start of the time range to search" },
|
|
241
|
+
snapshot: { type: "string", description: "the snapshot's id" },
|
|
242
|
+
snapshotId: { type: "string", description: "the snapshot's id" },
|
|
243
|
+
source: { type: "string", description: "where this artifact came from" },
|
|
244
|
+
state: { type: "string", description: "the run state to check or set" },
|
|
245
|
+
status: { type: "string", description: "the status to filter or set" },
|
|
246
|
+
strategy: { type: "string", description: "the strategy used to collect fan-in" },
|
|
247
|
+
strictSignatures: { type: "boolean", description: "when true, fail closed if a signature cannot be checked" },
|
|
248
|
+
subject: { type: "string", description: "the subject of this decision" },
|
|
249
|
+
suite: { type: "string", description: "the eval suite's id" },
|
|
250
|
+
suiteId: { type: "string", description: "the eval suite's id" },
|
|
251
|
+
supersedes: { type: "string", description: "the id of the earlier item this replaces" },
|
|
252
|
+
tag: { type: "string", description: "a short label for this topic" },
|
|
253
|
+
target: { type: "string", description: "the id of the target this acts on" },
|
|
254
|
+
targetId: { type: "string", description: "the id of the target this acts on" },
|
|
255
|
+
targetKind: { type: "string", description: "the kind of the target, such as candidate or commit" },
|
|
256
|
+
task: { type: "string", description: "the task text or id" },
|
|
257
|
+
taskId: { type: "string", description: "the task's id" },
|
|
258
|
+
text: { type: "string", description: "free-text search terms" },
|
|
259
|
+
thread: { type: "string", description: "the id of the comment thread" },
|
|
260
|
+
tieBreaker: { type: "string", description: "the rule used to break a tie between candidates" },
|
|
261
|
+
title: { type: "string", description: "a short title for this item" },
|
|
262
|
+
to: { type: "string", description: "the actor this is handed to" },
|
|
263
|
+
toRole: { type: "string", description: "the role this is handed to" },
|
|
264
|
+
topic: { type: "string", description: "the blackboard topic's id" },
|
|
265
|
+
topicId: { type: "string", description: "the blackboard topic's id" },
|
|
266
|
+
topology: { type: "string", description: "the topology definition's id" },
|
|
267
|
+
topologyId: { type: "string", description: "the topology definition's id" },
|
|
268
|
+
topologyRunId: { type: "string", description: "the id of the topology run" },
|
|
269
|
+
trustKey: { type: "string", description: "the trust key used to seal the run" },
|
|
270
|
+
unarchive: { type: "boolean", description: "when true, undo an archive mark instead of setting one" },
|
|
271
|
+
until: { type: "string", description: "the end of the time range to search" },
|
|
272
|
+
value: { type: "string", description: "the value to store in this context frame" },
|
|
273
|
+
verdict: { type: "string", description: "the review verdict" },
|
|
274
|
+
verifier: { type: "string", description: "the name of the verifier" },
|
|
275
|
+
verifierNode: { type: "string", description: "the id of the node holding the verifier result" },
|
|
276
|
+
verify: { type: "boolean", description: "when true, also verify the result after this step" },
|
|
277
|
+
view: { type: "string", description: "which view of the data to return" },
|
|
278
|
+
visibility: { type: "string", description: "who can see this message" },
|
|
279
|
+
withTrustKey: { type: "boolean", description: "when true, seal the output with the trust key" },
|
|
280
|
+
worker: { type: "string", description: "the worker's id" },
|
|
281
|
+
workerId: { type: "string", description: "the worker's id" },
|
|
282
|
+
workflow: { type: "string", description: "the workflow definition's id" },
|
|
283
|
+
workflowId: { type: "string", description: "the workflow definition's id" },
|
|
284
|
+
write: { type: "boolean", description: "when true, save the result instead of only reading it" },
|
|
285
|
+
};
|
|
286
|
+
/** Behavior hints per MCP tool name, surfaced as the standard MCP
|
|
287
|
+
* `annotations` field on each `tools/list` entry. A side table (like
|
|
288
|
+
* `MCP_REAL_HANDLERS` in wiring/capability-table/registry-core.ts) so
|
|
289
|
+
* `MCP_TOOL_DATA` below stays a pure transcript of the spec table.
|
|
290
|
+
*
|
|
291
|
+
* The rule for this table is strict, because a wrong hint is a safety
|
|
292
|
+
* bug (a client may skip its confirmation step for a "read-only" tool):
|
|
293
|
+
* - `readOnlyHint: true` ONLY for a tool whose handler was read and
|
|
294
|
+
* seen to do no write at all (no saveCheckpoint, no writeJson, no
|
|
295
|
+
* writeReport, no fs write of any kind);
|
|
296
|
+
* - `destructiveHint: true` for a tool whose handler was read and seen
|
|
297
|
+
* to delete stored data (gc / delete sweeps);
|
|
298
|
+
* - every other tool is ABSENT from this table and gets no
|
|
299
|
+
* annotations. Absent beats wrong. Some absences that look like
|
|
300
|
+
* reads are deliberate: cw_metrics_show persists its derived report,
|
|
301
|
+
* cw_workbench_view calls the metrics.show handler for one panel,
|
|
302
|
+
* cw_operator_report re-writes report.md, cw_schedule_due marks
|
|
303
|
+
* expired tasks, cw_run_resume can take the opt-in --drive path, and
|
|
304
|
+
* cw_multi_agent_reasoning can take the opt-in refresh path. */
|
|
305
|
+
exports.MCP_TOOL_ANNOTATIONS = {
|
|
306
|
+
// pure reads, in MCP_TOOL_DATA order (each handler checked by hand)
|
|
307
|
+
cw_list: { readOnlyHint: true },
|
|
308
|
+
cw_status: { readOnlyHint: true },
|
|
309
|
+
cw_next: { readOnlyHint: true },
|
|
310
|
+
cw_contract_show: { readOnlyHint: true },
|
|
311
|
+
cw_node_list: { readOnlyHint: true },
|
|
312
|
+
cw_node_show: { readOnlyHint: true },
|
|
313
|
+
cw_node_graph: { readOnlyHint: true },
|
|
314
|
+
cw_migration_list: { readOnlyHint: true },
|
|
315
|
+
cw_operator_status: { readOnlyHint: true },
|
|
316
|
+
cw_operator_graph: { readOnlyHint: true },
|
|
317
|
+
cw_worker_summary: { readOnlyHint: true },
|
|
318
|
+
cw_candidate_summary: { readOnlyHint: true },
|
|
319
|
+
cw_feedback_summary: { readOnlyHint: true },
|
|
320
|
+
cw_commit_summary: { readOnlyHint: true },
|
|
321
|
+
cw_multi_agent_summary: { readOnlyHint: true },
|
|
322
|
+
cw_multi_agent_graph: { readOnlyHint: true },
|
|
323
|
+
cw_multi_agent_dependencies: { readOnlyHint: true },
|
|
324
|
+
cw_multi_agent_failures: { readOnlyHint: true },
|
|
325
|
+
cw_multi_agent_evidence: { readOnlyHint: true },
|
|
326
|
+
cw_summary_show: { readOnlyHint: true },
|
|
327
|
+
cw_blackboard_summarize: { readOnlyHint: true },
|
|
328
|
+
cw_multi_agent_summarize: { readOnlyHint: true },
|
|
329
|
+
cw_multi_agent_graph_compact: { readOnlyHint: true },
|
|
330
|
+
cw_multi_agent_status: { readOnlyHint: true },
|
|
331
|
+
cw_multi_agent_run_show: { readOnlyHint: true },
|
|
332
|
+
cw_topology_list: { readOnlyHint: true },
|
|
333
|
+
cw_topology_show: { readOnlyHint: true },
|
|
334
|
+
cw_topology_validate: { readOnlyHint: true },
|
|
335
|
+
cw_topology_summary: { readOnlyHint: true },
|
|
336
|
+
cw_topology_graph: { readOnlyHint: true },
|
|
337
|
+
cw_blackboard_summary: { readOnlyHint: true },
|
|
338
|
+
cw_blackboard_graph: { readOnlyHint: true },
|
|
339
|
+
cw_blackboard_message_list: { readOnlyHint: true },
|
|
340
|
+
cw_blackboard_artifact_list: { readOnlyHint: true },
|
|
341
|
+
cw_coordinator_summary: { readOnlyHint: true },
|
|
342
|
+
cw_audit_summary: { readOnlyHint: true },
|
|
343
|
+
cw_audit_verify: { readOnlyHint: true },
|
|
344
|
+
cw_audit_worker: { readOnlyHint: true },
|
|
345
|
+
cw_audit_provenance: { readOnlyHint: true },
|
|
346
|
+
cw_audit_multi_agent: { readOnlyHint: true },
|
|
347
|
+
cw_audit_policy: { readOnlyHint: true },
|
|
348
|
+
cw_audit_role: { readOnlyHint: true },
|
|
349
|
+
cw_audit_blackboard: { readOnlyHint: true },
|
|
350
|
+
cw_audit_judge: { readOnlyHint: true },
|
|
351
|
+
cw_sandbox_list: { readOnlyHint: true },
|
|
352
|
+
cw_sandbox_show: { readOnlyHint: true },
|
|
353
|
+
cw_sandbox_validate: { readOnlyHint: true },
|
|
354
|
+
cw_backend_list: { readOnlyHint: true },
|
|
355
|
+
cw_backend_show: { readOnlyHint: true },
|
|
356
|
+
cw_backend_agent_config_show: { readOnlyHint: true },
|
|
357
|
+
cw_app_list: { readOnlyHint: true },
|
|
358
|
+
cw_app_show: { readOnlyHint: true },
|
|
359
|
+
cw_app_validate: { readOnlyHint: true },
|
|
360
|
+
cw_worker_list: { readOnlyHint: true },
|
|
361
|
+
cw_worker_show: { readOnlyHint: true },
|
|
362
|
+
cw_candidate_list: { readOnlyHint: true },
|
|
363
|
+
cw_candidate_show: { readOnlyHint: true },
|
|
364
|
+
cw_comment_list: { readOnlyHint: true },
|
|
365
|
+
cw_review_status: { readOnlyHint: true },
|
|
366
|
+
cw_feedback_list: { readOnlyHint: true },
|
|
367
|
+
cw_feedback_show: { readOnlyHint: true },
|
|
368
|
+
cw_ledger_verify: { readOnlyHint: true },
|
|
369
|
+
cw_ledger_apply: { readOnlyHint: true },
|
|
370
|
+
cw_ledger_list: { readOnlyHint: true },
|
|
371
|
+
cw_schedule_list: { readOnlyHint: true },
|
|
372
|
+
cw_schedule_history: { readOnlyHint: true },
|
|
373
|
+
cw_routine_list: { readOnlyHint: true },
|
|
374
|
+
cw_routine_events: { readOnlyHint: true },
|
|
375
|
+
cw_registry_show: { readOnlyHint: true },
|
|
376
|
+
cw_metrics_summary: { readOnlyHint: true },
|
|
377
|
+
cw_run_search: { readOnlyHint: true },
|
|
378
|
+
cw_run_list: { readOnlyHint: true },
|
|
379
|
+
cw_run_show: { readOnlyHint: true },
|
|
380
|
+
cw_run_inspect_archive: { readOnlyHint: true },
|
|
381
|
+
cw_run_drive: { readOnlyHint: true },
|
|
382
|
+
cw_queue_list: { readOnlyHint: true },
|
|
383
|
+
cw_queue_show: { readOnlyHint: true },
|
|
384
|
+
cw_sched_plan: { readOnlyHint: true },
|
|
385
|
+
cw_sched_policy_show: { readOnlyHint: true },
|
|
386
|
+
cw_gc_plan: { readOnlyHint: true },
|
|
387
|
+
cw_gc_verify: { readOnlyHint: true },
|
|
388
|
+
cw_clones_list: { readOnlyHint: true },
|
|
389
|
+
cw_orphans_list: { readOnlyHint: true },
|
|
390
|
+
cw_telemetry_verify: { readOnlyHint: true },
|
|
391
|
+
cw_history: { readOnlyHint: true },
|
|
392
|
+
cw_audit_head: { readOnlyHint: true },
|
|
393
|
+
// delete sweeps (each handler checked by hand: all delete stored data)
|
|
394
|
+
cw_schedule_delete: { readOnlyHint: false, destructiveHint: true },
|
|
395
|
+
cw_routine_delete: { readOnlyHint: false, destructiveHint: true },
|
|
396
|
+
cw_gc_run: { readOnlyHint: false, destructiveHint: true },
|
|
397
|
+
cw_clones_gc: { readOnlyHint: false, destructiveHint: true },
|
|
398
|
+
cw_orphans_gc: { readOnlyHint: false, destructiveHint: true },
|
|
399
|
+
};
|
|
71
400
|
exports.MCP_TOOL_DATA = [
|
|
72
401
|
{ tool: "cw_list", capability: "list", requiredArgs: [], properties: [], description: "List bundled CW workflows." },
|
|
73
402
|
{ tool: "cw_plan", capability: "plan", requiredArgs: ["workflowId"], properties: ["workflowId", "repo", "question"], description: "Create a CW run and return its canonical plan summary." },
|
|
74
403
|
{ tool: "cw_app_run", capability: "app.run", requiredArgs: ["appId"], properties: ["cwd", "appId", "inputs", "sandbox", "sandboxProfile", "sandboxProfileId"], description: "Create a run from an app id + structured inputs." },
|
|
75
|
-
{ tool: "cw_status", capability: "status", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read run checkpoint status." },
|
|
404
|
+
{ tool: "cw_status", capability: "status", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read run checkpoint status. The quick first check on one run: lifecycle, task counts, and next actions. For the fuller operator view use cw_operator_status; for every panel in one call use cw_workbench_view." },
|
|
76
405
|
{ tool: "cw_init", capability: "init", requiredArgs: ["workflowId"], properties: ["workflowId", "title", "output"], description: "Scaffold a new workflow definition." },
|
|
77
406
|
{ tool: "cw_next", capability: "next", requiredArgs: ["runId"], properties: ["runId", "cwd", "limit"], description: "Read the next recommended tasks for a run." },
|
|
78
407
|
{ tool: "cw_state_check", capability: "state.check", requiredArgs: ["runId"], properties: ["runId", "cwd", "state", "write"], description: "Check run-state schema compatibility." },
|
|
@@ -87,11 +416,11 @@ exports.MCP_TOOL_DATA = [
|
|
|
87
416
|
{ tool: "cw_migration_list", capability: "migration.list", requiredArgs: [], properties: [], description: "List the declared migration registry." },
|
|
88
417
|
{ tool: "cw_migration_check", capability: "migration.check", requiredArgs: [], properties: ["target", "contract", "cwd"], description: "Dry-run migration verdict for a target." },
|
|
89
418
|
{ tool: "cw_migration_prove", capability: "migration.prove", requiredArgs: [], properties: ["target", "contract", "cwd"], description: "Round-trip / non-destruction migration proof for a target." },
|
|
90
|
-
{ tool: "cw_operator_status", capability: "operator.status", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the structured Operator UX run status." },
|
|
419
|
+
{ tool: "cw_operator_status", capability: "operator.status", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the structured Operator UX run status. Fuller than cw_status: workers, candidates, feedback, and commits in one operator view. For every panel in one call use cw_workbench_view; for agent-topology detail use cw_multi_agent_status." },
|
|
91
420
|
{ tool: "cw_operator_graph", capability: "graph", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the structured Operator UX run graph." },
|
|
92
421
|
{ tool: "cw_operator_report", capability: "operator.report", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Refresh and read the structured Operator UX report summary." },
|
|
93
422
|
{ tool: "cw_worker_summary", capability: "worker.summary", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the structured worker summary for a run." },
|
|
94
|
-
{ tool: "cw_workbench_view", capability: "workbench.view", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the read-only five-panel Workbench view of one run (graph, blackboard, worker, candidate, audit)." },
|
|
423
|
+
{ tool: "cw_workbench_view", capability: "workbench.view", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the read-only five-panel Workbench view of one run (graph, blackboard, worker, candidate, audit). The widest one-call overview; prefer it when you want everything at once. For one quick answer use cw_status or cw_operator_status instead." },
|
|
95
424
|
{ tool: "cw_workbench_serve", capability: "workbench.serve", requiredArgs: [], properties: ["cwd", "port", "scope", "requireToken"], description: "Describe/serve the optional localhost-only, read-only Workbench host. requireToken is a CLI-only opt-in (the MCP path never actually binds, so it is a no-op here)." },
|
|
96
425
|
{ tool: "cw_candidate_summary", capability: "candidate.summary", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the structured candidate summary for a run." },
|
|
97
426
|
{ tool: "cw_feedback_summary", capability: "feedback.summary", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the structured feedback summary for a run." },
|
|
@@ -109,7 +438,7 @@ exports.MCP_TOOL_DATA = [
|
|
|
109
438
|
{ tool: "cw_multi_agent_summarize", capability: "multi-agent.summarize", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read the combined state-explosion report." },
|
|
110
439
|
{ tool: "cw_multi_agent_graph_compact", capability: "multi-agent.graph.compact", requiredArgs: ["runId"], properties: ["runId", "cwd", "view", "focus", "depth"], description: "Read a compact/focused multi-agent graph view." },
|
|
111
440
|
{ tool: "cw_multi_agent_run", capability: "multi-agent.run", requiredArgs: [], properties: ["runId", "cwd", "app", "appId", "workflow", "workflowId", "topology", "topologyId", "task", "mapperCount", "judgeCount", "debateRounds"], description: "Create or attach a topology-backed multi-agent run." },
|
|
112
|
-
{ tool: "cw_multi_agent_status", capability: "multi-agent.status", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read combined topology/blackboard/worker status." },
|
|
441
|
+
{ tool: "cw_multi_agent_status", capability: "multi-agent.status", requiredArgs: ["runId"], properties: ["runId", "cwd"], description: "Read combined topology/blackboard/worker status. Best for a multi-agent run: what each agent group is doing and what is blocked. For a plain run use cw_status; for every panel in one call use cw_workbench_view." },
|
|
113
442
|
{ tool: "cw_multi_agent_step", capability: "multi-agent.step", requiredArgs: ["runId"], properties: ["runId", "cwd", "sandbox", "backend", "limit"], description: "Perform one safe deterministic host step." },
|
|
114
443
|
{ tool: "cw_multi_agent_blackboard", capability: "multi-agent.blackboard", requiredArgs: ["runId"], properties: ["runId", "cwd", "action", "blackboardId", "topicId", "body", "kind", "path", "evidence"], description: "Operate on the active multi-agent blackboard." },
|
|
115
444
|
{ tool: "cw_multi_agent_score", capability: "multi-agent.score", requiredArgs: ["runId"], properties: ["runId", "cwd", "candidate", "candidateId", "worker", "criterion", "criteria", "evidence", "maxTotal"], description: "Score a candidate with evidence." },
|
|
@@ -168,7 +497,7 @@ exports.MCP_TOOL_DATA = [
|
|
|
168
497
|
{ tool: "cw_sandbox_show", capability: "sandbox.show", requiredArgs: ["profileId"], properties: ["cwd", "profileId"], description: "Show a resolved sandbox profile." },
|
|
169
498
|
{ tool: "cw_sandbox_validate", capability: "sandbox.validate", requiredArgs: ["profileFile"], properties: ["cwd", "profileFile"], description: "Validate a sandbox profile JSON file." },
|
|
170
499
|
{ tool: "cw_sandbox_choose", capability: "sandbox.choose", requiredArgs: [], properties: ["cwd", "profileId", "sandbox", "sandboxProfile", "sandboxProfileId"], description: "Resolve and validate a sandbox profile choice." },
|
|
171
|
-
{ tool: "cw_sandbox_resolve", capability: "sandbox.resolve", requiredArgs: [], properties: ["cwd", "profileId", "sandbox", "sandboxProfile", "sandboxProfileId"], description: "Alias of sandbox.choose." },
|
|
500
|
+
{ tool: "cw_sandbox_resolve", capability: "sandbox.resolve", requiredArgs: [], properties: ["cwd", "profileId", "sandbox", "sandboxProfile", "sandboxProfileId"], description: "Alias of sandbox.choose: a pure alias with the same input and the same output. Prefer cw_sandbox_choose." },
|
|
172
501
|
{ tool: "cw_backend_list", capability: "backend.list", requiredArgs: [], properties: ["cwd"], description: "List available execution backends and their capabilities." },
|
|
173
502
|
{ tool: "cw_backend_show", capability: "backend.show", requiredArgs: [], properties: ["cwd", "backendId"], description: "Show one execution backend descriptor." },
|
|
174
503
|
{ tool: "cw_backend_probe", capability: "backend.probe", requiredArgs: [], properties: ["cwd", "backendId"], description: "Probe execution backend readiness (live, deterministic)." },
|
|
@@ -257,8 +586,8 @@ exports.MCP_TOOL_DATA = [
|
|
|
257
586
|
{ tool: "cw_sched_reset", capability: "sched.reset", requiredArgs: [], properties: ["cwd", "id"], description: "Reset a parked entry to ready (operator recovery)." },
|
|
258
587
|
{ tool: "cw_sched_policy_show", capability: "sched.policy.show", requiredArgs: [], properties: ["cwd"], description: "Show the scheduling policy (file or default)." },
|
|
259
588
|
{ tool: "cw_sched_policy_set", capability: "sched.policy.set", requiredArgs: [], properties: ["cwd", "maxConcurrent", "maxAttempts", "leaseTtlMs", "backoffBaseMs", "backoffFactor", "backoffCapMs"], description: "Set scheduling policy fields (concurrency/attempts/backoff/TTL)." },
|
|
260
|
-
{ tool: "cw_gc_plan", capability: "gc.plan", requiredArgs: [], properties: ["cwd", "scope", "runId", "reclaimAfterArchiveDays", "keepScratch", "keepSnapshots"], description: "Dry-run plan of run reclamation (per-kind bytes + capability downgrade); frees nothing." },
|
|
261
|
-
{ tool: "cw_gc_run", capability: "gc.run", requiredArgs: [], properties: ["cwd", "scope", "runId", "reclaimAfterArchiveDays", "keepScratch", "keepSnapshots", "limit", "actor"], description: "Execute the write-ahead reclamation transaction (skeleton -> tombstone -> fsync -> free)." },
|
|
589
|
+
{ tool: "cw_gc_plan", capability: "gc.plan", requiredArgs: [], properties: ["cwd", "scope", "runId", "reclaimAfterArchiveDays", "keepScratch", "keepSnapshots", "keepCommits"], description: "Dry-run plan of run reclamation (per-kind bytes + capability downgrade); frees nothing." },
|
|
590
|
+
{ tool: "cw_gc_run", capability: "gc.run", requiredArgs: [], properties: ["cwd", "scope", "runId", "reclaimAfterArchiveDays", "keepScratch", "keepSnapshots", "keepCommits", "limit", "actor"], description: "Execute the write-ahead reclamation transaction (skeleton -> tombstone -> fsync -> free)." },
|
|
262
591
|
{ tool: "cw_gc_verify", capability: "gc.verify", requiredArgs: ["runId"], properties: ["cwd", "scope", "runId"], description: "Re-prove a reclaimed run: skeleton-complete, tombstone chain untampered, artifacts reconstructable." },
|
|
263
592
|
{ tool: "cw_clones_list", capability: "clones.list", requiredArgs: [], properties: [], description: "List the cached remote-source checkouts that --link/URL reviews populate (origin URL, kind, commit, age, bytes). Read-only." },
|
|
264
593
|
{ tool: "cw_clones_gc", capability: "clones.gc", requiredArgs: [], properties: ["olderThanDays", "all"], description: "Reclaim cached remote-source checkouts: a TTL sweep (--older-than-days, default 30) or --all. Deletes only inside the clones cache." },
|
package/dist/core/format/help.js
CHANGED
|
@@ -30,6 +30,7 @@ exports.formatHelp = formatHelp;
|
|
|
30
30
|
exports.formatCommandHelp = formatCommandHelp;
|
|
31
31
|
exports.formatInfo = formatInfo;
|
|
32
32
|
exports.formatSearchResults = formatSearchResults;
|
|
33
|
+
exports.formatWorkflowList = formatWorkflowList;
|
|
33
34
|
const capability_table_1 = require("../capability-table");
|
|
34
35
|
/** src/orchestrator.ts:934-951 — the "More commands" token set, in the old
|
|
35
36
|
* build's order (space-joined in the source, pipe-joined for display).
|
|
@@ -228,7 +229,12 @@ const COMMAND_HELP_ROWS = {
|
|
|
228
229
|
* capability-table rows that now support `--json`/`--format json`
|
|
229
230
|
* (io.ts's wantsJson) — the flag existed but was never documented here —
|
|
230
231
|
* and for a `--quiet` Flags row, a new CLI spelling of the existing
|
|
231
|
-
* CW_DRIVE_PROGRESS=0 env var (see cli/entry.ts)
|
|
232
|
+
* CW_DRIVE_PROGRESS=0 env var (see cli/entry.ts); and for a `--resume`
|
|
233
|
+
* Flags row (architecture-review-driven fix), documenting the existing
|
|
234
|
+
* `--resume --run <id>` continuation flag (shell/pipeline-cli.ts's
|
|
235
|
+
* quickstartRun) that previously existed only in code comments and an
|
|
236
|
+
* auto-generated continue hint — a user who never happened to type it
|
|
237
|
+
* first had no way to discover it via `cw help`. */
|
|
232
238
|
function formatHelp() {
|
|
233
239
|
const moreCommandsLines = wrapPipeJoined(exports.MORE_COMMANDS_TOKENS, MORE_COMMANDS_WRAP_WIDTH);
|
|
234
240
|
const lines = [
|
|
@@ -247,12 +253,14 @@ function formatHelp() {
|
|
|
247
253
|
" -claude Use Claude agent",
|
|
248
254
|
" -codex Use Codex agent",
|
|
249
255
|
" -gemini Use Gemini (via opencode)",
|
|
256
|
+
" -opencode Use OpenCode agent",
|
|
250
257
|
" -deepseek Use DeepSeek (via opencode)",
|
|
251
258
|
" --verbose Show full agent narration live (default: compact)",
|
|
252
259
|
" --full Verbose, plus the report printed inline at the end",
|
|
253
260
|
" --no-color Disable ANSI color (also honors NO_COLOR / FORCE_COLOR)",
|
|
254
261
|
" --json Print JSON for commands that support it",
|
|
255
262
|
" --quiet Suppress [drive] progress lines (not agent output)",
|
|
263
|
+
" --resume --run <id> Continue an interrupted run to completion",
|
|
256
264
|
"",
|
|
257
265
|
"More commands",
|
|
258
266
|
...moreCommandsLines,
|
|
@@ -270,16 +278,44 @@ function formatHelp() {
|
|
|
270
278
|
function cliCommandHelpRows(verb) {
|
|
271
279
|
return (0, capability_table_1.cliCapabilities)()
|
|
272
280
|
.filter((row) => row.cli.path[0] === verb && !row.cli.hiddenFromHelp)
|
|
273
|
-
.map((row) => ({
|
|
281
|
+
.map((row) => ({
|
|
282
|
+
command: `cw ${(row.cli.helpPath ?? row.cli.path).join(" ")}`,
|
|
283
|
+
summary: row.summary,
|
|
284
|
+
...(row.cli.flags ? { flags: row.cli.flags } : {}),
|
|
285
|
+
}));
|
|
286
|
+
}
|
|
287
|
+
/** A verb that is only a `caseTokens` alias of another verb's row (e.g.
|
|
288
|
+
* `audit-run` -> `quickstart`) has NO row whose `cli.path[0]` matches it,
|
|
289
|
+
* so `cliCommandHelpRows` above finds nothing for it. This looks the
|
|
290
|
+
* alias up the same way the dispatcher does (registry-core.ts's
|
|
291
|
+
* findCapabilityByCliPath alias branch: a row whose `caseTokens` holds
|
|
292
|
+
* the token) and returns the verb the alias dispatches to. */
|
|
293
|
+
function aliasTargetVerb(verb) {
|
|
294
|
+
for (const row of (0, capability_table_1.cliCapabilities)()) {
|
|
295
|
+
if (row.cli.caseTokens && row.cli.caseTokens.includes(verb) && row.cli.path[0] !== verb) {
|
|
296
|
+
return row.cli.path[0];
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return undefined;
|
|
274
300
|
}
|
|
275
301
|
/** src/orchestrator.ts:988-1007 — `formatCommandHelp(verb)`. Unknown verb
|
|
276
302
|
* gives a SOFT text (never a throw); known verb lists its registry rows,
|
|
277
303
|
* sorted by command string, padded to the longest command column + 2
|
|
278
304
|
* (capped at 40, per the old registry's own cap; none of the milestone-1
|
|
279
|
-
* fixture rows exceed it).
|
|
305
|
+
* fixture rows exceed it). An alias verb (a `caseTokens` token like
|
|
306
|
+
* `audit-run`) gets an alias header line plus its target verb's rows —
|
|
307
|
+
* before this fix it fell into the unknown-verb text and, worse, the
|
|
308
|
+
* Did-you-mean line suggested the very verb the user just typed. */
|
|
280
309
|
function formatCommandHelp(verb, suggestCommand) {
|
|
281
310
|
const rows = [...(COMMAND_HELP_ROWS[verb] ?? []), ...cliCommandHelpRows(verb)];
|
|
282
311
|
if (rows.length === 0) {
|
|
312
|
+
const target = aliasTargetVerb(verb);
|
|
313
|
+
if (target) {
|
|
314
|
+
const targetRows = [...(COMMAND_HELP_ROWS[target] ?? []), ...cliCommandHelpRows(target)];
|
|
315
|
+
if (targetRows.length > 0) {
|
|
316
|
+
return renderCommandHelpRows(`cw ${verb} — alias of cw ${target}`, targetRows);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
283
319
|
const hint = suggestCommand(verb);
|
|
284
320
|
const lines = [`Unknown command: ${verb}`];
|
|
285
321
|
if (hint)
|
|
@@ -287,13 +323,40 @@ function formatCommandHelp(verb, suggestCommand) {
|
|
|
287
323
|
lines.push(" Try: cw help (list all commands)");
|
|
288
324
|
return `${lines.join("\n")}\n`;
|
|
289
325
|
}
|
|
326
|
+
return renderCommandHelpRows(`cw ${verb}`, rows);
|
|
327
|
+
}
|
|
328
|
+
/** The row-list rendering `formatCommandHelp` has always done, extracted
|
|
329
|
+
* so the alias page above can render its target's rows under its own
|
|
330
|
+
* header line without a second copy of the sort/pad/Flags logic. */
|
|
331
|
+
function renderCommandHelpRows(header, rows) {
|
|
290
332
|
const sorted = [...rows].sort((a, b) => (a.command < b.command ? -1 : a.command > b.command ? 1 : 0));
|
|
291
333
|
const longest = Math.min(40, Math.max(...sorted.map((row) => row.command.length)));
|
|
292
|
-
const lines = [
|
|
334
|
+
const lines = [header, ""];
|
|
293
335
|
for (const row of sorted) {
|
|
294
336
|
const padded = row.command.padEnd(longest, " ");
|
|
295
337
|
lines.push(` ${padded} ${row.summary}`);
|
|
296
338
|
}
|
|
339
|
+
// Flags block(s): only for rows that declare at least one flag (most
|
|
340
|
+
// rows do not — see CliBinding.flags). Uses the SAME 4-space indent as
|
|
341
|
+
// formatHelp's own "Run cw help <command> ..." note above, on purpose:
|
|
342
|
+
// the CLI/MCP parity help-token parser reads only 2-space lines as
|
|
343
|
+
// command tokens, so any wider indent is a line it already knows to
|
|
344
|
+
// skip. One row's command name is only spelled out in the block's own
|
|
345
|
+
// header when more than one row on this page declares flags (e.g.
|
|
346
|
+
// "cw ledger" lists both propose and review); a single-row page (e.g.
|
|
347
|
+
// "cw doctor") just says "Flags".
|
|
348
|
+
const flaggedRows = sorted.filter((row) => row.flags && row.flags.length > 0);
|
|
349
|
+
if (flaggedRows.length > 0) {
|
|
350
|
+
const oneFlaggedRow = flaggedRows.length === 1;
|
|
351
|
+
for (const row of flaggedRows) {
|
|
352
|
+
const flags = row.flags;
|
|
353
|
+
const flagWidth = Math.min(40, Math.max(...flags.map((flag) => flag.name.length)));
|
|
354
|
+
lines.push("", oneFlaggedRow ? " Flags" : ` Flags (${row.command})`);
|
|
355
|
+
for (const flag of flags) {
|
|
356
|
+
lines.push(` ${flag.name.padEnd(flagWidth, " ")} ${flag.summary}`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
297
360
|
return `${lines.join("\n")}\n`;
|
|
298
361
|
}
|
|
299
362
|
/** `cw info <id>` human card — MILESTONE 12. Byte-exact in spirit to
|
|
@@ -354,3 +417,16 @@ function formatSearchResults(keyword, results) {
|
|
|
354
417
|
lines.push("Use cw info <id> for full details.");
|
|
355
418
|
return lines.join("\n");
|
|
356
419
|
}
|
|
420
|
+
/** `cw list`'s TTY-only human text (the `list` row's `humanRender`, see
|
|
421
|
+
* core/capability-data.ts's CliBinding). Modeled on formatSearchResults
|
|
422
|
+
* above: one "<id> — <title>" line per workflow, then the same short
|
|
423
|
+
* next-step footer. NEVER printed to a pipe — the row's canonical JSON
|
|
424
|
+
* stays the only piped output (SPEC/cli-surface.md's jsonMode contract:
|
|
425
|
+
* "default" verbs are always JSON on a non-TTY stream). */
|
|
426
|
+
function formatWorkflowList(workflows) {
|
|
427
|
+
const rows = (Array.isArray(workflows) ? workflows : []);
|
|
428
|
+
const lines = rows.map((w) => `${w.id} — ${w.title}`);
|
|
429
|
+
lines.push("");
|
|
430
|
+
lines.push("Use cw info <id> for full details.");
|
|
431
|
+
return lines.join("\n");
|
|
432
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// core/format/recovery-hint.ts — recoveryHint, a pure content-based lookup
|
|
3
|
+
// from a thrown error's message to ONE copy-pasteable follow-up command.
|
|
4
|
+
//
|
|
5
|
+
// src/cli.ts:18-29 in the old build. Moved here (out of cli/entry.ts) so
|
|
6
|
+
// mcp/server.ts can use the same lookup for its own error text without
|
|
7
|
+
// crossing the mcp/-may-never-import-cli/ layer rule that
|
|
8
|
+
// scripts/purity-gate.js enforces — core/ may be read by both cli/ and
|
|
9
|
+
// mcp/. cli/entry.ts now just re-exports this function; its own call
|
|
10
|
+
// site and behavior are unchanged.
|
|
11
|
+
//
|
|
12
|
+
// Content-based (reads the message text, not the call site), so it stays
|
|
13
|
+
// correct no matter which command or tool threw. Returns `undefined`
|
|
14
|
+
// rather than a wrong guess when no pattern matches.
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.recoveryHint = recoveryHint;
|
|
17
|
+
function recoveryHint(message) {
|
|
18
|
+
const m = message.toLowerCase();
|
|
19
|
+
if (m.startsWith("unknown command"))
|
|
20
|
+
return "cw help";
|
|
21
|
+
if (m.includes("not configured") || m.includes("agent backend"))
|
|
22
|
+
return "cw doctor";
|
|
23
|
+
if (m.includes("missing") && m.includes("repo"))
|
|
24
|
+
return 'cw -q "<question>" -dir <project-folder>';
|
|
25
|
+
if (m.includes("app") && (m.includes("not found") || m.includes("not available")))
|
|
26
|
+
return "cw app list";
|
|
27
|
+
if (m.includes("run id") || m.includes("run not found"))
|
|
28
|
+
return "cw run list";
|
|
29
|
+
if (m.includes("missing required input") && m.includes("question"))
|
|
30
|
+
return 'cw -q "<question>"';
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|