cclaw-cli 0.32.0 → 0.34.0
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/README.md +47 -19
- package/dist/content/diff-command.js +66 -20
- package/dist/content/harness-playbooks.d.ts +24 -0
- package/dist/content/harness-playbooks.js +292 -0
- package/dist/content/harnesses-doc.js +13 -3
- package/dist/content/status-command.js +89 -27
- package/dist/content/subagents.js +14 -8
- package/dist/content/tree-command.js +66 -16
- package/dist/delegation.d.ts +28 -0
- package/dist/delegation.js +47 -7
- package/dist/doctor.js +18 -2
- package/dist/harness-adapters.d.ts +40 -1
- package/dist/harness-adapters.js +24 -5
- package/dist/install.js +36 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -133,7 +133,7 @@ inside `/cc-ops` subcommands.
|
|
|
133
133
|
| **`/cc <idea>`** | Classify the task, discover origin docs (`docs/prd/**`, ADRs, root `PRD.md`, …), sniff the stack, recommend a track, then start the first stage of that track. `/cc` without arguments resumes the current flow. |
|
|
134
134
|
| **`/cc-next`** | The one progression primitive. Reads `flow-state.json`, checks gates + mandatory subagent delegations, and either resumes the current stage or advances to the next. `/cc-next` in a new session is how you **resume**. |
|
|
135
135
|
| **`/cc-ideate`** | Repository improvement discovery. Scans for TODOs, flaky tests, oversized modules, docs drift, and recurring knowledge-store lessons; returns a ranked backlog before you commit to a specific feature. |
|
|
136
|
-
| **`/cc-view`** | Read-only flow visibility. `/cc-view status` (default), `/cc-view tree
|
|
136
|
+
| **`/cc-view`** | Read-only flow visibility. `/cc-view status` (default) shows stage progress, mandatory delegations with their fulfillment mode (isolated / generic-dispatch / role-switch), the ship closeout substate (retro → compound → archive), and the active harness parity row. `/cc-view tree` renders the same picture as a tree with a closeout sub-branch under ship and a per-harness playbook summary. `/cc-view diff` shows stage/gate/closeout/delegation deltas since the last run. Never mutates state (except diff's snapshot baseline). |
|
|
137
137
|
|
|
138
138
|
> Power-user surface: `/cc-ops` is an operational router for manual
|
|
139
139
|
> overrides (rewind a stale stage, manage parallel features, re-run a
|
|
@@ -277,9 +277,8 @@ The `tdd` stage is not prose guidance. It requires:
|
|
|
277
277
|
- optional **REFACTOR** pass with coverage preservation
|
|
278
278
|
|
|
279
279
|
`/cc-next` will not advance past `tdd` until the delegation log shows the
|
|
280
|
-
subagent as `completed` or
|
|
281
|
-
|
|
282
|
-
[Harness support](#harness-support)).
|
|
280
|
+
subagent as `completed` (or, on Codex / OpenCode, role-switched with
|
|
281
|
+
`evidenceRefs` — see [Harness support](#harness-support)).
|
|
283
282
|
|
|
284
283
|
---
|
|
285
284
|
|
|
@@ -320,21 +319,50 @@ to: `/cc-next` is the only command.
|
|
|
320
319
|
|
|
321
320
|
## Harness support
|
|
322
321
|
|
|
323
|
-
cclaw is honest about
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
|
330
|
-
|
|
|
331
|
-
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
native
|
|
336
|
-
|
|
337
|
-
|
|
322
|
+
cclaw is honest about what each harness can and cannot do, and it
|
|
323
|
+
closes every real gap with a documented fallback — not a silent waiver.
|
|
324
|
+
|
|
325
|
+
| Harness | Dispatch | Fallback | Hook surface | Structured ask | Playbook |
|
|
326
|
+
|---|---|---|---|---|---|
|
|
327
|
+
| Claude Code | full (named subagents) | `native` | full | `AskUserQuestion` | [`claude-playbook.md`](./src/content/harness-playbooks.ts) |
|
|
328
|
+
| Cursor | generic Task dispatcher | `generic-dispatch` | full | `AskQuestion` | `cursor-playbook.md` |
|
|
329
|
+
| OpenCode | plugin / in-session | `role-switch` | plugin | plain-text | `opencode-playbook.md` |
|
|
330
|
+
| OpenAI Codex | in-session only | `role-switch` (evidenceRefs required) | full | plain-text | `codex-playbook.md` |
|
|
331
|
+
|
|
332
|
+
What the fallbacks mean:
|
|
333
|
+
|
|
334
|
+
- `native` — Claude runs mandatory delegations in isolated subagent
|
|
335
|
+
workers; cclaw records them with `fulfillmentMode: "isolated"`.
|
|
336
|
+
- `generic-dispatch` — Cursor has a real Task tool with a fixed
|
|
337
|
+
vocabulary of `subagent_type`s (`explore`, `generalPurpose`, …).
|
|
338
|
+
cclaw maps each named agent (planner / reviewer / test-author /
|
|
339
|
+
security-reviewer / doc-updater) onto the generic dispatcher with a
|
|
340
|
+
structured role prompt. Per-agent mapping lives in the Cursor
|
|
341
|
+
playbook.
|
|
342
|
+
- `role-switch` — OpenCode and Codex lack an isolated worker primitive.
|
|
343
|
+
The agent announces the role in-session, performs the work, and
|
|
344
|
+
records a delegation row with `fulfillmentMode: "role-switch"` and at
|
|
345
|
+
least one `evidenceRef` pointing at the artifact section that
|
|
346
|
+
captures the output. Under role-switch, a `completed` row **without**
|
|
347
|
+
evidenceRefs is classified as `missingEvidence` by `cclaw doctor` and
|
|
348
|
+
blocks stage completion.
|
|
349
|
+
- `waiver` — reserved. Only fires auto-waivers if every installed
|
|
350
|
+
harness declares it. Currently unused — v0.33 removed the old
|
|
351
|
+
Codex-only auto-waiver path.
|
|
352
|
+
|
|
353
|
+
The full capability matrix lives in
|
|
354
|
+
[`docs/harnesses.md`](./docs/harnesses.md). Per-harness playbooks are
|
|
355
|
+
generated into `.cclaw/references/harnesses/` on every install and
|
|
356
|
+
upgrade; stage skills cite them by path.
|
|
357
|
+
|
|
358
|
+
Runtime state:
|
|
359
|
+
|
|
360
|
+
- `.cclaw/state/harness-gaps.json` (schema v2) — per-harness list of
|
|
361
|
+
missing capabilities, missing hook events, the declared fallback, the
|
|
362
|
+
playbook path, and a `remediation[]` list you can act on.
|
|
363
|
+
- `cclaw doctor` — asserts every installed harness has its playbook on
|
|
364
|
+
disk and surfaces the expected fulfillment mode inside the
|
|
365
|
+
`delegation:mandatory:current_stage` check.
|
|
338
366
|
|
|
339
367
|
---
|
|
340
368
|
|
|
@@ -7,12 +7,23 @@ function flowStatePath() {
|
|
|
7
7
|
function snapshotPath() {
|
|
8
8
|
return `${RUNTIME_ROOT}/state/flow-state.snapshot.json`;
|
|
9
9
|
}
|
|
10
|
+
function delegationLogPath() {
|
|
11
|
+
return `${RUNTIME_ROOT}/state/delegation-log.json`;
|
|
12
|
+
}
|
|
13
|
+
function retroArtifactPath() {
|
|
14
|
+
return `${RUNTIME_ROOT}/artifacts/09-retro.md`;
|
|
15
|
+
}
|
|
10
16
|
export function diffCommandContract() {
|
|
11
17
|
return `# /cc-view diff
|
|
12
18
|
|
|
13
19
|
## Purpose
|
|
14
20
|
|
|
15
|
-
Show a visual before/after diff map for flow-state progression.
|
|
21
|
+
Show a visual before/after diff map for flow-state progression. Covers the core
|
|
22
|
+
stage/gate transitions plus:
|
|
23
|
+
|
|
24
|
+
- ship **closeout substate** transitions (\`retro_review\` → \`compound_review\` → \`ready_to_archive\`),
|
|
25
|
+
- delegation **fulfillmentMode** transitions per mandatory agent,
|
|
26
|
+
- appearance or removal of the retro artifact \`09-retro.md\`.
|
|
16
27
|
|
|
17
28
|
## HARD-GATE
|
|
18
29
|
|
|
@@ -21,16 +32,27 @@ Show a visual before/after diff map for flow-state progression.
|
|
|
21
32
|
|
|
22
33
|
## Algorithm
|
|
23
34
|
|
|
24
|
-
1. Read current state from \`${flowStatePath()}
|
|
25
|
-
2. Read
|
|
26
|
-
3.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
1. Read current state from \`${flowStatePath()}\` (including \`closeout\`).
|
|
36
|
+
2. Read current delegation log from \`${delegationLogPath()}\` (if missing treat as empty).
|
|
37
|
+
3. Read baseline from \`${snapshotPath()}\` (if missing -> create baseline from
|
|
38
|
+
current state **plus** a copy of the current delegation log; report
|
|
39
|
+
\`flow diff baseline created\` and stop).
|
|
40
|
+
4. Compute deltas:
|
|
41
|
+
- stage transition (\`from -> to\`),
|
|
42
|
+
- completed stage additions/removals,
|
|
43
|
+
- skipped stage additions/removals,
|
|
44
|
+
- stale stage additions/removals,
|
|
45
|
+
- current-stage gate \`passed\` and \`blocked\` changes,
|
|
46
|
+
- \`closeout.shipSubstate\` transition (\`from -> to\`),
|
|
47
|
+
- \`closeout.retroDraftedAt\` / \`retroAcceptedAt\` / \`retroSkipped\` flips,
|
|
48
|
+
- \`closeout.compoundPromoted\` / \`compoundSkipped\` flips,
|
|
49
|
+
- per-agent \`fulfillmentMode\` transitions from the baseline delegation log,
|
|
50
|
+
- appearance (\`+\`) or disappearance (\`-\`) of \`${retroArtifactPath()}\`.
|
|
51
|
+
5. Render a compact diff map (added \`+\`, removed \`-\`, changed \`->\`).
|
|
52
|
+
6. Persist current state back to \`${snapshotPath()}\` as new baseline with
|
|
53
|
+
\`capturedAt\` and an embedded \`delegations\` projection
|
|
54
|
+
(\`{ agent, status, fulfillmentMode }[]\`) so fulfillmentMode transitions are
|
|
55
|
+
computable on the next run.
|
|
34
56
|
|
|
35
57
|
## Diff Map Format
|
|
36
58
|
|
|
@@ -41,8 +63,18 @@ cclaw flow diff
|
|
|
41
63
|
stale: -design
|
|
42
64
|
gates(spec): +spec_contract_complete -spec_open_questions_closed
|
|
43
65
|
blocked(spec): +spec_trace_matrix_missing
|
|
66
|
+
closeout: idle -> retro_review
|
|
67
|
+
retro: +drafted (09-retro.md appeared)
|
|
68
|
+
delegations:
|
|
69
|
+
- reviewer: scheduled -> completed (mode=generic-dispatch)
|
|
70
|
+
- test-author: mode=? -> role-switch (evidenceRefs=2)
|
|
44
71
|
\`\`\`
|
|
45
72
|
|
|
73
|
+
- The \`closeout:\` line is omitted when \`shipSubstate\` is unchanged.
|
|
74
|
+
- The \`delegations:\` block is omitted when no agent changed status or mode.
|
|
75
|
+
- The \`retro:\` line is emitted only on artifact appearance/removal or on a
|
|
76
|
+
\`retroAcceptedAt\` / \`retroSkipped\` flip.
|
|
77
|
+
|
|
46
78
|
## Primary skill
|
|
47
79
|
|
|
48
80
|
**${RUNTIME_ROOT}/skills/${DIFF_SKILL_FOLDER}/SKILL.md**
|
|
@@ -51,7 +83,7 @@ cclaw flow diff
|
|
|
51
83
|
export function diffCommandSkillMarkdown() {
|
|
52
84
|
return `---
|
|
53
85
|
name: ${DIFF_SKILL_NAME}
|
|
54
|
-
description: "Compare current flow-state against saved snapshot and render gate/stage deltas."
|
|
86
|
+
description: "Compare current flow-state against saved snapshot and render gate/stage/closeout/delegation deltas."
|
|
55
87
|
---
|
|
56
88
|
|
|
57
89
|
# /cc-view diff
|
|
@@ -63,21 +95,35 @@ Never lose baseline visibility: render deltas before writing a new snapshot.
|
|
|
63
95
|
## Protocol
|
|
64
96
|
|
|
65
97
|
1. Read \`${flowStatePath()}\`.
|
|
66
|
-
2. Read \`${
|
|
67
|
-
3.
|
|
68
|
-
|
|
98
|
+
2. Read \`${delegationLogPath()}\` (missing → treat as empty list).
|
|
99
|
+
3. Read \`${snapshotPath()}\`.
|
|
100
|
+
4. If snapshot missing:
|
|
101
|
+
- write baseline snapshot from current state **plus** a
|
|
102
|
+
\`delegations\` projection (\`{ agent, status, fulfillmentMode }[]\`),
|
|
69
103
|
- print \`flow diff baseline created\`,
|
|
70
104
|
- stop.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
- \`
|
|
75
|
-
- \`
|
|
105
|
+
5. Build deltas for:
|
|
106
|
+
- stage, completed/skipped/stale sets,
|
|
107
|
+
- current-stage gate arrays (\`passed\`, \`blocked\`),
|
|
108
|
+
- \`closeout.shipSubstate\` transitions (\`from -> to\`),
|
|
109
|
+
- \`closeout.retroDraftedAt\` / \`retroAcceptedAt\` / \`retroSkipped\` flips,
|
|
110
|
+
- \`closeout.compoundPromoted\` / \`compoundSkipped\` / \`compoundCompletedAt\` flips,
|
|
111
|
+
- per-agent \`fulfillmentMode\` transitions by matching baseline delegations
|
|
112
|
+
against current delegations on \`agent\` + latest entry,
|
|
113
|
+
- appearance or removal of \`${retroArtifactPath()}\` on disk.
|
|
114
|
+
6. Print a compact diff map with explicit \`+\`, \`-\`, and \`->\` markers.
|
|
115
|
+
7. Write updated snapshot with:
|
|
116
|
+
- \`capturedAt\` (ISO),
|
|
117
|
+
- \`state\` (full current flow-state object),
|
|
118
|
+
- \`delegations\` projection from the current log.
|
|
76
119
|
|
|
77
120
|
## Validation
|
|
78
121
|
|
|
79
122
|
- Diff output must be deterministic for identical states ("no changes").
|
|
80
123
|
- Snapshot file stays valid JSON after every run.
|
|
81
124
|
- Do not suppress removed values; removals are first-class evidence.
|
|
125
|
+
- Closeout diff lines must use the same \`shipSubstate\` vocabulary as the
|
|
126
|
+
state machine (\`idle\` / \`retro_review\` / \`compound_review\` /
|
|
127
|
+
\`ready_to_archive\` / \`archived\`).
|
|
82
128
|
`;
|
|
83
129
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-harness parity playbooks.
|
|
3
|
+
*
|
|
4
|
+
* cclaw's subagent contracts (planner / reviewer / security-reviewer /
|
|
5
|
+
* test-author / doc-updater) assume Claude-style isolated workers. On
|
|
6
|
+
* harnesses without that primitive, the agent has to fulfil the role via a
|
|
7
|
+
* documented fallback (generic Task dispatch, role-switch in-session, …).
|
|
8
|
+
*
|
|
9
|
+
* Each playbook is:
|
|
10
|
+
* 1. short (≤ ~150 lines markdown),
|
|
11
|
+
* 2. executable — reproducible by an agent without reading the whole repo,
|
|
12
|
+
* 3. evidence-first — always records a delegation-log entry with
|
|
13
|
+
* `fulfillmentMode` and `evidenceRefs` so `cclaw doctor` can tell the
|
|
14
|
+
* role was actually performed.
|
|
15
|
+
*
|
|
16
|
+
* Playbooks are materialised at
|
|
17
|
+
* `.cclaw/references/harnesses/<harness>-playbook.md` by install/sync/upgrade.
|
|
18
|
+
*/
|
|
19
|
+
import type { HarnessId } from "../types.js";
|
|
20
|
+
export declare const HARNESS_PLAYBOOKS_DIR = "references/harnesses";
|
|
21
|
+
export declare function harnessPlaybookRelativePath(harness: HarnessId): string;
|
|
22
|
+
export declare function harnessPlaybookFileName(harness: HarnessId): string;
|
|
23
|
+
export declare function harnessPlaybookMarkdown(harness: HarnessId): string;
|
|
24
|
+
export declare function harnessPlaybooksIndexMarkdown(): string;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-harness parity playbooks.
|
|
3
|
+
*
|
|
4
|
+
* cclaw's subagent contracts (planner / reviewer / security-reviewer /
|
|
5
|
+
* test-author / doc-updater) assume Claude-style isolated workers. On
|
|
6
|
+
* harnesses without that primitive, the agent has to fulfil the role via a
|
|
7
|
+
* documented fallback (generic Task dispatch, role-switch in-session, …).
|
|
8
|
+
*
|
|
9
|
+
* Each playbook is:
|
|
10
|
+
* 1. short (≤ ~150 lines markdown),
|
|
11
|
+
* 2. executable — reproducible by an agent without reading the whole repo,
|
|
12
|
+
* 3. evidence-first — always records a delegation-log entry with
|
|
13
|
+
* `fulfillmentMode` and `evidenceRefs` so `cclaw doctor` can tell the
|
|
14
|
+
* role was actually performed.
|
|
15
|
+
*
|
|
16
|
+
* Playbooks are materialised at
|
|
17
|
+
* `.cclaw/references/harnesses/<harness>-playbook.md` by install/sync/upgrade.
|
|
18
|
+
*/
|
|
19
|
+
import { HARNESS_ADAPTERS } from "../harness-adapters.js";
|
|
20
|
+
export const HARNESS_PLAYBOOKS_DIR = "references/harnesses";
|
|
21
|
+
export function harnessPlaybookRelativePath(harness) {
|
|
22
|
+
return `${HARNESS_PLAYBOOKS_DIR}/${harness}-playbook.md`;
|
|
23
|
+
}
|
|
24
|
+
export function harnessPlaybookFileName(harness) {
|
|
25
|
+
return `${harness}-playbook.md`;
|
|
26
|
+
}
|
|
27
|
+
const CLAUDE_PLAYBOOK = `---
|
|
28
|
+
harness: claude
|
|
29
|
+
fallback: native
|
|
30
|
+
description: "Claude Code has real isolated subagent workers with user-defined named types. No fallback required — this playbook is reference-only."
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
# Claude Code — Parity Playbook
|
|
34
|
+
|
|
35
|
+
**Status: native.** Claude Code supports isolated subagent workers via the
|
|
36
|
+
\`Task\` tool with user-defined \`subagent_type\` (\`planner\`, \`reviewer\`,
|
|
37
|
+
\`security-reviewer\`, \`test-author\`, \`doc-updater\`). Each dispatch runs in
|
|
38
|
+
its own context and produces a return message visible only to the parent
|
|
39
|
+
agent.
|
|
40
|
+
|
|
41
|
+
This playbook exists so the harness matrix has one reference shape; Claude
|
|
42
|
+
itself has no parity gap to close.
|
|
43
|
+
|
|
44
|
+
## Dispatch pattern
|
|
45
|
+
|
|
46
|
+
1. Pick the \`subagent_type\` matching the cclaw agent (e.g. \`reviewer\`).
|
|
47
|
+
2. Provide a specific, self-contained \`prompt\` — the subagent cannot see
|
|
48
|
+
prior assistant turns.
|
|
49
|
+
3. Record a delegation entry before dispatch:
|
|
50
|
+
|
|
51
|
+
\`\`\`json
|
|
52
|
+
{
|
|
53
|
+
"stage": "review",
|
|
54
|
+
"agent": "reviewer",
|
|
55
|
+
"mode": "mandatory",
|
|
56
|
+
"status": "scheduled",
|
|
57
|
+
"fulfillmentMode": "isolated",
|
|
58
|
+
"spanId": "dspan-..."
|
|
59
|
+
}
|
|
60
|
+
\`\`\`
|
|
61
|
+
|
|
62
|
+
4. After the subagent returns, update the entry to \`status: "completed"\`
|
|
63
|
+
and attach \`evidenceRefs\` pointing at the artifact section that
|
|
64
|
+
captures the subagent's output.
|
|
65
|
+
|
|
66
|
+
## Verification
|
|
67
|
+
|
|
68
|
+
\`cclaw doctor\` will pass the \`delegation:mandatory:current_stage\` check
|
|
69
|
+
when each mandatory agent has a \`completed\` row for the active run.
|
|
70
|
+
`;
|
|
71
|
+
const CURSOR_PLAYBOOK = `---
|
|
72
|
+
harness: cursor
|
|
73
|
+
fallback: generic-dispatch
|
|
74
|
+
description: "Cursor has a generic Task dispatcher with subagent_type (generalPurpose, explore, shell, …) but no user-defined named subagents. cclaw maps planner/reviewer/test-author/… onto generic dispatch with a structured role prompt."
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
# Cursor — Parity Playbook
|
|
78
|
+
|
|
79
|
+
**Fallback: generic-dispatch.** Cursor's \`Task\` tool supports
|
|
80
|
+
\`subagent_type\` from a fixed vocabulary (\`generalPurpose\`, \`explore\`,
|
|
81
|
+
\`shell\`, \`browser-use\`, …). Real isolation, but no user-defined agent
|
|
82
|
+
names. cclaw closes the gap by mapping each named cclaw agent onto the
|
|
83
|
+
generic dispatcher with a strict role prompt.
|
|
84
|
+
|
|
85
|
+
## Named-agent → Cursor subagent_type map
|
|
86
|
+
|
|
87
|
+
| cclaw agent | Cursor \`subagent_type\` | Readonly? | Rationale |
|
|
88
|
+
|----------------------|-------------------------|-----------|-----------|
|
|
89
|
+
| \`planner\` | \`explore\` | yes | Pure research, no writes. |
|
|
90
|
+
| \`reviewer\` | \`explore\` | yes | Reads diff + context, emits findings. |
|
|
91
|
+
| \`security-reviewer\`| \`explore\` | yes | Reads code, produces report; no fixes. |
|
|
92
|
+
| \`test-author\` | \`generalPurpose\` | no | Writes tests, runs them, iterates. |
|
|
93
|
+
| \`doc-updater\` | \`generalPurpose\` | no | Edits docs, re-runs build. |
|
|
94
|
+
|
|
95
|
+
## Dispatch pattern
|
|
96
|
+
|
|
97
|
+
1. Pick the mapped \`subagent_type\` from the table above.
|
|
98
|
+
2. Build the \`prompt\` from the cclaw agent contract in
|
|
99
|
+
\`.cclaw/agents/<agent>.md\`, prefaced with a single line naming the
|
|
100
|
+
cclaw role (\`You are the cclaw <agent>. Follow the contract below.\`).
|
|
101
|
+
3. Set \`readonly: true\` when the table says yes — Cursor enforces it.
|
|
102
|
+
4. Before dispatch, append a delegation row:
|
|
103
|
+
|
|
104
|
+
\`\`\`json
|
|
105
|
+
{
|
|
106
|
+
"stage": "tdd",
|
|
107
|
+
"agent": "test-author",
|
|
108
|
+
"mode": "mandatory",
|
|
109
|
+
"status": "scheduled",
|
|
110
|
+
"fulfillmentMode": "generic-dispatch",
|
|
111
|
+
"spanId": "dspan-..."
|
|
112
|
+
}
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
5. After dispatch returns, transition the row to \`completed\` with
|
|
116
|
+
\`evidenceRefs\` citing the artifact anchor where the result landed.
|
|
117
|
+
|
|
118
|
+
## Why not upgrade Cursor to a full tier-1?
|
|
119
|
+
|
|
120
|
+
Cursor has dispatch + hooks + \`AskQuestion\`. The missing piece is
|
|
121
|
+
**user-defined named subagents**. Semantically this is the difference
|
|
122
|
+
between Claude's \`test-author\` (a distinct runtime worker registered by
|
|
123
|
+
cclaw) and Cursor's \`generalPurpose\` worker that cclaw *asks* to act as a
|
|
124
|
+
test-author. Good enough for parity; different enough to keep the labels
|
|
125
|
+
honest.
|
|
126
|
+
|
|
127
|
+
## Verification
|
|
128
|
+
|
|
129
|
+
\`cclaw doctor\` passes when the delegation row exists with
|
|
130
|
+
\`fulfillmentMode: "generic-dispatch"\` (or \`completed\` rows for the
|
|
131
|
+
mandatory agents in general). No evidenceRef requirement applies here —
|
|
132
|
+
Cursor dispatch is real isolation.
|
|
133
|
+
`;
|
|
134
|
+
const OPENCODE_PLAYBOOK = `---
|
|
135
|
+
harness: opencode
|
|
136
|
+
fallback: role-switch
|
|
137
|
+
description: "OpenCode has plugin-based dispatch hooks but no isolated subagent worker primitive. cclaw uses an in-session role-switch with a delegation-log entry + evidenceRefs."
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
# OpenCode — Parity Playbook
|
|
141
|
+
|
|
142
|
+
**Fallback: role-switch.** OpenCode exposes tool/session event hooks via a
|
|
143
|
+
plugin but does not provide an isolated subagent worker. cclaw closes the
|
|
144
|
+
delegation gate by role-switching inside the same session: the agent
|
|
145
|
+
announces the role, performs the work against the contract, and records
|
|
146
|
+
evidence.
|
|
147
|
+
|
|
148
|
+
## Role-switch protocol
|
|
149
|
+
|
|
150
|
+
1. Announce the role explicitly in a single message:
|
|
151
|
+
|
|
152
|
+
> Acting as cclaw **<agent>** per \`.cclaw/agents/<agent>.md\`. No other
|
|
153
|
+
> role may be assumed until the delegation row is closed.
|
|
154
|
+
|
|
155
|
+
2. Execute the role's contract. Do NOT interleave other roles' work.
|
|
156
|
+
3. Write the result into the stage artifact (e.g. TDD work lands in
|
|
157
|
+
\`.cclaw/artifacts/06-tdd.md\`).
|
|
158
|
+
4. Append a delegation row:
|
|
159
|
+
|
|
160
|
+
\`\`\`json
|
|
161
|
+
{
|
|
162
|
+
"stage": "tdd",
|
|
163
|
+
"agent": "test-author",
|
|
164
|
+
"mode": "mandatory",
|
|
165
|
+
"status": "completed",
|
|
166
|
+
"fulfillmentMode": "role-switch",
|
|
167
|
+
"evidenceRefs": [
|
|
168
|
+
".cclaw/artifacts/06-tdd.md#red-run",
|
|
169
|
+
".cclaw/artifacts/06-tdd.md#green-run"
|
|
170
|
+
],
|
|
171
|
+
"spanId": "dspan-..."
|
|
172
|
+
}
|
|
173
|
+
\`\`\`
|
|
174
|
+
|
|
175
|
+
5. \`evidenceRefs\` **must** point at concrete artifact anchors — not
|
|
176
|
+
placeholder text. \`cclaw doctor\` will report \`missingEvidence\` if
|
|
177
|
+
the array is empty under a role-switch fallback.
|
|
178
|
+
|
|
179
|
+
## Exception: OpenCode plugin dispatch
|
|
180
|
+
|
|
181
|
+
If the project configures a plugin-based dispatch path (e.g. a tool that
|
|
182
|
+
spawns a worker process), set \`fulfillmentMode: "generic-dispatch"\`
|
|
183
|
+
instead of \`role-switch\` and omit the role-announce step. evidenceRefs
|
|
184
|
+
remain optional but recommended.
|
|
185
|
+
|
|
186
|
+
## Verification
|
|
187
|
+
|
|
188
|
+
\`cclaw doctor\` passes when every mandatory agent for the active stage
|
|
189
|
+
has either a \`completed\` row with evidenceRefs (role-switch) or a
|
|
190
|
+
\`completed\` row under plugin dispatch.
|
|
191
|
+
`;
|
|
192
|
+
const CODEX_PLAYBOOK = `---
|
|
193
|
+
harness: codex
|
|
194
|
+
fallback: role-switch
|
|
195
|
+
description: "OpenAI Codex has no subagent dispatch primitive. cclaw uses role-switch with evidenceRefs; silent auto-waiver is explicitly disabled."
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
# OpenAI Codex — Parity Playbook
|
|
199
|
+
|
|
200
|
+
**Fallback: role-switch.** Codex has no subagent dispatch — neither named
|
|
201
|
+
nor generic. cclaw used to silently auto-waive mandatory delegations on
|
|
202
|
+
Codex; v0.33 disables that shortcut. The agent must role-switch in-session
|
|
203
|
+
and record evidence, or the delegation gate blocks stage completion.
|
|
204
|
+
|
|
205
|
+
## Role-switch protocol
|
|
206
|
+
|
|
207
|
+
Identical to OpenCode. Key requirements:
|
|
208
|
+
|
|
209
|
+
1. **Explicit announce.** Before performing the role, emit a single
|
|
210
|
+
message naming the role and citing \`.cclaw/agents/<agent>.md\`.
|
|
211
|
+
2. **No role interleaving.** Do not mix, for example, reviewer and
|
|
212
|
+
test-author work into the same turn — close one delegation before
|
|
213
|
+
opening another.
|
|
214
|
+
3. **EvidenceRefs are mandatory.** Under Codex's role-switch fallback a
|
|
215
|
+
\`completed\` row without \`evidenceRefs\` is treated as
|
|
216
|
+
\`missingEvidence\` by \`cclaw doctor\` and blocks the gate.
|
|
217
|
+
|
|
218
|
+
## Stage-specific role maps
|
|
219
|
+
|
|
220
|
+
| Stage | Mandatory roles | Artifact to cite in evidenceRefs |
|
|
221
|
+
|------------|----------------------------------|--------------------------------------|
|
|
222
|
+
| scope | \`planner\` | \`.cclaw/artifacts/02-scope.md\` |
|
|
223
|
+
| design | \`planner\` | \`.cclaw/artifacts/03-design.md\` |
|
|
224
|
+
| plan | \`planner\` | \`.cclaw/artifacts/05-plan.md\` |
|
|
225
|
+
| tdd | \`test-author\` | \`.cclaw/artifacts/06-tdd.md\` |
|
|
226
|
+
| review | \`reviewer\`, \`security-reviewer\` | \`.cclaw/artifacts/07-review.md\` |
|
|
227
|
+
| ship | \`doc-updater\` | \`.cclaw/artifacts/08-ship.md\` |
|
|
228
|
+
|
|
229
|
+
## Why no auto-waiver anymore?
|
|
230
|
+
|
|
231
|
+
Silent auto-waiver on Codex let entire stages complete without any
|
|
232
|
+
reviewer or test-author work. That defeats cclaw's hard gates. v0.33
|
|
233
|
+
replaces it with an explicit role-switch obligation: the agent still gets
|
|
234
|
+
a path forward, but the path is visible in the delegation log.
|
|
235
|
+
|
|
236
|
+
If a team genuinely wants to skip a delegation on Codex, they must
|
|
237
|
+
manually append a \`status: "waived"\` row with a one-line
|
|
238
|
+
\`waiverReason\` — the same audit trail any Claude/Cursor install would
|
|
239
|
+
need.
|
|
240
|
+
|
|
241
|
+
## Verification
|
|
242
|
+
|
|
243
|
+
\`cclaw doctor\` passes when every mandatory agent for the active stage
|
|
244
|
+
has a \`completed\` row with \`fulfillmentMode: "role-switch"\` and at
|
|
245
|
+
least one \`evidenceRef\`.
|
|
246
|
+
`;
|
|
247
|
+
const PLAYBOOK_BY_HARNESS = {
|
|
248
|
+
claude: CLAUDE_PLAYBOOK,
|
|
249
|
+
cursor: CURSOR_PLAYBOOK,
|
|
250
|
+
opencode: OPENCODE_PLAYBOOK,
|
|
251
|
+
codex: CODEX_PLAYBOOK
|
|
252
|
+
};
|
|
253
|
+
export function harnessPlaybookMarkdown(harness) {
|
|
254
|
+
const body = PLAYBOOK_BY_HARNESS[harness];
|
|
255
|
+
if (!body) {
|
|
256
|
+
throw new Error(`No playbook defined for harness "${harness}".`);
|
|
257
|
+
}
|
|
258
|
+
return body;
|
|
259
|
+
}
|
|
260
|
+
export function harnessPlaybooksIndexMarkdown() {
|
|
261
|
+
const rows = Object.keys(HARNESS_ADAPTERS)
|
|
262
|
+
.map((h) => {
|
|
263
|
+
const fallback = HARNESS_ADAPTERS[h].capabilities.subagentFallback;
|
|
264
|
+
return `| \`${h}\` | ${fallback} | [\`${harnessPlaybookFileName(h)}\`](./${harnessPlaybookFileName(h)}) |`;
|
|
265
|
+
})
|
|
266
|
+
.join("\n");
|
|
267
|
+
return `# Harness parity playbooks
|
|
268
|
+
|
|
269
|
+
Each playbook describes the concrete pattern cclaw expects when the
|
|
270
|
+
harness does not natively satisfy a mandatory delegation contract.
|
|
271
|
+
|
|
272
|
+
| Harness | Fallback | Playbook |
|
|
273
|
+
|---|---|---|
|
|
274
|
+
${rows}
|
|
275
|
+
|
|
276
|
+
## How cclaw uses these files
|
|
277
|
+
|
|
278
|
+
- \`cclaw doctor\` verifies that every installed harness has its playbook
|
|
279
|
+
present under \`.cclaw/references/harnesses/\`.
|
|
280
|
+
- Stage skills (TDD, review, ship) cite the active harness's playbook
|
|
281
|
+
instead of inlining the fallback pattern.
|
|
282
|
+
- The \`delegation:mandatory:current_stage\` check expects
|
|
283
|
+
\`fulfillmentMode\` to match the harness's declared \`subagentFallback\`
|
|
284
|
+
(\`isolated\`, \`generic-dispatch\`, or \`role-switch\`).
|
|
285
|
+
|
|
286
|
+
## When to edit
|
|
287
|
+
|
|
288
|
+
Playbooks are generated by \`cclaw upgrade\`. Local edits are overwritten.
|
|
289
|
+
To customise the parity pattern for a specific repository, override the
|
|
290
|
+
skill that cites the playbook, not the playbook itself.
|
|
291
|
+
`;
|
|
292
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { HARNESS_ADAPTERS, harnessTier } from "../harness-adapters.js";
|
|
2
2
|
import { HOOK_EVENTS_BY_HARNESS, HOOK_SEMANTIC_EVENTS } from "./hook-events.js";
|
|
3
|
+
import { HARNESS_PLAYBOOKS_DIR, harnessPlaybookFileName } from "./harness-playbooks.js";
|
|
3
4
|
function harnessTitle(harness) {
|
|
4
5
|
switch (harness) {
|
|
5
6
|
case "claude":
|
|
@@ -25,7 +26,9 @@ export function harnessIntegrationDocMarkdown() {
|
|
|
25
26
|
.map((harness) => {
|
|
26
27
|
const adapter = HARNESS_ADAPTERS[harness];
|
|
27
28
|
const tier = harnessTier(harness);
|
|
28
|
-
|
|
29
|
+
const caps = adapter.capabilities;
|
|
30
|
+
const playbook = `\`${HARNESS_PLAYBOOKS_DIR}/${harnessPlaybookFileName(harness)}\``;
|
|
31
|
+
return `| ${harnessTitle(harness)} | \`${harness}\` | \`${tier}\` (${tierDescription(tier)}) | ${caps.nativeSubagentDispatch} | ${caps.subagentFallback} | ${caps.hookSurface} | ${caps.structuredAsk} | ${playbook} |`;
|
|
29
32
|
})
|
|
30
33
|
.join("\n");
|
|
31
34
|
const hookRows = HOOK_SEMANTIC_EVENTS.map((eventName) => {
|
|
@@ -43,10 +46,17 @@ Generated from \`src/harness-adapters.ts\` capabilities and hook event mappings.
|
|
|
43
46
|
|
|
44
47
|
## Capability tiers
|
|
45
48
|
|
|
46
|
-
| Harness | ID | Tier | Native
|
|
47
|
-
|
|
49
|
+
| Harness | ID | Tier | Native dispatch | Fallback | Hook surface | Structured ask | Playbook |
|
|
50
|
+
|---|---|---|---|---|---|---|---|
|
|
48
51
|
${capabilityRows}
|
|
49
52
|
|
|
53
|
+
Fallback legend:
|
|
54
|
+
|
|
55
|
+
- \`native\` — first-class named subagent dispatch (Claude).
|
|
56
|
+
- \`generic-dispatch\` — generic Task dispatcher mapped to cclaw roles (Cursor).
|
|
57
|
+
- \`role-switch\` — in-session role announce + delegation-log entry with evidenceRefs (OpenCode, Codex).
|
|
58
|
+
- \`waiver\` — no parity path; reserved for harnesses that cannot role-switch (none shipped).
|
|
59
|
+
|
|
50
60
|
## Semantic hook event coverage
|
|
51
61
|
|
|
52
62
|
| Event | Claude | Cursor | OpenCode | Codex |
|