cclaw-cli 0.29.0 → 0.31.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 +130 -253
- package/dist/cli.d.ts +2 -4
- package/dist/cli.js +48 -133
- package/dist/config.d.ts +1 -11
- package/dist/config.js +0 -40
- package/dist/doctor.js +0 -2
- package/dist/harness-adapters.js +19 -7
- package/dist/install.d.ts +3 -5
- package/dist/install.js +4 -9
- package/dist/types.d.ts +0 -12
- package/dist/types.js +0 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# cclaw
|
|
2
2
|
|
|
3
|
-
**Install once, ship every time.** cclaw is an installer-first workflow
|
|
4
|
-
that gives your AI coding agent one inspectable path from idea to
|
|
3
|
+
**Install once, ship every time.** cclaw is an installer-first workflow
|
|
4
|
+
runtime that gives your AI coding agent one inspectable path from idea to
|
|
5
|
+
shipped PR:
|
|
5
6
|
|
|
6
7
|
> **brainstorm → scope → design → spec → plan → tdd → review → ship**
|
|
7
8
|
|
|
@@ -9,9 +10,9 @@ Every stage has real gates the agent cannot skip, every decision leaves a
|
|
|
9
10
|
file-backed audit trail, and the same six slash commands work across
|
|
10
11
|
Claude Code, Cursor, OpenCode, and OpenAI Codex.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
You install cclaw **once** from the terminal, then everything happens
|
|
14
|
+
inside your harness — no hidden control plane, no background daemon, no
|
|
15
|
+
operational knobs to memorise.
|
|
15
16
|
|
|
16
17
|
---
|
|
17
18
|
|
|
@@ -25,74 +26,66 @@ diff, and reason about.
|
|
|
25
26
|
- Maintainers of AI agents/skills who want **measurable prompt engineering**
|
|
26
27
|
via the built-in eval harness.
|
|
27
28
|
|
|
28
|
-
If you are looking for a virtual engineering org with 20+ role-play
|
|
29
|
-
commands, or for a plugin marketplace ecosystem, see the
|
|
30
|
-
[Compared to references](#compared-to-references) section — other tools do
|
|
31
|
-
that well. cclaw trades breadth for a single, inspectable pipeline.
|
|
32
|
-
|
|
33
29
|
---
|
|
34
30
|
|
|
35
31
|
## How it works
|
|
36
32
|
|
|
37
|
-
```mermaid
|
|
38
|
-
flowchart LR
|
|
39
|
-
A[Idea] --> B[Brainstorm]
|
|
40
|
-
B --> C[Scope]
|
|
41
|
-
C --> D[Design]
|
|
42
|
-
D --> E[Spec]
|
|
43
|
-
E --> F[Plan]
|
|
44
|
-
F --> G[TDD]
|
|
45
|
-
G --> H[Review]
|
|
46
|
-
H --> I[Ship]
|
|
47
33
|
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
S-->>U: Next stage is explicit
|
|
34
|
+
┌─────────┐ ┌──────┐ ┌────────┐ ┌──────┐ ┌──────┐
|
|
35
|
+
│ Idea │ → │ /cc │ → │Classify│ → │Track │ → │Stages│
|
|
36
|
+
└─────────┘ └──────┘ └────────┘ └──────┘ └──┬───┘
|
|
37
|
+
│
|
|
38
|
+
┌───────────────────────────────────────────────┘
|
|
39
|
+
▼
|
|
40
|
+
brainstorm → scope → design → spec → plan → tdd → review → ship
|
|
41
|
+
│ │ │ │ │ │ │ │
|
|
42
|
+
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
|
|
43
|
+
01.md 02.md 03.md 04.md 05.md 06.md 07.md 08.md
|
|
44
|
+
│
|
|
45
|
+
└──── gates + subagents + knowledge capture happen at every step
|
|
61
46
|
```
|
|
62
47
|
|
|
63
48
|
Every stage reads and writes real files under `.cclaw/`. `flow-state.json`
|
|
64
49
|
holds the single source of truth for "where are we"; `knowledge.jsonl`
|
|
65
|
-
accumulates reusable lessons
|
|
66
|
-
`.cclaw/artifacts/` until the feature is
|
|
50
|
+
accumulates reusable lessons **throughout** the flow, not only at the end;
|
|
51
|
+
stage artifacts live under `.cclaw/artifacts/` until the feature is
|
|
52
|
+
archived.
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
You ──► /cc <idea>
|
|
56
|
+
│
|
|
57
|
+
▼
|
|
58
|
+
harness loads stage contract + HARD-GATE
|
|
59
|
+
│
|
|
60
|
+
▼
|
|
61
|
+
cclaw reads state + knowledge, guides execution
|
|
62
|
+
│
|
|
63
|
+
▼
|
|
64
|
+
artifacts written, checkpoint saved
|
|
65
|
+
│
|
|
66
|
+
▼
|
|
67
|
+
next stage is explicit in flow-state.json
|
|
68
|
+
```
|
|
67
69
|
|
|
68
70
|
---
|
|
69
71
|
|
|
70
72
|
## 30-second install
|
|
71
73
|
|
|
72
74
|
```bash
|
|
73
|
-
npx cclaw-cli
|
|
75
|
+
npx cclaw-cli
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
Interactive setup will pick which harnesses to install into. For CI or
|
|
79
|
+
scripted installs:
|
|
78
80
|
|
|
79
81
|
```bash
|
|
80
|
-
npx cclaw-cli init --
|
|
82
|
+
npx cclaw-cli init --harnesses=claude,cursor --no-interactive
|
|
81
83
|
```
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
| Profile | promptGuardMode | tddEnforcement | gitHookGuards | languageRulePacks | Use when |
|
|
86
|
-
|---|---|---|---|---|---|
|
|
87
|
-
| `minimal` | advisory | advisory | off | none | Personal projects, quick exploration |
|
|
88
|
-
| `standard` _(default)_ | advisory | advisory | off | none | Most teams; enables the full flow without hard blocks |
|
|
89
|
-
| `full` | **strict** | **strict** | **on** | all | Enterprise / regulated / multi-contributor repos |
|
|
90
|
-
|
|
91
|
-
Profile values are persisted to `.cclaw/config.yaml` and preserved by
|
|
92
|
-
`cclaw upgrade`. Switch profile later with `cclaw init --profile=<id>` or
|
|
93
|
-
edit individual keys directly.
|
|
85
|
+
That's the entire CLI interaction. Everything after install happens
|
|
86
|
+
inside your harness (Claude Code, Cursor, OpenCode, or Codex).
|
|
94
87
|
|
|
95
|
-
### What
|
|
88
|
+
### What gets generated
|
|
96
89
|
|
|
97
90
|
```text
|
|
98
91
|
.cclaw/
|
|
@@ -104,7 +97,7 @@ edit individual keys directly.
|
|
|
104
97
|
├── adapters/ # per-harness translation notes
|
|
105
98
|
├── agents/ # subagent definitions (planner, reviewer, …)
|
|
106
99
|
├── hooks/ # harness-agnostic hook scripts
|
|
107
|
-
├── worktrees/ #
|
|
100
|
+
├── worktrees/ # isolated feature worktrees (power-user, via /cc-ops)
|
|
108
101
|
├── artifacts/ # active feature artifacts (00-idea.md → 09-retro.md)
|
|
109
102
|
├── runs/ # archived feature snapshots: YYYY-MM-DD-slug/
|
|
110
103
|
├── references/ # (optional) pinned copies of reference frameworks
|
|
@@ -122,22 +115,31 @@ Plus harness-specific shims:
|
|
|
122
115
|
- `.codex/commands/cc*.md` + `.codex/hooks.json`
|
|
123
116
|
- `AGENTS.md` with a managed routing block
|
|
124
117
|
|
|
118
|
+
`.cclaw/config.yaml` holds every tunable key (prompt guard strictness,
|
|
119
|
+
TDD enforcement, git-hook guards, language rule packs, track heuristics).
|
|
120
|
+
Edit it directly — `cclaw-cli upgrade` preserves your changes. Full key
|
|
121
|
+
reference: [`docs/config.md`](./docs/config.md).
|
|
122
|
+
|
|
125
123
|
---
|
|
126
124
|
|
|
127
|
-
## The
|
|
125
|
+
## The four commands you actually use
|
|
128
126
|
|
|
129
|
-
All
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
All four appear as slash commands in every supported harness. This is the
|
|
128
|
+
top-level user surface — everything else is either automatic or happens
|
|
129
|
+
inside `/cc-ops` subcommands.
|
|
132
130
|
|
|
133
131
|
| Command | What it does |
|
|
134
132
|
|---|---|
|
|
135
|
-
| **`/cc <idea>`** | Classify the task
|
|
133
|
+
| **`/cc <idea>`** | Classify the task, discover origin docs (`docs/prd/**`, ADRs, root `PRD.md`, …), sniff the stack, recommend a track, then start the first stage of that track. `/cc` without arguments resumes the current flow. |
|
|
136
134
|
| **`/cc-next`** | The one progression primitive. Reads `flow-state.json`, checks gates + mandatory subagent delegations, and either resumes the current stage or advances to the next. `/cc-next` in a new session is how you **resume**. |
|
|
137
135
|
| **`/cc-ideate`** | Repository improvement discovery. Scans for TODOs, flaky tests, oversized modules, docs drift, and recurring knowledge-store lessons; returns a ranked backlog before you commit to a specific feature. |
|
|
138
136
|
| **`/cc-view`** | Read-only flow visibility. `/cc-view status` (default), `/cc-view tree`, `/cc-view diff` (baseline delta map). Never mutates state. |
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
|
|
138
|
+
> Power-user surface: `/cc-ops` is an operational router for manual
|
|
139
|
+
> overrides (rewind a stale stage, manage parallel features, re-run a
|
|
140
|
+
> compound pass). `/cc-learn` is the strict-schema knowledge writer —
|
|
141
|
+
> agents call it automatically from completion protocols; you rarely
|
|
142
|
+
> invoke it by hand.
|
|
141
143
|
|
|
142
144
|
### Example first-run
|
|
143
145
|
|
|
@@ -199,7 +201,7 @@ cclaw has eight stages, but a single prompt rarely needs all of them.
|
|
|
199
201
|
|
|
200
202
|
Each stage produces a dated artifact under `.cclaw/artifacts/`:
|
|
201
203
|
`00-idea.md` (seed) and `01-brainstorm.md` through `08-ship.md`
|
|
202
|
-
(plus `09-retro.md` at closeout).
|
|
204
|
+
(plus `09-retro.md` at automatic closeout — see below).
|
|
203
205
|
|
|
204
206
|
### Track heuristics are configurable
|
|
205
207
|
|
|
@@ -231,80 +233,31 @@ Reclassification is append-only: the old decision stays in history.
|
|
|
231
233
|
|
|
232
234
|
---
|
|
233
235
|
|
|
234
|
-
##
|
|
235
|
-
|
|
236
|
-
Run anytime. Non-zero exit code means something observably wrong with the
|
|
237
|
-
`.cclaw/` runtime.
|
|
238
|
-
|
|
239
|
-
```bash
|
|
240
|
-
cclaw doctor # full sweep, PASS/FAIL summary
|
|
241
|
-
cclaw doctor --reconcile-gates # also recompute current stage gate evidence
|
|
242
|
-
cclaw doctor --explain # include fix + doc reference per check
|
|
243
|
-
cclaw doctor --only=error # or --only=trace:,hook: for narrow sweeps
|
|
244
|
-
cclaw doctor --quiet # only failing checks (CI-friendly)
|
|
245
|
-
cclaw doctor --json # machine-readable, exit 2 on error failures
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
Each failing check points at:
|
|
249
|
-
|
|
250
|
-
- a **severity** (error / warning / info)
|
|
251
|
-
- a one-line **summary**
|
|
252
|
-
- concrete **details** from your repo
|
|
253
|
-
- a **fix** string and a **doc reference** when `--explain` is on
|
|
254
|
-
|
|
255
|
-
Example:
|
|
256
|
-
|
|
257
|
-
```text
|
|
258
|
-
[ERROR]
|
|
259
|
-
FAIL trace:matrix_populated :: spec artifact exists but trace matrix is empty
|
|
260
|
-
details: .cclaw/artifacts/04-spec.md has 3 acceptance criteria; 0 mapped
|
|
261
|
-
fix: rebuild trace matrix via /cc-next (spec completion protocol) or edit 04-spec.md to add testable criteria
|
|
262
|
-
docs: .cclaw/skills/specification-authoring/SKILL.md#trace-matrix
|
|
263
|
-
|
|
264
|
-
Doctor status: BLOCKED (1 failing error check)
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
Add `cclaw doctor` to a pre-commit hook or CI job (`exit 2` on error
|
|
268
|
-
severity) and you inherit a shared definition of "the runtime is healthy".
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
## Closeout and compounding
|
|
273
|
-
|
|
274
|
-
Shipping a feature is a **separate stage** (`08-ship.md`), followed by two
|
|
275
|
-
more disciplined steps:
|
|
276
|
-
|
|
277
|
-
```text
|
|
278
|
-
/cc-ops retro # writes 09-retro.md; gates knowledge capture (≥1 compound line)
|
|
279
|
-
/cc-ops compound # (optional) lifts repeated learnings into first-class rules/skills
|
|
280
|
-
/cc-ops archive # moves artifacts/ to runs/YYYY-MM-DD-slug/, resets flow-state
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
Archive is gated on retro completion unless you explicitly pass
|
|
284
|
-
`--skip-retro --retro-reason="..."`. You cannot accidentally lose the
|
|
285
|
-
learning pass.
|
|
286
|
-
|
|
287
|
-
Knowledge entries are strict JSONL with frequency, maturity, and provenance
|
|
288
|
-
fields — not freeform markdown — so they stay machine-queryable across
|
|
289
|
-
sessions and contributors.
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## Parallel features with git worktrees
|
|
294
|
-
|
|
295
|
-
Use `/cc-ops feature` to run more than one cclaw flow side by side without
|
|
296
|
-
copying `.cclaw/` state:
|
|
236
|
+
## Guardrails that ship in the box
|
|
297
237
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
/cc-ops feature list # shows all active features + their branches
|
|
301
|
-
/cc-ops feature switch checkout-refactor
|
|
302
|
-
/cc-ops feature status # which feature this workspace is attached to
|
|
303
|
-
```
|
|
238
|
+
These are the things that make cclaw "enterprise-strong" without turning
|
|
239
|
+
it into ceremony:
|
|
304
240
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
241
|
+
- **Locked decisions (D-XX IDs).** Scope decisions are numbered and must
|
|
242
|
+
reappear in plan + TDD artifacts. The artifact linter catches any
|
|
243
|
+
silent drift.
|
|
244
|
+
- **No placeholders.** `TBD`, `TODO`, `similar to task`, and "static for
|
|
245
|
+
now"-style scope reduction are flagged before a stage completes.
|
|
246
|
+
- **Stale-stage detection.** If an upstream artifact changes after a
|
|
247
|
+
downstream stage is already complete, cclaw marks the downstream stage
|
|
248
|
+
stale and refuses to advance until you re-run it (or explicitly
|
|
249
|
+
acknowledge via a manual override).
|
|
250
|
+
- **Mandatory subagent delegation** at TDD, with per-harness waivers.
|
|
251
|
+
- **Turn Announce Discipline.** Every stage entry/exit emits a visible
|
|
252
|
+
line so users can see what the agent is doing, not just what it says.
|
|
253
|
+
- **Extracted protocols.** Decision, Completion, and Ethos protocols live
|
|
254
|
+
in a single place (`.cclaw/contexts/`), so every skill speaks the same
|
|
255
|
+
dialect.
|
|
256
|
+
- **Knowledge capture throughout the flow.** Every stage completion
|
|
257
|
+
protocol can emit entries to `knowledge.jsonl` — not only retro. Strict
|
|
258
|
+
JSONL schema keeps it machine-queryable.
|
|
259
|
+
- **Automatic integrity checks.** Runtime health is verified on every
|
|
260
|
+
stage transition — no command you need to remember to run.
|
|
308
261
|
|
|
309
262
|
---
|
|
310
263
|
|
|
@@ -323,9 +276,26 @@ subagent as `completed` or explicitly `waived` (for harnesses without
|
|
|
323
276
|
native subagent dispatch, such as Codex — see
|
|
324
277
|
[Harness support](#harness-support)).
|
|
325
278
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Ship and closeout
|
|
282
|
+
|
|
283
|
+
Shipping writes `08-ship.md` and then closes out the feature through a
|
|
284
|
+
guided three-step sequence:
|
|
285
|
+
|
|
286
|
+
1. **Retro** drafts `09-retro.md` from flow artifacts and the delegation
|
|
287
|
+
log; you review and accept.
|
|
288
|
+
2. **Compound pass** promotes repeated knowledge entries (frequency ≥ 2,
|
|
289
|
+
maturity = stable) into first-class rules or skills.
|
|
290
|
+
3. **Archive** moves artifacts to `.cclaw/runs/YYYY-MM-DD-<slug>/` and
|
|
291
|
+
resets `flow-state.json`.
|
|
292
|
+
|
|
293
|
+
Retro is not optional — archive is gated on retro completion so you can't
|
|
294
|
+
silently lose the learning pass.
|
|
295
|
+
|
|
296
|
+
> **Coming next:** cclaw will chain these three steps automatically from
|
|
297
|
+
> `ship` (one structured `edit`/`accept`/`skip` ask, resumable if the
|
|
298
|
+
> session ends). Tracked as the v0.32 closeout-automation wave.
|
|
329
299
|
|
|
330
300
|
---
|
|
331
301
|
|
|
@@ -335,62 +305,26 @@ cclaw is honest about which harnesses give you full automation and which
|
|
|
335
305
|
need small manual bridges. See
|
|
336
306
|
[`docs/harnesses.md`](./docs/harnesses.md) for the full matrix.
|
|
337
307
|
|
|
338
|
-
| Harness |
|
|
308
|
+
| Harness | Subagent dispatch | Hook surface | Structured ask | Status |
|
|
339
309
|
|---|---|---|---|---|
|
|
340
|
-
| Claude Code |
|
|
341
|
-
| Cursor |
|
|
342
|
-
| OpenCode |
|
|
343
|
-
| OpenAI Codex |
|
|
344
|
-
|
|
345
|
-
Capability gaps are captured in `.cclaw/state/harness-gaps.json` and
|
|
346
|
-
surfaced by `cclaw doctor`. Where native dispatch is missing, cclaw emits
|
|
347
|
-
a structured **waiver** rather than pretending the delegation happened.
|
|
348
|
-
|
|
349
|
-
---
|
|
350
|
-
|
|
351
|
-
## Guardrails that ship in the box
|
|
310
|
+
| Claude Code | native | full | `AskUserQuestion` | full parity |
|
|
311
|
+
| Cursor | partial | full | `AskQuestion` | parity gap: subagent dispatch |
|
|
312
|
+
| OpenCode | partial | plugin | plain-text | parity gap: plugin hooks |
|
|
313
|
+
| OpenAI Codex | none (waiver) | full | plain-text | parity gap: no subagent |
|
|
352
314
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
reappear in plan + TDD artifacts. The artifact linter catches any
|
|
358
|
-
silent drift.
|
|
359
|
-
- **No placeholders.** `TBD`, `TODO`, `similar to task`, and "static for
|
|
360
|
-
now"-style scope reduction are flagged before a stage completes.
|
|
361
|
-
- **Stale-stage detection.** If an upstream artifact changes after a
|
|
362
|
-
downstream stage is already complete, cclaw marks the downstream stage
|
|
363
|
-
stale and refuses to advance until you re-run it (or explicitly
|
|
364
|
-
acknowledge via `/cc-ops rewind --ack <stage>`).
|
|
365
|
-
- **Mandatory subagent delegation** at TDD, with per-harness waivers.
|
|
366
|
-
- **Turn Announce Discipline.** Every stage entry/exit emits a visible
|
|
367
|
-
line so users can see what the agent is doing, not just what it says.
|
|
368
|
-
- **Extracted protocols.** Decision, Completion, and Ethos protocols live
|
|
369
|
-
in a single place (`.cclaw/contexts/`), so every skill speaks the same
|
|
370
|
-
dialect.
|
|
371
|
-
- **Strict JSONL knowledge schema.** Queryable from scripts, not just
|
|
372
|
-
grep-able.
|
|
315
|
+
Capability gaps are captured in `.cclaw/state/harness-gaps.json`. Where
|
|
316
|
+
native dispatch is missing, cclaw emits a **structured waiver** rather
|
|
317
|
+
than pretending the delegation happened. Closing these gaps is an
|
|
318
|
+
ongoing kinetic effort — see the harness tracking doc above.
|
|
373
319
|
|
|
374
320
|
---
|
|
375
321
|
|
|
376
322
|
## Eval-driven prompt engineering
|
|
377
323
|
|
|
378
|
-
cclaw ships with `cclaw eval` — a three-tier regression harness for
|
|
379
|
-
skills and contracts the runtime generates. Use it when you change a
|
|
324
|
+
cclaw ships with `cclaw-cli eval` — a three-tier regression harness for
|
|
325
|
+
the skills and contracts the runtime generates. Use it when you change a
|
|
380
326
|
stage skill, tweak a prompt, or swap a model.
|
|
381
327
|
|
|
382
|
-
```bash
|
|
383
|
-
cclaw eval --dry-run # validate corpus + config
|
|
384
|
-
cclaw eval --schema-only # L1 structural (PR-blocking, no LLM)
|
|
385
|
-
cclaw eval --rules # L1 + L2 rule-based
|
|
386
|
-
cclaw eval --judge --mode=fixture --stage=spec # L3 LLM judge against a fixture
|
|
387
|
-
cclaw eval --judge --mode=agent --stage=plan # draft in a sandbox, then judge
|
|
388
|
-
cclaw eval --mode=workflow --judge # full multi-stage run (Tier C)
|
|
389
|
-
cclaw eval --compare-model=gpt-4o-mini # diff two models against same corpus
|
|
390
|
-
cclaw eval diff 0.26.0 latest # compare two saved reports
|
|
391
|
-
cclaw eval --background # long runs go to .cclaw/evals/runs/
|
|
392
|
-
```
|
|
393
|
-
|
|
394
328
|
Works with any OpenAI-compatible endpoint — Zhipu AI GLM, OpenAI, Together,
|
|
395
329
|
self-hosted vLLM — via three environment variables:
|
|
396
330
|
|
|
@@ -398,89 +332,32 @@ self-hosted vLLM — via three environment variables:
|
|
|
398
332
|
CCLAW_EVAL_API_KEY=...
|
|
399
333
|
CCLAW_EVAL_BASE_URL=https://api.z.ai/api/coding/paas/v4 # default
|
|
400
334
|
CCLAW_EVAL_MODEL=glm-5.1 # default
|
|
401
|
-
CCLAW_EVAL_DAILY_USD_CAP=5 # optional cost guard
|
|
402
335
|
```
|
|
403
336
|
|
|
404
|
-
Full details and the eval contract live in
|
|
337
|
+
Full details, corpus format, and the eval contract live in
|
|
405
338
|
[`docs/evals.md`](./docs/evals.md).
|
|
406
339
|
|
|
407
340
|
---
|
|
408
341
|
|
|
409
342
|
## CLI reference
|
|
410
343
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
[--interactive | --no-interactive] [--dry-run]
|
|
414
|
-
cclaw sync # regenerate shims
|
|
415
|
-
cclaw doctor [--reconcile-gates] [--explain] [--quiet] \
|
|
416
|
-
[--only=<filter>] [--json]
|
|
417
|
-
cclaw upgrade # refresh generated files; preserve config
|
|
418
|
-
cclaw archive [--name=<slug>] [--skip-retro --retro-reason=<t>]
|
|
419
|
-
cclaw eval <see evals section above>
|
|
420
|
-
cclaw uninstall # remove .cclaw + generated shims
|
|
421
|
-
cclaw --version # shows the installed package version
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
`sync` regenerates shims and runtime files without touching user artifacts,
|
|
425
|
-
state, or config keys. `upgrade` does the same **and** bumps the version
|
|
426
|
-
stamp in `.cclaw/config.yaml`, preserving every custom profile/heuristic
|
|
427
|
-
key. To reset to a named profile, re-run `cclaw init --profile=<id>`.
|
|
428
|
-
|
|
429
|
-
---
|
|
430
|
-
|
|
431
|
-
## Compared to references
|
|
432
|
-
|
|
433
|
-
cclaw stands on the shoulders of several open frameworks. Each one is
|
|
434
|
-
genuinely good at something. Here is the honest tradeoff.
|
|
435
|
-
|
|
436
|
-
**Superpowers** (obra) ships a mature methodology where skills compose and
|
|
437
|
-
activate ambiently. cclaw trades that breadth for a **single auditable
|
|
438
|
-
pipeline**: `flow-state.json`, stage gates, and `cclaw doctor` make it easy
|
|
439
|
-
to see *why* the agent is allowed to advance. Choose Superpowers for
|
|
440
|
-
ecosystem richness; choose cclaw when deterministic stage discipline
|
|
441
|
-
matters more than plugin variety.
|
|
442
|
-
|
|
443
|
-
**G-Stack** is a full virtual engineering org — dozens of slash commands
|
|
444
|
-
for planning, design, QA, and release. cclaw deliberately keeps **one
|
|
445
|
-
stage machine** and the same six harness entrypoints, prioritizing
|
|
446
|
-
repeatability across harnesses over role-surface area. Use G-Stack when
|
|
447
|
-
you want explicit multi-role theater; use cclaw when you want one pipeline
|
|
448
|
-
across Claude, Cursor, OpenCode, and Codex.
|
|
449
|
-
|
|
450
|
-
**Everything Claude Code** is an optimization and inventory system —
|
|
451
|
-
memory, instincts, security, and multi-ecosystem configs. cclaw is a
|
|
452
|
-
**minimal flow runtime**: eight stages, JSONL knowledge, and evals for
|
|
453
|
-
contract drift. Pair ECC-style breadth with cclaw if you need both
|
|
454
|
-
coverage and a single ship path.
|
|
455
|
-
|
|
456
|
-
---
|
|
457
|
-
|
|
458
|
-
## PR-first ship flow
|
|
459
|
-
|
|
460
|
-
cclaw does not run hidden git automation. Release discipline lives inside
|
|
461
|
-
the harness; repository operations stay explicit:
|
|
344
|
+
The CLI is deliberately small. Everything operational happens inside
|
|
345
|
+
your harness.
|
|
462
346
|
|
|
463
347
|
```bash
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
#
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
gh pr create
|
|
348
|
+
npx cclaw-cli # launches interactive setup (or prints
|
|
349
|
+
# a one-line status hint if already installed)
|
|
350
|
+
npx cclaw-cli upgrade # refresh generated files; preserves .cclaw/config.yaml
|
|
351
|
+
npx cclaw-cli uninstall # remove .cclaw + generated harness shims
|
|
352
|
+
npx cclaw-cli eval … # maintainer surface (see docs/evals.md)
|
|
353
|
+
npx cclaw-cli --version
|
|
471
354
|
```
|
|
472
355
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
GitHub Release, and uploads `.tgz` + plugin manifest artifacts.
|
|
479
|
-
- **Release Package** remains available for manual / event-driven flows.
|
|
480
|
-
|
|
481
|
-
Bump `package.json` in the PR to trigger a new publish.
|
|
482
|
-
|
|
483
|
-
Required repository secret: `NPM_TOKEN` with publish access.
|
|
356
|
+
For CI or scripted installs, `cclaw-cli init --harnesses=<list>
|
|
357
|
+
--no-interactive` is the non-interactive form. All other tunables
|
|
358
|
+
(prompt-guard strictness, TDD enforcement, language rule packs, track
|
|
359
|
+
heuristics) are set by editing `.cclaw/config.yaml` directly — see
|
|
360
|
+
[`docs/config.md`](./docs/config.md) for the full key reference.
|
|
484
361
|
|
|
485
362
|
---
|
|
486
363
|
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import type { FlowTrack, HarnessId
|
|
2
|
+
import type { FlowTrack, HarnessId } from "./types.js";
|
|
3
3
|
import type { EvalMode } from "./eval/types.js";
|
|
4
4
|
type CommandName = "init" | "sync" | "doctor" | "upgrade" | "uninstall" | "archive" | "eval";
|
|
5
5
|
interface ParsedArgs {
|
|
6
6
|
command?: CommandName;
|
|
7
7
|
harnesses?: HarnessId[];
|
|
8
8
|
track?: FlowTrack;
|
|
9
|
-
profile?: InitProfile;
|
|
10
9
|
dryRun?: boolean;
|
|
11
10
|
interactive?: boolean;
|
|
12
11
|
reconcileGates?: boolean;
|
|
@@ -40,6 +39,5 @@ interface ParsedArgs {
|
|
|
40
39
|
export declare function usage(): string;
|
|
41
40
|
declare function parseHarnesses(raw: string): HarnessId[];
|
|
42
41
|
declare function parseTrack(raw: string): FlowTrack;
|
|
43
|
-
declare function parseProfile(raw: string): InitProfile;
|
|
44
42
|
declare function parseArgs(argv: string[]): ParsedArgs;
|
|
45
|
-
export { parseArgs, parseHarnesses, parseTrack
|
|
43
|
+
export { parseArgs, parseHarnesses, parseTrack };
|
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createReadStream, realpathSync } from "node:fs";
|
|
2
|
+
import { createReadStream, existsSync, realpathSync } from "node:fs";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { createInterface } from "node:readline/promises";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { FLOW_TRACKS, HARNESS_IDS
|
|
9
|
+
import { FLOW_TRACKS, HARNESS_IDS } from "./types.js";
|
|
10
10
|
import { doctorChecks, doctorSucceeded } from "./doctor.js";
|
|
11
11
|
import { initCclaw, syncCclaw, uninstallCclaw, upgradeCclaw } from "./install.js";
|
|
12
12
|
import { error, info } from "./logger.js";
|
|
13
13
|
import { archiveRun } from "./runs.js";
|
|
14
14
|
import { CCLAW_VERSION, RUNTIME_ROOT } from "./constants.js";
|
|
15
|
-
import { createDefaultConfig
|
|
15
|
+
import { createDefaultConfig } from "./config.js";
|
|
16
16
|
import { detectHarnesses } from "./init-detect.js";
|
|
17
17
|
import { HARNESS_ADAPTERS } from "./harness-adapters.js";
|
|
18
18
|
import { runEval } from "./eval/runner.js";
|
|
@@ -21,7 +21,6 @@ import { writeBaselinesFromReport } from "./eval/baseline.js";
|
|
|
21
21
|
import { writeJsonReport, writeMarkdownReport } from "./eval/report.js";
|
|
22
22
|
import { formatDiffMarkdown, runEvalDiff } from "./eval/diff.js";
|
|
23
23
|
import { ensureRunDir, generateRunId, isRunAlive, listRuns, readRunStatus, resolveRunId, runLogPath, writeRunStatus } from "./eval/runs.js";
|
|
24
|
-
import { EVAL_MODES } from "./eval/types.js";
|
|
25
24
|
import { parseModeInput } from "./eval/mode.js";
|
|
26
25
|
import { FLOW_STAGES } from "./types.js";
|
|
27
26
|
const INSTALLER_COMMANDS = [
|
|
@@ -37,82 +36,33 @@ export function usage() {
|
|
|
37
36
|
return `cclaw - installer-first flow toolkit
|
|
38
37
|
|
|
39
38
|
Usage:
|
|
40
|
-
cclaw
|
|
41
|
-
cclaw
|
|
42
|
-
cclaw --
|
|
39
|
+
npx cclaw-cli # launch setup or print "already installed" hint
|
|
40
|
+
npx cclaw-cli <command> [flags]
|
|
41
|
+
npx cclaw-cli --help | -h
|
|
42
|
+
npx cclaw-cli --version | -v
|
|
43
43
|
|
|
44
44
|
Commands:
|
|
45
45
|
init Bootstrap .cclaw runtime, state, and harness shims in this project.
|
|
46
|
-
Flags: --
|
|
47
|
-
--
|
|
48
|
-
|
|
49
|
-
--interactive Force interactive prompts (TTY only).
|
|
50
|
-
--no-interactive Skip interactive prompts even on TTY.
|
|
51
|
-
--dry-run Print resolved config + generated surfaces without writing files.
|
|
52
|
-
sync Regenerate harness shim files from the current .cclaw config (non-destructive).
|
|
53
|
-
doctor Run health checks against the local .cclaw runtime. Exit code 2 when any error-severity check fails.
|
|
54
|
-
Flags: --reconcile-gates Recompute current-stage gate evidence before checks.
|
|
55
|
-
--json Emit machine-readable JSON output.
|
|
56
|
-
--only=<filter> Comma list of severities/check-name filters (error,warning,info,trace:,hook:...).
|
|
57
|
-
--explain Include fix + doc reference per check in text mode.
|
|
58
|
-
--quiet Print only failing checks (and totals).
|
|
59
|
-
archive Move .cclaw/artifacts into .cclaw/runs/<date>-<slug> and reset flow state.
|
|
60
|
-
Flags: --name=<feature> Feature slug (default: inferred from 00-idea.md).
|
|
61
|
-
--skip-retro Bypass mandatory retro gate (requires --retro-reason).
|
|
62
|
-
--retro-reason=<t> Reason for bypassing retro gate.
|
|
63
|
-
eval Run cclaw evals against .cclaw/evals/corpus (Phase 7: structural verifier + baselines).
|
|
64
|
-
Flags: --stage=<id> Limit to one flow stage (${FLOW_STAGES.join("|")}) for fixture/agent modes.
|
|
65
|
-
--mode=<${EVAL_MODES.join("|")}>
|
|
66
|
-
Evaluation mode:
|
|
67
|
-
fixture = verify existing artifacts with structural/rule/judge verifiers.
|
|
68
|
-
agent = LLM drafts one stage's artifact in a sandbox with tools.
|
|
69
|
-
workflow = LLM runs the full multi-stage flow (brainstorm→plan).
|
|
70
|
-
Legacy --tier=A|B|C still works (deprecated).
|
|
71
|
-
--schema-only Run only structural verifiers (default).
|
|
72
|
-
--rules Also run rule-based verifiers (keywords, regex, counts, uniqueness, traceability).
|
|
73
|
-
--judge Run the LLM judge (median-of-N) against each case's rubric. Requires CCLAW_EVAL_API_KEY; fixture mode judges an existing artifact, agent/workflow modes draft first and then judge.
|
|
74
|
-
--dry-run Validate config + corpus, print summary, do not execute.
|
|
75
|
-
--json Emit machine-readable JSON on stdout.
|
|
76
|
-
--no-write Skip writing the report to .cclaw/evals/reports/.
|
|
77
|
-
--update-baseline Overwrite baselines from the current run (requires --confirm).
|
|
78
|
-
--confirm Acknowledge --update-baseline (prevents accidental resets).
|
|
79
|
-
--quiet Silence the stderr progress logger (default: emit one
|
|
80
|
-
line per case / stage to stderr so long runs are visible).
|
|
81
|
-
--max-cost-usd=<n> Abort the run if committed USD spend crosses <n>
|
|
82
|
-
(independent from the daily cap). Also readable from
|
|
83
|
-
CCLAW_EVAL_MAX_COST_USD.
|
|
84
|
-
--compare-model=<id> Run the same corpus twice — once with the configured model
|
|
85
|
-
and once with <id> — then diff the summaries. Exit code 1
|
|
86
|
-
when the override model regressed.
|
|
87
|
-
--background Spawn the run as a detached child process, write the
|
|
88
|
-
combined output to .cclaw/evals/runs/<id>/run.log, and
|
|
89
|
-
return immediately. Attach later with
|
|
90
|
-
\`cclaw eval runs tail <id|latest>\`.
|
|
91
|
-
|
|
92
|
-
Subcommands:
|
|
93
|
-
diff <old> <new> Compare two reports under .cclaw/evals/reports/.
|
|
94
|
-
Each argument is a cclawVersion (e.g. 0.26.0), a filename,
|
|
95
|
-
or the literal "latest". Exit code 1 when the diff shows a
|
|
96
|
-
regression. Accepts --json to emit machine-readable output.
|
|
97
|
-
runs [action] [id] Inspect background runs under .cclaw/evals/runs/.
|
|
98
|
-
Actions: list (default) | status <id|latest> | tail <id|latest>.
|
|
99
|
-
upgrade Refresh generated files in .cclaw without modifying user artifacts.
|
|
46
|
+
Flags: --harnesses=<list> Comma list of harnesses (claude,cursor,opencode,codex).
|
|
47
|
+
--no-interactive Skip interactive prompts even on TTY (for CI/scripts).
|
|
48
|
+
upgrade Refresh generated files in .cclaw. Preserves your config.yaml.
|
|
100
49
|
uninstall Remove .cclaw runtime and the generated harness shim files.
|
|
50
|
+
eval Run cclaw evals. Maintainer surface — see docs/evals.md.
|
|
51
|
+
Full flag reference: \`npx cclaw-cli eval --help\` or docs/evals.md.
|
|
101
52
|
|
|
102
53
|
Global flags:
|
|
103
54
|
-h, --help Show this help message and exit 0.
|
|
104
55
|
-v, --version Print the cclaw CLI version and exit 0.
|
|
105
56
|
|
|
106
57
|
Examples:
|
|
107
|
-
cclaw
|
|
108
|
-
cclaw
|
|
109
|
-
cclaw
|
|
110
|
-
cclaw eval --dry-run
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
cclaw eval diff 0.26.0 latest
|
|
58
|
+
npx cclaw-cli
|
|
59
|
+
npx cclaw-cli init --harnesses=claude,cursor --no-interactive
|
|
60
|
+
npx cclaw-cli upgrade
|
|
61
|
+
npx cclaw-cli eval --dry-run
|
|
62
|
+
|
|
63
|
+
Everything operational (retro, archive, worktrees, doctor, learnings)
|
|
64
|
+
happens inside your harness via slash commands. The CLI is just a
|
|
65
|
+
launcher. See README.md for the four user-facing slash commands.
|
|
116
66
|
|
|
117
67
|
Docs: https://github.com/zuevrs/cclaw
|
|
118
68
|
Issues: https://github.com/zuevrs/cclaw/issues
|
|
@@ -136,13 +86,6 @@ function parseTrack(raw) {
|
|
|
136
86
|
}
|
|
137
87
|
return trimmed;
|
|
138
88
|
}
|
|
139
|
-
function parseProfile(raw) {
|
|
140
|
-
const trimmed = raw.trim();
|
|
141
|
-
if (!INIT_PROFILES.includes(trimmed)) {
|
|
142
|
-
throw new Error(`Unknown profile: ${trimmed}. Supported: ${INIT_PROFILES.join(", ")}`);
|
|
143
|
-
}
|
|
144
|
-
return trimmed;
|
|
145
|
-
}
|
|
146
89
|
function parseLegacyTier(raw) {
|
|
147
90
|
return parseModeInput(raw.toUpperCase(), {
|
|
148
91
|
source: "cli",
|
|
@@ -165,6 +108,26 @@ function parseEvalStage(raw) {
|
|
|
165
108
|
function isInitPromptAllowed(ctx) {
|
|
166
109
|
return Boolean(process.stdin.isTTY && ctx.stdout.isTTY);
|
|
167
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Print a short, friendly hint when the user runs `cclaw-cli` with no
|
|
113
|
+
* arguments. Does not read or mutate flow state — only checks whether
|
|
114
|
+
* `.cclaw/config.yaml` exists to branch between "installed" and
|
|
115
|
+
* "not-installed" messaging. Keeps exit 0 in both cases: users discover
|
|
116
|
+
* the tool through this path, not through an error.
|
|
117
|
+
*/
|
|
118
|
+
function printNoArgsHint(ctx) {
|
|
119
|
+
const installed = existsSync(path.join(ctx.cwd, RUNTIME_ROOT, "config.yaml"));
|
|
120
|
+
if (installed) {
|
|
121
|
+
ctx.stdout.write("cclaw is installed in this project. Open your harness (Claude Code, " +
|
|
122
|
+
"Cursor, OpenCode, or Codex) and type `/cc` to start.\n");
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
ctx.stdout.write("cclaw is not installed in this project yet.\n" +
|
|
126
|
+
"Run `npx cclaw-cli init` to bootstrap .cclaw and the harness shims.\n" +
|
|
127
|
+
"For help: `npx cclaw-cli --help`.\n");
|
|
128
|
+
}
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
168
131
|
function buildInitSurfacePreview(harnesses) {
|
|
169
132
|
const lines = [
|
|
170
133
|
".cclaw/config.yaml",
|
|
@@ -206,39 +169,11 @@ function buildInitSurfacePreview(harnesses) {
|
|
|
206
169
|
}
|
|
207
170
|
return lines;
|
|
208
171
|
}
|
|
209
|
-
function inferTrackDefault(profile, track) {
|
|
210
|
-
if (track)
|
|
211
|
-
return track;
|
|
212
|
-
if (!profile)
|
|
213
|
-
return "standard";
|
|
214
|
-
return createProfileConfig(profile).defaultTrack ?? "standard";
|
|
215
|
-
}
|
|
216
172
|
async function promptInitConfig(defaults, ctx) {
|
|
217
173
|
const rl = createInterface({
|
|
218
174
|
input: process.stdin,
|
|
219
175
|
output: ctx.stdout
|
|
220
176
|
});
|
|
221
|
-
const pickSingle = async (label, options, fallback) => {
|
|
222
|
-
while (true) {
|
|
223
|
-
ctx.stdout.write(`\n${label}\n`);
|
|
224
|
-
options.forEach((option, index) => {
|
|
225
|
-
const marker = option === fallback ? " (default)" : "";
|
|
226
|
-
ctx.stdout.write(` ${index + 1}) ${option}${marker}\n`);
|
|
227
|
-
});
|
|
228
|
-
const answer = (await rl.question("> ")).trim();
|
|
229
|
-
if (answer.length === 0) {
|
|
230
|
-
return fallback;
|
|
231
|
-
}
|
|
232
|
-
const numeric = Number(answer);
|
|
233
|
-
if (Number.isInteger(numeric) && numeric >= 1 && numeric <= options.length) {
|
|
234
|
-
return options[numeric - 1];
|
|
235
|
-
}
|
|
236
|
-
if (options.includes(answer)) {
|
|
237
|
-
return answer;
|
|
238
|
-
}
|
|
239
|
-
ctx.stdout.write("Invalid selection. Use option number or value.\n");
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
177
|
const pickHarnesses = async (fallback) => {
|
|
243
178
|
const fallbackText = fallback.join(",");
|
|
244
179
|
while (true) {
|
|
@@ -260,11 +195,8 @@ async function promptInitConfig(defaults, ctx) {
|
|
|
260
195
|
}
|
|
261
196
|
};
|
|
262
197
|
try {
|
|
263
|
-
const profile = await pickSingle("Select init profile:", INIT_PROFILES, defaults.profile);
|
|
264
|
-
const trackDefault = inferTrackDefault(profile, defaults.track);
|
|
265
|
-
const track = await pickSingle("Select default flow track:", FLOW_TRACKS, trackDefault);
|
|
266
198
|
const harnesses = await pickHarnesses(defaults.harnesses);
|
|
267
|
-
return {
|
|
199
|
+
return { harnesses };
|
|
268
200
|
}
|
|
269
201
|
finally {
|
|
270
202
|
rl.close();
|
|
@@ -279,13 +211,11 @@ async function resolveInitInputs(parsed, ctx) {
|
|
|
279
211
|
const promptForbidden = parsed.interactive === false;
|
|
280
212
|
const implicitPrompt = !promptForbidden &&
|
|
281
213
|
isInitPromptAllowed(ctx) &&
|
|
282
|
-
parsed.profile === undefined &&
|
|
283
214
|
parsed.track === undefined &&
|
|
284
215
|
parsed.harnesses === undefined;
|
|
285
216
|
const shouldPrompt = promptRequested || implicitPrompt;
|
|
286
217
|
if (!shouldPrompt) {
|
|
287
218
|
return {
|
|
288
|
-
profile: parsed.profile,
|
|
289
219
|
track: parsed.track,
|
|
290
220
|
harnesses: autoHarnesses,
|
|
291
221
|
detectedHarnesses
|
|
@@ -295,14 +225,11 @@ async function resolveInitInputs(parsed, ctx) {
|
|
|
295
225
|
throw new Error("Interactive init requires a TTY. Remove --interactive or run in a terminal.");
|
|
296
226
|
}
|
|
297
227
|
const defaults = {
|
|
298
|
-
profile: parsed.profile ?? "standard",
|
|
299
|
-
track: inferTrackDefault(parsed.profile, parsed.track),
|
|
300
228
|
harnesses: autoHarnesses ?? HARNESS_IDS.slice()
|
|
301
229
|
};
|
|
302
230
|
const prompted = await promptInitConfig(defaults, ctx);
|
|
303
231
|
return {
|
|
304
|
-
|
|
305
|
-
track: prompted.track,
|
|
232
|
+
track: parsed.track,
|
|
306
233
|
harnesses: prompted.harnesses,
|
|
307
234
|
detectedHarnesses
|
|
308
235
|
};
|
|
@@ -447,7 +374,6 @@ function parseArgs(argv) {
|
|
|
447
374
|
continue;
|
|
448
375
|
}
|
|
449
376
|
if (flag.startsWith("--profile=")) {
|
|
450
|
-
parsed.profile = parseProfile(flag.replace("--profile=", ""));
|
|
451
377
|
continue;
|
|
452
378
|
}
|
|
453
379
|
if (flag === "--interactive") {
|
|
@@ -780,28 +706,20 @@ async function runCommand(parsed, ctx) {
|
|
|
780
706
|
}
|
|
781
707
|
const command = parsed.command;
|
|
782
708
|
if (!command) {
|
|
783
|
-
ctx
|
|
784
|
-
return 1;
|
|
709
|
+
return printNoArgsHint(ctx);
|
|
785
710
|
}
|
|
786
711
|
if (command === "init") {
|
|
787
712
|
const resolved = await resolveInitInputs(parsed, ctx);
|
|
788
|
-
const effectiveProfile = resolved.profile;
|
|
789
713
|
const effectiveTrack = resolved.track;
|
|
790
714
|
const effectiveHarnesses = resolved.harnesses;
|
|
791
715
|
if (parsed.dryRun === true) {
|
|
792
|
-
const previewConfig =
|
|
793
|
-
? createProfileConfig(effectiveProfile, {
|
|
794
|
-
harnesses: effectiveHarnesses,
|
|
795
|
-
defaultTrack: effectiveTrack
|
|
796
|
-
})
|
|
797
|
-
: createDefaultConfig(effectiveHarnesses, effectiveTrack);
|
|
716
|
+
const previewConfig = createDefaultConfig(effectiveHarnesses, effectiveTrack);
|
|
798
717
|
const previewSurfaces = buildInitSurfacePreview(previewConfig.harnesses);
|
|
799
718
|
info(ctx, "Dry run: no files were written.");
|
|
800
719
|
if (resolved.detectedHarnesses.length > 0 && parsed.harnesses === undefined) {
|
|
801
720
|
info(ctx, `Detected harnesses from repo: ${resolved.detectedHarnesses.join(", ")}`);
|
|
802
721
|
}
|
|
803
722
|
ctx.stdout.write(`${JSON.stringify({
|
|
804
|
-
profile: effectiveProfile ?? "standard(default)",
|
|
805
723
|
track: previewConfig.defaultTrack ?? "standard",
|
|
806
724
|
harnesses: previewConfig.harnesses,
|
|
807
725
|
promptGuardMode: previewConfig.promptGuardMode,
|
|
@@ -814,16 +732,13 @@ async function runCommand(parsed, ctx) {
|
|
|
814
732
|
await initCclaw({
|
|
815
733
|
projectRoot: ctx.cwd,
|
|
816
734
|
harnesses: effectiveHarnesses,
|
|
817
|
-
track: effectiveTrack
|
|
818
|
-
profile: effectiveProfile
|
|
735
|
+
track: effectiveTrack
|
|
819
736
|
});
|
|
820
737
|
if (resolved.detectedHarnesses.length > 0 && parsed.harnesses === undefined) {
|
|
821
738
|
info(ctx, `Detected harnesses from repo: ${resolved.detectedHarnesses.join(", ")}`);
|
|
822
739
|
}
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
const suffix = profileNote || trackNote ? ` (${(profileNote + trackNote).trim()})` : "";
|
|
826
|
-
info(ctx, `Initialized .cclaw runtime and generated harness shims${suffix}`);
|
|
740
|
+
const trackNote = effectiveTrack ? ` (track=${effectiveTrack})` : "";
|
|
741
|
+
info(ctx, `Initialized .cclaw runtime and generated harness shims${trackNote}`);
|
|
827
742
|
return 0;
|
|
828
743
|
}
|
|
829
744
|
if (command === "sync") {
|
|
@@ -1043,4 +958,4 @@ function isDirectExecution() {
|
|
|
1043
958
|
if (isDirectExecution()) {
|
|
1044
959
|
void main();
|
|
1045
960
|
}
|
|
1046
|
-
export { parseArgs, parseHarnesses, parseTrack
|
|
961
|
+
export { parseArgs, parseHarnesses, parseTrack };
|
package/dist/config.d.ts
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import type { FlowTrack, HarnessId,
|
|
1
|
+
import type { FlowTrack, HarnessId, VibyConfig } from "./types.js";
|
|
2
2
|
export declare function configPath(projectRoot: string): string;
|
|
3
3
|
export declare function createDefaultConfig(harnesses?: HarnessId[], defaultTrack?: FlowTrack): VibyConfig;
|
|
4
|
-
/**
|
|
5
|
-
* Build a VibyConfig for a named init profile. Profile defaults are applied
|
|
6
|
-
* first, then any explicit overrides (CLI flags) win. This keeps the profile
|
|
7
|
-
* contract deterministic and testable.
|
|
8
|
-
*/
|
|
9
|
-
export declare function createProfileConfig(profile: InitProfile, overrides?: {
|
|
10
|
-
harnesses?: HarnessId[];
|
|
11
|
-
defaultTrack?: FlowTrack;
|
|
12
|
-
languageRulePacks?: LanguageRulePack[];
|
|
13
|
-
}): VibyConfig;
|
|
14
4
|
export declare function readConfig(projectRoot: string): Promise<VibyConfig>;
|
|
15
5
|
export declare function writeConfig(projectRoot: string, config: VibyConfig): Promise<void>;
|
package/dist/config.js
CHANGED
|
@@ -67,46 +67,6 @@ export function createDefaultConfig(harnesses = DEFAULT_HARNESSES, defaultTrack
|
|
|
67
67
|
languageRulePacks: []
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Build a VibyConfig for a named init profile. Profile defaults are applied
|
|
72
|
-
* first, then any explicit overrides (CLI flags) win. This keeps the profile
|
|
73
|
-
* contract deterministic and testable.
|
|
74
|
-
*/
|
|
75
|
-
export function createProfileConfig(profile, overrides = {}) {
|
|
76
|
-
const base = createDefaultConfig();
|
|
77
|
-
switch (profile) {
|
|
78
|
-
case "minimal":
|
|
79
|
-
return {
|
|
80
|
-
...base,
|
|
81
|
-
harnesses: overrides.harnesses ?? ["claude"],
|
|
82
|
-
promptGuardMode: "advisory",
|
|
83
|
-
tddEnforcement: "advisory",
|
|
84
|
-
gitHookGuards: false,
|
|
85
|
-
defaultTrack: overrides.defaultTrack ?? "medium",
|
|
86
|
-
languageRulePacks: overrides.languageRulePacks ?? []
|
|
87
|
-
};
|
|
88
|
-
case "standard":
|
|
89
|
-
return {
|
|
90
|
-
...base,
|
|
91
|
-
harnesses: overrides.harnesses ?? DEFAULT_HARNESSES,
|
|
92
|
-
promptGuardMode: "advisory",
|
|
93
|
-
tddEnforcement: "advisory",
|
|
94
|
-
gitHookGuards: false,
|
|
95
|
-
defaultTrack: overrides.defaultTrack ?? "standard",
|
|
96
|
-
languageRulePacks: overrides.languageRulePacks ?? []
|
|
97
|
-
};
|
|
98
|
-
case "full":
|
|
99
|
-
return {
|
|
100
|
-
...base,
|
|
101
|
-
harnesses: overrides.harnesses ?? DEFAULT_HARNESSES,
|
|
102
|
-
promptGuardMode: "strict",
|
|
103
|
-
tddEnforcement: "strict",
|
|
104
|
-
gitHookGuards: true,
|
|
105
|
-
defaultTrack: overrides.defaultTrack ?? "standard",
|
|
106
|
-
languageRulePacks: overrides.languageRulePacks ?? [...LANGUAGE_RULE_PACKS]
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
70
|
export async function readConfig(projectRoot) {
|
|
111
71
|
const fullPath = configPath(projectRoot);
|
|
112
72
|
if (!(await exists(fullPath))) {
|
package/dist/doctor.js
CHANGED
|
@@ -484,7 +484,6 @@ export async function doctorChecks(projectRoot, options = {}) {
|
|
|
484
484
|
const hasCcCommand = content.includes("/cc");
|
|
485
485
|
const hasCcNext = content.includes("/cc-next");
|
|
486
486
|
const hasCcIdeate = content.includes("/cc-ideate");
|
|
487
|
-
const hasCcLearn = content.includes("/cc-learn");
|
|
488
487
|
const hasCcView = content.includes("/cc-view");
|
|
489
488
|
const hasCcOps = content.includes("/cc-ops");
|
|
490
489
|
const hasVerification = content.includes("Verification Discipline");
|
|
@@ -494,7 +493,6 @@ export async function doctorChecks(projectRoot, options = {}) {
|
|
|
494
493
|
&& hasCcCommand
|
|
495
494
|
&& hasCcNext
|
|
496
495
|
&& hasCcIdeate
|
|
497
|
-
&& hasCcLearn
|
|
498
496
|
&& hasCcView
|
|
499
497
|
&& hasCcOps
|
|
500
498
|
&& hasVerification
|
package/dist/harness-adapters.js
CHANGED
|
@@ -30,12 +30,6 @@ const UTILITY_SHIMS = [
|
|
|
30
30
|
skillFolder: "flow-view",
|
|
31
31
|
commandFile: "view.md"
|
|
32
32
|
},
|
|
33
|
-
{
|
|
34
|
-
fileName: "cc-learn.md",
|
|
35
|
-
command: "learn",
|
|
36
|
-
skillFolder: "learnings",
|
|
37
|
-
commandFile: "learn.md"
|
|
38
|
-
},
|
|
39
33
|
{
|
|
40
34
|
fileName: "cc-ops.md",
|
|
41
35
|
command: "ops",
|
|
@@ -43,6 +37,13 @@ const UTILITY_SHIMS = [
|
|
|
43
37
|
commandFile: "ops.md"
|
|
44
38
|
}
|
|
45
39
|
];
|
|
40
|
+
/**
|
|
41
|
+
* Shims that older cclaw versions installed as top-level slash commands but
|
|
42
|
+
* which we now treat as internal (skill-only, invoked by the agent, never
|
|
43
|
+
* typed by users). On sync/upgrade we proactively delete any stale file from
|
|
44
|
+
* harness command directories so `/cc-learn` etc. do not linger.
|
|
45
|
+
*/
|
|
46
|
+
const LEGACY_HARNESS_SHIMS = ["cc-learn.md"];
|
|
46
47
|
export function harnessShimFileNames() {
|
|
47
48
|
return ["cc.md", ...UTILITY_SHIMS.map((shim) => shim.fileName)];
|
|
48
49
|
}
|
|
@@ -150,9 +151,11 @@ When in doubt, prefer **non-trivial** — the quick track is opt-in and only saf
|
|
|
150
151
|
| \`/cc-next\` | **Progression.** Advances to the next stage when current is complete. |
|
|
151
152
|
| \`/cc-ideate\` | **Discovery mode.** Generates a ranked repo-improvement backlog before implementation. |
|
|
152
153
|
| \`/cc-view\` | **Read-only router.** Unified entry for status/tree/diff views. |
|
|
153
|
-
| \`/cc-learn\` | **Cross-cutting.** Capture or review project knowledge (append-only JSONL). |
|
|
154
154
|
| \`/cc-ops\` | **Operations router.** Unified entry for feature/tdd-log/retro/compound/archive/rewind actions. |
|
|
155
155
|
|
|
156
|
+
Knowledge capture and curation run automatically as part of stage completion
|
|
157
|
+
protocols via the internal \`learnings\` skill — no user-facing command.
|
|
158
|
+
|
|
156
159
|
**Stage order:** brainstorm > scope > design > spec > plan > tdd > review > ship.
|
|
157
160
|
\`/cc-next\` loads the right stage skill automatically. Gates must pass before handoff.
|
|
158
161
|
|
|
@@ -263,6 +266,15 @@ export async function syncHarnessShims(projectRoot, harnesses) {
|
|
|
263
266
|
for (const shim of UTILITY_SHIMS) {
|
|
264
267
|
await writeFileSafe(path.join(commandDir, shim.fileName), utilityShimContent(harness, shim.command, shim.skillFolder, shim.commandFile));
|
|
265
268
|
}
|
|
269
|
+
for (const legacy of LEGACY_HARNESS_SHIMS) {
|
|
270
|
+
const legacyPath = path.join(commandDir, legacy);
|
|
271
|
+
try {
|
|
272
|
+
await fs.unlink(legacyPath);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
// fine — file may not exist (fresh install) or may be on read-only FS
|
|
276
|
+
}
|
|
277
|
+
}
|
|
266
278
|
}
|
|
267
279
|
await syncAgentFiles(projectRoot);
|
|
268
280
|
await syncAgentsMd(projectRoot, harnesses);
|
package/dist/install.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import type { FlowTrack, HarnessId
|
|
1
|
+
import type { FlowTrack, HarnessId } from "./types.js";
|
|
2
2
|
export interface InitOptions {
|
|
3
3
|
projectRoot: string;
|
|
4
4
|
harnesses?: HarnessId[];
|
|
5
5
|
track?: FlowTrack;
|
|
6
|
-
/** When set, pre-fills config defaults from the named profile before applying flag overrides. */
|
|
7
|
-
profile?: InitProfile;
|
|
8
6
|
}
|
|
9
7
|
export declare function initCclaw(options: InitOptions): Promise<void>;
|
|
10
8
|
export declare function syncCclaw(projectRoot: string): Promise<void>;
|
|
@@ -15,8 +13,8 @@ export declare function syncCclaw(projectRoot: string): Promise<void>;
|
|
|
15
13
|
* `promptGuardMode`, `tddEnforcement`, `gitHookGuards`, `languageRulePacks`,
|
|
16
14
|
* and `trackHeuristics` are preserved verbatim from the existing config.
|
|
17
15
|
*
|
|
18
|
-
* For an explicit reset
|
|
19
|
-
*
|
|
16
|
+
* For an explicit reset, run `cclaw-cli uninstall && cclaw-cli init`
|
|
17
|
+
* (after optionally archiving the current run via `/cc-ops archive`).
|
|
20
18
|
*/
|
|
21
19
|
export declare function upgradeCclaw(projectRoot: string): Promise<void>;
|
|
22
20
|
export declare function uninstallCclaw(projectRoot: string): Promise<void>;
|
package/dist/install.js
CHANGED
|
@@ -3,7 +3,7 @@ import fs from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { promisify } from "node:util";
|
|
5
5
|
import { CCLAW_VERSION, COMMAND_FILE_ORDER, FLOW_VERSION, REQUIRED_DIRS, RUNTIME_ROOT } from "./constants.js";
|
|
6
|
-
import { writeConfig, createDefaultConfig,
|
|
6
|
+
import { writeConfig, createDefaultConfig, readConfig, configPath } from "./config.js";
|
|
7
7
|
import { commandContract } from "./content/contracts.js";
|
|
8
8
|
import { contextModeFiles, createInitialContextModeState } from "./content/contexts.js";
|
|
9
9
|
import { learnSkillMarkdown, learnCommandContract } from "./content/learnings.js";
|
|
@@ -1088,12 +1088,7 @@ async function materializeRuntime(projectRoot, config, forceStateReset) {
|
|
|
1088
1088
|
await ensureGitignore(projectRoot);
|
|
1089
1089
|
}
|
|
1090
1090
|
export async function initCclaw(options) {
|
|
1091
|
-
const config = options.
|
|
1092
|
-
? createProfileConfig(options.profile, {
|
|
1093
|
-
harnesses: options.harnesses,
|
|
1094
|
-
defaultTrack: options.track
|
|
1095
|
-
})
|
|
1096
|
-
: createDefaultConfig(options.harnesses, options.track);
|
|
1091
|
+
const config = createDefaultConfig(options.harnesses, options.track);
|
|
1097
1092
|
await writeConfig(options.projectRoot, config);
|
|
1098
1093
|
await materializeRuntime(options.projectRoot, config, true);
|
|
1099
1094
|
}
|
|
@@ -1111,8 +1106,8 @@ export async function syncCclaw(projectRoot) {
|
|
|
1111
1106
|
* `promptGuardMode`, `tddEnforcement`, `gitHookGuards`, `languageRulePacks`,
|
|
1112
1107
|
* and `trackHeuristics` are preserved verbatim from the existing config.
|
|
1113
1108
|
*
|
|
1114
|
-
* For an explicit reset
|
|
1115
|
-
*
|
|
1109
|
+
* For an explicit reset, run `cclaw-cli uninstall && cclaw-cli init`
|
|
1110
|
+
* (after optionally archiving the current run via `/cc-ops archive`).
|
|
1116
1111
|
*/
|
|
1117
1112
|
export async function upgradeCclaw(projectRoot) {
|
|
1118
1113
|
const existing = await readConfig(projectRoot);
|
package/dist/types.d.ts
CHANGED
|
@@ -15,18 +15,6 @@ export type FlowTrack = (typeof FLOW_TRACKS)[number];
|
|
|
15
15
|
export declare const TRACK_STAGES: Record<FlowTrack, readonly FlowStage[]>;
|
|
16
16
|
export declare const HARNESS_IDS: readonly ["claude", "cursor", "opencode", "codex"];
|
|
17
17
|
export type HarnessId = (typeof HARNESS_IDS)[number];
|
|
18
|
-
/**
|
|
19
|
-
* Init profiles pre-fill `cclaw init` flags for common install shapes.
|
|
20
|
-
*
|
|
21
|
-
* - `minimal` — single-harness (claude), medium track default, no git hook guards. For solo
|
|
22
|
-
* contributors who still want brainstorm/spec/plan rigor without full scope+design overhead.
|
|
23
|
-
* - `standard` — default harness set, standard track, no git hook guards, advisory guards.
|
|
24
|
-
* Matches the pre-profile default behavior.
|
|
25
|
-
* - `full` — default harness set, standard track, git hook guards on, strict prompt guards.
|
|
26
|
-
* For teams that want every safety rail on.
|
|
27
|
-
*/
|
|
28
|
-
export declare const INIT_PROFILES: readonly ["minimal", "standard", "full"];
|
|
29
|
-
export type InitProfile = (typeof INIT_PROFILES)[number];
|
|
30
18
|
/**
|
|
31
19
|
* Opt-in language rule packs. When enabled in config, `cclaw sync` installs the
|
|
32
20
|
* corresponding utility skill so the meta-skill router can load language-specific
|
package/dist/types.js
CHANGED
|
@@ -25,17 +25,6 @@ export const TRACK_STAGES = {
|
|
|
25
25
|
quick: ["spec", "tdd", "review", "ship"]
|
|
26
26
|
};
|
|
27
27
|
export const HARNESS_IDS = ["claude", "cursor", "opencode", "codex"];
|
|
28
|
-
/**
|
|
29
|
-
* Init profiles pre-fill `cclaw init` flags for common install shapes.
|
|
30
|
-
*
|
|
31
|
-
* - `minimal` — single-harness (claude), medium track default, no git hook guards. For solo
|
|
32
|
-
* contributors who still want brainstorm/spec/plan rigor without full scope+design overhead.
|
|
33
|
-
* - `standard` — default harness set, standard track, no git hook guards, advisory guards.
|
|
34
|
-
* Matches the pre-profile default behavior.
|
|
35
|
-
* - `full` — default harness set, standard track, git hook guards on, strict prompt guards.
|
|
36
|
-
* For teams that want every safety rail on.
|
|
37
|
-
*/
|
|
38
|
-
export const INIT_PROFILES = ["minimal", "standard", "full"];
|
|
39
28
|
/**
|
|
40
29
|
* Opt-in language rule packs. When enabled in config, `cclaw sync` installs the
|
|
41
30
|
* corresponding utility skill so the meta-skill router can load language-specific
|