cclaw-cli 0.31.0 → 0.33.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 CHANGED
@@ -200,8 +200,9 @@ cclaw has eight stages, but a single prompt rarely needs all of them.
200
200
  | **standard** _(default)_ | all 8 stages | `new feature`, `refactor`, `migration`, `platform`, `schema`, `architecture` |
201
201
 
202
202
  Each stage produces a dated artifact under `.cclaw/artifacts/`:
203
- `00-idea.md` (seed) and `01-brainstorm.md` through `08-ship.md`
204
- (plus `09-retro.md` at automatic closeout see below).
203
+ `00-idea.md` (seed), `01-brainstorm.md` through `08-ship.md`, and
204
+ `09-retro.md` at automatic closeout (see
205
+ [Ship and closeout](#ship-and-closeout--automatic-resumable)).
205
206
 
206
207
  ### Track heuristics are configurable
207
208
 
@@ -254,8 +255,12 @@ it into ceremony:
254
255
  in a single place (`.cclaw/contexts/`), so every skill speaks the same
255
256
  dialect.
256
257
  - **Knowledge capture throughout the flow.** Every stage completion
257
- protocol can emit entries to `knowledge.jsonl` not only retro. Strict
258
- JSONL schema keeps it machine-queryable.
258
+ protocol emits typed entries (`rule` / `pattern` / `lesson`) to
259
+ `.cclaw/knowledge.jsonl` as the flow progresses — not only at retro.
260
+ Retro itself adds a `compound` entry, and the automatic compound pass
261
+ after ship promotes recurring entries (≥ 3) into first-class
262
+ rules/protocols/skills so the **next** run is easier. Strict JSONL
263
+ schema keeps the whole thing machine-queryable.
259
264
  - **Automatic integrity checks.** Runtime health is verified on every
260
265
  stage transition — no command you need to remember to run.
261
266
 
@@ -272,50 +277,92 @@ The `tdd` stage is not prose guidance. It requires:
272
277
  - optional **REFACTOR** pass with coverage preservation
273
278
 
274
279
  `/cc-next` will not advance past `tdd` until the delegation log shows the
275
- subagent as `completed` or explicitly `waived` (for harnesses without
276
- native subagent dispatch, such as Codex — see
277
- [Harness support](#harness-support)).
280
+ subagent as `completed` (or, on Codex / OpenCode, role-switched with
281
+ `evidenceRefs` see [Harness support](#harness-support)).
278
282
 
279
283
  ---
280
284
 
281
- ## Ship and closeout
282
-
283
- Shipping writes `08-ship.md` and then closes out the feature through a
284
- guided three-step sequence:
285
-
286
- 1. **Retro** drafts `09-retro.md` from flow artifacts and the delegation
287
- log; you review and accept.
288
- 2. **Compound pass** promotes repeated knowledge entries (frequency ≥ 2,
289
- maturity = stable) into first-class rules or skills.
290
- 3. **Archive** moves artifacts to `.cclaw/runs/YYYY-MM-DD-<slug>/` and
291
- resets `flow-state.json`.
292
-
293
- Retro is not optional archive is gated on retro completion so you can't
294
- silently lose the learning pass.
295
-
296
- > **Coming next:** cclaw will chain these three steps automatically from
297
- > `ship` (one structured `edit`/`accept`/`skip` ask, resumable if the
298
- > session ends). Tracked as the v0.32 closeout-automation wave.
285
+ ## Ship and closeout — automatic, resumable
286
+
287
+ Shipping writes `08-ship.md`. `/cc-next` then automatically walks the
288
+ feature through a deterministic three-step closeout without extra
289
+ commands from you:
290
+
291
+ 1. **Retro (`09-retro.md`).** cclaw drafts a retrospective from your
292
+ stage artifacts, the delegation log, and the knowledge entries
293
+ recorded during the run. It then asks exactly **one** structured
294
+ question:
295
+ - **accept** *(default)* — keep the draft, record one `compound`
296
+ knowledge entry, advance.
297
+ - **edit**you edit `09-retro.md` in place, then `/cc-next` again.
298
+ - **skip** record a one-line reason, continue (archive will
299
+ surface the skip in the run manifest).
300
+ 2. **Compound pass.** If the knowledge store has clusters recurring 3+
301
+ times, cclaw proposes concrete lifts into rules/protocols/skills and
302
+ asks once: apply-all / apply-selected / skip. An empty pass advances
303
+ silently.
304
+ 3. **Archive.** Moves artifacts into `.cclaw/runs/YYYY-MM-DD-<slug>/`,
305
+ snapshots `state/`, writes a manifest, and resets `flow-state.json`
306
+ to the track's initial stage.
307
+
308
+ The chain is driven by `closeout.shipSubstate` inside `flow-state.json`
309
+ (`retro_review` → `compound_review` → `ready_to_archive` → `archived`).
310
+ If your session dies mid-closeout, a new `/cc-next` resumes at the
311
+ exact step — retro drafts are not regenerated and no structured ask is
312
+ repeated silently.
313
+
314
+ You can still invoke each step manually (`/cc-ops retro`, `/cc-ops
315
+ compound`, `/cc-ops archive`), but for the default path you do not need
316
+ to: `/cc-next` is the only command.
299
317
 
300
318
  ---
301
319
 
302
320
  ## Harness support
303
321
 
304
- cclaw is honest about which harnesses give you full automation and which
305
- need small manual bridges. See
306
- [`docs/harnesses.md`](./docs/harnesses.md) for the full matrix.
307
-
308
- | Harness | Subagent dispatch | Hook surface | Structured ask | Status |
309
- |---|---|---|---|---|
310
- | Claude Code | native | full | `AskUserQuestion` | full parity |
311
- | Cursor | partial | full | `AskQuestion` | parity gap: subagent dispatch |
312
- | OpenCode | partial | plugin | plain-text | parity gap: plugin hooks |
313
- | OpenAI Codex | none (waiver) | full | plain-text | parity gap: no subagent |
314
-
315
- Capability gaps are captured in `.cclaw/state/harness-gaps.json`. Where
316
- native dispatch is missing, cclaw emits a **structured waiver** rather
317
- than pretending the delegation happened. Closing these gaps is an
318
- ongoing kinetic effort see the harness tracking doc above.
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.
319
366
 
320
367
  ---
321
368
 
@@ -15,35 +15,46 @@ export function archiveCommandContract() {
15
15
 
16
16
  ## Purpose
17
17
 
18
- Archive the active cclaw run from inside the harness flow (agent-first finish).
18
+ Finalize the active cclaw run: move artifacts to \`${runsPath()}/<archive-id>\`,
19
+ snapshot state, write a manifest, and reset runtime for the next run.
19
20
 
20
- This command removes the user-facing CLI gap: users can stay in \`/cc-*\` flow and
21
- finish with \`/cc-ops archive\` after ship + retro are complete.
21
+ Auto-triggered by \`/cc-next\` when \`closeout.shipSubstate === "ready_to_archive"\`.
22
+ Direct invocation from a harness command is supported but rarely needed.
22
23
 
23
24
  ## HARD-GATE
24
25
 
25
- - Do not archive a shipped run when retro is still incomplete.
26
- - Do not manually move files between \`${activeArtifactsPath()}\` and \`${runsPath()}\`.
27
- - Use the archive runtime so state snapshots + manifest stay consistent.
26
+ - Do not archive with \`closeout.shipSubstate !== "ready_to_archive"\`.
27
+ - Do not archive a shipped run when \`retro.completedAt\` is missing and
28
+ \`closeout.retroSkipped !== true\`.
29
+ - Never hand-move files between \`${activeArtifactsPath()}\` and \`${runsPath()}\`.
30
+ Always run the archive runtime command so the snapshot+manifest stay
31
+ atomic.
28
32
 
29
33
  ## Inputs
30
34
 
31
- \`/cc-ops archive [--name=<slug>] [--skip-retro --retro-reason=<text>]\`
35
+ \`/cc-ops archive [--name=<slug>]\`
36
+
37
+ (Legacy flags \`--skip-retro --retro-reason=<text>\` still exist for CLI
38
+ invocations; in-harness the skip path is driven by \`closeout.retroSkipped\`
39
+ set during retro.)
32
40
 
33
41
  ## Algorithm
34
42
 
35
43
  1. Read \`${flowStatePath()}\`.
36
- 2. If ship is complete and \`retro.completedAt\` is absent:
37
- - block with explicit instruction: run \`/cc-ops retro\` first.
44
+ 2. Verify \`closeout.shipSubstate === "ready_to_archive"\`. If not, report
45
+ \`closeout not ready (state=<substate>) | run: /cc-next\` and stop.
38
46
  3. Build archive command:
39
- - base: \`npx cclaw archive\`
40
- - optional: \`--name=<slug>\`
41
- - optional override: \`--skip-retro --retro-reason=<text>\`
42
- 4. Execute archive command in project root.
43
- 5. Surface result:
47
+ - base: \`npx cclaw archive\`,
48
+ - optional: \`--name=<slug>\`,
49
+ - legacy override: \`--skip-retro --retro-reason=<text>\` (only when user
50
+ explicitly wants the CLI skip path).
51
+ 4. Execute the archive command in project root.
52
+ 5. On success, flow-state is reset to the initial stage for the default
53
+ track; \`closeout.shipSubstate\` returns to \`"idle"\` on reset.
54
+ 6. Surface:
44
55
  - archive id/path,
45
- - reset stage (brainstorm/spec depending on track default),
46
- - knowledge curation hint when threshold exceeded.
56
+ - reset stage,
57
+ - knowledge curation hint when \`activeEntryCount >= softThreshold\`.
47
58
 
48
59
  ## Output format
49
60
 
@@ -63,36 +74,51 @@ cclaw archive
63
74
  export function archiveCommandSkillMarkdown() {
64
75
  return `---
65
76
  name: ${ARCHIVE_SKILL_NAME}
66
- description: "Archive the active cclaw run from harness flow and reset runtime safely."
77
+ description: "Finalize the active cclaw run. Auto-triggered by /cc-next when shipSubstate=ready_to_archive."
67
78
  ---
68
79
 
69
80
  # /cc-ops archive
70
81
 
71
82
  ## HARD-GATE
72
83
 
73
- Never simulate archive by hand-editing runtime files. Always execute the archive
74
- runtime command so state snapshots and manifest generation stay atomic.
84
+ Never simulate archive by hand-editing runtime files. Always execute the
85
+ archive runtime command so state snapshots and manifest generation stay
86
+ atomic. Never bypass the substate check — if retro/compound haven't
87
+ advanced the substate to \`ready_to_archive\`, stop and surface the
88
+ mismatch.
75
89
 
76
90
  ## Protocol
77
91
 
78
92
  1. Read \`${flowStatePath()}\`:
79
- - confirm whether ship is completed,
80
- - check \`retro.completedAt\` for post-ship runs.
81
- 2. If ship complete and retro incomplete -> stop and direct user to \`/cc-ops retro\`.
82
- 3. Build shell command:
83
- - \`npx cclaw archive\`
84
- - append \`--name=<slug>\` when provided
85
- - append \`--skip-retro --retro-reason=<text>\` only when user explicitly requests skip
86
- 4. Run command from repo root.
87
- 5. Relay key lines from output:
88
- - archive destination under \`${runsPath()}\`
89
- - flow reset confirmation
90
- - knowledge curation recommendation
93
+ - if \`closeout.shipSubstate !== "ready_to_archive"\`, stop and route
94
+ the user back to \`/cc-next\` (it will resume at the correct step),
95
+ - sanity-check: \`completedStages\` must include \`"ship"\`,
96
+ - sanity-check: \`retro.completedAt\` is set **or**
97
+ \`closeout.retroSkipped === true\` with a reason.
98
+ 2. Build shell command:
99
+ - \`npx cclaw archive\`,
100
+ - append \`--name=<slug>\` when provided,
101
+ - append legacy \`--skip-retro --retro-reason=<text>\` only when the user
102
+ explicitly requests the CLI skip path (normally not needed — skip is
103
+ captured in \`closeout\` during retro).
104
+ 3. Run command from repo root.
105
+ 4. Relay key lines from output:
106
+ - archive destination under \`${runsPath()}\`,
107
+ - flow reset confirmation,
108
+ - knowledge curation recommendation if \`activeEntryCount >= 50\`.
109
+
110
+ ## Resume semantics
111
+
112
+ Archive is idempotent on a per-run basis. If a previous session ran
113
+ archive successfully, the active artifacts directory is empty and
114
+ \`closeout.shipSubstate\` is \`"idle"\`; \`/cc-next\` will simply report
115
+ "Flow complete" or prompt for a new \`/cc\` input.
91
116
 
92
117
  ## Validation
93
118
 
94
- - \`${runsPath()}\` contains a new archive folder.
119
+ - \`${runsPath()}\` contains a new archive folder for this run.
95
120
  - \`${activeArtifactsPath()}\` is reset for the next run.
96
121
  - \`${flowStatePath()}\` is valid JSON and points to the initial stage.
122
+ - \`closeout.shipSubstate === "idle"\` after reset.
97
123
  `;
98
124
  }
@@ -6,29 +6,49 @@ export function compoundCommandContract() {
6
6
 
7
7
  ## Purpose
8
8
 
9
- Lift repeated lessons into durable project assets (rules, protocols, skills)
10
- so the next run is easier and safer.
9
+ Lift repeated lessons from \`${RUNTIME_ROOT}/knowledge.jsonl\` into durable
10
+ project assets (rules, protocols, skills) so the next run is easier and safer.
11
+
12
+ Auto-triggered by \`/cc-next\` when \`closeout.shipSubstate === "compound_review"\`.
13
+ Direct invocation is supported but rarely needed.
11
14
 
12
15
  ## HARD-GATE
13
16
 
14
- - Do not mutate rules/skills without explicit user approval.
15
- - Every proposal must cite concrete knowledge evidence (line references or IDs).
17
+ - Do not mutate rules/skills/protocols without explicit user approval.
18
+ - Every proposal must cite concrete knowledge evidence (line refs or IDs).
16
19
  - Keep scope focused: one compound change set per run.
20
+ - Do not block the archive step if no clusters qualify — record an empty
21
+ compound pass and advance.
22
+
23
+ ## Inputs
24
+
25
+ \`/cc-ops compound\` (no flags). The structured ask presents candidates;
26
+ the user can approve individual lifts, accept-all, or skip.
17
27
 
18
28
  ## Algorithm
19
29
 
20
- 1. Read \`${RUNTIME_ROOT}/knowledge.jsonl\`.
21
- 2. Cluster repeated trigger/action pairs.
22
- 3. For clusters with frequency >= 3, propose one lift action:
23
- - rule update
24
- - protocol update
25
- - utility skill update
26
- 4. For each proposal include:
27
- - why now
28
- - target file(s)
29
- - expected risk reduction
30
- 5. Ask user approval for each proposal before writing.
31
- 6. Apply approved lifts and record completion in retro artifact.
30
+ 1. Read \`${RUNTIME_ROOT}/knowledge.jsonl\` (strict JSONL, one entry per line).
31
+ 2. Cluster entries by \`trigger\` + \`action\` similarity.
32
+ 3. Filter candidates whose recurrence count >= 3.
33
+ 4. If **no candidates** exist:
34
+ - set \`closeout.compoundCompletedAt = <ISO>\`,
35
+ - set \`closeout.compoundPromoted = 0\`,
36
+ - set \`closeout.shipSubstate = "ready_to_archive"\`,
37
+ - emit \`compound: no candidates | next: /cc-next\` and stop.
38
+ 5. Otherwise, present **one** structured ask (AskUserQuestion / AskQuestion /
39
+ plain text) summarising all candidates at once:
40
+ - \`apply-all\` (default) apply every listed lift,
41
+ - \`apply-selected\` prompt per-candidate,
42
+ - \`skip\` — record a skip reason and advance without changes.
43
+ 6. Apply approved lifts to the target file(s). Each lift also appends a
44
+ \`type: "compound"\` entry back to \`${RUNTIME_ROOT}/knowledge.jsonl\`
45
+ summarising what was lifted.
46
+ 7. Update flow-state:
47
+ - \`closeout.compoundCompletedAt = <ISO>\`,
48
+ - \`closeout.compoundPromoted = <count>\`,
49
+ - \`closeout.compoundSkipped = true\` if user picked skip,
50
+ - \`closeout.shipSubstate = "ready_to_archive"\`.
51
+ 8. Emit one-line summary: \`compound: promoted=<N> skipped=<bool> | next: /cc-next\`.
32
52
 
33
53
  ## Primary skill
34
54
 
@@ -38,7 +58,7 @@ so the next run is easier and safer.
38
58
  export function compoundCommandSkillMarkdown() {
39
59
  return `---
40
60
  name: ${COMPOUND_SKILL_NAME}
41
- description: "Compound mode: convert repeated learnings into durable rules/protocols/skills."
61
+ description: "Lift repeated learnings into durable rules/protocols/skills. Auto-triggered after retro accept."
42
62
  ---
43
63
 
44
64
  # /cc-ops compound
@@ -49,13 +69,21 @@ description: "Compound mode: convert repeated learnings into durable rules/proto
49
69
 
50
70
  ## HARD-GATE
51
71
 
52
- No silent codification. Every lift requires explicit user approval.
72
+ No silent codification. Every lift requires explicit user approval. An
73
+ empty pass is allowed and must advance \`closeout.shipSubstate\` to
74
+ \`"ready_to_archive"\`.
53
75
 
54
76
  ## Protocol
55
77
 
56
- 1. Parse \`.cclaw/knowledge.jsonl\` and group repeated lessons.
57
- 2. Keep only candidates with clear recurrence and actionable lift path.
58
- 3. Propose each candidate using this template:
78
+ 1. Parse \`.cclaw/knowledge.jsonl\` and group repeated lessons by
79
+ trigger+action similarity.
80
+ 2. Keep only candidates with recurrence >= 3 and an actionable lift path.
81
+ 3. If none qualify, record an empty pass:
82
+ - \`closeout.compoundCompletedAt = <ISO>\`,
83
+ - \`closeout.compoundPromoted = 0\`,
84
+ - \`closeout.shipSubstate = "ready_to_archive"\`,
85
+ - announce \`compound: no candidates\` and stop.
86
+ 4. Otherwise, render each candidate as:
59
87
 
60
88
  \`\`\`
61
89
  Candidate: <short title>
@@ -65,8 +93,35 @@ Change type: <add/update/remove>
65
93
  Expected benefit: <what regressions this prevents>
66
94
  \`\`\`
67
95
 
68
- 4. Ask user to approve/reject per candidate.
69
- 5. Apply only approved candidates.
70
- 6. Append a \`compound\` learning entry summarizing what was lifted.
96
+ 5. Present **one** structured question with three options:
97
+ - \`apply-all\` (default) apply every candidate,
98
+ - \`apply-selected\` prompt per-candidate approval next,
99
+ - \`skip\` — record a skip reason and advance.
100
+
101
+ 6. For approved candidates:
102
+ - edit the target file(s) with the lift,
103
+ - append a \`type: "compound"\` entry to \`.cclaw/knowledge.jsonl\`
104
+ describing what was promoted.
105
+
106
+ 7. Update flow-state \`closeout\`:
107
+ - \`compoundCompletedAt\`,
108
+ - \`compoundPromoted\` (count),
109
+ - \`compoundSkipped\` (boolean) + \`compoundSkipReason\` when applicable,
110
+ - \`shipSubstate = "ready_to_archive"\`.
111
+
112
+ ## Resume semantics
113
+
114
+ A new session with \`shipSubstate === "compound_review"\` re-runs the scan
115
+ and re-asks the structured question. If the user already applied lifts in
116
+ a previous session but the state file was not updated, they should pick
117
+ \`skip\` with reason \`already-applied\` — compound is idempotent from the
118
+ closeout chain's perspective.
119
+
120
+ ## Validation
121
+
122
+ - \`closeout.compoundCompletedAt\` is set.
123
+ - \`closeout.shipSubstate === "ready_to_archive"\`.
124
+ - If lifts were applied, the target files show the edit and at least one
125
+ new \`compound\` line exists in \`.cclaw/knowledge.jsonl\`.
71
126
  `;
72
127
  }
@@ -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;