compound-agent 1.3.0 → 1.3.2

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/cli.js CHANGED
@@ -2,14 +2,14 @@
2
2
  import { Command } from 'commander';
3
3
  import { getLlama, resolveModelFile } from 'node-llama-cpp';
4
4
  import { mkdirSync, writeFileSync, statSync, unlinkSync, existsSync, readFileSync, copyFileSync, chmodSync, readdirSync } from 'fs';
5
- import { homedir } from 'os';
5
+ import { homedir, tmpdir } from 'os';
6
6
  import path, { join, dirname, resolve, relative } from 'path';
7
7
  import * as fs from 'fs/promises';
8
8
  import { readFile, mkdir, appendFile, writeFile, chmod, rm, rename, readdir } from 'fs/promises';
9
9
  import { createHash } from 'crypto';
10
10
  import { z } from 'zod';
11
11
  import { createRequire } from 'module';
12
- import { execSync, execFileSync } from 'child_process';
12
+ import { execSync, execFileSync, spawn } from 'child_process';
13
13
  import chalk from 'chalk';
14
14
 
15
15
  // src/cli-utils.ts
@@ -1135,6 +1135,171 @@ function registerCompoundCommands(program2) {
1135
1135
  var _require = createRequire(import.meta.url);
1136
1136
  var _pkg = _require("../package.json");
1137
1137
  var VERSION = _pkg.version;
1138
+ var SAMPLE_RATE = 22050;
1139
+ var BITS = 16;
1140
+ var MAX_AMP = 24576;
1141
+ var NOTE = {
1142
+ C3: 131,
1143
+ E3: 165,
1144
+ G3: 196,
1145
+ C4: 262,
1146
+ E4: 330,
1147
+ G4: 392,
1148
+ C5: 523,
1149
+ E5: 659,
1150
+ G5: 784,
1151
+ C6: 1047
1152
+ };
1153
+ function envelope(i, total, attack, release) {
1154
+ if (i < attack) return i / attack;
1155
+ if (i > total - release) return (total - i) / release;
1156
+ return 1;
1157
+ }
1158
+ function tone(freq, durationMs, amp = 1) {
1159
+ const samples = Math.floor(SAMPLE_RATE * durationMs / 1e3);
1160
+ const attack = Math.min(Math.floor(samples * 0.05), 200);
1161
+ const release = Math.min(Math.floor(samples * 0.15), 400);
1162
+ const out2 = [];
1163
+ for (let i = 0; i < samples; i++) {
1164
+ const env = envelope(i, samples, attack, release);
1165
+ out2.push(Math.sin(2 * Math.PI * freq * i / SAMPLE_RATE) * env * amp);
1166
+ }
1167
+ return out2;
1168
+ }
1169
+ function chord(freqs, durationMs, amp = 1) {
1170
+ const tones = freqs.map((f) => tone(f, durationMs, 1));
1171
+ const len = tones[0].length;
1172
+ const out2 = [];
1173
+ const scale = amp / freqs.length;
1174
+ for (let i = 0; i < len; i++) {
1175
+ let sum = 0;
1176
+ for (const t of tones) sum += t[i];
1177
+ out2.push(sum * scale);
1178
+ }
1179
+ return out2;
1180
+ }
1181
+ function silence(durationMs) {
1182
+ return new Array(Math.floor(SAMPLE_RATE * durationMs / 1e3)).fill(0);
1183
+ }
1184
+ function composeMelody() {
1185
+ const samples = [];
1186
+ samples.push(...tone(NOTE.C3, 250, 0.3));
1187
+ samples.push(...silence(150));
1188
+ samples.push(...tone(NOTE.C3, 250, 0.35));
1189
+ samples.push(...silence(100));
1190
+ samples.push(...tone(NOTE.E3, 200, 0.3));
1191
+ samples.push(...silence(80));
1192
+ samples.push(...tone(NOTE.C4, 140, 0.45));
1193
+ samples.push(...silence(30));
1194
+ samples.push(...tone(NOTE.E4, 140, 0.5));
1195
+ samples.push(...silence(30));
1196
+ samples.push(...tone(NOTE.G4, 140, 0.5));
1197
+ samples.push(...silence(30));
1198
+ samples.push(...tone(NOTE.C5, 160, 0.55));
1199
+ samples.push(...silence(30));
1200
+ samples.push(...tone(NOTE.E5, 160, 0.55));
1201
+ samples.push(...silence(30));
1202
+ samples.push(...tone(NOTE.G5, 180, 0.6));
1203
+ samples.push(...silence(60));
1204
+ samples.push(...tone(NOTE.C4, 100, 0.4));
1205
+ samples.push(...tone(NOTE.E4, 100, 0.45));
1206
+ samples.push(...tone(NOTE.G4, 100, 0.45));
1207
+ samples.push(...tone(NOTE.C5, 120, 0.5));
1208
+ samples.push(...tone(NOTE.E5, 120, 0.55));
1209
+ samples.push(...tone(NOTE.G5, 140, 0.6));
1210
+ samples.push(...silence(60));
1211
+ samples.push(...tone(NOTE.C6, 80, 0.3));
1212
+ samples.push(...silence(40));
1213
+ samples.push(...tone(NOTE.G5, 80, 0.35));
1214
+ samples.push(...silence(40));
1215
+ samples.push(...tone(NOTE.C6, 80, 0.3));
1216
+ samples.push(...silence(40));
1217
+ samples.push(...tone(NOTE.E5, 100, 0.35));
1218
+ samples.push(...silence(60));
1219
+ samples.push(...chord([NOTE.C4, NOTE.E4, NOTE.G4], 600, 0.7));
1220
+ samples.push(...chord([NOTE.C4, NOTE.E4, NOTE.G4, NOTE.C5], 500, 0.6));
1221
+ samples.push(...chord([NOTE.C3, NOTE.G3, NOTE.C4], 1200, 0.35));
1222
+ return samples;
1223
+ }
1224
+ function encodeWav(samples) {
1225
+ const dataSize = samples.length * (BITS / 8);
1226
+ const fileSize = 44 + dataSize;
1227
+ const buf = Buffer.alloc(fileSize);
1228
+ buf.write("RIFF", 0);
1229
+ buf.writeUInt32LE(fileSize - 8, 4);
1230
+ buf.write("WAVE", 8);
1231
+ buf.write("fmt ", 12);
1232
+ buf.writeUInt32LE(16, 16);
1233
+ buf.writeUInt16LE(1, 20);
1234
+ buf.writeUInt16LE(1, 22);
1235
+ buf.writeUInt32LE(SAMPLE_RATE, 24);
1236
+ buf.writeUInt32LE(SAMPLE_RATE * BITS / 8, 28);
1237
+ buf.writeUInt16LE(BITS / 8, 32);
1238
+ buf.writeUInt16LE(BITS, 34);
1239
+ buf.write("data", 36);
1240
+ buf.writeUInt32LE(dataSize, 40);
1241
+ let offset = 44;
1242
+ for (const s of samples) {
1243
+ const clamped = Math.max(-1, Math.min(1, s));
1244
+ buf.writeInt16LE(Math.round(clamped * MAX_AMP), offset);
1245
+ offset += 2;
1246
+ }
1247
+ return buf;
1248
+ }
1249
+ function spawnPlayer(filePath) {
1250
+ try {
1251
+ switch (process.platform) {
1252
+ case "darwin":
1253
+ return spawn("afplay", [filePath], { stdio: "ignore", detached: true });
1254
+ case "linux":
1255
+ return spawn("aplay", ["-q", filePath], { stdio: "ignore", detached: true });
1256
+ case "win32":
1257
+ return spawn("powershell", [
1258
+ "-c",
1259
+ `(New-Object Media.SoundPlayer '${filePath}').PlaySync()`
1260
+ ], { stdio: "ignore", detached: true });
1261
+ default:
1262
+ return null;
1263
+ }
1264
+ } catch {
1265
+ return null;
1266
+ }
1267
+ }
1268
+ function playBannerAudio() {
1269
+ try {
1270
+ const wav = encodeWav(composeMelody());
1271
+ const tmpPath = join(tmpdir(), `ca-banner-${process.pid}.wav`);
1272
+ writeFileSync(tmpPath, wav);
1273
+ const proc = spawnPlayer(tmpPath);
1274
+ if (!proc) {
1275
+ try {
1276
+ unlinkSync(tmpPath);
1277
+ } catch {
1278
+ }
1279
+ return null;
1280
+ }
1281
+ proc.unref();
1282
+ const cleanup2 = () => {
1283
+ try {
1284
+ proc.kill();
1285
+ } catch {
1286
+ }
1287
+ try {
1288
+ unlinkSync(tmpPath);
1289
+ } catch {
1290
+ }
1291
+ };
1292
+ proc.on("exit", () => {
1293
+ try {
1294
+ unlinkSync(tmpPath);
1295
+ } catch {
1296
+ }
1297
+ });
1298
+ return { stop: cleanup2 };
1299
+ } catch {
1300
+ return null;
1301
+ }
1302
+ }
1138
1303
 
1139
1304
  // src/setup/banner.ts
1140
1305
  var W = 62;
@@ -1316,6 +1481,7 @@ async function playInstallBanner() {
1316
1481
  const ps = [];
1317
1482
  const write = (s) => process.stdout.write(s);
1318
1483
  write("\x1B[?25l\x1B[2J\x1B[H");
1484
+ const audio = playBannerAudio();
1319
1485
  const restoreCursor = () => process.stdout.write("\x1B[?25h\x1B[0m");
1320
1486
  process.on("exit", restoreCursor);
1321
1487
  try {
@@ -1327,7 +1493,7 @@ async function playInstallBanner() {
1327
1493
  put(cvs, nx(CENTER), ny(CENTER), seedCh[f % 4], seedCo[f % 4]);
1328
1494
  write(flush(cvs));
1329
1495
  write(`
1330
- ${CO.DIM}Seed detected...${CO.VOID}
1496
+ ${CO.DIM}Seed detected...\x1B[K${CO.VOID}
1331
1497
  `);
1332
1498
  await sleep(60);
1333
1499
  }
@@ -1374,7 +1540,7 @@ async function playInstallBanner() {
1374
1540
  let active = 0;
1375
1541
  for (let i = 0; i < nc; i++) if (isGrown[i]) active++;
1376
1542
  write(`
1377
- \x1B[0;35mNodes \x1B[1;36m${active}\x1B[0;35m/${nc}\x1B[0m \x1B[0;90mGrowing neural tendrils...\x1B[0m
1543
+ \x1B[0;35mNodes \x1B[1;36m${active}\x1B[0;35m/${nc}\x1B[0m \x1B[0;90mGrowing neural tendrils...\x1B[K\x1B[0m
1378
1544
  `);
1379
1545
  await sleep(40);
1380
1546
  }
@@ -1397,7 +1563,7 @@ async function playInstallBanner() {
1397
1563
  renderParticles(cvs, ps, f);
1398
1564
  write(flush(cvs));
1399
1565
  write(`
1400
- ${CO.SETTLED}Crystallizing pathways...${CO.VOID}
1566
+ ${CO.SETTLED}Crystallizing pathways...\x1B[K${CO.VOID}
1401
1567
  `);
1402
1568
  await sleep(60);
1403
1569
  }
@@ -1473,6 +1639,7 @@ async function playInstallBanner() {
1473
1639
  await sleep(120);
1474
1640
  }
1475
1641
  } finally {
1642
+ audio?.stop();
1476
1643
  process.removeListener("exit", restoreCursor);
1477
1644
  restoreCursor();
1478
1645
  write("\n");
@@ -1489,6 +1656,30 @@ function checkBeadsAvailable() {
1489
1656
  };
1490
1657
  }
1491
1658
  }
1659
+ function checkBeadsInitialized(repoRoot) {
1660
+ return existsSync(join(repoRoot, ".beads"));
1661
+ }
1662
+ function checkBeadsHealthy(repoRoot) {
1663
+ try {
1664
+ execSync("bd doctor", { cwd: repoRoot, shell: "/bin/sh", stdio: "pipe", encoding: "utf-8" });
1665
+ return { healthy: true };
1666
+ } catch (e) {
1667
+ const msg = e instanceof Error && "stderr" in e ? String(e.stderr).trim() : "bd doctor failed";
1668
+ return { healthy: false, message: msg };
1669
+ }
1670
+ }
1671
+ function runFullBeadsCheck(repoRoot) {
1672
+ const cli = checkBeadsAvailable();
1673
+ if (!cli.available) {
1674
+ return { cliAvailable: false, initialized: false, healthy: false, healthMessage: cli.message };
1675
+ }
1676
+ const initialized = checkBeadsInitialized(repoRoot);
1677
+ if (!initialized) {
1678
+ return { cliAvailable: true, initialized: false, healthy: false };
1679
+ }
1680
+ const health = checkBeadsHealthy(repoRoot);
1681
+ return { cliAvailable: true, initialized: true, healthy: health.healthy, healthMessage: health.message };
1682
+ }
1492
1683
 
1493
1684
  // src/memory/capture/quality.ts
1494
1685
  var DEFAULT_SIMILARITY_THRESHOLD = 0.8;
@@ -2562,6 +2753,22 @@ function printPnpmConfigStatus(result) {
2562
2753
  console.log(` pnpm config: Added onlyBuiltDependencies [${result.added.join(", ")}]`);
2563
2754
  }
2564
2755
  }
2756
+ function printBeadsFullStatus(check) {
2757
+ console.log(` Beads CLI: ${check.cliAvailable ? "OK" : "not found"}`);
2758
+ if (check.cliAvailable) {
2759
+ console.log(` Beads repo: ${check.initialized ? "OK" : "not initialized (run: bd init)"}`);
2760
+ if (check.initialized) {
2761
+ console.log(` Beads health: ${check.healthy ? "OK" : `issues found${check.healthMessage ? ` \u2014 ${check.healthMessage}` : ""}`}`);
2762
+ }
2763
+ }
2764
+ }
2765
+ function printScopeStatus(scope) {
2766
+ if (scope.isUserScope) {
2767
+ console.log(" Scope: user-scope (reduced compounding value)");
2768
+ } else {
2769
+ console.log(" Scope: OK (repository scope)");
2770
+ }
2771
+ }
2565
2772
  async function runStatus(repoRoot) {
2566
2773
  const agentsDir = join(repoRoot, ".claude", "agents", "compound");
2567
2774
  const commandsDir = join(repoRoot, ".claude", "commands", "compound");
@@ -2580,12 +2787,10 @@ async function runStatus(repoRoot) {
2580
2787
  } catch {
2581
2788
  }
2582
2789
  console.log(` Hooks: ${hooksInstalled ? "installed" : "not installed"}`);
2583
- const beads = checkBeadsAvailable();
2584
- console.log(` Beads CLI: ${beads.available ? "available" : "not found"}`);
2790
+ const fullBeads = runFullBeadsCheck(repoRoot);
2791
+ printBeadsFullStatus(fullBeads);
2585
2792
  const scope = checkUserScope(repoRoot);
2586
- if (scope.isUserScope) {
2587
- console.log(" Scope: user-scope (reduced compounding value)");
2588
- }
2793
+ printScopeStatus(scope);
2589
2794
  }
2590
2795
  var REQUIRED_PATTERNS = ["node_modules/", ".claude/.cache/"];
2591
2796
  var SECTION_COMMENT = "# compound-agent";
@@ -4160,21 +4365,21 @@ npx ca prime
4160
4365
 
4161
4366
  // src/setup/templates/docs.ts
4162
4367
  var DOC_TEMPLATES = {
4163
- "HOW_TO_COMPOUND.md": `---
4368
+ "README.md": `---
4164
4369
  version: "{{VERSION}}"
4165
4370
  last-updated: "{{DATE}}"
4166
- summary: "Usage guide for compound-agent CLI, skills, and workflows"
4371
+ summary: "Overview and getting started guide for compound-agent"
4167
4372
  ---
4168
4373
 
4169
- # How to Compound
4374
+ # Compound Agent
4170
4375
 
4171
- A usage guide for humans and AI agents working with compound-agent -- the learning system that helps Claude Code avoid repeating mistakes across sessions.
4376
+ A learning system for Claude Code that captures, indexes, and retrieves lessons learned during development sessions -- so the same mistakes are not repeated.
4172
4377
 
4173
4378
  ---
4174
4379
 
4175
- ## 1. What is compound-agent
4380
+ ## What is compound-agent?
4176
4381
 
4177
- Compound-agent is a TypeScript CLI plugin for Claude Code that captures, indexes, and retrieves lessons learned during development sessions. When Claude makes a mistake and gets corrected, or discovers a useful pattern, that knowledge is stored as a **memory item** in \`.claude/lessons/index.jsonl\`. Future sessions search this memory before planning and implementing, so the same mistakes are not repeated.
4382
+ Compound-agent is a TypeScript CLI plugin for Claude Code. When Claude makes a mistake and gets corrected, or discovers a useful pattern, that knowledge is stored as a **memory item** in \`.claude/lessons/index.jsonl\`. Future sessions search this memory before planning and implementing.
4178
4383
 
4179
4384
  The system uses:
4180
4385
 
@@ -4183,17 +4388,21 @@ The system uses:
4183
4388
  - **Semantic embeddings** (EmbeddingGemma-300M via node-llama-cpp) for vector similarity search
4184
4389
  - **Claude Code hooks** to inject memory at session start, before compaction, and on tool failures
4185
4390
 
4186
- Memory items have four types: \`lesson\`, \`solution\`, \`pattern\`, and \`preference\`. Each has a trigger (what happened), an insight (what to do differently), tags, severity, and optional citations linking back to source code.
4391
+ Memory items have four types: \`lesson\`, \`solution\`, \`pattern\`, and \`preference\`. Each has a trigger, an insight, tags, severity, and optional citations.
4187
4392
 
4188
4393
  ---
4189
4394
 
4190
- ## 2. Installation
4191
-
4192
- ### Quick start
4395
+ ## Quick start
4193
4396
 
4194
4397
  \`\`\`bash
4195
- # In your project root:
4398
+ # Initialize in your project:
4196
4399
  npx ca init
4400
+
4401
+ # Full setup (includes embedding model download):
4402
+ npx ca setup
4403
+
4404
+ # Verify installation:
4405
+ npx ca doctor
4197
4406
  \`\`\`
4198
4407
 
4199
4408
  ### What \`init\` does
@@ -4202,31 +4411,16 @@ npx ca init
4202
4411
  2. Updates \`AGENTS.md\` with a compound-agent section
4203
4412
  3. Adds a reference to \`.claude/CLAUDE.md\`
4204
4413
  4. Creates \`.claude/plugin.json\` manifest
4205
- 5. Installs agent templates to \`.claude/agents/compound/\`
4206
- 6. Installs workflow slash commands to \`.claude/commands/compound/\`
4207
- 7. Installs phase skills to \`.claude/skills/compound/\`
4208
- 8. Installs agent role skills to \`.claude/skills/compound/agents/\`
4209
- 9. Installs a git pre-commit hook (lesson capture reminder)
4210
- 10. Installs Claude Code hooks (SessionStart, PreCompact, UserPromptSubmit, PostToolUseFailure, PostToolUse)
4211
- 11. For pnpm projects: auto-configures \`onlyBuiltDependencies\` for native addons
4212
-
4213
- ### Full setup (with embedding model)
4414
+ 5. Installs agent templates, workflow commands, phase skills, and agent role skills
4415
+ 6. Installs a git pre-commit hook (lesson capture reminder)
4416
+ 7. Installs Claude Code hooks (SessionStart, PreCompact, UserPromptSubmit, PostToolUseFailure, PostToolUse)
4417
+ 8. For pnpm projects: auto-configures \`onlyBuiltDependencies\` for native addons
4214
4418
 
4215
- \`\`\`bash
4216
- npx ca setup
4217
- \`\`\`
4419
+ \`setup\` does everything \`init\` does, plus downloads the EmbeddingGemma-300M model (~278MB). Use \`--skip-model\` to skip the download.
4218
4420
 
4219
- \`setup\` does everything \`init\` does, plus downloads the EmbeddingGemma-300M model (~278MB) for semantic search. Use \`--skip-model\` to skip the download.
4220
-
4221
- ### Verify installation
4222
-
4223
- \`\`\`bash
4224
- npx ca doctor
4225
- \`\`\`
4226
-
4227
- This checks for \`.claude/\` directory, lessons index, embedding model, Claude hooks, and beads (\`bd\`) availability.
4421
+ ---
4228
4422
 
4229
- ### Directory structure after install
4423
+ ## Directory structure
4230
4424
 
4231
4425
  \`\`\`
4232
4426
  .claude/
@@ -4245,29 +4439,57 @@ This checks for \`.claude/\` directory, lessons index, embedding model, Claude h
4245
4439
 
4246
4440
  ---
4247
4441
 
4248
- ## 3. The 5-phase workflow
4442
+ ## Quick reference
4443
+
4444
+ | Task | Command |
4445
+ |------|---------|
4446
+ | Capture a lesson | \`npx ca learn "insight" --trigger "what happened"\` |
4447
+ | Search memory | \`npx ca search "keywords"\` |
4448
+ | Check plan against memory | \`npx ca check-plan --plan "description"\` |
4449
+ | View stats | \`npx ca stats\` |
4450
+ | Run full workflow | \`/compound:lfg <epic-id>\` |
4451
+ | Health check | \`npx ca doctor\` |
4452
+
4453
+ ---
4454
+
4455
+ ## Further reading
4249
4456
 
4250
- Every feature or epic follows five phases:
4457
+ - [WORKFLOW.md](WORKFLOW.md) -- The 5-phase development workflow and LFG orchestrator
4458
+ - [CLI_REFERENCE.md](CLI_REFERENCE.md) -- Complete CLI command reference
4459
+ - [SKILLS.md](SKILLS.md) -- Phase skills and agent role skills
4460
+ - [INTEGRATION.md](INTEGRATION.md) -- Memory system, hooks, beads, and agent guidance
4461
+ `,
4462
+ "WORKFLOW.md": `---
4463
+ version: "{{VERSION}}"
4464
+ last-updated: "{{DATE}}"
4465
+ summary: "The 5-phase compound-agent workflow and LFG orchestrator"
4466
+ ---
4467
+
4468
+ # Workflow
4469
+
4470
+ Every feature or epic follows five phases. The \`/compound:lfg\` skill chains them with enforcement gates.
4251
4471
 
4252
- ### Phase 1: Brainstorm
4472
+ ---
4473
+
4474
+ ## Phase 1: Brainstorm
4253
4475
 
4254
- Explore the problem space before committing to a solution. Produce a structured brainstorm document with decisions, open questions, and a beads epic.
4476
+ Explore the problem space before committing to a solution.
4255
4477
 
4256
4478
  - Ask "why" before "how"
4257
4479
  - Search memory for similar past features
4258
4480
  - Generate multiple approaches, then converge
4259
4481
  - Create a beads epic: \`bd create --title="..." --type=epic\`
4260
4482
 
4261
- ### Phase 2: Plan
4483
+ ## Phase 2: Plan
4262
4484
 
4263
- Decompose work into small, testable tasks with dependencies and acceptance criteria.
4485
+ Decompose work into small, testable tasks with dependencies.
4264
4486
 
4265
4487
  - Review brainstorm output
4266
4488
  - Create beads tasks: \`bd create --title="..." --type=task\`
4267
4489
  - Create Review and Compound blocking tasks (these survive compaction)
4268
4490
  - Run \`npx ca worktree wire-deps <epic-id>\` if using worktrees
4269
4491
 
4270
- ### Phase 3: Work
4492
+ ## Phase 3: Work
4271
4493
 
4272
4494
  Execute implementation through agent teams using TDD.
4273
4495
 
@@ -4276,7 +4498,7 @@ Execute implementation through agent teams using TDD.
4276
4498
  - Commit incrementally as tests pass
4277
4499
  - Run \`/implementation-reviewer\` before closing tasks
4278
4500
 
4279
- ### Phase 4: Review
4501
+ ## Phase 4: Review
4280
4502
 
4281
4503
  Multi-agent code review with severity classification.
4282
4504
 
@@ -4285,7 +4507,7 @@ Multi-agent code review with severity classification.
4285
4507
  - Classify findings as P1/P2/P3
4286
4508
  - Fix all P1 findings before proceeding
4287
4509
 
4288
- ### Phase 5: Compound
4510
+ ## Phase 5: Compound
4289
4511
 
4290
4512
  Extract and store lessons learned. This is what makes the system compound.
4291
4513
 
@@ -4296,14 +4518,85 @@ Extract and store lessons learned. This is what makes the system compound.
4296
4518
 
4297
4519
  ---
4298
4520
 
4299
- ## 4. CLI reference
4521
+ ## LFG orchestrator
4522
+
4523
+ \`/compound:lfg\` chains all 5 phases with enforcement gates.
4524
+
4525
+ ### Invocation
4526
+
4527
+ \`\`\`
4528
+ /compound:lfg <epic-id>
4529
+ /compound:lfg <epic-id> from plan
4530
+ \`\`\`
4531
+
4532
+ ### Phase execution protocol
4533
+
4534
+ For each phase, LFG:
4535
+
4536
+ 1. Announces progress: \`[Phase N/5] PHASE_NAME\`
4537
+ 2. Initializes state: \`npx ca phase-check start <phase>\`
4538
+ 3. Reads the phase skill file (non-negotiable -- never from memory)
4539
+ 4. Runs \`npx ca search\` with the current goal
4540
+ 5. Executes the phase following skill instructions
4541
+ 6. Updates epic notes: \`bd update <epic-id> --notes="Phase: NAME COMPLETE | Next: NEXT"\`
4542
+ 7. Verifies the phase gate before proceeding
4543
+
4544
+ ### Phase gates
4545
+
4546
+ | Gate | When | Verification |
4547
+ |------|------|-------------|
4548
+ | Post-plan | After Plan | \`bd list --status=open\` shows Review + Compound tasks |
4549
+ | Gate 3 | After Work | \`bd list --status=in_progress\` returns empty |
4550
+ | Gate 4 | After Review | \`/implementation-reviewer\` returned APPROVED |
4551
+ | Final | After Compound | \`npx ca verify-gates <epic-id>\` passes, \`pnpm test\` and \`pnpm lint\` pass |
4552
+
4553
+ If any gate fails, LFG stops. You must fix the issue before proceeding.
4554
+
4555
+ ### Resumption
4556
+
4557
+ If interrupted, LFG can resume:
4558
+
4559
+ 1. Run \`bd show <epic-id>\` and read the notes for phase state
4560
+ 2. Re-invoke with \`from <phase>\` to skip completed phases
4561
+
4562
+ ### Phase state tracking
4563
+
4564
+ LFG persists state in \`.claude/.ca-phase-state.json\`. Useful commands:
4565
+
4566
+ \`\`\`bash
4567
+ npx ca phase-check status # See current phase state
4568
+ npx ca phase-check clean # Reset phase state (escape hatch)
4569
+ \`\`\`
4570
+
4571
+ ### Session close
4572
+
4573
+ Before saying "done", LFG runs this inviolable checklist:
4574
+
4575
+ \`\`\`bash
4576
+ git status
4577
+ git add <files>
4578
+ bd sync
4579
+ git commit -m "..."
4580
+ bd sync
4581
+ git push
4582
+ \`\`\`
4583
+ `,
4584
+ "CLI_REFERENCE.md": `---
4585
+ version: "{{VERSION}}"
4586
+ last-updated: "{{DATE}}"
4587
+ summary: "Complete CLI command reference for compound-agent"
4588
+ ---
4589
+
4590
+ # CLI Reference
4300
4591
 
4301
4592
  All commands use \`npx ca\` (or \`npx compound-agent\`). Global flags: \`-v, --verbose\` and \`-q, --quiet\`.
4302
4593
 
4303
- ### Capture commands
4594
+ ---
4595
+
4596
+ ## Capture commands
4304
4597
 
4305
4598
  \`\`\`bash
4306
- # Capture a lesson (primary command for storing knowledge)
4599
+ # Capture a lesson (primary command)
4307
4600
  npx ca learn "Always validate epic IDs before shell execution" \\
4308
4601
  --trigger "Shell injection via bd show" \\
4309
4602
  --tags "security,validation" \\
@@ -4311,7 +4604,7 @@ npx ca learn "Always validate epic IDs before shell execution" \\
4311
4604
  --type lesson
4312
4605
 
4313
4606
  # Capture a pattern (requires --pattern-bad and --pattern-good)
4314
- npx ca learn "Use execFileSync instead of execSync for external commands" \\
4607
+ npx ca learn "Use execFileSync instead of execSync" \\
4315
4608
  --type pattern \\
4316
4609
  --pattern-bad "execSync(\\\`bd show \\\${id}\\\`)" \\
4317
4610
  --pattern-good "execFileSync('bd', ['show', id])"
@@ -4327,68 +4620,44 @@ npx ca detect --input corrections.json --save --yes
4327
4620
  **Types**: \`lesson\` (default), \`solution\`, \`pattern\`, \`preference\`
4328
4621
  **Severity**: \`high\`, \`medium\`, \`low\`
4329
4622
 
4330
- ### Retrieval commands
4623
+ ## Retrieval commands
4331
4624
 
4332
4625
  \`\`\`bash
4333
- # Keyword search
4334
- npx ca search "sqlite validation"
4626
+ npx ca search "sqlite validation" # Keyword search
4335
4627
  npx ca search "security" --limit 5
4336
-
4337
- # List all memory items
4338
- npx ca list
4628
+ npx ca list # List all memory items
4339
4629
  npx ca list --limit 20
4340
- npx ca list --invalidated # Show only invalidated items
4341
-
4342
- # Semantic search against a plan
4630
+ npx ca list --invalidated # Show only invalidated items
4343
4631
  npx ca check-plan --plan "Implement git worktree integration"
4344
- echo "Add caching layer" | npx ca check-plan
4345
-
4346
- # Load high-severity lessons for session context
4347
- npx ca load-session
4632
+ echo "Add caching layer" | npx ca check-plan # Semantic search against a plan
4633
+ npx ca load-session # Load high-severity lessons
4348
4634
  npx ca load-session --json
4349
4635
  \`\`\`
4350
4636
 
4351
- ### Management commands
4637
+ ## Management commands
4352
4638
 
4353
4639
  \`\`\`bash
4354
- # View a specific item
4355
- npx ca show <id>
4640
+ npx ca show <id> # View a specific item
4356
4641
  npx ca show <id> --json
4357
-
4358
- # Update item fields
4359
- npx ca update <id> --insight "Updated insight text"
4642
+ npx ca update <id> --insight "Updated text" # Update item fields
4360
4643
  npx ca update <id> --severity high --tags "security,input-validation"
4361
-
4362
- # Soft delete (creates tombstone)
4363
- npx ca delete <id>
4644
+ npx ca delete <id> # Soft delete (creates tombstone)
4364
4645
  npx ca delete <id1> <id2> <id3>
4365
-
4366
- # Mark as invalid (excluded from retrieval but preserved)
4367
- npx ca wrong <id> --reason "This advice was incorrect"
4368
-
4369
- # Re-enable an invalidated item
4370
- npx ca validate <id>
4371
-
4372
- # Export as JSON
4373
- npx ca export
4646
+ npx ca wrong <id> --reason "Incorrect" # Mark as invalid
4647
+ npx ca validate <id> # Re-enable an invalidated item
4648
+ npx ca export # Export as JSON
4374
4649
  npx ca export --since 2026-01-01 --tags "security"
4375
-
4376
- # Import from JSONL file
4377
- npx ca import lessons-backup.jsonl
4378
-
4379
- # Database maintenance
4380
- npx ca compact # Remove tombstones and archive old items
4381
- npx ca compact --dry-run # Preview without changes
4382
- npx ca compact --force # Compact even if below threshold
4383
- npx ca rebuild # Rebuild SQLite index from JSONL
4384
- npx ca rebuild --force # Force rebuild even if unchanged
4385
- npx ca stats # Show database health and statistics
4386
-
4387
- # Context recovery
4388
- npx ca prime # Reload workflow context after compaction
4650
+ npx ca import lessons-backup.jsonl # Import from JSONL file
4651
+ npx ca compact # Remove tombstones and archive old items
4652
+ npx ca compact --dry-run
4653
+ npx ca compact --force
4654
+ npx ca rebuild # Rebuild SQLite index from JSONL
4655
+ npx ca rebuild --force
4656
+ npx ca stats # Show database health and statistics
4657
+ npx ca prime # Reload workflow context after compaction
4389
4658
  \`\`\`
4390
4659
 
4391
- ### Setup commands
4660
+ ## Setup commands
4392
4661
 
4393
4662
  \`\`\`bash
4394
4663
  npx ca init # Initialize in current repo
@@ -4396,21 +4665,18 @@ npx ca init --skip-agents # Skip AGENTS.md and template installation
4396
4665
  npx ca init --skip-hooks # Skip git hook installation
4397
4666
  npx ca init --skip-claude # Skip Claude Code hooks
4398
4667
  npx ca init --json # Output result as JSON
4399
-
4400
4668
  npx ca setup # Full setup (init + model download)
4401
4669
  npx ca setup --update # Regenerate templates (preserves user files)
4402
4670
  npx ca setup --uninstall # Remove compound-agent integration
4403
4671
  npx ca setup --status # Show installation status
4404
4672
  npx ca setup --skip-model # Skip embedding model download
4405
-
4406
4673
  npx ca setup claude # Install Claude Code hooks only
4407
4674
  npx ca setup claude --status # Check hook status
4408
-
4409
4675
  npx ca hooks # Install git hooks
4410
4676
  npx ca download-model # Download embedding model (~278MB)
4411
4677
  \`\`\`
4412
4678
 
4413
- ### Reviewer commands
4679
+ ## Reviewer commands
4414
4680
 
4415
4681
  \`\`\`bash
4416
4682
  npx ca reviewer enable gemini # Enable Gemini as external reviewer
@@ -4419,11 +4685,10 @@ npx ca reviewer disable gemini # Disable a reviewer
4419
4685
  npx ca reviewer list # List enabled reviewers
4420
4686
  \`\`\`
4421
4687
 
4422
- ### Loop command
4688
+ ## Loop command
4423
4689
 
4424
4690
  \`\`\`bash
4425
- # Generate an infinity loop script for autonomous epic processing
4426
- npx ca loop
4691
+ npx ca loop # Generate infinity loop script for autonomous processing
4427
4692
  npx ca loop --epics epic-1 epic-2
4428
4693
  npx ca loop --output my-loop.sh
4429
4694
  npx ca loop --max-retries 5
@@ -4431,22 +4696,15 @@ npx ca loop --model claude-opus-4-6
4431
4696
  npx ca loop --force # Overwrite existing script
4432
4697
  \`\`\`
4433
4698
 
4434
- ### Health and audit commands
4699
+ ## Health, audit, and verification commands
4435
4700
 
4436
4701
  \`\`\`bash
4702
+ npx ca about # Show version, animation, and recent changelog
4437
4703
  npx ca doctor # Check external dependencies and project health
4438
4704
  npx ca audit # Run pattern, rule, and lesson quality checks
4439
4705
  npx ca rules check # Check codebase against .claude/rules.json
4440
4706
  npx ca test-summary # Run tests and output compact pass/fail summary
4441
- \`\`\`
4442
-
4443
- ### Verification commands
4444
-
4445
- \`\`\`bash
4446
- # Verify workflow gates before epic closure
4447
- npx ca verify-gates <epic-id>
4448
-
4449
- # Phase state management (used by LFG workflow)
4707
+ npx ca verify-gates <epic-id> # Verify workflow gates before epic closure
4450
4708
  npx ca phase-check init <epic-id>
4451
4709
  npx ca phase-check status
4452
4710
  npx ca phase-check start <phase>
@@ -4454,39 +4712,37 @@ npx ca phase-check gate <gate-name> # post-plan, gate-3, gate-4, final
4454
4712
  npx ca phase-check clean
4455
4713
  \`\`\`
4456
4714
 
4457
- ### Worktree commands
4715
+ ## Worktree commands
4458
4716
 
4459
4717
  \`\`\`bash
4460
- # Create an isolated worktree for an epic
4461
- npx ca worktree create <epic-id>
4462
-
4463
- # Connect merge dependencies
4464
- npx ca worktree wire-deps <epic-id>
4465
-
4466
- # Merge worktree back to main (two-phase: resolve in worktree, land on main)
4467
- npx ca worktree merge <epic-id>
4468
-
4469
- # List active worktrees
4470
- npx ca worktree list
4471
-
4472
- # Remove worktree and clean up
4473
- npx ca worktree cleanup <epic-id>
4474
- npx ca worktree cleanup <epic-id> --force # Force cleanup of dirty worktrees
4718
+ npx ca worktree create <epic-id> # Create isolated worktree
4719
+ npx ca worktree wire-deps <epic-id> # Connect merge dependencies
4720
+ npx ca worktree merge <epic-id> # Merge worktree back to main
4721
+ npx ca worktree list # List active worktrees
4722
+ npx ca worktree cleanup <epic-id> # Remove worktree and clean up
4723
+ npx ca worktree cleanup <epic-id> --force # Force cleanup of dirty worktrees
4475
4724
  \`\`\`
4476
4725
 
4477
- ### Compound command
4726
+ ## Compound command
4478
4727
 
4479
4728
  \`\`\`bash
4480
- # Synthesize cross-cutting patterns from accumulated lessons
4481
- npx ca compound
4729
+ npx ca compound # Synthesize cross-cutting patterns from accumulated lessons
4482
4730
  \`\`\`
4483
-
4731
+ `,
4732
+ "SKILLS.md": `---
4733
+ version: "{{VERSION}}"
4734
+ last-updated: "{{DATE}}"
4735
+ summary: "Phase skills and agent role skills reference"
4484
4736
  ---
4485
4737
 
4486
- ## 5. Skills reference
4738
+ # Skills Reference
4487
4739
 
4488
4740
  Skills are instructions that Claude reads before executing each phase. They live in \`.claude/skills/compound/\` and are auto-installed by \`npx ca setup\`.
4489
4741
 
4742
+ ---
4743
+
4744
+ ## Phase skills
4745
+
4490
4746
  ### \`/compound:brainstorm\`
4491
4747
 
4492
4748
  **Purpose**: Divergent-then-convergent thinking to explore the solution space.
@@ -4533,7 +4789,7 @@ Skills are instructions that Claude reads before executing each phase. They live
4533
4789
 
4534
4790
  **When invoked**: When you want to run an entire epic end-to-end.
4535
4791
 
4536
- **What it does**: Sequences all 5 phases with mandatory gates between them, tracks progress in beads notes, handles resumption after interruption.
4792
+ **What it does**: Sequences all 5 phases with mandatory gates between them, tracks progress in beads notes, handles resumption after interruption. See [WORKFLOW.md](WORKFLOW.md) for full details.
4537
4793
 
4538
4794
  ### \`/compound:set-worktree\`
4539
4795
 
@@ -4545,150 +4801,42 @@ Skills are instructions that Claude reads before executing each phase. They live
4545
4801
 
4546
4802
  ---
4547
4803
 
4548
- ## 6. The LFG workflow
4549
-
4550
- \`/compound:lfg\` chains all 5 phases with enforcement gates. Here is how it works:
4551
-
4552
- ### Invocation
4553
-
4554
- \`\`\`
4555
- /compound:lfg <epic-id>
4556
- \`\`\`
4557
-
4558
- Or with a phase skip:
4559
-
4560
- \`\`\`
4561
- /compound:lfg <epic-id> from plan
4562
- \`\`\`
4563
-
4564
- ### Phase execution protocol
4565
-
4566
- For each phase, LFG:
4567
-
4568
- 1. Announces progress: \`[Phase N/5] PHASE_NAME\`
4569
- 2. Initializes state: \`npx ca phase-check start <phase>\`
4570
- 3. Reads the phase skill file (non-negotiable -- never from memory)
4571
- 4. Runs \`npx ca search\` with the current goal
4572
- 5. Executes the phase following skill instructions
4573
- 6. Updates epic notes: \`bd update <epic-id> --notes="Phase: NAME COMPLETE | Next: NEXT"\`
4574
- 7. Verifies the phase gate before proceeding
4575
-
4576
- ### Phase gates
4577
-
4578
- | Gate | When | Verification |
4579
- |------|------|-------------|
4580
- | Post-plan | After Plan | \`bd list --status=open\` shows Review + Compound tasks |
4581
- | Gate 3 | After Work | \`bd list --status=in_progress\` returns empty |
4582
- | Gate 4 | After Review | \`/implementation-reviewer\` returned APPROVED |
4583
- | Final | After Compound | \`npx ca verify-gates <epic-id>\` passes, \`pnpm test\` and \`pnpm lint\` pass |
4584
-
4585
- If any gate fails, LFG stops. You must fix the issue before proceeding.
4586
-
4587
- ### Resumption
4588
-
4589
- If interrupted, LFG can resume:
4804
+ ## Skill invocation
4590
4805
 
4591
- 1. Run \`bd show <epic-id>\` and read the notes for phase state
4592
- 2. Re-invoke with \`from <phase>\` to skip completed phases
4806
+ Skills are invoked as Claude Code slash commands:
4593
4807
 
4594
- ### Phase state tracking
4595
-
4596
- LFG persists state in \`.claude/.ca-phase-state.json\`. Useful commands:
4597
-
4598
- \`\`\`bash
4599
- npx ca phase-check status # See current phase state
4600
- npx ca phase-check clean # Reset phase state (escape hatch)
4601
4808
  \`\`\`
4602
-
4603
- ### Session close
4604
-
4605
- Before saying "done", LFG runs this inviolable checklist:
4606
-
4607
- \`\`\`bash
4608
- git status
4609
- git add <files>
4610
- bd sync
4611
- git commit -m "..."
4612
- bd sync
4613
- git push
4809
+ /compound:brainstorm # Start brainstorm phase
4810
+ /compound:plan # Start plan phase
4811
+ /compound:work # Start work phase
4812
+ /compound:review # Start review phase
4813
+ /compound:compound # Start compound phase
4814
+ /compound:lfg <epic-id> # Run all phases end-to-end
4815
+ /compound:set-worktree <epic-id> # Set up worktree before LFG
4614
4816
  \`\`\`
4615
4817
 
4818
+ Each skill reads its SKILL.md file from \`.claude/skills/compound/<phase>/SKILL.md\` at invocation time. Skills are never executed from memory.
4819
+ `,
4820
+ "INTEGRATION.md": `---
4821
+ version: "{{VERSION}}"
4822
+ last-updated: "{{DATE}}"
4823
+ summary: "Memory system, hooks, beads integration, and agent guidance"
4616
4824
  ---
4617
4825
 
4618
- ## 7. Worktree integration
4619
-
4620
- Worktrees let you run epics in isolation, enabling parallel execution across multiple Claude Code sessions.
4621
-
4622
- ### Creating a worktree
4623
-
4624
- \`\`\`bash
4625
- npx ca worktree create <epic-id>
4626
- \`\`\`
4627
-
4628
- This:
4629
-
4630
- 1. Creates a git worktree at \`../<repo>-wt-<epic-id>\` on branch \`epic/<epic-id>\`
4631
- 2. Installs dependencies via \`pnpm install --frozen-lockfile\`
4632
- 3. Copies \`.claude/lessons/index.jsonl\` to the worktree
4633
- 4. Runs \`npx ca setup --skip-model\` in the worktree
4634
- 5. Creates a Merge beads task linked to the epic
4635
-
4636
- ### Using with LFG
4637
-
4638
- \`\`\`bash
4639
- # From main repo:
4640
- npx ca worktree create my-epic-id
4641
-
4642
- # Then in the worktree directory:
4643
- # Run /compound:lfg or /compound:set-worktree followed by /compound:lfg
4644
- \`\`\`
4645
-
4646
- Or use the skill:
4647
-
4648
- \`\`\`
4649
- /compound:set-worktree <epic-id>
4650
- \`\`\`
4651
-
4652
- ### Merging back
4653
-
4654
- When all work tasks complete, the Merge task surfaces via \`bd ready\`:
4655
-
4656
- \`\`\`bash
4657
- npx ca worktree merge <epic-id>
4658
- \`\`\`
4659
-
4660
- This runs a two-phase merge:
4661
-
4662
- 1. Merges \`main\` into the worktree branch (resolve conflicts there)
4663
- 2. Fast-forwards \`main\` to the worktree branch (clean landing)
4826
+ # Integration
4664
4827
 
4665
- ### Cleanup
4666
-
4667
- \`\`\`bash
4668
- npx ca worktree cleanup <epic-id>
4669
- npx ca worktree cleanup <epic-id> --force # For dirty worktrees
4670
- \`\`\`
4671
-
4672
- This removes the worktree directory, deletes the branch, and closes the Merge task.
4673
-
4674
- ### Listing worktrees
4675
-
4676
- \`\`\`bash
4677
- npx ca worktree list
4678
- \`\`\`
4679
-
4680
- Shows active worktrees with their epic and merge task status.
4828
+ Deep integration topics for compound-agent: memory system internals, Claude Code hooks, beads workflow, worktree integration, and agent guidance.
4681
4829
 
4682
4830
  ---
4683
4831
 
4684
- ## 8. Memory system
4832
+ ## Memory system
4685
4833
 
4686
4834
  ### Storage format
4687
4835
 
4688
4836
  Memory items are stored as newline-delimited JSON in \`.claude/lessons/index.jsonl\`. Each line is a complete JSON object:
4689
4837
 
4690
4838
  \`\`\`json
4691
- {"id":"L-abc123","type":"lesson","trigger":"Shell injection via execSync","insight":"Use execFileSync with array args to prevent shell interpretation","tags":["security"],"source":"manual","context":{"tool":"cli","intent":"manual learning"},"created":"2026-02-15T10:00:00Z","confirmed":true,"severity":"high","supersedes":[],"related":[]}
4839
+ {"id":"L-abc123","type":"lesson","trigger":"Shell injection via execSync","insight":"Use execFileSync with array args","tags":["security"],"source":"manual","context":{"tool":"cli","intent":"manual learning"},"created":"2026-02-15T10:00:00Z","confirmed":true,"severity":"high","supersedes":[],"related":[]}
4692
4840
  \`\`\`
4693
4841
 
4694
4842
  ### Indexing
@@ -4709,14 +4857,6 @@ The index is rebuilt automatically when the JSONL changes. Force rebuild with \`
4709
4857
 
4710
4858
  **Session loading** (\`npx ca load-session\`): Returns high-severity confirmed lessons for injection at session start.
4711
4859
 
4712
- ### Compounding (pattern synthesis)
4713
-
4714
- \`\`\`bash
4715
- npx ca compound
4716
- \`\`\`
4717
-
4718
- This reads all memory items, computes embeddings, clusters them by similarity, and synthesizes cross-cutting patterns into \`.claude/lessons/cct-patterns.jsonl\`. Clusters with 2+ items become patterns; single-item clusters are filtered as noise.
4719
-
4720
4860
  ### Data lifecycle
4721
4861
 
4722
4862
  | Operation | Effect |
@@ -4729,21 +4869,7 @@ This reads all memory items, computes embeddings, clusters them by similarity, a
4729
4869
 
4730
4870
  ---
4731
4871
 
4732
- ## 9. For AI agents
4733
-
4734
- ### Integrating into CLAUDE.md
4735
-
4736
- Add a reference to compound-agent in your project's \`.claude/CLAUDE.md\`:
4737
-
4738
- \`\`\`markdown
4739
- ## References
4740
-
4741
- - docs/compound/HOW_TO_COMPOUND.md -- Usage guide for humans and AI agents
4742
- \`\`\`
4743
-
4744
- The \`npx ca init\` command does this automatically.
4745
-
4746
- ### Claude Code hooks
4872
+ ## Claude Code hooks
4747
4873
 
4748
4874
  Compound-agent installs five hooks into \`.claude/settings.json\`:
4749
4875
 
@@ -4751,7 +4877,7 @@ Compound-agent installs five hooks into \`.claude/settings.json\`:
4751
4877
  |------|---------|--------|
4752
4878
  | **SessionStart** | New session or resume | Runs \`npx ca prime\` to load workflow context and high-severity lessons |
4753
4879
  | **PreCompact** | Before context compaction | Runs \`npx ca prime\` to preserve context across compaction |
4754
- | **UserPromptSubmit** | Every user message | Detects correction language ("actually", "wrong") and planning language ("implement", "build"), injects memory reminders |
4880
+ | **UserPromptSubmit** | Every user message | Detects correction/planning language, injects memory reminders |
4755
4881
  | **PostToolUseFailure** | Bash/Edit/Write failures | After 2 failures on same file or 3 total, suggests \`npx ca search\` |
4756
4882
  | **PostToolUse** | After successful tool use | Resets failure tracking; tracks skill file reads for phase guard |
4757
4883
 
@@ -4778,7 +4904,9 @@ npx ca learn "The insight" --trigger "What happened" --severity medium
4778
4904
  npx ca compound
4779
4905
  \`\`\`
4780
4906
 
4781
- ### Beads workflow integration
4907
+ ---
4908
+
4909
+ ## Beads integration
4782
4910
 
4783
4911
  Compound-agent works with beads (\`bd\`) for issue tracking:
4784
4912
 
@@ -4801,11 +4929,38 @@ Before closing an epic, verify all gates pass:
4801
4929
  npx ca verify-gates <epic-id>
4802
4930
  \`\`\`
4803
4931
 
4804
- This checks that:
4932
+ This checks that a Review task, Compound task, and (if applicable) Merge task all exist and are closed.
4933
+
4934
+ ---
4935
+
4936
+ ## Worktree integration
4937
+
4938
+ Worktrees let you run epics in isolation, enabling parallel execution across multiple Claude Code sessions.
4939
+
4940
+ \`\`\`bash
4941
+ npx ca worktree create <epic-id> # Creates worktree + installs deps + copies lessons
4942
+ npx ca worktree merge <epic-id> # Two-phase merge back to main
4943
+ npx ca worktree cleanup <epic-id> # Remove worktree, delete branch, close Merge task
4944
+ npx ca worktree list # Show active worktrees
4945
+ \`\`\`
4946
+
4947
+ See [CLI_REFERENCE.md](CLI_REFERENCE.md) for full worktree command details.
4948
+
4949
+ ---
4950
+
4951
+ ## For AI agents
4952
+
4953
+ ### Integrating into CLAUDE.md
4805
4954
 
4806
- 1. A Review task exists and is closed
4807
- 2. A Compound task exists and is closed
4808
- 3. If a Merge task exists (worktree epic), it is also closed
4955
+ Add a reference to compound-agent in your project's \`.claude/CLAUDE.md\`:
4956
+
4957
+ \`\`\`markdown
4958
+ ## References
4959
+
4960
+ - docs/compound/README.md -- Compound-agent overview and getting started
4961
+ \`\`\`
4962
+
4963
+ The \`npx ca init\` command does this automatically.
4809
4964
 
4810
4965
  ### Session completion checklist
4811
4966
 
@@ -5386,12 +5541,18 @@ Synthesize analysis results into a refined optimization plan:
5386
5541
  - Estimate impact on test suite speed and coverage
5387
5542
  - Iterate with subagents until the plan is comprehensive
5388
5543
 
5389
- ### Phase 3: Adversarial Review
5544
+ ### Phase 3: Adversarial Review (CRITICAL QUALITY GATE)
5545
+ **This is THE KEY PHASE -- the most important phase in the entire workflow. NEVER skip, NEVER rush, NEVER settle for "good enough."**
5546
+
5390
5547
  Expose the plan to two neutral reviewer subagents:
5391
5548
  - **Reviewer A** (Opus): Independent critique of the optimization plan
5392
5549
  - **Reviewer B** (Sonnet): Independent critique from a different perspective
5550
+
5393
5551
  Both reviewers challenge assumptions, identify risks, and suggest improvements.
5394
- Iterate: adapt the plan based on feedback until confident.
5552
+
5553
+ **Mandatory iteration loop**: After each reviewer pass, if ANY issues, concerns, or suggestions remain from EITHER reviewer, revise the plan and re-submit to BOTH reviewers. Repeat until BOTH reviewers explicitly approve with ZERO reservations. Do not proceed to Phase 4 until unanimous, unconditional approval is reached.
5554
+
5555
+ This is the critical quality gate. Loop as many times as needed. The test suite must be bulletproof before execution begins.
5395
5556
 
5396
5557
  ### Phase 4: Execution
5397
5558
  Apply the agreed changes:
@@ -5417,13 +5578,13 @@ Apply the agreed changes:
5417
5578
  ## Common Pitfalls
5418
5579
  - Deleting tests without verifying coverage is maintained elsewhere
5419
5580
  - Optimizing for speed at the cost of correctness
5420
- - Not running the adversarial review (skipping Phase 3)
5581
+ - Settling for partial approval or cutting the Phase 3 review loop short before BOTH reviewers approve with zero reservations
5421
5582
  - Making changes without machine-readable output
5422
5583
  - Not feeding results back into compound-agent memory
5423
5584
 
5424
5585
  ## Quality Criteria
5425
5586
  - All 5 phases completed (analysis, planning, review, execution, verification)
5426
- - Adversarial review with 2 independent reviewers was conducted
5587
+ - Both adversarial reviewers approved with zero reservations after iterative refinement
5427
5588
  - Machine-readable output format used throughout
5428
5589
  - Full test suite passes after changes
5429
5590
  - Coverage not degraded
@@ -5726,7 +5887,7 @@ async function stripHeadersRecursive(dir, dryRun = false) {
5726
5887
  return count;
5727
5888
  }
5728
5889
  async function upgradeDocVersion(repoRoot, newVersion, dryRun = false) {
5729
- const docPath = join(repoRoot, "docs", "compound", "HOW_TO_COMPOUND.md");
5890
+ const docPath = join(repoRoot, "docs", "compound", "README.md");
5730
5891
  if (!existsSync(docPath)) return false;
5731
5892
  const content = await readFile(docPath, "utf-8");
5732
5893
  const updated = content.replace(/^(version: ")([^"]+)(")/m, `$1${newVersion}$3`);
@@ -5872,6 +6033,10 @@ async function runUpdate(repoRoot, dryRun) {
5872
6033
  for (const [name, content] of Object.entries(AGENT_ROLE_SKILLS)) {
5873
6034
  await processFile(join(repoRoot, ".claude", "skills", "compound", "agents", name, "SKILL.md"), content);
5874
6035
  }
6036
+ for (const [filename, template] of Object.entries(DOC_TEMPLATES)) {
6037
+ const content = template.replace("{{VERSION}}", VERSION).replace("{{DATE}}", (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
6038
+ await processFile(join(repoRoot, "docs", "compound", filename), content);
6039
+ }
5875
6040
  for (const filename of LEGACY_ROOT_SLASH_COMMANDS) {
5876
6041
  const filePath = join(repoRoot, ".claude", "commands", filename);
5877
6042
  if (existsSync(filePath)) {
@@ -5881,6 +6046,14 @@ async function runUpdate(repoRoot, dryRun) {
5881
6046
  }
5882
6047
  }
5883
6048
  }
6049
+ const oldDocPath = join(repoRoot, "docs", "compound", "HOW_TO_COMPOUND.md");
6050
+ if (existsSync(oldDocPath)) {
6051
+ const oldContent = await readFile(oldDocPath, "utf-8");
6052
+ if (oldContent.startsWith("---\nversion:")) {
6053
+ if (!dryRun) await rm(oldDocPath);
6054
+ updated++;
6055
+ }
6056
+ }
5884
6057
  let configUpdated = false;
5885
6058
  if (!dryRun) {
5886
6059
  const { hooks } = await configureClaudeSettings();
@@ -5895,11 +6068,12 @@ var MODEL_STATUS_MSG = {
5895
6068
  already_exists: "Already exists",
5896
6069
  failed: "Download failed (run `ca download-model` manually)"
5897
6070
  };
5898
- async function printSetupResult(result, quiet) {
6071
+ async function printSetupResult(result, quiet, repoRoot) {
5899
6072
  if (!quiet) {
5900
- if (result.scope.isUserScope) console.log(` ${result.scope.message}`);
5901
- if (!result.beads.available) console.log(` ${result.beads.message}`);
5902
- if (result.upgrade?.isUpgrade) console.log(` ${result.upgrade.message}`);
6073
+ if (result.upgrade?.isUpgrade) {
6074
+ console.log(` ${result.upgrade.message}`);
6075
+ console.log(" Tip: Run with --update to regenerate managed files with latest templates.");
6076
+ }
5903
6077
  if (process.stdout.isTTY) await playInstallBanner();
5904
6078
  }
5905
6079
  out.success("Compound agent setup complete");
@@ -5910,6 +6084,9 @@ async function printSetupResult(result, quiet) {
5910
6084
  printPnpmConfigStatus(result.pnpmConfig);
5911
6085
  printGitignoreStatus(result.gitignore);
5912
6086
  console.log(` Model: ${MODEL_STATUS_MSG[result.model]}`);
6087
+ const fullBeads = runFullBeadsCheck(repoRoot);
6088
+ printBeadsFullStatus(fullBeads);
6089
+ printScopeStatus(result.scope);
5913
6090
  console.log("\nNext steps:\n 1. Restart Claude Code to load hooks\n 2. Use `npx ca search` and `npx ca learn` commands");
5914
6091
  }
5915
6092
  function registerSetupAllCommand(setupCommand) {
@@ -5931,6 +6108,7 @@ function registerSetupAllCommand(setupCommand) {
5931
6108
  return;
5932
6109
  }
5933
6110
  if (options.update) {
6111
+ if (!dryRun && process.stdout.isTTY) await playInstallBanner();
5934
6112
  const result2 = await runUpdate(repoRoot, dryRun);
5935
6113
  const prefix = dryRun ? "[dry-run] " : "";
5936
6114
  if (result2.upgrade.isUpgrade) {
@@ -5946,6 +6124,10 @@ function registerSetupAllCommand(setupCommand) {
5946
6124
  console.log(` ${prefix}.gitignore: Added [${result2.gitignore.added.join(", ")}]`);
5947
6125
  }
5948
6126
  if (result2.configUpdated) console.log(` ${prefix}Config: hooks updated`);
6127
+ const fullBeads = runFullBeadsCheck(repoRoot);
6128
+ printBeadsFullStatus(fullBeads);
6129
+ const scope = checkUserScope(repoRoot);
6130
+ printScopeStatus(scope);
5949
6131
  return;
5950
6132
  }
5951
6133
  if (options.status) {
@@ -5954,7 +6136,7 @@ function registerSetupAllCommand(setupCommand) {
5954
6136
  }
5955
6137
  const result = await runSetup({ skipModel: options.skipModel, skipHooks: options.skipHooks });
5956
6138
  const { quiet } = getGlobalOpts(this);
5957
- await printSetupResult(result, quiet);
6139
+ await printSetupResult(result, quiet, repoRoot);
5958
6140
  });
5959
6141
  }
5960
6142
  async function handleStatus(alreadyInstalled, displayPath, settingsPath, options) {
@@ -6175,18 +6357,14 @@ async function initAction(cmd, options) {
6175
6357
  const repoRoot = getRepoRoot();
6176
6358
  const { quiet } = getGlobalOpts(cmd);
6177
6359
  const scopeResult = checkUserScope(repoRoot);
6178
- if (scopeResult.isUserScope && !quiet && !options.json) {
6179
- console.log(` ${scopeResult.message}`);
6180
- }
6181
- const beadsResult = checkBeadsAvailable();
6182
- if (!beadsResult.available && !quiet && !options.json) {
6183
- console.log(` ${beadsResult.message}`);
6184
- }
6185
6360
  let upgradeResult = null;
6186
6361
  if (options.update || detectExistingInstall(repoRoot)) {
6187
6362
  upgradeResult = await runUpgrade(repoRoot);
6188
6363
  if (!quiet && !options.json && upgradeResult.isUpgrade) {
6189
6364
  console.log(` ${upgradeResult.message}`);
6365
+ if (!options.update) {
6366
+ console.log(" Tip: Run with --update to regenerate managed files with latest templates.");
6367
+ }
6190
6368
  }
6191
6369
  }
6192
6370
  if (!quiet && !options.json && process.stdout.isTTY) {
@@ -6220,8 +6398,9 @@ async function initAction(cmd, options) {
6220
6398
  claudeHooksResult = await installClaudeHooksForInit(repoRoot);
6221
6399
  }
6222
6400
  const gitignoreResult = await ensureGitignore(repoRoot);
6401
+ const fullBeads = runFullBeadsCheck(repoRoot);
6223
6402
  if (options.json) {
6224
- printInitJson({ lessonsDir, agentsMdUpdated, hookResult, claudeHooksResult, pnpmConfig, beadsResult, scopeResult, upgradeResult, gitignoreResult });
6403
+ printInitJson({ lessonsDir, agentsMdUpdated, hookResult, claudeHooksResult, pnpmConfig, fullBeads, scopeResult, upgradeResult, gitignoreResult });
6225
6404
  return;
6226
6405
  }
6227
6406
  if (quiet) return;
@@ -6232,6 +6411,8 @@ async function initAction(cmd, options) {
6232
6411
  printClaudeHooksStatus(claudeHooksResult, options.skipClaude);
6233
6412
  printPnpmConfigStatus2(pnpmConfig);
6234
6413
  printGitignoreStatus(gitignoreResult);
6414
+ printBeadsFullStatus(fullBeads);
6415
+ printScopeStatus(scopeResult);
6235
6416
  }
6236
6417
  function printInitJson(ctx) {
6237
6418
  const claudeHooksInstalled = ctx.claudeHooksResult.action === "installed";
@@ -6244,7 +6425,9 @@ function printInitJson(ctx) {
6244
6425
  hookStatus: ctx.hookResult?.status ?? "skipped",
6245
6426
  claudeHooks: claudeHooksInstalled,
6246
6427
  pnpmConfig: ctx.pnpmConfig.isPnpm ? { added: ctx.pnpmConfig.added, alreadyConfigured: ctx.pnpmConfig.alreadyConfigured } : null,
6247
- beadsAvailable: ctx.beadsResult.available,
6428
+ beadsAvailable: ctx.fullBeads.cliAvailable,
6429
+ beadsInitialized: ctx.fullBeads.initialized,
6430
+ beadsHealthy: ctx.fullBeads.healthy,
6248
6431
  userScope: ctx.scopeResult.isUserScope,
6249
6432
  upgrade: ctx.upgradeResult ? { isUpgrade: ctx.upgradeResult.isUpgrade, removedCommands: ctx.upgradeResult.removedCommands, strippedHeaders: ctx.upgradeResult.strippedHeaders } : null,
6250
6433
  gitignore: ctx.gitignoreResult.added
@@ -6514,6 +6697,17 @@ function registerCrudCommands(program2) {
6514
6697
  await deleteAction(ids, options);
6515
6698
  });
6516
6699
  }
6700
+ function checkGitignoreHealth(repoRoot) {
6701
+ const gitignorePath = join(repoRoot, ".gitignore");
6702
+ if (!existsSync(gitignorePath)) return false;
6703
+ try {
6704
+ const content = readFileSync(gitignorePath, "utf-8");
6705
+ const lines = new Set(content.split("\n").map((l) => l.trim()));
6706
+ return ["node_modules/", ".claude/.cache/"].every((p) => lines.has(p));
6707
+ } catch {
6708
+ return false;
6709
+ }
6710
+ }
6517
6711
  async function runDoctor(repoRoot) {
6518
6712
  const checks = [];
6519
6713
  const claudeDir = join(repoRoot, ".claude");
@@ -6540,20 +6734,21 @@ async function runDoctor(repoRoot) {
6540
6734
  checks.push(modelOk ? { name: "Embedding model", status: "pass" } : { name: "Embedding model", status: "warn", fix: "Run: npx ca download-model" });
6541
6735
  const beadsResult = checkBeadsAvailable();
6542
6736
  checks.push(beadsResult.available ? { name: "Beads CLI", status: "pass" } : { name: "Beads CLI", status: "warn", fix: "Install beads: https://github.com/Nathandela/beads" });
6543
- const gitignorePath = join(repoRoot, ".gitignore");
6544
- const requiredPatterns = ["node_modules/", ".claude/.cache/"];
6545
- let gitignoreOk = false;
6546
- if (existsSync(gitignorePath)) {
6737
+ checks.push(checkGitignoreHealth(repoRoot) ? { name: ".gitignore health", status: "pass" } : { name: ".gitignore health", status: "warn", fix: "Run: npx ca setup --update" });
6738
+ const docPath = join(repoRoot, "docs", "compound", "README.md");
6739
+ checks.push(existsSync(docPath) ? { name: "Usage documentation", status: "pass" } : { name: "Usage documentation", status: "warn", fix: "Run: npx ca setup" });
6740
+ const beadsDir = join(repoRoot, ".beads");
6741
+ checks.push(existsSync(beadsDir) ? { name: "Beads initialized", status: "pass" } : { name: "Beads initialized", status: "warn", fix: "Run: bd init" });
6742
+ if (beadsResult.available && existsSync(beadsDir)) {
6547
6743
  try {
6548
- const content = readFileSync(gitignorePath, "utf-8");
6549
- const lines = new Set(content.split("\n").map((l) => l.trim()));
6550
- gitignoreOk = requiredPatterns.every((p) => lines.has(p));
6744
+ execSync("bd doctor", { cwd: repoRoot, shell: "/bin/sh", stdio: "pipe" });
6745
+ checks.push({ name: "Beads healthy", status: "pass" });
6551
6746
  } catch {
6747
+ checks.push({ name: "Beads healthy", status: "warn", fix: "Run: bd doctor" });
6552
6748
  }
6553
6749
  }
6554
- checks.push(gitignoreOk ? { name: ".gitignore health", status: "pass" } : { name: ".gitignore health", status: "warn", fix: "Run: npx ca setup --update" });
6555
- const docPath = join(repoRoot, "docs", "compound", "HOW_TO_COMPOUND.md");
6556
- checks.push(existsSync(docPath) ? { name: "Usage documentation", status: "pass" } : { name: "Usage documentation", status: "warn", fix: "Run: npx ca setup" });
6750
+ const scope = checkUserScope(repoRoot);
6751
+ checks.push(!scope.isUserScope ? { name: "Codebase scope", status: "pass" } : { name: "Codebase scope", status: "warn", fix: "Install in a specific repository, not home directory" });
6557
6752
  return checks;
6558
6753
  }
6559
6754
  var STATUS_ICONS = {
@@ -7335,6 +7530,96 @@ function registerVerifyGatesCommand(program2) {
7335
7530
  }
7336
7531
  });
7337
7532
  }
7533
+
7534
+ // src/changelog-data.ts
7535
+ var CHANGELOG_RECENT = `## [1.3.2] - 2026-02-21
7536
+
7537
+ ### Added
7538
+
7539
+ - **Banner audio**: Pure TypeScript WAV synthesis plays a rising pentatonic melody during the tendril animation. Cross-platform: \`afplay\` (macOS), \`aplay\` (Linux), PowerShell (Windows). Silently skips if player unavailable. Zero dependencies.
7540
+ - **Test coverage**: 19 new tests for \`ca about\` command, changelog extraction/escaping, and \`--update\` doc migration path
7541
+
7542
+ ### Fixed
7543
+
7544
+ - **\`setup --update\` doc migration**: \`--update\` now installs the 5 split docs before removing legacy \`HOW_TO_COMPOUND.md\`, preventing empty \`docs/compound/\`
7545
+ - **Fresh checkout type-check**: \`src/changelog-data.ts\` tracked in git so \`tsc --noEmit\` passes without a prior build
7546
+ - **Trailing status text**: Banner animation no longer leaves "al tendrils..." remnant from previous phase
7547
+
7548
+ ### Changed
7549
+
7550
+ - **\`ca about\` command**: Renamed from \`ca version-show\` for brevity
7551
+ - **Changelog extraction**: Core parsing/escaping logic extracted to \`scripts/changelog-utils.ts\` (shared between prebuild script and tests)
7552
+ - **Narrowed \`.gitignore\`**: Setup-generated patterns scoped to \`compound/\` subdirectories to avoid hiding tracked TDD agent definitions
7553
+
7554
+ ## [1.3.1] - 2026-02-21
7555
+
7556
+ ### Added
7557
+
7558
+ - **\`ca about\` command**: Displays version with terminal animation (tendril growth) and recent changelog entries. Non-TTY environments get plain text output. Changelog is embedded at build time from CHANGELOG.md.
7559
+ - **3 new doctor checks**: Beads initialized (\`.beads/\` dir), beads healthy (\`bd doctor\`), codebase scope (user-scope detection)
7560
+ - **Beads + scope status in init/setup output**: Full beads health display (CLI available, initialized, healthy) and scope status shown after \`ca init\`, \`ca setup\`, and \`ca setup --update\`
7561
+ - **Banner on \`--update\`**: Terminal art animation now plays during \`ca setup --update\` and \`ca init --update\` (same TTY/quiet guards as fresh install)
7562
+
7563
+ ### Changed
7564
+
7565
+ - **Split documentation**: \`HOW_TO_COMPOUND.md\` replaced by 5 focused documents in \`docs/compound/\`: \`README.md\`, \`WORKFLOW.md\`, \`CLI_REFERENCE.md\`, \`SKILLS.md\`, \`INTEGRATION.md\`
7566
+ - **Test-cleaner Phase 3 strengthened**: Adversarial review phase now mandates iteration loop until both reviewers give unconditional approval. Heading, emphasis, and quality criteria updated.
7567
+ - **Update hint on upgrade**: When \`ca init\` or \`ca setup\` detects an existing install, displays tip to run with \`--update\` to regenerate managed files
7568
+ - **HOW_TO_COMPOUND.md migration**: \`ca setup --update\` automatically removes old monolithic \`HOW_TO_COMPOUND.md\` if it has version frontmatter (generated by compound-agent)
7569
+ - **Doctor doc check**: Now checks for \`docs/compound/README.md\` instead of \`HOW_TO_COMPOUND.md\`
7570
+
7571
+ ## [1.3.0] - 2026-02-21
7572
+
7573
+ ### Added
7574
+
7575
+ - **Setup hardening**: Four new pre-flight checks during \`ca init\` and \`ca setup\`:
7576
+ - **Beads CLI check** (\`beads-check.ts\`): Detects if \`bd\` is available, shows install URL if missing (informational, non-blocking)
7577
+ - **User-scope detection** (\`scope-check.ts\`): Warns when installing at home directory level where lessons are shared across projects
7578
+ - **.gitignore injection** (\`gitignore.ts\`): Ensures \`node_modules/\` and \`.claude/.cache/\` patterns exist in \`.gitignore\`
7579
+ - **Upgrade detection** (\`upgrade.ts\`): Detects existing installs and runs migration pipeline (deprecated command removal, header stripping, doc version update)
7580
+ - **Upgrade engine**: Automated migration from v1.2.x to v1.3.0:
7581
+ - Removes 5 deprecated CLI wrapper commands (\`search.md\`, \`list.md\`, \`show.md\`, \`stats.md\`, \`wrong.md\`)
7582
+ - Strips legacy \`<!-- generated by compound-agent -->\` headers from installed files
7583
+ - Updates \`HOW_TO_COMPOUND.md\` version during upgrade
7584
+ - **\`/compound:research\` skill**: PhD-depth research producing structured survey documents following \`TEMPLATE_FOR_RESEARCH.md\` format
7585
+ - **\`/compound:test-clean\` skill**: 5-phase test suite optimization with adversarial review (audit, design, implement, verify, report)
7586
+ - **Documentation template**: \`HOW_TO_COMPOUND.md\` deployed to \`docs/compound/\` during setup with version and date placeholders
7587
+ - **Test scripts**: \`test:segment\` (run tests for specific module), \`test:random\` (seeded random subset), \`test:critical\` (*.critical.test.ts convention)
7588
+ - **3 new doctor checks**: Beads CLI availability, \`.gitignore\` health, usage documentation presence
7589
+
7590
+ ### Fixed
7591
+
7592
+ - **\`setup --update --dry-run\` no longer mutates files**: \`runUpgrade()\` now accepts a \`dryRun\` parameter propagated to all sub-functions (removeDeprecatedCommands, stripGeneratedHeaders, upgradeDocVersion)
7593
+ - **\`setup --uninstall\` respects plugin.json ownership**: Checks \`name === "compound-agent"\` before deleting; user-owned plugin manifests are preserved
7594
+ - **Upgrade ownership guard**: \`removeDeprecatedCommands\` checks file content for compound-agent markers before deleting, preventing silent removal of user-authored files with the same name
7595
+ - **Malformed settings.json no longer silently clobbered**: On parse error, \`configureClaudeSettings\` warns and skips instead of overwriting with empty config
7596
+
7597
+ ### Changed
7598
+
7599
+ - **\`setup --update\` overhaul**: Now uses path-based file detection (compound/ = managed) instead of marker-based. Runs upgrade pipeline and \`.gitignore\` remediation during update
7600
+ - **JSON-first \`bd\` parsing in loop**: \`jq\` primary with \`python3\` fallback via \`parse_json()\` helper
7601
+ - **CLI test helpers hardened**: Replaced shell string interpolation with \`execFileSync\` for safety and reliability
7602
+ - **Beads check portable**: Uses POSIX \`command -v\` instead of non-portable \`which\`
7603
+ - **Template expansion**: Brainstorm and plan skills now cross-reference researcher skill; 9 total skills, 11 total commands
7604
+ - **Code organization**: Extracted display utilities to \`display-utils.ts\`, uninstall logic to \`uninstall.ts\`
7605
+
7606
+ ### Removed
7607
+
7608
+ - **5 deprecated CLI wrapper commands**: \`search.md\`, \`list.md\`, \`show.md\`, \`stats.md\`, \`wrong.md\` (redundant wrappers around \`npx ca <cmd>\`)
7609
+ - **\`GENERATED_MARKER\` on new installs**: New installs use path-based detection; marker retained only for backward-compatible \`--update\` detection`;
7610
+
7611
+ // src/commands/about.ts
7612
+ function registerAboutCommand(program2) {
7613
+ program2.command("about").description("Show version, animation, and recent changelog").action(async () => {
7614
+ if (process.stdout.isTTY) {
7615
+ await playInstallBanner();
7616
+ } else {
7617
+ console.log(`compound-agent v${VERSION}`);
7618
+ }
7619
+ console.log("");
7620
+ console.log(CHANGELOG_RECENT);
7621
+ });
7622
+ }
7338
7623
  function parseWorktreeList(raw) {
7339
7624
  const entries = [];
7340
7625
  let currentPath = "";
@@ -8443,6 +8728,7 @@ function registerManagementCommands(program2) {
8443
8728
  registerRulesCommands(program2);
8444
8729
  registerTestSummaryCommand(program2);
8445
8730
  registerVerifyGatesCommand(program2);
8731
+ registerAboutCommand(program2);
8446
8732
  registerWorktreeCommands(program2);
8447
8733
  }
8448
8734