kairn-cli 1.6.0 → 1.7.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 +65 -13
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/src/registry/templates/api-service.json +9 -2
- package/src/registry/templates/content-writing.json +1 -1
- package/src/registry/templates/nextjs-fullstack.json +9 -2
- package/src/registry/templates/research-project.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -362,12 +362,12 @@ You must output a JSON object matching the EnvironmentSpec schema.
|
|
|
362
362
|
|
|
363
363
|
- **Minimalism over completeness.** Fewer, well-chosen tools beat many generic ones. Each MCP server costs 500-2000 context tokens.
|
|
364
364
|
- **Workflow-specific, not generic.** Every instruction, command, and rule must relate to the user's actual workflow.
|
|
365
|
-
- **Concise CLAUDE.md.** Under
|
|
365
|
+
- **Concise CLAUDE.md.** Under 120 lines. No generic text like "be helpful." Include build/test commands, reference docs/ and skills/.
|
|
366
366
|
- **Security by default.** Always include deny rules for destructive commands and secret file access.
|
|
367
367
|
|
|
368
368
|
## CLAUDE.md Template (mandatory structure)
|
|
369
369
|
|
|
370
|
-
The \`claude_md\` field MUST follow this exact structure (max
|
|
370
|
+
The \`claude_md\` field MUST follow this exact structure (max 120 lines):
|
|
371
371
|
|
|
372
372
|
\`\`\`
|
|
373
373
|
# {Project Name}
|
|
@@ -392,6 +392,30 @@ The \`claude_md\` field MUST follow this exact structure (max 100 lines):
|
|
|
392
392
|
|
|
393
393
|
## Output
|
|
394
394
|
{where results go, key files}
|
|
395
|
+
|
|
396
|
+
## Verification
|
|
397
|
+
After implementing any change, verify it works:
|
|
398
|
+
- {build command} \u2014 must pass with no errors
|
|
399
|
+
- {test command} \u2014 all tests must pass
|
|
400
|
+
- {lint command} \u2014 no warnings or errors
|
|
401
|
+
- {type check command} \u2014 no type errors
|
|
402
|
+
|
|
403
|
+
If any verification step fails, fix the issue before moving on.
|
|
404
|
+
Do NOT skip verification steps.
|
|
405
|
+
|
|
406
|
+
## Known Gotchas
|
|
407
|
+
<!-- After any correction, add it here: "Update CLAUDE.md so you don't make that mistake again." -->
|
|
408
|
+
<!-- Prune this section when it exceeds 10 items \u2014 keep only the recurring ones. -->
|
|
409
|
+
- (none yet \u2014 this section grows as you work)
|
|
410
|
+
|
|
411
|
+
## Debugging
|
|
412
|
+
When debugging, paste raw error output. Don't summarize \u2014 Claude works better with raw data.
|
|
413
|
+
Use subagents for deep investigation to keep main context clean.
|
|
414
|
+
|
|
415
|
+
## Git Workflow
|
|
416
|
+
- Prefer small, focused commits (one feature or fix per commit)
|
|
417
|
+
- Use conventional commits: feat:, fix:, docs:, refactor:, test:
|
|
418
|
+
- Target < 200 lines per PR when possible
|
|
395
419
|
\`\`\`
|
|
396
420
|
|
|
397
421
|
Do not add generic filler. Every line must be specific to the user's workflow.
|
|
@@ -410,6 +434,10 @@ Do not add generic filler. Every line must be specific to the user's workflow.
|
|
|
410
434
|
10. A \`/project:status\` command for code projects (uses ! for live git/test output)
|
|
411
435
|
11. A \`/project:fix\` command for code projects (uses $ARGUMENTS for issue number)
|
|
412
436
|
12. A \`docs/SPRINT.md\` file for sprint contracts (acceptance criteria, verification steps)
|
|
437
|
+
13. A "Verification" section in CLAUDE.md with concrete verify commands for the project
|
|
438
|
+
14. A "Known Gotchas" section in CLAUDE.md (starts empty, grows with corrections)
|
|
439
|
+
15. A "Debugging" section in CLAUDE.md (2 lines: paste raw errors, use subagents)
|
|
440
|
+
16. A "Git Workflow" section in CLAUDE.md (3 rules: small commits, conventional format, <200 lines PR)
|
|
413
441
|
|
|
414
442
|
## Shell-Integrated Commands
|
|
415
443
|
|
|
@@ -530,7 +558,7 @@ Merge this into the settings hooks alongside the PreToolUse and PostToolUse hook
|
|
|
530
558
|
## Context Budget (STRICT)
|
|
531
559
|
|
|
532
560
|
- MCP servers: maximum 6. Prefer fewer.
|
|
533
|
-
- CLAUDE.md: maximum
|
|
561
|
+
- CLAUDE.md: maximum 120 lines.
|
|
534
562
|
- Rules: maximum 5 files, each under 20 lines.
|
|
535
563
|
- Skills: maximum 3. Only include directly relevant ones.
|
|
536
564
|
- Agents: maximum 3. QA pipeline + one specialist.
|
|
@@ -558,6 +586,10 @@ Each MCP server costs 500-2000 tokens of context window.
|
|
|
558
586
|
- \`@qa-orchestrator\` (sonnet) \u2014 delegates to linter and e2e-tester, compiles QA report
|
|
559
587
|
- \`@linter\` (haiku) \u2014 runs formatters, linters, security scanners
|
|
560
588
|
- \`@e2e-tester\` (sonnet, only when Playwright is in tools) \u2014 browser-based QA via Playwright
|
|
589
|
+
- \`/project:spec\` command (interview-based spec creation \u2014 asks 5-8 questions one at a time, writes structured spec to docs/SPRINT.md, does NOT start coding until confirmed)
|
|
590
|
+
- \`/project:prove\` command (runs tests, shows git diff vs main, rates confidence HIGH/MEDIUM/LOW with evidence)
|
|
591
|
+
- \`/project:grill\` command (adversarial code review \u2014 challenges each change with "why this approach?", "what if X input?", rates BLOCKER/SHOULD-FIX/NITPICK, blocks until BLOCKERs resolved)
|
|
592
|
+
- \`/project:reset\` command (reads DECISIONS.md and LEARNINGS.md, proposes clean restart, stashes current work, implements elegant solution)
|
|
561
593
|
|
|
562
594
|
## For Research Projects, Additionally Include
|
|
563
595
|
|
|
@@ -565,6 +597,7 @@ Each MCP server costs 500-2000 tokens of context window.
|
|
|
565
597
|
- \`/project:summarize\` command (summarize findings)
|
|
566
598
|
- A research-synthesis skill
|
|
567
599
|
- A researcher agent
|
|
600
|
+
- Note: the Verification section in CLAUDE.md should adapt for research \u2014 e.g. "Verify all sources are cited" instead of build/test commands
|
|
568
601
|
|
|
569
602
|
## For Content/Writing Projects, Additionally Include
|
|
570
603
|
|
|
@@ -593,7 +626,7 @@ Return ONLY valid JSON matching this structure:
|
|
|
593
626
|
{ "tool_id": "id-from-registry", "reason": "why this tool fits" }
|
|
594
627
|
],
|
|
595
628
|
"harness": {
|
|
596
|
-
"claude_md": "The full CLAUDE.md content (under
|
|
629
|
+
"claude_md": "The full CLAUDE.md content (under 120 lines)",
|
|
597
630
|
"settings": {
|
|
598
631
|
"permissions": {
|
|
599
632
|
"allow": ["Bash(npm run *)", "Read", "Write", "Edit"],
|
|
@@ -608,7 +641,11 @@ Return ONLY valid JSON matching this structure:
|
|
|
608
641
|
"tasks": "markdown content for /project:tasks",
|
|
609
642
|
"status": "Show project status:\\n\\n!git status --short\\n\\n!git log --oneline -5\\n\\nRead TODO.md and summarize progress.",
|
|
610
643
|
"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",
|
|
611
|
-
"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."
|
|
644
|
+
"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.",
|
|
645
|
+
"spec": "Before building this feature, interview me to create a complete spec.\\n\\nAsk me 5-8 questions, one at a time:\\n1. What specifically should this feature do?\\n2. Who uses it and how?\\n3. What are the edge cases or error states?\\n4. How will we know it works? (acceptance criteria)\\n5. What should it explicitly NOT do? (scope boundaries)\\n6. Any dependencies, APIs, or constraints?\\n7. How does it fit with existing code?\\n8. Priority: speed, quality, or flexibility?\\n\\nAfter my answers, write a structured spec to docs/SPRINT.md:\\n- Feature name\\n- Description (from my answers, not invented)\\n- Acceptance criteria (testable)\\n- Out of scope\\n- Technical approach\\n\\nDo NOT start coding until I confirm the spec.",
|
|
646
|
+
"prove": "Prove the current implementation works.\\n\\n1. Run the full test suite:\\n\\n!npm test 2>&1\\n\\n2. Compare against main:\\n\\n!git diff main --stat 2>/dev/null\\n\\n3. Show evidence:\\n - Test results (pass/fail counts)\\n - Behavioral diff (main vs this branch)\\n - Edge cases tested\\n - Error handling verified\\n\\n4. Rate confidence:\\n - HIGH: All tests pass, edge cases covered, no regressions\\n - MEDIUM: Core works, some edges untested\\n - LOW: Needs more verification\\n\\nIf LOW or MEDIUM, explain what's missing and fix it.",
|
|
647
|
+
"grill": "Review the current changes adversarially.\\n\\n!git diff --staged 2>/dev/null || git diff HEAD 2>/dev/null\\n\\nAct as a senior engineer. For each file changed:\\n\\n1. \\"Why this approach over X?\\"\\n2. \\"What happens if Y input?\\"\\n3. \\"Performance impact of Z?\\"\\n4. \\"This could break if...\\"\\n\\nFor each concern:\\n- Severity: BLOCKER / SHOULD-FIX / NITPICK\\n- The exact scenario that could fail\\n- A suggested alternative\\n\\nDo NOT approve until all BLOCKERs are resolved.",
|
|
648
|
+
"reset": "Stop. Read docs/DECISIONS.md and docs/LEARNINGS.md.\\n\\nConsidering everything we've learned:\\n1. What was the original approach?\\n2. What went wrong or feels inelegant?\\n3. What would the clean solution look like?\\n\\nPropose the new approach. Do NOT implement yet.\\nIf I approve, stash current changes:\\n git stash -m \\"pre-reset: $(date +%Y%m%d-%H%M)\\"\\n\\nThen implement the elegant solution."
|
|
612
649
|
},
|
|
613
650
|
"rules": {
|
|
614
651
|
"continuity": "markdown content for continuity rule",
|
|
@@ -882,6 +919,22 @@ async function generateClarifications(intent, onProgress) {
|
|
|
882
919
|
// src/adapter/claude-code.ts
|
|
883
920
|
import fs5 from "fs/promises";
|
|
884
921
|
import path5 from "path";
|
|
922
|
+
var STATUS_LINE = {
|
|
923
|
+
command: `printf '%s | %s tasks' "$(git branch --show-current 2>/dev/null || echo 'no-git')" "$(grep -c '\\- \\[ \\]' docs/TODO.md 2>/dev/null || echo 0)"`
|
|
924
|
+
};
|
|
925
|
+
function isCodeProject(spec) {
|
|
926
|
+
const commands = spec.harness.commands ?? {};
|
|
927
|
+
return "status" in commands || "test" in commands;
|
|
928
|
+
}
|
|
929
|
+
function resolveSettings(spec) {
|
|
930
|
+
const settings = spec.harness.settings;
|
|
931
|
+
if (!settings || Object.keys(settings).length === 0) return null;
|
|
932
|
+
if ("statusLine" in settings) return settings;
|
|
933
|
+
if (isCodeProject(spec)) {
|
|
934
|
+
return { ...settings, statusLine: STATUS_LINE };
|
|
935
|
+
}
|
|
936
|
+
return settings;
|
|
937
|
+
}
|
|
885
938
|
async function writeFile(filePath, content) {
|
|
886
939
|
await fs5.mkdir(path5.dirname(filePath), { recursive: true });
|
|
887
940
|
await fs5.writeFile(filePath, content, "utf-8");
|
|
@@ -891,11 +944,9 @@ function buildFileMap(spec) {
|
|
|
891
944
|
if (spec.harness.claude_md) {
|
|
892
945
|
files.set(".claude/CLAUDE.md", spec.harness.claude_md);
|
|
893
946
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
JSON.stringify(spec.harness.settings, null, 2)
|
|
898
|
-
);
|
|
947
|
+
const resolvedSettings = resolveSettings(spec);
|
|
948
|
+
if (resolvedSettings) {
|
|
949
|
+
files.set(".claude/settings.json", JSON.stringify(resolvedSettings, null, 2));
|
|
899
950
|
}
|
|
900
951
|
if (spec.harness.mcp_config && Object.keys(spec.harness.mcp_config).length > 0) {
|
|
901
952
|
files.set(
|
|
@@ -938,9 +989,10 @@ async function writeEnvironment(spec, targetDir) {
|
|
|
938
989
|
await writeFile(p, spec.harness.claude_md);
|
|
939
990
|
written.push(".claude/CLAUDE.md");
|
|
940
991
|
}
|
|
941
|
-
|
|
992
|
+
const resolvedSettings = resolveSettings(spec);
|
|
993
|
+
if (resolvedSettings) {
|
|
942
994
|
const p = path5.join(claudeDir, "settings.json");
|
|
943
|
-
await writeFile(p, JSON.stringify(
|
|
995
|
+
await writeFile(p, JSON.stringify(resolvedSettings, null, 2));
|
|
944
996
|
written.push(".claude/settings.json");
|
|
945
997
|
}
|
|
946
998
|
if (spec.harness.mcp_config && Object.keys(spec.harness.mcp_config).length > 0) {
|
|
@@ -2363,7 +2415,7 @@ var templatesCommand = new Command9("templates").description("Browse available t
|
|
|
2363
2415
|
var program = new Command10();
|
|
2364
2416
|
program.name("kairn").description(
|
|
2365
2417
|
"Compile natural language intent into optimized Claude Code environments"
|
|
2366
|
-
).version("1.
|
|
2418
|
+
).version("1.7.0").option("--no-color", "Disable colored output");
|
|
2367
2419
|
program.addCommand(initCommand);
|
|
2368
2420
|
program.addCommand(describeCommand);
|
|
2369
2421
|
program.addCommand(optimizeCommand);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/config.ts","../src/ui.ts","../src/logo.ts","../src/commands/describe.ts","../src/compiler/compile.ts","../src/compiler/prompt.ts","../src/registry/loader.ts","../src/adapter/claude-code.ts","../src/adapter/hermes-agent.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","../src/commands/registry.ts","../src/commands/templates.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\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\";\nimport { registryCommand } from \"./commands/registry.js\";\nimport { templatesCommand } from \"./commands/templates.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.6.0\")\n .option(\"--no-color\", \"Disable colored output\");\n\nprogram.addCommand(initCommand);\nprogram.addCommand(describeCommand);\nprogram.addCommand(optimizeCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(activateCommand);\nprogram.addCommand(updateRegistryCommand);\nprogram.addCommand(doctorCommand);\nprogram.addCommand(registryCommand);\nprogram.addCommand(templatesCommand);\n\n// Check for --no-color before parsing (Commander handles it but chalk needs manual disable)\nif (process.argv.includes(\"--no-color\") || process.env.NO_COLOR) {\n chalk.level = 0;\n}\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 fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { loadConfig, saveConfig, getConfigPath, getTemplatesDir } from \"../config.js\";\nimport type { KairnConfig, LLMProvider } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printFullBanner } from \"../logo.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nasync function installSeedTemplates(): Promise<void> {\n const templatesDir = getTemplatesDir();\n await fs.mkdir(templatesDir, { recursive: true });\n\n const candidates = [\n path.resolve(__dirname, \"../registry/templates\"),\n path.resolve(__dirname, \"../src/registry/templates\"),\n path.resolve(__dirname, \"../../src/registry/templates\"),\n ];\n\n let seedDir: string | null = null;\n for (const candidate of candidates) {\n try {\n await fs.access(candidate);\n seedDir = candidate;\n break;\n } catch {\n continue;\n }\n }\n\n if (!seedDir) return;\n\n const files = (await fs.readdir(seedDir)).filter((f) => f.endsWith(\".json\"));\n let installed = 0;\n\n for (const file of files) {\n const dest = path.join(templatesDir, file);\n try {\n await fs.access(dest);\n // File already exists — don't overwrite user modifications\n } catch {\n await fs.copyFile(path.join(seedDir, file), dest);\n installed++;\n }\n }\n\n if (installed > 0) {\n console.log(ui.success(`${installed} template${installed === 1 ? \"\" : \"s\"} installed`));\n }\n}\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 printFullBanner(\"Setup\");\n\n const existing = await loadConfig();\n if (existing) {\n console.log(ui.warn(`Config already exists at ${chalk.dim(getConfigPath())}`));\n console.log(ui.warn(\"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(ui.error(\"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(ui.error(\"Invalid API key. Check your key and try again.\"));\n process.exit(1);\n }\n\n console.log(ui.success(\"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(ui.success(`Config saved to ${chalk.dim(getConfigPath())}`));\n console.log(ui.kv(\"Provider\", providerInfo.name));\n console.log(ui.kv(\"Model\", model));\n\n await installSeedTemplates();\n\n const hasClaude = detectClaudeCode();\n if (hasClaude) {\n console.log(ui.success(\"Claude Code detected\"));\n } else {\n console.log(\n ui.warn(\"Claude Code not found. Install it: npm install -g @anthropic-ai/claude-code\")\n );\n }\n\n console.log(\n \"\\n\" + ui.success(`Ready! Run ${chalk.bold(\"kairn describe\")} 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\");\nconst TEMPLATES_DIR = path.join(KAIRN_DIR, \"templates\");\nconst USER_REGISTRY_PATH = path.join(KAIRN_DIR, \"user-registry.json\");\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 function getTemplatesDir(): string {\n return TEMPLATES_DIR;\n}\n\nexport function getUserRegistryPath(): string {\n return USER_REGISTRY_PATH;\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 await fs.mkdir(TEMPLATES_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 chalk from \"chalk\";\n\n// Brand colors\nconst maroon = chalk.rgb(139, 0, 0);\nconst warm = chalk.rgb(212, 165, 116);\n\nexport const ui = {\n // Brand\n brand: (text: string) => maroon.bold(text),\n accent: (text: string) => warm(text),\n\n // Headers\n header: (text: string) => {\n const line = \"─\".repeat(50);\n return `\\n ${maroon(\"┌\" + line + \"┐\")}\\n ${maroon(\"│\")} ${maroon.bold(text.padEnd(49))}${maroon(\"│\")}\\n ${maroon(\"└\" + line + \"┘\")}\\n`;\n },\n\n // Sections\n section: (title: string) => `\\n ${warm(\"━━\")} ${chalk.bold(title)} ${warm(\"━\".repeat(Math.max(0, 44 - title.length)))}`,\n\n // Status\n success: (text: string) => chalk.green(` ✓ ${text}`),\n warn: (text: string) => chalk.yellow(` ⚠ ${text}`),\n error: (text: string) => chalk.red(` ✗ ${text}`),\n info: (text: string) => chalk.cyan(` ℹ ${text}`),\n\n // Key-value pairs\n kv: (key: string, value: string) => ` ${chalk.cyan(key.padEnd(14))} ${value}`,\n\n // File list\n file: (path: string) => chalk.dim(` ${path}`),\n\n // Tool display\n tool: (name: string, reason: string) => ` ${warm(\"●\")} ${chalk.bold(name)}\\n ${chalk.dim(reason)}`,\n\n // Divider\n divider: () => chalk.dim(` ${\"─\".repeat(50)}`),\n\n // Command suggestion\n cmd: (command: string) => ` ${chalk.bold.white(\"$ \" + command)}`,\n\n // Env var setup\n envVar: (name: string, desc: string, url?: string) => {\n let out = ` ${chalk.bold(`export ${name}=`)}${chalk.dim('\"your-key-here\"')}\\n`;\n out += chalk.dim(` ${desc}`);\n if (url) out += `\\n ${chalk.dim(\"Get one at:\")} ${warm(url)}`;\n return out;\n },\n\n // Clarification question display\n question: (q: string, suggestion: string) =>\n ` ${warm(\"?\")} ${chalk.bold(q)}\\n ${chalk.dim(`suggested: ${suggestion}`)}`,\n\n // Branded error box\n errorBox: (title: string, message: string) => {\n const line = \"─\".repeat(50);\n return `\\n ${chalk.red(\"┌\" + line + \"┐\")}\\n ${chalk.red(\"│\")} ${chalk.red.bold(title.padEnd(49))}${chalk.red(\"│\")}\\n ${chalk.red(\"└\" + line + \"┘\")}\\n\\n ${chalk.red(\"✗\")} ${message}\\n`;\n },\n};\n","import chalk from \"chalk\";\n\n// Kairn brand colors\nconst maroon = chalk.rgb(139, 0, 0);\nconst darkMaroon = chalk.rgb(100, 0, 0);\nconst warmStone = chalk.rgb(180, 120, 80);\nconst lightStone = chalk.rgb(212, 165, 116);\nconst dimStone = chalk.rgb(140, 100, 70);\n\n// Block-character wordmark (matches Hermes quality level)\nconst KAIRN_WORDMARK = [\n maroon(\"██╗ ██╗\") + darkMaroon(\" \") + maroon(\"█████╗ \") + darkMaroon(\" \") + maroon(\"██╗\") + darkMaroon(\" \") + maroon(\"██████╗ \") + darkMaroon(\" \") + maroon(\"███╗ ██╗\"),\n maroon(\"██║ ██╔╝\") + darkMaroon(\" \") + maroon(\"██╔══██╗\") + darkMaroon(\" \") + maroon(\"██║\") + darkMaroon(\" \") + maroon(\"██╔══██╗\") + darkMaroon(\" \") + maroon(\"████╗ ██║\"),\n warmStone(\"█████╔╝ \") + dimStone(\" \") + warmStone(\"███████║\") + dimStone(\" \") + warmStone(\"██║\") + dimStone(\" \") + warmStone(\"██████╔╝\") + dimStone(\" \") + warmStone(\"██╔██╗ ██║\"),\n warmStone(\"██╔═██╗ \") + dimStone(\" \") + warmStone(\"██╔══██║\") + dimStone(\" \") + warmStone(\"██║\") + dimStone(\" \") + warmStone(\"██╔══██╗\") + dimStone(\" \") + warmStone(\"██║╚██╗██║\"),\n lightStone(\"██║ ██╗\") + dimStone(\" \") + lightStone(\"██║ ██║\") + dimStone(\" \") + lightStone(\"██║\") + dimStone(\" \") + lightStone(\"██║ ██║\") + dimStone(\" \") + lightStone(\"██║ ╚████║\"),\n lightStone(\"╚═╝ ╚═╝\") + dimStone(\" \") + lightStone(\"╚═╝ ╚═╝\") + dimStone(\" \") + lightStone(\"╚═╝\") + dimStone(\" \") + lightStone(\"╚═╝ ╚═╝\") + dimStone(\" \") + lightStone(\"╚═╝ ╚═══╝\"),\n];\n\n// Braille-art cairn (stacked stones)\nconst CAIRN_ART = [\n dimStone(\" ⣀⣀⣀ \"),\n warmStone(\" ⣴⣿⣿⣿⣦ \"),\n warmStone(\" ⠙⠿⠿⠋ \"),\n dimStone(\" ⣀⣤⣤⣤⣤⣀ \"),\n lightStone(\" ⣴⣿⣿⣿⣿⣿⣿⣦ \"),\n lightStone(\" ⠙⠻⠿⠿⠿⠟⠋ \"),\n dimStone(\" ⣀⣤⣤⣶⣶⣶⣶⣤⣤⣀ \"),\n warmStone(\" ⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦ \"),\n warmStone(\" ⠙⠻⠿⠿⠿⠿⠿⠿⠟⠋ \"),\n dimStone(\" ⣀⣤⣶⣶⣿⣿⣿⣿⣿⣿⣶⣶⣤⣀ \"),\n lightStone(\" ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ \"),\n dimStone(\" ⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉ \"),\n];\n\nexport function printLogo(): void {\n console.log(\"\");\n for (const line of KAIRN_WORDMARK) {\n console.log(\" \" + line);\n }\n console.log(\"\");\n}\n\nexport function printCairn(): void {\n console.log(\"\");\n for (const line of CAIRN_ART) {\n console.log(\" \" + line);\n }\n console.log(\"\");\n}\n\nexport function printFullBanner(subtitle?: string): void {\n console.log(\"\");\n for (const line of KAIRN_WORDMARK) {\n console.log(\" \" + line);\n }\n if (subtitle) {\n console.log(dimStone(` ${subtitle}`));\n }\n console.log(\"\");\n}\n\n// Compact one-liner for smaller outputs\nexport function printCompactBanner(): void {\n const line = maroon(\"━\").repeat(50);\n console.log(`\\n ${line}`);\n console.log(` ${maroon(\" ◆\")} ${chalk.bold.rgb(139, 0, 0)(\"KAIRN\")} ${dimStone(\"— Agent Environment Compiler\")}`);\n console.log(` ${line}\\n`);\n}\n","import { Command } from \"commander\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { loadConfig } from \"../config.js\";\nimport { generateClarifications, compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { writeHermesEnvironment } from \"../adapter/hermes-agent.js\";\nimport { loadRegistry } from \"../registry/loader.js\";\nimport { ui } from \"../ui.js\";\nimport { printFullBanner } from \"../logo.js\";\nimport type { RuntimeTarget, Clarification } from \"../types.js\";\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 .option(\"-q, --quick\", \"Skip clarification questions\")\n .option(\"--runtime <runtime>\", \"Target runtime (claude-code or hermes)\", \"claude-code\")\n .action(async (\n intentArg: string | undefined,\n options: { yes?: boolean; quick?: boolean; runtime?: string }\n ) => {\n // 1. Banner\n printFullBanner(\"The Agent Environment Compiler\");\n\n // 2. Check config\n const config = await loadConfig();\n if (!config) {\n console.log(\n ui.errorBox(\n \"No configuration found\",\n `Run ${chalk.bold(\"kairn init\")} to set up your API key.`\n )\n );\n process.exit(1);\n }\n\n // 3. Get intent\n const intentRaw =\n intentArg ||\n (await input({\n message: \"What do you want your agent to do?\",\n }));\n\n if (!intentRaw.trim()) {\n console.log(chalk.red(\"\\n No description provided. Aborting.\\n\"));\n process.exit(1);\n }\n\n // 4. Clarification flow\n let finalIntent = intentRaw;\n\n if (!options.quick) {\n console.log(ui.section(\"Clarification\"));\n console.log(chalk.dim(\" Let me understand your project better.\"));\n console.log(chalk.dim(\" Press Enter to accept the suggestion, or type your own answer.\\n\"));\n\n let clarifications: Clarification[] = [];\n try {\n clarifications = await generateClarifications(intentRaw);\n } catch {\n // Non-fatal: proceed without clarifications\n }\n\n if (clarifications.length > 0) {\n const answers: Array<{ question: string; answer: string }> = [];\n\n for (const c of clarifications) {\n const answer = await input({\n message: c.question,\n default: c.suggestion,\n });\n answers.push({ question: c.question, answer });\n }\n\n const clarificationLines = answers\n .map((a) => `- ${a.question}: ${a.answer}`)\n .join(\"\\n\");\n\n finalIntent =\n `User intent: \"${intentRaw}\"\\n\\nClarifications:\\n${clarificationLines}`;\n }\n }\n\n // 5. Compilation\n console.log(ui.section(\"Compilation\"));\n\n const spinner = ora({ text: \"Loading tool registry...\", indent: 2 }).start();\n\n let spec;\n try {\n spec = await compile(finalIntent, (msg) => {\n spinner.text = msg;\n });\n spinner.succeed(\"Environment compiled\");\n } catch (err) {\n spinner.fail(\"Compilation failed\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n ${msg}\\n`));\n process.exit(1);\n }\n\n // 6. Results display\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(\"\");\n console.log(ui.kv(\"Name:\", spec.name));\n console.log(ui.kv(\"Description:\", spec.description));\n console.log(ui.kv(\"Tools:\", String(summary.toolCount)));\n console.log(ui.kv(\"Commands:\", String(summary.commandCount)));\n console.log(ui.kv(\"Rules:\", String(summary.ruleCount)));\n console.log(ui.kv(\"Skills:\", String(summary.skillCount)));\n console.log(ui.kv(\"Agents:\", String(summary.agentCount)));\n\n if (spec.tools.length > 0) {\n console.log(ui.section(\"Selected Tools\"));\n console.log(\"\");\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(ui.tool(name, tool.reason));\n console.log(\"\");\n }\n }\n\n // 7. Confirm\n const proceed =\n options.yes ||\n (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 // 8. Write\n const targetDir = process.cwd();\n const runtime = (options.runtime ?? \"claude-code\") as RuntimeTarget;\n\n if (runtime === \"hermes\") {\n await writeHermesEnvironment(spec, registry);\n console.log(\"\\n\" + ui.success(\"Environment written for Hermes\"));\n console.log(\n chalk.cyan(\"\\n Ready! Run \") + chalk.bold(\"hermes\") + chalk.cyan(\" to start.\\n\")\n );\n } else {\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(ui.section(\"Files Written\"));\n console.log(\"\");\n for (const file of written) {\n console.log(ui.file(file));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(ui.section(\"Setup Required\"));\n console.log(\"\");\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(ui.envVar(env.envVar, env.description, env.signupUrl));\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(ui.section(\"Plugins\"));\n console.log(\"\");\n for (const cmd of summary.pluginCommands) {\n console.log(ui.cmd(cmd));\n }\n console.log(\"\");\n }\n\n console.log(ui.divider());\n console.log(ui.success(\"Ready! Run: $ claude\"));\n console.log(\"\");\n }\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport crypto from \"crypto\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { loadConfig, getEnvsDir, ensureDirs } from \"../config.js\";\nimport { SYSTEM_PROMPT, CLARIFICATION_PROMPT } from \"./prompt.js\";\nimport { loadRegistry } from \"../registry/loader.js\";\nimport type { EnvironmentSpec, RegistryTool, KairnConfig, Clarification } from \"../types.js\";\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\nexport async function generateClarifications(\n intent: string,\n onProgress?: (msg: string) => void\n): Promise<Clarification[]> {\n const config = await loadConfig();\n if (!config) {\n throw new Error(\"No config found. Run `kairn init` first.\");\n }\n\n onProgress?.(\"Analyzing your request...\");\n\n // Use a fast model for clarifications\n const clarificationConfig = { ...config };\n if (config.provider === \"anthropic\") {\n clarificationConfig.model = \"claude-haiku-4-5-20251001\";\n }\n\n const response = await callLLM(clarificationConfig, CLARIFICATION_PROMPT + \"\\n\\nUser description: \" + intent);\n\n try {\n let cleaned = response.trim();\n if (cleaned.startsWith(\"```\")) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, \"\").replace(/\\n?```$/, \"\");\n }\n const jsonMatch = cleaned.match(/\\[[\\s\\S]*\\]/);\n if (!jsonMatch) return [];\n return JSON.parse(jsonMatch[0]) as Clarification[];\n } catch {\n return [];\n }\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## Hermes Runtime\n\nWhen generating for Hermes runtime, the same EnvironmentSpec JSON is produced. The adapter layer handles conversion:\n- MCP config entries → Hermes config.yaml mcp_servers\n- Commands and skills → ~/.hermes/skills/ markdown files\n- Rules → ~/.hermes/skills/rule-*.md files\n\nThe LLM output format does not change. Adapter-level conversion happens post-compilation.\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\nexport const CLARIFICATION_PROMPT = `You are helping a user define their project for environment compilation.\n\nGiven their initial description, generate 3-5 clarifying questions to understand:\n1. Language and framework\n2. What the project specifically does (be precise)\n3. Primary workflow (build, research, write, analyze?)\n4. Key dependencies or integrations\n5. Target audience\n\nFor each question, provide a reasonable suggestion based on the description.\n\nOutput ONLY a JSON array:\n[\n { \"question\": \"Language/framework?\", \"suggestion\": \"TypeScript + Node.js\" },\n ...\n]\n\nRules:\n- Suggestions should be reasonable guesses, clearly marked as suggestions\n- Keep questions short (under 10 words)\n- Maximum 5 questions\n- If the description is already very detailed, ask fewer questions`;\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getUserRegistryPath } from \"../config.js\";\nimport type { RegistryTool } from \"../types.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport async function loadBundledRegistry(): Promise<RegistryTool[]> {\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 async function loadUserRegistry(): Promise<RegistryTool[]> {\n try {\n const data = await fs.readFile(getUserRegistryPath(), \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n return [];\n }\n}\n\nexport async function saveUserRegistry(tools: RegistryTool[]): Promise<void> {\n await fs.writeFile(getUserRegistryPath(), JSON.stringify(tools, null, 2), \"utf-8\");\n}\n\nexport async function loadRegistry(): Promise<RegistryTool[]> {\n const bundled = await loadBundledRegistry();\n const user = await loadUserRegistry();\n\n if (user.length === 0) return bundled;\n\n // User tools take precedence by ID\n const merged = new Map<string, RegistryTool>();\n for (const tool of bundled) {\n merged.set(tool.id, tool);\n }\n for (const tool of user) {\n merged.set(tool.id, tool);\n }\n return Array.from(merged.values());\n}\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 fs from \"fs/promises\";\nimport path from \"path\";\nimport os from \"os\";\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\nfunction toYaml(obj: unknown, indent: number = 0): string {\n const pad = \" \".repeat(indent);\n\n if (obj === null || obj === undefined) {\n return \"~\";\n }\n\n if (typeof obj === \"boolean\") {\n return obj ? \"true\" : \"false\";\n }\n\n if (typeof obj === \"number\") {\n return String(obj);\n }\n\n if (typeof obj === \"string\") {\n // Quote strings that contain special characters or look like other types\n const needsQuotes =\n obj === \"\" ||\n /[:#\\[\\]{}&*!|>'\"%@`,]/.test(obj) ||\n /^(true|false|null|~|\\d)/.test(obj) ||\n obj.includes(\"\\n\");\n return needsQuotes ? `\"${obj.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"` : obj;\n }\n\n if (Array.isArray(obj)) {\n if (obj.length === 0) {\n return \"[]\";\n }\n return obj\n .map((item) => `${pad}- ${toYaml(item, indent + 1).trimStart()}`)\n .join(\"\\n\");\n }\n\n if (typeof obj === \"object\") {\n const entries = Object.entries(obj as Record<string, unknown>);\n if (entries.length === 0) {\n return \"{}\";\n }\n return entries\n .map(([key, value]) => {\n const valueStr = toYaml(value, indent + 1);\n const isScalar =\n typeof value !== \"object\" || value === null || Array.isArray(value);\n if (isScalar && !Array.isArray(value)) {\n return `${pad}${key}: ${valueStr}`;\n }\n if (Array.isArray(value)) {\n if ((value as unknown[]).length === 0) {\n return `${pad}${key}: []`;\n }\n return `${pad}${key}:\\n${valueStr}`;\n }\n return `${pad}${key}:\\n${valueStr}`;\n })\n .join(\"\\n\");\n }\n\n return String(obj);\n}\n\nfunction buildMcpServersYaml(\n spec: EnvironmentSpec,\n registry: RegistryTool[]\n): string {\n const servers: Record<string, unknown> = {};\n\n // For each selected tool, check for hermes-specific mcp_server config first\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.hermes?.mcp_server) {\n const serverName = tool.id.replace(/_/g, \"-\");\n servers[serverName] = tool.install.hermes.mcp_server;\n } else if (tool.install.mcp_config) {\n // Fall back to converting the Claude Code mcp_config format\n for (const [serverName, serverConfig] of Object.entries(\n tool.install.mcp_config\n )) {\n servers[serverName] = serverConfig;\n }\n }\n }\n\n // Also include any mcp_config entries from the harness that weren't covered by tools\n for (const [serverName, serverConfig] of Object.entries(\n spec.harness.mcp_config || {}\n )) {\n if (!(serverName in servers)) {\n servers[serverName] = serverConfig;\n }\n }\n\n if (Object.keys(servers).length === 0) {\n return \"\";\n }\n\n const lines: string[] = [];\n lines.push(`# Generated by Kairn v1.5.0`);\n lines.push(`# Environment: ${spec.name}`);\n lines.push(``);\n lines.push(`mcp_servers:`);\n\n for (const [serverName, serverConfig] of Object.entries(servers)) {\n lines.push(` ${serverName}:`);\n lines.push(toYaml(serverConfig, 2));\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nexport async function writeHermesEnvironment(\n spec: EnvironmentSpec,\n registry: RegistryTool[]\n): Promise<string[]> {\n const hermesDir = path.join(os.homedir(), \".hermes\");\n const written: string[] = [];\n\n // 1. config.yaml\n const configYaml = buildMcpServersYaml(spec, registry);\n if (configYaml) {\n const configPath = path.join(hermesDir, \"config.yaml\");\n await writeFile(configPath, configYaml);\n written.push(\".hermes/config.yaml\");\n }\n\n // 2. Skills from commands\n if (spec.harness.commands) {\n for (const [name, content] of Object.entries(spec.harness.commands)) {\n const skillPath = path.join(hermesDir, \"skills\", `${name}.md`);\n await writeFile(skillPath, content);\n written.push(`.hermes/skills/${name}.md`);\n }\n }\n\n // 3. Skills from skills\n if (spec.harness.skills) {\n for (const [name, content] of Object.entries(spec.harness.skills)) {\n const skillPath = path.join(hermesDir, \"skills\", `${name}.md`);\n await writeFile(skillPath, content);\n written.push(`.hermes/skills/${name}.md`);\n }\n }\n\n // 4. Skills from rules (prefixed with \"rule-\")\n if (spec.harness.rules) {\n for (const [name, content] of Object.entries(spec.harness.rules)) {\n const skillPath = path.join(hermesDir, \"skills\", `rule-${name}.md`);\n await writeFile(skillPath, content);\n written.push(`.hermes/skills/rule-${name}.md`);\n }\n }\n\n return written;\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\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.js\";\n\nexport const listCommand = new Command(\"list\")\n .description(\"Show saved environments\")\n .action(async () => {\n printCompactBanner();\n\n const envsDir = getEnvsDir();\n\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.dim(\" 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(\" No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n let first = true;\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 if (!first) {\n console.log(ui.divider());\n }\n first = false;\n\n console.log(ui.kv(\"Name\", chalk.bold(spec.name)));\n console.log(ui.kv(\"Description\", spec.description));\n console.log(ui.kv(\"Date\", `${date} · ${toolCount} tools`));\n console.log(ui.kv(\"ID\", chalk.dim(spec.id)));\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, getTemplatesDir } from \"../config.js\";\nimport { writeEnvironment } from \"../adapter/claude-code.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.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 printCompactBanner();\n\n const envsDir = getEnvsDir();\n const templatesDir = getTemplatesDir();\n\n // Find the env file — accept full ID or partial match\n let sourceDir: string;\n let match: string | undefined;\n let fromTemplate = false;\n\n // 1. Search envs dir\n let envFiles: string[] = [];\n try {\n envFiles = await fs.readdir(envsDir);\n } catch {\n // envs dir may not exist yet; continue to templates search\n }\n\n match = envFiles.find(\n (f) => f === `${envId}.json` || f.startsWith(envId)\n );\n\n if (match) {\n sourceDir = envsDir;\n } else {\n // 2. Fall back to templates dir\n let templateFiles: string[] = [];\n try {\n templateFiles = await fs.readdir(templatesDir);\n } catch {\n // templates dir may not exist\n }\n\n match = templateFiles.find(\n (f) => f === `${envId}.json` || f.startsWith(envId)\n );\n\n if (match) {\n sourceDir = templatesDir;\n fromTemplate = true;\n } else {\n console.log(ui.error(`Environment \"${envId}\" not found.`));\n console.log(chalk.dim(\" Run kairn list to see saved environments.\"));\n console.log(chalk.dim(\" Run kairn templates to see available templates.\\n\"));\n process.exit(1);\n }\n }\n\n const data = await fs.readFile(path.join(sourceDir, match), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n\n const label = fromTemplate ? chalk.dim(\" (template)\") : \"\";\n console.log(chalk.cyan(` Activating: ${spec.name}`) + label);\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(ui.success(\"Environment written\\n\"));\n for (const file of written) {\n console.log(ui.file(file));\n }\n\n console.log(\"\\n\" + ui.success(`Ready! Run: $ claude`) + \"\\n\");\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.js\";\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 printCompactBanner();\n\n const url = options.url || REGISTRY_URL;\n\n console.log(chalk.dim(` Fetching registry from ${url}...`));\n\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n console.log(\n ui.error(`Failed to fetch registry: ${response.status} ${response.statusText}`)\n );\n console.log(chalk.dim(\" The remote registry may not be available yet.\"));\n console.log(chalk.dim(\" Your local registry is still active.\\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(ui.error(`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(ui.success(`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(ui.error(`Network error: ${msg}`));\n console.log(chalk.dim(\" Your local registry is still active.\\n\"));\n }\n });\n","import { Command } from \"commander\";\nimport { confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\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 { writeHermesEnvironment } from \"../adapter/hermes-agent.js\";\nimport { loadRegistry } from \"../registry/loader.js\";\nimport type { RuntimeTarget } from \"../types.js\";\nimport { scanProject } from \"../scanner/scan.js\";\nimport type { ProjectProfile } from \"../scanner/scan.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.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\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 .option(\"--runtime <runtime>\", \"Target runtime (claude-code or hermes)\", \"claude-code\")\n .action(async (options: { yes?: boolean; auditOnly?: boolean; diff?: boolean; runtime?: string }) => {\n printCompactBanner();\n\n const config = await loadConfig();\n if (!config) {\n console.log(ui.errorBox(\"KAIRN — Error\", \"No config found. Run kairn init first.\"));\n process.exit(1);\n }\n\n const targetDir = process.cwd();\n\n // 1. Scan\n console.log(ui.section(\"Project Scan\"));\n const scanSpinner = ora({ text: \"Scanning project...\", indent: 2 }).start();\n const profile = await scanProject(targetDir);\n scanSpinner.stop();\n\n // 2. Show profile\n if (profile.language) console.log(ui.kv(\"Language:\", profile.language));\n if (profile.framework) console.log(ui.kv(\"Framework:\", profile.framework));\n console.log(ui.kv(\"Dependencies:\", String(profile.dependencies.length)));\n if (profile.testCommand) console.log(ui.kv(\"Tests:\", profile.testCommand));\n if (profile.buildCommand) console.log(ui.kv(\"Build:\", profile.buildCommand));\n if (profile.hasDocker) console.log(ui.kv(\"Docker:\", \"yes\"));\n if (profile.hasCi) console.log(ui.kv(\"CI/CD:\", \"yes\"));\n if (profile.envKeys.length > 0) console.log(ui.kv(\"Env keys:\", profile.envKeys.join(\", \")));\n\n // 3. Audit existing harness\n if (profile.hasClaudeDir) {\n console.log(ui.section(\"Harness Audit\"));\n console.log(ui.kv(\"CLAUDE.md:\", `${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? \" ⚠ bloated\" : \" ✓\"}`));\n console.log(ui.kv(\"MCP servers:\", String(profile.mcpServerCount)));\n console.log(ui.kv(\"Commands:\", profile.existingCommands.length > 0 ? profile.existingCommands.join(\", \") : \"none\"));\n console.log(ui.kv(\"Rules:\", profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"));\n console.log(ui.kv(\"Skills:\", profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"));\n console.log(ui.kv(\"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(\"\");\n for (const issue of issues) {\n console.log(ui.warn(issue));\n }\n } else {\n console.log(ui.success(\"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 const spinner = ora({ text: \"Compiling optimized environment...\", indent: 2 }).start();\n try {\n spec = await compile(intent, (msg) => {\n spinner.text = msg;\n });\n spinner.succeed(\"Environment compiled\");\n } catch (err) {\n spinner.fail(\"Compilation failed\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(ui.errorBox(\"KAIRN — Error\", `Optimization failed: ${msg}`));\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(\"\");\n console.log(ui.kv(\"Name:\", spec.name));\n console.log(ui.kv(\"Tools:\", String(summary.toolCount)));\n console.log(ui.kv(\"Commands:\", String(summary.commandCount)));\n console.log(ui.kv(\"Rules:\", String(summary.ruleCount)));\n console.log(ui.kv(\"Skills:\", String(summary.skillCount)));\n console.log(ui.kv(\"Agents:\", String(summary.agentCount)));\n\n if (spec.tools.length > 0) {\n console.log(ui.section(\"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(ui.tool(name, tool.reason));\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(ui.success(\"No changes needed — environment is already up to date.\"));\n console.log(\"\");\n return;\n }\n\n console.log(ui.section(\"Changes Preview\"));\n for (const d of changedDiffs) {\n console.log(chalk.cyan(`\\n --- ${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 }\n console.log(\"\");\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 runtime = (options.runtime ?? \"claude-code\") as RuntimeTarget;\n\n if (runtime === \"hermes\") {\n await writeHermesEnvironment(spec, registry);\n console.log(ui.divider());\n console.log(ui.success(`Ready! Run: $ hermes`));\n console.log(\"\");\n } else {\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(ui.section(\"Files Written\"));\n for (const file of written) {\n console.log(ui.file(file));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(ui.section(\"Setup Required\"));\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(ui.envVar(env.envVar, env.description, env.signupUrl));\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(ui.section(\"Plugins\"));\n for (const cmd of summary.pluginCommands) {\n console.log(ui.cmd(cmd));\n }\n console.log(\"\");\n }\n\n console.log(ui.divider());\n console.log(ui.success(\"Ready! Run: $ claude\"));\n console.log(\"\");\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\";\nimport { ui } from \"../ui.js\";\nimport { printFullBanner } from \"../logo.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 printFullBanner(\"Doctor\");\n\n const targetDir = process.cwd();\n\n console.log(chalk.dim(\" Checking .claude/ environment...\\n\"));\n\n const profile = await scanProject(targetDir);\n\n if (!profile.hasClaudeDir) {\n console.log(ui.error(\"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 console.log(ui.section(\"Health Check\"));\n console.log(\"\");\n\n // Display results\n for (const check of checks) {\n if (check.status === \"pass\") {\n console.log(ui.success(`${check.name}: ${check.message}`));\n } else if (check.status === \"warn\") {\n console.log(ui.warn(`${check.name}: ${check.message}`));\n } else {\n console.log(ui.error(`${check.name}: ${check.message}`));\n }\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","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { input, select } from \"@inquirer/prompts\";\nimport { loadRegistry, loadUserRegistry, saveUserRegistry } from \"../registry/loader.js\";\nimport type { RegistryTool } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.js\";\n\nconst listCommand = new Command(\"list\")\n .description(\"List tools in the registry\")\n .option(\"--category <cat>\", \"Filter by category\")\n .option(\"--user-only\", \"Show only user-defined tools\")\n .action(async (options: { category?: string; userOnly?: boolean }) => {\n printCompactBanner();\n\n let all: RegistryTool[];\n let userTools: RegistryTool[];\n\n try {\n [all, userTools] = await Promise.all([loadRegistry(), loadUserRegistry()]);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(ui.error(`Failed to load registry: ${msg}\\n`));\n process.exit(1);\n }\n\n const userIds = new Set(userTools.map((t) => t.id));\n\n let tools = all;\n\n if (options.userOnly) {\n tools = tools.filter((t) => userIds.has(t.id));\n }\n\n if (options.category) {\n tools = tools.filter(\n (t) => t.category.toLowerCase() === options.category!.toLowerCase()\n );\n }\n\n if (tools.length === 0) {\n console.log(chalk.dim(\"\\n No tools found.\\n\"));\n return;\n }\n\n const bundledCount = all.filter((t) => !userIds.has(t.id)).length;\n const userCount = userIds.size;\n\n console.log(ui.section(\"Registry Tools\"));\n console.log(\"\");\n\n for (const tool of tools) {\n const isUser = userIds.has(tool.id);\n const meta = [\n tool.category,\n `tier ${tool.tier}`,\n tool.auth,\n ].join(\", \");\n\n console.log(` ${ui.accent(tool.id)}` + chalk.dim(` (${meta})`));\n console.log(chalk.dim(` ${tool.description}`));\n\n if (tool.best_for.length > 0) {\n console.log(chalk.dim(` Best for: ${tool.best_for.join(\", \")}`));\n }\n\n if (isUser) {\n console.log(chalk.yellow(\" [USER-DEFINED]\"));\n }\n\n console.log(\"\");\n }\n\n const totalShown = tools.length;\n const shownUser = tools.filter((t) => userIds.has(t.id)).length;\n const shownBundled = totalShown - shownUser;\n\n console.log(\n chalk.dim(\n ` ${totalShown} tool${totalShown !== 1 ? \"s\" : \"\"} (${shownBundled} bundled, ${shownUser} user-defined)`\n ) + \"\\n\"\n );\n });\n\nconst addCommand = new Command(\"add\")\n .description(\"Add a tool to the user registry\")\n .action(async () => {\n let id: string;\n try {\n id = await input({\n message: \"Tool ID (kebab-case)\",\n validate: (v) => {\n if (!v) return \"ID is required\";\n if (!/^[a-z][a-z0-9-]*$/.test(v)) return \"ID must be kebab-case (e.g. my-tool)\";\n return true;\n },\n });\n\n const name = await input({ message: \"Display name\" });\n const description = await input({ message: \"Description\" });\n\n const category = await select({\n message: \"Category\",\n choices: [\n { value: \"universal\" },\n { value: \"code\" },\n { value: \"search\" },\n { value: \"data\" },\n { value: \"communication\" },\n { value: \"design\" },\n { value: \"monitoring\" },\n { value: \"infrastructure\" },\n { value: \"sandbox\" },\n ],\n });\n\n const tier = await select<number>({\n message: \"Tier\",\n choices: [\n { name: \"1 — Universal\", value: 1 },\n { name: \"2 — Common\", value: 2 },\n { name: \"3 — Specialized\", value: 3 },\n ],\n });\n\n const type = await select<\"mcp_server\" | \"plugin\" | \"hook\">({\n message: \"Type\",\n choices: [\n { value: \"mcp_server\" },\n { value: \"plugin\" },\n { value: \"hook\" },\n ],\n });\n\n const auth = await select<\"none\" | \"api_key\" | \"oauth\" | \"connection_string\">({\n message: \"Auth\",\n choices: [\n { value: \"none\" },\n { value: \"api_key\" },\n { value: \"oauth\" },\n { value: \"connection_string\" },\n ],\n });\n\n const env_vars: { name: string; description: string }[] = [];\n if (auth === \"api_key\" || auth === \"connection_string\") {\n let addMore = true;\n while (addMore) {\n const varName = await input({ message: \"Env var name\" });\n const varDesc = await input({ message: \"Env var description\" });\n env_vars.push({ name: varName, description: varDesc });\n const another = await select<boolean>({\n message: \"Add another env var?\",\n choices: [\n { name: \"No\", value: false },\n { name: \"Yes\", value: true },\n ],\n });\n addMore = another;\n }\n }\n\n const signup_url_raw = await input({ message: \"Signup URL (optional, press enter to skip)\" });\n const signup_url = signup_url_raw.trim() || undefined;\n\n const best_for_raw = await input({ message: \"Best-for tags, comma-separated\" });\n const best_for = best_for_raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n const install: RegistryTool[\"install\"] = {};\n if (type === \"mcp_server\") {\n const command = await input({ message: \"MCP command\" });\n const args_raw = await input({ message: \"MCP args, comma-separated (leave blank for none)\" });\n const args = args_raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n install.mcp_config = { command, args };\n }\n\n const tool: RegistryTool = {\n id,\n name,\n description,\n category,\n tier,\n type,\n auth,\n best_for,\n install,\n ...(env_vars.length > 0 ? { env_vars } : {}),\n ...(signup_url ? { signup_url } : {}),\n };\n\n let userToolsList: RegistryTool[];\n try {\n userToolsList = await loadUserRegistry();\n } catch {\n userToolsList = [];\n }\n\n const existingIdx = userToolsList.findIndex((t) => t.id === id);\n if (existingIdx >= 0) {\n userToolsList[existingIdx] = tool;\n } else {\n userToolsList.push(tool);\n }\n\n await saveUserRegistry(userToolsList);\n\n console.log(ui.success(`Tool ${id} added to user registry\\n`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(ui.error(`Failed to add tool: ${msg}\\n`));\n process.exit(1);\n }\n });\n\nexport const registryCommand = new Command(\"registry\")\n .description(\"Manage the tool registry\")\n .addCommand(listCommand)\n .addCommand(addCommand);\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getTemplatesDir } from \"../config.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.js\";\n\nexport const templatesCommand = new Command(\"templates\")\n .description(\"Browse available templates\")\n .option(\"--category <cat>\", \"filter templates by category keyword\")\n .option(\"--json\", \"output raw JSON array\")\n .action(async (options: { category?: string; json?: boolean }) => {\n printCompactBanner();\n\n const templatesDir = getTemplatesDir();\n\n let files: string[];\n try {\n files = await fs.readdir(templatesDir);\n } catch {\n console.log(\n chalk.dim(\n \" No templates found. Templates will be installed with \"\n ) +\n chalk.bold(\"kairn init\") +\n chalk.dim(\n \" or you can add .json files to ~/.kairn/templates/\\n\"\n )\n );\n return;\n }\n\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n if (jsonFiles.length === 0) {\n console.log(\n chalk.dim(\n \" No templates found. Templates will be installed with \"\n ) +\n chalk.bold(\"kairn init\") +\n chalk.dim(\n \" or you can add .json files to ~/.kairn/templates/\\n\"\n )\n );\n return;\n }\n\n const templates: EnvironmentSpec[] = [];\n\n for (const file of jsonFiles) {\n try {\n const data = await fs.readFile(\n path.join(templatesDir, file),\n \"utf-8\"\n );\n const spec = JSON.parse(data) as EnvironmentSpec;\n templates.push(spec);\n } catch {\n // Skip malformed files\n }\n }\n\n const filtered = options.category\n ? templates.filter((t) => {\n const keyword = options.category!.toLowerCase();\n return (\n t.intent?.toLowerCase().includes(keyword) ||\n t.description?.toLowerCase().includes(keyword)\n );\n })\n : templates;\n\n if (options.json) {\n console.log(JSON.stringify(filtered, null, 2));\n return;\n }\n\n if (filtered.length === 0) {\n console.log(\n chalk.dim(` No templates matched category \"${options.category}\".\\n`)\n );\n return;\n }\n\n console.log(ui.section(\"Templates\"));\n console.log(\"\");\n\n for (const spec of filtered) {\n const toolCount = spec.tools?.length ?? 0;\n const commandCount = Object.keys(spec.harness?.commands ?? {}).length;\n const ruleCount = Object.keys(spec.harness?.rules ?? {}).length;\n\n console.log(ui.kv(\"Name\", chalk.bold(spec.name)));\n console.log(ui.kv(\"ID\", chalk.dim(spec.id)));\n console.log(ui.kv(\"Description\", spec.description));\n console.log(\n ui.kv(\"Contents\", `${toolCount} tools · ${commandCount} commands · ${ruleCount} rules`)\n );\n console.log(\"\");\n }\n\n console.log(\n chalk.dim(` ${filtered.length} template${filtered.length === 1 ? \"\" : \"s\"} available\\n`)\n );\n });\n"],"mappings":"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","names":["Command","chalk","chalk","fs","path","path","chalk","maroon","maroon","chalk","path","fs","chalk","Command","chalk","fs","path","Anthropic","OpenAI","fs","path","fileURLToPath","__filename","fileURLToPath","__dirname","path","fs","Anthropic","OpenAI","path","fs","fs","path","fs","path","os","writeFile","Command","chalk","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","fileURLToPath","__filename","fileURLToPath","__dirname","path","fs","Command","chalk","Command","confirm","chalk","ora","fs","path","fs","path","chalk","path","fs","Command","ora","confirm","Command","chalk","perms","Command","chalk","Command","chalk","input","select","listCommand","Command","chalk","input","select","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/config.ts","../src/ui.ts","../src/logo.ts","../src/commands/describe.ts","../src/compiler/compile.ts","../src/compiler/prompt.ts","../src/registry/loader.ts","../src/adapter/claude-code.ts","../src/adapter/hermes-agent.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","../src/commands/registry.ts","../src/commands/templates.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\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\";\nimport { registryCommand } from \"./commands/registry.js\";\nimport { templatesCommand } from \"./commands/templates.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.7.0\")\n .option(\"--no-color\", \"Disable colored output\");\n\nprogram.addCommand(initCommand);\nprogram.addCommand(describeCommand);\nprogram.addCommand(optimizeCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(activateCommand);\nprogram.addCommand(updateRegistryCommand);\nprogram.addCommand(doctorCommand);\nprogram.addCommand(registryCommand);\nprogram.addCommand(templatesCommand);\n\n// Check for --no-color before parsing (Commander handles it but chalk needs manual disable)\nif (process.argv.includes(\"--no-color\") || process.env.NO_COLOR) {\n chalk.level = 0;\n}\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 fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { loadConfig, saveConfig, getConfigPath, getTemplatesDir } from \"../config.js\";\nimport type { KairnConfig, LLMProvider } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printFullBanner } from \"../logo.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nasync function installSeedTemplates(): Promise<void> {\n const templatesDir = getTemplatesDir();\n await fs.mkdir(templatesDir, { recursive: true });\n\n const candidates = [\n path.resolve(__dirname, \"../registry/templates\"),\n path.resolve(__dirname, \"../src/registry/templates\"),\n path.resolve(__dirname, \"../../src/registry/templates\"),\n ];\n\n let seedDir: string | null = null;\n for (const candidate of candidates) {\n try {\n await fs.access(candidate);\n seedDir = candidate;\n break;\n } catch {\n continue;\n }\n }\n\n if (!seedDir) return;\n\n const files = (await fs.readdir(seedDir)).filter((f) => f.endsWith(\".json\"));\n let installed = 0;\n\n for (const file of files) {\n const dest = path.join(templatesDir, file);\n try {\n await fs.access(dest);\n // File already exists — don't overwrite user modifications\n } catch {\n await fs.copyFile(path.join(seedDir, file), dest);\n installed++;\n }\n }\n\n if (installed > 0) {\n console.log(ui.success(`${installed} template${installed === 1 ? \"\" : \"s\"} installed`));\n }\n}\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 printFullBanner(\"Setup\");\n\n const existing = await loadConfig();\n if (existing) {\n console.log(ui.warn(`Config already exists at ${chalk.dim(getConfigPath())}`));\n console.log(ui.warn(\"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(ui.error(\"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(ui.error(\"Invalid API key. Check your key and try again.\"));\n process.exit(1);\n }\n\n console.log(ui.success(\"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(ui.success(`Config saved to ${chalk.dim(getConfigPath())}`));\n console.log(ui.kv(\"Provider\", providerInfo.name));\n console.log(ui.kv(\"Model\", model));\n\n await installSeedTemplates();\n\n const hasClaude = detectClaudeCode();\n if (hasClaude) {\n console.log(ui.success(\"Claude Code detected\"));\n } else {\n console.log(\n ui.warn(\"Claude Code not found. Install it: npm install -g @anthropic-ai/claude-code\")\n );\n }\n\n console.log(\n \"\\n\" + ui.success(`Ready! Run ${chalk.bold(\"kairn describe\")} 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\");\nconst TEMPLATES_DIR = path.join(KAIRN_DIR, \"templates\");\nconst USER_REGISTRY_PATH = path.join(KAIRN_DIR, \"user-registry.json\");\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 function getTemplatesDir(): string {\n return TEMPLATES_DIR;\n}\n\nexport function getUserRegistryPath(): string {\n return USER_REGISTRY_PATH;\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 await fs.mkdir(TEMPLATES_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 chalk from \"chalk\";\n\n// Brand colors\nconst maroon = chalk.rgb(139, 0, 0);\nconst warm = chalk.rgb(212, 165, 116);\n\nexport const ui = {\n // Brand\n brand: (text: string) => maroon.bold(text),\n accent: (text: string) => warm(text),\n\n // Headers\n header: (text: string) => {\n const line = \"─\".repeat(50);\n return `\\n ${maroon(\"┌\" + line + \"┐\")}\\n ${maroon(\"│\")} ${maroon.bold(text.padEnd(49))}${maroon(\"│\")}\\n ${maroon(\"└\" + line + \"┘\")}\\n`;\n },\n\n // Sections\n section: (title: string) => `\\n ${warm(\"━━\")} ${chalk.bold(title)} ${warm(\"━\".repeat(Math.max(0, 44 - title.length)))}`,\n\n // Status\n success: (text: string) => chalk.green(` ✓ ${text}`),\n warn: (text: string) => chalk.yellow(` ⚠ ${text}`),\n error: (text: string) => chalk.red(` ✗ ${text}`),\n info: (text: string) => chalk.cyan(` ℹ ${text}`),\n\n // Key-value pairs\n kv: (key: string, value: string) => ` ${chalk.cyan(key.padEnd(14))} ${value}`,\n\n // File list\n file: (path: string) => chalk.dim(` ${path}`),\n\n // Tool display\n tool: (name: string, reason: string) => ` ${warm(\"●\")} ${chalk.bold(name)}\\n ${chalk.dim(reason)}`,\n\n // Divider\n divider: () => chalk.dim(` ${\"─\".repeat(50)}`),\n\n // Command suggestion\n cmd: (command: string) => ` ${chalk.bold.white(\"$ \" + command)}`,\n\n // Env var setup\n envVar: (name: string, desc: string, url?: string) => {\n let out = ` ${chalk.bold(`export ${name}=`)}${chalk.dim('\"your-key-here\"')}\\n`;\n out += chalk.dim(` ${desc}`);\n if (url) out += `\\n ${chalk.dim(\"Get one at:\")} ${warm(url)}`;\n return out;\n },\n\n // Clarification question display\n question: (q: string, suggestion: string) =>\n ` ${warm(\"?\")} ${chalk.bold(q)}\\n ${chalk.dim(`suggested: ${suggestion}`)}`,\n\n // Branded error box\n errorBox: (title: string, message: string) => {\n const line = \"─\".repeat(50);\n return `\\n ${chalk.red(\"┌\" + line + \"┐\")}\\n ${chalk.red(\"│\")} ${chalk.red.bold(title.padEnd(49))}${chalk.red(\"│\")}\\n ${chalk.red(\"└\" + line + \"┘\")}\\n\\n ${chalk.red(\"✗\")} ${message}\\n`;\n },\n};\n","import chalk from \"chalk\";\n\n// Kairn brand colors\nconst maroon = chalk.rgb(139, 0, 0);\nconst darkMaroon = chalk.rgb(100, 0, 0);\nconst warmStone = chalk.rgb(180, 120, 80);\nconst lightStone = chalk.rgb(212, 165, 116);\nconst dimStone = chalk.rgb(140, 100, 70);\n\n// Block-character wordmark (matches Hermes quality level)\nconst KAIRN_WORDMARK = [\n maroon(\"██╗ ██╗\") + darkMaroon(\" \") + maroon(\"█████╗ \") + darkMaroon(\" \") + maroon(\"██╗\") + darkMaroon(\" \") + maroon(\"██████╗ \") + darkMaroon(\" \") + maroon(\"███╗ ██╗\"),\n maroon(\"██║ ██╔╝\") + darkMaroon(\" \") + maroon(\"██╔══██╗\") + darkMaroon(\" \") + maroon(\"██║\") + darkMaroon(\" \") + maroon(\"██╔══██╗\") + darkMaroon(\" \") + maroon(\"████╗ ██║\"),\n warmStone(\"█████╔╝ \") + dimStone(\" \") + warmStone(\"███████║\") + dimStone(\" \") + warmStone(\"██║\") + dimStone(\" \") + warmStone(\"██████╔╝\") + dimStone(\" \") + warmStone(\"██╔██╗ ██║\"),\n warmStone(\"██╔═██╗ \") + dimStone(\" \") + warmStone(\"██╔══██║\") + dimStone(\" \") + warmStone(\"██║\") + dimStone(\" \") + warmStone(\"██╔══██╗\") + dimStone(\" \") + warmStone(\"██║╚██╗██║\"),\n lightStone(\"██║ ██╗\") + dimStone(\" \") + lightStone(\"██║ ██║\") + dimStone(\" \") + lightStone(\"██║\") + dimStone(\" \") + lightStone(\"██║ ██║\") + dimStone(\" \") + lightStone(\"██║ ╚████║\"),\n lightStone(\"╚═╝ ╚═╝\") + dimStone(\" \") + lightStone(\"╚═╝ ╚═╝\") + dimStone(\" \") + lightStone(\"╚═╝\") + dimStone(\" \") + lightStone(\"╚═╝ ╚═╝\") + dimStone(\" \") + lightStone(\"╚═╝ ╚═══╝\"),\n];\n\n// Braille-art cairn (stacked stones)\nconst CAIRN_ART = [\n dimStone(\" ⣀⣀⣀ \"),\n warmStone(\" ⣴⣿⣿⣿⣦ \"),\n warmStone(\" ⠙⠿⠿⠋ \"),\n dimStone(\" ⣀⣤⣤⣤⣤⣀ \"),\n lightStone(\" ⣴⣿⣿⣿⣿⣿⣿⣦ \"),\n lightStone(\" ⠙⠻⠿⠿⠿⠟⠋ \"),\n dimStone(\" ⣀⣤⣤⣶⣶⣶⣶⣤⣤⣀ \"),\n warmStone(\" ⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦ \"),\n warmStone(\" ⠙⠻⠿⠿⠿⠿⠿⠿⠟⠋ \"),\n dimStone(\" ⣀⣤⣶⣶⣿⣿⣿⣿⣿⣿⣶⣶⣤⣀ \"),\n lightStone(\" ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ \"),\n dimStone(\" ⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉ \"),\n];\n\nexport function printLogo(): void {\n console.log(\"\");\n for (const line of KAIRN_WORDMARK) {\n console.log(\" \" + line);\n }\n console.log(\"\");\n}\n\nexport function printCairn(): void {\n console.log(\"\");\n for (const line of CAIRN_ART) {\n console.log(\" \" + line);\n }\n console.log(\"\");\n}\n\nexport function printFullBanner(subtitle?: string): void {\n console.log(\"\");\n for (const line of KAIRN_WORDMARK) {\n console.log(\" \" + line);\n }\n if (subtitle) {\n console.log(dimStone(` ${subtitle}`));\n }\n console.log(\"\");\n}\n\n// Compact one-liner for smaller outputs\nexport function printCompactBanner(): void {\n const line = maroon(\"━\").repeat(50);\n console.log(`\\n ${line}`);\n console.log(` ${maroon(\" ◆\")} ${chalk.bold.rgb(139, 0, 0)(\"KAIRN\")} ${dimStone(\"— Agent Environment Compiler\")}`);\n console.log(` ${line}\\n`);\n}\n","import { Command } from \"commander\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { loadConfig } from \"../config.js\";\nimport { generateClarifications, compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { writeHermesEnvironment } from \"../adapter/hermes-agent.js\";\nimport { loadRegistry } from \"../registry/loader.js\";\nimport { ui } from \"../ui.js\";\nimport { printFullBanner } from \"../logo.js\";\nimport type { RuntimeTarget, Clarification } from \"../types.js\";\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 .option(\"-q, --quick\", \"Skip clarification questions\")\n .option(\"--runtime <runtime>\", \"Target runtime (claude-code or hermes)\", \"claude-code\")\n .action(async (\n intentArg: string | undefined,\n options: { yes?: boolean; quick?: boolean; runtime?: string }\n ) => {\n // 1. Banner\n printFullBanner(\"The Agent Environment Compiler\");\n\n // 2. Check config\n const config = await loadConfig();\n if (!config) {\n console.log(\n ui.errorBox(\n \"No configuration found\",\n `Run ${chalk.bold(\"kairn init\")} to set up your API key.`\n )\n );\n process.exit(1);\n }\n\n // 3. Get intent\n const intentRaw =\n intentArg ||\n (await input({\n message: \"What do you want your agent to do?\",\n }));\n\n if (!intentRaw.trim()) {\n console.log(chalk.red(\"\\n No description provided. Aborting.\\n\"));\n process.exit(1);\n }\n\n // 4. Clarification flow\n let finalIntent = intentRaw;\n\n if (!options.quick) {\n console.log(ui.section(\"Clarification\"));\n console.log(chalk.dim(\" Let me understand your project better.\"));\n console.log(chalk.dim(\" Press Enter to accept the suggestion, or type your own answer.\\n\"));\n\n let clarifications: Clarification[] = [];\n try {\n clarifications = await generateClarifications(intentRaw);\n } catch {\n // Non-fatal: proceed without clarifications\n }\n\n if (clarifications.length > 0) {\n const answers: Array<{ question: string; answer: string }> = [];\n\n for (const c of clarifications) {\n const answer = await input({\n message: c.question,\n default: c.suggestion,\n });\n answers.push({ question: c.question, answer });\n }\n\n const clarificationLines = answers\n .map((a) => `- ${a.question}: ${a.answer}`)\n .join(\"\\n\");\n\n finalIntent =\n `User intent: \"${intentRaw}\"\\n\\nClarifications:\\n${clarificationLines}`;\n }\n }\n\n // 5. Compilation\n console.log(ui.section(\"Compilation\"));\n\n const spinner = ora({ text: \"Loading tool registry...\", indent: 2 }).start();\n\n let spec;\n try {\n spec = await compile(finalIntent, (msg) => {\n spinner.text = msg;\n });\n spinner.succeed(\"Environment compiled\");\n } catch (err) {\n spinner.fail(\"Compilation failed\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n ${msg}\\n`));\n process.exit(1);\n }\n\n // 6. Results display\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(\"\");\n console.log(ui.kv(\"Name:\", spec.name));\n console.log(ui.kv(\"Description:\", spec.description));\n console.log(ui.kv(\"Tools:\", String(summary.toolCount)));\n console.log(ui.kv(\"Commands:\", String(summary.commandCount)));\n console.log(ui.kv(\"Rules:\", String(summary.ruleCount)));\n console.log(ui.kv(\"Skills:\", String(summary.skillCount)));\n console.log(ui.kv(\"Agents:\", String(summary.agentCount)));\n\n if (spec.tools.length > 0) {\n console.log(ui.section(\"Selected Tools\"));\n console.log(\"\");\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(ui.tool(name, tool.reason));\n console.log(\"\");\n }\n }\n\n // 7. Confirm\n const proceed =\n options.yes ||\n (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 // 8. Write\n const targetDir = process.cwd();\n const runtime = (options.runtime ?? \"claude-code\") as RuntimeTarget;\n\n if (runtime === \"hermes\") {\n await writeHermesEnvironment(spec, registry);\n console.log(\"\\n\" + ui.success(\"Environment written for Hermes\"));\n console.log(\n chalk.cyan(\"\\n Ready! Run \") + chalk.bold(\"hermes\") + chalk.cyan(\" to start.\\n\")\n );\n } else {\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(ui.section(\"Files Written\"));\n console.log(\"\");\n for (const file of written) {\n console.log(ui.file(file));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(ui.section(\"Setup Required\"));\n console.log(\"\");\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(ui.envVar(env.envVar, env.description, env.signupUrl));\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(ui.section(\"Plugins\"));\n console.log(\"\");\n for (const cmd of summary.pluginCommands) {\n console.log(ui.cmd(cmd));\n }\n console.log(\"\");\n }\n\n console.log(ui.divider());\n console.log(ui.success(\"Ready! Run: $ claude\"));\n console.log(\"\");\n }\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport crypto from \"crypto\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { loadConfig, getEnvsDir, ensureDirs } from \"../config.js\";\nimport { SYSTEM_PROMPT, CLARIFICATION_PROMPT } from \"./prompt.js\";\nimport { loadRegistry } from \"../registry/loader.js\";\nimport type { EnvironmentSpec, RegistryTool, KairnConfig, Clarification } from \"../types.js\";\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\nexport async function generateClarifications(\n intent: string,\n onProgress?: (msg: string) => void\n): Promise<Clarification[]> {\n const config = await loadConfig();\n if (!config) {\n throw new Error(\"No config found. Run `kairn init` first.\");\n }\n\n onProgress?.(\"Analyzing your request...\");\n\n // Use a fast model for clarifications\n const clarificationConfig = { ...config };\n if (config.provider === \"anthropic\") {\n clarificationConfig.model = \"claude-haiku-4-5-20251001\";\n }\n\n const response = await callLLM(clarificationConfig, CLARIFICATION_PROMPT + \"\\n\\nUser description: \" + intent);\n\n try {\n let cleaned = response.trim();\n if (cleaned.startsWith(\"```\")) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, \"\").replace(/\\n?```$/, \"\");\n }\n const jsonMatch = cleaned.match(/\\[[\\s\\S]*\\]/);\n if (!jsonMatch) return [];\n return JSON.parse(jsonMatch[0]) as Clarification[];\n } catch {\n return [];\n }\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 120 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 120 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## Verification\nAfter implementing any change, verify it works:\n- {build command} — must pass with no errors\n- {test command} — all tests must pass\n- {lint command} — no warnings or errors\n- {type check command} — no type errors\n\nIf any verification step fails, fix the issue before moving on.\nDo NOT skip verification steps.\n\n## Known Gotchas\n<!-- After any correction, add it here: \"Update CLAUDE.md so you don't make that mistake again.\" -->\n<!-- Prune this section when it exceeds 10 items — keep only the recurring ones. -->\n- (none yet — this section grows as you work)\n\n## Debugging\nWhen debugging, paste raw error output. Don't summarize — Claude works better with raw data.\nUse subagents for deep investigation to keep main context clean.\n\n## Git Workflow\n- Prefer small, focused commits (one feature or fix per commit)\n- Use conventional commits: feat:, fix:, docs:, refactor:, test:\n- Target < 200 lines per PR when possible\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)\n13. A \"Verification\" section in CLAUDE.md with concrete verify commands for the project\n14. A \"Known Gotchas\" section in CLAUDE.md (starts empty, grows with corrections)\n15. A \"Debugging\" section in CLAUDE.md (2 lines: paste raw errors, use subagents)\n16. A \"Git Workflow\" section in CLAUDE.md (3 rules: small commits, conventional format, <200 lines PR)\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 120 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- \\`/project:spec\\` command (interview-based spec creation — asks 5-8 questions one at a time, writes structured spec to docs/SPRINT.md, does NOT start coding until confirmed)\n- \\`/project:prove\\` command (runs tests, shows git diff vs main, rates confidence HIGH/MEDIUM/LOW with evidence)\n- \\`/project:grill\\` command (adversarial code review — challenges each change with \"why this approach?\", \"what if X input?\", rates BLOCKER/SHOULD-FIX/NITPICK, blocks until BLOCKERs resolved)\n- \\`/project:reset\\` command (reads DECISIONS.md and LEARNINGS.md, proposes clean restart, stashes current work, implements elegant solution)\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- Note: the Verification section in CLAUDE.md should adapt for research — e.g. \"Verify all sources are cited\" instead of build/test commands\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## Hermes Runtime\n\nWhen generating for Hermes runtime, the same EnvironmentSpec JSON is produced. The adapter layer handles conversion:\n- MCP config entries → Hermes config.yaml mcp_servers\n- Commands and skills → ~/.hermes/skills/ markdown files\n- Rules → ~/.hermes/skills/rule-*.md files\n\nThe LLM output format does not change. Adapter-level conversion happens post-compilation.\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 120 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 \"spec\": \"Before building this feature, interview me to create a complete spec.\\\\n\\\\nAsk me 5-8 questions, one at a time:\\\\n1. What specifically should this feature do?\\\\n2. Who uses it and how?\\\\n3. What are the edge cases or error states?\\\\n4. How will we know it works? (acceptance criteria)\\\\n5. What should it explicitly NOT do? (scope boundaries)\\\\n6. Any dependencies, APIs, or constraints?\\\\n7. How does it fit with existing code?\\\\n8. Priority: speed, quality, or flexibility?\\\\n\\\\nAfter my answers, write a structured spec to docs/SPRINT.md:\\\\n- Feature name\\\\n- Description (from my answers, not invented)\\\\n- Acceptance criteria (testable)\\\\n- Out of scope\\\\n- Technical approach\\\\n\\\\nDo NOT start coding until I confirm the spec.\",\n \"prove\": \"Prove the current implementation works.\\\\n\\\\n1. Run the full test suite:\\\\n\\\\n!npm test 2>&1\\\\n\\\\n2. Compare against main:\\\\n\\\\n!git diff main --stat 2>/dev/null\\\\n\\\\n3. Show evidence:\\\\n - Test results (pass/fail counts)\\\\n - Behavioral diff (main vs this branch)\\\\n - Edge cases tested\\\\n - Error handling verified\\\\n\\\\n4. Rate confidence:\\\\n - HIGH: All tests pass, edge cases covered, no regressions\\\\n - MEDIUM: Core works, some edges untested\\\\n - LOW: Needs more verification\\\\n\\\\nIf LOW or MEDIUM, explain what's missing and fix it.\",\n \"grill\": \"Review the current changes adversarially.\\\\n\\\\n!git diff --staged 2>/dev/null || git diff HEAD 2>/dev/null\\\\n\\\\nAct as a senior engineer. For each file changed:\\\\n\\\\n1. \\\\\\\"Why this approach over X?\\\\\\\"\\\\n2. \\\\\\\"What happens if Y input?\\\\\\\"\\\\n3. \\\\\\\"Performance impact of Z?\\\\\\\"\\\\n4. \\\\\\\"This could break if...\\\\\\\"\\\\n\\\\nFor each concern:\\\\n- Severity: BLOCKER / SHOULD-FIX / NITPICK\\\\n- The exact scenario that could fail\\\\n- A suggested alternative\\\\n\\\\nDo NOT approve until all BLOCKERs are resolved.\",\n \"reset\": \"Stop. Read docs/DECISIONS.md and docs/LEARNINGS.md.\\\\n\\\\nConsidering everything we've learned:\\\\n1. What was the original approach?\\\\n2. What went wrong or feels inelegant?\\\\n3. What would the clean solution look like?\\\\n\\\\nPropose the new approach. Do NOT implement yet.\\\\nIf I approve, stash current changes:\\\\n git stash -m \\\\\\\"pre-reset: $(date +%Y%m%d-%H%M)\\\\\\\"\\\\n\\\\nThen implement the elegant solution.\"\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\nexport const CLARIFICATION_PROMPT = `You are helping a user define their project for environment compilation.\n\nGiven their initial description, generate 3-5 clarifying questions to understand:\n1. Language and framework\n2. What the project specifically does (be precise)\n3. Primary workflow (build, research, write, analyze?)\n4. Key dependencies or integrations\n5. Target audience\n\nFor each question, provide a reasonable suggestion based on the description.\n\nOutput ONLY a JSON array:\n[\n { \"question\": \"Language/framework?\", \"suggestion\": \"TypeScript + Node.js\" },\n ...\n]\n\nRules:\n- Suggestions should be reasonable guesses, clearly marked as suggestions\n- Keep questions short (under 10 words)\n- Maximum 5 questions\n- If the description is already very detailed, ask fewer questions`;\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getUserRegistryPath } from \"../config.js\";\nimport type { RegistryTool } from \"../types.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport async function loadBundledRegistry(): Promise<RegistryTool[]> {\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 async function loadUserRegistry(): Promise<RegistryTool[]> {\n try {\n const data = await fs.readFile(getUserRegistryPath(), \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n return [];\n }\n}\n\nexport async function saveUserRegistry(tools: RegistryTool[]): Promise<void> {\n await fs.writeFile(getUserRegistryPath(), JSON.stringify(tools, null, 2), \"utf-8\");\n}\n\nexport async function loadRegistry(): Promise<RegistryTool[]> {\n const bundled = await loadBundledRegistry();\n const user = await loadUserRegistry();\n\n if (user.length === 0) return bundled;\n\n // User tools take precedence by ID\n const merged = new Map<string, RegistryTool>();\n for (const tool of bundled) {\n merged.set(tool.id, tool);\n }\n for (const tool of user) {\n merged.set(tool.id, tool);\n }\n return Array.from(merged.values());\n}\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport type { EnvironmentSpec, RegistryTool } from \"../types.js\";\n\nconst STATUS_LINE = {\n command:\n \"printf '%s | %s tasks' \\\"$(git branch --show-current 2>/dev/null || echo 'no-git')\\\" \\\"$(grep -c '\\\\- \\\\[ \\\\]' docs/TODO.md 2>/dev/null || echo 0)\\\"\",\n};\n\nfunction isCodeProject(spec: EnvironmentSpec): boolean {\n const commands = spec.harness.commands ?? {};\n return \"status\" in commands || \"test\" in commands;\n}\n\nfunction resolveSettings(\n spec: EnvironmentSpec\n): Record<string, unknown> | null {\n const settings = spec.harness.settings;\n if (!settings || Object.keys(settings).length === 0) return null;\n if (\"statusLine\" in settings) return settings as Record<string, unknown>;\n if (isCodeProject(spec)) {\n return { ...(settings as Record<string, unknown>), statusLine: STATUS_LINE };\n }\n return settings as Record<string, unknown>;\n}\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 const resolvedSettings = resolveSettings(spec);\n if (resolvedSettings) {\n files.set(\".claude/settings.json\", JSON.stringify(resolvedSettings, null, 2));\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 const resolvedSettings = resolveSettings(spec);\n if (resolvedSettings) {\n const p = path.join(claudeDir, \"settings.json\");\n await writeFile(p, JSON.stringify(resolvedSettings, 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 fs from \"fs/promises\";\nimport path from \"path\";\nimport os from \"os\";\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\nfunction toYaml(obj: unknown, indent: number = 0): string {\n const pad = \" \".repeat(indent);\n\n if (obj === null || obj === undefined) {\n return \"~\";\n }\n\n if (typeof obj === \"boolean\") {\n return obj ? \"true\" : \"false\";\n }\n\n if (typeof obj === \"number\") {\n return String(obj);\n }\n\n if (typeof obj === \"string\") {\n // Quote strings that contain special characters or look like other types\n const needsQuotes =\n obj === \"\" ||\n /[:#\\[\\]{}&*!|>'\"%@`,]/.test(obj) ||\n /^(true|false|null|~|\\d)/.test(obj) ||\n obj.includes(\"\\n\");\n return needsQuotes ? `\"${obj.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"` : obj;\n }\n\n if (Array.isArray(obj)) {\n if (obj.length === 0) {\n return \"[]\";\n }\n return obj\n .map((item) => `${pad}- ${toYaml(item, indent + 1).trimStart()}`)\n .join(\"\\n\");\n }\n\n if (typeof obj === \"object\") {\n const entries = Object.entries(obj as Record<string, unknown>);\n if (entries.length === 0) {\n return \"{}\";\n }\n return entries\n .map(([key, value]) => {\n const valueStr = toYaml(value, indent + 1);\n const isScalar =\n typeof value !== \"object\" || value === null || Array.isArray(value);\n if (isScalar && !Array.isArray(value)) {\n return `${pad}${key}: ${valueStr}`;\n }\n if (Array.isArray(value)) {\n if ((value as unknown[]).length === 0) {\n return `${pad}${key}: []`;\n }\n return `${pad}${key}:\\n${valueStr}`;\n }\n return `${pad}${key}:\\n${valueStr}`;\n })\n .join(\"\\n\");\n }\n\n return String(obj);\n}\n\nfunction buildMcpServersYaml(\n spec: EnvironmentSpec,\n registry: RegistryTool[]\n): string {\n const servers: Record<string, unknown> = {};\n\n // For each selected tool, check for hermes-specific mcp_server config first\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.hermes?.mcp_server) {\n const serverName = tool.id.replace(/_/g, \"-\");\n servers[serverName] = tool.install.hermes.mcp_server;\n } else if (tool.install.mcp_config) {\n // Fall back to converting the Claude Code mcp_config format\n for (const [serverName, serverConfig] of Object.entries(\n tool.install.mcp_config\n )) {\n servers[serverName] = serverConfig;\n }\n }\n }\n\n // Also include any mcp_config entries from the harness that weren't covered by tools\n for (const [serverName, serverConfig] of Object.entries(\n spec.harness.mcp_config || {}\n )) {\n if (!(serverName in servers)) {\n servers[serverName] = serverConfig;\n }\n }\n\n if (Object.keys(servers).length === 0) {\n return \"\";\n }\n\n const lines: string[] = [];\n lines.push(`# Generated by Kairn v1.5.0`);\n lines.push(`# Environment: ${spec.name}`);\n lines.push(``);\n lines.push(`mcp_servers:`);\n\n for (const [serverName, serverConfig] of Object.entries(servers)) {\n lines.push(` ${serverName}:`);\n lines.push(toYaml(serverConfig, 2));\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nexport async function writeHermesEnvironment(\n spec: EnvironmentSpec,\n registry: RegistryTool[]\n): Promise<string[]> {\n const hermesDir = path.join(os.homedir(), \".hermes\");\n const written: string[] = [];\n\n // 1. config.yaml\n const configYaml = buildMcpServersYaml(spec, registry);\n if (configYaml) {\n const configPath = path.join(hermesDir, \"config.yaml\");\n await writeFile(configPath, configYaml);\n written.push(\".hermes/config.yaml\");\n }\n\n // 2. Skills from commands\n if (spec.harness.commands) {\n for (const [name, content] of Object.entries(spec.harness.commands)) {\n const skillPath = path.join(hermesDir, \"skills\", `${name}.md`);\n await writeFile(skillPath, content);\n written.push(`.hermes/skills/${name}.md`);\n }\n }\n\n // 3. Skills from skills\n if (spec.harness.skills) {\n for (const [name, content] of Object.entries(spec.harness.skills)) {\n const skillPath = path.join(hermesDir, \"skills\", `${name}.md`);\n await writeFile(skillPath, content);\n written.push(`.hermes/skills/${name}.md`);\n }\n }\n\n // 4. Skills from rules (prefixed with \"rule-\")\n if (spec.harness.rules) {\n for (const [name, content] of Object.entries(spec.harness.rules)) {\n const skillPath = path.join(hermesDir, \"skills\", `rule-${name}.md`);\n await writeFile(skillPath, content);\n written.push(`.hermes/skills/rule-${name}.md`);\n }\n }\n\n return written;\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\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.js\";\n\nexport const listCommand = new Command(\"list\")\n .description(\"Show saved environments\")\n .action(async () => {\n printCompactBanner();\n\n const envsDir = getEnvsDir();\n\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.dim(\" 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(\" No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n let first = true;\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 if (!first) {\n console.log(ui.divider());\n }\n first = false;\n\n console.log(ui.kv(\"Name\", chalk.bold(spec.name)));\n console.log(ui.kv(\"Description\", spec.description));\n console.log(ui.kv(\"Date\", `${date} · ${toolCount} tools`));\n console.log(ui.kv(\"ID\", chalk.dim(spec.id)));\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, getTemplatesDir } from \"../config.js\";\nimport { writeEnvironment } from \"../adapter/claude-code.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.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 printCompactBanner();\n\n const envsDir = getEnvsDir();\n const templatesDir = getTemplatesDir();\n\n // Find the env file — accept full ID or partial match\n let sourceDir: string;\n let match: string | undefined;\n let fromTemplate = false;\n\n // 1. Search envs dir\n let envFiles: string[] = [];\n try {\n envFiles = await fs.readdir(envsDir);\n } catch {\n // envs dir may not exist yet; continue to templates search\n }\n\n match = envFiles.find(\n (f) => f === `${envId}.json` || f.startsWith(envId)\n );\n\n if (match) {\n sourceDir = envsDir;\n } else {\n // 2. Fall back to templates dir\n let templateFiles: string[] = [];\n try {\n templateFiles = await fs.readdir(templatesDir);\n } catch {\n // templates dir may not exist\n }\n\n match = templateFiles.find(\n (f) => f === `${envId}.json` || f.startsWith(envId)\n );\n\n if (match) {\n sourceDir = templatesDir;\n fromTemplate = true;\n } else {\n console.log(ui.error(`Environment \"${envId}\" not found.`));\n console.log(chalk.dim(\" Run kairn list to see saved environments.\"));\n console.log(chalk.dim(\" Run kairn templates to see available templates.\\n\"));\n process.exit(1);\n }\n }\n\n const data = await fs.readFile(path.join(sourceDir, match), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n\n const label = fromTemplate ? chalk.dim(\" (template)\") : \"\";\n console.log(chalk.cyan(` Activating: ${spec.name}`) + label);\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(ui.success(\"Environment written\\n\"));\n for (const file of written) {\n console.log(ui.file(file));\n }\n\n console.log(\"\\n\" + ui.success(`Ready! Run: $ claude`) + \"\\n\");\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.js\";\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 printCompactBanner();\n\n const url = options.url || REGISTRY_URL;\n\n console.log(chalk.dim(` Fetching registry from ${url}...`));\n\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n console.log(\n ui.error(`Failed to fetch registry: ${response.status} ${response.statusText}`)\n );\n console.log(chalk.dim(\" The remote registry may not be available yet.\"));\n console.log(chalk.dim(\" Your local registry is still active.\\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(ui.error(`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(ui.success(`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(ui.error(`Network error: ${msg}`));\n console.log(chalk.dim(\" Your local registry is still active.\\n\"));\n }\n });\n","import { Command } from \"commander\";\nimport { confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\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 { writeHermesEnvironment } from \"../adapter/hermes-agent.js\";\nimport { loadRegistry } from \"../registry/loader.js\";\nimport type { RuntimeTarget } from \"../types.js\";\nimport { scanProject } from \"../scanner/scan.js\";\nimport type { ProjectProfile } from \"../scanner/scan.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.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\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 .option(\"--runtime <runtime>\", \"Target runtime (claude-code or hermes)\", \"claude-code\")\n .action(async (options: { yes?: boolean; auditOnly?: boolean; diff?: boolean; runtime?: string }) => {\n printCompactBanner();\n\n const config = await loadConfig();\n if (!config) {\n console.log(ui.errorBox(\"KAIRN — Error\", \"No config found. Run kairn init first.\"));\n process.exit(1);\n }\n\n const targetDir = process.cwd();\n\n // 1. Scan\n console.log(ui.section(\"Project Scan\"));\n const scanSpinner = ora({ text: \"Scanning project...\", indent: 2 }).start();\n const profile = await scanProject(targetDir);\n scanSpinner.stop();\n\n // 2. Show profile\n if (profile.language) console.log(ui.kv(\"Language:\", profile.language));\n if (profile.framework) console.log(ui.kv(\"Framework:\", profile.framework));\n console.log(ui.kv(\"Dependencies:\", String(profile.dependencies.length)));\n if (profile.testCommand) console.log(ui.kv(\"Tests:\", profile.testCommand));\n if (profile.buildCommand) console.log(ui.kv(\"Build:\", profile.buildCommand));\n if (profile.hasDocker) console.log(ui.kv(\"Docker:\", \"yes\"));\n if (profile.hasCi) console.log(ui.kv(\"CI/CD:\", \"yes\"));\n if (profile.envKeys.length > 0) console.log(ui.kv(\"Env keys:\", profile.envKeys.join(\", \")));\n\n // 3. Audit existing harness\n if (profile.hasClaudeDir) {\n console.log(ui.section(\"Harness Audit\"));\n console.log(ui.kv(\"CLAUDE.md:\", `${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? \" ⚠ bloated\" : \" ✓\"}`));\n console.log(ui.kv(\"MCP servers:\", String(profile.mcpServerCount)));\n console.log(ui.kv(\"Commands:\", profile.existingCommands.length > 0 ? profile.existingCommands.join(\", \") : \"none\"));\n console.log(ui.kv(\"Rules:\", profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"));\n console.log(ui.kv(\"Skills:\", profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"));\n console.log(ui.kv(\"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(\"\");\n for (const issue of issues) {\n console.log(ui.warn(issue));\n }\n } else {\n console.log(ui.success(\"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 const spinner = ora({ text: \"Compiling optimized environment...\", indent: 2 }).start();\n try {\n spec = await compile(intent, (msg) => {\n spinner.text = msg;\n });\n spinner.succeed(\"Environment compiled\");\n } catch (err) {\n spinner.fail(\"Compilation failed\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(ui.errorBox(\"KAIRN — Error\", `Optimization failed: ${msg}`));\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(\"\");\n console.log(ui.kv(\"Name:\", spec.name));\n console.log(ui.kv(\"Tools:\", String(summary.toolCount)));\n console.log(ui.kv(\"Commands:\", String(summary.commandCount)));\n console.log(ui.kv(\"Rules:\", String(summary.ruleCount)));\n console.log(ui.kv(\"Skills:\", String(summary.skillCount)));\n console.log(ui.kv(\"Agents:\", String(summary.agentCount)));\n\n if (spec.tools.length > 0) {\n console.log(ui.section(\"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(ui.tool(name, tool.reason));\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(ui.success(\"No changes needed — environment is already up to date.\"));\n console.log(\"\");\n return;\n }\n\n console.log(ui.section(\"Changes Preview\"));\n for (const d of changedDiffs) {\n console.log(chalk.cyan(`\\n --- ${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 }\n console.log(\"\");\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 runtime = (options.runtime ?? \"claude-code\") as RuntimeTarget;\n\n if (runtime === \"hermes\") {\n await writeHermesEnvironment(spec, registry);\n console.log(ui.divider());\n console.log(ui.success(`Ready! Run: $ hermes`));\n console.log(\"\");\n } else {\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(ui.section(\"Files Written\"));\n for (const file of written) {\n console.log(ui.file(file));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(ui.section(\"Setup Required\"));\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(ui.envVar(env.envVar, env.description, env.signupUrl));\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(ui.section(\"Plugins\"));\n for (const cmd of summary.pluginCommands) {\n console.log(ui.cmd(cmd));\n }\n console.log(\"\");\n }\n\n console.log(ui.divider());\n console.log(ui.success(\"Ready! Run: $ claude\"));\n console.log(\"\");\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\";\nimport { ui } from \"../ui.js\";\nimport { printFullBanner } from \"../logo.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 printFullBanner(\"Doctor\");\n\n const targetDir = process.cwd();\n\n console.log(chalk.dim(\" Checking .claude/ environment...\\n\"));\n\n const profile = await scanProject(targetDir);\n\n if (!profile.hasClaudeDir) {\n console.log(ui.error(\"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 console.log(ui.section(\"Health Check\"));\n console.log(\"\");\n\n // Display results\n for (const check of checks) {\n if (check.status === \"pass\") {\n console.log(ui.success(`${check.name}: ${check.message}`));\n } else if (check.status === \"warn\") {\n console.log(ui.warn(`${check.name}: ${check.message}`));\n } else {\n console.log(ui.error(`${check.name}: ${check.message}`));\n }\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","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { input, select } from \"@inquirer/prompts\";\nimport { loadRegistry, loadUserRegistry, saveUserRegistry } from \"../registry/loader.js\";\nimport type { RegistryTool } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.js\";\n\nconst listCommand = new Command(\"list\")\n .description(\"List tools in the registry\")\n .option(\"--category <cat>\", \"Filter by category\")\n .option(\"--user-only\", \"Show only user-defined tools\")\n .action(async (options: { category?: string; userOnly?: boolean }) => {\n printCompactBanner();\n\n let all: RegistryTool[];\n let userTools: RegistryTool[];\n\n try {\n [all, userTools] = await Promise.all([loadRegistry(), loadUserRegistry()]);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(ui.error(`Failed to load registry: ${msg}\\n`));\n process.exit(1);\n }\n\n const userIds = new Set(userTools.map((t) => t.id));\n\n let tools = all;\n\n if (options.userOnly) {\n tools = tools.filter((t) => userIds.has(t.id));\n }\n\n if (options.category) {\n tools = tools.filter(\n (t) => t.category.toLowerCase() === options.category!.toLowerCase()\n );\n }\n\n if (tools.length === 0) {\n console.log(chalk.dim(\"\\n No tools found.\\n\"));\n return;\n }\n\n const bundledCount = all.filter((t) => !userIds.has(t.id)).length;\n const userCount = userIds.size;\n\n console.log(ui.section(\"Registry Tools\"));\n console.log(\"\");\n\n for (const tool of tools) {\n const isUser = userIds.has(tool.id);\n const meta = [\n tool.category,\n `tier ${tool.tier}`,\n tool.auth,\n ].join(\", \");\n\n console.log(` ${ui.accent(tool.id)}` + chalk.dim(` (${meta})`));\n console.log(chalk.dim(` ${tool.description}`));\n\n if (tool.best_for.length > 0) {\n console.log(chalk.dim(` Best for: ${tool.best_for.join(\", \")}`));\n }\n\n if (isUser) {\n console.log(chalk.yellow(\" [USER-DEFINED]\"));\n }\n\n console.log(\"\");\n }\n\n const totalShown = tools.length;\n const shownUser = tools.filter((t) => userIds.has(t.id)).length;\n const shownBundled = totalShown - shownUser;\n\n console.log(\n chalk.dim(\n ` ${totalShown} tool${totalShown !== 1 ? \"s\" : \"\"} (${shownBundled} bundled, ${shownUser} user-defined)`\n ) + \"\\n\"\n );\n });\n\nconst addCommand = new Command(\"add\")\n .description(\"Add a tool to the user registry\")\n .action(async () => {\n let id: string;\n try {\n id = await input({\n message: \"Tool ID (kebab-case)\",\n validate: (v) => {\n if (!v) return \"ID is required\";\n if (!/^[a-z][a-z0-9-]*$/.test(v)) return \"ID must be kebab-case (e.g. my-tool)\";\n return true;\n },\n });\n\n const name = await input({ message: \"Display name\" });\n const description = await input({ message: \"Description\" });\n\n const category = await select({\n message: \"Category\",\n choices: [\n { value: \"universal\" },\n { value: \"code\" },\n { value: \"search\" },\n { value: \"data\" },\n { value: \"communication\" },\n { value: \"design\" },\n { value: \"monitoring\" },\n { value: \"infrastructure\" },\n { value: \"sandbox\" },\n ],\n });\n\n const tier = await select<number>({\n message: \"Tier\",\n choices: [\n { name: \"1 — Universal\", value: 1 },\n { name: \"2 — Common\", value: 2 },\n { name: \"3 — Specialized\", value: 3 },\n ],\n });\n\n const type = await select<\"mcp_server\" | \"plugin\" | \"hook\">({\n message: \"Type\",\n choices: [\n { value: \"mcp_server\" },\n { value: \"plugin\" },\n { value: \"hook\" },\n ],\n });\n\n const auth = await select<\"none\" | \"api_key\" | \"oauth\" | \"connection_string\">({\n message: \"Auth\",\n choices: [\n { value: \"none\" },\n { value: \"api_key\" },\n { value: \"oauth\" },\n { value: \"connection_string\" },\n ],\n });\n\n const env_vars: { name: string; description: string }[] = [];\n if (auth === \"api_key\" || auth === \"connection_string\") {\n let addMore = true;\n while (addMore) {\n const varName = await input({ message: \"Env var name\" });\n const varDesc = await input({ message: \"Env var description\" });\n env_vars.push({ name: varName, description: varDesc });\n const another = await select<boolean>({\n message: \"Add another env var?\",\n choices: [\n { name: \"No\", value: false },\n { name: \"Yes\", value: true },\n ],\n });\n addMore = another;\n }\n }\n\n const signup_url_raw = await input({ message: \"Signup URL (optional, press enter to skip)\" });\n const signup_url = signup_url_raw.trim() || undefined;\n\n const best_for_raw = await input({ message: \"Best-for tags, comma-separated\" });\n const best_for = best_for_raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n const install: RegistryTool[\"install\"] = {};\n if (type === \"mcp_server\") {\n const command = await input({ message: \"MCP command\" });\n const args_raw = await input({ message: \"MCP args, comma-separated (leave blank for none)\" });\n const args = args_raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n install.mcp_config = { command, args };\n }\n\n const tool: RegistryTool = {\n id,\n name,\n description,\n category,\n tier,\n type,\n auth,\n best_for,\n install,\n ...(env_vars.length > 0 ? { env_vars } : {}),\n ...(signup_url ? { signup_url } : {}),\n };\n\n let userToolsList: RegistryTool[];\n try {\n userToolsList = await loadUserRegistry();\n } catch {\n userToolsList = [];\n }\n\n const existingIdx = userToolsList.findIndex((t) => t.id === id);\n if (existingIdx >= 0) {\n userToolsList[existingIdx] = tool;\n } else {\n userToolsList.push(tool);\n }\n\n await saveUserRegistry(userToolsList);\n\n console.log(ui.success(`Tool ${id} added to user registry\\n`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(ui.error(`Failed to add tool: ${msg}\\n`));\n process.exit(1);\n }\n });\n\nexport const registryCommand = new Command(\"registry\")\n .description(\"Manage the tool registry\")\n .addCommand(listCommand)\n .addCommand(addCommand);\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getTemplatesDir } from \"../config.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\nimport { ui } from \"../ui.js\";\nimport { printCompactBanner } from \"../logo.js\";\n\nexport const templatesCommand = new Command(\"templates\")\n .description(\"Browse available templates\")\n .option(\"--category <cat>\", \"filter templates by category keyword\")\n .option(\"--json\", \"output raw JSON array\")\n .action(async (options: { category?: string; json?: boolean }) => {\n printCompactBanner();\n\n const templatesDir = getTemplatesDir();\n\n let files: string[];\n try {\n files = await fs.readdir(templatesDir);\n } catch {\n console.log(\n chalk.dim(\n \" No templates found. Templates will be installed with \"\n ) +\n chalk.bold(\"kairn init\") +\n chalk.dim(\n \" or you can add .json files to ~/.kairn/templates/\\n\"\n )\n );\n return;\n }\n\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n if (jsonFiles.length === 0) {\n console.log(\n chalk.dim(\n \" No templates found. Templates will be installed with \"\n ) +\n chalk.bold(\"kairn init\") +\n chalk.dim(\n \" or you can add .json files to ~/.kairn/templates/\\n\"\n )\n );\n return;\n }\n\n const templates: EnvironmentSpec[] = [];\n\n for (const file of jsonFiles) {\n try {\n const data = await fs.readFile(\n path.join(templatesDir, file),\n \"utf-8\"\n );\n const spec = JSON.parse(data) as EnvironmentSpec;\n templates.push(spec);\n } catch {\n // Skip malformed files\n }\n }\n\n const filtered = options.category\n ? templates.filter((t) => {\n const keyword = options.category!.toLowerCase();\n return (\n t.intent?.toLowerCase().includes(keyword) ||\n t.description?.toLowerCase().includes(keyword)\n );\n })\n : templates;\n\n if (options.json) {\n console.log(JSON.stringify(filtered, null, 2));\n return;\n }\n\n if (filtered.length === 0) {\n console.log(\n chalk.dim(` No templates matched category \"${options.category}\".\\n`)\n );\n return;\n }\n\n console.log(ui.section(\"Templates\"));\n console.log(\"\");\n\n for (const spec of filtered) {\n const toolCount = spec.tools?.length ?? 0;\n const commandCount = Object.keys(spec.harness?.commands ?? {}).length;\n const ruleCount = Object.keys(spec.harness?.rules ?? {}).length;\n\n console.log(ui.kv(\"Name\", chalk.bold(spec.name)));\n console.log(ui.kv(\"ID\", chalk.dim(spec.id)));\n console.log(ui.kv(\"Description\", spec.description));\n console.log(\n ui.kv(\"Contents\", `${toolCount} tools · ${commandCount} commands · ${ruleCount} rules`)\n );\n console.log(\"\");\n }\n\n console.log(\n chalk.dim(` ${filtered.length} template${filtered.length === 1 ? \"\" : \"s\"} available\\n`)\n );\n });\n"],"mappings":"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","names":["Command","chalk","chalk","fs","path","path","chalk","maroon","maroon","chalk","path","fs","chalk","Command","chalk","fs","path","Anthropic","OpenAI","fs","path","fileURLToPath","__filename","fileURLToPath","__dirname","path","fs","Anthropic","OpenAI","path","fs","fs","path","fs","path","os","writeFile","Command","chalk","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","fileURLToPath","__filename","fileURLToPath","__dirname","path","fs","Command","chalk","Command","confirm","chalk","ora","fs","path","fs","path","chalk","path","fs","Command","ora","confirm","Command","chalk","perms","Command","chalk","Command","chalk","input","select","listCommand","Command","chalk","input","select","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk"]}
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
{ "tool_id": "postgresql-bytebase", "reason": "Schema inspection and safe migration execution" }
|
|
12
12
|
],
|
|
13
13
|
"harness": {
|
|
14
|
-
"claude_md": "# API Service\n\n## Purpose\nREST API backend service with Node.js, Express, and PostgreSQL.\n\n## Tech Stack\n- Node.js 20 + TypeScript (strict)\n- Express.js\n- Prisma + PostgreSQL\n- Vitest (unit + integration)\n- Zod (validation)\n\n## Commands\n```bash\nnpm run dev # Start dev server with hot reload\nnpm run build # Compile TypeScript\nnpm run test # Run Vitest\nnpm run migrate # Run Prisma migrations\nnpm run lint # ESLint check\n```\n\n## Architecture\n```\nsrc/\n api/ → Route handlers\n routes/ → Express router definitions\n services/ → Business logic layer\n db/ → Prisma client and helpers\n middleware/ → Auth, validation, error handling\n types/ → Shared TypeScript types\ntests/ → Unit and integration tests\n```\n\n## Conventions\n- All handlers return `{ data, error }` shape\n- Use Zod for all request/response validation\n- Log errors with request ID for traceability\n- Never expose internal error details to clients\n- Conventional commits: feat:, fix:, docs:, refactor:\n\n## Key Commands\n- `/project:help` — environment guide\n- `/project:tasks` — manage TODO list\n- `/project:sprint` — start a focused work session\n- `/project:review` — review staged changes\n\n## Output\n- Build output: `dist/`\n- Test coverage: `coverage/`\n- API docs: `docs/API.md`\n",
|
|
14
|
+
"claude_md": "# API Service\n\n## Purpose\nREST API backend service with Node.js, Express, and PostgreSQL.\n\n## Tech Stack\n- Node.js 20 + TypeScript (strict)\n- Express.js\n- Prisma + PostgreSQL\n- Vitest (unit + integration)\n- Zod (validation)\n\n## Commands\n```bash\nnpm run dev # Start dev server with hot reload\nnpm run build # Compile TypeScript\nnpm run test # Run Vitest\nnpm run migrate # Run Prisma migrations\nnpm run lint # ESLint check\n```\n\n## Architecture\n```\nsrc/\n api/ → Route handlers\n routes/ → Express router definitions\n services/ → Business logic layer\n db/ → Prisma client and helpers\n middleware/ → Auth, validation, error handling\n types/ → Shared TypeScript types\ntests/ → Unit and integration tests\n```\n\n## Conventions\n- All handlers return `{ data, error }` shape\n- Use Zod for all request/response validation\n- Log errors with request ID for traceability\n- Never expose internal error details to clients\n- Conventional commits: feat:, fix:, docs:, refactor:\n\n## Key Commands\n- `/project:help` — environment guide\n- `/project:tasks` — manage TODO list\n- `/project:sprint` — start a focused work session\n- `/project:review` — review staged changes\n\n## Output\n- Build output: `dist/`\n- Test coverage: `coverage/`\n- API docs: `docs/API.md`\n\n## Verification\nAfter implementing any change, verify:\n- `npm run build` — must pass with no errors\n- `npm run test` — all tests must pass\n- `npm run lint` — no warnings\n\nIf any step fails, fix before moving on.\n\n## Known Gotchas\n<!-- Update this after corrections. Prune when >10 items. -->\n- (none yet)\n\n## Debugging\nPaste raw error output. Don't summarize. Use subagents for deep investigation.\n\n## Git Workflow\n- Small, focused commits (one feature/fix per commit)\n- Conventional commits: feat:, fix:, docs:, refactor:, test:\n- Target < 200 lines per PR\n",
|
|
15
15
|
"settings": {
|
|
16
16
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
17
17
|
"permissions": {
|
|
@@ -56,6 +56,9 @@
|
|
|
56
56
|
]
|
|
57
57
|
}
|
|
58
58
|
]
|
|
59
|
+
},
|
|
60
|
+
"statusLine": {
|
|
61
|
+
"command": "printf '%s | %s tasks' \"$(git branch --show-current 2>/dev/null || echo 'no-git')\" \"$(grep -c '\\- \\[ \\]' docs/TODO.md 2>/dev/null || echo 0)\""
|
|
59
62
|
}
|
|
60
63
|
},
|
|
61
64
|
"mcp_config": {},
|
|
@@ -68,7 +71,11 @@
|
|
|
68
71
|
"plan": "Analyze the task and create a plan before coding.\n\n1. Read the relevant code to understand current state\n2. Write a step-by-step plan to docs/DECISIONS.md\n3. Include: what files to modify, what tests to write, risks\n4. Do NOT start coding — plan only\n\n!git diff --stat HEAD~3 2>/dev/null",
|
|
69
72
|
"review": "Review staged changes for quality, security, and completeness:\n\n!git diff --staged\n\nFocus on:\n1. Security vulnerabilities (injection, XSS, auth bypass)\n2. Error handling gaps\n3. Missing edge cases\n4. Test coverage\n5. Adherence to project conventions\n\nRate each finding: HIGH/MEDIUM/LOW severity.",
|
|
70
73
|
"test": "Run the test suite and fix any failures:\n\n!npm run test 2>&1 | tail -40\n\nIf tests pass: report summary.\nIf tests fail: read the failing test, understand what's expected,\nfix the implementation (not the test), and re-run.\n\nIterate until all tests pass.",
|
|
71
|
-
"commit": "Create a well-formatted conventional commit:\n\n!git diff --staged --stat\n\nWrite a commit message following conventional commits:\n- feat: new feature\n- fix: bug fix\n- docs: documentation\n- refactor: code restructuring\n- test: adding tests\n\nInclude a brief body if the change is non-trivial.\nRun: git commit -m \"type: description\""
|
|
74
|
+
"commit": "Create a well-formatted conventional commit:\n\n!git diff --staged --stat\n\nWrite a commit message following conventional commits:\n- feat: new feature\n- fix: bug fix\n- docs: documentation\n- refactor: code restructuring\n- test: adding tests\n\nInclude a brief body if the change is non-trivial.\nRun: git commit -m \"type: description\"",
|
|
75
|
+
"spec": "Before building this feature, interview me to create a complete spec.\n\nAsk me 5-8 questions, one at a time:\n1. What specifically should this feature do?\n2. Who uses it and how?\n3. Edge cases or error states?\n4. How will we know it works?\n5. What should it NOT do?\n6. Dependencies or constraints?\n7. Integration points?\n8. Priority: speed, quality, or flexibility?\n\nWrite spec to docs/SPRINT.md. Do NOT start coding until I confirm.",
|
|
76
|
+
"prove": "Prove the current implementation works.\n\n1. Run tests:\n\n!npm run test 2>&1\n\n2. Compare against main:\n\n!git diff main --stat 2>/dev/null\n\n3. Show evidence: test results, behavioral diff, edge cases, error handling.\n\n4. Rate confidence: HIGH / MEDIUM / LOW\n\nIf not HIGH, explain what's missing and fix it.",
|
|
77
|
+
"grill": "Review changes adversarially.\n\n!git diff --staged 2>/dev/null || git diff HEAD 2>/dev/null\n\nFor each file: challenge approach, edge cases, performance.\nRate: BLOCKER / SHOULD-FIX / NITPICK\nDo NOT approve until BLOCKERs resolved.",
|
|
78
|
+
"reset": "Stop. Read docs/DECISIONS.md and docs/LEARNINGS.md.\n\nWhat was the original approach? What went wrong?\nPropose clean solution. Do NOT implement yet.\nIf approved: git stash -m \"pre-reset: $(date +%Y%m%d-%H%M)\"\nThen implement."
|
|
72
79
|
},
|
|
73
80
|
"rules": {
|
|
74
81
|
"continuity": "At the end of significant work sessions:\n- Update docs/TODO.md with current task status\n- Update docs/DECISIONS.md with any architectural decisions\n- Update docs/LEARNINGS.md with non-obvious discoveries\n\nAt the start of sessions:\n- Read docs/TODO.md and docs/DECISIONS.md for context",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{ "tool_id": "exa-search", "reason": "Research facts, find examples, and verify claims" }
|
|
11
11
|
],
|
|
12
12
|
"harness": {
|
|
13
|
-
"claude_md": "# Content Writing Project\n\n## Purpose\nContent creation workspace for drafting, editing, and publishing written work.\n\n## Tech Stack\n- Exa for research and fact-checking\n- Sequential Thinking for outlining\n- Markdown for all drafts\n\n## Commands\n```bash\n# No build system — this is a writing-first project\n```\n\n## Architecture\n```\ndocs/\n TODO.md → Content backlog and status\n LEARNINGS.md → Research notes and key facts\ndrafts/ → Work-in-progress pieces\npublished/ → Final, approved content\n```\n\n## Conventions\n- All drafts go in `drafts/` until approved\n- Move to `published/` only after review\n- Record research sources in docs/LEARNINGS.md\n- One file per piece — use descriptive filenames\n\n## Key Commands\n- `/project:help` — environment guide\n- `/project:tasks` — manage content backlog\n- `/project:draft` — start a new draft\n- `/project:edit` — review and improve a draft\n\n## Output\n- Drafts: `drafts/`\n- Published: `published/`\n- Research notes: `docs/LEARNINGS.md`\n",
|
|
13
|
+
"claude_md": "# Content Writing Project\n\n## Purpose\nContent creation workspace for drafting, editing, and publishing written work.\n\n## Tech Stack\n- Exa for research and fact-checking\n- Sequential Thinking for outlining\n- Markdown for all drafts\n\n## Commands\n```bash\n# No build system — this is a writing-first project\n```\n\n## Architecture\n```\ndocs/\n TODO.md → Content backlog and status\n LEARNINGS.md → Research notes and key facts\ndrafts/ → Work-in-progress pieces\npublished/ → Final, approved content\n```\n\n## Conventions\n- All drafts go in `drafts/` until approved\n- Move to `published/` only after review\n- Record research sources in docs/LEARNINGS.md\n- One file per piece — use descriptive filenames\n\n## Key Commands\n- `/project:help` — environment guide\n- `/project:tasks` — manage content backlog\n- `/project:draft` — start a new draft\n- `/project:edit` — review and improve a draft\n\n## Output\n- Drafts: `drafts/`\n- Published: `published/`\n- Research notes: `docs/LEARNINGS.md`\n\n## Verification\nAfter writing sessions, verify:\n- Draft saved in drafts/ with descriptive filename\n- Sources cited in docs/LEARNINGS.md\n- Content backlog updated in docs/TODO.md\n\n## Known Gotchas\n<!-- Update after corrections. Prune when >10 items. -->\n- (none yet)\n",
|
|
14
14
|
"settings": {
|
|
15
15
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
16
16
|
"permissions": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
{ "tool_id": "playwright", "reason": "E2E browser testing for UI flows and API routes" }
|
|
12
12
|
],
|
|
13
13
|
"harness": {
|
|
14
|
-
"claude_md": "# Next.js Full-Stack App\n\n## Purpose\nFull-stack web application built with Next.js, TypeScript, and deployed to production.\n\n## Tech Stack\n- Next.js 15 (App Router)\n- TypeScript (strict)\n- Tailwind CSS\n- Prisma + PostgreSQL\n- Vitest + Playwright\n\n## Commands\n```bash\nnpm run dev # Start dev server (localhost:3000)\nnpm run build # Production build\nnpm run test # Run Vitest unit tests\nnpm run e2e # Run Playwright E2E tests\nnpm run lint # ESLint + TypeScript check\n```\n\n## Architecture\n```\napp/ → Next.js App Router pages and layouts\napp/api/ → Route handlers (REST endpoints)\ncomponents/ → Shared UI components\nlib/ → Business logic and utilities\nprisma/ → Schema, migrations, seed\ntests/ → Unit and integration tests\ne2e/ → Playwright E2E specs\n```\n\n## Conventions\n- Server Components by default; add 'use client' only when needed\n- All API routes return `{ data, error }` shape\n- Use Zod for request/response validation\n- Conventional commits: feat:, fix:, docs:, refactor:\n\n## Key Commands\n- `/project:help` — environment guide\n- `/project:tasks` — manage TODO list\n- `/project:sprint` — start a focused work session\n- `/project:review` — review staged changes\n- `/project:test` — run tests and fix failures\n\n## Output\n- Build artifacts: `.next/`\n- Test reports: `coverage/`\n- Decisions log: `docs/DECISIONS.md`\n",
|
|
14
|
+
"claude_md": "# Next.js Full-Stack App\n\n## Purpose\nFull-stack web application built with Next.js, TypeScript, and deployed to production.\n\n## Tech Stack\n- Next.js 15 (App Router)\n- TypeScript (strict)\n- Tailwind CSS\n- Prisma + PostgreSQL\n- Vitest + Playwright\n\n## Commands\n```bash\nnpm run dev # Start dev server (localhost:3000)\nnpm run build # Production build\nnpm run test # Run Vitest unit tests\nnpm run e2e # Run Playwright E2E tests\nnpm run lint # ESLint + TypeScript check\n```\n\n## Architecture\n```\napp/ → Next.js App Router pages and layouts\napp/api/ → Route handlers (REST endpoints)\ncomponents/ → Shared UI components\nlib/ → Business logic and utilities\nprisma/ → Schema, migrations, seed\ntests/ → Unit and integration tests\ne2e/ → Playwright E2E specs\n```\n\n## Conventions\n- Server Components by default; add 'use client' only when needed\n- All API routes return `{ data, error }` shape\n- Use Zod for request/response validation\n- Conventional commits: feat:, fix:, docs:, refactor:\n\n## Key Commands\n- `/project:help` — environment guide\n- `/project:tasks` — manage TODO list\n- `/project:sprint` — start a focused work session\n- `/project:review` — review staged changes\n- `/project:test` — run tests and fix failures\n\n## Output\n- Build artifacts: `.next/`\n- Test reports: `coverage/`\n- Decisions log: `docs/DECISIONS.md`\n\n## Verification\nAfter implementing any change, verify:\n- `npm run build` — must pass with no errors\n- `npm run test` — all tests must pass\n- `npm run lint` — no warnings\n\nIf any step fails, fix before moving on.\n\n## Known Gotchas\n<!-- Update this after corrections. Prune when >10 items. -->\n- (none yet)\n\n## Debugging\nPaste raw error output. Don't summarize. Use subagents for deep investigation.\n\n## Git Workflow\n- Small, focused commits (one feature/fix per commit)\n- Conventional commits: feat:, fix:, docs:, refactor:, test:\n- Target < 200 lines per PR\n",
|
|
15
15
|
"settings": {
|
|
16
16
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
17
17
|
"permissions": {
|
|
@@ -56,6 +56,9 @@
|
|
|
56
56
|
]
|
|
57
57
|
}
|
|
58
58
|
]
|
|
59
|
+
},
|
|
60
|
+
"statusLine": {
|
|
61
|
+
"command": "printf '%s | %s tasks' \"$(git branch --show-current 2>/dev/null || echo 'no-git')\" \"$(grep -c '\\- \\[ \\]' docs/TODO.md 2>/dev/null || echo 0)\""
|
|
59
62
|
}
|
|
60
63
|
},
|
|
61
64
|
"mcp_config": {},
|
|
@@ -68,7 +71,11 @@
|
|
|
68
71
|
"plan": "Analyze the task and create a plan before coding.\n\n1. Read the relevant code to understand current state\n2. Write a step-by-step plan to docs/DECISIONS.md\n3. Include: what files to modify, what tests to write, risks\n4. Do NOT start coding — plan only\n\n!git diff --stat HEAD~3 2>/dev/null",
|
|
69
72
|
"review": "Review staged changes for quality, security, and completeness:\n\n!git diff --staged\n\nFocus on:\n1. Security vulnerabilities (injection, XSS, auth bypass)\n2. Error handling gaps\n3. Missing edge cases\n4. Test coverage\n5. Adherence to project conventions\n\nRate each finding: HIGH/MEDIUM/LOW severity.",
|
|
70
73
|
"test": "Run the test suite and fix any failures:\n\n!npm run test 2>&1 | tail -40\n\nIf tests pass: report summary.\nIf tests fail: read the failing test, understand what's expected,\nfix the implementation (not the test), and re-run.\n\nIterate until all tests pass.",
|
|
71
|
-
"commit": "Create a well-formatted conventional commit:\n\n!git diff --staged --stat\n\nWrite a commit message following conventional commits:\n- feat: new feature\n- fix: bug fix\n- docs: documentation\n- refactor: code restructuring\n- test: adding tests\n\nInclude a brief body if the change is non-trivial.\nRun: git commit -m \"type: description\""
|
|
74
|
+
"commit": "Create a well-formatted conventional commit:\n\n!git diff --staged --stat\n\nWrite a commit message following conventional commits:\n- feat: new feature\n- fix: bug fix\n- docs: documentation\n- refactor: code restructuring\n- test: adding tests\n\nInclude a brief body if the change is non-trivial.\nRun: git commit -m \"type: description\"",
|
|
75
|
+
"spec": "Before building this feature, interview me to create a complete spec.\n\nAsk me 5-8 questions, one at a time:\n1. What specifically should this feature do?\n2. Who uses it and how?\n3. Edge cases or error states?\n4. How will we know it works?\n5. What should it NOT do?\n6. Dependencies or constraints?\n7. Integration points?\n8. Priority: speed, quality, or flexibility?\n\nWrite spec to docs/SPRINT.md. Do NOT start coding until I confirm.",
|
|
76
|
+
"prove": "Prove the current implementation works.\n\n1. Run tests:\n\n!npm run test 2>&1\n\n2. Compare against main:\n\n!git diff main --stat 2>/dev/null\n\n3. Show evidence: test results, behavioral diff, edge cases, error handling.\n\n4. Rate confidence: HIGH / MEDIUM / LOW\n\nIf not HIGH, explain what's missing and fix it.",
|
|
77
|
+
"grill": "Review changes adversarially.\n\n!git diff --staged 2>/dev/null || git diff HEAD 2>/dev/null\n\nFor each file: challenge approach, edge cases, performance.\nRate: BLOCKER / SHOULD-FIX / NITPICK\nDo NOT approve until BLOCKERs resolved.",
|
|
78
|
+
"reset": "Stop. Read docs/DECISIONS.md and docs/LEARNINGS.md.\n\nWhat was the original approach? What went wrong?\nPropose clean solution. Do NOT implement yet.\nIf approved: git stash -m \"pre-reset: $(date +%Y%m%d-%H%M)\"\nThen implement."
|
|
72
79
|
},
|
|
73
80
|
"rules": {
|
|
74
81
|
"continuity": "At the end of significant work sessions:\n- Update docs/TODO.md with current task status\n- Update docs/DECISIONS.md with any architectural decisions\n- Update docs/LEARNINGS.md with non-obvious discoveries\n\nAt the start of sessions:\n- Read docs/TODO.md and docs/DECISIONS.md for context",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
{ "tool_id": "perplexity", "reason": "AI-assisted research synthesis and fact-checking" }
|
|
12
12
|
],
|
|
13
13
|
"harness": {
|
|
14
|
-
"claude_md": "# Research Project\n\n## Purpose\nStructured research and analysis workspace for deep-dive investigation.\n\n## Tech Stack\n- MCP search tools: Exa, Perplexity\n- Sequential Thinking for structured analysis\n- Markdown docs for notes and synthesis\n\n## Commands\n```bash\n# No build system — this is a docs-first project\n```\n\n## Architecture\n```\ndocs/\n TODO.md → Tasks and open questions\n SOURCES.md → Collected sources with notes\n LEARNINGS.md → Key findings and insights\n SUMMARY.md → Synthesized output\n```\n\n## Conventions\n- Log every source in docs/SOURCES.md with title, URL, and key contribution\n- Record non-obvious findings in docs/LEARNINGS.md immediately\n- Open questions go in docs/TODO.md\n- Final synthesis goes to docs/SUMMARY.md\n\n## Key Commands\n- `/project:help` — environment guide\n- `/project:tasks` — manage open questions\n- `/project:research` — deep-dive on a topic\n- `/project:summarize` — synthesize current findings\n\n## Output\n- Primary deliverable: `docs/SUMMARY.md`\n- Source log: `docs/SOURCES.md`\n- Insights: `docs/LEARNINGS.md`\n",
|
|
14
|
+
"claude_md": "# Research Project\n\n## Purpose\nStructured research and analysis workspace for deep-dive investigation.\n\n## Tech Stack\n- MCP search tools: Exa, Perplexity\n- Sequential Thinking for structured analysis\n- Markdown docs for notes and synthesis\n\n## Commands\n```bash\n# No build system — this is a docs-first project\n```\n\n## Architecture\n```\ndocs/\n TODO.md → Tasks and open questions\n SOURCES.md → Collected sources with notes\n LEARNINGS.md → Key findings and insights\n SUMMARY.md → Synthesized output\n```\n\n## Conventions\n- Log every source in docs/SOURCES.md with title, URL, and key contribution\n- Record non-obvious findings in docs/LEARNINGS.md immediately\n- Open questions go in docs/TODO.md\n- Final synthesis goes to docs/SUMMARY.md\n\n## Key Commands\n- `/project:help` — environment guide\n- `/project:tasks` — manage open questions\n- `/project:research` — deep-dive on a topic\n- `/project:summarize` — synthesize current findings\n\n## Output\n- Primary deliverable: `docs/SUMMARY.md`\n- Source log: `docs/SOURCES.md`\n- Insights: `docs/LEARNINGS.md`\n\n## Verification\nAfter research sessions, verify:\n- All sources logged in docs/SOURCES.md with URL and key contribution\n- Key findings recorded in docs/LEARNINGS.md\n- Open questions tracked in docs/TODO.md\n\n## Known Gotchas\n<!-- Update after corrections. Prune when >10 items. -->\n- (none yet)\n",
|
|
15
15
|
"settings": {
|
|
16
16
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
17
17
|
"permissions": {
|