cclaw-cli 0.7.1 → 0.9.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/dist/content/agents.d.ts +9 -0
- package/dist/content/agents.js +177 -6
- package/dist/content/examples.d.ts +17 -0
- package/dist/content/examples.js +275 -4
- package/dist/content/harness-tool-refs.d.ts +20 -0
- package/dist/content/harness-tool-refs.js +240 -0
- package/dist/content/meta-skill.js +203 -33
- package/dist/content/skills.js +106 -49
- package/dist/content/stage-schema.js +63 -11
- package/dist/content/start-command.js +63 -17
- package/dist/content/subagents.js +169 -0
- package/dist/content/templates.js +44 -6
- package/dist/content/utility-skills.d.ts +2 -1
- package/dist/content/utility-skills.js +141 -2
- package/dist/doctor.js +77 -0
- package/dist/harness-adapters.js +55 -16
- package/dist/install.js +19 -0
- package/package.json +1 -1
package/dist/content/agents.d.ts
CHANGED
|
@@ -33,6 +33,15 @@ export declare function agentMarkdown(agent: AgentDefinition): string;
|
|
|
33
33
|
* Markdown table mapping Cclaw stage entry points to specialist agents.
|
|
34
34
|
*/
|
|
35
35
|
export declare function agentRoutingTable(): string;
|
|
36
|
+
/**
|
|
37
|
+
* Cost tier routing: keep heavy reasoning on the \`deep\` tier (planner, a
|
|
38
|
+
* single post-review reconciliation), push read-only research and narrow
|
|
39
|
+
* machine-only checks to the \`fast\` tier, and default review to \`balanced\`.
|
|
40
|
+
* This table is emitted into AGENTS.md so harness users understand why
|
|
41
|
+
* certain specialists are automatically fan-out-able without blowing the
|
|
42
|
+
* context budget.
|
|
43
|
+
*/
|
|
44
|
+
export declare function agentCostTierTable(): string;
|
|
36
45
|
/**
|
|
37
46
|
* AGENTS.md-ready section describing Cclaw’s specialist delegation model.
|
|
38
47
|
*/
|
package/dist/content/agents.js
CHANGED
|
@@ -170,6 +170,157 @@ export const CCLAW_AGENTS = [
|
|
|
170
170
|
"**Scope control:** only update what needs updating — **do not rewrite** docs that remain correct.",
|
|
171
171
|
].join("\n"),
|
|
172
172
|
},
|
|
173
|
+
{
|
|
174
|
+
name: "repo-research-analyst",
|
|
175
|
+
description: "PROACTIVE at the start of brainstorm/scope/design: delegates deep codebase exploration — existing modules, ownership boundaries, duplication, and reuse candidates — so the primary agent can plan from a grounded map instead of guesses.",
|
|
176
|
+
tools: ["Read", "Grep", "Glob"],
|
|
177
|
+
model: "fast",
|
|
178
|
+
activation: "proactive",
|
|
179
|
+
relatedStages: ["brainstorm", "scope", "design"],
|
|
180
|
+
body: [
|
|
181
|
+
"You are a **repo research analyst**.",
|
|
182
|
+
"",
|
|
183
|
+
"Scan the codebase for existing modules, helpers, patterns, and ownership boundaries relevant to the current task. Deliver a grounded map the primary agent can plan against.",
|
|
184
|
+
"",
|
|
185
|
+
"**Process:**",
|
|
186
|
+
"",
|
|
187
|
+
"1. Identify the task domain keywords (nouns, verbs, known file/module names).",
|
|
188
|
+
"2. Glob for obvious homes (by convention: `src/**`, `packages/**`, `apps/**`, etc.).",
|
|
189
|
+
"3. Grep for existing implementations of the same capability.",
|
|
190
|
+
"4. Enumerate adjacent tests/fixtures that already cover the area.",
|
|
191
|
+
"5. Flag duplication, near-duplicates, and reuse candidates with file:line.",
|
|
192
|
+
"",
|
|
193
|
+
"**Output schema:**",
|
|
194
|
+
"",
|
|
195
|
+
"- `Relevant modules:` bulleted list with `path — 1-line purpose`.",
|
|
196
|
+
"- `Reuse candidates:` bulleted list with `file:line — why this could absorb the change`.",
|
|
197
|
+
"- `Ownership hints:` any CODEOWNERS / README / comment signals.",
|
|
198
|
+
"- `Gaps:` what does NOT yet exist that the task would need.",
|
|
199
|
+
"",
|
|
200
|
+
"**Role boundary:** read-only. Do NOT edit files. Cite `file:line` for every claim; never guess paths.",
|
|
201
|
+
].join("\n"),
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "learnings-researcher",
|
|
205
|
+
description: "PROACTIVE before every non-trivial stage: streams `.cclaw/knowledge.jsonl` and surfaces the entries (rules, patterns, lessons, compounds) most relevant to the current task before the primary agent commits to a direction.",
|
|
206
|
+
tools: ["Read", "Grep", "Glob"],
|
|
207
|
+
model: "fast",
|
|
208
|
+
activation: "proactive",
|
|
209
|
+
relatedStages: ["brainstorm", "scope", "design", "spec", "plan", "tdd", "review", "ship"],
|
|
210
|
+
body: [
|
|
211
|
+
"You are a **project learnings researcher**.",
|
|
212
|
+
"",
|
|
213
|
+
"Stream `.cclaw/knowledge.jsonl` and surface the entries most relevant to the current task. The goal is to prevent the primary agent from re-learning things the project already wrote down.",
|
|
214
|
+
"",
|
|
215
|
+
"**Process:**",
|
|
216
|
+
"",
|
|
217
|
+
"1. Parse `.cclaw/knowledge.jsonl` (one JSON object per line, strict schema).",
|
|
218
|
+
"2. Match entries by `domain`, `stage`, and substring overlap with the current task description.",
|
|
219
|
+
"3. Rank by `confidence` then recency (`created`).",
|
|
220
|
+
"4. Group by `type` (rule, pattern, lesson, compound).",
|
|
221
|
+
"5. Return the top 10 entries verbatim with a one-line reason each.",
|
|
222
|
+
"",
|
|
223
|
+
"**Output schema:**",
|
|
224
|
+
"",
|
|
225
|
+
"- `Matched rules:` list of `trigger → action (confidence)`.",
|
|
226
|
+
"- `Matched patterns:` list of `trigger → action (confidence)`.",
|
|
227
|
+
"- `Matched lessons:` list of `trigger → action (confidence)`.",
|
|
228
|
+
"- `Matched compounds:` list of `trigger → action (confidence)`.",
|
|
229
|
+
"- `No-match note:` if nothing relevant exists, say so explicitly.",
|
|
230
|
+
"",
|
|
231
|
+
"**Role boundary:** read-only. Never rewrite or delete entries — corrections are appended by the primary agent via `/cc-learn add`.",
|
|
232
|
+
].join("\n"),
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "framework-docs-researcher",
|
|
236
|
+
description: "PROACTIVE during design/spec/tdd for tasks that touch a specific framework, library, or SDK: fetches authoritative, version-aware documentation (via context7 when available) so implementation matches the live API, not training priors.",
|
|
237
|
+
tools: ["Read", "Grep", "Glob", "WebSearch", "WebFetch"],
|
|
238
|
+
model: "fast",
|
|
239
|
+
activation: "on-demand",
|
|
240
|
+
relatedStages: ["design", "spec", "tdd", "review"],
|
|
241
|
+
body: [
|
|
242
|
+
"You are a **framework documentation researcher**.",
|
|
243
|
+
"",
|
|
244
|
+
"Fetch authoritative, version-aware docs for any library/framework/SDK/CLI the current task depends on. The goal is to replace model priors with live API references.",
|
|
245
|
+
"",
|
|
246
|
+
"**Process:**",
|
|
247
|
+
"",
|
|
248
|
+
"1. Identify the exact library + version from the repo (package.json, pyproject, go.mod, etc.).",
|
|
249
|
+
"2. If context7 MCP is available, use it first — it returns docs keyed to the installed version.",
|
|
250
|
+
"3. Otherwise WebSearch / WebFetch for the official docs site or the tagged release changelog.",
|
|
251
|
+
"4. Capture: public API signatures, breaking changes since a major version back, migration notes, and any deprecated paths relevant to the task.",
|
|
252
|
+
"",
|
|
253
|
+
"**Output schema:**",
|
|
254
|
+
"",
|
|
255
|
+
"- `Library + version:` name and resolved version.",
|
|
256
|
+
"- `Key APIs:` bullet list of signatures the task will touch.",
|
|
257
|
+
"- `Breaking changes:` notable deltas relevant to the task.",
|
|
258
|
+
"- `Gotchas:` footguns, deprecated paths, version-gated flags.",
|
|
259
|
+
"- `Source:` URL(s) or MCP reference used.",
|
|
260
|
+
"",
|
|
261
|
+
"**Role boundary:** never invent APIs. If docs are unclear, say `UNKNOWN` and surface the gap instead of guessing.",
|
|
262
|
+
].join("\n"),
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
name: "best-practices-researcher",
|
|
266
|
+
description: "PROACTIVE during design/spec when the task touches a well-known domain (auth, caching, rate limiting, observability, accessibility, etc.): delivers a short, opinionated best-practice summary grounded in citable sources.",
|
|
267
|
+
tools: ["Read", "Grep", "Glob", "WebSearch", "WebFetch"],
|
|
268
|
+
model: "fast",
|
|
269
|
+
activation: "on-demand",
|
|
270
|
+
relatedStages: ["brainstorm", "scope", "design", "spec", "review"],
|
|
271
|
+
body: [
|
|
272
|
+
"You are a **best-practices researcher**.",
|
|
273
|
+
"",
|
|
274
|
+
"For a named domain (auth, caching, rate limiting, observability, accessibility, etc.), deliver a short, opinionated best-practice summary that is citable and current.",
|
|
275
|
+
"",
|
|
276
|
+
"**Process:**",
|
|
277
|
+
"",
|
|
278
|
+
"1. Restate the domain + narrow it to the sub-problem the task is solving.",
|
|
279
|
+
"2. Gather 3–5 authoritative sources (official docs, IETF / W3C / OWASP references, well-known community standards).",
|
|
280
|
+
"3. Surface the 5–8 practices most relevant to the task, each with one-line rationale + source.",
|
|
281
|
+
"4. Flag practices that look common but are anti-patterns today.",
|
|
282
|
+
"",
|
|
283
|
+
"**Output schema:**",
|
|
284
|
+
"",
|
|
285
|
+
"- `Domain + sub-problem:` one sentence.",
|
|
286
|
+
"- `Recommended practices:` list of `practice — rationale — source`.",
|
|
287
|
+
"- `Common traps:` list of `trap — why it fails — source`.",
|
|
288
|
+
"- `Decision hooks:` 1–3 explicit questions the primary agent must answer before moving on.",
|
|
289
|
+
"",
|
|
290
|
+
"**Role boundary:** never prescribe a choice without citing a source. If the domain has no authoritative answer, say so.",
|
|
291
|
+
].join("\n"),
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: "git-history-analyzer",
|
|
295
|
+
description: "PROACTIVE when a task touches an existing module: reads git log/blame/diff to surface prior changes, failed attempts, revert patterns, and code owners that bias the current plan.",
|
|
296
|
+
tools: ["Read", "Grep", "Glob", "Bash"],
|
|
297
|
+
model: "fast",
|
|
298
|
+
activation: "on-demand",
|
|
299
|
+
relatedStages: ["scope", "design", "plan", "review"],
|
|
300
|
+
body: [
|
|
301
|
+
"You are a **git history analyzer**.",
|
|
302
|
+
"",
|
|
303
|
+
"Read commit history, blame, and recent diffs for files the current task touches. The goal is to expose prior context (attempts, reverts, owners, flaky surfaces) the primary agent would otherwise miss.",
|
|
304
|
+
"",
|
|
305
|
+
"**Process:**",
|
|
306
|
+
"",
|
|
307
|
+
"1. For each impacted path: `git log --follow -n 20 -- <path>` and note the themes.",
|
|
308
|
+
"2. `git blame` the hot lines to surface current owners.",
|
|
309
|
+
"3. Look for `Revert ...`, `Reopen ...`, or repeated regressions in the last 90 days.",
|
|
310
|
+
"4. Check CODEOWNERS / committer frequency for ownership signal.",
|
|
311
|
+
"5. Flag any recent refactors or migrations in-flight that this task might collide with.",
|
|
312
|
+
"",
|
|
313
|
+
"**Output schema:**",
|
|
314
|
+
"",
|
|
315
|
+
"- `Impacted paths:` list.",
|
|
316
|
+
"- `Recent themes:` 3–5 bullets summarizing what changed lately in those paths.",
|
|
317
|
+
"- `Revert/regression signals:` list with commit SHAs.",
|
|
318
|
+
"- `Owners:` best-guess owners with supporting evidence.",
|
|
319
|
+
"- `Collision risks:` in-flight branches/migrations that overlap.",
|
|
320
|
+
"",
|
|
321
|
+
"**Role boundary:** read-only; never amend history, never `git push`. Use `git` commands only.",
|
|
322
|
+
].join("\n"),
|
|
323
|
+
},
|
|
173
324
|
];
|
|
174
325
|
import { enhancedAgentBody } from "./subagents.js";
|
|
175
326
|
/**
|
|
@@ -213,13 +364,29 @@ ${taskDelegation}
|
|
|
213
364
|
export function agentRoutingTable() {
|
|
214
365
|
return `| Stage Entry | Primary Agent | Supporting Agents |
|
|
215
366
|
|---|---|---|
|
|
216
|
-
| Brainstorm (start with \`/cc <idea>\`) | planner |
|
|
217
|
-
| Scope / Design / Spec / Plan (advance via \`/cc-next\`) | planner | security-reviewer on design, spec-reviewer on spec |
|
|
218
|
-
| TDD (via \`/cc-next\`) | test-author | doc-updater |
|
|
219
|
-
| Review (via \`/cc-next\`) | spec-reviewer, code-reviewer, security-reviewer |
|
|
367
|
+
| Brainstorm (start with \`/cc <idea>\`) | planner | repo-research-analyst, learnings-researcher, best-practices-researcher |
|
|
368
|
+
| Scope / Design / Spec / Plan (advance via \`/cc-next\`) | planner | security-reviewer on design, spec-reviewer on spec, framework-docs-researcher + git-history-analyzer on design/plan |
|
|
369
|
+
| TDD (via \`/cc-next\`) | test-author | doc-updater, framework-docs-researcher |
|
|
370
|
+
| Review (via \`/cc-next\`) | spec-reviewer, code-reviewer, security-reviewer | best-practices-researcher, git-history-analyzer |
|
|
220
371
|
| Ship (via \`/cc-next\`) | — | doc-updater |
|
|
221
372
|
`;
|
|
222
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Cost tier routing: keep heavy reasoning on the \`deep\` tier (planner, a
|
|
376
|
+
* single post-review reconciliation), push read-only research and narrow
|
|
377
|
+
* machine-only checks to the \`fast\` tier, and default review to \`balanced\`.
|
|
378
|
+
* This table is emitted into AGENTS.md so harness users understand why
|
|
379
|
+
* certain specialists are automatically fan-out-able without blowing the
|
|
380
|
+
* context budget.
|
|
381
|
+
*/
|
|
382
|
+
export function agentCostTierTable() {
|
|
383
|
+
return `| Tier | Use for | Example agents |
|
|
384
|
+
|---|---|---|
|
|
385
|
+
| \`deep\` | one heavy plan or one final reconciliation per stage | planner |
|
|
386
|
+
| \`balanced\` | spec compliance and code/security review with enough context | spec-reviewer, code-reviewer, security-reviewer, test-author |
|
|
387
|
+
| \`fast\` | read-only research / narrow machine checks / docs updates; safe to fan out 3-5× in parallel | repo-research-analyst, learnings-researcher, framework-docs-researcher, best-practices-researcher, git-history-analyzer, doc-updater |
|
|
388
|
+
`;
|
|
389
|
+
}
|
|
223
390
|
/**
|
|
224
391
|
* AGENTS.md-ready section describing Cclaw’s specialist delegation model.
|
|
225
392
|
*/
|
|
@@ -232,8 +399,12 @@ ${agentRoutingTable()}
|
|
|
232
399
|
|
|
233
400
|
**Activation modes:**
|
|
234
401
|
- **Mandatory:** MUST be used when the related stage runs (spec-reviewer, code-reviewer, and security-reviewer during review; planner during scope and design; test-author during tdd; doc-updater during ship). Even if a change has no trust-boundary impact, security-reviewer produces an explicit no-change attestation.
|
|
235
|
-
- **Proactive:** Should be used automatically when context matches (planner for complex features, security-reviewer escalations outside review, doc-updater on behavior changes)
|
|
236
|
-
- **On-demand:** Invoked only when explicitly requested
|
|
402
|
+
- **Proactive:** Should be used automatically when context matches (planner for complex features, repo-research-analyst / learnings-researcher at the start of brainstorm/scope/design, security-reviewer escalations outside review, doc-updater on behavior changes).
|
|
403
|
+
- **On-demand:** Invoked only when explicitly requested, but strongly suggested in the matching contexts (framework-docs-researcher when the task touches a specific library/SDK, best-practices-researcher when the task touches a well-known domain, git-history-analyzer when the task touches existing code).
|
|
404
|
+
|
|
405
|
+
### Cost-aware routing
|
|
406
|
+
|
|
407
|
+
${agentCostTierTable()}
|
|
237
408
|
|
|
238
409
|
**Agent files:** \`.cclaw/agents/{name}.md\` — each contains YAML frontmatter with tools and model tier.
|
|
239
410
|
`;
|
|
@@ -1,2 +1,19 @@
|
|
|
1
1
|
import type { FlowStage } from "../types.js";
|
|
2
|
+
export declare function stageGoodBadExamples(stage: FlowStage): string;
|
|
3
|
+
export declare const STAGE_EXAMPLES_REFERENCE_DIR = "references/stages";
|
|
4
|
+
export declare function stageExamplesReferencePath(stage: FlowStage): string;
|
|
5
|
+
/**
|
|
6
|
+
* Returns the full example artifact body as a standalone reference markdown
|
|
7
|
+
* file. Materialized under .cclaw/references/stages/<stage>-examples.md so
|
|
8
|
+
* the always-rendered skill body can link instead of inlining.
|
|
9
|
+
*/
|
|
10
|
+
export declare function stageExamplesReferenceMarkdown(stage: FlowStage): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Returns the short inline pointer rendered directly inside the stage skill.
|
|
13
|
+
* Replaces the previous always-inline ~50-100 line fenced block and
|
|
14
|
+
* delivers true progressive disclosure: the full example lives in a
|
|
15
|
+
* reference file loaded on demand.
|
|
16
|
+
*/
|
|
2
17
|
export declare function stageExamples(stage: FlowStage): string;
|
|
18
|
+
export type ExampleDomain = "web" | "cli" | "library" | "data-pipeline";
|
|
19
|
+
export declare function stageDomainExamples(stage: FlowStage): string;
|
package/dist/content/examples.js
CHANGED
|
@@ -432,14 +432,92 @@ Execution rule: complete and verify each wave before starting the next wave.
|
|
|
432
432
|
- Execution result: PR #42 created via \`gh pr create\`; CI passed; squash-merged to main.
|
|
433
433
|
- PR URL: https://github.com/example/repo/pull/42`,
|
|
434
434
|
};
|
|
435
|
-
|
|
435
|
+
const GOOD_BAD_EXAMPLES = {
|
|
436
|
+
brainstorm: {
|
|
437
|
+
good: "Problem: release checks are fragile and inconsistent between CI and local runs; invalid metadata sometimes reaches npm publish. Success: invalid release preconditions are caught before publish with explicit operator feedback, in both CI and local workflows. Constraints: no new runtime dependencies.",
|
|
438
|
+
bad: "Problem: releases are broken. Success: make them better. Constraints: be careful.",
|
|
439
|
+
lesson: "\"Make it better\" is not a success criterion — an agent cannot know when it is done. State the observable condition that proves success."
|
|
440
|
+
},
|
|
441
|
+
scope: {
|
|
442
|
+
good: "In scope: in-app notification feed, SSE delivery path, read/unread state, retry on transient failures. Out of scope: email/SMS/push providers, per-user preferences. Deferred: WebSocket channel, rich media, full-text search.",
|
|
443
|
+
bad: "In scope: notifications. Out of scope: stuff we are not doing. Deferred: v2.",
|
|
444
|
+
lesson: "Vague boundaries get relitigated in every subsequent stage. Enumerate concrete capabilities on each side — \"stuff we are not doing\" is not a decision."
|
|
445
|
+
},
|
|
446
|
+
design: {
|
|
447
|
+
good: "Failure: SSE connection drop. Trigger: network interruption. Detection: client heartbeat timeout (30s). Mitigation: auto-reconnect with exponential backoff + REST snapshot fallback. User impact: ≤10s delay, no data loss.",
|
|
448
|
+
bad: "Failure: network errors. Mitigation: retry and log. User impact: users may see issues sometimes.",
|
|
449
|
+
lesson: "A failure row without a detection signal and a bounded user impact is aspirational, not a design. Name the trigger, the detector, and the recovery behavior."
|
|
450
|
+
},
|
|
451
|
+
spec: {
|
|
452
|
+
good: "AC-1: Given a signed-in user with an active session, when the server publishes a new notification event for that user, the client feed shows the new item within 5 seconds without a full page reload.",
|
|
453
|
+
bad: "AC-1: Users should see their notifications quickly and reliably, with a good user experience.",
|
|
454
|
+
lesson: "Spec criteria must be observable, measurable, and falsifiable. \"Quickly\" is a feeling; \"within 5 seconds without a full page reload\" is a test."
|
|
455
|
+
},
|
|
456
|
+
plan: {
|
|
457
|
+
good: "T-2: Implement publisher + outbox write path. Acceptance: AC-1. Verification: `pnpm vitest run tests/integration/publisher.test.ts`. Depends on: T-1. Effort: M.",
|
|
458
|
+
bad: "T-2: Build the backend. Verify: manual testing. Effort: a few days.",
|
|
459
|
+
lesson: "A task without a single acceptance criterion and a reproducible verification command is a wish. If you cannot say how you will know it is done, you cannot ship it."
|
|
460
|
+
},
|
|
461
|
+
tdd: {
|
|
462
|
+
good: "RED: `pnpm vitest run tests/unit/dedupe-feed.test.ts` → `publishToOutbox is not a function`. GREEN (after minimal impl): same command, 47/47 pass, full suite. REFACTOR: extracted `mergeLatestByDedupeKey`; suite still 47/47.",
|
|
463
|
+
bad: "Wrote the publisher code. Tests pass now. Will add unit tests later when I have time.",
|
|
464
|
+
lesson: "Code written before a failing test is guessing validated after the fact. The RED failure IS the specification — without it, the GREEN pass proves nothing about the intended behavior."
|
|
465
|
+
},
|
|
466
|
+
review: {
|
|
467
|
+
good: "R-1 Critical: snapshot endpoint returns newest N rows but does not guarantee consistency with stream cursor — users can miss items between snapshot and subscribe. Evidence: integration test `notification-consistency.test.ts:22-58`. Status: open.",
|
|
468
|
+
bad: "Looks good overall. A few small things could be polished, maybe refactor the merge logic. LGTM.",
|
|
469
|
+
lesson: "\"LGTM\" is not a review — it is a signature on whatever the author shipped. Every finding needs a severity, a falsifiable description, evidence, and a status."
|
|
470
|
+
},
|
|
471
|
+
ship: {
|
|
472
|
+
good: "Rollback trigger: error rate on `/notifications/stream` >5% for 5 minutes, or p95 publish-to-visible lag >10s. Steps: `git revert <merge-sha> && git push origin main` then redeploy; run `2026_04_12_notifications_cursor_down.sql` before traffic. Verification: error rate returns to baseline within 10 minutes.",
|
|
473
|
+
bad: "Rollback plan: revert the commit if anything goes wrong.",
|
|
474
|
+
lesson: "\"Revert if anything goes wrong\" leaves the on-call engineer to invent the plan at 2 a.m. The rollback trigger is an operational contract: state the signal, the command, and the verification."
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
export function stageGoodBadExamples(stage) {
|
|
478
|
+
const sample = GOOD_BAD_EXAMPLES[stage];
|
|
479
|
+
if (!sample)
|
|
480
|
+
return "";
|
|
481
|
+
return [
|
|
482
|
+
"## Good vs Bad (at-a-glance)",
|
|
483
|
+
"",
|
|
484
|
+
"Contrasting samples to calibrate the quality bar for this stage. Read before writing the artifact — mirror the **Good** shape, avoid the **Bad** shape.",
|
|
485
|
+
"",
|
|
486
|
+
"**Good**",
|
|
487
|
+
"",
|
|
488
|
+
"> " + sample.good,
|
|
489
|
+
"",
|
|
490
|
+
"**Bad**",
|
|
491
|
+
"",
|
|
492
|
+
"> " + sample.bad,
|
|
493
|
+
"",
|
|
494
|
+
"**Why it matters:** " + sample.lesson,
|
|
495
|
+
""
|
|
496
|
+
].join("\n");
|
|
497
|
+
}
|
|
498
|
+
export const STAGE_EXAMPLES_REFERENCE_DIR = "references/stages";
|
|
499
|
+
export function stageExamplesReferencePath(stage) {
|
|
500
|
+
return `.cclaw/${STAGE_EXAMPLES_REFERENCE_DIR}/${stage}-examples.md`;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Returns the full example artifact body as a standalone reference markdown
|
|
504
|
+
* file. Materialized under .cclaw/references/stages/<stage>-examples.md so
|
|
505
|
+
* the always-rendered skill body can link instead of inlining.
|
|
506
|
+
*/
|
|
507
|
+
export function stageExamplesReferenceMarkdown(stage) {
|
|
436
508
|
const examples = STAGE_EXAMPLES[stage];
|
|
437
509
|
if (!examples)
|
|
438
|
-
return
|
|
510
|
+
return null;
|
|
439
511
|
return [
|
|
440
|
-
|
|
512
|
+
`---`,
|
|
513
|
+
`stage: ${stage}`,
|
|
514
|
+
`name: ${stage}-stage-examples`,
|
|
515
|
+
`description: "Full sample artifact for the ${stage} stage. Loaded only when an agent explicitly needs a complete example; the stage skill links here rather than inlining."`,
|
|
516
|
+
`---`,
|
|
441
517
|
"",
|
|
442
|
-
|
|
518
|
+
`# ${stage} stage — full artifact sample`,
|
|
519
|
+
"",
|
|
520
|
+
`This file is linked from \`.cclaw/skills/<${stage}-stage>/SKILL.md\` under **Examples → See also**. The sample uses H2 headings that mirror the artifact a cclaw session must produce, so the markdown is wrapped in a fence to avoid collapsing into the outline.`,
|
|
443
521
|
"",
|
|
444
522
|
"```markdown",
|
|
445
523
|
examples,
|
|
@@ -447,3 +525,196 @@ export function stageExamples(stage) {
|
|
|
447
525
|
""
|
|
448
526
|
].join("\n");
|
|
449
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* Returns the short inline pointer rendered directly inside the stage skill.
|
|
530
|
+
* Replaces the previous always-inline ~50-100 line fenced block and
|
|
531
|
+
* delivers true progressive disclosure: the full example lives in a
|
|
532
|
+
* reference file loaded on demand.
|
|
533
|
+
*/
|
|
534
|
+
export function stageExamples(stage) {
|
|
535
|
+
const examples = STAGE_EXAMPLES[stage];
|
|
536
|
+
if (!examples)
|
|
537
|
+
return "";
|
|
538
|
+
return [
|
|
539
|
+
"## Examples",
|
|
540
|
+
"",
|
|
541
|
+
`Full artifact sample for this stage lives at \`${stageExamplesReferencePath(stage)}\`. Open it when you need a complete reference; do NOT paste the example into the artifact verbatim — it is a shape guide, not a template.`,
|
|
542
|
+
"",
|
|
543
|
+
"Summary of what the reference covers:",
|
|
544
|
+
...exampleSummaryBullets(stage),
|
|
545
|
+
""
|
|
546
|
+
].join("\n");
|
|
547
|
+
}
|
|
548
|
+
function exampleSummaryBullets(stage) {
|
|
549
|
+
const headings = STAGE_EXAMPLE_SECTION_HEADINGS[stage] ?? [];
|
|
550
|
+
if (headings.length === 0)
|
|
551
|
+
return ["- Full artifact structure."];
|
|
552
|
+
return headings.map((heading) => `- ${heading}`);
|
|
553
|
+
}
|
|
554
|
+
// Kept in sync with STAGE_EXAMPLES above so the inline summary matches the
|
|
555
|
+
// reference file without duplicating the heavy text. Update whenever the
|
|
556
|
+
// sample in STAGE_EXAMPLES gains or loses a top-level section.
|
|
557
|
+
const STAGE_EXAMPLE_SECTION_HEADINGS = {
|
|
558
|
+
brainstorm: [
|
|
559
|
+
"Problem framing (problem, success, constraints)",
|
|
560
|
+
"Candidate approaches with trade-offs",
|
|
561
|
+
"Recommended direction + open questions",
|
|
562
|
+
"Clarification log and decision record"
|
|
563
|
+
],
|
|
564
|
+
scope: [
|
|
565
|
+
"In-scope / out-of-scope / deferred lists with concrete capabilities",
|
|
566
|
+
"Requirements table with stable R# IDs",
|
|
567
|
+
"Boundary stress-tests and non-negotiables",
|
|
568
|
+
"Decision record for premise challenges"
|
|
569
|
+
],
|
|
570
|
+
design: [
|
|
571
|
+
"Blast-radius file list",
|
|
572
|
+
"Mandatory architecture diagram (Mermaid)",
|
|
573
|
+
"Failure-mode table with detection + mitigation",
|
|
574
|
+
"Test strategy + performance budget",
|
|
575
|
+
"Completion dashboard + unresolved decisions"
|
|
576
|
+
],
|
|
577
|
+
spec: [
|
|
578
|
+
"Acceptance-criteria table (observable, measurable, falsifiable)",
|
|
579
|
+
"Requirement-ref column tying each AC back to an R# from scope",
|
|
580
|
+
"Verification-approach column",
|
|
581
|
+
"Approval block"
|
|
582
|
+
],
|
|
583
|
+
plan: [
|
|
584
|
+
"Dependency graph + dependency waves",
|
|
585
|
+
"Task list with effort + minutes estimate per task",
|
|
586
|
+
"Acceptance mapping (every AC → task IDs)",
|
|
587
|
+
"No-Placeholder scan row + WAIT_FOR_CONFIRM marker"
|
|
588
|
+
],
|
|
589
|
+
tdd: [
|
|
590
|
+
"RED evidence per slice (failing test output)",
|
|
591
|
+
"Acceptance mapping per slice",
|
|
592
|
+
"GREEN evidence (full-suite pass)",
|
|
593
|
+
"REFACTOR notes with behavior-preservation confirmation",
|
|
594
|
+
"Test-pyramid shape + prove-it reproduction when applicable"
|
|
595
|
+
],
|
|
596
|
+
review: [
|
|
597
|
+
"Spec-compliance findings (Layer 1)",
|
|
598
|
+
"Code-quality findings (Layer 2)",
|
|
599
|
+
"Severity, evidence, and status per finding",
|
|
600
|
+
"Go / no-go verdict"
|
|
601
|
+
],
|
|
602
|
+
ship: [
|
|
603
|
+
"Release checklist (version, changelog, tag, artifacts)",
|
|
604
|
+
"Rollback plan with trigger, steps, verification",
|
|
605
|
+
"Runbook (how to verify the release post-deploy)",
|
|
606
|
+
"Sign-off block"
|
|
607
|
+
]
|
|
608
|
+
};
|
|
609
|
+
const DOMAIN_LABELS = {
|
|
610
|
+
web: "Web app (full-stack)",
|
|
611
|
+
cli: "CLI tool",
|
|
612
|
+
library: "Library / SDK",
|
|
613
|
+
"data-pipeline": "Data pipeline / ETL"
|
|
614
|
+
};
|
|
615
|
+
const STAGE_DOMAIN_SAMPLES = {
|
|
616
|
+
spec: [
|
|
617
|
+
{
|
|
618
|
+
domain: "web",
|
|
619
|
+
label: "AC",
|
|
620
|
+
body: "AC-W1: Given a signed-in admin viewing `/dashboard/orders`, when an order's status changes server-side, the row updates within 2s without a full navigation (assert via `pnpm playwright test orders-live.spec.ts`)."
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
domain: "cli",
|
|
624
|
+
label: "AC",
|
|
625
|
+
body: "AC-C1: Given `cclaw init --claude` run in an empty directory, exit code is `0`, `.cclaw/config.yaml` is created with `harnesses: [claude]`, and stderr contains no warnings (asserted by `tests/integration/init-sync-doctor.test.ts`)."
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
domain: "library",
|
|
629
|
+
label: "AC",
|
|
630
|
+
body: "AC-L1: `validateHookDocument(obj)` returns `{ ok: true }` for every fixture under `tests/fixtures/valid-hooks/` and `{ ok: false, errors: [...] }` with at least one message for every fixture under `tests/fixtures/invalid-hooks/`."
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
domain: "data-pipeline",
|
|
634
|
+
label: "AC",
|
|
635
|
+
body: "AC-D1: For any `orders.csv` input, the pipeline emits exactly one row per `(order_id, event_ts)` pair to `warehouse.fact_orders`; running the job twice on the same input is idempotent (row count unchanged, verified by `dbt test --select fact_orders`)."
|
|
636
|
+
}
|
|
637
|
+
],
|
|
638
|
+
plan: [
|
|
639
|
+
{
|
|
640
|
+
domain: "web",
|
|
641
|
+
label: "Task",
|
|
642
|
+
body: "T-W-3 `[~4m]`: Wire SSE endpoint `/api/orders/stream` into `useOrderFeed` hook. AC-W1. Verify: `pnpm playwright test orders-live.spec.ts`. Depends on: T-W-2."
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
domain: "cli",
|
|
646
|
+
label: "Task",
|
|
647
|
+
body: "T-C-2 `[~3m]`: Add `--dry-run` flag to `cclaw archive` that prints the would-be-archived run IDs to stdout and exits 0. AC-C3. Verify: `node dist/cli.js archive --dry-run` + `tests/unit/cli-parse.test.ts`."
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
domain: "library",
|
|
651
|
+
label: "Task",
|
|
652
|
+
body: "T-L-1 `[~5m]`: Expose `validateHookDocument` from the package root and re-export its types. AC-L1. Verify: `pnpm build && node -e \"console.log(require('./dist').validateHookDocument)\"`."
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
domain: "data-pipeline",
|
|
656
|
+
label: "Task",
|
|
657
|
+
body: "T-D-2 `[~5m]`: Add dedup step keyed on `(order_id, event_ts)` between `raw.orders` and `fact_orders`. AC-D1. Verify: `dbt run --select fact_orders+ && dbt test --select fact_orders`."
|
|
658
|
+
}
|
|
659
|
+
],
|
|
660
|
+
tdd: [
|
|
661
|
+
{
|
|
662
|
+
domain: "web",
|
|
663
|
+
label: "RED→GREEN→REFACTOR",
|
|
664
|
+
body: "RED: `pnpm playwright test orders-live.spec.ts` → timeout waiting for row update. GREEN: wired SSE event → row rerenders via `useOrderFeed`. REFACTOR: extracted `applyOrderEvent(row, event)` pure helper; 87/87 tests still pass."
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
domain: "cli",
|
|
668
|
+
label: "RED→GREEN→REFACTOR",
|
|
669
|
+
body: "RED: `tests/unit/cli-parse.test.ts` expects `--dry-run` flag → `unknown option` error. GREEN: added to the Zod parser; 19/19 pass. REFACTOR: hoisted the dry-run formatter into `src/cli/format.ts` shared with `status`."
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
domain: "library",
|
|
673
|
+
label: "RED→GREEN→REFACTOR",
|
|
674
|
+
body: "RED: `tests/unit/hook-schema.test.ts` imports `validateHookDocument` from package root → `export not found`. GREEN: added re-export + types. REFACTOR: renamed internal `__validate` to `validateHookDocument` so the export name matches the source."
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
domain: "data-pipeline",
|
|
678
|
+
label: "RED→GREEN→REFACTOR",
|
|
679
|
+
body: "RED: `dbt test --select fact_orders` → `unique test on (order_id, event_ts)` fails on re-run. GREEN: added `row_number()` dedup in the staging model. REFACTOR: extracted the dedup CTE into `int_orders_deduped` for reuse by `fact_returns`."
|
|
680
|
+
}
|
|
681
|
+
],
|
|
682
|
+
ship: [
|
|
683
|
+
{
|
|
684
|
+
domain: "web",
|
|
685
|
+
label: "Rollback",
|
|
686
|
+
body: "Trigger: error rate on `/api/orders/stream` > 2% for 5 minutes, or p95 latency > 1.5s for 10 minutes. Steps: `vercel rollback <deployment>`; run `2026_04_14_revert_orders_stream.sql` before traffic returns. Verify: error rate returns to baseline within 10 minutes on the `orders-live` dashboard."
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
domain: "cli",
|
|
690
|
+
label: "Rollback",
|
|
691
|
+
body: "Trigger: `cclaw init --claude` exits non-zero on a fresh tmp dir, OR `cclaw doctor` regresses (FAIL count increases) on the smoke matrix. Steps: `npm unpublish cclaw-cli@<version>` (within the 72h window) or `npm deprecate cclaw-cli@<version> '<reason>'`; publish the previous patch. Verify: `npx cclaw-cli@latest --version` prints the previous version."
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
domain: "library",
|
|
695
|
+
label: "Rollback",
|
|
696
|
+
body: "Trigger: any consumer reports `validateHookDocument` no longer exported, OR the CI `dual-package-check` job fails. Steps: `npm deprecate cclaw-cli@<version> 'broken package export — use <prev>'`; publish the previous minor with a patch bump; emit changelog `## Rollback` entry. Verify: a smoke consumer project `pnpm add cclaw-cli@latest` imports cleanly."
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
domain: "data-pipeline",
|
|
700
|
+
label: "Rollback",
|
|
701
|
+
body: "Trigger: `dbt test --select fact_orders` fails on production run, OR downstream dashboard MAU count drops >10% week-over-week. Steps: disable the new model via `dbt_project.yml` + `dbt run --select state:modified` with the previous git SHA; rerun backfill `dagster asset materialize fact_orders --partition <yesterday>`. Verify: `fact_orders` row count within ±1% of the previous week's baseline."
|
|
702
|
+
}
|
|
703
|
+
]
|
|
704
|
+
};
|
|
705
|
+
export function stageDomainExamples(stage) {
|
|
706
|
+
const samples = STAGE_DOMAIN_SAMPLES[stage];
|
|
707
|
+
if (!samples || samples.length === 0)
|
|
708
|
+
return "";
|
|
709
|
+
const lines = [
|
|
710
|
+
"## Living Examples by Domain",
|
|
711
|
+
"",
|
|
712
|
+
"Use the row matching your project shape to calibrate voice, specificity, and command choice. The rows are deliberately terse — copy the **shape**, not the text.",
|
|
713
|
+
""
|
|
714
|
+
];
|
|
715
|
+
for (const sample of samples) {
|
|
716
|
+
lines.push(`**${DOMAIN_LABELS[sample.domain]} — ${sample.label}:** ${sample.body}`);
|
|
717
|
+
lines.push("");
|
|
718
|
+
}
|
|
719
|
+
return lines.join("\n");
|
|
720
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-harness tool-mapping reference files.
|
|
3
|
+
*
|
|
4
|
+
* Addresses A.1#4: the four supported harnesses (claude, cursor, opencode, codex)
|
|
5
|
+
* expose different primitive names for the same capabilities (ask-user,
|
|
6
|
+
* delegate/Task, web fetch, file edit, code execution, ...). cclaw's stage skills
|
|
7
|
+
* need to pick the right name at runtime without bloating every stage with per-harness
|
|
8
|
+
* if/else ladders.
|
|
9
|
+
*
|
|
10
|
+
* Each file below is short (one table per capability), authoritative, and materialised
|
|
11
|
+
* at `.cclaw/references/harness-tools/<harness>.md`. Stage skills and the meta-skill
|
|
12
|
+
* cite the folder instead of duplicating the mappings inline.
|
|
13
|
+
*
|
|
14
|
+
* When a new harness is added (or an existing one renames a tool), update the
|
|
15
|
+
* corresponding entry here — do NOT scatter tool names across skill text.
|
|
16
|
+
*/
|
|
17
|
+
import type { HarnessId } from "../types.js";
|
|
18
|
+
export declare const HARNESS_TOOL_REFS_DIR = "references/harness-tools";
|
|
19
|
+
export declare function harnessToolRefMarkdown(harness: HarnessId): string;
|
|
20
|
+
export declare const HARNESS_TOOL_REFS_INDEX_MD = "---\nname: Harness tool maps\ndescription: \"Index file. One reference per supported harness \u2014 cite the per-harness file instead of hardcoding tool names in stage skills.\"\n---\n\n# Harness Tool Maps\n\ncclaw supports four harnesses; each exposes different primitive names for the same capabilities. Stage skills and utility skills cite the file matching the currently active harness and fall back to plain-text equivalents for capabilities that the harness lacks.\n\n| Harness | File | Notes |\n|---|---|---|\n| Claude Code | `.cclaw/references/harness-tools/claude.md` | Richest tool surface (AskUserQuestion, Task, WebFetch, WebSearch, MCP, \u2026). |\n| Cursor | `.cclaw/references/harness-tools/cursor.md` | Near-parity with Claude; uses `AskQuestion` instead of `AskUserQuestion`. |\n| OpenCode | `.cclaw/references/harness-tools/opencode.md` | No native ask-user / dispatch; more plain-text fallbacks. |\n| Codex | `.cclaw/references/harness-tools/codex.md` | No native ask-user / dispatch; shell + file I/O only by default. |\n\nWhen a new harness is added or an existing one renames a tool, update the corresponding file (and this index) \u2014 do NOT scatter tool names across skill text.\n";
|