kairn-cli 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +362 -8
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/cli.ts
|
|
2
|
-
import { Command as
|
|
2
|
+
import { Command as Command8 } from "commander";
|
|
3
3
|
|
|
4
4
|
// src/commands/init.ts
|
|
5
5
|
import { Command } from "commander";
|
|
@@ -261,6 +261,7 @@ Do not add generic filler. Every line must be specific to the user's workflow.
|
|
|
261
261
|
9. settings.json with deny rules for \`rm -rf\`, \`curl|sh\`, reading \`.env\` and \`secrets/\`
|
|
262
262
|
10. A \`/project:status\` command for code projects (uses ! for live git/test output)
|
|
263
263
|
11. A \`/project:fix\` command for code projects (uses $ARGUMENTS for issue number)
|
|
264
|
+
12. A \`docs/SPRINT.md\` file for sprint contracts (acceptance criteria, verification steps)
|
|
264
265
|
|
|
265
266
|
## Shell-Integrated Commands
|
|
266
267
|
|
|
@@ -349,6 +350,26 @@ Generate hooks in settings.json based on project type:
|
|
|
349
350
|
|
|
350
351
|
Merge hooks into the \`settings\` object alongside permissions. Choose the formatter hook based on detected dependencies (Prettier \u2192 prettier, ESLint \u2192 eslint, Black \u2192 black).
|
|
351
352
|
|
|
353
|
+
## PostCompact Hook
|
|
354
|
+
|
|
355
|
+
All projects should include a PostCompact hook to restore context after compaction:
|
|
356
|
+
|
|
357
|
+
\`\`\`json
|
|
358
|
+
{
|
|
359
|
+
"hooks": {
|
|
360
|
+
"PostCompact": [{
|
|
361
|
+
"matcher": "",
|
|
362
|
+
"hooks": [{
|
|
363
|
+
"type": "prompt",
|
|
364
|
+
"prompt": "Re-read CLAUDE.md and docs/SPRINT.md (if it exists) to restore project context after compaction."
|
|
365
|
+
}]
|
|
366
|
+
}]
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
\`\`\`
|
|
370
|
+
|
|
371
|
+
Merge this into the settings hooks alongside the PreToolUse and PostToolUse hooks.
|
|
372
|
+
|
|
352
373
|
## Tool Selection Rules
|
|
353
374
|
|
|
354
375
|
- Only select tools directly relevant to the described workflow
|
|
@@ -358,6 +379,19 @@ Merge hooks into the \`settings\` object alongside permissions. Choose the forma
|
|
|
358
379
|
- Maximum 6-8 MCP servers to avoid context bloat
|
|
359
380
|
- Include a \`reason\` for each selected tool explaining why it fits this workflow
|
|
360
381
|
|
|
382
|
+
## Context Budget (STRICT)
|
|
383
|
+
|
|
384
|
+
- MCP servers: maximum 6. Prefer fewer.
|
|
385
|
+
- CLAUDE.md: maximum 100 lines.
|
|
386
|
+
- Rules: maximum 5 files, each under 20 lines.
|
|
387
|
+
- Skills: maximum 3. Only include directly relevant ones.
|
|
388
|
+
- Agents: maximum 3. QA pipeline + one specialist.
|
|
389
|
+
- Commands: no limit (loaded on demand, zero context cost).
|
|
390
|
+
- Hooks: maximum 4 (auto-format, block-destructive, PostCompact, plus one contextual).
|
|
391
|
+
|
|
392
|
+
If the workflow doesn't clearly need a tool, DO NOT include it.
|
|
393
|
+
Each MCP server costs 500-2000 tokens of context window.
|
|
394
|
+
|
|
361
395
|
## For Code Projects, Additionally Include
|
|
362
396
|
|
|
363
397
|
- \`/project:plan\` command (plan before coding)
|
|
@@ -366,12 +400,16 @@ Merge hooks into the \`settings\` object alongside permissions. Choose the forma
|
|
|
366
400
|
- \`/project:commit\` command (conventional commits)
|
|
367
401
|
- \`/project:status\` command (live git status, recent commits, TODO overview using ! prefix)
|
|
368
402
|
- \`/project:fix\` command (takes $ARGUMENTS as issue number, plans fix, implements, tests, commits)
|
|
403
|
+
- \`/project:sprint\` command (define acceptance criteria before coding, writes to docs/SPRINT.md)
|
|
369
404
|
- A TDD skill using the 3-phase isolation pattern (RED \u2192 GREEN \u2192 REFACTOR):
|
|
370
405
|
- RED: Write failing test only. Verify it FAILS.
|
|
371
406
|
- GREEN: Write MINIMUM code to pass. Nothing extra.
|
|
372
407
|
- REFACTOR: Improve while keeping tests green.
|
|
373
408
|
Rules: never write tests and implementation in same step, AAA pattern, one assertion per test.
|
|
374
|
-
- A
|
|
409
|
+
- A multi-agent QA pipeline:
|
|
410
|
+
- \`@qa-orchestrator\` (sonnet) \u2014 delegates to linter and e2e-tester, compiles QA report
|
|
411
|
+
- \`@linter\` (haiku) \u2014 runs formatters, linters, security scanners
|
|
412
|
+
- \`@e2e-tester\` (sonnet, only when Playwright is in tools) \u2014 browser-based QA via Playwright
|
|
375
413
|
|
|
376
414
|
## For Research Projects, Additionally Include
|
|
377
415
|
|
|
@@ -412,7 +450,8 @@ Return ONLY valid JSON matching this structure:
|
|
|
412
450
|
"help": "markdown content for /project:help",
|
|
413
451
|
"tasks": "markdown content for /project:tasks",
|
|
414
452
|
"status": "Show project status:\\n\\n!git status --short\\n\\n!git log --oneline -5\\n\\nRead TODO.md and summarize progress.",
|
|
415
|
-
"fix": "Fix issue #$ARGUMENTS:\\n\\n1. Read the issue and understand the problem\\n2. Plan the fix\\n3. Implement the fix\\n4. Run tests:\\n\\n!npm test 2>&1 | tail -20\\n\\n5. Commit with: fix: resolve #$ARGUMENTS"
|
|
453
|
+
"fix": "Fix issue #$ARGUMENTS:\\n\\n1. Read the issue and understand the problem\\n2. Plan the fix\\n3. Implement the fix\\n4. Run tests:\\n\\n!npm test 2>&1 | tail -20\\n\\n5. Commit with: fix: resolve #$ARGUMENTS",
|
|
454
|
+
"sprint": "Define a sprint contract for the next feature:\\n\\n1. Read docs/TODO.md for context:\\n\\n!cat docs/TODO.md 2>/dev/null\\n\\n2. Write a CONTRACT to docs/SPRINT.md with: feature name, acceptance criteria, verification steps, files to modify, scope estimate.\\n3. Do NOT start coding until contract is confirmed."
|
|
416
455
|
},
|
|
417
456
|
"rules": {
|
|
418
457
|
"continuity": "markdown content for continuity rule",
|
|
@@ -422,12 +461,15 @@ Return ONLY valid JSON matching this structure:
|
|
|
422
461
|
"skill-name/SKILL": "markdown content with YAML frontmatter"
|
|
423
462
|
},
|
|
424
463
|
"agents": {
|
|
425
|
-
"
|
|
464
|
+
"qa-orchestrator": "---\\nname: qa-orchestrator\\ndescription: Orchestrates QA pipeline\\nmodel: sonnet\\n---\\nRun QA: delegate to @linter for static analysis, @e2e-tester for browser tests. Compile consolidated report.",
|
|
465
|
+
"linter": "---\\nname: linter\\ndescription: Fast static analysis\\nmodel: haiku\\n---\\nRun available linters (eslint, prettier, biome, ruff, mypy, semgrep). Report issues.",
|
|
466
|
+
"e2e-tester": "---\\nname: e2e-tester\\ndescription: Browser-based QA via Playwright\\nmodel: sonnet\\n---\\nTest user flows via Playwright. Verify behavior, not just DOM. Screenshot failures."
|
|
426
467
|
},
|
|
427
468
|
"docs": {
|
|
428
469
|
"TODO": "# TODO\\n\\n- [ ] First task based on workflow",
|
|
429
470
|
"DECISIONS": "# Decisions\\n\\nArchitectural decisions for this project.",
|
|
430
|
-
"LEARNINGS": "# Learnings\\n\\nNon-obvious discoveries and gotchas."
|
|
471
|
+
"LEARNINGS": "# Learnings\\n\\nNon-obvious discoveries and gotchas.",
|
|
472
|
+
"SPRINT": "# Sprint Contract\\n\\nDefine acceptance criteria before starting work."
|
|
431
473
|
}
|
|
432
474
|
}
|
|
433
475
|
}
|
|
@@ -563,6 +605,24 @@ async function callLLM(config, userMessage) {
|
|
|
563
605
|
}
|
|
564
606
|
throw new Error(`Unsupported provider: ${config.provider}. Run \`kairn init\` to reconfigure.`);
|
|
565
607
|
}
|
|
608
|
+
function validateSpec(spec, onProgress) {
|
|
609
|
+
const warnings = [];
|
|
610
|
+
if (spec.tools.length > 8) {
|
|
611
|
+
warnings.push(`${spec.tools.length} MCP servers selected (recommended: \u22646)`);
|
|
612
|
+
}
|
|
613
|
+
if (spec.harness.claude_md) {
|
|
614
|
+
const lines = spec.harness.claude_md.split("\n").length;
|
|
615
|
+
if (lines > 150) {
|
|
616
|
+
warnings.push(`CLAUDE.md is ${lines} lines (recommended: \u2264100)`);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
if (spec.harness.skills && Object.keys(spec.harness.skills).length > 5) {
|
|
620
|
+
warnings.push(`${Object.keys(spec.harness.skills).length} skills (recommended: \u22643)`);
|
|
621
|
+
}
|
|
622
|
+
for (const warning of warnings) {
|
|
623
|
+
onProgress?.(`\u26A0 ${warning}`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
566
626
|
async function compile(intent, onProgress) {
|
|
567
627
|
const config = await loadConfig();
|
|
568
628
|
if (!config) {
|
|
@@ -581,6 +641,7 @@ async function compile(intent, onProgress) {
|
|
|
581
641
|
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
582
642
|
...parsed
|
|
583
643
|
};
|
|
644
|
+
validateSpec(spec, onProgress);
|
|
584
645
|
await ensureDirs();
|
|
585
646
|
const envPath = path2.join(getEnvsDir(), `${spec.id}.json`);
|
|
586
647
|
await fs2.writeFile(envPath, JSON.stringify(spec, null, 2), "utf-8");
|
|
@@ -594,6 +655,50 @@ async function writeFile(filePath, content) {
|
|
|
594
655
|
await fs3.mkdir(path3.dirname(filePath), { recursive: true });
|
|
595
656
|
await fs3.writeFile(filePath, content, "utf-8");
|
|
596
657
|
}
|
|
658
|
+
function buildFileMap(spec) {
|
|
659
|
+
const files = /* @__PURE__ */ new Map();
|
|
660
|
+
if (spec.harness.claude_md) {
|
|
661
|
+
files.set(".claude/CLAUDE.md", spec.harness.claude_md);
|
|
662
|
+
}
|
|
663
|
+
if (spec.harness.settings && Object.keys(spec.harness.settings).length > 0) {
|
|
664
|
+
files.set(
|
|
665
|
+
".claude/settings.json",
|
|
666
|
+
JSON.stringify(spec.harness.settings, null, 2)
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
if (spec.harness.mcp_config && Object.keys(spec.harness.mcp_config).length > 0) {
|
|
670
|
+
files.set(
|
|
671
|
+
".mcp.json",
|
|
672
|
+
JSON.stringify({ mcpServers: spec.harness.mcp_config }, null, 2)
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
if (spec.harness.commands) {
|
|
676
|
+
for (const [name, content] of Object.entries(spec.harness.commands)) {
|
|
677
|
+
files.set(`.claude/commands/${name}.md`, content);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
if (spec.harness.rules) {
|
|
681
|
+
for (const [name, content] of Object.entries(spec.harness.rules)) {
|
|
682
|
+
files.set(`.claude/rules/${name}.md`, content);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (spec.harness.skills) {
|
|
686
|
+
for (const [skillPath, content] of Object.entries(spec.harness.skills)) {
|
|
687
|
+
files.set(`.claude/skills/${skillPath}.md`, content);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
if (spec.harness.agents) {
|
|
691
|
+
for (const [name, content] of Object.entries(spec.harness.agents)) {
|
|
692
|
+
files.set(`.claude/agents/${name}.md`, content);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
if (spec.harness.docs) {
|
|
696
|
+
for (const [name, content] of Object.entries(spec.harness.docs)) {
|
|
697
|
+
files.set(`.claude/docs/${name}.md`, content);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
return files;
|
|
701
|
+
}
|
|
597
702
|
async function writeEnvironment(spec, targetDir) {
|
|
598
703
|
const claudeDir = path3.join(targetDir, ".claude");
|
|
599
704
|
const written = [];
|
|
@@ -1135,6 +1240,58 @@ async function scanProject(dir) {
|
|
|
1135
1240
|
}
|
|
1136
1241
|
|
|
1137
1242
|
// src/commands/optimize.ts
|
|
1243
|
+
function simpleDiff(oldContent, newContent) {
|
|
1244
|
+
const oldLines = oldContent.split("\n");
|
|
1245
|
+
const newLines = newContent.split("\n");
|
|
1246
|
+
const output = [];
|
|
1247
|
+
const maxLines = Math.max(oldLines.length, newLines.length);
|
|
1248
|
+
for (let i = 0; i < maxLines; i++) {
|
|
1249
|
+
const oldLine = oldLines[i];
|
|
1250
|
+
const newLine = newLines[i];
|
|
1251
|
+
if (oldLine === void 0) {
|
|
1252
|
+
output.push(chalk6.green(`+ ${newLine}`));
|
|
1253
|
+
} else if (newLine === void 0) {
|
|
1254
|
+
output.push(chalk6.red(`- ${oldLine}`));
|
|
1255
|
+
} else if (oldLine !== newLine) {
|
|
1256
|
+
output.push(chalk6.red(`- ${oldLine}`));
|
|
1257
|
+
output.push(chalk6.green(`+ ${newLine}`));
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
return output;
|
|
1261
|
+
}
|
|
1262
|
+
async function generateDiff(spec, targetDir) {
|
|
1263
|
+
const fileMap = buildFileMap(spec);
|
|
1264
|
+
const results = [];
|
|
1265
|
+
for (const [relativePath, newContent] of fileMap) {
|
|
1266
|
+
const absolutePath = path9.join(targetDir, relativePath);
|
|
1267
|
+
let oldContent = null;
|
|
1268
|
+
try {
|
|
1269
|
+
oldContent = await fs9.readFile(absolutePath, "utf-8");
|
|
1270
|
+
} catch {
|
|
1271
|
+
}
|
|
1272
|
+
if (oldContent === null) {
|
|
1273
|
+
results.push({
|
|
1274
|
+
path: relativePath,
|
|
1275
|
+
status: "new",
|
|
1276
|
+
diff: chalk6.green("+ NEW FILE")
|
|
1277
|
+
});
|
|
1278
|
+
} else if (oldContent === newContent) {
|
|
1279
|
+
results.push({
|
|
1280
|
+
path: relativePath,
|
|
1281
|
+
status: "unchanged",
|
|
1282
|
+
diff: ""
|
|
1283
|
+
});
|
|
1284
|
+
} else {
|
|
1285
|
+
const diffLines = simpleDiff(oldContent, newContent);
|
|
1286
|
+
results.push({
|
|
1287
|
+
path: relativePath,
|
|
1288
|
+
status: "modified",
|
|
1289
|
+
diff: diffLines.join("\n")
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
return results;
|
|
1294
|
+
}
|
|
1138
1295
|
async function loadRegistry3() {
|
|
1139
1296
|
const __filename = fileURLToPath4(import.meta.url);
|
|
1140
1297
|
const __dirname = path9.dirname(__filename);
|
|
@@ -1231,7 +1388,7 @@ ${profile.existingClaudeMd}`);
|
|
|
1231
1388
|
}
|
|
1232
1389
|
return parts.join("\n");
|
|
1233
1390
|
}
|
|
1234
|
-
var optimizeCommand = new Command6("optimize").description("Scan an existing project and generate or optimize its Claude Code environment").option("-y, --yes", "Skip confirmation prompts").option("--audit-only", "Only audit the existing harness, don't generate changes").action(async (options) => {
|
|
1391
|
+
var optimizeCommand = new Command6("optimize").description("Scan an existing project and generate or optimize its Claude Code environment").option("-y, --yes", "Skip confirmation prompts").option("--audit-only", "Only audit the existing harness, don't generate changes").option("--diff", "Preview changes as a diff without writing").action(async (options) => {
|
|
1235
1392
|
const config = await loadConfig();
|
|
1236
1393
|
if (!config) {
|
|
1237
1394
|
console.log(
|
|
@@ -1345,6 +1502,34 @@ var optimizeCommand = new Command6("optimize").description("Scan an existing pro
|
|
|
1345
1502
|
console.log(chalk6.yellow(` ${cmd}`));
|
|
1346
1503
|
}
|
|
1347
1504
|
}
|
|
1505
|
+
if (options.diff) {
|
|
1506
|
+
const diffs = await generateDiff(spec, targetDir);
|
|
1507
|
+
const changedDiffs = diffs.filter((d) => d.status !== "unchanged");
|
|
1508
|
+
if (changedDiffs.length === 0) {
|
|
1509
|
+
console.log(chalk6.green("\n \u2713 No changes needed \u2014 environment is already up to date.\n"));
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
console.log(chalk6.cyan("\n Changes preview:\n"));
|
|
1513
|
+
for (const d of changedDiffs) {
|
|
1514
|
+
console.log(chalk6.cyan(` --- ${d.path}`));
|
|
1515
|
+
if (d.status === "new") {
|
|
1516
|
+
console.log(` ${d.diff}`);
|
|
1517
|
+
} else {
|
|
1518
|
+
for (const line of d.diff.split("\n")) {
|
|
1519
|
+
console.log(` ${line}`);
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
console.log("");
|
|
1523
|
+
}
|
|
1524
|
+
const apply = await confirm2({
|
|
1525
|
+
message: "Apply these changes?",
|
|
1526
|
+
default: true
|
|
1527
|
+
});
|
|
1528
|
+
if (!apply) {
|
|
1529
|
+
console.log(chalk6.dim("\n Aborted.\n"));
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1348
1533
|
const written = await writeEnvironment(spec, targetDir);
|
|
1349
1534
|
console.log(chalk6.green("\n \u2713 Environment written\n"));
|
|
1350
1535
|
for (const file of written) {
|
|
@@ -1375,16 +1560,185 @@ var optimizeCommand = new Command6("optimize").description("Scan an existing pro
|
|
|
1375
1560
|
);
|
|
1376
1561
|
});
|
|
1377
1562
|
|
|
1563
|
+
// src/commands/doctor.ts
|
|
1564
|
+
import { Command as Command7 } from "commander";
|
|
1565
|
+
import chalk7 from "chalk";
|
|
1566
|
+
function runChecks(profile) {
|
|
1567
|
+
const checks = [];
|
|
1568
|
+
if (!profile.existingClaudeMd) {
|
|
1569
|
+
checks.push({
|
|
1570
|
+
name: "CLAUDE.md",
|
|
1571
|
+
weight: 3,
|
|
1572
|
+
status: "fail",
|
|
1573
|
+
message: "Missing CLAUDE.md"
|
|
1574
|
+
});
|
|
1575
|
+
} else if (profile.claudeMdLineCount > 200) {
|
|
1576
|
+
checks.push({
|
|
1577
|
+
name: "CLAUDE.md",
|
|
1578
|
+
weight: 2,
|
|
1579
|
+
status: "warn",
|
|
1580
|
+
message: `${profile.claudeMdLineCount} lines (recommended: \u2264100)`
|
|
1581
|
+
});
|
|
1582
|
+
} else {
|
|
1583
|
+
checks.push({
|
|
1584
|
+
name: "CLAUDE.md",
|
|
1585
|
+
weight: 3,
|
|
1586
|
+
status: "pass",
|
|
1587
|
+
message: `${profile.claudeMdLineCount} lines`
|
|
1588
|
+
});
|
|
1589
|
+
}
|
|
1590
|
+
if (!profile.existingSettings) {
|
|
1591
|
+
checks.push({
|
|
1592
|
+
name: "settings.json",
|
|
1593
|
+
weight: 2,
|
|
1594
|
+
status: "fail",
|
|
1595
|
+
message: "Missing settings.json"
|
|
1596
|
+
});
|
|
1597
|
+
} else {
|
|
1598
|
+
const perms2 = profile.existingSettings.permissions;
|
|
1599
|
+
const hasDeny = perms2?.deny && Array.isArray(perms2.deny) && perms2.deny.length > 0;
|
|
1600
|
+
checks.push({
|
|
1601
|
+
name: "Deny rules",
|
|
1602
|
+
weight: 2,
|
|
1603
|
+
status: hasDeny ? "pass" : "warn",
|
|
1604
|
+
message: hasDeny ? "Deny rules configured" : "No deny rules in settings.json"
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
if (profile.mcpServerCount > 8) {
|
|
1608
|
+
checks.push({
|
|
1609
|
+
name: "MCP servers",
|
|
1610
|
+
weight: 1,
|
|
1611
|
+
status: "warn",
|
|
1612
|
+
message: `${profile.mcpServerCount} servers (recommended: \u22648)`
|
|
1613
|
+
});
|
|
1614
|
+
} else if (profile.mcpServerCount > 0) {
|
|
1615
|
+
checks.push({
|
|
1616
|
+
name: "MCP servers",
|
|
1617
|
+
weight: 1,
|
|
1618
|
+
status: "pass",
|
|
1619
|
+
message: `${profile.mcpServerCount} servers`
|
|
1620
|
+
});
|
|
1621
|
+
} else {
|
|
1622
|
+
checks.push({
|
|
1623
|
+
name: "MCP servers",
|
|
1624
|
+
weight: 1,
|
|
1625
|
+
status: "warn",
|
|
1626
|
+
message: "No MCP servers configured"
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
checks.push({
|
|
1630
|
+
name: "/project:help",
|
|
1631
|
+
weight: 2,
|
|
1632
|
+
status: profile.existingCommands.includes("help") ? "pass" : "fail",
|
|
1633
|
+
message: profile.existingCommands.includes("help") ? "Help command present" : "Missing /project:help command"
|
|
1634
|
+
});
|
|
1635
|
+
checks.push({
|
|
1636
|
+
name: "/project:tasks",
|
|
1637
|
+
weight: 1,
|
|
1638
|
+
status: profile.existingCommands.includes("tasks") ? "pass" : "warn",
|
|
1639
|
+
message: profile.existingCommands.includes("tasks") ? "Tasks command present" : "Missing /project:tasks command"
|
|
1640
|
+
});
|
|
1641
|
+
checks.push({
|
|
1642
|
+
name: "Security rule",
|
|
1643
|
+
weight: 3,
|
|
1644
|
+
status: profile.existingRules.includes("security") ? "pass" : "fail",
|
|
1645
|
+
message: profile.existingRules.includes("security") ? "Security rule present" : "Missing rules/security.md"
|
|
1646
|
+
});
|
|
1647
|
+
checks.push({
|
|
1648
|
+
name: "Continuity rule",
|
|
1649
|
+
weight: 2,
|
|
1650
|
+
status: profile.existingRules.includes("continuity") ? "pass" : "warn",
|
|
1651
|
+
message: profile.existingRules.includes("continuity") ? "Continuity rule present" : "Missing rules/continuity.md"
|
|
1652
|
+
});
|
|
1653
|
+
const hasHooks = profile.existingSettings?.hooks;
|
|
1654
|
+
checks.push({
|
|
1655
|
+
name: "Hooks",
|
|
1656
|
+
weight: 1,
|
|
1657
|
+
status: hasHooks ? "pass" : "warn",
|
|
1658
|
+
message: hasHooks ? "Hooks configured" : "No hooks in settings.json"
|
|
1659
|
+
});
|
|
1660
|
+
const perms = profile.existingSettings?.permissions;
|
|
1661
|
+
const denyList = perms?.deny || [];
|
|
1662
|
+
const envProtected = denyList.some((d) => d.includes(".env"));
|
|
1663
|
+
checks.push({
|
|
1664
|
+
name: ".env protection",
|
|
1665
|
+
weight: 2,
|
|
1666
|
+
status: envProtected ? "pass" : "warn",
|
|
1667
|
+
message: envProtected ? ".env in deny list" : ".env not in deny list"
|
|
1668
|
+
});
|
|
1669
|
+
if (profile.existingClaudeMd) {
|
|
1670
|
+
const requiredSections = ["## Purpose", "## Commands", "## Tech Stack"];
|
|
1671
|
+
const missingSections = requiredSections.filter(
|
|
1672
|
+
(s) => !profile.existingClaudeMd.includes(s)
|
|
1673
|
+
);
|
|
1674
|
+
if (missingSections.length > 0) {
|
|
1675
|
+
checks.push({
|
|
1676
|
+
name: "CLAUDE.md sections",
|
|
1677
|
+
weight: 1,
|
|
1678
|
+
status: "warn",
|
|
1679
|
+
message: `Missing: ${missingSections.join(", ")}`
|
|
1680
|
+
});
|
|
1681
|
+
} else {
|
|
1682
|
+
checks.push({
|
|
1683
|
+
name: "CLAUDE.md sections",
|
|
1684
|
+
weight: 1,
|
|
1685
|
+
status: "pass",
|
|
1686
|
+
message: "Required sections present"
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
return checks;
|
|
1691
|
+
}
|
|
1692
|
+
var doctorCommand = new Command7("doctor").description(
|
|
1693
|
+
"Validate the current Claude Code environment against best practices"
|
|
1694
|
+
).action(async () => {
|
|
1695
|
+
const targetDir = process.cwd();
|
|
1696
|
+
console.log(chalk7.dim("\n Checking .claude/ environment...\n"));
|
|
1697
|
+
const profile = await scanProject(targetDir);
|
|
1698
|
+
if (!profile.hasClaudeDir) {
|
|
1699
|
+
console.log(chalk7.red(" \u274C No .claude/ directory found.\n"));
|
|
1700
|
+
console.log(
|
|
1701
|
+
chalk7.dim(" Run ") + chalk7.bold("kairn describe") + chalk7.dim(" or ") + chalk7.bold("kairn optimize") + chalk7.dim(" to generate one.\n")
|
|
1702
|
+
);
|
|
1703
|
+
process.exit(1);
|
|
1704
|
+
}
|
|
1705
|
+
const checks = runChecks(profile);
|
|
1706
|
+
for (const check of checks) {
|
|
1707
|
+
const icon = check.status === "pass" ? chalk7.green("\u2705") : check.status === "warn" ? chalk7.yellow("\u26A0\uFE0F ") : chalk7.red("\u274C");
|
|
1708
|
+
const msg = check.status === "pass" ? chalk7.dim(check.message) : check.status === "warn" ? chalk7.yellow(check.message) : chalk7.red(check.message);
|
|
1709
|
+
console.log(` ${icon} ${check.name}: ${msg}`);
|
|
1710
|
+
}
|
|
1711
|
+
const maxScore = checks.reduce((sum, c) => sum + c.weight, 0);
|
|
1712
|
+
const score = checks.reduce((sum, c) => {
|
|
1713
|
+
if (c.status === "pass") return sum + c.weight;
|
|
1714
|
+
if (c.status === "warn") return sum + Math.floor(c.weight / 2);
|
|
1715
|
+
return sum;
|
|
1716
|
+
}, 0);
|
|
1717
|
+
const percentage = Math.round(score / maxScore * 100);
|
|
1718
|
+
const scoreColor = percentage >= 80 ? chalk7.green : percentage >= 50 ? chalk7.yellow : chalk7.red;
|
|
1719
|
+
console.log(
|
|
1720
|
+
`
|
|
1721
|
+
Score: ${scoreColor(`${score}/${maxScore}`)} (${scoreColor(`${percentage}%`)})
|
|
1722
|
+
`
|
|
1723
|
+
);
|
|
1724
|
+
if (percentage < 80) {
|
|
1725
|
+
console.log(
|
|
1726
|
+
chalk7.dim(" Run ") + chalk7.bold("kairn optimize") + chalk7.dim(" to fix issues.\n")
|
|
1727
|
+
);
|
|
1728
|
+
}
|
|
1729
|
+
});
|
|
1730
|
+
|
|
1378
1731
|
// src/cli.ts
|
|
1379
|
-
var program = new
|
|
1732
|
+
var program = new Command8();
|
|
1380
1733
|
program.name("kairn").description(
|
|
1381
1734
|
"Compile natural language intent into optimized Claude Code environments"
|
|
1382
|
-
).version("1.
|
|
1735
|
+
).version("1.4.0");
|
|
1383
1736
|
program.addCommand(initCommand);
|
|
1384
1737
|
program.addCommand(describeCommand);
|
|
1385
1738
|
program.addCommand(optimizeCommand);
|
|
1386
1739
|
program.addCommand(listCommand);
|
|
1387
1740
|
program.addCommand(activateCommand);
|
|
1388
1741
|
program.addCommand(updateRegistryCommand);
|
|
1742
|
+
program.addCommand(doctorCommand);
|
|
1389
1743
|
program.parse();
|
|
1390
1744
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/config.ts","../src/commands/describe.ts","../src/compiler/compile.ts","../src/compiler/prompt.ts","../src/adapter/claude-code.ts","../src/commands/list.ts","../src/commands/activate.ts","../src/commands/update-registry.ts","../src/commands/optimize.ts","../src/scanner/scan.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { describeCommand } from \"./commands/describe.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { activateCommand } from \"./commands/activate.js\";\nimport { updateRegistryCommand } from \"./commands/update-registry.js\";\nimport { optimizeCommand } from \"./commands/optimize.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"kairn\")\n .description(\n \"Compile natural language intent into optimized Claude Code environments\"\n )\n .version(\"1.3.0\");\n\nprogram.addCommand(initCommand);\nprogram.addCommand(describeCommand);\nprogram.addCommand(optimizeCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(activateCommand);\nprogram.addCommand(updateRegistryCommand);\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { password, select } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { execFileSync } from \"child_process\";\nimport { loadConfig, saveConfig, getConfigPath } from \"../config.js\";\nimport type { KairnConfig, LLMProvider } from \"../types.js\";\n\nconst PROVIDER_MODELS: Record<LLMProvider, { name: string; models: { name: string; value: string }[] }> = {\n anthropic: {\n name: \"Anthropic\",\n models: [\n { name: \"Claude Sonnet 4.6 (recommended — fast, smart)\", value: \"claude-sonnet-4-6\" },\n { name: \"Claude Opus 4.6 (highest quality)\", value: \"claude-opus-4-6\" },\n { name: \"Claude Haiku 4.5 (fastest, cheapest)\", value: \"claude-haiku-4-5-20251001\" },\n ],\n },\n openai: {\n name: \"OpenAI\",\n models: [\n { name: \"GPT-4o (recommended)\", value: \"gpt-4o\" },\n { name: \"GPT-4o mini (faster, cheaper)\", value: \"gpt-4o-mini\" },\n { name: \"o3 (reasoning)\", value: \"o3\" },\n ],\n },\n google: {\n name: \"Google Gemini\",\n models: [\n { name: \"Gemini 2.5 Flash (recommended)\", value: \"gemini-2.5-flash-preview-05-20\" },\n { name: \"Gemini 2.5 Pro (highest quality)\", value: \"gemini-2.5-pro-preview-05-06\" },\n ],\n },\n};\n\nasync function verifyKey(provider: LLMProvider, apiKey: string, model: string): Promise<boolean> {\n try {\n if (provider === \"anthropic\") {\n const client = new Anthropic({ apiKey });\n await client.messages.create({\n model: \"claude-haiku-4-5-20251001\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n } else if (provider === \"openai\") {\n const client = new OpenAI({ apiKey });\n await client.chat.completions.create({\n model: \"gpt-4o-mini\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n } else if (provider === \"google\") {\n // Google uses OpenAI-compatible API\n const client = new OpenAI({\n apiKey,\n baseURL: \"https://generativelanguage.googleapis.com/v1beta/openai/\",\n });\n await client.chat.completions.create({\n model: \"gemini-2.5-flash-preview-05-20\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\nfunction detectClaudeCode(): boolean {\n try {\n execFileSync(\"which\", [\"claude\"], { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport const initCommand = new Command(\"init\")\n .description(\"Set up Kairn with your API key\")\n .action(async () => {\n console.log(chalk.cyan(\"\\n Kairn Setup\\n\"));\n\n const existing = await loadConfig();\n if (existing) {\n console.log(\n chalk.yellow(\" Config already exists at \") +\n chalk.dim(getConfigPath())\n );\n console.log(chalk.yellow(\" Running setup will overwrite it.\\n\"));\n }\n\n const provider = await select<LLMProvider>({\n message: \"LLM provider\",\n choices: [\n { name: \"Anthropic (Claude) — recommended\", value: \"anthropic\" as LLMProvider },\n { name: \"OpenAI (GPT)\", value: \"openai\" as LLMProvider },\n { name: \"Google (Gemini)\", value: \"google\" as LLMProvider },\n ],\n });\n\n const providerInfo = PROVIDER_MODELS[provider];\n\n const model = await select({\n message: \"Compilation model\",\n choices: providerInfo.models,\n });\n\n const apiKey = await password({\n message: `${providerInfo.name} API key`,\n mask: \"*\",\n });\n\n if (!apiKey) {\n console.log(chalk.red(\"\\n No API key provided. Aborting.\"));\n process.exit(1);\n }\n\n console.log(chalk.dim(\"\\n Verifying API key...\"));\n const valid = await verifyKey(provider, apiKey, model);\n\n if (!valid) {\n console.log(\n chalk.red(\" Invalid API key. Check your key and try again.\")\n );\n process.exit(1);\n }\n\n console.log(chalk.green(\" ✓ API key verified\"));\n\n const config: KairnConfig = {\n provider,\n api_key: apiKey,\n model,\n default_runtime: \"claude-code\",\n created_at: new Date().toISOString(),\n };\n\n await saveConfig(config);\n console.log(\n chalk.green(\" ✓ Config saved to \") + chalk.dim(getConfigPath())\n );\n console.log(\n chalk.dim(` ✓ Provider: ${providerInfo.name}, Model: ${model}`)\n );\n\n const hasClaude = detectClaudeCode();\n if (hasClaude) {\n console.log(chalk.green(\" ✓ Claude Code detected\"));\n } else {\n console.log(\n chalk.yellow(\n \" ⚠ Claude Code not found. Install it: npm install -g @anthropic-ai/claude-code\"\n )\n );\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.cyan(\" to create your first environment.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { KairnConfig } from \"./types.js\";\n\nconst KAIRN_DIR = path.join(os.homedir(), \".kairn\");\nconst CONFIG_PATH = path.join(KAIRN_DIR, \"config.json\");\nconst ENVS_DIR = path.join(KAIRN_DIR, \"envs\");\n\nexport function getKairnDir(): string {\n return KAIRN_DIR;\n}\n\nexport function getConfigPath(): string {\n return CONFIG_PATH;\n}\n\nexport function getEnvsDir(): string {\n return ENVS_DIR;\n}\n\nexport async function ensureDirs(): Promise<void> {\n await fs.mkdir(KAIRN_DIR, { recursive: true });\n await fs.mkdir(ENVS_DIR, { recursive: true });\n}\n\nexport async function loadConfig(): Promise<KairnConfig | null> {\n try {\n const data = await fs.readFile(CONFIG_PATH, \"utf-8\");\n const raw = JSON.parse(data) as Record<string, unknown>;\n\n // Handle old config format (v1.0.0: anthropic_api_key)\n if (raw.anthropic_api_key && !raw.provider) {\n return {\n provider: \"anthropic\",\n api_key: raw.anthropic_api_key as string,\n model: \"claude-sonnet-4-6\",\n default_runtime: \"claude-code\",\n created_at: (raw.created_at as string) || new Date().toISOString(),\n };\n }\n\n return raw as unknown as KairnConfig;\n } catch {\n return null;\n }\n}\n\nexport async function saveConfig(config: KairnConfig): Promise<void> {\n await ensureDirs();\n await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), \"utf-8\");\n}\n","import { Command } from \"commander\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { loadConfig } from \"../config.js\";\nimport { compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { fileURLToPath } from \"url\";\nimport type { RegistryTool } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nexport const describeCommand = new Command(\"describe\")\n .description(\"Describe your workflow and generate a Claude Code environment\")\n .argument(\"[intent]\", \"What you want your agent to do\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (intentArg: string | undefined, options: { yes?: boolean }) => {\n // 1. Check config\n const config = await loadConfig();\n if (!config) {\n console.log(\n chalk.red(\"\\n No config found. Run \") +\n chalk.bold(\"kairn init\") +\n chalk.red(\" first.\\n\")\n );\n process.exit(1);\n }\n\n // 2. Get intent\n const intent =\n intentArg ||\n (await input({\n message: \"What do you want your agent to do?\",\n }));\n\n if (!intent.trim()) {\n console.log(chalk.red(\"\\n No description provided. Aborting.\\n\"));\n process.exit(1);\n }\n\n // 3. Compile with progress\n console.log(\"\");\n let spec;\n try {\n spec = await compile(intent, (msg) => {\n process.stdout.write(`\\r ${chalk.dim(msg)} `);\n });\n process.stdout.write(\"\\r \\r\");\n } catch (err) {\n process.stdout.write(\"\\r \\r\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n Compilation failed: ${msg}\\n`));\n process.exit(1);\n }\n\n // 4. Show results\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(chalk.green(\"\\n ✓ Environment compiled\\n\"));\n console.log(chalk.cyan(\" Name: \") + spec.name);\n console.log(chalk.cyan(\" Description: \") + spec.description);\n console.log(chalk.cyan(\" Tools: \") + summary.toolCount);\n console.log(chalk.cyan(\" Commands: \") + summary.commandCount);\n console.log(chalk.cyan(\" Rules: \") + summary.ruleCount);\n console.log(chalk.cyan(\" Skills: \") + summary.skillCount);\n console.log(chalk.cyan(\" Agents: \") + summary.agentCount);\n\n if (spec.tools.length > 0) {\n console.log(chalk.dim(\"\\n Selected tools:\"));\n for (const tool of spec.tools) {\n const regTool = registry.find((t) => t.id === tool.tool_id);\n const name = regTool?.name || tool.tool_id;\n console.log(chalk.dim(` - ${name}: ${tool.reason}`));\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Plugins to install manually:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.yellow(` ${cmd}`));\n }\n }\n\n // 5. Confirm\n console.log(\"\");\n const proceed = options.yes || await confirm({\n message: \"Generate environment in current directory?\",\n default: true,\n });\n\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted. Environment saved to ~/.kairn/envs/\\n\"));\n return;\n }\n\n // 6. Write\n const targetDir = process.cwd();\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\"\\n ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(chalk.yellow(\"\\n API keys needed (set these environment variables):\\n\"));\n const seen = new Set<string>();\n for (const env of summary.envSetup) {\n if (seen.has(env.envVar)) continue;\n seen.add(env.envVar);\n console.log(chalk.bold(` export ${env.envVar}=\"your-key-here\"`));\n console.log(chalk.dim(` ${env.description}`));\n if (env.signupUrl) {\n console.log(chalk.dim(` Get one at: ${env.signupUrl}`));\n }\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\" Install plugins by running these in Claude Code:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.bold(` ${cmd}`));\n }\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport crypto from \"crypto\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { loadConfig, getEnvsDir, ensureDirs } from \"../config.js\";\nimport { SYSTEM_PROMPT } from \"./prompt.js\";\nimport type { EnvironmentSpec, RegistryTool, KairnConfig } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nfunction buildUserMessage(intent: string, registry: RegistryTool[]): string {\n const registrySummary = registry\n .map(\n (t) =>\n `- ${t.id} (${t.type}, tier ${t.tier}, auth: ${t.auth}): ${t.description} [best_for: ${t.best_for.join(\", \")}]`\n )\n .join(\"\\n\");\n\n return `## User Intent\\n\\n${intent}\\n\\n## Available Tool Registry\\n\\n${registrySummary}\\n\\nGenerate the EnvironmentSpec JSON now.`;\n}\n\nfunction parseSpecResponse(text: string): Omit<EnvironmentSpec, \"id\" | \"intent\" | \"created_at\"> {\n let cleaned = text.trim();\n // Strip markdown code fences\n if (cleaned.startsWith(\"```\")) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, \"\").replace(/\\n?```$/, \"\");\n }\n // Try to extract JSON if there's surrounding text\n const jsonMatch = cleaned.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n throw new Error(\n \"LLM response did not contain valid JSON. Try again or use a different model.\"\n );\n }\n try {\n return JSON.parse(jsonMatch[0]);\n } catch (err) {\n throw new Error(\n `Failed to parse LLM response as JSON: ${err instanceof Error ? err.message : String(err)}\\n` +\n `Response started with: ${cleaned.slice(0, 200)}...`\n );\n }\n}\n\nfunction classifyError(err: unknown, provider: string): string {\n const msg = err instanceof Error ? err.message : String(err);\n const status = (err as { status?: number })?.status;\n const code = (err as { code?: string })?.code;\n\n // Network errors\n if (code === \"ECONNREFUSED\" || code === \"ENOTFOUND\" || code === \"ETIMEDOUT\") {\n return `Network error: could not reach ${provider} API. Check your internet connection.`;\n }\n\n // Auth errors\n if (status === 401 || msg.includes(\"invalid\") && msg.includes(\"key\")) {\n return `Invalid API key for ${provider}. Run \\`kairn init\\` to reconfigure.`;\n }\n if (status === 403) {\n return `Access denied by ${provider}. Your API key may lack permissions for this model.`;\n }\n\n // Rate limiting\n if (status === 429 || msg.includes(\"rate limit\") || msg.includes(\"quota\")) {\n return `Rate limited by ${provider}. Wait a moment and try again, or switch to a cheaper model with \\`kairn init\\`.`;\n }\n\n // Model errors\n if (status === 404 || msg.includes(\"not found\") || msg.includes(\"does not exist\")) {\n return `Model not found on ${provider}. Run \\`kairn init\\` to select a valid model.`;\n }\n\n // Overloaded\n if (status === 529 || status === 503 || msg.includes(\"overloaded\")) {\n return `${provider} is temporarily overloaded. Try again in a few seconds.`;\n }\n\n // Token/context limit\n if (msg.includes(\"token\") && (msg.includes(\"limit\") || msg.includes(\"exceed\"))) {\n return `Request too large for the selected model. Try a shorter workflow description.`;\n }\n\n // Billing\n if (msg.includes(\"billing\") || msg.includes(\"payment\") || msg.includes(\"insufficient\")) {\n return `Billing issue with your ${provider} account. Check your account dashboard.`;\n }\n\n // Fallback\n return `${provider} API error: ${msg}`;\n}\n\nasync function callLLM(config: KairnConfig, userMessage: string): Promise<string> {\n if (config.provider === \"anthropic\") {\n const client = new Anthropic({ apiKey: config.api_key });\n try {\n const response = await client.messages.create({\n model: config.model,\n max_tokens: 8192,\n system: SYSTEM_PROMPT,\n messages: [{ role: \"user\", content: userMessage }],\n });\n const textBlock = response.content.find((block) => block.type === \"text\");\n if (!textBlock || textBlock.type !== \"text\") {\n throw new Error(\"No text response from compiler LLM\");\n }\n return textBlock.text;\n } catch (err) {\n throw new Error(classifyError(err, \"Anthropic\"));\n }\n } else if (config.provider === \"openai\" || config.provider === \"google\") {\n const providerName = config.provider === \"google\" ? \"Google\" : \"OpenAI\";\n const clientOptions: { apiKey: string; baseURL?: string } = { apiKey: config.api_key };\n if (config.provider === \"google\") {\n clientOptions.baseURL = \"https://generativelanguage.googleapis.com/v1beta/openai/\";\n }\n const client = new OpenAI(clientOptions);\n try {\n const response = await client.chat.completions.create({\n model: config.model,\n max_tokens: 8192,\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: userMessage },\n ],\n });\n const text = response.choices[0]?.message?.content;\n if (!text) {\n throw new Error(\"No text response from compiler LLM\");\n }\n return text;\n } catch (err) {\n throw new Error(classifyError(err, providerName));\n }\n }\n throw new Error(`Unsupported provider: ${config.provider}. Run \\`kairn init\\` to reconfigure.`);\n}\n\nexport async function compile(\n intent: string,\n onProgress?: (msg: string) => void\n): Promise<EnvironmentSpec> {\n const config = await loadConfig();\n if (!config) {\n throw new Error(\"No config found. Run `kairn init` first.\");\n }\n\n onProgress?.(\"Loading tool registry...\");\n const registry = await loadRegistry();\n\n onProgress?.(`Compiling with ${config.provider} (${config.model})...`);\n const userMessage = buildUserMessage(intent, registry);\n const responseText = await callLLM(config, userMessage);\n\n onProgress?.(\"Parsing environment spec...\");\n const parsed = parseSpecResponse(responseText);\n\n const spec: EnvironmentSpec = {\n id: `env_${crypto.randomUUID()}`,\n intent,\n created_at: new Date().toISOString(),\n ...parsed,\n };\n\n // Save to ~/.kairn/envs/\n await ensureDirs();\n const envPath = path.join(getEnvsDir(), `${spec.id}.json`);\n await fs.writeFile(envPath, JSON.stringify(spec, null, 2), \"utf-8\");\n\n return spec;\n}\n","export const SYSTEM_PROMPT = `You are the Kairn environment compiler. Your job is to generate a minimal, optimal Claude Code agent environment from a user's natural language description of what they want their agent to do.\n\nYou will receive:\n1. The user's intent (what they want to build/do)\n2. A tool registry (available MCP servers, plugins, and hooks)\n\nYou must output a JSON object matching the EnvironmentSpec schema.\n\n## Core Principles\n\n- **Minimalism over completeness.** Fewer, well-chosen tools beat many generic ones. Each MCP server costs 500-2000 context tokens.\n- **Workflow-specific, not generic.** Every instruction, command, and rule must relate to the user's actual workflow.\n- **Concise CLAUDE.md.** Under 100 lines. No generic text like \"be helpful.\" Include build/test commands, reference docs/ and skills/.\n- **Security by default.** Always include deny rules for destructive commands and secret file access.\n\n## CLAUDE.md Template (mandatory structure)\n\nThe \\`claude_md\\` field MUST follow this exact structure (max 100 lines):\n\n\\`\\`\\`\n# {Project Name}\n\n## Purpose\n{one-line description}\n\n## Tech Stack\n{bullet list of frameworks/languages}\n\n## Commands\n{concrete build/test/lint/dev commands}\n\n## Architecture\n{brief folder structure, max 10 lines}\n\n## Conventions\n{3-5 specific coding rules}\n\n## Key Commands\n{list /project: commands with descriptions}\n\n## Output\n{where results go, key files}\n\\`\\`\\`\n\nDo not add generic filler. Every line must be specific to the user's workflow.\n\n## What You Must Always Include\n\n1. A concise, workflow-specific \\`claude_md\\` (the CLAUDE.md content)\n2. A \\`/project:help\\` command that explains the environment\n3. A \\`/project:tasks\\` command for task management via TODO.md\n4. A \\`docs/TODO.md\\` file for continuity\n5. A \\`docs/DECISIONS.md\\` file for architectural decisions\n6. A \\`docs/LEARNINGS.md\\` file for non-obvious discoveries\n7. A \\`rules/continuity.md\\` rule encouraging updates to DECISIONS.md and LEARNINGS.md\n8. A \\`rules/security.md\\` rule with essential security instructions\n9. settings.json with deny rules for \\`rm -rf\\`, \\`curl|sh\\`, reading \\`.env\\` and \\`secrets/\\`\n10. A \\`/project:status\\` command for code projects (uses ! for live git/test output)\n11. A \\`/project:fix\\` command for code projects (uses $ARGUMENTS for issue number)\n\n## Shell-Integrated Commands\n\nCommands that reference live project state should use Claude Code's \\`!\\` prefix for shell output:\n\n\\`\\`\\`markdown\n# Example: .claude/commands/review.md\nReview the staged changes for quality and security:\n\n!git diff --staged\n\nRun tests and check for failures:\n\n!npm test 2>&1 | tail -20\n\nFocus on: security, error handling, test coverage.\n\\`\\`\\`\n\nUse \\`!\\` when a command needs: git status, test results, build output, or file listings.\n\n## Path-Scoped Rules\n\nFor code projects with multiple domains (API, frontend, tests), generate path-scoped rules using YAML frontmatter:\n\n\\`\\`\\`markdown\n# Example: rules/api.md\n---\npaths:\n - \"src/api/**\"\n - \"src/routes/**\"\n---\n- All handlers return { data, error } shape\n- Use Zod for request validation\n- Log errors with request ID context\n\\`\\`\\`\n\n\\`\\`\\`markdown\n# Example: rules/testing.md\n---\npaths:\n - \"tests/**\"\n - \"**/*.test.*\"\n - \"**/*.spec.*\"\n---\n- Use AAA pattern: Arrange-Act-Assert\n- One assertion per test when possible\n- Mock external dependencies, never real APIs\n\\`\\`\\`\n\nKeep \\`security.md\\` and \\`continuity.md\\` as unconditional (no paths frontmatter).\nOnly generate scoped rules when the workflow involves multiple code domains.\n\n## Hooks\n\nGenerate hooks in settings.json based on project type:\n\n**All code projects** — block destructive commands:\n\\`\\`\\`json\n{\n \"hooks\": {\n \"PreToolUse\": [{\n \"matcher\": \"Bash\",\n \"hooks\": [{\n \"type\": \"command\",\n \"command\": \"CMD=$(cat | jq -r '.tool_input.command // empty') && echo \\\\\"$CMD\\\\\" | grep -qiE 'rm\\\\\\\\s+-rf\\\\\\\\s+/|DROP\\\\\\\\s+TABLE|curl.*\\\\\\\\|\\\\\\\\s*sh' && echo 'Blocked destructive command' >&2 && exit 2 || true\"\n }]\n }]\n }\n}\n\\`\\`\\`\n\n**Projects with Prettier/ESLint/Black** — auto-format on write:\n\\`\\`\\`json\n{\n \"hooks\": {\n \"PostToolUse\": [{\n \"matcher\": \"Edit|Write\",\n \"hooks\": [{\n \"type\": \"command\",\n \"command\": \"FILE=$(cat | jq -r '.tool_input.file_path // empty') && [ -n \\\\\"$FILE\\\\\" ] && npx prettier --write \\\\\"$FILE\\\\\" 2>/dev/null || true\"\n }]\n }]\n }\n}\n\\`\\`\\`\n\nMerge hooks into the \\`settings\\` object alongside permissions. Choose the formatter hook based on detected dependencies (Prettier → prettier, ESLint → eslint, Black → black).\n\n## Tool Selection Rules\n\n- Only select tools directly relevant to the described workflow\n- Prefer free tools (auth: \"none\") when quality is comparable\n- Tier 1 tools (Context7, Sequential Thinking, security-guidance) should be included in most environments\n- For tools requiring API keys (auth: \"api_key\"), use \\${ENV_VAR} syntax — never hardcode keys\n- Maximum 6-8 MCP servers to avoid context bloat\n- Include a \\`reason\\` for each selected tool explaining why it fits this workflow\n\n## For Code Projects, Additionally Include\n\n- \\`/project:plan\\` command (plan before coding)\n- \\`/project:review\\` command (review changes)\n- \\`/project:test\\` command (run and fix tests)\n- \\`/project:commit\\` command (conventional commits)\n- \\`/project:status\\` command (live git status, recent commits, TODO overview using ! prefix)\n- \\`/project:fix\\` command (takes $ARGUMENTS as issue number, plans fix, implements, tests, commits)\n- A TDD skill using the 3-phase isolation pattern (RED → GREEN → REFACTOR):\n - RED: Write failing test only. Verify it FAILS.\n - GREEN: Write MINIMUM code to pass. Nothing extra.\n - REFACTOR: Improve while keeping tests green.\n Rules: never write tests and implementation in same step, AAA pattern, one assertion per test.\n- A reviewer agent (read-only, Sonnet model)\n\n## For Research Projects, Additionally Include\n\n- \\`/project:research\\` command (deep research on a topic)\n- \\`/project:summarize\\` command (summarize findings)\n- A research-synthesis skill\n- A researcher agent\n\n## For Content/Writing Projects, Additionally Include\n\n- \\`/project:draft\\` command (write first draft)\n- \\`/project:edit\\` command (review and improve writing)\n- A writing-workflow skill\n\n## Output Schema\n\nReturn ONLY valid JSON matching this structure:\n\n\\`\\`\\`json\n{\n \"name\": \"short-kebab-case-name\",\n \"description\": \"One-line description of the environment\",\n \"tools\": [\n { \"tool_id\": \"id-from-registry\", \"reason\": \"why this tool fits\" }\n ],\n \"harness\": {\n \"claude_md\": \"The full CLAUDE.md content (under 100 lines)\",\n \"settings\": {\n \"permissions\": {\n \"allow\": [\"Bash(npm run *)\", \"Read\", \"Write\", \"Edit\"],\n \"deny\": [\"Bash(rm -rf *)\", \"Bash(curl * | sh)\", \"Read(./.env)\", \"Read(./secrets/**)\"]\n }\n },\n \"mcp_config\": {\n \"server-name\": { \"command\": \"npx\", \"args\": [\"...\"], \"env\": {} }\n },\n \"commands\": {\n \"help\": \"markdown content for /project:help\",\n \"tasks\": \"markdown content for /project:tasks\",\n \"status\": \"Show project status:\\\\n\\\\n!git status --short\\\\n\\\\n!git log --oneline -5\\\\n\\\\nRead TODO.md and summarize progress.\",\n \"fix\": \"Fix issue #$ARGUMENTS:\\\\n\\\\n1. Read the issue and understand the problem\\\\n2. Plan the fix\\\\n3. Implement the fix\\\\n4. Run tests:\\\\n\\\\n!npm test 2>&1 | tail -20\\\\n\\\\n5. Commit with: fix: resolve #$ARGUMENTS\"\n },\n \"rules\": {\n \"continuity\": \"markdown content for continuity rule\",\n \"security\": \"markdown content for security rule\"\n },\n \"skills\": {\n \"skill-name/SKILL\": \"markdown content with YAML frontmatter\"\n },\n \"agents\": {\n \"agent-name\": \"markdown content with YAML frontmatter\"\n },\n \"docs\": {\n \"TODO\": \"# TODO\\\\n\\\\n- [ ] First task based on workflow\",\n \"DECISIONS\": \"# Decisions\\\\n\\\\nArchitectural decisions for this project.\",\n \"LEARNINGS\": \"# Learnings\\\\n\\\\nNon-obvious discoveries and gotchas.\"\n }\n }\n}\n\\`\\`\\`\n\nDo not include any text outside the JSON object. Do not wrap in markdown code fences.`;\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport type { EnvironmentSpec, RegistryTool } from \"../types.js\";\n\nasync function writeFile(filePath: string, content: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, \"utf-8\");\n}\n\nexport async function writeEnvironment(\n spec: EnvironmentSpec,\n targetDir: string\n): Promise<string[]> {\n const claudeDir = path.join(targetDir, \".claude\");\n const written: string[] = [];\n\n // 1. CLAUDE.md\n if (spec.harness.claude_md) {\n const p = path.join(claudeDir, \"CLAUDE.md\");\n await writeFile(p, spec.harness.claude_md);\n written.push(\".claude/CLAUDE.md\");\n }\n\n // 2. settings.json\n if (spec.harness.settings && Object.keys(spec.harness.settings).length > 0) {\n const p = path.join(claudeDir, \"settings.json\");\n await writeFile(p, JSON.stringify(spec.harness.settings, null, 2));\n written.push(\".claude/settings.json\");\n }\n\n // 3. .mcp.json (project-scoped, goes in project root)\n if (\n spec.harness.mcp_config &&\n Object.keys(spec.harness.mcp_config).length > 0\n ) {\n const p = path.join(targetDir, \".mcp.json\");\n const mcpContent = { mcpServers: spec.harness.mcp_config };\n await writeFile(p, JSON.stringify(mcpContent, null, 2));\n written.push(\".mcp.json\");\n }\n\n // 4. Commands\n if (spec.harness.commands) {\n for (const [name, content] of Object.entries(spec.harness.commands)) {\n const p = path.join(claudeDir, \"commands\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/commands/${name}.md`);\n }\n }\n\n // 5. Rules\n if (spec.harness.rules) {\n for (const [name, content] of Object.entries(spec.harness.rules)) {\n const p = path.join(claudeDir, \"rules\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/rules/${name}.md`);\n }\n }\n\n // 6. Skills\n if (spec.harness.skills) {\n for (const [skillPath, content] of Object.entries(spec.harness.skills)) {\n const p = path.join(claudeDir, \"skills\", `${skillPath}.md`);\n await writeFile(p, content);\n written.push(`.claude/skills/${skillPath}.md`);\n }\n }\n\n // 7. Agents\n if (spec.harness.agents) {\n for (const [name, content] of Object.entries(spec.harness.agents)) {\n const p = path.join(claudeDir, \"agents\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/agents/${name}.md`);\n }\n }\n\n // 8. Docs\n if (spec.harness.docs) {\n for (const [name, content] of Object.entries(spec.harness.docs)) {\n const p = path.join(claudeDir, \"docs\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/docs/${name}.md`);\n }\n }\n\n return written;\n}\n\nexport interface EnvSetupInfo {\n toolName: string;\n envVar: string;\n description: string;\n signupUrl?: string;\n}\n\nexport function summarizeSpec(\n spec: EnvironmentSpec,\n registry: RegistryTool[]\n): {\n toolCount: number;\n commandCount: number;\n ruleCount: number;\n skillCount: number;\n agentCount: number;\n pluginCommands: string[];\n envSetup: EnvSetupInfo[];\n} {\n const pluginCommands: string[] = [];\n const envSetup: EnvSetupInfo[] = [];\n\n for (const selected of spec.tools) {\n const tool = registry.find((t) => t.id === selected.tool_id);\n if (!tool) continue;\n\n if (tool.install.plugin_command) {\n pluginCommands.push(tool.install.plugin_command);\n }\n\n if (tool.env_vars) {\n for (const ev of tool.env_vars) {\n envSetup.push({\n toolName: tool.name,\n envVar: ev.name,\n description: ev.description,\n signupUrl: tool.signup_url,\n });\n }\n }\n }\n\n return {\n toolCount: spec.tools.length,\n commandCount: Object.keys(spec.harness.commands || {}).length,\n ruleCount: Object.keys(spec.harness.rules || {}).length,\n skillCount: Object.keys(spec.harness.skills || {}).length,\n agentCount: Object.keys(spec.harness.agents || {}).length,\n pluginCommands,\n envSetup,\n };\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getEnvsDir } from \"../config.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\n\nexport const listCommand = new Command(\"list\")\n .description(\"Show saved environments\")\n .action(async () => {\n const envsDir = getEnvsDir();\n\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.dim(\"\\n No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n if (jsonFiles.length === 0) {\n console.log(chalk.dim(\"\\n No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n console.log(chalk.cyan(\"\\n Saved Environments\\n\"));\n\n for (const file of jsonFiles) {\n try {\n const data = await fs.readFile(path.join(envsDir, file), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n const date = new Date(spec.created_at).toLocaleDateString();\n const toolCount = spec.tools?.length ?? 0;\n\n console.log(chalk.bold(` ${spec.name}`));\n console.log(chalk.dim(` ${spec.description}`));\n console.log(\n chalk.dim(` ${date} · ${toolCount} tools · ${spec.id}`)\n );\n console.log(\"\");\n } catch {\n // Skip malformed files\n }\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getEnvsDir } from \"../config.js\";\nimport { writeEnvironment } from \"../adapter/claude-code.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\n\nexport const activateCommand = new Command(\"activate\")\n .description(\"Re-deploy a saved environment to the current directory\")\n .argument(\"<env_id>\", \"Environment ID (from kairn list)\")\n .action(async (envId: string) => {\n const envsDir = getEnvsDir();\n\n // Find the env file — accept full ID or partial match\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.red(\"\\n No saved environments found.\\n\"));\n process.exit(1);\n }\n\n const match = files.find(\n (f) => f === `${envId}.json` || f.startsWith(envId)\n );\n\n if (!match) {\n console.log(chalk.red(`\\n Environment \"${envId}\" not found.`));\n console.log(chalk.dim(\" Run kairn list to see saved environments.\\n\"));\n process.exit(1);\n }\n\n const data = await fs.readFile(path.join(envsDir, match), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n\n console.log(chalk.cyan(`\\n Activating: ${spec.name}`));\n console.log(chalk.dim(` ${spec.description}\\n`));\n\n const targetDir = process.cwd();\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\" ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst REGISTRY_URL =\n \"https://raw.githubusercontent.com/ashtonperlroth/kairn/main/src/registry/tools.json\";\n\nasync function getLocalRegistryPath(): Promise<string> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n await fs.access(candidate);\n return candidate;\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find local tools.json registry\");\n}\n\nexport const updateRegistryCommand = new Command(\"update-registry\")\n .description(\"Fetch the latest tool registry from GitHub\")\n .option(\"--url <url>\", \"Custom registry URL\")\n .action(async (options: { url?: string }) => {\n const url = options.url || REGISTRY_URL;\n\n console.log(chalk.dim(`\\n Fetching registry from ${url}...`));\n\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n console.log(\n chalk.red(` Failed to fetch registry: ${response.status} ${response.statusText}`)\n );\n console.log(\n chalk.dim(\" The remote registry may not be available yet.\")\n );\n console.log(\n chalk.dim(\" Your local registry is still active.\\n\")\n );\n return;\n }\n\n const text = await response.text();\n\n // Validate it's valid JSON and has the expected structure\n let tools: unknown[];\n try {\n tools = JSON.parse(text);\n if (!Array.isArray(tools)) throw new Error(\"Not an array\");\n if (tools.length === 0) throw new Error(\"Empty registry\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(` Invalid registry format: ${msg}\\n`));\n return;\n }\n\n const registryPath = await getLocalRegistryPath();\n\n // Back up existing registry\n const backupPath = registryPath + \".bak\";\n try {\n await fs.copyFile(registryPath, backupPath);\n } catch {\n // No existing file to back up\n }\n\n await fs.writeFile(registryPath, JSON.stringify(tools, null, 2), \"utf-8\");\n\n console.log(chalk.green(` ✓ Registry updated: ${tools.length} tools`));\n console.log(chalk.dim(` Saved to: ${registryPath}`));\n console.log(chalk.dim(` Backup: ${backupPath}\\n`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(` Network error: ${msg}`));\n console.log(chalk.dim(\" Your local registry is still active.\\n\"));\n }\n });\n","import { Command } from \"commander\";\nimport { input, confirm, checkbox } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { loadConfig } from \"../config.js\";\nimport { compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { scanProject } from \"../scanner/scan.js\";\nimport type { ProjectProfile } from \"../scanner/scan.js\";\nimport type { RegistryTool } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nfunction buildProfileSummary(profile: ProjectProfile): string {\n const lines: string[] = [];\n lines.push(`Project: ${profile.name}`);\n if (profile.description) lines.push(`Description: ${profile.description}`);\n if (profile.language) lines.push(`Language: ${profile.language}`);\n if (profile.framework) lines.push(`Framework: ${profile.framework}`);\n if (profile.dependencies.length > 0) {\n lines.push(`Dependencies: ${profile.dependencies.join(\", \")}`);\n }\n if (profile.testCommand) lines.push(`Test command: ${profile.testCommand}`);\n if (profile.buildCommand) lines.push(`Build command: ${profile.buildCommand}`);\n if (profile.lintCommand) lines.push(`Lint command: ${profile.lintCommand}`);\n if (profile.hasDocker) lines.push(\"Has Docker configuration\");\n if (profile.hasCi) lines.push(\"Has CI/CD (GitHub Actions)\");\n if (profile.envKeys.length > 0) {\n lines.push(`Env keys needed: ${profile.envKeys.join(\", \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction buildAuditSummary(profile: ProjectProfile): string {\n const lines: string[] = [];\n lines.push(`\\nExisting .claude/ harness found:`);\n lines.push(` CLAUDE.md: ${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? \" (⚠ over 200 — may degrade adherence)\" : \"\"}`);\n lines.push(` MCP servers: ${profile.mcpServerCount}`);\n lines.push(` Commands: ${profile.existingCommands.length > 0 ? profile.existingCommands.map(c => `/project:${c}`).join(\", \") : \"none\"}`);\n lines.push(` Rules: ${profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"}`);\n lines.push(` Skills: ${profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"}`);\n lines.push(` Agents: ${profile.existingAgents.length > 0 ? profile.existingAgents.join(\", \") : \"none\"}`);\n return lines.join(\"\\n\");\n}\n\nfunction buildOptimizeIntent(profile: ProjectProfile): string {\n const parts: string[] = [];\n\n parts.push(\"## Project Profile (scanned from actual codebase)\\n\");\n parts.push(buildProfileSummary(profile));\n\n if (profile.hasClaudeDir) {\n parts.push(buildAuditSummary(profile));\n\n if (profile.existingClaudeMd) {\n parts.push(`\\n## Existing CLAUDE.md Content\\n\\n${profile.existingClaudeMd}`);\n }\n\n parts.push(`\\n## Task\\n`);\n parts.push(\"Analyze this existing Claude Code environment and generate an OPTIMIZED version.\");\n parts.push(\"Preserve what works. Fix what's wrong. Add what's missing. Remove what's bloat.\");\n parts.push(\"Key optimizations to consider:\");\n parts.push(\"- Is CLAUDE.md under 100 lines? If not, move detail to rules/ or docs/\");\n parts.push(\"- Are the right MCP servers selected for these dependencies?\");\n parts.push(\"- Are there missing slash commands (help, tasks, plan, test, commit)?\");\n parts.push(\"- Are security rules present?\");\n parts.push(\"- Is there a continuity rule for session memory?\");\n parts.push(\"- Are there unnecessary MCP servers adding context bloat?\");\n parts.push(\"- Are hooks configured in settings.json for destructive command blocking?\");\n parts.push(\"- Are there path-scoped rules for different code domains (api, testing, frontend)?\");\n parts.push(\"- Does the project have a /project:status command with live git output?\");\n parts.push(\"- Is there a /project:fix command for issue-driven development?\");\n if (profile.claudeMdLineCount > 200) {\n parts.push(`- CLAUDE.md is ${profile.claudeMdLineCount} lines — needs aggressive trimming`);\n }\n if (!profile.existingCommands.includes(\"help\")) {\n parts.push(\"- Missing /project:help command\");\n }\n if (!profile.existingRules.includes(\"security\")) {\n parts.push(\"- Missing security rules\");\n }\n } else {\n parts.push(`\\n## Task\\n`);\n parts.push(\"Generate an optimal Claude Code environment for this existing project.\");\n parts.push(\"Use the scanned project profile — this is a real codebase, not a description.\");\n parts.push(\"The environment should match the actual tech stack, dependencies, and workflows.\");\n }\n\n return parts.join(\"\\n\");\n}\n\nexport const optimizeCommand = new Command(\"optimize\")\n .description(\"Scan an existing project and generate or optimize its Claude Code environment\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--audit-only\", \"Only audit the existing harness, don't generate changes\")\n .action(async (options: { yes?: boolean; auditOnly?: boolean }) => {\n const config = await loadConfig();\n if (!config) {\n console.log(\n chalk.red(\"\\n No config found. Run \") +\n chalk.bold(\"kairn init\") +\n chalk.red(\" first.\\n\")\n );\n process.exit(1);\n }\n\n const targetDir = process.cwd();\n\n // 1. Scan\n console.log(chalk.dim(\"\\n Scanning project...\"));\n const profile = await scanProject(targetDir);\n\n // 2. Show profile\n console.log(chalk.cyan(\"\\n Project Profile\\n\"));\n if (profile.language) console.log(chalk.dim(` Language: ${profile.language}`));\n if (profile.framework) console.log(chalk.dim(` Framework: ${profile.framework}`));\n console.log(chalk.dim(` Dependencies: ${profile.dependencies.length}`));\n if (profile.testCommand) console.log(chalk.dim(` Tests: ${profile.testCommand}`));\n if (profile.buildCommand) console.log(chalk.dim(` Build: ${profile.buildCommand}`));\n if (profile.hasDocker) console.log(chalk.dim(\" Docker: yes\"));\n if (profile.hasCi) console.log(chalk.dim(\" CI/CD: yes\"));\n if (profile.envKeys.length > 0) console.log(chalk.dim(` Env keys: ${profile.envKeys.join(\", \")}`));\n\n // 3. Audit existing harness\n if (profile.hasClaudeDir) {\n console.log(chalk.yellow(\"\\n Existing .claude/ harness detected\\n\"));\n console.log(chalk.dim(` CLAUDE.md: ${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? chalk.yellow(\" ⚠ bloated\") : chalk.green(\" ✓\")}`));\n console.log(chalk.dim(` MCP servers: ${profile.mcpServerCount}`));\n console.log(chalk.dim(` Commands: ${profile.existingCommands.length > 0 ? profile.existingCommands.map(c => c).join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Rules: ${profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Skills: ${profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Agents: ${profile.existingAgents.length > 0 ? profile.existingAgents.join(\", \") : \"none\"}`));\n\n // Quick audit checks\n const issues: string[] = [];\n if (profile.claudeMdLineCount > 200) issues.push(\"CLAUDE.md over 200 lines — move detail to rules/ or docs/\");\n if (!profile.existingCommands.includes(\"help\")) issues.push(\"Missing /project:help command\");\n if (!profile.existingRules.includes(\"security\")) issues.push(\"Missing security rules\");\n if (!profile.existingRules.includes(\"continuity\")) issues.push(\"Missing continuity rule for session memory\");\n if (profile.mcpServerCount > 8) issues.push(`${profile.mcpServerCount} MCP servers — may cause context bloat`);\n if (profile.mcpServerCount === 0 && profile.dependencies.length > 0) issues.push(\"No MCP servers configured\");\n if (profile.hasTests && !profile.existingCommands.includes(\"test\")) issues.push(\"Has tests but no /project:test command\");\n if (!profile.existingCommands.includes(\"tasks\")) issues.push(\"Missing /project:tasks command\");\n if (!profile.existingSettings?.hooks) issues.push(\"No hooks configured — missing destructive command blocking\");\n const scopedRules = profile.existingRules.filter(r => r !== \"security\" && r !== \"continuity\");\n if (profile.hasSrc && scopedRules.length === 0) issues.push(\"No path-scoped rules — consider adding api.md, testing.md, or frontend.md rules\");\n\n if (issues.length > 0) {\n console.log(chalk.yellow(\"\\n Issues Found:\\n\"));\n for (const issue of issues) {\n console.log(chalk.yellow(` ⚠ ${issue}`));\n }\n } else {\n console.log(chalk.green(\"\\n ✓ No obvious issues found\"));\n }\n\n if (options.auditOnly) {\n console.log(chalk.dim(\"\\n Audit complete. Run without --audit-only to generate optimized environment.\\n\"));\n return;\n }\n\n // Ask before overwriting\n if (!options.yes) {\n console.log(\"\");\n const proceed = await confirm({\n message: \"Generate optimized environment? This will overwrite existing .claude/ files.\",\n default: false,\n });\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n } else {\n console.log(chalk.dim(\"\\n No existing .claude/ directory found — generating from scratch.\\n\"));\n\n if (!options.yes) {\n const proceed = await confirm({\n message: \"Generate Claude Code environment for this project?\",\n default: true,\n });\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n }\n\n // 4. Compile with scanned profile\n const intent = buildOptimizeIntent(profile);\n let spec;\n try {\n spec = await compile(intent, (msg) => {\n process.stdout.write(`\\r ${chalk.dim(msg)} `);\n });\n process.stdout.write(\"\\r \\r\");\n } catch (err) {\n process.stdout.write(\"\\r \\r\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n Optimization failed: ${msg}\\n`));\n process.exit(1);\n }\n\n // 5. Show results\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(chalk.green(\" ✓ Environment compiled\\n\"));\n console.log(chalk.cyan(\" Name: \") + spec.name);\n console.log(chalk.cyan(\" Tools: \") + summary.toolCount);\n console.log(chalk.cyan(\" Commands: \") + summary.commandCount);\n console.log(chalk.cyan(\" Rules: \") + summary.ruleCount);\n console.log(chalk.cyan(\" Skills: \") + summary.skillCount);\n console.log(chalk.cyan(\" Agents: \") + summary.agentCount);\n\n if (spec.tools.length > 0) {\n console.log(chalk.dim(\"\\n Selected tools:\"));\n for (const tool of spec.tools) {\n const regTool = registry.find((t) => t.id === tool.tool_id);\n const name = regTool?.name || tool.tool_id;\n console.log(chalk.dim(` - ${name}: ${tool.reason}`));\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Plugins to install manually:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.yellow(` ${cmd}`));\n }\n }\n\n // 6. Write\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\"\\n ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(chalk.yellow(\"\\n API keys needed (set these environment variables):\\n\"));\n const seen = new Set<string>();\n for (const env of summary.envSetup) {\n if (seen.has(env.envVar)) continue;\n seen.add(env.envVar);\n console.log(chalk.bold(` export ${env.envVar}=\"your-key-here\"`));\n console.log(chalk.dim(` ${env.description}`));\n if (env.signupUrl) {\n console.log(chalk.dim(` Get one at: ${env.signupUrl}`));\n }\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\" Install plugins by running these in Claude Code:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.bold(` ${cmd}`));\n }\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\n\nexport interface ProjectProfile {\n // Core identity\n name: string;\n description: string;\n directory: string;\n\n // Language & framework\n language: string | null;\n framework: string | null;\n typescript: boolean;\n\n // Dependencies\n dependencies: string[];\n devDependencies: string[];\n\n // Scripts & commands\n scripts: Record<string, string>;\n hasTests: boolean;\n testCommand: string | null;\n buildCommand: string | null;\n lintCommand: string | null;\n\n // Project structure\n hasSrc: boolean;\n hasDocker: boolean;\n hasCi: boolean;\n hasEnvFile: boolean;\n envKeys: string[]; // from .env.example only — never read .env values\n\n // Existing harness\n hasClaudeDir: boolean;\n existingClaudeMd: string | null;\n existingSettings: Record<string, unknown> | null;\n existingMcpConfig: Record<string, unknown> | null;\n existingCommands: string[];\n existingRules: string[];\n existingSkills: string[];\n existingAgents: string[];\n mcpServerCount: number;\n claudeMdLineCount: number;\n\n // Key files found\n keyFiles: string[];\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readJsonSafe(p: string): Promise<Record<string, unknown> | null> {\n try {\n const data = await fs.readFile(p, \"utf-8\");\n return JSON.parse(data);\n } catch {\n return null;\n }\n}\n\nasync function readFileSafe(p: string): Promise<string | null> {\n try {\n return await fs.readFile(p, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nasync function listDirSafe(p: string): Promise<string[]> {\n try {\n const entries = await fs.readdir(p);\n return entries.filter((e) => !e.startsWith(\".\"));\n } catch {\n return [];\n }\n}\n\nfunction detectFramework(deps: string[]): string | null {\n const frameworks: [string[], string][] = [\n [[\"next\"], \"Next.js\"],\n [[\"nuxt\"], \"Nuxt\"],\n [[\"@remix-run/node\", \"@remix-run/react\"], \"Remix\"],\n [[\"svelte\", \"@sveltejs/kit\"], \"SvelteKit\"],\n [[\"express\"], \"Express\"],\n [[\"fastify\"], \"Fastify\"],\n [[\"hono\"], \"Hono\"],\n [[\"react\", \"react-dom\"], \"React\"],\n [[\"vue\"], \"Vue\"],\n [[\"angular\"], \"Angular\"],\n [[\"django\"], \"Django\"],\n [[\"flask\"], \"Flask\"],\n [[\"fastapi\"], \"FastAPI\"],\n [[\"@supabase/supabase-js\"], \"Supabase\"],\n [[\"prisma\", \"@prisma/client\"], \"Prisma\"],\n [[\"drizzle-orm\"], \"Drizzle\"],\n [[\"tailwindcss\"], \"Tailwind CSS\"],\n ];\n\n const detected: string[] = [];\n for (const [packages, name] of frameworks) {\n if (packages.some((pkg) => deps.includes(pkg))) {\n detected.push(name);\n }\n }\n return detected.length > 0 ? detected.join(\" + \") : null;\n}\n\nfunction detectLanguage(dir: string, keyFiles: string[]): string | null {\n if (keyFiles.some((f) => f === \"tsconfig.json\")) return \"TypeScript\";\n if (keyFiles.some((f) => f === \"package.json\")) return \"JavaScript\";\n if (keyFiles.some((f) => f === \"pyproject.toml\" || f === \"setup.py\" || f === \"requirements.txt\")) return \"Python\";\n if (keyFiles.some((f) => f === \"Cargo.toml\")) return \"Rust\";\n if (keyFiles.some((f) => f === \"go.mod\")) return \"Go\";\n if (keyFiles.some((f) => f === \"Gemfile\")) return \"Ruby\";\n return null;\n}\n\nfunction extractEnvKeys(content: string): string[] {\n const keys: string[] = [];\n for (const line of content.split(\"\\n\")) {\n const match = line.match(/^([A-Z][A-Z0-9_]*)=/);\n if (match) keys.push(match[1]);\n }\n return keys;\n}\n\nexport async function scanProject(dir: string): Promise<ProjectProfile> {\n // Read package.json\n const pkg = await readJsonSafe(path.join(dir, \"package.json\")) as Record<string, unknown> | null;\n const deps = pkg?.dependencies ? Object.keys(pkg.dependencies as Record<string, string>) : [];\n const devDeps = pkg?.devDependencies ? Object.keys(pkg.devDependencies as Record<string, string>) : [];\n const allDeps = [...deps, ...devDeps];\n const scripts = (pkg?.scripts || {}) as Record<string, string>;\n\n // Detect key files\n const rootFiles = await listDirSafe(dir);\n const keyFiles = rootFiles.filter((f) =>\n [\n \"package.json\", \"tsconfig.json\", \"pyproject.toml\", \"setup.py\",\n \"requirements.txt\", \"Cargo.toml\", \"go.mod\", \"Gemfile\",\n \"docker-compose.yml\", \"Dockerfile\", \".env.example\", \".env\",\n \"README.md\", \"CLAUDE.md\",\n ].includes(f)\n );\n\n // Detect language & framework\n const language = detectLanguage(dir, keyFiles);\n const framework = detectFramework(allDeps);\n const typescript = keyFiles.includes(\"tsconfig.json\") || allDeps.includes(\"typescript\");\n\n // Test detection\n const testCommand = scripts.test && scripts.test !== 'echo \"Error: no test specified\" && exit 1'\n ? scripts.test : null;\n const hasTests = testCommand !== null ||\n await fileExists(path.join(dir, \"tests\")) ||\n await fileExists(path.join(dir, \"__tests__\")) ||\n await fileExists(path.join(dir, \"test\"));\n\n // Build & lint\n const buildCommand = scripts.build || null;\n const lintCommand = scripts.lint || null;\n\n // Structure\n const hasSrc = await fileExists(path.join(dir, \"src\"));\n const hasDocker = await fileExists(path.join(dir, \"docker-compose.yml\")) ||\n await fileExists(path.join(dir, \"Dockerfile\"));\n const hasCi = await fileExists(path.join(dir, \".github/workflows\"));\n\n // Env keys (from .env.example only — never read actual .env values)\n const hasEnvFile = await fileExists(path.join(dir, \".env\")) ||\n await fileExists(path.join(dir, \".env.example\"));\n let envKeys: string[] = [];\n const envExample = await readFileSafe(path.join(dir, \".env.example\"));\n if (envExample) {\n envKeys = extractEnvKeys(envExample);\n }\n\n // Existing .claude/ harness\n const claudeDir = path.join(dir, \".claude\");\n const hasClaudeDir = await fileExists(claudeDir);\n let existingClaudeMd: string | null = null;\n let existingSettings: Record<string, unknown> | null = null;\n let existingMcpConfig: Record<string, unknown> | null = null;\n let existingCommands: string[] = [];\n let existingRules: string[] = [];\n let existingSkills: string[] = [];\n let existingAgents: string[] = [];\n let mcpServerCount = 0;\n let claudeMdLineCount = 0;\n\n if (hasClaudeDir) {\n existingClaudeMd = await readFileSafe(path.join(claudeDir, \"CLAUDE.md\"));\n if (existingClaudeMd) {\n claudeMdLineCount = existingClaudeMd.split(\"\\n\").length;\n }\n\n existingSettings = await readJsonSafe(path.join(claudeDir, \"settings.json\"));\n existingMcpConfig = await readJsonSafe(path.join(dir, \".mcp.json\"));\n if (existingMcpConfig?.mcpServers) {\n mcpServerCount = Object.keys(existingMcpConfig.mcpServers as Record<string, unknown>).length;\n }\n\n existingCommands = (await listDirSafe(path.join(claudeDir, \"commands\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n existingRules = (await listDirSafe(path.join(claudeDir, \"rules\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n existingSkills = await listDirSafe(path.join(claudeDir, \"skills\"));\n existingAgents = (await listDirSafe(path.join(claudeDir, \"agents\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n }\n\n // Project name & description\n const name = (pkg?.name as string) || path.basename(dir);\n const description = (pkg?.description as string) || \"\";\n\n return {\n name,\n description,\n directory: dir,\n language,\n framework,\n typescript,\n dependencies: deps,\n devDependencies: devDeps,\n scripts,\n hasTests,\n testCommand,\n buildCommand,\n lintCommand,\n hasSrc,\n hasDocker,\n hasCi,\n hasEnvFile,\n envKeys,\n hasClaudeDir,\n existingClaudeMd,\n existingSettings,\n existingMcpConfig,\n existingCommands,\n existingRules,\n existingSkills,\n existingAgents,\n mcpServerCount,\n claudeMdLineCount,\n keyFiles,\n };\n}\n"],"mappings":"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","names":["Command","Command","chalk","fs","path","fs","path","Anthropic","OpenAI","path","fs","Anthropic","OpenAI","fs","path","fileURLToPath","loadRegistry","path","fs","Command","chalk","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","fileURLToPath","Command","confirm","chalk","fs","path","fileURLToPath","fs","path","loadRegistry","fileURLToPath","path","fs","Command","chalk","confirm","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/config.ts","../src/commands/describe.ts","../src/compiler/compile.ts","../src/compiler/prompt.ts","../src/adapter/claude-code.ts","../src/commands/list.ts","../src/commands/activate.ts","../src/commands/update-registry.ts","../src/commands/optimize.ts","../src/scanner/scan.ts","../src/commands/doctor.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { describeCommand } from \"./commands/describe.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { activateCommand } from \"./commands/activate.js\";\nimport { updateRegistryCommand } from \"./commands/update-registry.js\";\nimport { optimizeCommand } from \"./commands/optimize.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"kairn\")\n .description(\n \"Compile natural language intent into optimized Claude Code environments\"\n )\n .version(\"1.4.0\");\n\nprogram.addCommand(initCommand);\nprogram.addCommand(describeCommand);\nprogram.addCommand(optimizeCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(activateCommand);\nprogram.addCommand(updateRegistryCommand);\nprogram.addCommand(doctorCommand);\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { password, select } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { execFileSync } from \"child_process\";\nimport { loadConfig, saveConfig, getConfigPath } from \"../config.js\";\nimport type { KairnConfig, LLMProvider } from \"../types.js\";\n\nconst PROVIDER_MODELS: Record<LLMProvider, { name: string; models: { name: string; value: string }[] }> = {\n anthropic: {\n name: \"Anthropic\",\n models: [\n { name: \"Claude Sonnet 4.6 (recommended — fast, smart)\", value: \"claude-sonnet-4-6\" },\n { name: \"Claude Opus 4.6 (highest quality)\", value: \"claude-opus-4-6\" },\n { name: \"Claude Haiku 4.5 (fastest, cheapest)\", value: \"claude-haiku-4-5-20251001\" },\n ],\n },\n openai: {\n name: \"OpenAI\",\n models: [\n { name: \"GPT-4o (recommended)\", value: \"gpt-4o\" },\n { name: \"GPT-4o mini (faster, cheaper)\", value: \"gpt-4o-mini\" },\n { name: \"o3 (reasoning)\", value: \"o3\" },\n ],\n },\n google: {\n name: \"Google Gemini\",\n models: [\n { name: \"Gemini 2.5 Flash (recommended)\", value: \"gemini-2.5-flash-preview-05-20\" },\n { name: \"Gemini 2.5 Pro (highest quality)\", value: \"gemini-2.5-pro-preview-05-06\" },\n ],\n },\n};\n\nasync function verifyKey(provider: LLMProvider, apiKey: string, model: string): Promise<boolean> {\n try {\n if (provider === \"anthropic\") {\n const client = new Anthropic({ apiKey });\n await client.messages.create({\n model: \"claude-haiku-4-5-20251001\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n } else if (provider === \"openai\") {\n const client = new OpenAI({ apiKey });\n await client.chat.completions.create({\n model: \"gpt-4o-mini\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n } else if (provider === \"google\") {\n // Google uses OpenAI-compatible API\n const client = new OpenAI({\n apiKey,\n baseURL: \"https://generativelanguage.googleapis.com/v1beta/openai/\",\n });\n await client.chat.completions.create({\n model: \"gemini-2.5-flash-preview-05-20\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\nfunction detectClaudeCode(): boolean {\n try {\n execFileSync(\"which\", [\"claude\"], { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport const initCommand = new Command(\"init\")\n .description(\"Set up Kairn with your API key\")\n .action(async () => {\n console.log(chalk.cyan(\"\\n Kairn Setup\\n\"));\n\n const existing = await loadConfig();\n if (existing) {\n console.log(\n chalk.yellow(\" Config already exists at \") +\n chalk.dim(getConfigPath())\n );\n console.log(chalk.yellow(\" Running setup will overwrite it.\\n\"));\n }\n\n const provider = await select<LLMProvider>({\n message: \"LLM provider\",\n choices: [\n { name: \"Anthropic (Claude) — recommended\", value: \"anthropic\" as LLMProvider },\n { name: \"OpenAI (GPT)\", value: \"openai\" as LLMProvider },\n { name: \"Google (Gemini)\", value: \"google\" as LLMProvider },\n ],\n });\n\n const providerInfo = PROVIDER_MODELS[provider];\n\n const model = await select({\n message: \"Compilation model\",\n choices: providerInfo.models,\n });\n\n const apiKey = await password({\n message: `${providerInfo.name} API key`,\n mask: \"*\",\n });\n\n if (!apiKey) {\n console.log(chalk.red(\"\\n No API key provided. Aborting.\"));\n process.exit(1);\n }\n\n console.log(chalk.dim(\"\\n Verifying API key...\"));\n const valid = await verifyKey(provider, apiKey, model);\n\n if (!valid) {\n console.log(\n chalk.red(\" Invalid API key. Check your key and try again.\")\n );\n process.exit(1);\n }\n\n console.log(chalk.green(\" ✓ API key verified\"));\n\n const config: KairnConfig = {\n provider,\n api_key: apiKey,\n model,\n default_runtime: \"claude-code\",\n created_at: new Date().toISOString(),\n };\n\n await saveConfig(config);\n console.log(\n chalk.green(\" ✓ Config saved to \") + chalk.dim(getConfigPath())\n );\n console.log(\n chalk.dim(` ✓ Provider: ${providerInfo.name}, Model: ${model}`)\n );\n\n const hasClaude = detectClaudeCode();\n if (hasClaude) {\n console.log(chalk.green(\" ✓ Claude Code detected\"));\n } else {\n console.log(\n chalk.yellow(\n \" ⚠ Claude Code not found. Install it: npm install -g @anthropic-ai/claude-code\"\n )\n );\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.cyan(\" to create your first environment.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { KairnConfig } from \"./types.js\";\n\nconst KAIRN_DIR = path.join(os.homedir(), \".kairn\");\nconst CONFIG_PATH = path.join(KAIRN_DIR, \"config.json\");\nconst ENVS_DIR = path.join(KAIRN_DIR, \"envs\");\n\nexport function getKairnDir(): string {\n return KAIRN_DIR;\n}\n\nexport function getConfigPath(): string {\n return CONFIG_PATH;\n}\n\nexport function getEnvsDir(): string {\n return ENVS_DIR;\n}\n\nexport async function ensureDirs(): Promise<void> {\n await fs.mkdir(KAIRN_DIR, { recursive: true });\n await fs.mkdir(ENVS_DIR, { recursive: true });\n}\n\nexport async function loadConfig(): Promise<KairnConfig | null> {\n try {\n const data = await fs.readFile(CONFIG_PATH, \"utf-8\");\n const raw = JSON.parse(data) as Record<string, unknown>;\n\n // Handle old config format (v1.0.0: anthropic_api_key)\n if (raw.anthropic_api_key && !raw.provider) {\n return {\n provider: \"anthropic\",\n api_key: raw.anthropic_api_key as string,\n model: \"claude-sonnet-4-6\",\n default_runtime: \"claude-code\",\n created_at: (raw.created_at as string) || new Date().toISOString(),\n };\n }\n\n return raw as unknown as KairnConfig;\n } catch {\n return null;\n }\n}\n\nexport async function saveConfig(config: KairnConfig): Promise<void> {\n await ensureDirs();\n await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), \"utf-8\");\n}\n","import { Command } from \"commander\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { loadConfig } from \"../config.js\";\nimport { compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { fileURLToPath } from \"url\";\nimport type { RegistryTool } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nexport const describeCommand = new Command(\"describe\")\n .description(\"Describe your workflow and generate a Claude Code environment\")\n .argument(\"[intent]\", \"What you want your agent to do\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (intentArg: string | undefined, options: { yes?: boolean }) => {\n // 1. Check config\n const config = await loadConfig();\n if (!config) {\n console.log(\n chalk.red(\"\\n No config found. Run \") +\n chalk.bold(\"kairn init\") +\n chalk.red(\" first.\\n\")\n );\n process.exit(1);\n }\n\n // 2. Get intent\n const intent =\n intentArg ||\n (await input({\n message: \"What do you want your agent to do?\",\n }));\n\n if (!intent.trim()) {\n console.log(chalk.red(\"\\n No description provided. Aborting.\\n\"));\n process.exit(1);\n }\n\n // 3. Compile with progress\n console.log(\"\");\n let spec;\n try {\n spec = await compile(intent, (msg) => {\n process.stdout.write(`\\r ${chalk.dim(msg)} `);\n });\n process.stdout.write(\"\\r \\r\");\n } catch (err) {\n process.stdout.write(\"\\r \\r\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n Compilation failed: ${msg}\\n`));\n process.exit(1);\n }\n\n // 4. Show results\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(chalk.green(\"\\n ✓ Environment compiled\\n\"));\n console.log(chalk.cyan(\" Name: \") + spec.name);\n console.log(chalk.cyan(\" Description: \") + spec.description);\n console.log(chalk.cyan(\" Tools: \") + summary.toolCount);\n console.log(chalk.cyan(\" Commands: \") + summary.commandCount);\n console.log(chalk.cyan(\" Rules: \") + summary.ruleCount);\n console.log(chalk.cyan(\" Skills: \") + summary.skillCount);\n console.log(chalk.cyan(\" Agents: \") + summary.agentCount);\n\n if (spec.tools.length > 0) {\n console.log(chalk.dim(\"\\n Selected tools:\"));\n for (const tool of spec.tools) {\n const regTool = registry.find((t) => t.id === tool.tool_id);\n const name = regTool?.name || tool.tool_id;\n console.log(chalk.dim(` - ${name}: ${tool.reason}`));\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Plugins to install manually:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.yellow(` ${cmd}`));\n }\n }\n\n // 5. Confirm\n console.log(\"\");\n const proceed = options.yes || await confirm({\n message: \"Generate environment in current directory?\",\n default: true,\n });\n\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted. Environment saved to ~/.kairn/envs/\\n\"));\n return;\n }\n\n // 6. Write\n const targetDir = process.cwd();\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\"\\n ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(chalk.yellow(\"\\n API keys needed (set these environment variables):\\n\"));\n const seen = new Set<string>();\n for (const env of summary.envSetup) {\n if (seen.has(env.envVar)) continue;\n seen.add(env.envVar);\n console.log(chalk.bold(` export ${env.envVar}=\"your-key-here\"`));\n console.log(chalk.dim(` ${env.description}`));\n if (env.signupUrl) {\n console.log(chalk.dim(` Get one at: ${env.signupUrl}`));\n }\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\" Install plugins by running these in Claude Code:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.bold(` ${cmd}`));\n }\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport crypto from \"crypto\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { loadConfig, getEnvsDir, ensureDirs } from \"../config.js\";\nimport { SYSTEM_PROMPT } from \"./prompt.js\";\nimport type { EnvironmentSpec, RegistryTool, KairnConfig } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nfunction buildUserMessage(intent: string, registry: RegistryTool[]): string {\n const registrySummary = registry\n .map(\n (t) =>\n `- ${t.id} (${t.type}, tier ${t.tier}, auth: ${t.auth}): ${t.description} [best_for: ${t.best_for.join(\", \")}]`\n )\n .join(\"\\n\");\n\n return `## User Intent\\n\\n${intent}\\n\\n## Available Tool Registry\\n\\n${registrySummary}\\n\\nGenerate the EnvironmentSpec JSON now.`;\n}\n\nfunction parseSpecResponse(text: string): Omit<EnvironmentSpec, \"id\" | \"intent\" | \"created_at\"> {\n let cleaned = text.trim();\n // Strip markdown code fences\n if (cleaned.startsWith(\"```\")) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, \"\").replace(/\\n?```$/, \"\");\n }\n // Try to extract JSON if there's surrounding text\n const jsonMatch = cleaned.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n throw new Error(\n \"LLM response did not contain valid JSON. Try again or use a different model.\"\n );\n }\n try {\n return JSON.parse(jsonMatch[0]);\n } catch (err) {\n throw new Error(\n `Failed to parse LLM response as JSON: ${err instanceof Error ? err.message : String(err)}\\n` +\n `Response started with: ${cleaned.slice(0, 200)}...`\n );\n }\n}\n\nfunction classifyError(err: unknown, provider: string): string {\n const msg = err instanceof Error ? err.message : String(err);\n const status = (err as { status?: number })?.status;\n const code = (err as { code?: string })?.code;\n\n // Network errors\n if (code === \"ECONNREFUSED\" || code === \"ENOTFOUND\" || code === \"ETIMEDOUT\") {\n return `Network error: could not reach ${provider} API. Check your internet connection.`;\n }\n\n // Auth errors\n if (status === 401 || msg.includes(\"invalid\") && msg.includes(\"key\")) {\n return `Invalid API key for ${provider}. Run \\`kairn init\\` to reconfigure.`;\n }\n if (status === 403) {\n return `Access denied by ${provider}. Your API key may lack permissions for this model.`;\n }\n\n // Rate limiting\n if (status === 429 || msg.includes(\"rate limit\") || msg.includes(\"quota\")) {\n return `Rate limited by ${provider}. Wait a moment and try again, or switch to a cheaper model with \\`kairn init\\`.`;\n }\n\n // Model errors\n if (status === 404 || msg.includes(\"not found\") || msg.includes(\"does not exist\")) {\n return `Model not found on ${provider}. Run \\`kairn init\\` to select a valid model.`;\n }\n\n // Overloaded\n if (status === 529 || status === 503 || msg.includes(\"overloaded\")) {\n return `${provider} is temporarily overloaded. Try again in a few seconds.`;\n }\n\n // Token/context limit\n if (msg.includes(\"token\") && (msg.includes(\"limit\") || msg.includes(\"exceed\"))) {\n return `Request too large for the selected model. Try a shorter workflow description.`;\n }\n\n // Billing\n if (msg.includes(\"billing\") || msg.includes(\"payment\") || msg.includes(\"insufficient\")) {\n return `Billing issue with your ${provider} account. Check your account dashboard.`;\n }\n\n // Fallback\n return `${provider} API error: ${msg}`;\n}\n\nasync function callLLM(config: KairnConfig, userMessage: string): Promise<string> {\n if (config.provider === \"anthropic\") {\n const client = new Anthropic({ apiKey: config.api_key });\n try {\n const response = await client.messages.create({\n model: config.model,\n max_tokens: 8192,\n system: SYSTEM_PROMPT,\n messages: [{ role: \"user\", content: userMessage }],\n });\n const textBlock = response.content.find((block) => block.type === \"text\");\n if (!textBlock || textBlock.type !== \"text\") {\n throw new Error(\"No text response from compiler LLM\");\n }\n return textBlock.text;\n } catch (err) {\n throw new Error(classifyError(err, \"Anthropic\"));\n }\n } else if (config.provider === \"openai\" || config.provider === \"google\") {\n const providerName = config.provider === \"google\" ? \"Google\" : \"OpenAI\";\n const clientOptions: { apiKey: string; baseURL?: string } = { apiKey: config.api_key };\n if (config.provider === \"google\") {\n clientOptions.baseURL = \"https://generativelanguage.googleapis.com/v1beta/openai/\";\n }\n const client = new OpenAI(clientOptions);\n try {\n const response = await client.chat.completions.create({\n model: config.model,\n max_tokens: 8192,\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: userMessage },\n ],\n });\n const text = response.choices[0]?.message?.content;\n if (!text) {\n throw new Error(\"No text response from compiler LLM\");\n }\n return text;\n } catch (err) {\n throw new Error(classifyError(err, providerName));\n }\n }\n throw new Error(`Unsupported provider: ${config.provider}. Run \\`kairn init\\` to reconfigure.`);\n}\n\nfunction validateSpec(spec: EnvironmentSpec, onProgress?: (msg: string) => void): void {\n const warnings: string[] = [];\n\n if (spec.tools.length > 8) {\n warnings.push(`${spec.tools.length} MCP servers selected (recommended: ≤6)`);\n }\n\n if (spec.harness.claude_md) {\n const lines = spec.harness.claude_md.split('\\n').length;\n if (lines > 150) {\n warnings.push(`CLAUDE.md is ${lines} lines (recommended: ≤100)`);\n }\n }\n\n if (spec.harness.skills && Object.keys(spec.harness.skills).length > 5) {\n warnings.push(`${Object.keys(spec.harness.skills).length} skills (recommended: ≤3)`);\n }\n\n for (const warning of warnings) {\n onProgress?.(`⚠ ${warning}`);\n }\n}\n\nexport async function compile(\n intent: string,\n onProgress?: (msg: string) => void\n): Promise<EnvironmentSpec> {\n const config = await loadConfig();\n if (!config) {\n throw new Error(\"No config found. Run `kairn init` first.\");\n }\n\n onProgress?.(\"Loading tool registry...\");\n const registry = await loadRegistry();\n\n onProgress?.(`Compiling with ${config.provider} (${config.model})...`);\n const userMessage = buildUserMessage(intent, registry);\n const responseText = await callLLM(config, userMessage);\n\n onProgress?.(\"Parsing environment spec...\");\n const parsed = parseSpecResponse(responseText);\n\n const spec: EnvironmentSpec = {\n id: `env_${crypto.randomUUID()}`,\n intent,\n created_at: new Date().toISOString(),\n ...parsed,\n };\n\n validateSpec(spec, onProgress);\n\n // Save to ~/.kairn/envs/\n await ensureDirs();\n const envPath = path.join(getEnvsDir(), `${spec.id}.json`);\n await fs.writeFile(envPath, JSON.stringify(spec, null, 2), \"utf-8\");\n\n return spec;\n}\n","export const SYSTEM_PROMPT = `You are the Kairn environment compiler. Your job is to generate a minimal, optimal Claude Code agent environment from a user's natural language description of what they want their agent to do.\n\nYou will receive:\n1. The user's intent (what they want to build/do)\n2. A tool registry (available MCP servers, plugins, and hooks)\n\nYou must output a JSON object matching the EnvironmentSpec schema.\n\n## Core Principles\n\n- **Minimalism over completeness.** Fewer, well-chosen tools beat many generic ones. Each MCP server costs 500-2000 context tokens.\n- **Workflow-specific, not generic.** Every instruction, command, and rule must relate to the user's actual workflow.\n- **Concise CLAUDE.md.** Under 100 lines. No generic text like \"be helpful.\" Include build/test commands, reference docs/ and skills/.\n- **Security by default.** Always include deny rules for destructive commands and secret file access.\n\n## CLAUDE.md Template (mandatory structure)\n\nThe \\`claude_md\\` field MUST follow this exact structure (max 100 lines):\n\n\\`\\`\\`\n# {Project Name}\n\n## Purpose\n{one-line description}\n\n## Tech Stack\n{bullet list of frameworks/languages}\n\n## Commands\n{concrete build/test/lint/dev commands}\n\n## Architecture\n{brief folder structure, max 10 lines}\n\n## Conventions\n{3-5 specific coding rules}\n\n## Key Commands\n{list /project: commands with descriptions}\n\n## Output\n{where results go, key files}\n\\`\\`\\`\n\nDo not add generic filler. Every line must be specific to the user's workflow.\n\n## What You Must Always Include\n\n1. A concise, workflow-specific \\`claude_md\\` (the CLAUDE.md content)\n2. A \\`/project:help\\` command that explains the environment\n3. A \\`/project:tasks\\` command for task management via TODO.md\n4. A \\`docs/TODO.md\\` file for continuity\n5. A \\`docs/DECISIONS.md\\` file for architectural decisions\n6. A \\`docs/LEARNINGS.md\\` file for non-obvious discoveries\n7. A \\`rules/continuity.md\\` rule encouraging updates to DECISIONS.md and LEARNINGS.md\n8. A \\`rules/security.md\\` rule with essential security instructions\n9. settings.json with deny rules for \\`rm -rf\\`, \\`curl|sh\\`, reading \\`.env\\` and \\`secrets/\\`\n10. A \\`/project:status\\` command for code projects (uses ! for live git/test output)\n11. A \\`/project:fix\\` command for code projects (uses $ARGUMENTS for issue number)\n12. A \\`docs/SPRINT.md\\` file for sprint contracts (acceptance criteria, verification steps)\n\n## Shell-Integrated Commands\n\nCommands that reference live project state should use Claude Code's \\`!\\` prefix for shell output:\n\n\\`\\`\\`markdown\n# Example: .claude/commands/review.md\nReview the staged changes for quality and security:\n\n!git diff --staged\n\nRun tests and check for failures:\n\n!npm test 2>&1 | tail -20\n\nFocus on: security, error handling, test coverage.\n\\`\\`\\`\n\nUse \\`!\\` when a command needs: git status, test results, build output, or file listings.\n\n## Path-Scoped Rules\n\nFor code projects with multiple domains (API, frontend, tests), generate path-scoped rules using YAML frontmatter:\n\n\\`\\`\\`markdown\n# Example: rules/api.md\n---\npaths:\n - \"src/api/**\"\n - \"src/routes/**\"\n---\n- All handlers return { data, error } shape\n- Use Zod for request validation\n- Log errors with request ID context\n\\`\\`\\`\n\n\\`\\`\\`markdown\n# Example: rules/testing.md\n---\npaths:\n - \"tests/**\"\n - \"**/*.test.*\"\n - \"**/*.spec.*\"\n---\n- Use AAA pattern: Arrange-Act-Assert\n- One assertion per test when possible\n- Mock external dependencies, never real APIs\n\\`\\`\\`\n\nKeep \\`security.md\\` and \\`continuity.md\\` as unconditional (no paths frontmatter).\nOnly generate scoped rules when the workflow involves multiple code domains.\n\n## Hooks\n\nGenerate hooks in settings.json based on project type:\n\n**All code projects** — block destructive commands:\n\\`\\`\\`json\n{\n \"hooks\": {\n \"PreToolUse\": [{\n \"matcher\": \"Bash\",\n \"hooks\": [{\n \"type\": \"command\",\n \"command\": \"CMD=$(cat | jq -r '.tool_input.command // empty') && echo \\\\\"$CMD\\\\\" | grep -qiE 'rm\\\\\\\\s+-rf\\\\\\\\s+/|DROP\\\\\\\\s+TABLE|curl.*\\\\\\\\|\\\\\\\\s*sh' && echo 'Blocked destructive command' >&2 && exit 2 || true\"\n }]\n }]\n }\n}\n\\`\\`\\`\n\n**Projects with Prettier/ESLint/Black** — auto-format on write:\n\\`\\`\\`json\n{\n \"hooks\": {\n \"PostToolUse\": [{\n \"matcher\": \"Edit|Write\",\n \"hooks\": [{\n \"type\": \"command\",\n \"command\": \"FILE=$(cat | jq -r '.tool_input.file_path // empty') && [ -n \\\\\"$FILE\\\\\" ] && npx prettier --write \\\\\"$FILE\\\\\" 2>/dev/null || true\"\n }]\n }]\n }\n}\n\\`\\`\\`\n\nMerge hooks into the \\`settings\\` object alongside permissions. Choose the formatter hook based on detected dependencies (Prettier → prettier, ESLint → eslint, Black → black).\n\n## PostCompact Hook\n\nAll projects should include a PostCompact hook to restore context after compaction:\n\n\\`\\`\\`json\n{\n \"hooks\": {\n \"PostCompact\": [{\n \"matcher\": \"\",\n \"hooks\": [{\n \"type\": \"prompt\",\n \"prompt\": \"Re-read CLAUDE.md and docs/SPRINT.md (if it exists) to restore project context after compaction.\"\n }]\n }]\n }\n}\n\\`\\`\\`\n\nMerge this into the settings hooks alongside the PreToolUse and PostToolUse hooks.\n\n## Tool Selection Rules\n\n- Only select tools directly relevant to the described workflow\n- Prefer free tools (auth: \"none\") when quality is comparable\n- Tier 1 tools (Context7, Sequential Thinking, security-guidance) should be included in most environments\n- For tools requiring API keys (auth: \"api_key\"), use \\${ENV_VAR} syntax — never hardcode keys\n- Maximum 6-8 MCP servers to avoid context bloat\n- Include a \\`reason\\` for each selected tool explaining why it fits this workflow\n\n## Context Budget (STRICT)\n\n- MCP servers: maximum 6. Prefer fewer.\n- CLAUDE.md: maximum 100 lines.\n- Rules: maximum 5 files, each under 20 lines.\n- Skills: maximum 3. Only include directly relevant ones.\n- Agents: maximum 3. QA pipeline + one specialist.\n- Commands: no limit (loaded on demand, zero context cost).\n- Hooks: maximum 4 (auto-format, block-destructive, PostCompact, plus one contextual).\n\nIf the workflow doesn't clearly need a tool, DO NOT include it.\nEach MCP server costs 500-2000 tokens of context window.\n\n## For Code Projects, Additionally Include\n\n- \\`/project:plan\\` command (plan before coding)\n- \\`/project:review\\` command (review changes)\n- \\`/project:test\\` command (run and fix tests)\n- \\`/project:commit\\` command (conventional commits)\n- \\`/project:status\\` command (live git status, recent commits, TODO overview using ! prefix)\n- \\`/project:fix\\` command (takes $ARGUMENTS as issue number, plans fix, implements, tests, commits)\n- \\`/project:sprint\\` command (define acceptance criteria before coding, writes to docs/SPRINT.md)\n- A TDD skill using the 3-phase isolation pattern (RED → GREEN → REFACTOR):\n - RED: Write failing test only. Verify it FAILS.\n - GREEN: Write MINIMUM code to pass. Nothing extra.\n - REFACTOR: Improve while keeping tests green.\n Rules: never write tests and implementation in same step, AAA pattern, one assertion per test.\n- A multi-agent QA pipeline:\n - \\`@qa-orchestrator\\` (sonnet) — delegates to linter and e2e-tester, compiles QA report\n - \\`@linter\\` (haiku) — runs formatters, linters, security scanners\n - \\`@e2e-tester\\` (sonnet, only when Playwright is in tools) — browser-based QA via Playwright\n\n## For Research Projects, Additionally Include\n\n- \\`/project:research\\` command (deep research on a topic)\n- \\`/project:summarize\\` command (summarize findings)\n- A research-synthesis skill\n- A researcher agent\n\n## For Content/Writing Projects, Additionally Include\n\n- \\`/project:draft\\` command (write first draft)\n- \\`/project:edit\\` command (review and improve writing)\n- A writing-workflow skill\n\n## Output Schema\n\nReturn ONLY valid JSON matching this structure:\n\n\\`\\`\\`json\n{\n \"name\": \"short-kebab-case-name\",\n \"description\": \"One-line description of the environment\",\n \"tools\": [\n { \"tool_id\": \"id-from-registry\", \"reason\": \"why this tool fits\" }\n ],\n \"harness\": {\n \"claude_md\": \"The full CLAUDE.md content (under 100 lines)\",\n \"settings\": {\n \"permissions\": {\n \"allow\": [\"Bash(npm run *)\", \"Read\", \"Write\", \"Edit\"],\n \"deny\": [\"Bash(rm -rf *)\", \"Bash(curl * | sh)\", \"Read(./.env)\", \"Read(./secrets/**)\"]\n }\n },\n \"mcp_config\": {\n \"server-name\": { \"command\": \"npx\", \"args\": [\"...\"], \"env\": {} }\n },\n \"commands\": {\n \"help\": \"markdown content for /project:help\",\n \"tasks\": \"markdown content for /project:tasks\",\n \"status\": \"Show project status:\\\\n\\\\n!git status --short\\\\n\\\\n!git log --oneline -5\\\\n\\\\nRead TODO.md and summarize progress.\",\n \"fix\": \"Fix issue #$ARGUMENTS:\\\\n\\\\n1. Read the issue and understand the problem\\\\n2. Plan the fix\\\\n3. Implement the fix\\\\n4. Run tests:\\\\n\\\\n!npm test 2>&1 | tail -20\\\\n\\\\n5. Commit with: fix: resolve #$ARGUMENTS\",\n \"sprint\": \"Define a sprint contract for the next feature:\\\\n\\\\n1. Read docs/TODO.md for context:\\\\n\\\\n!cat docs/TODO.md 2>/dev/null\\\\n\\\\n2. Write a CONTRACT to docs/SPRINT.md with: feature name, acceptance criteria, verification steps, files to modify, scope estimate.\\\\n3. Do NOT start coding until contract is confirmed.\"\n },\n \"rules\": {\n \"continuity\": \"markdown content for continuity rule\",\n \"security\": \"markdown content for security rule\"\n },\n \"skills\": {\n \"skill-name/SKILL\": \"markdown content with YAML frontmatter\"\n },\n \"agents\": {\n \"qa-orchestrator\": \"---\\\\nname: qa-orchestrator\\\\ndescription: Orchestrates QA pipeline\\\\nmodel: sonnet\\\\n---\\\\nRun QA: delegate to @linter for static analysis, @e2e-tester for browser tests. Compile consolidated report.\",\n \"linter\": \"---\\\\nname: linter\\\\ndescription: Fast static analysis\\\\nmodel: haiku\\\\n---\\\\nRun available linters (eslint, prettier, biome, ruff, mypy, semgrep). Report issues.\",\n \"e2e-tester\": \"---\\\\nname: e2e-tester\\\\ndescription: Browser-based QA via Playwright\\\\nmodel: sonnet\\\\n---\\\\nTest user flows via Playwright. Verify behavior, not just DOM. Screenshot failures.\"\n },\n \"docs\": {\n \"TODO\": \"# TODO\\\\n\\\\n- [ ] First task based on workflow\",\n \"DECISIONS\": \"# Decisions\\\\n\\\\nArchitectural decisions for this project.\",\n \"LEARNINGS\": \"# Learnings\\\\n\\\\nNon-obvious discoveries and gotchas.\",\n \"SPRINT\": \"# Sprint Contract\\\\n\\\\nDefine acceptance criteria before starting work.\"\n }\n }\n}\n\\`\\`\\`\n\nDo not include any text outside the JSON object. Do not wrap in markdown code fences.`;\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport type { EnvironmentSpec, RegistryTool } from \"../types.js\";\n\nasync function writeFile(filePath: string, content: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, \"utf-8\");\n}\n\nexport function buildFileMap(spec: EnvironmentSpec): Map<string, string> {\n const files = new Map<string, string>();\n\n if (spec.harness.claude_md) {\n files.set(\".claude/CLAUDE.md\", spec.harness.claude_md);\n }\n if (spec.harness.settings && Object.keys(spec.harness.settings).length > 0) {\n files.set(\n \".claude/settings.json\",\n JSON.stringify(spec.harness.settings, null, 2)\n );\n }\n if (\n spec.harness.mcp_config &&\n Object.keys(spec.harness.mcp_config).length > 0\n ) {\n files.set(\n \".mcp.json\",\n JSON.stringify({ mcpServers: spec.harness.mcp_config }, null, 2)\n );\n }\n if (spec.harness.commands) {\n for (const [name, content] of Object.entries(spec.harness.commands)) {\n files.set(`.claude/commands/${name}.md`, content);\n }\n }\n if (spec.harness.rules) {\n for (const [name, content] of Object.entries(spec.harness.rules)) {\n files.set(`.claude/rules/${name}.md`, content);\n }\n }\n if (spec.harness.skills) {\n for (const [skillPath, content] of Object.entries(spec.harness.skills)) {\n files.set(`.claude/skills/${skillPath}.md`, content);\n }\n }\n if (spec.harness.agents) {\n for (const [name, content] of Object.entries(spec.harness.agents)) {\n files.set(`.claude/agents/${name}.md`, content);\n }\n }\n if (spec.harness.docs) {\n for (const [name, content] of Object.entries(spec.harness.docs)) {\n files.set(`.claude/docs/${name}.md`, content);\n }\n }\n\n return files;\n}\n\nexport async function writeEnvironment(\n spec: EnvironmentSpec,\n targetDir: string\n): Promise<string[]> {\n const claudeDir = path.join(targetDir, \".claude\");\n const written: string[] = [];\n\n // 1. CLAUDE.md\n if (spec.harness.claude_md) {\n const p = path.join(claudeDir, \"CLAUDE.md\");\n await writeFile(p, spec.harness.claude_md);\n written.push(\".claude/CLAUDE.md\");\n }\n\n // 2. settings.json\n if (spec.harness.settings && Object.keys(spec.harness.settings).length > 0) {\n const p = path.join(claudeDir, \"settings.json\");\n await writeFile(p, JSON.stringify(spec.harness.settings, null, 2));\n written.push(\".claude/settings.json\");\n }\n\n // 3. .mcp.json (project-scoped, goes in project root)\n if (\n spec.harness.mcp_config &&\n Object.keys(spec.harness.mcp_config).length > 0\n ) {\n const p = path.join(targetDir, \".mcp.json\");\n const mcpContent = { mcpServers: spec.harness.mcp_config };\n await writeFile(p, JSON.stringify(mcpContent, null, 2));\n written.push(\".mcp.json\");\n }\n\n // 4. Commands\n if (spec.harness.commands) {\n for (const [name, content] of Object.entries(spec.harness.commands)) {\n const p = path.join(claudeDir, \"commands\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/commands/${name}.md`);\n }\n }\n\n // 5. Rules\n if (spec.harness.rules) {\n for (const [name, content] of Object.entries(spec.harness.rules)) {\n const p = path.join(claudeDir, \"rules\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/rules/${name}.md`);\n }\n }\n\n // 6. Skills\n if (spec.harness.skills) {\n for (const [skillPath, content] of Object.entries(spec.harness.skills)) {\n const p = path.join(claudeDir, \"skills\", `${skillPath}.md`);\n await writeFile(p, content);\n written.push(`.claude/skills/${skillPath}.md`);\n }\n }\n\n // 7. Agents\n if (spec.harness.agents) {\n for (const [name, content] of Object.entries(spec.harness.agents)) {\n const p = path.join(claudeDir, \"agents\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/agents/${name}.md`);\n }\n }\n\n // 8. Docs\n if (spec.harness.docs) {\n for (const [name, content] of Object.entries(spec.harness.docs)) {\n const p = path.join(claudeDir, \"docs\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/docs/${name}.md`);\n }\n }\n\n return written;\n}\n\nexport interface EnvSetupInfo {\n toolName: string;\n envVar: string;\n description: string;\n signupUrl?: string;\n}\n\nexport function summarizeSpec(\n spec: EnvironmentSpec,\n registry: RegistryTool[]\n): {\n toolCount: number;\n commandCount: number;\n ruleCount: number;\n skillCount: number;\n agentCount: number;\n pluginCommands: string[];\n envSetup: EnvSetupInfo[];\n} {\n const pluginCommands: string[] = [];\n const envSetup: EnvSetupInfo[] = [];\n\n for (const selected of spec.tools) {\n const tool = registry.find((t) => t.id === selected.tool_id);\n if (!tool) continue;\n\n if (tool.install.plugin_command) {\n pluginCommands.push(tool.install.plugin_command);\n }\n\n if (tool.env_vars) {\n for (const ev of tool.env_vars) {\n envSetup.push({\n toolName: tool.name,\n envVar: ev.name,\n description: ev.description,\n signupUrl: tool.signup_url,\n });\n }\n }\n }\n\n return {\n toolCount: spec.tools.length,\n commandCount: Object.keys(spec.harness.commands || {}).length,\n ruleCount: Object.keys(spec.harness.rules || {}).length,\n skillCount: Object.keys(spec.harness.skills || {}).length,\n agentCount: Object.keys(spec.harness.agents || {}).length,\n pluginCommands,\n envSetup,\n };\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getEnvsDir } from \"../config.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\n\nexport const listCommand = new Command(\"list\")\n .description(\"Show saved environments\")\n .action(async () => {\n const envsDir = getEnvsDir();\n\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.dim(\"\\n No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n if (jsonFiles.length === 0) {\n console.log(chalk.dim(\"\\n No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n console.log(chalk.cyan(\"\\n Saved Environments\\n\"));\n\n for (const file of jsonFiles) {\n try {\n const data = await fs.readFile(path.join(envsDir, file), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n const date = new Date(spec.created_at).toLocaleDateString();\n const toolCount = spec.tools?.length ?? 0;\n\n console.log(chalk.bold(` ${spec.name}`));\n console.log(chalk.dim(` ${spec.description}`));\n console.log(\n chalk.dim(` ${date} · ${toolCount} tools · ${spec.id}`)\n );\n console.log(\"\");\n } catch {\n // Skip malformed files\n }\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getEnvsDir } from \"../config.js\";\nimport { writeEnvironment } from \"../adapter/claude-code.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\n\nexport const activateCommand = new Command(\"activate\")\n .description(\"Re-deploy a saved environment to the current directory\")\n .argument(\"<env_id>\", \"Environment ID (from kairn list)\")\n .action(async (envId: string) => {\n const envsDir = getEnvsDir();\n\n // Find the env file — accept full ID or partial match\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.red(\"\\n No saved environments found.\\n\"));\n process.exit(1);\n }\n\n const match = files.find(\n (f) => f === `${envId}.json` || f.startsWith(envId)\n );\n\n if (!match) {\n console.log(chalk.red(`\\n Environment \"${envId}\" not found.`));\n console.log(chalk.dim(\" Run kairn list to see saved environments.\\n\"));\n process.exit(1);\n }\n\n const data = await fs.readFile(path.join(envsDir, match), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n\n console.log(chalk.cyan(`\\n Activating: ${spec.name}`));\n console.log(chalk.dim(` ${spec.description}\\n`));\n\n const targetDir = process.cwd();\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\" ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst REGISTRY_URL =\n \"https://raw.githubusercontent.com/ashtonperlroth/kairn/main/src/registry/tools.json\";\n\nasync function getLocalRegistryPath(): Promise<string> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n await fs.access(candidate);\n return candidate;\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find local tools.json registry\");\n}\n\nexport const updateRegistryCommand = new Command(\"update-registry\")\n .description(\"Fetch the latest tool registry from GitHub\")\n .option(\"--url <url>\", \"Custom registry URL\")\n .action(async (options: { url?: string }) => {\n const url = options.url || REGISTRY_URL;\n\n console.log(chalk.dim(`\\n Fetching registry from ${url}...`));\n\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n console.log(\n chalk.red(` Failed to fetch registry: ${response.status} ${response.statusText}`)\n );\n console.log(\n chalk.dim(\" The remote registry may not be available yet.\")\n );\n console.log(\n chalk.dim(\" Your local registry is still active.\\n\")\n );\n return;\n }\n\n const text = await response.text();\n\n // Validate it's valid JSON and has the expected structure\n let tools: unknown[];\n try {\n tools = JSON.parse(text);\n if (!Array.isArray(tools)) throw new Error(\"Not an array\");\n if (tools.length === 0) throw new Error(\"Empty registry\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(` Invalid registry format: ${msg}\\n`));\n return;\n }\n\n const registryPath = await getLocalRegistryPath();\n\n // Back up existing registry\n const backupPath = registryPath + \".bak\";\n try {\n await fs.copyFile(registryPath, backupPath);\n } catch {\n // No existing file to back up\n }\n\n await fs.writeFile(registryPath, JSON.stringify(tools, null, 2), \"utf-8\");\n\n console.log(chalk.green(` ✓ Registry updated: ${tools.length} tools`));\n console.log(chalk.dim(` Saved to: ${registryPath}`));\n console.log(chalk.dim(` Backup: ${backupPath}\\n`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(` Network error: ${msg}`));\n console.log(chalk.dim(\" Your local registry is still active.\\n\"));\n }\n });\n","import { Command } from \"commander\";\nimport { input, confirm, checkbox } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { loadConfig } from \"../config.js\";\nimport { compile } from \"../compiler/compile.js\";\nimport {\n writeEnvironment,\n summarizeSpec,\n buildFileMap,\n} from \"../adapter/claude-code.js\";\nimport { scanProject } from \"../scanner/scan.js\";\nimport type { ProjectProfile } from \"../scanner/scan.js\";\nimport type { EnvironmentSpec, RegistryTool } from \"../types.js\";\n\ninterface FileDiff {\n path: string;\n status: \"new\" | \"modified\" | \"unchanged\";\n diff: string;\n}\n\nfunction simpleDiff(oldContent: string, newContent: string): string[] {\n const oldLines = oldContent.split(\"\\n\");\n const newLines = newContent.split(\"\\n\");\n const output: string[] = [];\n\n const maxLines = Math.max(oldLines.length, newLines.length);\n for (let i = 0; i < maxLines; i++) {\n const oldLine = oldLines[i];\n const newLine = newLines[i];\n\n if (oldLine === undefined) {\n output.push(chalk.green(`+ ${newLine}`));\n } else if (newLine === undefined) {\n output.push(chalk.red(`- ${oldLine}`));\n } else if (oldLine !== newLine) {\n output.push(chalk.red(`- ${oldLine}`));\n output.push(chalk.green(`+ ${newLine}`));\n }\n }\n\n return output;\n}\n\nasync function generateDiff(\n spec: EnvironmentSpec,\n targetDir: string\n): Promise<FileDiff[]> {\n const fileMap = buildFileMap(spec);\n const results: FileDiff[] = [];\n\n for (const [relativePath, newContent] of fileMap) {\n const absolutePath = path.join(targetDir, relativePath);\n let oldContent: string | null = null;\n try {\n oldContent = await fs.readFile(absolutePath, \"utf-8\");\n } catch {\n // File does not exist yet\n }\n\n if (oldContent === null) {\n results.push({\n path: relativePath,\n status: \"new\",\n diff: chalk.green(\"+ NEW FILE\"),\n });\n } else if (oldContent === newContent) {\n results.push({\n path: relativePath,\n status: \"unchanged\",\n diff: \"\",\n });\n } else {\n const diffLines = simpleDiff(oldContent, newContent);\n results.push({\n path: relativePath,\n status: \"modified\",\n diff: diffLines.join(\"\\n\"),\n });\n }\n }\n\n return results;\n}\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nfunction buildProfileSummary(profile: ProjectProfile): string {\n const lines: string[] = [];\n lines.push(`Project: ${profile.name}`);\n if (profile.description) lines.push(`Description: ${profile.description}`);\n if (profile.language) lines.push(`Language: ${profile.language}`);\n if (profile.framework) lines.push(`Framework: ${profile.framework}`);\n if (profile.dependencies.length > 0) {\n lines.push(`Dependencies: ${profile.dependencies.join(\", \")}`);\n }\n if (profile.testCommand) lines.push(`Test command: ${profile.testCommand}`);\n if (profile.buildCommand) lines.push(`Build command: ${profile.buildCommand}`);\n if (profile.lintCommand) lines.push(`Lint command: ${profile.lintCommand}`);\n if (profile.hasDocker) lines.push(\"Has Docker configuration\");\n if (profile.hasCi) lines.push(\"Has CI/CD (GitHub Actions)\");\n if (profile.envKeys.length > 0) {\n lines.push(`Env keys needed: ${profile.envKeys.join(\", \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction buildAuditSummary(profile: ProjectProfile): string {\n const lines: string[] = [];\n lines.push(`\\nExisting .claude/ harness found:`);\n lines.push(` CLAUDE.md: ${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? \" (⚠ over 200 — may degrade adherence)\" : \"\"}`);\n lines.push(` MCP servers: ${profile.mcpServerCount}`);\n lines.push(` Commands: ${profile.existingCommands.length > 0 ? profile.existingCommands.map(c => `/project:${c}`).join(\", \") : \"none\"}`);\n lines.push(` Rules: ${profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"}`);\n lines.push(` Skills: ${profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"}`);\n lines.push(` Agents: ${profile.existingAgents.length > 0 ? profile.existingAgents.join(\", \") : \"none\"}`);\n return lines.join(\"\\n\");\n}\n\nfunction buildOptimizeIntent(profile: ProjectProfile): string {\n const parts: string[] = [];\n\n parts.push(\"## Project Profile (scanned from actual codebase)\\n\");\n parts.push(buildProfileSummary(profile));\n\n if (profile.hasClaudeDir) {\n parts.push(buildAuditSummary(profile));\n\n if (profile.existingClaudeMd) {\n parts.push(`\\n## Existing CLAUDE.md Content\\n\\n${profile.existingClaudeMd}`);\n }\n\n parts.push(`\\n## Task\\n`);\n parts.push(\"Analyze this existing Claude Code environment and generate an OPTIMIZED version.\");\n parts.push(\"Preserve what works. Fix what's wrong. Add what's missing. Remove what's bloat.\");\n parts.push(\"Key optimizations to consider:\");\n parts.push(\"- Is CLAUDE.md under 100 lines? If not, move detail to rules/ or docs/\");\n parts.push(\"- Are the right MCP servers selected for these dependencies?\");\n parts.push(\"- Are there missing slash commands (help, tasks, plan, test, commit)?\");\n parts.push(\"- Are security rules present?\");\n parts.push(\"- Is there a continuity rule for session memory?\");\n parts.push(\"- Are there unnecessary MCP servers adding context bloat?\");\n parts.push(\"- Are hooks configured in settings.json for destructive command blocking?\");\n parts.push(\"- Are there path-scoped rules for different code domains (api, testing, frontend)?\");\n parts.push(\"- Does the project have a /project:status command with live git output?\");\n parts.push(\"- Is there a /project:fix command for issue-driven development?\");\n if (profile.claudeMdLineCount > 200) {\n parts.push(`- CLAUDE.md is ${profile.claudeMdLineCount} lines — needs aggressive trimming`);\n }\n if (!profile.existingCommands.includes(\"help\")) {\n parts.push(\"- Missing /project:help command\");\n }\n if (!profile.existingRules.includes(\"security\")) {\n parts.push(\"- Missing security rules\");\n }\n } else {\n parts.push(`\\n## Task\\n`);\n parts.push(\"Generate an optimal Claude Code environment for this existing project.\");\n parts.push(\"Use the scanned project profile — this is a real codebase, not a description.\");\n parts.push(\"The environment should match the actual tech stack, dependencies, and workflows.\");\n }\n\n return parts.join(\"\\n\");\n}\n\nexport const optimizeCommand = new Command(\"optimize\")\n .description(\"Scan an existing project and generate or optimize its Claude Code environment\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--audit-only\", \"Only audit the existing harness, don't generate changes\")\n .option(\"--diff\", \"Preview changes as a diff without writing\")\n .action(async (options: { yes?: boolean; auditOnly?: boolean; diff?: boolean }) => {\n const config = await loadConfig();\n if (!config) {\n console.log(\n chalk.red(\"\\n No config found. Run \") +\n chalk.bold(\"kairn init\") +\n chalk.red(\" first.\\n\")\n );\n process.exit(1);\n }\n\n const targetDir = process.cwd();\n\n // 1. Scan\n console.log(chalk.dim(\"\\n Scanning project...\"));\n const profile = await scanProject(targetDir);\n\n // 2. Show profile\n console.log(chalk.cyan(\"\\n Project Profile\\n\"));\n if (profile.language) console.log(chalk.dim(` Language: ${profile.language}`));\n if (profile.framework) console.log(chalk.dim(` Framework: ${profile.framework}`));\n console.log(chalk.dim(` Dependencies: ${profile.dependencies.length}`));\n if (profile.testCommand) console.log(chalk.dim(` Tests: ${profile.testCommand}`));\n if (profile.buildCommand) console.log(chalk.dim(` Build: ${profile.buildCommand}`));\n if (profile.hasDocker) console.log(chalk.dim(\" Docker: yes\"));\n if (profile.hasCi) console.log(chalk.dim(\" CI/CD: yes\"));\n if (profile.envKeys.length > 0) console.log(chalk.dim(` Env keys: ${profile.envKeys.join(\", \")}`));\n\n // 3. Audit existing harness\n if (profile.hasClaudeDir) {\n console.log(chalk.yellow(\"\\n Existing .claude/ harness detected\\n\"));\n console.log(chalk.dim(` CLAUDE.md: ${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? chalk.yellow(\" ⚠ bloated\") : chalk.green(\" ✓\")}`));\n console.log(chalk.dim(` MCP servers: ${profile.mcpServerCount}`));\n console.log(chalk.dim(` Commands: ${profile.existingCommands.length > 0 ? profile.existingCommands.map(c => c).join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Rules: ${profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Skills: ${profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Agents: ${profile.existingAgents.length > 0 ? profile.existingAgents.join(\", \") : \"none\"}`));\n\n // Quick audit checks\n const issues: string[] = [];\n if (profile.claudeMdLineCount > 200) issues.push(\"CLAUDE.md over 200 lines — move detail to rules/ or docs/\");\n if (!profile.existingCommands.includes(\"help\")) issues.push(\"Missing /project:help command\");\n if (!profile.existingRules.includes(\"security\")) issues.push(\"Missing security rules\");\n if (!profile.existingRules.includes(\"continuity\")) issues.push(\"Missing continuity rule for session memory\");\n if (profile.mcpServerCount > 8) issues.push(`${profile.mcpServerCount} MCP servers — may cause context bloat`);\n if (profile.mcpServerCount === 0 && profile.dependencies.length > 0) issues.push(\"No MCP servers configured\");\n if (profile.hasTests && !profile.existingCommands.includes(\"test\")) issues.push(\"Has tests but no /project:test command\");\n if (!profile.existingCommands.includes(\"tasks\")) issues.push(\"Missing /project:tasks command\");\n if (!profile.existingSettings?.hooks) issues.push(\"No hooks configured — missing destructive command blocking\");\n const scopedRules = profile.existingRules.filter(r => r !== \"security\" && r !== \"continuity\");\n if (profile.hasSrc && scopedRules.length === 0) issues.push(\"No path-scoped rules — consider adding api.md, testing.md, or frontend.md rules\");\n\n if (issues.length > 0) {\n console.log(chalk.yellow(\"\\n Issues Found:\\n\"));\n for (const issue of issues) {\n console.log(chalk.yellow(` ⚠ ${issue}`));\n }\n } else {\n console.log(chalk.green(\"\\n ✓ No obvious issues found\"));\n }\n\n if (options.auditOnly) {\n console.log(chalk.dim(\"\\n Audit complete. Run without --audit-only to generate optimized environment.\\n\"));\n return;\n }\n\n // Ask before overwriting\n if (!options.yes) {\n console.log(\"\");\n const proceed = await confirm({\n message: \"Generate optimized environment? This will overwrite existing .claude/ files.\",\n default: false,\n });\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n } else {\n console.log(chalk.dim(\"\\n No existing .claude/ directory found — generating from scratch.\\n\"));\n\n if (!options.yes) {\n const proceed = await confirm({\n message: \"Generate Claude Code environment for this project?\",\n default: true,\n });\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n }\n\n // 4. Compile with scanned profile\n const intent = buildOptimizeIntent(profile);\n let spec;\n try {\n spec = await compile(intent, (msg) => {\n process.stdout.write(`\\r ${chalk.dim(msg)} `);\n });\n process.stdout.write(\"\\r \\r\");\n } catch (err) {\n process.stdout.write(\"\\r \\r\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n Optimization failed: ${msg}\\n`));\n process.exit(1);\n }\n\n // 5. Show results\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(chalk.green(\" ✓ Environment compiled\\n\"));\n console.log(chalk.cyan(\" Name: \") + spec.name);\n console.log(chalk.cyan(\" Tools: \") + summary.toolCount);\n console.log(chalk.cyan(\" Commands: \") + summary.commandCount);\n console.log(chalk.cyan(\" Rules: \") + summary.ruleCount);\n console.log(chalk.cyan(\" Skills: \") + summary.skillCount);\n console.log(chalk.cyan(\" Agents: \") + summary.agentCount);\n\n if (spec.tools.length > 0) {\n console.log(chalk.dim(\"\\n Selected tools:\"));\n for (const tool of spec.tools) {\n const regTool = registry.find((t) => t.id === tool.tool_id);\n const name = regTool?.name || tool.tool_id;\n console.log(chalk.dim(` - ${name}: ${tool.reason}`));\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Plugins to install manually:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.yellow(` ${cmd}`));\n }\n }\n\n // 6. Diff preview or direct write\n if (options.diff) {\n const diffs = await generateDiff(spec, targetDir);\n const changedDiffs = diffs.filter((d) => d.status !== \"unchanged\");\n\n if (changedDiffs.length === 0) {\n console.log(chalk.green(\"\\n ✓ No changes needed — environment is already up to date.\\n\"));\n return;\n }\n\n console.log(chalk.cyan(\"\\n Changes preview:\\n\"));\n for (const d of changedDiffs) {\n console.log(chalk.cyan(` --- ${d.path}`));\n if (d.status === \"new\") {\n console.log(` ${d.diff}`);\n } else {\n for (const line of d.diff.split(\"\\n\")) {\n console.log(` ${line}`);\n }\n }\n console.log(\"\");\n }\n\n const apply = await confirm({\n message: \"Apply these changes?\",\n default: true,\n });\n if (!apply) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\"\\n ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(chalk.yellow(\"\\n API keys needed (set these environment variables):\\n\"));\n const seen = new Set<string>();\n for (const env of summary.envSetup) {\n if (seen.has(env.envVar)) continue;\n seen.add(env.envVar);\n console.log(chalk.bold(` export ${env.envVar}=\"your-key-here\"`));\n console.log(chalk.dim(` ${env.description}`));\n if (env.signupUrl) {\n console.log(chalk.dim(` Get one at: ${env.signupUrl}`));\n }\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\" Install plugins by running these in Claude Code:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.bold(` ${cmd}`));\n }\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\n\nexport interface ProjectProfile {\n // Core identity\n name: string;\n description: string;\n directory: string;\n\n // Language & framework\n language: string | null;\n framework: string | null;\n typescript: boolean;\n\n // Dependencies\n dependencies: string[];\n devDependencies: string[];\n\n // Scripts & commands\n scripts: Record<string, string>;\n hasTests: boolean;\n testCommand: string | null;\n buildCommand: string | null;\n lintCommand: string | null;\n\n // Project structure\n hasSrc: boolean;\n hasDocker: boolean;\n hasCi: boolean;\n hasEnvFile: boolean;\n envKeys: string[]; // from .env.example only — never read .env values\n\n // Existing harness\n hasClaudeDir: boolean;\n existingClaudeMd: string | null;\n existingSettings: Record<string, unknown> | null;\n existingMcpConfig: Record<string, unknown> | null;\n existingCommands: string[];\n existingRules: string[];\n existingSkills: string[];\n existingAgents: string[];\n mcpServerCount: number;\n claudeMdLineCount: number;\n\n // Key files found\n keyFiles: string[];\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readJsonSafe(p: string): Promise<Record<string, unknown> | null> {\n try {\n const data = await fs.readFile(p, \"utf-8\");\n return JSON.parse(data);\n } catch {\n return null;\n }\n}\n\nasync function readFileSafe(p: string): Promise<string | null> {\n try {\n return await fs.readFile(p, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nasync function listDirSafe(p: string): Promise<string[]> {\n try {\n const entries = await fs.readdir(p);\n return entries.filter((e) => !e.startsWith(\".\"));\n } catch {\n return [];\n }\n}\n\nfunction detectFramework(deps: string[]): string | null {\n const frameworks: [string[], string][] = [\n [[\"next\"], \"Next.js\"],\n [[\"nuxt\"], \"Nuxt\"],\n [[\"@remix-run/node\", \"@remix-run/react\"], \"Remix\"],\n [[\"svelte\", \"@sveltejs/kit\"], \"SvelteKit\"],\n [[\"express\"], \"Express\"],\n [[\"fastify\"], \"Fastify\"],\n [[\"hono\"], \"Hono\"],\n [[\"react\", \"react-dom\"], \"React\"],\n [[\"vue\"], \"Vue\"],\n [[\"angular\"], \"Angular\"],\n [[\"django\"], \"Django\"],\n [[\"flask\"], \"Flask\"],\n [[\"fastapi\"], \"FastAPI\"],\n [[\"@supabase/supabase-js\"], \"Supabase\"],\n [[\"prisma\", \"@prisma/client\"], \"Prisma\"],\n [[\"drizzle-orm\"], \"Drizzle\"],\n [[\"tailwindcss\"], \"Tailwind CSS\"],\n ];\n\n const detected: string[] = [];\n for (const [packages, name] of frameworks) {\n if (packages.some((pkg) => deps.includes(pkg))) {\n detected.push(name);\n }\n }\n return detected.length > 0 ? detected.join(\" + \") : null;\n}\n\nfunction detectLanguage(dir: string, keyFiles: string[]): string | null {\n if (keyFiles.some((f) => f === \"tsconfig.json\")) return \"TypeScript\";\n if (keyFiles.some((f) => f === \"package.json\")) return \"JavaScript\";\n if (keyFiles.some((f) => f === \"pyproject.toml\" || f === \"setup.py\" || f === \"requirements.txt\")) return \"Python\";\n if (keyFiles.some((f) => f === \"Cargo.toml\")) return \"Rust\";\n if (keyFiles.some((f) => f === \"go.mod\")) return \"Go\";\n if (keyFiles.some((f) => f === \"Gemfile\")) return \"Ruby\";\n return null;\n}\n\nfunction extractEnvKeys(content: string): string[] {\n const keys: string[] = [];\n for (const line of content.split(\"\\n\")) {\n const match = line.match(/^([A-Z][A-Z0-9_]*)=/);\n if (match) keys.push(match[1]);\n }\n return keys;\n}\n\nexport async function scanProject(dir: string): Promise<ProjectProfile> {\n // Read package.json\n const pkg = await readJsonSafe(path.join(dir, \"package.json\")) as Record<string, unknown> | null;\n const deps = pkg?.dependencies ? Object.keys(pkg.dependencies as Record<string, string>) : [];\n const devDeps = pkg?.devDependencies ? Object.keys(pkg.devDependencies as Record<string, string>) : [];\n const allDeps = [...deps, ...devDeps];\n const scripts = (pkg?.scripts || {}) as Record<string, string>;\n\n // Detect key files\n const rootFiles = await listDirSafe(dir);\n const keyFiles = rootFiles.filter((f) =>\n [\n \"package.json\", \"tsconfig.json\", \"pyproject.toml\", \"setup.py\",\n \"requirements.txt\", \"Cargo.toml\", \"go.mod\", \"Gemfile\",\n \"docker-compose.yml\", \"Dockerfile\", \".env.example\", \".env\",\n \"README.md\", \"CLAUDE.md\",\n ].includes(f)\n );\n\n // Detect language & framework\n const language = detectLanguage(dir, keyFiles);\n const framework = detectFramework(allDeps);\n const typescript = keyFiles.includes(\"tsconfig.json\") || allDeps.includes(\"typescript\");\n\n // Test detection\n const testCommand = scripts.test && scripts.test !== 'echo \"Error: no test specified\" && exit 1'\n ? scripts.test : null;\n const hasTests = testCommand !== null ||\n await fileExists(path.join(dir, \"tests\")) ||\n await fileExists(path.join(dir, \"__tests__\")) ||\n await fileExists(path.join(dir, \"test\"));\n\n // Build & lint\n const buildCommand = scripts.build || null;\n const lintCommand = scripts.lint || null;\n\n // Structure\n const hasSrc = await fileExists(path.join(dir, \"src\"));\n const hasDocker = await fileExists(path.join(dir, \"docker-compose.yml\")) ||\n await fileExists(path.join(dir, \"Dockerfile\"));\n const hasCi = await fileExists(path.join(dir, \".github/workflows\"));\n\n // Env keys (from .env.example only — never read actual .env values)\n const hasEnvFile = await fileExists(path.join(dir, \".env\")) ||\n await fileExists(path.join(dir, \".env.example\"));\n let envKeys: string[] = [];\n const envExample = await readFileSafe(path.join(dir, \".env.example\"));\n if (envExample) {\n envKeys = extractEnvKeys(envExample);\n }\n\n // Existing .claude/ harness\n const claudeDir = path.join(dir, \".claude\");\n const hasClaudeDir = await fileExists(claudeDir);\n let existingClaudeMd: string | null = null;\n let existingSettings: Record<string, unknown> | null = null;\n let existingMcpConfig: Record<string, unknown> | null = null;\n let existingCommands: string[] = [];\n let existingRules: string[] = [];\n let existingSkills: string[] = [];\n let existingAgents: string[] = [];\n let mcpServerCount = 0;\n let claudeMdLineCount = 0;\n\n if (hasClaudeDir) {\n existingClaudeMd = await readFileSafe(path.join(claudeDir, \"CLAUDE.md\"));\n if (existingClaudeMd) {\n claudeMdLineCount = existingClaudeMd.split(\"\\n\").length;\n }\n\n existingSettings = await readJsonSafe(path.join(claudeDir, \"settings.json\"));\n existingMcpConfig = await readJsonSafe(path.join(dir, \".mcp.json\"));\n if (existingMcpConfig?.mcpServers) {\n mcpServerCount = Object.keys(existingMcpConfig.mcpServers as Record<string, unknown>).length;\n }\n\n existingCommands = (await listDirSafe(path.join(claudeDir, \"commands\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n existingRules = (await listDirSafe(path.join(claudeDir, \"rules\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n existingSkills = await listDirSafe(path.join(claudeDir, \"skills\"));\n existingAgents = (await listDirSafe(path.join(claudeDir, \"agents\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n }\n\n // Project name & description\n const name = (pkg?.name as string) || path.basename(dir);\n const description = (pkg?.description as string) || \"\";\n\n return {\n name,\n description,\n directory: dir,\n language,\n framework,\n typescript,\n dependencies: deps,\n devDependencies: devDeps,\n scripts,\n hasTests,\n testCommand,\n buildCommand,\n lintCommand,\n hasSrc,\n hasDocker,\n hasCi,\n hasEnvFile,\n envKeys,\n hasClaudeDir,\n existingClaudeMd,\n existingSettings,\n existingMcpConfig,\n existingCommands,\n existingRules,\n existingSkills,\n existingAgents,\n mcpServerCount,\n claudeMdLineCount,\n keyFiles,\n };\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { scanProject } from \"../scanner/scan.js\";\nimport type { ProjectProfile } from \"../scanner/scan.js\";\n\ninterface Check {\n name: string;\n weight: number; // 1-3\n status: \"pass\" | \"warn\" | \"fail\";\n message: string;\n}\n\nfunction runChecks(profile: ProjectProfile): Check[] {\n const checks: Check[] = [];\n\n // CLAUDE.md existence and size\n if (!profile.existingClaudeMd) {\n checks.push({\n name: \"CLAUDE.md\",\n weight: 3,\n status: \"fail\",\n message: \"Missing CLAUDE.md\",\n });\n } else if (profile.claudeMdLineCount > 200) {\n checks.push({\n name: \"CLAUDE.md\",\n weight: 2,\n status: \"warn\",\n message: `${profile.claudeMdLineCount} lines (recommended: ≤100)`,\n });\n } else {\n checks.push({\n name: \"CLAUDE.md\",\n weight: 3,\n status: \"pass\",\n message: `${profile.claudeMdLineCount} lines`,\n });\n }\n\n // Settings.json with deny rules\n if (!profile.existingSettings) {\n checks.push({\n name: \"settings.json\",\n weight: 2,\n status: \"fail\",\n message: \"Missing settings.json\",\n });\n } else {\n const perms = profile.existingSettings.permissions as\n | Record<string, unknown>\n | undefined;\n const hasDeny =\n perms?.deny &&\n Array.isArray(perms.deny) &&\n (perms.deny as string[]).length > 0;\n checks.push({\n name: \"Deny rules\",\n weight: 2,\n status: hasDeny ? \"pass\" : \"warn\",\n message: hasDeny\n ? \"Deny rules configured\"\n : \"No deny rules in settings.json\",\n });\n }\n\n // MCP server count\n if (profile.mcpServerCount > 8) {\n checks.push({\n name: \"MCP servers\",\n weight: 1,\n status: \"warn\",\n message: `${profile.mcpServerCount} servers (recommended: ≤8)`,\n });\n } else if (profile.mcpServerCount > 0) {\n checks.push({\n name: \"MCP servers\",\n weight: 1,\n status: \"pass\",\n message: `${profile.mcpServerCount} servers`,\n });\n } else {\n checks.push({\n name: \"MCP servers\",\n weight: 1,\n status: \"warn\",\n message: \"No MCP servers configured\",\n });\n }\n\n // /project:help command\n checks.push({\n name: \"/project:help\",\n weight: 2,\n status: profile.existingCommands.includes(\"help\") ? \"pass\" : \"fail\",\n message: profile.existingCommands.includes(\"help\")\n ? \"Help command present\"\n : \"Missing /project:help command\",\n });\n\n // /project:tasks command\n checks.push({\n name: \"/project:tasks\",\n weight: 1,\n status: profile.existingCommands.includes(\"tasks\") ? \"pass\" : \"warn\",\n message: profile.existingCommands.includes(\"tasks\")\n ? \"Tasks command present\"\n : \"Missing /project:tasks command\",\n });\n\n // Security rule\n checks.push({\n name: \"Security rule\",\n weight: 3,\n status: profile.existingRules.includes(\"security\") ? \"pass\" : \"fail\",\n message: profile.existingRules.includes(\"security\")\n ? \"Security rule present\"\n : \"Missing rules/security.md\",\n });\n\n // Continuity rule\n checks.push({\n name: \"Continuity rule\",\n weight: 2,\n status: profile.existingRules.includes(\"continuity\") ? \"pass\" : \"warn\",\n message: profile.existingRules.includes(\"continuity\")\n ? \"Continuity rule present\"\n : \"Missing rules/continuity.md\",\n });\n\n // Hooks\n const hasHooks = profile.existingSettings?.hooks;\n checks.push({\n name: \"Hooks\",\n weight: 1,\n status: hasHooks ? \"pass\" : \"warn\",\n message: hasHooks ? \"Hooks configured\" : \"No hooks in settings.json\",\n });\n\n // .env protection\n const perms = profile.existingSettings?.permissions as\n | Record<string, unknown>\n | undefined;\n const denyList = (perms?.deny as string[] | undefined) || [];\n const envProtected = denyList.some((d: string) => d.includes(\".env\"));\n checks.push({\n name: \".env protection\",\n weight: 2,\n status: envProtected ? \"pass\" : \"warn\",\n message: envProtected ? \".env in deny list\" : \".env not in deny list\",\n });\n\n // CLAUDE.md sections check (if exists)\n if (profile.existingClaudeMd) {\n const requiredSections = [\"## Purpose\", \"## Commands\", \"## Tech Stack\"];\n const missingSections = requiredSections.filter(\n (s) => !profile.existingClaudeMd!.includes(s)\n );\n if (missingSections.length > 0) {\n checks.push({\n name: \"CLAUDE.md sections\",\n weight: 1,\n status: \"warn\",\n message: `Missing: ${missingSections.join(\", \")}`,\n });\n } else {\n checks.push({\n name: \"CLAUDE.md sections\",\n weight: 1,\n status: \"pass\",\n message: \"Required sections present\",\n });\n }\n }\n\n return checks;\n}\n\nexport const doctorCommand = new Command(\"doctor\")\n .description(\n \"Validate the current Claude Code environment against best practices\"\n )\n .action(async () => {\n const targetDir = process.cwd();\n\n console.log(chalk.dim(\"\\n Checking .claude/ environment...\\n\"));\n\n const profile = await scanProject(targetDir);\n\n if (!profile.hasClaudeDir) {\n console.log(chalk.red(\" ❌ No .claude/ directory found.\\n\"));\n console.log(\n chalk.dim(\" Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" or \") +\n chalk.bold(\"kairn optimize\") +\n chalk.dim(\" to generate one.\\n\")\n );\n process.exit(1);\n }\n\n const checks = runChecks(profile);\n\n // Display results\n for (const check of checks) {\n const icon =\n check.status === \"pass\"\n ? chalk.green(\"✅\")\n : check.status === \"warn\"\n ? chalk.yellow(\"⚠️ \")\n : chalk.red(\"❌\");\n const msg =\n check.status === \"pass\"\n ? chalk.dim(check.message)\n : check.status === \"warn\"\n ? chalk.yellow(check.message)\n : chalk.red(check.message);\n console.log(` ${icon} ${check.name}: ${msg}`);\n }\n\n // Calculate score\n const maxScore = checks.reduce((sum, c) => sum + c.weight, 0);\n const score = checks.reduce((sum, c) => {\n if (c.status === \"pass\") return sum + c.weight;\n if (c.status === \"warn\") return sum + Math.floor(c.weight / 2);\n return sum;\n }, 0);\n\n const percentage = Math.round((score / maxScore) * 100);\n const scoreColor =\n percentage >= 80\n ? chalk.green\n : percentage >= 50\n ? chalk.yellow\n : chalk.red;\n\n console.log(\n `\\n Score: ${scoreColor(`${score}/${maxScore}`)} (${scoreColor(`${percentage}%`)})\\n`\n );\n\n if (percentage < 80) {\n console.log(\n chalk.dim(\" Run \") +\n chalk.bold(\"kairn optimize\") +\n chalk.dim(\" to fix issues.\\n\")\n );\n }\n });\n"],"mappings":"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","names":["Command","Command","chalk","fs","path","fs","path","Anthropic","OpenAI","path","fs","Anthropic","OpenAI","fs","path","fileURLToPath","loadRegistry","path","fs","Command","chalk","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","fileURLToPath","Command","confirm","chalk","fs","path","fileURLToPath","fs","path","chalk","path","fs","loadRegistry","fileURLToPath","Command","confirm","Command","chalk","perms","Command","chalk","Command"]}
|