cclaw-cli 0.10.1 → 0.12.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 +4 -3
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +297 -9
- package/dist/config.js +83 -3
- package/dist/content/core-agents.d.ts +44 -0
- package/dist/content/core-agents.js +225 -0
- package/dist/content/doctor-references.d.ts +2 -0
- package/dist/content/doctor-references.js +144 -0
- package/dist/content/examples.js +1 -1
- package/dist/content/harnesses-doc.d.ts +1 -0
- package/dist/content/harnesses-doc.js +95 -0
- package/dist/content/hook-events.d.ts +4 -0
- package/dist/content/hook-events.js +42 -0
- package/dist/content/hooks.js +81 -11
- package/dist/content/meta-skill.d.ts +0 -8
- package/dist/content/meta-skill.js +51 -341
- package/dist/content/next-command.js +2 -1
- package/dist/content/protocols.d.ts +7 -0
- package/dist/content/protocols.js +123 -0
- package/dist/content/research-playbooks.d.ts +8 -0
- package/dist/content/research-playbooks.js +135 -0
- package/dist/content/skills.js +202 -312
- package/dist/content/stage-common-guidance.d.ts +2 -0
- package/dist/content/stage-common-guidance.js +71 -0
- package/dist/content/stage-schema.d.ts +11 -1
- package/dist/content/stage-schema.js +155 -52
- package/dist/content/start-command.js +19 -13
- package/dist/content/subagents.d.ts +1 -1
- package/dist/content/subagents.js +23 -38
- package/dist/content/templates.d.ts +1 -1
- package/dist/content/templates.js +49 -11
- package/dist/delegation.d.ts +1 -0
- package/dist/delegation.js +27 -1
- package/dist/doctor-registry.d.ts +8 -0
- package/dist/doctor-registry.js +127 -0
- package/dist/doctor.d.ts +5 -0
- package/dist/doctor.js +133 -27
- package/dist/flow-state.d.ts +4 -0
- package/dist/flow-state.js +4 -1
- package/dist/gate-evidence.d.ts +9 -1
- package/dist/gate-evidence.js +121 -17
- package/dist/harness-adapters.d.ts +7 -0
- package/dist/harness-adapters.js +53 -9
- package/dist/init-detect.d.ts +2 -0
- package/dist/init-detect.js +45 -0
- package/dist/install.js +73 -1
- package/dist/policy.js +21 -13
- package/dist/runs.js +21 -4
- package/dist/track-heuristics.d.ts +12 -0
- package/dist/track-heuristics.js +144 -0
- package/dist/types.d.ts +26 -3
- package/dist/types.js +6 -3
- package/package.json +2 -1
- package/dist/content/agents.d.ts +0 -48
- package/dist/content/agents.js +0 -411
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent persona content for cclaw.
|
|
3
|
+
*
|
|
4
|
+
* cclaw materializes markdown agent definitions (`.md` with YAML frontmatter)
|
|
5
|
+
* under `.cclaw/agents/` for harness delegation. Research work that does not
|
|
6
|
+
* need isolated subagent context lives in `.cclaw/skills/research/*.md`
|
|
7
|
+
* playbooks and is executed in-thread by the primary agent.
|
|
8
|
+
*/
|
|
9
|
+
function yamlScalarString(value) {
|
|
10
|
+
// JSON double-quoted strings are valid YAML scalars and escape reliably.
|
|
11
|
+
return JSON.stringify(value);
|
|
12
|
+
}
|
|
13
|
+
function yamlFlowSequence(values) {
|
|
14
|
+
return JSON.stringify(values);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Canonical specialist roster (core-5) materialized under `.cclaw/agents/`.
|
|
18
|
+
*/
|
|
19
|
+
export const CCLAW_AGENTS = [
|
|
20
|
+
{
|
|
21
|
+
name: "planner",
|
|
22
|
+
description: "MANDATORY for scope/design/plan and PROACTIVE for high-ambiguity work. MUST BE USED when sequencing, dependency mapping, or risk trade-offs are required before coding.",
|
|
23
|
+
tools: ["Read", "Grep", "Glob", "WebSearch"],
|
|
24
|
+
model: "deep",
|
|
25
|
+
activation: "mandatory",
|
|
26
|
+
relatedStages: ["brainstorm", "scope", "design", "spec", "plan"],
|
|
27
|
+
body: [
|
|
28
|
+
"You are an **implementation planning specialist** (staff engineer mindset).",
|
|
29
|
+
"",
|
|
30
|
+
"When invoked:",
|
|
31
|
+
"1. Analyze scope and break it into concrete sub-problems.",
|
|
32
|
+
"2. Map each sub-problem to existing modules and reusable code.",
|
|
33
|
+
"3. Produce an ordered execution plan with dependencies and checks.",
|
|
34
|
+
"4. Highlight risks and unknowns that need user decisions.",
|
|
35
|
+
"",
|
|
36
|
+
"**Role boundary:** planning only. Do NOT write production code."
|
|
37
|
+
].join("\n")
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "reviewer",
|
|
41
|
+
description: "MANDATORY during review. MUST BE USED to run a two-pass audit: spec compliance first, then correctness/maintainability/performance/architecture.",
|
|
42
|
+
tools: ["Read", "Grep", "Glob"],
|
|
43
|
+
model: "balanced",
|
|
44
|
+
activation: "mandatory",
|
|
45
|
+
relatedStages: ["spec", "review", "ship"],
|
|
46
|
+
body: [
|
|
47
|
+
"You are a **combined spec + code reviewer**.",
|
|
48
|
+
"",
|
|
49
|
+
"Run two explicit passes:",
|
|
50
|
+
"",
|
|
51
|
+
"1. **Spec pass**",
|
|
52
|
+
" - For each acceptance criterion: PASS / PARTIAL / FAIL.",
|
|
53
|
+
" - Cite evidence as `file:line`.",
|
|
54
|
+
"",
|
|
55
|
+
"2. **Code-quality pass**",
|
|
56
|
+
" - Correctness: logic, boundaries, state transitions.",
|
|
57
|
+
" - Maintainability: naming, structure, complexity, debt risks.",
|
|
58
|
+
" - Performance: avoid obvious hot-path regressions.",
|
|
59
|
+
" - Architecture fit: layering and contract stability.",
|
|
60
|
+
"",
|
|
61
|
+
"For each finding include:",
|
|
62
|
+
"- Severity: `Critical` | `Important` | `Suggestion`",
|
|
63
|
+
"- Location: `file:line`",
|
|
64
|
+
"- Problem and concrete recommendation",
|
|
65
|
+
"",
|
|
66
|
+
"**Trust model:** never rely on implementer claims; verify by reading code."
|
|
67
|
+
].join("\n")
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "security-reviewer",
|
|
71
|
+
description: "MANDATORY during review; PROACTIVE during design/ship for trust-boundary changes. Always produce an explicit no-change attestation when no security-relevant surface moved.",
|
|
72
|
+
tools: ["Read", "Grep", "Glob"],
|
|
73
|
+
model: "balanced",
|
|
74
|
+
activation: "mandatory",
|
|
75
|
+
relatedStages: ["design", "review", "ship"],
|
|
76
|
+
body: [
|
|
77
|
+
"You are a **security vulnerability specialist** focused on exploitability.",
|
|
78
|
+
"",
|
|
79
|
+
"Check for (non-exhaustive):",
|
|
80
|
+
"- validation gaps and injection vectors",
|
|
81
|
+
"- authz/authn boundary violations",
|
|
82
|
+
"- secret leakage in code/logging",
|
|
83
|
+
"- unsafe file/system/network operations",
|
|
84
|
+
"- privilege escalation and trust-boundary misuse",
|
|
85
|
+
"",
|
|
86
|
+
"For each finding include:",
|
|
87
|
+
"- severity aligned to ship risk",
|
|
88
|
+
"- CWE ID when possible (or UNKNOWN)",
|
|
89
|
+
"- short proof-of-concept vector",
|
|
90
|
+
"- concrete control-oriented fix"
|
|
91
|
+
].join("\n")
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "test-author",
|
|
95
|
+
description: "MANDATORY in TDD stage. MUST BE USED for RED -> GREEN -> REFACTOR with evidence-first discipline.",
|
|
96
|
+
tools: ["Read", "Write", "Edit", "Grep", "Glob", "Bash"],
|
|
97
|
+
model: "balanced",
|
|
98
|
+
activation: "mandatory",
|
|
99
|
+
relatedStages: ["tdd"],
|
|
100
|
+
body: [
|
|
101
|
+
"You are a **test-driven development** specialist.",
|
|
102
|
+
"",
|
|
103
|
+
"**Iron law:** no production code without a failing test first.",
|
|
104
|
+
"",
|
|
105
|
+
"Process:",
|
|
106
|
+
"1. RED: write a failing test for the desired behavior.",
|
|
107
|
+
"2. Verify RED fails for the right reason.",
|
|
108
|
+
"3. GREEN: implement minimal code to pass.",
|
|
109
|
+
"4. Verify GREEN on relevant suite/full suite.",
|
|
110
|
+
"5. REFACTOR with behavior preserved."
|
|
111
|
+
].join("\n")
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "doc-updater",
|
|
115
|
+
description: "MANDATORY at ship and PROACTIVE when behavior/config/public API changes. Keep docs and runbooks in lockstep with shipped behavior.",
|
|
116
|
+
tools: ["Read", "Write", "Edit", "Grep", "Glob"],
|
|
117
|
+
model: "fast",
|
|
118
|
+
activation: "mandatory",
|
|
119
|
+
relatedStages: ["tdd", "ship"],
|
|
120
|
+
body: [
|
|
121
|
+
"You are a **documentation maintenance specialist**.",
|
|
122
|
+
"",
|
|
123
|
+
"After code changes, verify and update only stale sections in:",
|
|
124
|
+
"- README / setup / usage",
|
|
125
|
+
"- API docs and examples",
|
|
126
|
+
"- migration and operational notes",
|
|
127
|
+
"",
|
|
128
|
+
"Preserve existing tone and structure; avoid rewrites for style alone."
|
|
129
|
+
].join("\n")
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
import { enhancedAgentBody } from "./subagents.js";
|
|
133
|
+
/**
|
|
134
|
+
* Render a complete cclaw agent markdown file (YAML frontmatter + body).
|
|
135
|
+
*/
|
|
136
|
+
export function agentMarkdown(agent) {
|
|
137
|
+
const frontmatter = [
|
|
138
|
+
"---",
|
|
139
|
+
`name: ${agent.name}`,
|
|
140
|
+
`description: ${yamlScalarString(agent.description)}`,
|
|
141
|
+
`tools: ${yamlFlowSequence(agent.tools)}`,
|
|
142
|
+
`model: ${agent.model}`,
|
|
143
|
+
"---"
|
|
144
|
+
].join("\n");
|
|
145
|
+
const relatedStages = agent.relatedStages.length > 0 ? agent.relatedStages.join(", ") : "(none)";
|
|
146
|
+
const taskDelegation = enhancedAgentBody(agent.name);
|
|
147
|
+
return `${frontmatter}
|
|
148
|
+
|
|
149
|
+
# ${agent.name}
|
|
150
|
+
|
|
151
|
+
${agent.body}
|
|
152
|
+
|
|
153
|
+
## Activation
|
|
154
|
+
|
|
155
|
+
- Mode: ${agent.activation}
|
|
156
|
+
- Related stages: ${relatedStages}
|
|
157
|
+
|
|
158
|
+
## Rules
|
|
159
|
+
|
|
160
|
+
- Cite file:line for every finding
|
|
161
|
+
- Do not make changes outside your specialist domain
|
|
162
|
+
- Report findings with severity classification
|
|
163
|
+
- If uncertain, say "UNKNOWN" - never guess
|
|
164
|
+
|
|
165
|
+
${taskDelegation}
|
|
166
|
+
`;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Markdown table mapping cclaw stage entry points to specialist agents.
|
|
170
|
+
*/
|
|
171
|
+
export function agentRoutingTable() {
|
|
172
|
+
return `| Stage Entry | Primary Agent(s) | Supporting guidance |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| Brainstorm (start with \`/cc <idea>\`) | planner | Run in-thread research playbooks: \`research/repo-scan.md\`, \`research/learnings-lookup.md\` |
|
|
175
|
+
| Scope / Design / Plan (via \`/cc-next\`) | planner | Use \`research/git-history.md\` (scope) and \`research/framework-docs-lookup.md\` + \`research/best-practices-lookup.md\` (design) as needed |
|
|
176
|
+
| Spec (via \`/cc-next\`) | reviewer | planner (if ambiguity or conflicts remain) |
|
|
177
|
+
| TDD (via \`/cc-next\`) | test-author | doc-updater on public behavior/config changes |
|
|
178
|
+
| Review (via \`/cc-next\`) | reviewer, security-reviewer | conditional second reviewer for high blast-radius diffs |
|
|
179
|
+
| Ship (via \`/cc-next\`) | doc-updater | security-reviewer when release risk is elevated |
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Cost tier routing for the core-5 agent roster.
|
|
184
|
+
*/
|
|
185
|
+
export function agentCostTierTable() {
|
|
186
|
+
return `| Tier | Use for | Example agents |
|
|
187
|
+
|---|---|---|
|
|
188
|
+
| \`deep\` | one heavy planning pass per stage | planner |
|
|
189
|
+
| \`balanced\` | review and TDD specialists with stronger reasoning depth | reviewer, security-reviewer, test-author |
|
|
190
|
+
| \`fast\` | bounded maintenance updates with limited blast radius | doc-updater |
|
|
191
|
+
`;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* AGENTS.md-ready section describing cclaw’s specialist delegation model.
|
|
195
|
+
*/
|
|
196
|
+
export function agentsAgentsMdBlock() {
|
|
197
|
+
return `### Agent Specialists
|
|
198
|
+
|
|
199
|
+
cclaw materializes **5 core specialist agents** under \`.cclaw/agents/\`.
|
|
200
|
+
|
|
201
|
+
${agentRoutingTable()}
|
|
202
|
+
|
|
203
|
+
### Research Playbooks (in-thread)
|
|
204
|
+
|
|
205
|
+
Research work is no longer modeled as standalone personas. Use in-thread playbooks under \`.cclaw/skills/research/\`:
|
|
206
|
+
|
|
207
|
+
- \`repo-scan.md\`
|
|
208
|
+
- \`learnings-lookup.md\`
|
|
209
|
+
- \`framework-docs-lookup.md\`
|
|
210
|
+
- \`best-practices-lookup.md\`
|
|
211
|
+
- \`git-history.md\`
|
|
212
|
+
|
|
213
|
+
### Activation modes
|
|
214
|
+
|
|
215
|
+
- **Mandatory:** planner (scope/design/plan), reviewer + security-reviewer (review), test-author (tdd), doc-updater (ship).
|
|
216
|
+
- **Proactive:** planner on ambiguity, security-reviewer on trust-boundary movement outside review, doc-updater on behavior/config drift.
|
|
217
|
+
- **On-demand:** none in the core-5 roster; research playbooks are in-thread procedures.
|
|
218
|
+
|
|
219
|
+
### Cost-aware routing
|
|
220
|
+
|
|
221
|
+
${agentCostTierTable()}
|
|
222
|
+
|
|
223
|
+
**Agent files:** \`.cclaw/agents/{name}.md\` — each contains YAML frontmatter with tools and model tier.
|
|
224
|
+
`;
|
|
225
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
|
+
export const DOCTOR_REFERENCE_DIR = `${RUNTIME_ROOT}/references/doctor`;
|
|
3
|
+
export const DOCTOR_REFERENCE_MARKDOWN = {
|
|
4
|
+
"README.md": `# Doctor Reference Index
|
|
5
|
+
|
|
6
|
+
Reference docs for \`cclaw doctor\` checks.
|
|
7
|
+
|
|
8
|
+
## Categories
|
|
9
|
+
|
|
10
|
+
- \`runtime-layout.md\` - runtime directories, generated commands, and skill files
|
|
11
|
+
- \`hooks-and-lifecycle.md\` - hook wiring and harness lifecycle integration
|
|
12
|
+
- \`harness-and-routing.md\` - harness shims, AGENTS/CLAUDE routing blocks, cursor rule
|
|
13
|
+
- \`state-and-gates.md\` - flow-state integrity and gate evidence contracts
|
|
14
|
+
- \`delegation-and-preamble.md\` - mandatory delegations and preamble budget controls
|
|
15
|
+
- \`traceability.md\` - spec/plan/tdd trace matrix expectations
|
|
16
|
+
- \`tooling-capabilities.md\` - local runtime prerequisites (bash/node/python/jq)
|
|
17
|
+
- \`config-and-policy.md\` - config schema, rules policy, and validation references
|
|
18
|
+
`,
|
|
19
|
+
"runtime-layout.md": `# Runtime Layout
|
|
20
|
+
|
|
21
|
+
## Expected surfaces
|
|
22
|
+
|
|
23
|
+
- \`.cclaw/\` root and generated subdirectories
|
|
24
|
+
- stage command contracts under \`.cclaw/commands/\`
|
|
25
|
+
- stage skills under \`.cclaw/skills/\`
|
|
26
|
+
- utility command contracts (\`start\`, \`next\`, \`learn\`, \`status\`)
|
|
27
|
+
- state files under \`.cclaw/state/\`
|
|
28
|
+
|
|
29
|
+
## Typical fixes
|
|
30
|
+
|
|
31
|
+
1. Run \`cclaw sync\` to re-materialize generated assets.
|
|
32
|
+
2. If runtime is severely drifted, run \`cclaw upgrade\`.
|
|
33
|
+
3. Avoid manual edits under generated runtime paths unless explicitly supported.
|
|
34
|
+
`,
|
|
35
|
+
"hooks-and-lifecycle.md": `# Hooks And Lifecycle
|
|
36
|
+
|
|
37
|
+
## Expected behavior
|
|
38
|
+
|
|
39
|
+
- session start rehydrates flow + knowledge digest
|
|
40
|
+
- pre-tool hooks run prompt/workflow guards
|
|
41
|
+
- post-tool hooks run context monitor
|
|
42
|
+
- stop hooks checkpoint progress
|
|
43
|
+
- OpenCode uses plugin-based lifecycle integration
|
|
44
|
+
|
|
45
|
+
## Typical fixes
|
|
46
|
+
|
|
47
|
+
1. Re-run \`cclaw sync\` after harness config changes.
|
|
48
|
+
2. Ensure harness is enabled in \`.cclaw/config.yaml\`.
|
|
49
|
+
3. Validate hook JSON shape and remove malformed manual edits.
|
|
50
|
+
`,
|
|
51
|
+
"harness-and-routing.md": `# Harness And Routing
|
|
52
|
+
|
|
53
|
+
## Expected behavior
|
|
54
|
+
|
|
55
|
+
- command shims exist for every enabled harness
|
|
56
|
+
- managed routing block is present in \`AGENTS.md\` (and \`CLAUDE.md\` when applicable)
|
|
57
|
+
- cursor rule mirrors workflow activation guidance
|
|
58
|
+
- opencode plugin path is registered in opencode config
|
|
59
|
+
|
|
60
|
+
## Typical fixes
|
|
61
|
+
|
|
62
|
+
1. Confirm \`harnesses\` list in \`.cclaw/config.yaml\`.
|
|
63
|
+
2. Run \`cclaw sync\` to re-generate shims/routing files.
|
|
64
|
+
3. Remove stale harness artifacts for disabled harnesses via \`cclaw sync\`.
|
|
65
|
+
`,
|
|
66
|
+
"state-and-gates.md": `# State And Gates
|
|
67
|
+
|
|
68
|
+
## Expected behavior
|
|
69
|
+
|
|
70
|
+
- \`flow-state.json\` has activeRunId, current stage, and consistent track/skippedStages
|
|
71
|
+
- current-stage gate evidence is internally consistent
|
|
72
|
+
- completed stages only include passed required gates
|
|
73
|
+
|
|
74
|
+
## Typical fixes
|
|
75
|
+
|
|
76
|
+
1. Run \`cclaw doctor --reconcile-gates\` to refresh current-stage gate catalog.
|
|
77
|
+
2. Repair inconsistent stage artifacts, then re-run doctor.
|
|
78
|
+
3. Do not manually mutate gate arrays without matching artifact evidence.
|
|
79
|
+
`,
|
|
80
|
+
"delegation-and-preamble.md": `# Delegation And Preamble
|
|
81
|
+
|
|
82
|
+
## Delegation contract
|
|
83
|
+
|
|
84
|
+
- mandatory delegations for the current stage must be completed or waived
|
|
85
|
+
- waivers should include an explicit reason
|
|
86
|
+
- stale entries from previous runs are ignored by current-run checks
|
|
87
|
+
|
|
88
|
+
## Preamble budget contract
|
|
89
|
+
|
|
90
|
+
- preamble events are logged to \`.cclaw/state/preamble-log.jsonl\`
|
|
91
|
+
- repeated entries inside cooldown windows indicate noisy preamble behavior
|
|
92
|
+
- in TDD wave mode, emit once per wave unless plan materially changes
|
|
93
|
+
|
|
94
|
+
## Typical fixes
|
|
95
|
+
|
|
96
|
+
1. Append missing delegation records with \`completed\` or \`waived\` status.
|
|
97
|
+
2. Record harness-limitation waivers when native delegation is unavailable.
|
|
98
|
+
3. Reduce repeated preamble emissions and keep logs structured (\`ts/stage/trigger/hash\`).
|
|
99
|
+
`,
|
|
100
|
+
"traceability.md": `# Traceability
|
|
101
|
+
|
|
102
|
+
## Expected behavior
|
|
103
|
+
|
|
104
|
+
- spec criteria map to plan tasks
|
|
105
|
+
- plan tasks map to tdd slices/tests
|
|
106
|
+
- no orphaned criteria/tasks/tests when downstream artifacts exist
|
|
107
|
+
|
|
108
|
+
## Typical fixes
|
|
109
|
+
|
|
110
|
+
1. Add stable IDs to spec/plan/tdd sections.
|
|
111
|
+
2. Ensure mapping tables include every active criterion/task/slice.
|
|
112
|
+
3. Re-run \`cclaw doctor\` after artifact updates.
|
|
113
|
+
`,
|
|
114
|
+
"tooling-capabilities.md": `# Tooling Capabilities
|
|
115
|
+
|
|
116
|
+
## Required
|
|
117
|
+
|
|
118
|
+
- \`bash\` for runtime hook scripts
|
|
119
|
+
- \`node\` for generated runtime scripts/plugins
|
|
120
|
+
|
|
121
|
+
## Optional fallback
|
|
122
|
+
|
|
123
|
+
- at least one of \`python3\` or \`jq\` for JSON parsing fallback paths
|
|
124
|
+
|
|
125
|
+
## Typical fixes
|
|
126
|
+
|
|
127
|
+
1. Install missing runtime tools.
|
|
128
|
+
2. Keep at least one JSON fallback parser available (\`python3\` or \`jq\`).
|
|
129
|
+
`,
|
|
130
|
+
"config-and-policy.md": `# Config And Policy
|
|
131
|
+
|
|
132
|
+
## Expected behavior
|
|
133
|
+
|
|
134
|
+
- \`.cclaw/config.yaml\` parses and uses supported keys/values
|
|
135
|
+
- \`.cclaw/rules/rules.json\` matches generated policy schema
|
|
136
|
+
- policy needles and required sections remain present in generated contracts
|
|
137
|
+
|
|
138
|
+
## Typical fixes
|
|
139
|
+
|
|
140
|
+
1. Repair invalid config values and run \`cclaw sync\`.
|
|
141
|
+
2. Re-generate policy files via \`cclaw sync\` if drift is detected.
|
|
142
|
+
3. Keep generated contracts aligned with stage schemas and policy needles.
|
|
143
|
+
`
|
|
144
|
+
};
|
package/dist/content/examples.js
CHANGED
|
@@ -379,7 +379,7 @@ Execution rule: complete and verify each wave before starting the next wave.
|
|
|
379
379
|
## Review Army Contract
|
|
380
380
|
|
|
381
381
|
- See \`07-review-army.json\`
|
|
382
|
-
- Reconciliation summary: 1 duplicate collapsed (R-1 reported by
|
|
382
|
+
- Reconciliation summary: 1 duplicate collapsed (R-1 reported by reviewer and security-reviewer), 0 conflicts
|
|
383
383
|
|
|
384
384
|
## Review Readiness Dashboard
|
|
385
385
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function harnessIntegrationDocMarkdown(): string;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { HARNESS_ADAPTERS, harnessTier } from "../harness-adapters.js";
|
|
2
|
+
import { HOOK_EVENTS_BY_HARNESS, HOOK_SEMANTIC_EVENTS } from "./hook-events.js";
|
|
3
|
+
function harnessTitle(harness) {
|
|
4
|
+
switch (harness) {
|
|
5
|
+
case "claude":
|
|
6
|
+
return "Claude Code";
|
|
7
|
+
case "cursor":
|
|
8
|
+
return "Cursor";
|
|
9
|
+
case "opencode":
|
|
10
|
+
return "OpenCode";
|
|
11
|
+
case "codex":
|
|
12
|
+
return "OpenAI Codex";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function tierDescription(tier) {
|
|
16
|
+
if (tier === "tier1")
|
|
17
|
+
return "full native automation";
|
|
18
|
+
if (tier === "tier2")
|
|
19
|
+
return "partial automation with waivers";
|
|
20
|
+
return "manual fallback only";
|
|
21
|
+
}
|
|
22
|
+
export function harnessIntegrationDocMarkdown() {
|
|
23
|
+
const harnesses = Object.keys(HARNESS_ADAPTERS);
|
|
24
|
+
const capabilityRows = harnesses
|
|
25
|
+
.map((harness) => {
|
|
26
|
+
const adapter = HARNESS_ADAPTERS[harness];
|
|
27
|
+
const tier = harnessTier(harness);
|
|
28
|
+
return `| ${harnessTitle(harness)} | \`${harness}\` | \`${tier}\` (${tierDescription(tier)}) | ${adapter.capabilities.nativeSubagentDispatch} | ${adapter.capabilities.hookSurface} | ${adapter.capabilities.structuredAsk} |`;
|
|
29
|
+
})
|
|
30
|
+
.join("\n");
|
|
31
|
+
const hookRows = HOOK_SEMANTIC_EVENTS.map((eventName) => {
|
|
32
|
+
const columns = harnesses
|
|
33
|
+
.map((harness) => {
|
|
34
|
+
const mapping = HOOK_EVENTS_BY_HARNESS[harness][eventName];
|
|
35
|
+
return mapping ?? "missing";
|
|
36
|
+
})
|
|
37
|
+
.join(" | ");
|
|
38
|
+
return `| \`${eventName}\` | ${columns} |`;
|
|
39
|
+
}).join("\n");
|
|
40
|
+
return `# Harness Integration Matrix
|
|
41
|
+
|
|
42
|
+
Generated from \`src/harness-adapters.ts\` capabilities and hook event mappings.
|
|
43
|
+
|
|
44
|
+
## Capability tiers
|
|
45
|
+
|
|
46
|
+
| Harness | ID | Tier | Native subagent dispatch | Hook surface | Structured ask |
|
|
47
|
+
|---|---|---|---|---|---|
|
|
48
|
+
${capabilityRows}
|
|
49
|
+
|
|
50
|
+
## Semantic hook event coverage
|
|
51
|
+
|
|
52
|
+
| Event | Claude | Cursor | OpenCode | Codex |
|
|
53
|
+
|---|---|---|---|---|
|
|
54
|
+
${hookRows}
|
|
55
|
+
|
|
56
|
+
## Interpretation
|
|
57
|
+
|
|
58
|
+
- \`tier1\`: full native delegation + structured asks + full hook surface.
|
|
59
|
+
- \`tier2\`: usable flow with capability gaps; mandatory delegation can require waivers.
|
|
60
|
+
- \`tier3\`: manual-only fallback; no native automation guarantees.
|
|
61
|
+
|
|
62
|
+
## Shared command contract
|
|
63
|
+
|
|
64
|
+
All harnesses receive the same utility commands:
|
|
65
|
+
|
|
66
|
+
- \`/cc\` - flow entry and resume
|
|
67
|
+
- \`/cc-next\` - stage progression
|
|
68
|
+
- \`/cc-learn\` - knowledge capture/lookup
|
|
69
|
+
|
|
70
|
+
Stage order remains canonical:
|
|
71
|
+
\`brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship\`
|
|
72
|
+
|
|
73
|
+
## Install surfaces
|
|
74
|
+
|
|
75
|
+
Always generated:
|
|
76
|
+
|
|
77
|
+
- \`.cclaw/commands/*.md\`
|
|
78
|
+
- \`.cclaw/skills/*/SKILL.md\`
|
|
79
|
+
- \`.cclaw/references/**\`
|
|
80
|
+
- \`.cclaw/state/*.json|*.jsonl\`
|
|
81
|
+
- \`AGENTS.md\` managed block
|
|
82
|
+
|
|
83
|
+
Harness-specific additions:
|
|
84
|
+
|
|
85
|
+
- \`claude\`: \`.claude/commands/cc*.md\`, \`.claude/hooks/hooks.json\`
|
|
86
|
+
- \`cursor\`: \`.cursor/commands/cc*.md\`, \`.cursor/hooks.json\`, \`.cursor/rules/cclaw-workflow.mdc\`
|
|
87
|
+
- \`opencode\`: \`.opencode/commands/cc*.md\`, \`.opencode/plugins/cclaw-plugin.mjs\`, opencode plugin registration
|
|
88
|
+
- \`codex\`: \`.codex/commands/cc*.md\`, \`.codex/hooks.json\`
|
|
89
|
+
|
|
90
|
+
## Runtime observability
|
|
91
|
+
|
|
92
|
+
- \`.cclaw/state/harness-gaps.json\` captures per-harness capability gaps for the active config.
|
|
93
|
+
- \`cclaw doctor\` validates shim, hook, and lifecycle surfaces against this capability model.
|
|
94
|
+
`;
|
|
95
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HarnessId } from "../types.js";
|
|
2
|
+
export declare const HOOK_SEMANTIC_EVENTS: readonly ["session_rehydrate", "pre_tool_prompt_guard", "pre_tool_workflow_guard", "post_tool_context_monitor", "stop_checkpoint", "precompact_digest"];
|
|
3
|
+
export type HookSemanticEvent = (typeof HOOK_SEMANTIC_EVENTS)[number];
|
|
4
|
+
export declare const HOOK_EVENTS_BY_HARNESS: Record<HarnessId, Partial<Record<HookSemanticEvent, string>>>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const HOOK_SEMANTIC_EVENTS = [
|
|
2
|
+
"session_rehydrate",
|
|
3
|
+
"pre_tool_prompt_guard",
|
|
4
|
+
"pre_tool_workflow_guard",
|
|
5
|
+
"post_tool_context_monitor",
|
|
6
|
+
"stop_checkpoint",
|
|
7
|
+
"precompact_digest"
|
|
8
|
+
];
|
|
9
|
+
export const HOOK_EVENTS_BY_HARNESS = {
|
|
10
|
+
claude: {
|
|
11
|
+
session_rehydrate: "SessionStart matcher startup|resume|clear|compact",
|
|
12
|
+
pre_tool_prompt_guard: "PreToolUse -> prompt-guard.sh",
|
|
13
|
+
pre_tool_workflow_guard: "PreToolUse -> workflow-guard.sh",
|
|
14
|
+
post_tool_context_monitor: "PostToolUse -> context-monitor.sh",
|
|
15
|
+
stop_checkpoint: "Stop -> stop-checkpoint.sh",
|
|
16
|
+
precompact_digest: "PreCompact -> pre-compact.sh"
|
|
17
|
+
},
|
|
18
|
+
cursor: {
|
|
19
|
+
session_rehydrate: "sessionStart/sessionResume/sessionClear/sessionCompact",
|
|
20
|
+
pre_tool_prompt_guard: "preToolUse -> prompt-guard.sh",
|
|
21
|
+
pre_tool_workflow_guard: "preToolUse -> workflow-guard.sh",
|
|
22
|
+
post_tool_context_monitor: "postToolUse -> context-monitor.sh",
|
|
23
|
+
stop_checkpoint: "stop -> stop-checkpoint.sh",
|
|
24
|
+
precompact_digest: "sessionCompact -> pre-compact.sh"
|
|
25
|
+
},
|
|
26
|
+
opencode: {
|
|
27
|
+
session_rehydrate: "plugin event handlers + transform rehydration",
|
|
28
|
+
pre_tool_prompt_guard: "plugin tool.execute.before -> prompt-guard.sh",
|
|
29
|
+
pre_tool_workflow_guard: "plugin tool.execute.before -> workflow-guard.sh",
|
|
30
|
+
post_tool_context_monitor: "plugin tool.execute.after -> context-monitor.sh",
|
|
31
|
+
stop_checkpoint: "plugin session.idle -> stop-checkpoint.sh",
|
|
32
|
+
precompact_digest: "plugin session.cleared/session.resumed hooks"
|
|
33
|
+
},
|
|
34
|
+
codex: {
|
|
35
|
+
session_rehydrate: "SessionStart matcher startup|resume|clear|compact",
|
|
36
|
+
pre_tool_prompt_guard: "PreToolUse -> prompt-guard.sh",
|
|
37
|
+
pre_tool_workflow_guard: "PreToolUse -> workflow-guard.sh",
|
|
38
|
+
post_tool_context_monitor: "PostToolUse -> context-monitor.sh",
|
|
39
|
+
stop_checkpoint: "Stop -> stop-checkpoint.sh",
|
|
40
|
+
precompact_digest: "PreCompact -> pre-compact.sh"
|
|
41
|
+
}
|
|
42
|
+
};
|
package/dist/content/hooks.js
CHANGED
|
@@ -39,7 +39,7 @@ export const RUNTIME_SHELL_DETECT_ROOT = DETECT_ROOT;
|
|
|
39
39
|
export function sessionStartScript(_options = {}) {
|
|
40
40
|
return `#!/usr/bin/env bash
|
|
41
41
|
# cclaw session-start hook — generated by cclaw sync
|
|
42
|
-
# Injects using-cclaw + flow status + active artifacts + knowledge
|
|
42
|
+
# Injects using-cclaw + flow status + active artifacts + compact knowledge digest + checkpoint/activity summary.
|
|
43
43
|
set -euo pipefail
|
|
44
44
|
|
|
45
45
|
${DETECT_ROOT}
|
|
@@ -52,6 +52,7 @@ CONTEXT_WARNINGS_FILE="$ROOT/${RUNTIME_ROOT}/state/context-warnings.jsonl"
|
|
|
52
52
|
CONTEXT_MODE_FILE="$ROOT/${RUNTIME_ROOT}/state/context-mode.json"
|
|
53
53
|
CONTEXTS_DIR="$ROOT/${RUNTIME_ROOT}/contexts"
|
|
54
54
|
KNOWLEDGE_FILE="$ROOT/${RUNTIME_ROOT}/knowledge.jsonl"
|
|
55
|
+
KNOWLEDGE_DIGEST_FILE="$ROOT/${RUNTIME_ROOT}/state/knowledge-digest.md"
|
|
55
56
|
META_SKILL="$ROOT/${RUNTIME_ROOT}/skills/${META_SKILL_NAME}/SKILL.md"
|
|
56
57
|
|
|
57
58
|
# --- Read flow state ---
|
|
@@ -309,12 +310,72 @@ if [ -f "$META_SKILL" ]; then
|
|
|
309
310
|
META_CONTENT=$(cat "$META_SKILL" 2>/dev/null || echo "")
|
|
310
311
|
fi
|
|
311
312
|
|
|
312
|
-
# ---
|
|
313
|
-
|
|
313
|
+
# --- Build compact knowledge digest (stage-biased, top entries only) ---
|
|
314
|
+
KNOWLEDGE_DIGEST=""
|
|
314
315
|
LEARNINGS_COUNT=0
|
|
315
316
|
if [ -f "$KNOWLEDGE_FILE" ] && [ -s "$KNOWLEDGE_FILE" ]; then
|
|
316
|
-
KNOWLEDGE_SUMMARY=$(tail -n 30 "$KNOWLEDGE_FILE" 2>/dev/null || echo "")
|
|
317
317
|
LEARNINGS_COUNT=$(grep -c '^{' "$KNOWLEDGE_FILE" 2>/dev/null || echo "0")
|
|
318
|
+
if command -v jq >/dev/null 2>&1; then
|
|
319
|
+
KNOWLEDGE_DIGEST=$(tail -n 200 "$KNOWLEDGE_FILE" 2>/dev/null | jq -Rsc --arg stage "$STAGE" '
|
|
320
|
+
split("\\n")
|
|
321
|
+
| map(select(length > 0))
|
|
322
|
+
| map(try fromjson catch null)
|
|
323
|
+
| map(select(type == "object"))
|
|
324
|
+
| map(select((.stage // null) == $stage or (.stage // null) == null))
|
|
325
|
+
| reverse
|
|
326
|
+
| .[0:8]
|
|
327
|
+
| map("- [" + ((.confidence // "unknown")|tostring) + " • " + ((.stage // "global")|tostring) + " • " + ((.domain // "general")|tostring) + "] " + ((.trigger // "trigger")|tostring) + " -> " + ((.action // "action")|tostring))
|
|
328
|
+
| join("\\n")
|
|
329
|
+
' 2>/dev/null || echo "")
|
|
330
|
+
elif command -v python3 >/dev/null 2>&1; then
|
|
331
|
+
KNOWLEDGE_DIGEST=$(python3 - "$KNOWLEDGE_FILE" "$STAGE" <<'PY'
|
|
332
|
+
import json
|
|
333
|
+
import sys
|
|
334
|
+
|
|
335
|
+
path = sys.argv[1]
|
|
336
|
+
stage = sys.argv[2]
|
|
337
|
+
entries = []
|
|
338
|
+
try:
|
|
339
|
+
with open(path, "r", encoding="utf-8") as fh:
|
|
340
|
+
lines = fh.readlines()[-200:]
|
|
341
|
+
for raw in lines:
|
|
342
|
+
raw = raw.strip()
|
|
343
|
+
if not raw:
|
|
344
|
+
continue
|
|
345
|
+
try:
|
|
346
|
+
obj = json.loads(raw)
|
|
347
|
+
except Exception:
|
|
348
|
+
continue
|
|
349
|
+
if not isinstance(obj, dict):
|
|
350
|
+
continue
|
|
351
|
+
row_stage = obj.get("stage")
|
|
352
|
+
if row_stage not in (stage, None):
|
|
353
|
+
continue
|
|
354
|
+
entries.append(obj)
|
|
355
|
+
except Exception:
|
|
356
|
+
entries = []
|
|
357
|
+
|
|
358
|
+
entries = list(reversed(entries))[:8]
|
|
359
|
+
out = []
|
|
360
|
+
for obj in entries:
|
|
361
|
+
conf = str(obj.get("confidence", "unknown"))
|
|
362
|
+
row_stage = str(obj.get("stage", "global"))
|
|
363
|
+
domain = str(obj.get("domain", "general"))
|
|
364
|
+
trigger = str(obj.get("trigger", "trigger"))
|
|
365
|
+
action = str(obj.get("action", "action"))
|
|
366
|
+
out.append(f"- [{conf} • {row_stage} • {domain}] {trigger} -> {action}")
|
|
367
|
+
print("\\n".join(out))
|
|
368
|
+
PY
|
|
369
|
+
)
|
|
370
|
+
else
|
|
371
|
+
KNOWLEDGE_DIGEST=$(tail -n 8 "$KNOWLEDGE_FILE" 2>/dev/null || echo "")
|
|
372
|
+
fi
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
if [ -n "$KNOWLEDGE_DIGEST" ]; then
|
|
376
|
+
printf '# Knowledge digest (auto-generated)\\n\\n%s\\n' "$KNOWLEDGE_DIGEST" > "$KNOWLEDGE_DIGEST_FILE" 2>/dev/null || true
|
|
377
|
+
elif [ -f "$KNOWLEDGE_DIGEST_FILE" ]; then
|
|
378
|
+
printf '# Knowledge digest (auto-generated)\\n\\n(no matching entries for current stage)\\n' > "$KNOWLEDGE_DIGEST_FILE" 2>/dev/null || true
|
|
318
379
|
fi
|
|
319
380
|
|
|
320
381
|
# --- Installed cclaw-cli version vs. project's recorded version (one-block
|
|
@@ -391,10 +452,10 @@ if [ -n "$STAGE_SUGGESTION" ]; then
|
|
|
391
452
|
$STAGE_SUGGESTION
|
|
392
453
|
To disable suggestions persistently set ${RUNTIME_ROOT}/state/suggestion-memory.json -> enabled=false."
|
|
393
454
|
fi
|
|
394
|
-
if [ -n "$
|
|
455
|
+
if [ -n "$KNOWLEDGE_DIGEST" ]; then
|
|
395
456
|
CTX="$CTX
|
|
396
|
-
Knowledge
|
|
397
|
-
$
|
|
457
|
+
Knowledge digest (top relevant entries):
|
|
458
|
+
$KNOWLEDGE_DIGEST"
|
|
398
459
|
fi
|
|
399
460
|
if [ -n "$META_CONTENT" ]; then
|
|
400
461
|
CTX="$CTX
|
|
@@ -833,6 +894,7 @@ export default function cclawPlugin(ctx) {
|
|
|
833
894
|
const contextsDir = join(runtimeDir, "contexts");
|
|
834
895
|
const sessionDigestPath = join(stateDir, "session-digest.md");
|
|
835
896
|
const knowledgePath = join(runtimeDir, "knowledge.jsonl");
|
|
897
|
+
const knowledgeDigestPath = join(stateDir, "knowledge-digest.md");
|
|
836
898
|
const metaSkillPath = join(runtimeDir, "skills/${META_SKILL_NAME}/SKILL.md");
|
|
837
899
|
|
|
838
900
|
function ensureRuntimeDirs() {
|
|
@@ -937,8 +999,16 @@ export default function cclawPlugin(ctx) {
|
|
|
937
999
|
}
|
|
938
1000
|
}
|
|
939
1001
|
|
|
940
|
-
function
|
|
941
|
-
|
|
1002
|
+
function readKnowledgeDigest() {
|
|
1003
|
+
const digest = readFileText(knowledgeDigestPath).trim();
|
|
1004
|
+
if (!digest) {
|
|
1005
|
+
return readTailLines(knowledgePath, 12);
|
|
1006
|
+
}
|
|
1007
|
+
return digest
|
|
1008
|
+
.split(/\\r?\\n/)
|
|
1009
|
+
.map((line) => line.trim())
|
|
1010
|
+
.filter((line) => line.length > 0)
|
|
1011
|
+
.filter((line) => !line.startsWith("#"));
|
|
942
1012
|
}
|
|
943
1013
|
|
|
944
1014
|
function buildBootstrap() {
|
|
@@ -965,8 +1035,8 @@ export default function cclawPlugin(ctx) {
|
|
|
965
1035
|
const warning = readLatestContextWarning();
|
|
966
1036
|
if (warning) parts.push("Latest context warning:", warning);
|
|
967
1037
|
|
|
968
|
-
const knowledge =
|
|
969
|
-
if (knowledge.length > 0) parts.push("Knowledge
|
|
1038
|
+
const knowledge = readKnowledgeDigest();
|
|
1039
|
+
if (knowledge.length > 0) parts.push("Knowledge digest (top relevant entries):", ...knowledge);
|
|
970
1040
|
|
|
971
1041
|
parts.push(
|
|
972
1042
|
"If you discover a non-obvious rule or pattern, append one strict-schema JSON line to .cclaw/knowledge.jsonl using type: rule, pattern, lesson, or compound."
|