cclaw-cli 0.51.22 → 0.51.24
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 +14 -13
- package/dist/content/core-agents.d.ts +18 -2
- package/dist/content/core-agents.js +59 -13
- package/dist/content/examples.js +15 -7
- package/dist/content/hook-manifest.js +1 -4
- package/dist/content/learnings.js +5 -2
- package/dist/content/meta-skill.d.ts +1 -0
- package/dist/content/meta-skill.js +10 -1
- package/dist/content/node-hooks.js +1 -1
- package/dist/content/seed-shelf.js +73 -8
- package/dist/content/skills.js +14 -10
- package/dist/content/stage-command.d.ts +2 -0
- package/dist/content/stage-command.js +17 -0
- package/dist/content/stage-schema.js +50 -6
- package/dist/content/stages/brainstorm.js +20 -15
- package/dist/content/stages/design.js +16 -16
- package/dist/content/stages/review.js +20 -11
- package/dist/content/stages/schema-types.d.ts +1 -1
- package/dist/content/stages/scope.js +16 -11
- package/dist/content/stages/tdd.js +10 -3
- package/dist/content/subagents.js +73 -7
- package/dist/content/templates.js +127 -31
- package/dist/content/track-render-context.js +7 -0
- package/dist/delegation.d.ts +2 -2
- package/dist/delegation.js +16 -9
- package/dist/doctor-registry.js +1 -1
- package/dist/doctor.js +195 -33
- package/dist/flow-state.d.ts +1 -0
- package/dist/flow-state.js +1 -0
- package/dist/harness-adapters.d.ts +14 -11
- package/dist/harness-adapters.js +153 -17
- package/dist/install.js +101 -5
- package/dist/knowledge-store.js +30 -6
- package/dist/run-archive.js +11 -0
- package/dist/run-persistence.js +14 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -344,8 +344,9 @@ The `tdd` stage is not prose guidance. It requires:
|
|
|
344
344
|
- optional **REFACTOR** pass with coverage preservation
|
|
345
345
|
|
|
346
346
|
`/cc-next` will not advance past `tdd` until the delegation log shows the
|
|
347
|
-
subagent as `completed
|
|
348
|
-
|
|
347
|
+
subagent as `completed`. Codex and OpenCode use generated native subagents
|
|
348
|
+
by default; a role-switch row is only a degraded fallback and must include
|
|
349
|
+
`evidenceRefs` — see [Harness support](#harness-support).
|
|
349
350
|
|
|
350
351
|
---
|
|
351
352
|
|
|
@@ -391,25 +392,25 @@ closes every real gap with a documented fallback — not a silent waiver.
|
|
|
391
392
|
|---|---|---|---|---|
|
|
392
393
|
| Claude Code | full (named subagents) | `native` | full | `AskUserQuestion` |
|
|
393
394
|
| Cursor | generic Task dispatcher | `generic-dispatch` | full | `AskQuestion` |
|
|
394
|
-
| OpenCode |
|
|
395
|
-
| OpenAI Codex |
|
|
395
|
+
| OpenCode | native subagents (`.opencode/agents`) | `native` | plugin | `question` (permission-gated; `permission.question: "allow"`) |
|
|
396
|
+
| OpenAI Codex | native parallel subagents (`.codex/agents`) | `native` | limited (Bash-only `PreToolUse`/`PostToolUse`; requires `codex_hooks` feature flag) | `request_user_input` (experimental; Plan / Collaboration mode) |
|
|
396
397
|
|
|
397
398
|
What the fallbacks mean:
|
|
398
399
|
|
|
399
|
-
- `native` — Claude
|
|
400
|
-
workers; cclaw records them with `fulfillmentMode: "isolated"`.
|
|
400
|
+
- `native` — Claude, OpenCode, and Codex run mandatory delegations in
|
|
401
|
+
isolated subagent workers; cclaw records them with `fulfillmentMode: "isolated"`.
|
|
401
402
|
- `generic-dispatch` — Cursor has a real Task tool with a fixed
|
|
402
403
|
vocabulary of `subagent_type`s (`explore`, `generalPurpose`, …).
|
|
403
404
|
cclaw maps each named agent (planner / reviewer / test-author /
|
|
404
405
|
security-reviewer / doc-updater) onto the generic dispatcher with a
|
|
405
406
|
structured role prompt.
|
|
406
|
-
- `role-switch` —
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
407
|
+
- `role-switch` — degraded fallback only when the active runtime cannot
|
|
408
|
+
expose its declared dispatch surface. The agent announces
|
|
409
|
+
`## cclaw role-switch: <stage>/<agent> (<mode>)`, loads
|
|
410
|
+
`.cclaw/agents/<agent>.md`, writes outputs to the stage artifact, and
|
|
411
|
+
records a delegation row with `fulfillmentMode: "role-switch"` plus at
|
|
412
|
+
least one `evidenceRef`. A role-switch `completed` row without
|
|
413
|
+
evidenceRefs is classified as `missingEvidence` by `cclaw doctor`.
|
|
413
414
|
- `waiver` — reserved. Only fires auto-waivers if every installed
|
|
414
415
|
harness declares it. Currently unused — v0.33 removed the old
|
|
415
416
|
Codex-only auto-waiver path.
|
|
@@ -23,7 +23,7 @@ export interface AgentDefinition {
|
|
|
23
23
|
body: string;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* Canonical specialist roster
|
|
26
|
+
* Canonical specialist roster materialized under `.cclaw/agents/`.
|
|
27
27
|
*
|
|
28
28
|
* Declared with `satisfies` so the array retains literal `name` types for
|
|
29
29
|
* downstream type-level consumers (e.g. `AgentName`), while still being
|
|
@@ -39,6 +39,22 @@ export declare const CCLAW_AGENTS: readonly [{
|
|
|
39
39
|
readonly activation: "mandatory";
|
|
40
40
|
readonly relatedStages: ["brainstorm", "scope", "design", "spec", "plan"];
|
|
41
41
|
readonly body: string;
|
|
42
|
+
}, {
|
|
43
|
+
readonly name: "product-manager";
|
|
44
|
+
readonly description: "PROACTIVE during brainstorm/scope when product value, persona/JTBD, success metric, or why-now framing is unclear. Use for product discovery, not implementation.";
|
|
45
|
+
readonly tools: ["Read", "Grep", "Glob", "WebSearch"];
|
|
46
|
+
readonly model: "balanced";
|
|
47
|
+
readonly activation: "proactive";
|
|
48
|
+
readonly relatedStages: ["brainstorm", "scope"];
|
|
49
|
+
readonly body: string;
|
|
50
|
+
}, {
|
|
51
|
+
readonly name: "critic";
|
|
52
|
+
readonly description: "PROACTIVE during brainstorm/scope/design when premises, alternatives, cost, rollback, or hidden assumptions need adversarial pressure.";
|
|
53
|
+
readonly tools: ["Read", "Grep", "Glob", "WebSearch"];
|
|
54
|
+
readonly model: "balanced";
|
|
55
|
+
readonly activation: "proactive";
|
|
56
|
+
readonly relatedStages: ["brainstorm", "scope", "design"];
|
|
57
|
+
readonly body: string;
|
|
42
58
|
}, {
|
|
43
59
|
readonly name: "reviewer";
|
|
44
60
|
readonly description: "MANDATORY during review. MUST BE USED to run a two-pass audit: spec compliance first, then correctness/maintainability/performance/architecture.";
|
|
@@ -87,7 +103,7 @@ export declare function agentMarkdown(agent: AgentDefinition): string;
|
|
|
87
103
|
*/
|
|
88
104
|
export declare function agentRoutingTable(): string;
|
|
89
105
|
/**
|
|
90
|
-
* Cost tier routing for the
|
|
106
|
+
* Cost tier routing for the specialist agent roster.
|
|
91
107
|
*/
|
|
92
108
|
export declare function agentCostTierTable(): string;
|
|
93
109
|
/**
|
|
@@ -39,7 +39,7 @@ function activationModeSummary() {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* Canonical specialist roster
|
|
42
|
+
* Canonical specialist roster materialized under `.cclaw/agents/`.
|
|
43
43
|
*
|
|
44
44
|
* Declared with `satisfies` so the array retains literal `name` types for
|
|
45
45
|
* downstream type-level consumers (e.g. `AgentName`), while still being
|
|
@@ -59,14 +59,56 @@ export const CCLAW_AGENTS = [
|
|
|
59
59
|
"You are an **implementation planning specialist** (staff engineer mindset).",
|
|
60
60
|
"",
|
|
61
61
|
"When invoked:",
|
|
62
|
-
"1.
|
|
63
|
-
"2.
|
|
64
|
-
"3.
|
|
65
|
-
"4.
|
|
62
|
+
"1. Map upstream decisions, scope boundaries, and explicit drift before planning.",
|
|
63
|
+
"2. Break the work into concrete sub-problems with dependencies and existing-module fit.",
|
|
64
|
+
"3. Enforce one-question discipline: ask only decision-changing questions, one at a time.",
|
|
65
|
+
"4. Produce an ordered execution plan with verification checks and handoff quality notes.",
|
|
66
|
+
"5. Highlight risks and unknowns that need user decisions.",
|
|
66
67
|
"",
|
|
67
68
|
"**Role boundary:** planning only. Do NOT write production code."
|
|
68
69
|
].join("\n")
|
|
69
70
|
},
|
|
71
|
+
{
|
|
72
|
+
name: "product-manager",
|
|
73
|
+
description: "PROACTIVE during brainstorm/scope when product value, persona/JTBD, success metric, or why-now framing is unclear. Use for product discovery, not implementation.",
|
|
74
|
+
tools: ["Read", "Grep", "Glob", "WebSearch"],
|
|
75
|
+
model: "balanced",
|
|
76
|
+
activation: "proactive",
|
|
77
|
+
relatedStages: ["brainstorm", "scope"],
|
|
78
|
+
body: [
|
|
79
|
+
"You are a **product discovery specialist**.",
|
|
80
|
+
"",
|
|
81
|
+
"Produce concise evidence for:",
|
|
82
|
+
"- persona / user and job to be done",
|
|
83
|
+
"- pain or trigger",
|
|
84
|
+
"- value hypothesis and success metric",
|
|
85
|
+
"- evidence or signal strength",
|
|
86
|
+
"- why now, do-nothing consequence, and non-goals",
|
|
87
|
+
"",
|
|
88
|
+
"For technical-maintenance work, translate this to operator/developer, failure mode, operational improvement, verification signal, do-nothing cost, and non-goals.",
|
|
89
|
+
"",
|
|
90
|
+
"**Role boundary:** frame value and problem fit. Do NOT choose implementation architecture."
|
|
91
|
+
].join("\n")
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "critic",
|
|
95
|
+
description: "PROACTIVE during brainstorm/scope/design when premises, alternatives, cost, rollback, or hidden assumptions need adversarial pressure.",
|
|
96
|
+
tools: ["Read", "Grep", "Glob", "WebSearch"],
|
|
97
|
+
model: "balanced",
|
|
98
|
+
activation: "proactive",
|
|
99
|
+
relatedStages: ["brainstorm", "scope", "design"],
|
|
100
|
+
body: [
|
|
101
|
+
"You are an **adversarial critic** for product and engineering decisions.",
|
|
102
|
+
"",
|
|
103
|
+
"Your job:",
|
|
104
|
+
"1. Attack the premise and name what could make the current direction wrong.",
|
|
105
|
+
"2. Identify cheaper, smaller, or more reversible alternatives.",
|
|
106
|
+
"3. Surface hidden assumptions, do-nothing viability, and scope creep.",
|
|
107
|
+
"4. In design, require a shadow alternative, switch trigger, failure/rescue path, and verification evidence.",
|
|
108
|
+
"",
|
|
109
|
+
"Return confirmed risks, disproven concerns, and the smallest decision-changing recommendation."
|
|
110
|
+
].join("\n")
|
|
111
|
+
},
|
|
70
112
|
{
|
|
71
113
|
name: "reviewer",
|
|
72
114
|
description: "MANDATORY during review. MUST BE USED to run a two-pass audit: spec compliance first, then correctness/maintainability/performance/architecture.",
|
|
@@ -91,9 +133,11 @@ export const CCLAW_AGENTS = [
|
|
|
91
133
|
"",
|
|
92
134
|
"For each finding include:",
|
|
93
135
|
"- Severity: `Critical` | `Important` | `Suggestion`",
|
|
94
|
-
"- Location: `file:line
|
|
136
|
+
"- Location: `file:line`; if no line is possible, state the no-line reason",
|
|
95
137
|
"- Problem and concrete recommendation",
|
|
96
138
|
"",
|
|
139
|
+
"Also report files inspected, changed-file coverage, diagnostics run, dependency/version audit when relevant, and a no-finding attestation when no issues are found.",
|
|
140
|
+
"",
|
|
97
141
|
"**Trust model:** never rely on implementer claims; verify by reading code."
|
|
98
142
|
].join("\n")
|
|
99
143
|
},
|
|
@@ -118,7 +162,8 @@ export const CCLAW_AGENTS = [
|
|
|
118
162
|
"- severity aligned to ship risk",
|
|
119
163
|
"- CWE ID when possible (or UNKNOWN)",
|
|
120
164
|
"- short proof-of-concept vector",
|
|
121
|
-
"- concrete control-oriented fix"
|
|
165
|
+
"- concrete control-oriented fix",
|
|
166
|
+
"- `NO_CHANGE_ATTESTATION` or `NO_SECURITY_IMPACT` with inspected surfaces when no security finding exists"
|
|
122
167
|
].join("\n")
|
|
123
168
|
},
|
|
124
169
|
{
|
|
@@ -131,7 +176,7 @@ export const CCLAW_AGENTS = [
|
|
|
131
176
|
body: [
|
|
132
177
|
"You are a **test-driven development** specialist.",
|
|
133
178
|
"",
|
|
134
|
-
"**Iron law:** no production code without a failing test first.",
|
|
179
|
+
"**Iron law:** no production code without a failing test first during RED. In design, focus on testability and verification evidence without editing production code.",
|
|
135
180
|
"",
|
|
136
181
|
"Process:",
|
|
137
182
|
"1. RED: write a failing test for the desired behavior.",
|
|
@@ -154,7 +199,8 @@ export const CCLAW_AGENTS = [
|
|
|
154
199
|
"After code changes, verify and update only stale sections in:",
|
|
155
200
|
"- README / setup / usage",
|
|
156
201
|
"- API docs and examples",
|
|
157
|
-
"- migration and operational notes",
|
|
202
|
+
"- migration, rollout, rollback, and operational notes",
|
|
203
|
+
"- public-surface change notes tied to actual changed files",
|
|
158
204
|
"",
|
|
159
205
|
"Preserve existing tone and structure; avoid rewrites for style alone."
|
|
160
206
|
].join("\n")
|
|
@@ -221,13 +267,13 @@ export function agentRoutingTable() {
|
|
|
221
267
|
`;
|
|
222
268
|
}
|
|
223
269
|
/**
|
|
224
|
-
* Cost tier routing for the
|
|
270
|
+
* Cost tier routing for the specialist agent roster.
|
|
225
271
|
*/
|
|
226
272
|
export function agentCostTierTable() {
|
|
227
273
|
return `| Tier | Use for | Example agents |
|
|
228
274
|
|---|---|---|
|
|
229
275
|
| \`deep\` | one heavy planning pass per stage | planner |
|
|
230
|
-
| \`balanced\` | review and TDD specialists with stronger reasoning depth | reviewer, security-reviewer, test-author |
|
|
276
|
+
| \`balanced\` | discovery, criticism, review, and TDD specialists with stronger reasoning depth | product-manager, critic, reviewer, security-reviewer, test-author |
|
|
231
277
|
| \`fast\` | bounded maintenance updates with limited blast radius | doc-updater |
|
|
232
278
|
`;
|
|
233
279
|
}
|
|
@@ -237,7 +283,7 @@ export function agentCostTierTable() {
|
|
|
237
283
|
export function agentsAgentsMdBlock() {
|
|
238
284
|
return `### Agent Specialists
|
|
239
285
|
|
|
240
|
-
cclaw materializes
|
|
286
|
+
cclaw materializes specialist agents under \`.cclaw/agents/\`, including planner, product-manager, critic, reviewer, security-reviewer, test-author, and doc-updater.
|
|
241
287
|
|
|
242
288
|
${agentRoutingTable()}
|
|
243
289
|
|
|
@@ -257,7 +303,7 @@ ${(() => {
|
|
|
257
303
|
const mode = activationModeSummary();
|
|
258
304
|
return `- **Mandatory:** ${mode.mandatory}.
|
|
259
305
|
- **Proactive:** ${mode.proactive}.
|
|
260
|
-
- **On-demand:** none in the
|
|
306
|
+
- **On-demand:** none in the specialist roster; research playbooks are in-thread procedures.`;
|
|
261
307
|
})()}
|
|
262
308
|
|
|
263
309
|
### Cost-aware routing
|
package/dist/content/examples.js
CHANGED
|
@@ -4,11 +4,19 @@ const STAGE_EXAMPLES = {
|
|
|
4
4
|
- **Project state:** Monorepo with CI pipeline using custom release scripts. Release checks are scattered across shell scripts with no shared validation logic.
|
|
5
5
|
- **Relevant existing code/patterns:** \`scripts/pre-publish.sh\` does metadata checks. \`src/release/\` has partial validation helpers.
|
|
6
6
|
|
|
7
|
-
## Problem
|
|
7
|
+
## Problem Decision Record
|
|
8
8
|
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
|
|
9
|
+
- **Depth:** standard
|
|
10
|
+
- **Frame type:** technical-maintenance
|
|
11
|
+
|
|
12
|
+
### Technical-maintenance framing
|
|
13
|
+
|
|
14
|
+
- **Affected operator/developer:** release operator and package maintainer.
|
|
15
|
+
- **Current failure mode:** release checks are fragile and inconsistent between CI and local runs; invalid metadata sometimes reaches npm publish.
|
|
16
|
+
- **Expected operational improvement:** invalid release preconditions are caught before publish with explicit operator feedback in CI and local workflows.
|
|
17
|
+
- **Verification signal:** shared release validation tests and CI release-check command fail on invalid metadata.
|
|
18
|
+
- **Do-nothing cost:** continued publish risk and duplicated local/CI fixes.
|
|
19
|
+
- **Non-goals:** no new runtime dependencies; no release-framework rewrite.
|
|
12
20
|
|
|
13
21
|
## Clarifying Questions
|
|
14
22
|
|
|
@@ -667,7 +675,7 @@ function exampleSummaryBullets(stage) {
|
|
|
667
675
|
// sample in STAGE_EXAMPLES gains or loses a top-level section.
|
|
668
676
|
const STAGE_EXAMPLE_SECTION_HEADINGS = {
|
|
669
677
|
brainstorm: [
|
|
670
|
-
"Problem
|
|
678
|
+
"Problem Decision Record (product or technical-maintenance framing)",
|
|
671
679
|
"Candidate approaches with trade-offs",
|
|
672
680
|
"Recommended direction + open questions",
|
|
673
681
|
"Clarification log and decision record"
|
|
@@ -726,8 +734,8 @@ const DOMAIN_LABELS = {
|
|
|
726
734
|
export const RESEARCH_FLEET_USAGE_EXAMPLE = [
|
|
727
735
|
"Before drafting `03-design.md`, run `research/research-fleet.md` once and",
|
|
728
736
|
"capture all four lenses in `.cclaw/artifacts/02a-research.md`.",
|
|
729
|
-
"Dispatch semantics by harness: Claude/
|
|
730
|
-
"
|
|
737
|
+
"Dispatch semantics by harness: Claude/OpenCode/Codex = native subagents;",
|
|
738
|
+
"Cursor = generic-dispatch Task mapping; role-switch only as degraded fallback.",
|
|
731
739
|
"Design must include a `Research Fleet Synthesis` section that maps each",
|
|
732
740
|
"lens to concrete architecture decisions and risks."
|
|
733
741
|
].join(" ");
|
|
@@ -74,10 +74,7 @@ export const HOOK_MANIFEST = [
|
|
|
74
74
|
bindings: {
|
|
75
75
|
claude: [{ event: "PreToolUse", matcher: "Write|Edit|MultiEdit|NotebookEdit|Bash" }],
|
|
76
76
|
cursor: [{ event: "preToolUse", matcher: "*" }],
|
|
77
|
-
codex: [
|
|
78
|
-
{ event: "UserPromptSubmit" },
|
|
79
|
-
{ event: "PreToolUse", matcher: "Bash|bash" }
|
|
80
|
-
]
|
|
77
|
+
codex: [{ event: "PreToolUse", matcher: "Bash|bash" }]
|
|
81
78
|
}
|
|
82
79
|
},
|
|
83
80
|
{
|
|
@@ -78,7 +78,7 @@ Do not invent alternate stores (no markdown mirror, no SQLite, no per-stage file
|
|
|
78
78
|
|
|
79
79
|
Exactly one JSON object per line. Required fields must appear in the order:
|
|
80
80
|
\`type, trigger, action, confidence, domain, stage, origin_stage, origin_run, frequency, universality, maturity, created, first_seen_ts, last_seen_ts, project\`.
|
|
81
|
-
Optional fields \`source\` and \`
|
|
81
|
+
Optional fields \`source\`, \`severity\`, \`supersedes\`, and \`superseded_by\` may be appended after \`project\`.
|
|
82
82
|
|
|
83
83
|
\`\`\`json
|
|
84
84
|
{"type":"pattern","trigger":"when reviewing external payloads","action":"parse through zod before touching service layer","confidence":"high","domain":"api","stage":"review","origin_stage":"review","origin_run":"payload-hardening","frequency":1,"universality":"project","maturity":"raw","created":"2026-04-14T12:00:00Z","first_seen_ts":"2026-04-14T12:00:00Z","last_seen_ts":"2026-04-14T12:00:00Z","project":"cclaw"}
|
|
@@ -103,12 +103,15 @@ Optional fields \`source\` and \`severity\` may be appended after \`project\`.
|
|
|
103
103
|
| \`project\` | string \\| null | yes | Repo or scope name. Use \`null\` when the entry crosses projects. |
|
|
104
104
|
| \`source\` | \`"stage" \\| "retro" \\| "compound" \\| "ideate" \\| "manual" \\| null\` | no | Origin channel for the entry when known. |
|
|
105
105
|
| \`severity\` | \`"critical" \\| "important" \\| "suggestion"\` | no | Priority signal for compound lifts; \`critical\` enables single-hit override in compound readiness analysis. |
|
|
106
|
+
| \`supersedes\` | string[] | no | Non-empty IDs/slugs of older entries this entry refreshes. Use only for clear replacements discovered during compound closeout or curation. |
|
|
107
|
+
| \`superseded_by\` | string | no | Non-empty ID/slug of the newer entry that refreshes this one. Use only when marking stale guidance as replaced. |
|
|
106
108
|
|
|
107
109
|
Rules:
|
|
108
110
|
- No other fields beyond the table above. Extra keys are forbidden and MUST be rejected by any writer.
|
|
109
111
|
- Every required-null field must be emitted explicitly as \`null\` (not omitted). This keeps the file grep-friendly.
|
|
110
112
|
- Append-only: never rewrite or delete a historical line. Corrections are new
|
|
111
|
-
entries whose \`trigger\` clearly supersedes the earlier one
|
|
113
|
+
entries whose \`trigger\` clearly supersedes the earlier one; add \`supersedes\` /
|
|
114
|
+
\`superseded_by\` only when the replacement relationship is clear.
|
|
112
115
|
- Keep each entry one line. No pretty-printing. No trailing commas.
|
|
113
116
|
|
|
114
117
|
## Curation policy (target: ≤ 50 active entries)
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { conversationLanguagePolicyMarkdown } from "./language-policy.js";
|
|
2
2
|
import { CLOSEOUT_CHAIN, closeoutChainInline, closeoutFlowMapSentence, closeoutProtocolBehaviorSentence } from "./closeout-guidance.js";
|
|
3
3
|
export const META_SKILL_NAME = "using-cclaw";
|
|
4
|
+
export const META_SKILL_GENERATED_HELPER_SKILLS = [
|
|
5
|
+
"subagent-dev",
|
|
6
|
+
"parallel-dispatch",
|
|
7
|
+
"session",
|
|
8
|
+
"iron-laws"
|
|
9
|
+
];
|
|
10
|
+
function generatedHelperSkillList() {
|
|
11
|
+
return META_SKILL_GENERATED_HELPER_SKILLS.map((name) => `\`${name}\``).join(", ");
|
|
12
|
+
}
|
|
4
13
|
export function usingCclawSkillMarkdown() {
|
|
5
14
|
return `---
|
|
6
15
|
name: using-cclaw
|
|
@@ -25,7 +34,7 @@ ${conversationLanguagePolicyMarkdown()}
|
|
|
25
34
|
If \`.cclaw/state/flow-state.json\` exists and \`currentStage\` is set,
|
|
26
35
|
load the matching stage SKILL before producing **substantive** work
|
|
27
36
|
(artifact edits, code, structured clarifying questions). Do not improvise
|
|
28
|
-
from memory. Load only generated helper surfaces that actually exist in this install:
|
|
37
|
+
from memory. Load only generated helper surfaces that actually exist in this install: ${generatedHelperSkillList()}, research playbooks, review prompts, or enabled language rule packs under \`.cclaw/rules/lang/\`. Do not invent helper-skill names beyond those generated surfaces.
|
|
29
38
|
|
|
30
39
|
Substantive vs. non-substantive:
|
|
31
40
|
|
|
@@ -1636,7 +1636,7 @@ async function handleVerifyCurrentState(runtime) {
|
|
|
1636
1636
|
process.stderr.write(result.stderr.trim().length > 0
|
|
1637
1637
|
? result.stderr
|
|
1638
1638
|
: "[cclaw] hook: local Node runtime entrypoint is required for verify-current-state\\n");
|
|
1639
|
-
return 1;
|
|
1639
|
+
return mode === "strict" ? 1 : 0;
|
|
1640
1640
|
}
|
|
1641
1641
|
if (mode === "strict") {
|
|
1642
1642
|
if (result.code !== 0) {
|
|
@@ -4,6 +4,8 @@ import { parse } from "yaml";
|
|
|
4
4
|
import { RUNTIME_ROOT } from "../constants.js";
|
|
5
5
|
const SEED_FILE_NAME_PATTERN = /^SEED-(\d{4}-\d{2}-\d{2})-([a-z0-9]+(?:-[a-z0-9]+)*)(?:-(\d+))?\.md$/u;
|
|
6
6
|
const DEFAULT_MAX_MATCHES = 3;
|
|
7
|
+
const MAX_SEED_MATCHES = 10;
|
|
8
|
+
const MIN_TOKEN_OVERLAP = 2;
|
|
7
9
|
function isRecord(value) {
|
|
8
10
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
11
|
}
|
|
@@ -189,18 +191,81 @@ export async function readSeedShelf(projectRoot) {
|
|
|
189
191
|
entries.sort((a, b) => b.fileName.localeCompare(a.fileName));
|
|
190
192
|
return entries;
|
|
191
193
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (
|
|
194
|
+
function normalizeMatchText(value) {
|
|
195
|
+
return value.toLowerCase().trim().replace(/\s+/gu, " ");
|
|
196
|
+
}
|
|
197
|
+
function tokenizeSeedText(value) {
|
|
198
|
+
if (!value)
|
|
199
|
+
return [];
|
|
200
|
+
return value
|
|
201
|
+
.toLowerCase()
|
|
202
|
+
.split(/[^a-z0-9]+/u)
|
|
203
|
+
.map((token) => token.trim())
|
|
204
|
+
.filter((token) => token.length >= 3);
|
|
205
|
+
}
|
|
206
|
+
function uniqueTokens(values) {
|
|
207
|
+
return new Set(values);
|
|
208
|
+
}
|
|
209
|
+
function exactTriggerMatch(seed, normalizedPrompt) {
|
|
210
|
+
if (normalizedPrompt.length === 0 || seed.triggerWhen.length === 0)
|
|
197
211
|
return false;
|
|
198
|
-
return seed.triggerWhen.some((trigger) =>
|
|
212
|
+
return seed.triggerWhen.some((trigger) => {
|
|
213
|
+
const normalizedTrigger = normalizeMatchText(trigger);
|
|
214
|
+
return normalizedTrigger.length > 0 && normalizedPrompt.includes(normalizedTrigger);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
function seedContentTokens(seed) {
|
|
218
|
+
return uniqueTokens([
|
|
219
|
+
...tokenizeSeedText(seed.title),
|
|
220
|
+
...tokenizeSeedText(seed.summary),
|
|
221
|
+
...tokenizeSeedText(seed.hypothesis),
|
|
222
|
+
...tokenizeSeedText(seed.action)
|
|
223
|
+
]);
|
|
224
|
+
}
|
|
225
|
+
function tokenOverlap(seed, promptTokens) {
|
|
226
|
+
if (promptTokens.size === 0)
|
|
227
|
+
return 0;
|
|
228
|
+
const contentTokens = seedContentTokens(seed);
|
|
229
|
+
let overlap = 0;
|
|
230
|
+
for (const token of promptTokens) {
|
|
231
|
+
if (contentTokens.has(token))
|
|
232
|
+
overlap += 1;
|
|
233
|
+
}
|
|
234
|
+
return overlap;
|
|
235
|
+
}
|
|
236
|
+
export function seedMatchesPrompt(seed, prompt) {
|
|
237
|
+
const normalizedPrompt = normalizeMatchText(prompt);
|
|
238
|
+
if (exactTriggerMatch(seed, normalizedPrompt))
|
|
239
|
+
return true;
|
|
240
|
+
return tokenOverlap(seed, uniqueTokens(tokenizeSeedText(prompt))) >= MIN_TOKEN_OVERLAP;
|
|
199
241
|
}
|
|
200
242
|
export async function findMatchingSeeds(projectRoot, prompt, maxMatches = DEFAULT_MAX_MATCHES) {
|
|
201
243
|
const seeds = await readSeedShelf(projectRoot);
|
|
202
|
-
const
|
|
203
|
-
|
|
244
|
+
const normalizedPrompt = normalizeMatchText(prompt);
|
|
245
|
+
if (normalizedPrompt.length === 0)
|
|
246
|
+
return [];
|
|
247
|
+
const promptTokens = uniqueTokens(tokenizeSeedText(prompt));
|
|
248
|
+
const cappedMax = typeof maxMatches === "number" && Number.isFinite(maxMatches) && maxMatches > 0
|
|
249
|
+
? Math.min(MAX_SEED_MATCHES, Math.max(1, Math.floor(maxMatches)))
|
|
250
|
+
: DEFAULT_MAX_MATCHES;
|
|
251
|
+
const ranked = seeds
|
|
252
|
+
.map((seed, index) => {
|
|
253
|
+
const exact = exactTriggerMatch(seed, normalizedPrompt);
|
|
254
|
+
const overlap = tokenOverlap(seed, promptTokens);
|
|
255
|
+
return { seed, index, exact, overlap };
|
|
256
|
+
})
|
|
257
|
+
.filter((row) => row.exact || row.overlap >= MIN_TOKEN_OVERLAP);
|
|
258
|
+
ranked.sort((a, b) => {
|
|
259
|
+
if (a.exact !== b.exact)
|
|
260
|
+
return a.exact ? -1 : 1;
|
|
261
|
+
if (b.overlap !== a.overlap)
|
|
262
|
+
return b.overlap - a.overlap;
|
|
263
|
+
const recency = b.seed.createdOn.localeCompare(a.seed.createdOn);
|
|
264
|
+
if (recency !== 0)
|
|
265
|
+
return recency;
|
|
266
|
+
return a.index - b.index;
|
|
267
|
+
});
|
|
268
|
+
return ranked.slice(0, cappedMax).map((row) => row.seed);
|
|
204
269
|
}
|
|
205
270
|
export function renderSeedTemplate(input) {
|
|
206
271
|
const triggerWhen = [...input.triggerWhen].map((item) => item.trim()).filter((item) => item.length > 0);
|
package/dist/content/skills.js
CHANGED
|
@@ -61,23 +61,24 @@ function autoSubagentDispatchBlock(stage, track) {
|
|
|
61
61
|
const rules = stageAutoSubagentDispatch(stage);
|
|
62
62
|
if (rules.length === 0)
|
|
63
63
|
return "";
|
|
64
|
+
const schema = stageSchema(stage, track);
|
|
64
65
|
const rows = rules
|
|
65
66
|
.map((rule) => {
|
|
66
67
|
const userGate = rule.requiresUserGate ? "required" : "not required";
|
|
67
|
-
return `| ${rule.agent} | ${rule.mode} | ${userGate} | ${rule.when} |`;
|
|
68
|
+
return `| ${rule.agent} | ${rule.mode} | ${userGate} | ${rule.when} | ${rule.purpose} |`;
|
|
68
69
|
})
|
|
69
70
|
.join("\n");
|
|
70
|
-
const mandatory =
|
|
71
|
+
const mandatory = schema.mandatoryDelegations;
|
|
71
72
|
const mandatoryList = mandatory.length > 0 ? mandatory.map((a) => `\`${a}\``).join(", ") : "none";
|
|
72
73
|
const delegationLogRel = `${RUNTIME_ROOT}/state/delegation-log.json`;
|
|
74
|
+
const artifactRef = `${RUNTIME_ROOT}/artifacts/${schema.artifactRules.artifactFile}`;
|
|
73
75
|
return `## Automatic Subagent Dispatch
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|---|---|---|---|
|
|
76
|
+
| Agent | Mode | User Gate | Trigger | Purpose |
|
|
77
|
+
|---|---|---|---|---|
|
|
77
78
|
${rows}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
Mandatory: ${mandatoryList}. Record completion/waiver in \`${delegationLogRel}\` before completion.
|
|
80
|
+
### Harness Dispatch Contract
|
|
81
|
+
Use true harness dispatch: Claude native Task, Cursor generic dispatch, OpenCode \`.opencode/agents/<agent>.md\`, Codex \`.codex/agents/<agent>.toml\`. Run independent read-only/review agents in parallel where safe, write evidence into \`${artifactRef}\`, then append \`${delegationLogRel}\` rows with matching \`fulfillmentMode: "isolated"\` or \`"generic-dispatch"\`. Do not collapse OpenCode or Codex to role-switch by default; role-switch is degraded fallback and must carry non-empty \`evidenceRefs\`. Missing evidence blocks completion.
|
|
81
82
|
`;
|
|
82
83
|
}
|
|
83
84
|
function researchPlaybooksBlock(playbooks) {
|
|
@@ -160,15 +161,18 @@ function batchExecutionModeBlock(stage, track) {
|
|
|
160
161
|
const schema = stageSchema(stage, track);
|
|
161
162
|
if (!schema.batchExecutionAllowed)
|
|
162
163
|
return "";
|
|
164
|
+
const orderingGuidance = track === "quick"
|
|
165
|
+
? "Use spec acceptance items / bug reproduction slices for ordering."
|
|
166
|
+
: "Use plan slices for ordering.";
|
|
163
167
|
return `## Batch Execution Mode
|
|
164
168
|
|
|
165
169
|
Execute the current dependency batch task-by-task (RED -> GREEN -> REFACTOR).
|
|
166
170
|
Stop on BLOCKED status or when user input is required.
|
|
167
|
-
Apply concise turn announces: one announce per batch boundary (or when risk/
|
|
171
|
+
Apply concise turn announces: one announce per batch boundary (or when risk/source
|
|
168
172
|
changes materially), then execute tasks without repetitive boilerplate.
|
|
169
173
|
|
|
170
174
|
Detailed walkthrough:
|
|
171
|
-
|
|
175
|
+
${orderingGuidance} Keep RED -> GREEN -> REFACTOR evidence in the TDD artifact.
|
|
172
176
|
`;
|
|
173
177
|
}
|
|
174
178
|
function crossStageTraceBlock(trace) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
|
+
import { stageSkillFolder } from "./skills.js";
|
|
3
|
+
export function stageCommandShimMarkdown(stage) {
|
|
4
|
+
const skillPath = `${RUNTIME_ROOT}/skills/${stageSkillFolder(stage)}/SKILL.md`;
|
|
5
|
+
return `# /cc-${stage}
|
|
6
|
+
|
|
7
|
+
This is a thin compatibility shim for the \`${stage}\` flow stage.
|
|
8
|
+
|
|
9
|
+
Load and follow the authoritative stage skill:
|
|
10
|
+
|
|
11
|
+
- \`${skillPath}\`
|
|
12
|
+
|
|
13
|
+
Normal stage resume and advancement uses \`/cc-next\`. Use \`/cc-next\` to read
|
|
14
|
+
\`.cclaw/state/flow-state.json\`, select the active stage, and advance only after
|
|
15
|
+
that stage's gates pass. Do not duplicate the stage protocol here.
|
|
16
|
+
`;
|
|
17
|
+
}
|