claude-launchpad 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -17
- package/dist/cli.js +45 -123
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ A launchpad isn't just where you start. It's where you prepare, run checks, and
|
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
17
|
npm i -g claude-launchpad
|
|
18
|
+
cd your-project
|
|
18
19
|
```
|
|
19
20
|
|
|
20
21
|
## Two Paths, One Tool
|
|
@@ -39,14 +40,14 @@ Scans your Claude Code config, gives you a score out of 100, and tells you exact
|
|
|
39
40
|
|
|
40
41
|
## All Commands
|
|
41
42
|
|
|
42
|
-
| Command | What it does |
|
|
43
|
-
|
|
44
|
-
| `claude-launchpad init` | Launch a new project: detects stack, generates config, hooks,
|
|
45
|
-
| `claude-launchpad` | Check your config: score it 0-100, list issues |
|
|
46
|
-
| `claude-launchpad doctor --fix` | Auto-fix issues: adds hooks, rules, missing sections, .claudeignore |
|
|
47
|
-
| `claude-launchpad doctor --watch` | Live score that updates when you save config files |
|
|
48
|
-
| `claude-launchpad enhance` | Claude reads your code and completes CLAUDE.md with real content |
|
|
49
|
-
| `claude-launchpad eval --suite security` | Run Claude against test scenarios, prove your config works |
|
|
43
|
+
| Command | What it does |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `claude-launchpad init` | Launch a new project: detects stack, generates config, security rules, hooks, permissions |
|
|
46
|
+
| `claude-launchpad` | Check your config: score it 0-100, list issues |
|
|
47
|
+
| `claude-launchpad doctor --fix` | Auto-fix issues: adds hooks, rules, missing sections, .claudeignore |
|
|
48
|
+
| `claude-launchpad doctor --watch` | Live score that updates when you save config files |
|
|
49
|
+
| `claude-launchpad enhance` | Claude reads your code and completes CLAUDE.md with real content |
|
|
50
|
+
| `claude-launchpad eval --suite security` | Run Claude against test scenarios, prove your config works |
|
|
50
51
|
|
|
51
52
|
## Quick Start
|
|
52
53
|
|
|
@@ -67,7 +68,7 @@ claude-launchpad doctor --fix
|
|
|
67
68
|
claude-launchpad
|
|
68
69
|
```
|
|
69
70
|
|
|
70
|
-
That takes you from ~42% to ~
|
|
71
|
+
That takes you from ~42% to ~93% with zero manual work.
|
|
71
72
|
|
|
72
73
|
## The Doctor
|
|
73
74
|
|
|
@@ -115,23 +116,26 @@ Detects your project and generates Claude Code config that fits. No templates, n
|
|
|
115
116
|
|
|
116
117
|
```
|
|
117
118
|
→ Detecting project...
|
|
118
|
-
✓ Found Next.js
|
|
119
|
+
✓ Found Next.js project
|
|
119
120
|
· Package manager: pnpm
|
|
120
|
-
· Dev command: pnpm dev
|
|
121
121
|
|
|
122
122
|
✓ Generated CLAUDE.md
|
|
123
123
|
✓ Generated TASKS.md
|
|
124
|
-
✓ Generated .claude/settings.json (
|
|
124
|
+
✓ Generated .claude/settings.json (schema, permissions, hooks)
|
|
125
|
+
✓ Generated .claude/.gitignore
|
|
125
126
|
✓ Generated .claudeignore
|
|
127
|
+
✓ Generated .claude/rules/conventions.md
|
|
126
128
|
```
|
|
127
129
|
|
|
128
130
|
**Works with:** TypeScript, JavaScript, Python, Go, Ruby, Rust, Dart, PHP, Java, Kotlin, Swift, Elixir, C# — and detects frameworks (Next.js, FastAPI, Django, Rails, Laravel, Express, SvelteKit, Angular, NestJS, and 15+ more).
|
|
129
131
|
|
|
130
|
-
**What you get:**
|
|
132
|
+
**What you get (6 files):**
|
|
131
133
|
- `CLAUDE.md` — your stack, commands, conventions, guardrails
|
|
132
|
-
- `TASKS.md` —
|
|
133
|
-
- `.claude/settings.json` —
|
|
134
|
-
- `.
|
|
134
|
+
- `TASKS.md` — sprint tracking and session continuity
|
|
135
|
+
- `.claude/settings.json` — `$schema` for IDE autocomplete, `permissions.deny` for security, hooks for .env protection + destructive command blocking + auto-format
|
|
136
|
+
- `.claude/.gitignore` — prevents local settings and plans from being committed
|
|
137
|
+
- `.claudeignore` — language-specific ignore patterns
|
|
138
|
+
- `.claude/rules/conventions.md` — language-specific starter rules
|
|
135
139
|
|
|
136
140
|
## Enhance
|
|
137
141
|
|
|
@@ -237,7 +241,7 @@ Then use `/launchpad:doctor`, `/launchpad:init`, `/launchpad:enhance`, `/launchp
|
|
|
237
241
|
|
|
238
242
|
**Doctor** reads your files and runs static analysis. No API calls. No network. No cost.
|
|
239
243
|
|
|
240
|
-
**Init** scans manifest files (package.json, go.mod, pyproject.toml, etc.), detects your stack, and generates
|
|
244
|
+
**Init** scans manifest files (package.json, go.mod, pyproject.toml, etc.), detects your stack, and generates 6 files: CLAUDE.md, TASKS.md, settings.json (with $schema, permissions.deny, and hooks), .claude/.gitignore, .claudeignore, and language-specific rules. Formatter hooks use hardcoded safe commands only.
|
|
241
245
|
|
|
242
246
|
**Enhance** spawns `claude "prompt"` as an interactive child process. You see Claude's full UI. No data passes through the tool — it just launches Claude with a task.
|
|
243
247
|
|
package/dist/cli.js
CHANGED
|
@@ -248,98 +248,35 @@ function detectPackageManager(m, lockfiles) {
|
|
|
248
248
|
if (m.composerJson) return "composer";
|
|
249
249
|
return null;
|
|
250
250
|
}
|
|
251
|
+
var LANGUAGE_SCRIPTS = {
|
|
252
|
+
Go: { devCommand: "go run .", buildCommand: "go build .", testCommand: "go test ./...", lintCommand: "golangci-lint run", formatCommand: "gofmt -w ." },
|
|
253
|
+
Ruby: { devCommand: "bin/dev", buildCommand: null, testCommand: "bin/rails test", lintCommand: "bin/rubocop", formatCommand: null },
|
|
254
|
+
PHP: { devCommand: "php artisan serve", buildCommand: null, testCommand: "php artisan test", lintCommand: "vendor/bin/phpstan analyse", formatCommand: "vendor/bin/pint" },
|
|
255
|
+
Rust: { devCommand: "cargo run", buildCommand: "cargo build", testCommand: "cargo test", lintCommand: "cargo clippy", formatCommand: "cargo fmt" },
|
|
256
|
+
Java: { devCommand: null, buildCommand: "mvn package", testCommand: "mvn test", lintCommand: null, formatCommand: null },
|
|
257
|
+
Kotlin: { devCommand: null, buildCommand: "mvn package", testCommand: "mvn test", lintCommand: null, formatCommand: null },
|
|
258
|
+
Swift: { devCommand: null, buildCommand: "swift build", testCommand: "swift test", lintCommand: "swiftlint", formatCommand: "swift-format format -r ." },
|
|
259
|
+
Elixir: { devCommand: "mix phx.server", buildCommand: "mix compile", testCommand: "mix test", lintCommand: "mix credo", formatCommand: "mix format" },
|
|
260
|
+
"C#": { devCommand: "dotnet run", buildCommand: "dotnet build", testCommand: "dotnet test", lintCommand: null, formatCommand: "dotnet format" }
|
|
261
|
+
};
|
|
251
262
|
function detectScripts(m) {
|
|
252
|
-
const scripts = m.pkgJson?.scripts ?? {};
|
|
253
263
|
if (m.pkgJson) {
|
|
264
|
+
const scripts = m.pkgJson.scripts ?? {};
|
|
265
|
+
const run = pmRun(m.pkgJson);
|
|
254
266
|
return {
|
|
255
|
-
devCommand: scripts.dev ? `${
|
|
256
|
-
buildCommand: scripts.build ? `${
|
|
257
|
-
testCommand: scripts.test ? `${
|
|
258
|
-
lintCommand: scripts.lint ? `${
|
|
259
|
-
formatCommand: scripts.format ? `${
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
if (m.language === "Go") {
|
|
263
|
-
return {
|
|
264
|
-
devCommand: "go run .",
|
|
265
|
-
buildCommand: "go build .",
|
|
266
|
-
testCommand: "go test ./...",
|
|
267
|
-
lintCommand: "golangci-lint run",
|
|
268
|
-
formatCommand: "gofmt -w ."
|
|
267
|
+
devCommand: scripts.dev ? `${run} dev` : null,
|
|
268
|
+
buildCommand: scripts.build ? `${run} build` : null,
|
|
269
|
+
testCommand: scripts.test ? `${run} test` : null,
|
|
270
|
+
lintCommand: scripts.lint ? `${run} lint` : null,
|
|
271
|
+
formatCommand: scripts.format ? `${run} format` : null
|
|
269
272
|
};
|
|
270
273
|
}
|
|
271
274
|
if (m.language === "Python") {
|
|
272
|
-
const
|
|
273
|
-
return {
|
|
274
|
-
devCommand: null,
|
|
275
|
-
buildCommand: null,
|
|
276
|
-
testCommand: `${runner} pytest`,
|
|
277
|
-
lintCommand: `${runner} ruff check .`,
|
|
278
|
-
formatCommand: `${runner} ruff format .`
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
if (m.gemfile) {
|
|
282
|
-
return {
|
|
283
|
-
devCommand: "bin/dev",
|
|
284
|
-
buildCommand: null,
|
|
285
|
-
testCommand: "bin/rails test",
|
|
286
|
-
lintCommand: "bin/rubocop",
|
|
287
|
-
formatCommand: null
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
if (m.language === "PHP") {
|
|
291
|
-
return {
|
|
292
|
-
devCommand: "php artisan serve",
|
|
293
|
-
buildCommand: null,
|
|
294
|
-
testCommand: "php artisan test",
|
|
295
|
-
lintCommand: "vendor/bin/phpstan analyse",
|
|
296
|
-
formatCommand: "vendor/bin/pint"
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
if (m.language === "Rust") {
|
|
300
|
-
return {
|
|
301
|
-
devCommand: "cargo run",
|
|
302
|
-
buildCommand: "cargo build",
|
|
303
|
-
testCommand: "cargo test",
|
|
304
|
-
lintCommand: "cargo clippy",
|
|
305
|
-
formatCommand: "cargo fmt"
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
if (m.language === "Java" || m.language === "Kotlin") {
|
|
309
|
-
return {
|
|
310
|
-
devCommand: null,
|
|
311
|
-
buildCommand: "mvn package",
|
|
312
|
-
testCommand: "mvn test",
|
|
313
|
-
lintCommand: null,
|
|
314
|
-
formatCommand: null
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
if (m.language === "Swift") {
|
|
318
|
-
return {
|
|
319
|
-
devCommand: null,
|
|
320
|
-
buildCommand: "swift build",
|
|
321
|
-
testCommand: "swift test",
|
|
322
|
-
lintCommand: "swiftlint",
|
|
323
|
-
formatCommand: "swift-format format -r ."
|
|
324
|
-
};
|
|
275
|
+
const r = m.pyProject?.includes("[tool.uv]") ? "uv run" : "python -m";
|
|
276
|
+
return { devCommand: null, buildCommand: null, testCommand: `${r} pytest`, lintCommand: `${r} ruff check .`, formatCommand: `${r} ruff format .` };
|
|
325
277
|
}
|
|
326
|
-
if (m.language
|
|
327
|
-
return
|
|
328
|
-
devCommand: "mix phx.server",
|
|
329
|
-
buildCommand: "mix compile",
|
|
330
|
-
testCommand: "mix test",
|
|
331
|
-
lintCommand: "mix credo",
|
|
332
|
-
formatCommand: "mix format"
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
if (m.language === "C#") {
|
|
336
|
-
return {
|
|
337
|
-
devCommand: "dotnet run",
|
|
338
|
-
buildCommand: "dotnet build",
|
|
339
|
-
testCommand: "dotnet test",
|
|
340
|
-
lintCommand: null,
|
|
341
|
-
formatCommand: "dotnet format"
|
|
342
|
-
};
|
|
278
|
+
if (m.language && LANGUAGE_SCRIPTS[m.language]) {
|
|
279
|
+
return LANGUAGE_SCRIPTS[m.language];
|
|
343
280
|
}
|
|
344
281
|
return { devCommand: null, buildCommand: null, testCommand: null, lintCommand: null, formatCommand: null };
|
|
345
282
|
}
|
|
@@ -1313,50 +1250,35 @@ async function applyFixes(issues, projectRoot) {
|
|
|
1313
1250
|
}
|
|
1314
1251
|
return { fixed, skipped };
|
|
1315
1252
|
}
|
|
1316
|
-
|
|
1317
|
-
|
|
1253
|
+
var FIX_TABLE = [
|
|
1254
|
+
{ analyzer: "Hooks", match: "No hooks configured", fix: async (root, detected) => {
|
|
1318
1255
|
const a = await addEnvProtectionHook(root);
|
|
1319
1256
|
const b = await addAutoFormatHook(root, detected);
|
|
1320
1257
|
const c = await addForcePushProtection(root);
|
|
1321
1258
|
return a || b || c;
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
}
|
|
1332
|
-
if (issue.analyzer === "Quality" && issue.message.includes("Architecture")) {
|
|
1333
|
-
return addClaudeMdSection(root, "## Architecture", "<!-- TODO: Describe your codebase structure. Run `claude-launchpad enhance` to auto-fill this. -->");
|
|
1334
|
-
}
|
|
1335
|
-
if (issue.analyzer === "Quality" && issue.message.includes("Off-Limits")) {
|
|
1336
|
-
return addClaudeMdSection(root, "## Off-Limits", "- Never hardcode secrets \u2014 use environment variables\n- Never write to `.env` files\n- Never expose internal error details in API responses");
|
|
1337
|
-
}
|
|
1338
|
-
if (issue.analyzer === "Quality" && issue.message.includes("Commands")) {
|
|
1339
|
-
return addClaudeMdSection(root, "## Commands", "<!-- TODO: Add your dev/build/test commands -->");
|
|
1340
|
-
}
|
|
1341
|
-
if (issue.analyzer === "Quality" && issue.message.includes("Stack")) {
|
|
1342
|
-
const stackContent = detected.language ? `- **Language**: ${detected.language}${detected.framework ? `
|
|
1259
|
+
} },
|
|
1260
|
+
{ analyzer: "Hooks", match: ".env file protection", fix: (root) => addEnvProtectionHook(root) },
|
|
1261
|
+
{ analyzer: "Hooks", match: "auto-format", fix: (root, detected) => addAutoFormatHook(root, detected) },
|
|
1262
|
+
{ analyzer: "Hooks", match: "No PreToolUse", fix: (root) => addEnvProtectionHook(root) },
|
|
1263
|
+
{ analyzer: "Quality", match: "Architecture", fix: (root) => addClaudeMdSection(root, "## Architecture", "<!-- TODO: Describe your codebase structure. Run `claude-launchpad enhance` to auto-fill this. -->") },
|
|
1264
|
+
{ analyzer: "Quality", match: "Off-Limits", fix: (root) => addClaudeMdSection(root, "## Off-Limits", "- Never hardcode secrets - use environment variables\n- Never write to `.env` files\n- Never expose internal error details in API responses") },
|
|
1265
|
+
{ analyzer: "Quality", match: "Commands", fix: (root) => addClaudeMdSection(root, "## Commands", "<!-- TODO: Add your dev/build/test commands -->") },
|
|
1266
|
+
{ analyzer: "Quality", match: "Stack", fix: (root, detected) => {
|
|
1267
|
+
const content = detected.language ? `- **Language**: ${detected.language}${detected.framework ? `
|
|
1343
1268
|
- **Framework**: ${detected.framework}` : ""}${detected.packageManager ? `
|
|
1344
1269
|
- **Package Manager**: ${detected.packageManager}` : ""}` : "<!-- TODO: Define your tech stack -->";
|
|
1345
|
-
return addClaudeMdSection(root, "## Stack",
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
return addForcePushProtection(root);
|
|
1358
|
-
}
|
|
1359
|
-
return false;
|
|
1270
|
+
return addClaudeMdSection(root, "## Stack", content);
|
|
1271
|
+
} },
|
|
1272
|
+
{ analyzer: "Quality", match: "Session Start", fix: (root) => addClaudeMdSection(root, "## Session Start", "- ALWAYS read @TASKS.md first - it tracks progress across sessions\n- Update TASKS.md as you complete work") },
|
|
1273
|
+
{ analyzer: "Rules", match: "No .claudeignore", fix: (root, detected) => createClaudeignore(root, detected) },
|
|
1274
|
+
{ analyzer: "Rules", match: "No .claude/rules/", fix: (root) => createStarterRules(root) },
|
|
1275
|
+
{ analyzer: "Permissions", match: "force-push", fix: (root) => addForcePushProtection(root) }
|
|
1276
|
+
];
|
|
1277
|
+
async function tryFix(issue, root, detected) {
|
|
1278
|
+
const entry = FIX_TABLE.find(
|
|
1279
|
+
(e) => e.analyzer === issue.analyzer && issue.message.includes(e.match)
|
|
1280
|
+
);
|
|
1281
|
+
return entry ? entry.fix(root, detected) : false;
|
|
1360
1282
|
}
|
|
1361
1283
|
async function addEnvProtectionHook(root) {
|
|
1362
1284
|
const settings = await readSettingsJson(root);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/init/index.ts","../src/lib/output.ts","../src/lib/fs-utils.ts","../src/lib/detect.ts","../src/commands/init/generators/claude-md.ts","../src/commands/init/generators/tasks-md.ts","../src/commands/init/generators/settings.ts","../src/commands/init/generators/claudeignore.ts","../src/commands/doctor/index.ts","../src/lib/parser.ts","../src/commands/doctor/analyzers/budget.ts","../src/commands/doctor/analyzers/settings.ts","../src/commands/doctor/analyzers/hooks.ts","../src/commands/doctor/analyzers/rules.ts","../src/commands/doctor/analyzers/permissions.ts","../src/commands/doctor/analyzers/mcp.ts","../src/commands/doctor/analyzers/quality.ts","../src/commands/doctor/fixer.ts","../src/commands/doctor/watcher.ts","../src/commands/eval/index.ts","../src/commands/eval/loader.ts","../src/commands/eval/schema.ts","../src/commands/eval/runner.ts","../src/commands/enhance/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { join } from \"node:path\";\nimport { createInitCommand } from \"./commands/init/index.js\";\nimport { createDoctorCommand } from \"./commands/doctor/index.js\";\nimport { createEvalCommand } from \"./commands/eval/index.js\";\nimport { createEnhanceCommand } from \"./commands/enhance/index.js\";\nimport { printBanner, log } from \"./lib/output.js\";\nimport { fileExists } from \"./lib/fs-utils.js\";\n\nconst program = new Command()\n .name(\"claude-launchpad\")\n .description(\"CLI toolkit that makes Claude Code setups measurably good\")\n .version(\"0.4.0\", \"-v, --version\")\n .action(async () => {\n // Default behavior: detect existing config and route accordingly\n const hasConfig = await fileExists(join(process.cwd(), \"CLAUDE.md\"))\n || await fileExists(join(process.cwd(), \".claude\", \"settings.json\"));\n\n if (hasConfig) {\n // Route directly to doctor — it prints its own banner\n await program.commands.find((c) => c.name() === \"doctor\")?.parseAsync([], { from: \"user\" });\n } else {\n printBanner();\n log.info(\"No Claude Code config found in this directory.\");\n log.blank();\n log.step(\"Run `claude-launchpad init` to set up your project\");\n log.step(\"Run `claude-launchpad doctor` to diagnose an existing config\");\n log.step(\"Run `claude-launchpad eval` to test your config quality\");\n log.blank();\n }\n });\n\nprogram.addCommand(createInitCommand());\nprogram.addCommand(createDoctorCommand());\nprogram.addCommand(createEnhanceCommand());\nprogram.addCommand(createEvalCommand());\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport { writeFile, mkdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { printBanner, log } from \"../../lib/output.js\";\nimport { fileExists } from \"../../lib/fs-utils.js\";\nimport { detectProject } from \"../../lib/detect.js\";\nimport type { InitOptions, DetectedProject } from \"../../types/index.js\";\nimport { generateClaudeMd } from \"./generators/claude-md.js\";\nimport { generateTasksMd } from \"./generators/tasks-md.js\";\nimport { generateSettings } from \"./generators/settings.js\";\nimport { generateClaudeignore } from \"./generators/claudeignore.js\";\n\nexport function createInitCommand(): Command {\n return new Command(\"init\")\n .description(\"Set up Claude Code configuration for any project\")\n .option(\"-n, --name <name>\", \"Project name\")\n .option(\"-y, --yes\", \"Accept all defaults\")\n .action(async (opts) => {\n printBanner();\n\n const root = process.cwd();\n\n // Detect what kind of project this is\n log.step(\"Detecting project...\");\n const detected = await detectProject(root);\n\n if (detected.language) {\n log.success(`Found ${detected.framework ?? detected.language} project`);\n if (detected.packageManager) log.info(`Package manager: ${detected.packageManager}`);\n if (detected.devCommand) log.info(`Dev command: ${detected.devCommand}`);\n if (detected.testCommand) log.info(`Test command: ${detected.testCommand}`);\n } else {\n log.warn(\"Could not detect project type — generating minimal config\");\n }\n log.blank();\n\n // Resolve options\n const name = opts.name ?? detected.name ?? await input({\n message: \"Project name:\",\n validate: (v: string) => (v.trim().length > 0 ? true : \"Name cannot be empty\"),\n });\n\n const description = opts.yes ? \"\" : await input({\n message: \"One-line description (optional):\",\n });\n\n const options: InitOptions = { name: name.trim(), description: description.trim() };\n\n // Check for existing files\n const hasClaudeMd = await fileExists(join(root, \"CLAUDE.md\"));\n if (hasClaudeMd && !opts.yes) {\n const overwrite = await confirm({\n message: \"CLAUDE.md already exists. Overwrite?\",\n default: false,\n });\n if (!overwrite) {\n log.info(\"Keeping existing CLAUDE.md\");\n log.step(\"Tip: run `claude-launchpad doctor` to check your existing config\");\n return;\n }\n }\n\n await scaffold(root, options, detected);\n });\n}\n\nasync function scaffold(root: string, options: InitOptions, detected: DetectedProject): Promise<void> {\n log.step(\"Generating configuration...\");\n\n const claudeMd = generateClaudeMd(options, detected);\n const tasksMd = generateTasksMd(options);\n const settings = generateSettings(detected);\n const claudeignore = generateClaudeignore(detected);\n\n await mkdir(join(root, \".claude\", \"rules\"), { recursive: true });\n\n // Merge with existing settings.json instead of overwriting\n const settingsPath = join(root, \".claude\", \"settings.json\");\n const mergedSettings = await mergeSettings(settingsPath, settings as unknown as Record<string, unknown>);\n\n // Only generate files that don't exist yet\n const claudeignorePath = join(root, \".claudeignore\");\n const hasClaudeignore = await fileExists(claudeignorePath);\n const claudeGitignorePath = join(root, \".claude\", \".gitignore\");\n const hasClaudeGitignore = await fileExists(claudeGitignorePath);\n const rulesPath = join(root, \".claude\", \"rules\", \"conventions.md\");\n const hasRules = await fileExists(rulesPath);\n\n const writes: Promise<void>[] = [\n writeFile(join(root, \"CLAUDE.md\"), claudeMd),\n writeFile(join(root, \"TASKS.md\"), tasksMd),\n writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2) + \"\\n\"),\n ];\n\n if (!hasClaudeignore) {\n writes.push(writeFile(claudeignorePath, claudeignore));\n }\n\n if (!hasClaudeGitignore) {\n writes.push(writeFile(claudeGitignorePath, [\n \"# Local-only Claude Code files (never commit these)\",\n \"settings.local.json\",\n \"plans/\",\n \"memory/\",\n \"sessions/\",\n \"tmp/\",\n \"\",\n ].join(\"\\n\")));\n }\n\n if (!hasRules) {\n const rulesContent = generateStarterRules(detected);\n writes.push(writeFile(rulesPath, rulesContent));\n }\n\n await Promise.all(writes);\n\n log.success(\"Generated CLAUDE.md\");\n log.success(\"Generated TASKS.md\");\n log.success(\"Generated .claude/settings.json (schema, permissions, hooks)\");\n if (!hasClaudeGitignore) log.success(\"Generated .claude/.gitignore\");\n if (!hasClaudeignore) log.success(\"Generated .claudeignore\");\n if (!hasRules) log.success(\"Generated .claude/rules/conventions.md\");\n\n log.blank();\n log.success(\"Done! Run `claude` to start.\");\n log.info(\"Run `claude-launchpad doctor` to check your config quality.\");\n log.blank();\n}\n\nfunction generateStarterRules(detected: DetectedProject): string {\n const lines = [\n \"# Project Conventions\",\n \"\",\n \"- Use conventional commits (feat:, fix:, docs:, refactor:, test:, chore:)\",\n \"- Keep files under 400 lines, functions under 50 lines\",\n \"- Handle errors explicitly - no empty catch blocks\",\n \"- Validate input at system boundaries\",\n ];\n\n if (detected.language === \"TypeScript\" || detected.language === \"JavaScript\") {\n lines.push(\"- Use named exports, no default exports except Next.js pages\");\n lines.push(\"- No `any` types in TypeScript\");\n }\n\n if (detected.language === \"Python\") {\n lines.push(\"- Type hints on all function signatures\");\n lines.push(\"- Async everywhere for I/O operations\");\n }\n\n if (detected.language === \"Go\") {\n lines.push(\"- Table-driven tests\");\n lines.push(\"- Errors are values - handle them, don't ignore them\");\n }\n\n if (detected.language === \"Rust\") {\n lines.push(\"- Prefer Result over unwrap/expect in library code\");\n lines.push(\"- No unsafe blocks without a safety comment\");\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n\nasync function mergeSettings(\n existingPath: string,\n generated: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n try {\n const existing = JSON.parse(await readFile(existingPath, \"utf-8\")) as Record<string, unknown>;\n\n // Merge hooks: keep existing hooks, add generated ones that don't conflict\n const existingHooks = (existing.hooks ?? {}) as Record<string, unknown[]>;\n const generatedHooks = (generated.hooks ?? {}) as Record<string, unknown[]>;\n\n const mergedHooks: Record<string, unknown[]> = { ...existingHooks };\n for (const [event, hookList] of Object.entries(generatedHooks)) {\n if (!mergedHooks[event]) {\n mergedHooks[event] = hookList;\n }\n // If event already exists, keep existing (don't duplicate)\n }\n\n return {\n ...existing,\n ...generated,\n hooks: Object.keys(mergedHooks).length > 0 ? mergedHooks : undefined,\n };\n } catch {\n // No existing file — just use generated\n return generated;\n }\n}\n","import chalk from \"chalk\";\nimport type { Severity, AnalyzerResult, DiagnosticIssue } from \"../types/index.js\";\n\n// ─── Colors ───\n\nexport const colors = {\n success: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n info: chalk.cyan,\n dim: chalk.dim,\n bold: chalk.bold,\n score: (score: number): string => {\n if (score >= 80) return chalk.green.bold(`${score}%`);\n if (score >= 60) return chalk.yellow.bold(`${score}%`);\n return chalk.red.bold(`${score}%`);\n },\n severity: (sev: Severity): string => {\n const map: Record<Severity, (s: string) => string> = {\n critical: chalk.bgRed.white.bold,\n high: chalk.red.bold,\n medium: chalk.yellow,\n low: chalk.cyan,\n info: chalk.dim,\n };\n return map[sev](` ${sev.toUpperCase()} `);\n },\n} as const;\n\n// ─── Prefixed Output ───\n\nexport const log = {\n success: (msg: string): void => console.log(` ${chalk.green(\"✓\")} ${msg}`),\n error: (msg: string): void => console.log(` ${chalk.red(\"✗\")} ${msg}`),\n warn: (msg: string): void => console.log(` ${chalk.yellow(\"!\")} ${msg}`),\n step: (msg: string): void => console.log(` ${chalk.cyan(\"→\")} ${msg}`),\n info: (msg: string): void => console.log(` ${chalk.dim(\"·\")} ${msg}`),\n blank: (): void => console.log(),\n} as const;\n\n// ─── Banner ───\n\nexport function printBanner(): void {\n log.blank();\n console.log(chalk.cyan.bold(\" Claude Launchpad\"));\n console.log(chalk.dim(\" Scaffold · Diagnose · Evaluate\"));\n log.blank();\n}\n\n// ─── Score Display ───\n\nexport function printScoreCard(label: string, score: number, max: number = 100): void {\n const pct = Math.round((score / max) * 100);\n const bar = renderBar(pct, 20);\n console.log(` ${chalk.bold(label.padEnd(22))} ${bar} ${colors.score(pct).padStart(12)}`);\n}\n\nfunction renderBar(pct: number, width: number): string {\n const filled = Math.round((pct / 100) * width);\n const empty = width - filled;\n const color = pct >= 80 ? chalk.green : pct >= 60 ? chalk.yellow : chalk.red;\n return color(\"━\".repeat(filled)) + chalk.dim(\"─\".repeat(empty));\n}\n\n// ─── Issues List (replaces table) ───\n\nexport function printIssue(severity: Severity, analyzer: string, message: string, fix?: string): void {\n const tag = colors.severity(severity);\n console.log(` ${tag} ${chalk.bold(analyzer)}`);\n console.log(` ${message}`);\n if (fix) {\n console.log(` ${chalk.dim(\"Fix:\")} ${chalk.dim(fix)}`);\n }\n console.log();\n}\n\n// ─── Report Rendering (shared by doctor + watcher) ───\n\nexport function renderDoctorReport(results: ReadonlyArray<AnalyzerResult>): {\n overallScore: number;\n actionableCount: number;\n} {\n const overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n\n for (const result of results) {\n printScoreCard(result.name, result.score);\n }\n log.blank();\n printScoreCard(\"Overall\", overallScore);\n log.blank();\n\n const allIssues = results.flatMap((r) => r.issues);\n const actionable = allIssues.filter((i) => i.severity !== \"info\");\n\n if (actionable.length === 0) {\n log.success(\"No issues found. Your configuration looks solid.\");\n return { overallScore, actionableCount: 0 };\n }\n\n const sorted = [...actionable].sort((a, b) => {\n const order: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };\n return (order[a.severity] ?? 4) - (order[b.severity] ?? 4);\n });\n\n for (const issue of sorted) {\n printIssue(issue.severity, issue.analyzer, issue.message, issue.fix);\n }\n\n log.info(`${actionable.length} issue(s) found. Fix critical/high first.`);\n return { overallScore, actionableCount: actionable.length };\n}\n","import { readFile, access } from \"node:fs/promises\";\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readFileOrNull(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nexport async function readJsonOrNull<T>(path: string): Promise<T | null> {\n try {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n","import { join, basename } from \"node:path\";\nimport { fileExists, readFileOrNull, readJsonOrNull } from \"./fs-utils.js\";\nimport type { DetectedProject } from \"../types/index.js\";\n\n/**\n * Detect project characteristics by scanning manifest files and directory structure.\n * Works with any stack — no hardcoded list of supported frameworks.\n */\nexport async function detectProject(root: string): Promise<DetectedProject> {\n const name = basename(root);\n\n const [pkgJson, goMod, pyProject, gemfile, cargo, pubspec, composerJson, pomXml, buildGradle, packageSwift, mixExs, csproj, lockfiles] = await Promise.all([\n readJsonOrNull<PackageJson>(join(root, \"package.json\")),\n fileExists(join(root, \"go.mod\")),\n readFileOrNull(join(root, \"pyproject.toml\")),\n fileExists(join(root, \"Gemfile\")),\n fileExists(join(root, \"Cargo.toml\")),\n fileExists(join(root, \"pubspec.yaml\")),\n readJsonOrNull<ComposerJson>(join(root, \"composer.json\")),\n fileExists(join(root, \"pom.xml\")),\n fileExists(join(root, \"build.gradle\")) || fileExists(join(root, \"build.gradle.kts\")),\n fileExists(join(root, \"Package.swift\")),\n fileExists(join(root, \"mix.exs\")),\n globExists(root, \"*.csproj\"),\n detectLockfiles(root),\n ]);\n\n const manifests: ManifestState = {\n pkgJson, goMod, pyProject, gemfile, cargo, pubspec,\n composerJson, pomXml, buildGradle, packageSwift, mixExs, csproj,\n };\n\n const language = detectLanguage(manifests);\n const framework = detectFramework(manifests);\n const packageManager = detectPackageManager(manifests, lockfiles);\n const scripts = detectScripts({ pkgJson, pyProject, goMod, gemfile, composerJson, language });\n\n return {\n name,\n language,\n framework,\n packageManager,\n hasTests: scripts.testCommand !== null,\n hasLinter: scripts.lintCommand !== null,\n hasFormatter: scripts.formatCommand !== null,\n ...scripts,\n };\n}\n\n// ─── Language Detection ───\n\ninterface ManifestState {\n pkgJson: PackageJson | null;\n goMod: boolean;\n pyProject: string | null;\n gemfile: boolean;\n cargo: boolean;\n pubspec: boolean;\n composerJson: ComposerJson | null;\n pomXml: boolean;\n buildGradle: boolean;\n packageSwift: boolean;\n mixExs: boolean;\n csproj: boolean;\n}\n\nfunction detectLanguage(m: ManifestState): string | null {\n if (m.pkgJson?.devDependencies?.typescript || m.pkgJson?.dependencies?.typescript) return \"TypeScript\";\n if (m.pkgJson) return \"JavaScript\";\n if (m.goMod) return \"Go\";\n if (m.pyProject) return \"Python\";\n if (m.gemfile) return \"Ruby\";\n if (m.cargo) return \"Rust\";\n if (m.pubspec) return \"Dart\";\n if (m.composerJson) return \"PHP\";\n if (m.buildGradle) return \"Kotlin\";\n if (m.pomXml) return \"Java\";\n if (m.packageSwift) return \"Swift\";\n if (m.mixExs) return \"Elixir\";\n if (m.csproj) return \"C#\";\n return null;\n}\n\n// ─── Framework Detection ───\n\nfunction detectFramework(m: ManifestState): string | null {\n const deps = { ...m.pkgJson?.dependencies, ...m.pkgJson?.devDependencies };\n\n // JS/TS frameworks\n if (deps.next) return \"Next.js\";\n if (deps.nuxt) return \"Nuxt\";\n if (deps.svelte || deps[\"@sveltejs/kit\"]) return \"SvelteKit\";\n if (deps.astro) return \"Astro\";\n if (deps[\"@angular/core\"]) return \"Angular\";\n if (deps.remix || deps[\"@remix-run/react\"]) return \"Remix\";\n if (deps.vue) return \"Vue\";\n if (deps.react && !deps.next) return \"React\";\n if (deps.express) return \"Express\";\n if (deps.fastify) return \"Fastify\";\n if (deps.hono) return \"Hono\";\n if (deps.nestjs || deps[\"@nestjs/core\"]) return \"NestJS\";\n\n // Python frameworks\n if (m.pyProject) {\n if (m.pyProject.includes(\"fastapi\")) return \"FastAPI\";\n if (m.pyProject.includes(\"django\")) return \"Django\";\n if (m.pyProject.includes(\"flask\")) return \"Flask\";\n }\n\n // PHP frameworks\n if (m.composerJson) {\n const phpDeps = { ...m.composerJson.require, ...m.composerJson[\"require-dev\"] };\n if (phpDeps[\"laravel/framework\"]) return \"Laravel\";\n if (phpDeps[\"symfony/framework-bundle\"]) return \"Symfony\";\n }\n\n // Ruby\n if (m.gemfile) return \"Rails\";\n\n // JVM\n if (m.buildGradle) return \"Gradle\"; // Could be Spring Boot, Android, etc.\n if (m.pomXml) return \"Maven\";\n\n return null;\n}\n\n// ─── Package Manager Detection ───\n\ninterface DetectedLockfiles {\n pnpmLock: boolean;\n yarnLock: boolean;\n bunLock: boolean;\n npmLock: boolean;\n}\n\nasync function detectLockfiles(root: string): Promise<DetectedLockfiles> {\n const [pnpmLock, yarnLock, bunLock, npmLock] = await Promise.all([\n fileExists(join(root, \"pnpm-lock.yaml\")),\n fileExists(join(root, \"yarn.lock\")),\n fileExists(join(root, \"bun.lockb\")),\n fileExists(join(root, \"package-lock.json\")),\n ]);\n return { pnpmLock, yarnLock, bunLock, npmLock };\n}\n\nfunction detectPackageManager(\n m: Pick<ManifestState, \"pkgJson\" | \"goMod\" | \"pyProject\" | \"gemfile\" | \"cargo\" | \"composerJson\">,\n lockfiles: DetectedLockfiles,\n): string | null {\n if (m.pkgJson) {\n // Check packageManager field first (most explicit)\n const pm = m.pkgJson.packageManager;\n if (pm?.startsWith(\"pnpm\")) return \"pnpm\";\n if (pm?.startsWith(\"yarn\")) return \"yarn\";\n if (pm?.startsWith(\"bun\")) return \"bun\";\n if (pm?.startsWith(\"npm\")) return \"npm\";\n\n // Fall back to lockfile detection\n if (lockfiles.pnpmLock) return \"pnpm\";\n if (lockfiles.yarnLock) return \"yarn\";\n if (lockfiles.bunLock) return \"bun\";\n if (lockfiles.npmLock) return \"npm\";\n\n return \"npm\";\n }\n if (m.goMod) return \"go modules\";\n if (m.pyProject) {\n if (m.pyProject.includes(\"[tool.uv]\")) return \"uv\";\n if (m.pyProject.includes(\"[tool.poetry]\")) return \"poetry\";\n return \"pip\";\n }\n if (m.gemfile) return \"bundler\";\n if (m.cargo) return \"cargo\";\n if (m.composerJson) return \"composer\";\n return null;\n}\n\n// ─── Script Detection ───\n\ninterface DetectedScripts {\n formatCommand: string | null;\n lintCommand: string | null;\n testCommand: string | null;\n devCommand: string | null;\n buildCommand: string | null;\n}\n\nfunction detectScripts(m: {\n pkgJson: PackageJson | null;\n pyProject: string | null;\n goMod: boolean;\n gemfile: boolean;\n composerJson: ComposerJson | null;\n language: string | null;\n}): DetectedScripts {\n const scripts = m.pkgJson?.scripts ?? {};\n\n if (m.pkgJson) {\n return {\n devCommand: scripts.dev ? `${pmRun(m.pkgJson)} dev` : null,\n buildCommand: scripts.build ? `${pmRun(m.pkgJson)} build` : null,\n testCommand: scripts.test ? `${pmRun(m.pkgJson)} test` : null,\n lintCommand: scripts.lint ? `${pmRun(m.pkgJson)} lint` : null,\n formatCommand: scripts.format ? `${pmRun(m.pkgJson)} format` : null,\n };\n }\n\n if (m.language === \"Go\") {\n return {\n devCommand: \"go run .\",\n buildCommand: \"go build .\",\n testCommand: \"go test ./...\",\n lintCommand: \"golangci-lint run\",\n formatCommand: \"gofmt -w .\",\n };\n }\n\n if (m.language === \"Python\") {\n const runner = m.pyProject?.includes(\"[tool.uv]\") ? \"uv run\" : \"python -m\";\n return {\n devCommand: null,\n buildCommand: null,\n testCommand: `${runner} pytest`,\n lintCommand: `${runner} ruff check .`,\n formatCommand: `${runner} ruff format .`,\n };\n }\n\n if (m.gemfile) {\n return {\n devCommand: \"bin/dev\",\n buildCommand: null,\n testCommand: \"bin/rails test\",\n lintCommand: \"bin/rubocop\",\n formatCommand: null,\n };\n }\n\n if (m.language === \"PHP\") {\n return {\n devCommand: \"php artisan serve\",\n buildCommand: null,\n testCommand: \"php artisan test\",\n lintCommand: \"vendor/bin/phpstan analyse\",\n formatCommand: \"vendor/bin/pint\",\n };\n }\n\n if (m.language === \"Rust\") {\n return {\n devCommand: \"cargo run\",\n buildCommand: \"cargo build\",\n testCommand: \"cargo test\",\n lintCommand: \"cargo clippy\",\n formatCommand: \"cargo fmt\",\n };\n }\n\n if (m.language === \"Java\" || m.language === \"Kotlin\") {\n return {\n devCommand: null,\n buildCommand: \"mvn package\",\n testCommand: \"mvn test\",\n lintCommand: null,\n formatCommand: null,\n };\n }\n\n if (m.language === \"Swift\") {\n return {\n devCommand: null,\n buildCommand: \"swift build\",\n testCommand: \"swift test\",\n lintCommand: \"swiftlint\",\n formatCommand: \"swift-format format -r .\",\n };\n }\n\n if (m.language === \"Elixir\") {\n return {\n devCommand: \"mix phx.server\",\n buildCommand: \"mix compile\",\n testCommand: \"mix test\",\n lintCommand: \"mix credo\",\n formatCommand: \"mix format\",\n };\n }\n\n if (m.language === \"C#\") {\n return {\n devCommand: \"dotnet run\",\n buildCommand: \"dotnet build\",\n testCommand: \"dotnet test\",\n lintCommand: null,\n formatCommand: \"dotnet format\",\n };\n }\n\n return { devCommand: null, buildCommand: null, testCommand: null, lintCommand: null, formatCommand: null };\n}\n\nfunction pmRun(pkg: PackageJson): string {\n const pm = pkg.packageManager;\n if (pm?.startsWith(\"pnpm\")) return \"pnpm\";\n if (pm?.startsWith(\"yarn\")) return \"yarn\";\n if (pm?.startsWith(\"bun\")) return \"bun\";\n return \"npm run\";\n}\n\n// ─── Utilities ───\n\ninterface PackageJson {\n name?: string;\n packageManager?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\ninterface ComposerJson {\n require?: Record<string, string>;\n \"require-dev\"?: Record<string, string>;\n}\n\nasync function globExists(dir: string, pattern: string): Promise<boolean> {\n const { readdir } = await import(\"node:fs/promises\");\n try {\n const entries = await readdir(dir);\n return entries.some((e) => e.endsWith(pattern.replace(\"*\", \"\")));\n } catch {\n return false;\n }\n}\n","import type { InitOptions, DetectedProject } from \"../../../types/index.js\";\n\nexport function generateClaudeMd(options: InitOptions, detected: DetectedProject): string {\n const sections: string[] = [];\n\n // Header\n sections.push(`# ${options.name}`);\n if (options.description) {\n sections.push(\"\", options.description);\n }\n\n // Stack (auto-detected)\n sections.push(\"\", \"## Stack\");\n if (detected.language) {\n const items: string[] = [];\n if (detected.framework) items.push(`- **Framework**: ${detected.framework}`);\n items.push(`- **Language**: ${detected.language}`);\n if (detected.packageManager) items.push(`- **Package Manager**: ${detected.packageManager}`);\n sections.push(items.join(\"\\n\"));\n } else {\n sections.push(\"<!-- TODO: Define your tech stack -->\");\n }\n\n // Commands (auto-detected)\n sections.push(\"\", \"## Commands\");\n const commands: string[] = [];\n if (detected.devCommand) commands.push(`- Dev: \\`${detected.devCommand}\\``);\n if (detected.buildCommand) commands.push(`- Build: \\`${detected.buildCommand}\\``);\n if (detected.testCommand) commands.push(`- Test: \\`${detected.testCommand}\\``);\n if (detected.lintCommand) commands.push(`- Lint: \\`${detected.lintCommand}\\``);\n if (detected.formatCommand) commands.push(`- Format: \\`${detected.formatCommand}\\``);\n if (commands.length > 0) {\n sections.push(commands.join(\"\\n\"));\n } else {\n sections.push(\"<!-- TODO: Add your dev/build/test commands -->\");\n }\n\n // Session Start\n sections.push(\"\", `## Session Start\n- ALWAYS read @TASKS.md first — it tracks progress across sessions\n- Check the Session Log at the bottom of TASKS.md for where we left off\n- Update TASKS.md as you complete work`);\n\n // Conventions\n sections.push(\"\", `## Conventions\n- Git: Conventional commits (\\`feat:\\`, \\`fix:\\`, \\`docs:\\`, \\`refactor:\\`, \\`test:\\`, \\`chore:\\`)`);\n\n // Off-Limits\n sections.push(\"\", `## Off-Limits\n- Never hardcode secrets — use environment variables\n- Never write to \\`.env\\` files\n- Never expose internal error details in API responses`);\n\n // Key Decisions\n sections.push(\"\", `## Key Decisions\n<!-- Record architectural decisions as you make them -->`);\n\n return sections.join(\"\\n\") + \"\\n\";\n}\n","import type { InitOptions } from \"../../../types/index.js\";\n\nexport function generateTasksMd(options: InitOptions): string {\n return `# ${options.name} — Task Tracker\n\n> Claude: Read this at session start. Keep this file SHORT — only current state matters.\n> Rules: (1) Only show current + next sprint tasks. (2) Completed sprints get one summary line. (3) Session log: max 3 lines per session, keep only last 3 sessions. (4) Target: under 80 lines total.\n\n## Completed Sprints\n\n## Current Sprint: Sprint 1 — Setup\n\n### In Progress\n\n### To Do\n- [ ] Project scaffolding and environment setup\n- [ ] Core feature implementation\n- [ ] Test infrastructure\n\n### Done\n\n## Next Sprint: Sprint 2 — Core Features\n- [ ] ...\n\n## Session Log\n<!-- Keep last 3 sessions only. Max 3 lines each. -->\n`;\n}\n","import type { DetectedProject } from \"../../../types/index.js\";\n\ninterface HookEntry {\n readonly type: \"command\";\n readonly command: string;\n}\n\ninterface HookGroup {\n readonly matcher: string;\n readonly hooks: ReadonlyArray<HookEntry>;\n}\n\ninterface ClaudeSettings {\n readonly $schema?: string;\n readonly permissions?: {\n readonly deny?: ReadonlyArray<string>;\n };\n readonly hooks?: Record<string, ReadonlyArray<HookGroup>>;\n}\n\n/**\n * Generate .claude/settings.json based on detected project.\n * Includes: schema for IDE autocomplete, security deny-lists, hooks.\n */\nexport function generateSettings(detected: DetectedProject): ClaudeSettings {\n const preToolUse: HookGroup[] = [];\n const postToolUse: HookGroup[] = [];\n\n // Universal: .env file protection (block read + write)\n preToolUse.push({\n matcher: \"Read|Write|Edit\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -qE '\\\\.(env|env\\\\..*)$' && ! echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -q '.env.example' && echo 'BLOCKED: .env files contain secrets' && exit 1; exit 0\",\n }],\n });\n\n // Universal: block destructive commands\n preToolUse.push({\n matcher: \"Bash\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_COMMAND\\\" | grep -qE 'rm\\\\s+-rf\\\\s+/|DROP\\\\s+TABLE|DROP\\\\s+DATABASE|push.*--force|push.*-f' && echo 'BLOCKED: Destructive command detected' && exit 1; exit 0\",\n }],\n });\n\n // Auto-format based on detected tooling\n const formatHook = buildFormatHook(detected);\n if (formatHook) {\n postToolUse.push(formatHook);\n }\n\n const hooks: Record<string, ReadonlyArray<HookGroup>> = {};\n if (preToolUse.length > 0) hooks.PreToolUse = preToolUse;\n if (postToolUse.length > 0) hooks.PostToolUse = postToolUse;\n\n return {\n $schema: \"https://json.schemastore.org/claude-code-settings.json\",\n permissions: {\n deny: [\n \"Bash(rm -rf /)\",\n \"Bash(rm -rf ~)\",\n \"Read(.env)\",\n \"Read(.env.*)\",\n \"Read(secrets/**)\",\n ],\n },\n hooks,\n };\n}\n\n// Safe formatter commands - never interpolate user-controlled strings\nconst SAFE_FORMATTERS: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: { extensions: [\"ts\", \"tsx\"], command: \"npx prettier --write\" },\n JavaScript: { extensions: [\"js\", \"jsx\"], command: \"npx prettier --write\" },\n Python: { extensions: [\"py\"], command: \"ruff format\" },\n Go: { extensions: [\"go\"], command: \"gofmt -w\" },\n Rust: { extensions: [\"rs\"], command: \"rustfmt\" },\n Ruby: { extensions: [\"rb\"], command: \"rubocop -A\" },\n Dart: { extensions: [\"dart\"], command: \"dart format\" },\n PHP: { extensions: [\"php\"], command: \"vendor/bin/pint\" },\n Kotlin: { extensions: [\"kt\", \"kts\"], command: \"ktlint -F\" },\n Java: { extensions: [\"java\"], command: \"google-java-format -i\" },\n Swift: { extensions: [\"swift\"], command: \"swift-format format -i\" },\n Elixir: { extensions: [\"ex\", \"exs\"], command: \"mix format\" },\n \"C#\": { extensions: [\"cs\"], command: \"dotnet format\" },\n};\n\nfunction buildFormatHook(detected: DetectedProject): HookGroup | null {\n if (!detected.language) return null;\n\n const config = SAFE_FORMATTERS[detected.language];\n if (!config) return null;\n\n const extChecks = config.extensions\n .map((ext) => `[ \"$ext\" = \"${ext}\" ]`)\n .join(\" || \");\n\n return {\n matcher: \"Write|Edit\",\n hooks: [{\n type: \"command\",\n command: `ext=\\${TOOL_INPUT_FILE_PATH##*.}; (${extChecks}) && ${config.command} \"$TOOL_INPUT_FILE_PATH\" 2>/dev/null; exit 0`,\n }],\n };\n}\n","import type { DetectedProject } from \"../../../types/index.js\";\n\n/**\n * Generate .claudeignore based on detected project type.\n * Prevents Claude from reading noise files that waste context.\n */\nexport function generateClaudeignore(detected: DetectedProject): string {\n const sections: string[] = [\"# Generated by claude-launchpad\"];\n\n // Universal ignores\n sections.push(`\n# Dependencies\nnode_modules/\n.pnp/\n.yarn/\n\n# Build output\ndist/\nbuild/\nout/\n.next/\n.nuxt/\n.output/\n.svelte-kit/\n.vercel/\n.turbo/\n\n# Package manager\npnpm-lock.yaml\npackage-lock.json\nyarn.lock\nbun.lockb\n\n# IDE & OS\n.vscode/\n.idea/\n*.swp\n*.swo\n.DS_Store\nThumbs.db\n\n# Test & coverage\ncoverage/\n.nyc_output/\n__snapshots__/\n\n# Environment (should never be read)\n.env\n.env.*\n!.env.example`);\n\n // Language-specific ignores\n const lang = detected.language;\n\n if (lang === \"Python\") {\n sections.push(`\n# Python\n__pycache__/\n*.pyc\n*.pyo\n.venv/\nvenv/\n.mypy_cache/\n.ruff_cache/\n.pytest_cache/\n*.egg-info/`);\n }\n\n if (lang === \"Go\") {\n sections.push(`\n# Go\nbin/\nvendor/`);\n }\n\n if (lang === \"Rust\") {\n sections.push(`\n# Rust\ntarget/\nCargo.lock`);\n }\n\n if (lang === \"Ruby\") {\n sections.push(`\n# Ruby\nvendor/bundle/\n.bundle/\ntmp/\nlog/`);\n }\n\n if (lang === \"Java\" || lang === \"Kotlin\") {\n sections.push(`\n# JVM\ntarget/\nbuild/\n.gradle/\n*.class\n*.jar`);\n }\n\n if (lang === \"Dart\") {\n sections.push(`\n# Dart/Flutter\n.dart_tool/\n.packages\nbuild/`);\n }\n\n if (lang === \"PHP\") {\n sections.push(`\n# PHP\nvendor/\ncomposer.lock`);\n }\n\n if (lang === \"C#\") {\n sections.push(`\n# .NET\nbin/\nobj/\n*.dll`);\n }\n\n if (lang === \"Elixir\") {\n sections.push(`\n# Elixir\n_build/\ndeps/\n.elixir_ls/`);\n }\n\n if (lang === \"Swift\") {\n sections.push(`\n# Swift\n.build/\nDerivedData/\n*.xcuserdata`);\n }\n\n return sections.join(\"\\n\") + \"\\n\";\n}\n","import { Command } from \"commander\";\nimport { printBanner, log, renderDoctorReport } from \"../../lib/output.js\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { analyzeBudget } from \"./analyzers/budget.js\";\nimport { analyzeSettings } from \"./analyzers/settings.js\";\nimport { analyzeHooks } from \"./analyzers/hooks.js\";\nimport { analyzeRules } from \"./analyzers/rules.js\";\nimport { analyzePermissions } from \"./analyzers/permissions.js\";\nimport { analyzeMcp } from \"./analyzers/mcp.js\";\nimport { analyzeQuality } from \"./analyzers/quality.js\";\nimport { applyFixes } from \"./fixer.js\";\nimport { watchConfig } from \"./watcher.js\";\nimport type { AnalyzerResult } from \"../../types/index.js\";\n\nexport function createDoctorCommand(): Command {\n return new Command(\"doctor\")\n .description(\"Diagnose your Claude Code configuration and report issues\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .option(\"--json\", \"Output as JSON\")\n .option(\"--min-score <n>\", \"Exit non-zero if overall score is below this threshold (for CI)\")\n .option(\"--fix\", \"Auto-apply deterministic fixes for detected issues\")\n .option(\"--watch\", \"Watch for config changes and re-run automatically\")\n .action(async (opts) => {\n if (opts.watch) {\n await watchConfig(opts.path);\n return;\n }\n\n if (!opts.json) {\n printBanner();\n log.step(\"Scanning Claude Code configuration...\");\n log.blank();\n }\n\n const config = await parseClaudeConfig(opts.path);\n\n if (config.claudeMdContent === null && config.settings === null) {\n log.error(\"No Claude Code configuration found in this directory.\");\n log.info(\"Run `claude-launchpad init` to set up a project, or cd into a configured project.\");\n process.exit(1);\n }\n\n const results: AnalyzerResult[] = await Promise.all([\n analyzeBudget(config),\n analyzeQuality(config),\n analyzeSettings(config),\n analyzeHooks(config),\n analyzeRules(config),\n analyzePermissions(config),\n analyzeMcp(config),\n ]);\n\n if (opts.json) {\n const overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n console.log(JSON.stringify({ overallScore, analyzers: results, timestamp: new Date().toISOString() }, null, 2));\n return;\n }\n\n const { overallScore } = renderDoctorReport(results);\n\n // Auto-fix mode\n if (opts.fix) {\n const allIssues = results.flatMap((r) => r.issues);\n const fixable = allIssues.filter((i) => i.severity !== \"info\");\n if (fixable.length > 0) {\n log.blank();\n log.step(\"Applying fixes...\");\n log.blank();\n const { fixed, skipped } = await applyFixes(fixable, opts.path);\n log.blank();\n if (fixed > 0) {\n log.success(`Applied ${fixed} fix(es). Run \\`claude-launchpad doctor\\` again to see your new score.`);\n }\n if (skipped > 0) {\n log.info(`${skipped} issue(s) require manual intervention.`);\n }\n }\n }\n\n // CI mode: exit non-zero if score is below threshold\n if (opts.minScore) {\n const threshold = parseInt(opts.minScore, 10);\n if (overallScore < threshold) {\n process.exit(1);\n }\n }\n });\n}\n","import { readdir, access } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { readFileOrNull } from \"./fs-utils.js\";\nimport type { ClaudeConfig, HookConfig, McpServerConfig } from \"../types/index.js\";\n\nconst CLAUDE_MD = \"CLAUDE.md\";\nconst CLAUDE_DIR = \".claude\";\nconst SETTINGS_FILE = \"settings.json\";\nconst RULES_DIR = \"rules\";\n\nexport async function parseClaudeConfig(projectRoot: string): Promise<ClaudeConfig> {\n const root = resolve(projectRoot);\n const claudeDir = join(root, CLAUDE_DIR);\n\n const [claudeMd, settings, hooks, rules, mcpServers, skills] = await Promise.all([\n readClaudeMd(root),\n readSettings(claudeDir),\n readHooks(claudeDir),\n readRules(claudeDir),\n readMcpServers(claudeDir),\n readSkills(claudeDir),\n ]);\n\n const instructionCount = claudeMd\n ? countInstructions(claudeMd)\n : 0;\n\n return {\n claudeMdPath: claudeMd !== null ? join(root, CLAUDE_MD) : null,\n claudeMdContent: claudeMd,\n claudeMdInstructionCount: instructionCount,\n settingsPath: settings !== null ? join(claudeDir, SETTINGS_FILE) : null,\n settings,\n hooks,\n rules,\n mcpServers,\n skills,\n };\n}\n\n// ─── CLAUDE.md ───\n\nasync function readClaudeMd(root: string): Promise<string | null> {\n return readFileOrNull(join(root, CLAUDE_MD));\n}\n\n/**\n * Count actionable instructions in CLAUDE.md.\n * Heuristic: non-empty, non-comment, non-heading-only lines that contain\n * imperative/declarative content (not blank lines or markdown structure).\n */\nexport function countInstructions(content: string): number {\n const lines = content.split(\"\\n\");\n let count = 0;\n\n for (const line of lines) {\n const trimmed = line.trim();\n // Skip empty lines\n if (trimmed === \"\") continue;\n // Skip pure comments\n if (trimmed.startsWith(\"<!--\") && trimmed.endsWith(\"-->\")) continue;\n // Skip code fence markers\n if (trimmed.startsWith(\"```\")) continue;\n // Skip headings that are just section markers (no instruction content)\n if (/^#{1,6}\\s+\\S/.test(trimmed)) continue;\n // Everything else is an instruction\n count++;\n }\n\n return count;\n}\n\n// ─── Settings ───\n\nasync function readSettings(claudeDir: string): Promise<Record<string, unknown> | null> {\n const raw = await readFileOrNull(join(claudeDir, SETTINGS_FILE));\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n// ─── Hooks ───\n\nasync function readHooks(claudeDir: string): Promise<ReadonlyArray<HookConfig>> {\n const settingsRaw = await readFileOrNull(join(claudeDir, SETTINGS_FILE));\n if (settingsRaw === null) return [];\n\n try {\n const settings = JSON.parse(settingsRaw) as Record<string, unknown>;\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks || typeof hooks !== \"object\") return [];\n\n const result: HookConfig[] = [];\n for (const [event, hookList] of Object.entries(hooks)) {\n if (!Array.isArray(hookList)) continue;\n for (const group of hookList) {\n const g = group as Record<string, unknown>;\n const matcher = g.matcher as string | undefined;\n\n // New schema: { matcher, hooks: [{ type, command }] }\n const nestedHooks = g.hooks as Record<string, unknown>[] | undefined;\n if (Array.isArray(nestedHooks)) {\n for (const hook of nestedHooks) {\n const h = hook as Record<string, unknown>;\n result.push({\n event: event as HookConfig[\"event\"],\n type: (h.type as HookConfig[\"type\"]) ?? \"command\",\n matcher,\n command: h.command as string | undefined,\n });\n }\n } else {\n // Legacy flat schema: { matcher, type, command }\n result.push({\n event: event as HookConfig[\"event\"],\n type: (g.type as HookConfig[\"type\"]) ?? \"command\",\n matcher,\n command: g.command as string | undefined,\n });\n }\n }\n }\n return result;\n } catch {\n return [];\n }\n}\n\n// ─── Rules ───\n\nasync function readRules(claudeDir: string): Promise<ReadonlyArray<string>> {\n const rulesDir = join(claudeDir, RULES_DIR);\n return listFilesRecursive(rulesDir, \".md\");\n}\n\n// ─── MCP Servers ───\n\nasync function readMcpServers(claudeDir: string): Promise<ReadonlyArray<McpServerConfig>> {\n const settingsRaw = await readFileOrNull(join(claudeDir, SETTINGS_FILE));\n if (settingsRaw === null) return [];\n\n try {\n const settings = JSON.parse(settingsRaw) as Record<string, unknown>;\n const servers = settings.mcpServers as Record<string, unknown> | undefined;\n if (!servers || typeof servers !== \"object\") return [];\n\n const result: McpServerConfig[] = [];\n for (const [name, config] of Object.entries(servers)) {\n const c = config as Record<string, unknown>;\n result.push({\n name,\n transport: (c.transport as McpServerConfig[\"transport\"]) ?? \"stdio\",\n command: c.command as string | undefined,\n url: c.url as string | undefined,\n });\n }\n return result;\n } catch {\n return [];\n }\n}\n\n// ─── Skills ───\n\nasync function readSkills(claudeDir: string): Promise<ReadonlyArray<string>> {\n const commandsDir = join(claudeDir, \"commands\");\n const skillsDir = join(claudeDir, \"skills\");\n\n const [commands, skills] = await Promise.all([\n listFilesRecursive(commandsDir, \".md\"),\n listFilesRecursive(skillsDir, \".md\"),\n ]);\n\n return [...commands, ...skills];\n}\n\n\nasync function listFilesRecursive(dir: string, ext: string): Promise<string[]> {\n try {\n await access(dir);\n } catch {\n return [];\n }\n\n const results: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const nested = await listFilesRecursive(fullPath, ext);\n results.push(...nested);\n } else if (entry.name.endsWith(ext)) {\n results.push(fullPath);\n }\n }\n\n return results;\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nconst BUDGET_WARN = 120;\nconst BUDGET_DANGER = 150;\nconst BUDGET_CRITICAL = 200;\n\nexport async function analyzeBudget(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n const count = config.claudeMdInstructionCount;\n\n if (config.claudeMdContent === null) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"high\",\n message: \"No CLAUDE.md found\",\n fix: \"Run `claude-launchpad init` or create CLAUDE.md manually\",\n });\n return { name: \"Instruction Budget\", issues, score: 0 };\n }\n\n if (count === 0) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"medium\",\n message: \"CLAUDE.md exists but has no actionable instructions\",\n fix: \"Add project-specific instructions to CLAUDE.md\",\n });\n return { name: \"Instruction Budget\", issues, score: 30 };\n }\n\n if (count > BUDGET_CRITICAL) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"critical\",\n message: `${count} instructions — way over the ~150 budget. Compliance drops significantly past 150.`,\n fix: \"Move detailed rules to .claude/rules/*.md files. Keep CLAUDE.md to essential project identity.\",\n });\n } else if (count > BUDGET_DANGER) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"high\",\n message: `${count} instructions — over the ~150 budget. Claude may start ignoring lower-priority rules.`,\n fix: \"Move verbose sections (conventions, off-limits details) to .claude/rules/ files.\",\n });\n } else if (count > BUDGET_WARN) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"medium\",\n message: `${count} instructions — approaching the ~150 budget.`,\n fix: \"Consider moving some rules to .claude/rules/ to leave headroom.\",\n });\n }\n\n // Score: 100 if under warn, scales down from there\n let score: number;\n if (count <= BUDGET_WARN) {\n score = 100;\n } else if (count <= BUDGET_DANGER) {\n score = 100 - Math.round(((count - BUDGET_WARN) / (BUDGET_DANGER - BUDGET_WARN)) * 30);\n } else if (count <= BUDGET_CRITICAL) {\n score = 70 - Math.round(((count - BUDGET_DANGER) / (BUDGET_CRITICAL - BUDGET_DANGER)) * 40);\n } else {\n score = Math.max(0, 30 - Math.round((count - BUDGET_CRITICAL) / 5));\n }\n\n return { name: \"Instruction Budget\", issues, score };\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeSettings(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n\n if (config.settings === null) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"medium\",\n message: \"No .claude/settings.json found\",\n fix: \"Run `claude-launchpad init` or create .claude/settings.json\",\n });\n return { name: \"Settings\", issues, score: 40 };\n }\n\n // Check for hooks (the most important setting)\n const hooks = config.settings.hooks as Record<string, unknown> | undefined;\n if (!hooks || Object.keys(hooks).length === 0) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"medium\",\n message: \"settings.json has no hooks configured\",\n fix: \"Run `claude-launchpad doctor --fix` to generate hooks\",\n });\n }\n\n // Plugins are optional — info only, doesn't affect score\n const plugins = config.settings.enabledPlugins as Record<string, boolean> | undefined;\n if (!plugins || Object.keys(plugins).length === 0) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"info\",\n message: \"No plugins enabled — plugins are optional but can add capabilities\",\n });\n }\n\n // Permission rules — only flag if allowedTools is set without security hooks\n const allowedTools = config.settings.allowedTools as string[] | undefined;\n if (allowedTools && allowedTools.length > 0 && config.hooks.length === 0) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"medium\",\n message: \"Tools auto-allowed without any hooks — no safety net for dangerous operations\",\n fix: \"Add PreToolUse hooks for security or remove allowedTools to use interactive prompting\",\n });\n }\n\n // Score: deduct for actionable issues only (not info)\n const actionableCount = issues.filter((i) => i.severity !== \"info\").length;\n const score = Math.max(0, 100 - actionableCount * 20);\n return { name: \"Settings\", issues, score };\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeHooks(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n const hooks = config.hooks;\n\n if (hooks.length === 0) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"medium\",\n message: \"No hooks configured — CLAUDE.md rules are advisory (~80% compliance), hooks are 100%\",\n fix: \"Add PostToolUse hooks for auto-formatting and PreToolUse for security gates\",\n });\n return { name: \"Hooks\", issues, score: 30 };\n }\n\n // Check for auto-format hook (prettier, ruff, gofmt, rustfmt, etc.)\n const formatPatterns = [\"format\", \"prettier\", \"gofmt\", \"rustfmt\", \"rubocop\", \"pint\", \"ktlint\", \"swift-format\", \"dotnet format\"];\n const hasPostFormat = hooks.some(\n (h) => h.event === \"PostToolUse\" && h.matcher?.includes(\"Write\") && formatPatterns.some((p) => h.command?.includes(p)),\n );\n if (!hasPostFormat) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"low\",\n message: \"No auto-format hook found\",\n fix: \"Add a PostToolUse hook that runs your formatter on Write|Edit\",\n });\n }\n\n // Check for security gate (env file protection)\n const hasEnvProtection = hooks.some(\n (h) => h.event === \"PreToolUse\" && h.command?.includes(\".env\"),\n );\n if (!hasEnvProtection) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"medium\",\n message: \"No .env file protection hook — Claude could read or write secrets in .env files\",\n fix: \"Add a PreToolUse hook on Read|Write|Edit that blocks access to .env files\",\n });\n }\n\n // Check for PreToolUse hooks (security layer)\n const hasPreToolUse = hooks.some((h) => h.event === \"PreToolUse\");\n if (!hasPreToolUse) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"medium\",\n message: \"No PreToolUse hooks — this is your security enforcement layer\",\n fix: \"Add PreToolUse hooks for file protection and dangerous command blocking\",\n });\n }\n\n const score = Math.max(0, 100 - issues.length * 20);\n return { name: \"Hooks\", issues, score };\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename, join, dirname } from \"node:path\";\nimport { fileExists } from \"../../../lib/fs-utils.js\";\nimport type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeRules(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n\n // Check for .claudeignore\n const projectRoot = config.claudeMdPath ? dirname(config.claudeMdPath) : process.cwd();\n const hasClaudeignore = await fileExists(join(projectRoot, \".claudeignore\"));\n if (!hasClaudeignore) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No .claudeignore found — Claude may read noise files (node_modules, dist, lockfiles)\",\n fix: \"Run `claude-launchpad init` or `doctor --fix` to generate one\",\n });\n }\n\n if (config.rules.length === 0) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No .claude/rules/ files found\",\n fix: \"Move detailed conventions from CLAUDE.md to .claude/rules/*.md (auto-loaded, saves budget)\",\n });\n return { name: \"Rules\", issues, score: 60 };\n }\n\n // Check for empty or near-empty rule files\n for (const rulePath of config.rules) {\n try {\n const content = await readFile(rulePath, \"utf-8\");\n const trimmed = content.trim();\n if (trimmed.length === 0) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: `Empty rule file: ${basename(rulePath)}`,\n fix: `Add content to ${basename(rulePath)} or delete it`,\n });\n } else if (trimmed.length < 20) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"info\",\n message: `Very short rule file (${trimmed.length} chars): ${basename(rulePath)}`,\n });\n }\n } catch {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: `Could not read rule file: ${basename(rulePath)}`,\n });\n }\n }\n\n const score = Math.max(0, 100 - issues.length * 10);\n return { name: \"Rules\", issues, score };\n}\n\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzePermissions(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n\n // Check if Bash is allowed without security hooks\n const hasBashSecurity = config.hooks.some(\n (h) => h.event === \"PreToolUse\" && (h.matcher?.includes(\"Bash\") || !h.matcher),\n );\n\n const bashAllowed = config.settings?.allowedTools as string[] | undefined;\n const hasBashAutoAllow = bashAllowed?.some((t) =>\n typeof t === \"string\" && t.toLowerCase().includes(\"bash\"),\n );\n\n if (hasBashAutoAllow && !hasBashSecurity) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: \"Bash is auto-allowed without a security hook — dangerous commands could run unchecked\",\n fix: \"Add a PreToolUse hook for Bash that blocks destructive commands (rm -rf, git push --force)\",\n });\n }\n\n // Check for force push protection\n const hasForceProtection = config.hooks.some(\n (h) => h.event === \"PreToolUse\" && h.command?.includes(\"force\"),\n );\n if (!hasForceProtection) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"low\",\n message: \"No force-push protection hook\",\n fix: \"Add a PreToolUse hook that warns on `git push --force` commands\",\n });\n }\n\n // Check CLAUDE.md for off-limits section\n if (config.claudeMdContent) {\n const hasOffLimits = config.claudeMdContent.includes(\"## Off-Limits\") ||\n config.claudeMdContent.includes(\"## off-limits\");\n if (!hasOffLimits) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"medium\",\n message: \"No Off-Limits section in CLAUDE.md — Claude has no guardrails beyond defaults\",\n fix: \"Add an ## Off-Limits section with project-specific restrictions\",\n });\n }\n }\n\n const score = Math.max(0, 100 - issues.length * 20);\n return { name: \"Permissions\", issues, score };\n}\n","import { access } from \"node:fs/promises\";\nimport type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeMcp(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n const servers = config.mcpServers;\n\n if (servers.length === 0) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"info\",\n message: \"No MCP servers configured. Run `claude-launchpad enhance` to get stack-specific recommendations.\",\n });\n return { name: \"MCP Servers\", issues, score: 50 };\n }\n\n for (const server of servers) {\n if (server.transport === \"stdio\" && !server.command) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"high\",\n message: `MCP server \"${server.name}\" uses stdio transport but has no command`,\n fix: `Add a \"command\" field to the \"${server.name}\" MCP server config`,\n });\n }\n\n if ((server.transport === \"sse\" || server.transport === \"http\") && !server.url) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"high\",\n message: `MCP server \"${server.name}\" uses ${server.transport} transport but has no URL`,\n fix: `Add a \"url\" field to the \"${server.name}\" MCP server config`,\n });\n }\n\n if (server.transport === \"stdio\" && server.command) {\n const executable = server.command.split(\" \")[0];\n if (executable.startsWith(\"/\") || executable.startsWith(\"./\")) {\n try {\n await access(executable);\n } catch {\n issues.push({\n analyzer: \"MCP\",\n severity: \"medium\",\n message: `MCP server \"${server.name}\" command not found: ${executable}`,\n fix: \"Verify the path exists or install the required package\",\n });\n }\n }\n }\n }\n\n const score = Math.max(0, 100 - issues.filter((i) => i.severity !== \"info\").length * 25);\n return { name: \"MCP Servers\", issues, score };\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nconst ESSENTIAL_SECTIONS = [\n { pattern: /^##\\s+(Tech )?Stack/m, name: \"Stack\", why: \"Claude performs worse without knowing the tech stack\" },\n { pattern: /^##\\s+Commands/m, name: \"Commands\", why: \"Claude guesses wrong without explicit dev/build/test commands\" },\n { pattern: /^##\\s+Session Start/m, name: \"Session Start\", why: \"Without this, Claude won't read TASKS.md or maintain continuity\" },\n { pattern: /^##\\s+Off.?Limits/m, name: \"Off-Limits\", why: \"Without guardrails, Claude has no boundaries beyond defaults\" },\n { pattern: /^##\\s+(Architecture|Project Structure)/m, name: \"Architecture/Structure\", why: \"Claude makes better decisions when it understands the codebase shape\" },\n] as const;\n\nconst VAGUE_PATTERNS = [\n { pattern: /write (good|clean|quality|nice) code/i, label: \"write good code\" },\n { pattern: /be (careful|thorough|diligent)/i, label: \"be careful\" },\n { pattern: /follow best practices/i, label: \"follow best practices\" },\n { pattern: /make sure (everything|it) works/i, label: \"make sure it works\" },\n] as const;\n\nconst SECRET_PATTERNS = [\n { pattern: /sk-[a-zA-Z0-9]{20,}/, label: \"OpenAI API key\" },\n { pattern: /ghp_[a-zA-Z0-9]{36}/, label: \"GitHub personal token\" },\n { pattern: /AKIA[0-9A-Z]{16}/, label: \"AWS access key\" },\n { pattern: /xoxb-[0-9]+-[a-zA-Z0-9]+/, label: \"Slack bot token\" },\n] as const;\n\nexport async function analyzeQuality(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n const content = config.claudeMdContent;\n\n if (content === null) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"high\",\n message: \"No CLAUDE.md found\",\n fix: \"Run `claude-launchpad init` to generate one\",\n });\n return { name: \"CLAUDE.md Quality\", issues, score: 0 };\n }\n\n // Check essential sections\n let sectionsFound = 0;\n for (const section of ESSENTIAL_SECTIONS) {\n if (section.pattern.test(content)) {\n sectionsFound++;\n } else {\n issues.push({\n analyzer: \"Quality\",\n severity: \"medium\",\n message: `Missing \"## ${section.name}\" section — ${section.why}`,\n fix: `Add a ## ${section.name} section to CLAUDE.md`,\n });\n }\n }\n\n // Check for vague/useless instructions\n for (const vague of VAGUE_PATTERNS) {\n if (vague.pattern.test(content)) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"low\",\n message: `Vague instruction detected: \"${vague.label}\" — zero signal, wastes budget`,\n fix: \"Replace with specific, actionable instructions\",\n });\n }\n }\n\n // Check for hardcoded secrets\n for (const secret of SECRET_PATTERNS) {\n if (secret.pattern.test(content)) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"critical\",\n message: `Possible ${secret.label} found in CLAUDE.md — secrets must never be in config files`,\n fix: \"Remove the secret immediately and rotate it\",\n });\n }\n }\n\n // Check for TODO placeholders (unfinished config)\n const todoCount = (content.match(/<!--\\s*TODO/gi) ?? []).length;\n if (todoCount > 3) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"medium\",\n message: `${todoCount} TODO placeholders — CLAUDE.md is mostly unfinished`,\n fix: \"Fill in the TODO sections or remove them\",\n });\n }\n\n // Score: base 100, deduct per issue\n const criticals = issues.filter((i) => i.severity === \"critical\").length;\n const highs = issues.filter((i) => i.severity === \"high\").length;\n const mediums = issues.filter((i) => i.severity === \"medium\").length;\n const lows = issues.filter((i) => i.severity === \"low\").length;\n\n const score = Math.max(0, 100 - criticals * 40 - highs * 30 - mediums * 15 - lows * 5);\n return { name: \"CLAUDE.md Quality\", issues, score };\n}\n","import { readFile, writeFile, mkdir, access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { log } from \"../../lib/output.js\";\nimport { detectProject } from \"../../lib/detect.js\";\nimport { generateClaudeignore } from \"../init/generators/claudeignore.js\";\nimport type { DiagnosticIssue, DetectedProject } from \"../../types/index.js\";\n\ninterface FixResult {\n readonly fixed: number;\n readonly skipped: number;\n}\n\n/**\n * Auto-apply deterministic fixes for doctor issues.\n * Only applies fixes that are safe and unambiguous.\n */\nexport async function applyFixes(\n issues: ReadonlyArray<DiagnosticIssue>,\n projectRoot: string,\n): Promise<FixResult> {\n const detected = await detectProject(projectRoot);\n let fixed = 0;\n let skipped = 0;\n\n for (const issue of issues) {\n const applied = await tryFix(issue, projectRoot, detected);\n if (applied) {\n fixed++;\n } else {\n skipped++;\n }\n }\n\n return { fixed, skipped };\n}\n\nasync function tryFix(\n issue: DiagnosticIssue,\n root: string,\n detected: DetectedProject,\n): Promise<boolean> {\n // ─── Hooks: No hooks at all (create settings.json from scratch) ───\n if (issue.analyzer === \"Hooks\" && issue.message.includes(\"No hooks configured\")) {\n const a = await addEnvProtectionHook(root);\n const b = await addAutoFormatHook(root, detected);\n const c = await addForcePushProtection(root);\n return a || b || c;\n }\n\n // ─── Hooks: No .env protection ───\n if (issue.analyzer === \"Hooks\" && issue.message.includes(\".env file protection\")) {\n return addEnvProtectionHook(root);\n }\n\n // ─── Hooks: No auto-format ───\n if (issue.analyzer === \"Hooks\" && issue.message.includes(\"auto-format\")) {\n return addAutoFormatHook(root, detected);\n }\n\n // ─── Hooks: No PreToolUse ───\n if (issue.analyzer === \"Hooks\" && issue.message.includes(\"No PreToolUse\")) {\n return addEnvProtectionHook(root);\n }\n\n // ─── Quality: Missing Architecture section ───\n if (issue.analyzer === \"Quality\" && issue.message.includes(\"Architecture\")) {\n return addClaudeMdSection(root, \"## Architecture\", \"<!-- TODO: Describe your codebase structure. Run `claude-launchpad enhance` to auto-fill this. -->\");\n }\n\n // ─── Quality: Missing Off-Limits section ───\n if (issue.analyzer === \"Quality\" && issue.message.includes(\"Off-Limits\")) {\n return addClaudeMdSection(root, \"## Off-Limits\", \"- Never hardcode secrets — use environment variables\\n- Never write to `.env` files\\n- Never expose internal error details in API responses\");\n }\n\n // ─── Quality: Missing Commands section ───\n if (issue.analyzer === \"Quality\" && issue.message.includes(\"Commands\")) {\n return addClaudeMdSection(root, \"## Commands\", \"<!-- TODO: Add your dev/build/test commands -->\");\n }\n\n // ─── Quality: Missing Stack section ───\n if (issue.analyzer === \"Quality\" && issue.message.includes(\"Stack\")) {\n const stackContent = detected.language\n ? `- **Language**: ${detected.language}${detected.framework ? `\\n- **Framework**: ${detected.framework}` : \"\"}${detected.packageManager ? `\\n- **Package Manager**: ${detected.packageManager}` : \"\"}`\n : \"<!-- TODO: Define your tech stack -->\";\n return addClaudeMdSection(root, \"## Stack\", stackContent);\n }\n\n // ─── Quality: Missing Session Start ───\n if (issue.analyzer === \"Quality\" && issue.message.includes(\"Session Start\")) {\n return addClaudeMdSection(root, \"## Session Start\", \"- ALWAYS read @TASKS.md first — it tracks progress across sessions\\n- Update TASKS.md as you complete work\");\n }\n\n // ─── Rules: No .claudeignore ───\n if (issue.analyzer === \"Rules\" && issue.message.includes(\"No .claudeignore\")) {\n return createClaudeignore(root, detected);\n }\n\n // ─── Rules: No rules files ───\n if (issue.analyzer === \"Rules\" && issue.message.includes(\"No .claude/rules/\")) {\n return createStarterRules(root);\n }\n\n // ─── Permissions: No force-push protection ───\n if (issue.analyzer === \"Permissions\" && issue.message.includes(\"force-push\")) {\n return addForcePushProtection(root);\n }\n\n // Can't auto-fix this one\n return false;\n}\n\n// ─── Fix Implementations ───\n\nasync function addEnvProtectionHook(root: string): Promise<boolean> {\n const settings = await readSettingsJson(root);\n const hooks = (settings.hooks ?? {}) as Record<string, unknown>;\n const preToolUse = (hooks.PreToolUse as Record<string, unknown>[] | undefined) ?? [];\n\n // Check if already exists\n const alreadyHas = preToolUse.some((g: Record<string, unknown>) => {\n const nested = g.hooks as Record<string, unknown>[] | undefined;\n return nested?.some((h) => String(h.command ?? \"\").includes(\".env\"));\n });\n\n if (alreadyHas) return false;\n\n preToolUse.push({\n matcher: \"Read|Write|Edit\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -qE '\\\\.(env|env\\\\..*)$' && ! echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -q '.env.example' && echo 'BLOCKED: .env files contain secrets' && exit 1; exit 0\",\n }],\n });\n\n (settings as Record<string, unknown>).hooks = { ...hooks, PreToolUse: preToolUse };\n await writeSettingsJson(root, settings);\n log.success(\"Added .env file protection hook (PreToolUse)\");\n return true;\n}\n\nasync function addAutoFormatHook(root: string, detected: DetectedProject): Promise<boolean> {\n if (!detected.language) return false;\n\n // Safe formatter commands only — never use detected.formatCommand to prevent injection\n const formatters: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: { extensions: [\"ts\", \"tsx\"], command: \"npx prettier --write\" },\n JavaScript: { extensions: [\"js\", \"jsx\"], command: \"npx prettier --write\" },\n Python: { extensions: [\"py\"], command: \"ruff format\" },\n Go: { extensions: [\"go\"], command: \"gofmt -w\" },\n Rust: { extensions: [\"rs\"], command: \"rustfmt\" },\n Ruby: { extensions: [\"rb\"], command: \"rubocop -A\" },\n PHP: { extensions: [\"php\"], command: \"vendor/bin/pint\" },\n };\n\n const config = formatters[detected.language];\n if (!config) return false;\n\n const settings = await readSettingsJson(root);\n const hooks = (settings.hooks ?? {}) as Record<string, unknown>;\n const postToolUse = (hooks.PostToolUse as Record<string, unknown>[] | undefined) ?? [];\n\n const alreadyHas = postToolUse.some((g: Record<string, unknown>) => {\n const nested = g.hooks as Record<string, unknown>[] | undefined;\n return nested?.some((h) => String(h.command ?? \"\").includes(\"format\"));\n });\n\n if (alreadyHas) return false;\n\n const extChecks = config.extensions.map((ext) => `[ \"$ext\" = \"${ext}\" ]`).join(\" || \");\n\n postToolUse.push({\n matcher: \"Write|Edit\",\n hooks: [{\n type: \"command\",\n command: `ext=\\${TOOL_INPUT_FILE_PATH##*.}; (${extChecks}) && ${config.command} \"$TOOL_INPUT_FILE_PATH\" 2>/dev/null; exit 0`,\n }],\n });\n\n (settings as Record<string, unknown>).hooks = { ...hooks, PostToolUse: postToolUse };\n await writeSettingsJson(root, settings);\n log.success(`Added auto-format hook (PostToolUse → ${config.command})`);\n return true;\n}\n\nasync function addForcePushProtection(root: string): Promise<boolean> {\n const settings = await readSettingsJson(root);\n const hooks = (settings.hooks ?? {}) as Record<string, unknown>;\n const preToolUse = (hooks.PreToolUse as Record<string, unknown>[] | undefined) ?? [];\n\n const alreadyHas = preToolUse.some((g: Record<string, unknown>) => {\n const nested = g.hooks as Record<string, unknown>[] | undefined;\n return nested?.some((h) => String(h.command ?? \"\").includes(\"force\"));\n });\n\n if (alreadyHas) return false;\n\n preToolUse.push({\n matcher: \"Bash\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_COMMAND\\\" | grep -qE 'push.*--force|push.*-f' && echo 'WARNING: Force push detected — this can destroy remote history' && exit 1; exit 0\",\n }],\n });\n\n (settings as Record<string, unknown>).hooks = { ...hooks, PreToolUse: preToolUse };\n await writeSettingsJson(root, settings);\n log.success(\"Added force-push protection hook (PreToolUse → Bash)\");\n return true;\n}\n\nasync function addClaudeMdSection(root: string, heading: string, content: string): Promise<boolean> {\n const claudeMdPath = join(root, \"CLAUDE.md\");\n let existing: string;\n try {\n existing = await readFile(claudeMdPath, \"utf-8\");\n } catch {\n return false; // No CLAUDE.md to add to\n }\n\n // Don't add if section already exists\n if (existing.includes(heading)) return false;\n\n // Append before Key Decisions if it exists, otherwise at end\n const keyDecisionsIdx = existing.indexOf(\"## Key Decisions\");\n const insertAt = keyDecisionsIdx > -1 ? keyDecisionsIdx : existing.length;\n\n const section = `\\n${heading}\\n${content}\\n\\n`;\n const updated = existing.slice(0, insertAt) + section + existing.slice(insertAt);\n\n await writeFile(claudeMdPath, updated);\n log.success(`Added \"${heading}\" section to CLAUDE.md`);\n return true;\n}\n\nasync function createClaudeignore(root: string, detected: DetectedProject): Promise<boolean> {\n const ignorePath = join(root, \".claudeignore\");\n try {\n await access(ignorePath);\n return false; // Already exists\n } catch {\n // Create it\n }\n\n const content = generateClaudeignore(detected);\n await writeFile(ignorePath, content);\n log.success(\"Generated .claudeignore with language-specific ignore patterns\");\n return true;\n}\n\nasync function createStarterRules(root: string): Promise<boolean> {\n const rulesDir = join(root, \".claude\", \"rules\");\n try {\n await access(rulesDir);\n return false; // Already exists\n } catch {\n // Create it\n }\n\n await mkdir(rulesDir, { recursive: true });\n\n await writeFile(\n join(rulesDir, \"conventions.md\"),\n `# Project Conventions\n\n- Use conventional commits (feat:, fix:, docs:, refactor:, test:, chore:)\n- Keep files under 400 lines, functions under 50 lines\n- Handle errors explicitly — no empty catch blocks\n- Validate input at system boundaries\n`,\n );\n\n log.success(\"Created .claude/rules/conventions.md with starter rules\");\n return true;\n}\n\n// ─── Settings JSON helpers ───\n\nasync function readSettingsJson(root: string): Promise<Record<string, unknown>> {\n const path = join(root, \".claude\", \"settings.json\");\n try {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nasync function writeSettingsJson(root: string, settings: Record<string, unknown>): Promise<void> {\n const dir = join(root, \".claude\");\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, \"settings.json\"), JSON.stringify(settings, null, 2) + \"\\n\");\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { log, renderDoctorReport } from \"../../lib/output.js\";\nimport { analyzeBudget } from \"./analyzers/budget.js\";\nimport { analyzeSettings } from \"./analyzers/settings.js\";\nimport { analyzeHooks } from \"./analyzers/hooks.js\";\nimport { analyzeRules } from \"./analyzers/rules.js\";\nimport { analyzePermissions } from \"./analyzers/permissions.js\";\nimport { analyzeMcp } from \"./analyzers/mcp.js\";\nimport { analyzeQuality } from \"./analyzers/quality.js\";\nimport type { AnalyzerResult } from \"../../types/index.js\";\n\n/**\n * Watch config files for changes using polling (reliable on all OS).\n * Re-runs doctor on every detected change.\n */\nexport async function watchConfig(projectRoot: string): Promise<void> {\n await runAndDisplay(projectRoot);\n\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n\n let lastSnapshot = await getFileSnapshot(projectRoot);\n\n setInterval(async () => {\n const currentSnapshot = await getFileSnapshot(projectRoot);\n if (currentSnapshot !== lastSnapshot) {\n lastSnapshot = currentSnapshot;\n console.clear();\n await runAndDisplay(projectRoot);\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n }\n }, 1000);\n\n await new Promise(() => {});\n}\n\nasync function getFileSnapshot(projectRoot: string): Promise<string> {\n const files = [\n join(projectRoot, \"CLAUDE.md\"),\n join(projectRoot, \".claudeignore\"),\n ];\n\n const claudeDir = join(projectRoot, \".claude\");\n try {\n const entries = await readdir(claudeDir, { withFileTypes: true, recursive: true });\n for (const entry of entries) {\n if (entry.isFile()) {\n const parentPath = (entry as unknown as { parentPath?: string }).parentPath ?? claudeDir;\n files.push(join(parentPath, entry.name));\n }\n }\n } catch {\n // .claude/ doesn't exist\n }\n\n const mtimes: string[] = [];\n for (const file of files) {\n try {\n const s = await stat(file);\n mtimes.push(`${file}:${s.mtimeMs}`);\n } catch {\n mtimes.push(`${file}:missing`);\n }\n }\n\n return mtimes.join(\"|\");\n}\n\nasync function runAndDisplay(projectRoot: string): Promise<void> {\n console.log(\"\\x1b[36m\\x1b[1m Claude Launchpad\\x1b[0m\");\n console.log(\"\\x1b[2m Scaffold · Diagnose · Evaluate\\x1b[0m\");\n log.blank();\n\n const config = await parseClaudeConfig(projectRoot);\n\n if (config.claudeMdContent === null && config.settings === null) {\n log.error(\"No Claude Code configuration found.\");\n return;\n }\n\n const results: AnalyzerResult[] = await Promise.all([\n analyzeBudget(config),\n analyzeQuality(config),\n analyzeSettings(config),\n analyzeHooks(config),\n analyzeRules(config),\n analyzePermissions(config),\n analyzeMcp(config),\n ]);\n\n renderDoctorReport(results);\n}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { printBanner, log, printScoreCard } from \"../../lib/output.js\";\nimport { loadScenarios } from \"./loader.js\";\nimport { runScenarioWithRetries } from \"./runner.js\";\nimport type { EvalRunResult } from \"../../types/index.js\";\n\nexport function createEvalCommand(): Command {\n return new Command(\"eval\")\n .description(\"Test your Claude Code config against eval scenarios\")\n .option(\"-s, --suite <suite>\", \"Eval suite to run (e.g., security, conventions, workflow)\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .option(\"--scenarios <path>\", \"Custom scenarios directory\")\n .option(\"--runs <n>\", \"Runs per scenario (default: 3)\", \"3\")\n .option(\"--timeout <ms>\", \"Timeout per run in ms (default: 120000)\", \"120000\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--debug\", \"Keep sandbox directories for inspection\")\n .option(\"--model <model>\", \"Model to use for eval (e.g., sonnet, haiku, opus)\")\n .action(async (opts) => {\n printBanner();\n\n // Verify Claude CLI is available\n const claudeAvailable = await checkClaudeCli();\n if (!claudeAvailable) {\n log.error(\"Claude CLI not found. Install it: https://docs.anthropic.com/en/docs/claude-code\");\n log.info(\"The eval command runs Claude headless against scenarios — it requires the CLI.\");\n process.exit(1);\n }\n\n // Load scenarios\n log.step(\"Loading eval scenarios...\");\n const scenarios = await loadScenarios({\n suite: opts.suite,\n customPath: opts.scenarios,\n });\n\n if (scenarios.length === 0) {\n log.warn(\"No matching scenarios found.\");\n if (opts.suite) {\n log.info(`Check that the suite \"${opts.suite}\" exists in the scenarios directory.`);\n }\n return;\n }\n\n log.success(`Loaded ${scenarios.length} scenario(s)`);\n if (opts.model) {\n log.info(`Model: ${opts.model}`);\n }\n log.blank();\n\n const runs = parseInt(opts.runs, 10);\n const timeout = parseInt(opts.timeout, 10);\n\n // Run scenarios\n const results: EvalRunResult[] = [];\n\n for (const scenario of scenarios) {\n const spinner = ora({\n text: `Running: ${scenario.name} (${runs} run${runs > 1 ? \"s\" : \"\"})`,\n prefixText: \" \",\n }).start();\n\n try {\n const result = await runScenarioWithRetries(\n { ...scenario, runs },\n { projectRoot: opts.path, timeout, debug: opts.debug, model: opts.model },\n );\n results.push(result);\n\n if (result.passed) {\n spinner.succeed(`${scenario.name} ${result.score}/${result.maxScore}`);\n } else {\n spinner.fail(`${scenario.name} ${result.score}/${result.maxScore}`);\n }\n } catch (error: unknown) {\n spinner.fail(`${scenario.name} ERROR`);\n const msg = error instanceof Error ? error.message : String(error);\n log.error(` ${msg}`);\n results.push({\n scenario: scenario.name,\n score: 0,\n maxScore: scenario.checks.reduce((s, c) => s + c.points, 0),\n passed: false,\n checks: scenario.checks.map((c) => ({ label: c.label, passed: false, points: c.points })),\n });\n }\n }\n\n log.blank();\n\n if (opts.json) {\n const overallScore = results.reduce((s, r) => s + r.score, 0);\n const overallMax = results.reduce((s, r) => s + r.maxScore, 0);\n console.log(JSON.stringify({\n results,\n overallScore,\n overallMax,\n passed: overallScore >= overallMax * 0.8,\n timestamp: new Date().toISOString(),\n }, null, 2));\n return;\n }\n\n renderEvalReport(results);\n\n // Save report to .claude/eval/\n await saveEvalReport(results, opts.path, opts.suite, opts.model);\n });\n}\n\nfunction renderEvalReport(results: ReadonlyArray<EvalRunResult>): void {\n for (const result of results) {\n const icon = result.passed ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const status = result.passed ? chalk.green(\"PASS\") : chalk.red(\"FAIL\");\n const score = `${result.score}/${result.maxScore}`;\n\n console.log(` ${icon} ${chalk.bold(result.scenario)} ${score} ${status}`);\n\n const failedChecks = result.checks.filter((c) => !c.passed);\n for (const check of failedChecks) {\n console.log(` ${chalk.red(\"✗\")} ${chalk.dim(check.label)}`);\n }\n }\n\n log.blank();\n\n const totalScore = results.reduce((s, r) => s + r.score, 0);\n const totalMax = results.reduce((s, r) => s + r.maxScore, 0);\n const pct = totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0;\n\n printScoreCard(\"Config Eval Score\", pct);\n log.blank();\n\n const passed = results.filter((r) => r.passed).length;\n const failed = results.length - passed;\n\n if (failed === 0) {\n log.success(`All ${passed} scenario(s) passed.`);\n } else {\n log.warn(`${passed} passed, ${failed} failed out of ${results.length} scenario(s).`);\n }\n}\n\nasync function saveEvalReport(\n results: ReadonlyArray<EvalRunResult>,\n projectRoot: string,\n suite?: string,\n model?: string,\n): Promise<void> {\n const totalScore = results.reduce((s, r) => s + r.score, 0);\n const totalMax = results.reduce((s, r) => s + r.maxScore, 0);\n const pct = totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0;\n const passed = results.filter((r) => r.passed).length;\n const failed = results.length - passed;\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\").slice(0, 19);\n\n const lines: string[] = [\n `# Eval Report — ${timestamp}`,\n \"\",\n `**Score: ${pct}%** (${passed} passed, ${failed} failed out of ${results.length} scenarios)`,\n \"\",\n `- Suite: ${suite ?? \"all\"}`,\n `- Model: ${model ?? \"default\"}`,\n `- Date: ${new Date().toISOString().split(\"T\")[0]}`,\n \"\",\n \"## Results\",\n \"\",\n ];\n\n for (const result of results) {\n const status = result.passed ? \"PASS\" : \"FAIL\";\n lines.push(`### ${result.scenario} — ${result.score}/${result.maxScore} ${status}`);\n\n const failedChecks = result.checks.filter((c) => !c.passed);\n const passedChecks = result.checks.filter((c) => c.passed);\n\n for (const check of passedChecks) {\n lines.push(`- PASSED: ${check.label} (${check.points} pts)`);\n }\n for (const check of failedChecks) {\n lines.push(`- FAILED: ${check.label} (${check.points} pts)`);\n }\n lines.push(\"\");\n }\n\n if (failed > 0) {\n lines.push(\"## Recommendations\");\n lines.push(\"\");\n for (const result of results.filter((r) => !r.passed)) {\n lines.push(`### Fix: ${result.scenario}`);\n const failedChecks = result.checks.filter((c) => !c.passed);\n for (const check of failedChecks) {\n lines.push(`- ${check.label} — update CLAUDE.md instructions or add hooks to enforce this behavior`);\n }\n lines.push(\"\");\n }\n }\n\n const evalDir = join(projectRoot, \".claude\", \"eval\");\n await mkdir(evalDir, { recursive: true });\n const filename = `eval-${suite ?? \"all\"}-${timestamp}.md`;\n await writeFile(join(evalDir, filename), lines.join(\"\\n\"));\n log.success(`Report saved to .claude/eval/${filename}`);\n}\n\nasync function checkClaudeCli(): Promise<boolean> {\n const { execFile } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const exec = promisify(execFile);\n\n try {\n await exec(\"claude\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile, readdir, access } from \"node:fs/promises\";\nimport { join, resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parse as parseYaml } from \"yaml\";\nimport { validateScenario } from \"./schema.js\";\nimport type { EvalScenario } from \"../../types/index.js\";\n\n/**\n * Find the scenarios directory. Works both in dev (tsx) and bundled (tsup).\n * - Dev: __dirname is src/commands/eval/, scenarios is at ../../../scenarios/\n * - Bundled: __dirname is dist/, scenarios is at ../scenarios/\n * - npm installed: __dirname is node_modules/claude-launchpad/dist/, scenarios is at ../scenarios/\n */\nasync function findScenariosDir(): Promise<string> {\n const thisDir = dirname(fileURLToPath(import.meta.url));\n\n // Try relative to this file (dev mode: src/commands/eval/ → ../../../scenarios/)\n const devPath = resolve(thisDir, \"../../../scenarios\");\n if (await dirExists(devPath)) return devPath;\n\n // Try relative to dist/ (bundled: dist/ → ../scenarios/)\n const bundledPath = resolve(thisDir, \"../scenarios\");\n if (await dirExists(bundledPath)) return bundledPath;\n\n // Try relative to package root (fallback)\n const rootPath = resolve(thisDir, \"../../scenarios\");\n if (await dirExists(rootPath)) return rootPath;\n\n return devPath; // Fall through — will just find 0 scenarios\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Load eval scenarios from a directory. Supports:\n * - Built-in scenarios (shipped in scenarios/)\n * - Custom scenarios from a user-specified path\n */\nexport async function loadScenarios(options: {\n suite?: string;\n customPath?: string;\n}): Promise<ReadonlyArray<EvalScenario>> {\n const { suite, customPath } = options;\n\n const scenarioDir = customPath\n ? resolve(customPath)\n : await findScenariosDir();\n\n const dirs = suite\n ? [join(scenarioDir, suite)]\n : await getSubdirectories(scenarioDir);\n\n // Also check the root dir for flat YAML files\n const allDirs = [scenarioDir, ...dirs];\n\n const scenarios: EvalScenario[] = [];\n\n for (const dir of allDirs) {\n const files = await listYamlFiles(dir);\n for (const file of files) {\n try {\n const content = await readFile(file, \"utf-8\");\n const raw = parseYaml(content);\n const scenario = validateScenario(raw, file);\n scenarios.push(scenario);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.warn(` Warning: Skipping ${file}: ${msg}`);\n }\n }\n }\n\n return scenarios;\n}\n\nasync function getSubdirectories(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n\nasync function listYamlFiles(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isFile() && (e.name.endsWith(\".yaml\") || e.name.endsWith(\".yml\")))\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n","import type { EvalScenario, EvalCheck } from \"../../types/index.js\";\n\n/**\n * Validates a raw parsed YAML object against the EvalScenario schema.\n * Returns a validated scenario or throws with a descriptive error.\n */\nexport function validateScenario(raw: unknown, filePath: string): EvalScenario {\n if (!raw || typeof raw !== \"object\") {\n throw new ScenarioError(filePath, \"Scenario must be a YAML object\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n const name = requireString(obj, \"name\", filePath);\n const description = requireString(obj, \"description\", filePath);\n const prompt = requireString(obj, \"prompt\", filePath);\n const setup = validateSetup(obj.setup, filePath);\n const checks = validateChecks(obj.checks, filePath);\n const passingScore = requireNumber(obj, \"passingScore\", filePath);\n const runs = optionalNumber(obj, \"runs\") ?? 3;\n\n return { name, description, setup, prompt, checks, passingScore, runs };\n}\n\n// ─── Field Validators ───\n\nfunction validateSetup(\n raw: unknown,\n filePath: string,\n): EvalScenario[\"setup\"] {\n if (!raw || typeof raw !== \"object\") {\n throw new ScenarioError(filePath, '\"setup\" must be an object with a \"files\" array');\n }\n\n const obj = raw as Record<string, unknown>;\n const files = obj.files;\n\n if (!Array.isArray(files)) {\n throw new ScenarioError(filePath, '\"setup.files\" must be an array');\n }\n\n const validatedFiles = files.map((f, i) => {\n if (!f || typeof f !== \"object\") {\n throw new ScenarioError(filePath, `setup.files[${i}] must be an object`);\n }\n const file = f as Record<string, unknown>;\n if (typeof file.path !== \"string\" || typeof file.content !== \"string\") {\n throw new ScenarioError(filePath, `setup.files[${i}] must have \"path\" and \"content\" strings`);\n }\n return { path: file.path, content: file.content };\n });\n\n const instructions = typeof obj.instructions === \"string\" ? obj.instructions : undefined;\n\n return { files: validatedFiles, instructions };\n}\n\nfunction validateChecks(raw: unknown, filePath: string): ReadonlyArray<EvalCheck> {\n if (!Array.isArray(raw) || raw.length === 0) {\n throw new ScenarioError(filePath, '\"checks\" must be a non-empty array');\n }\n\n return raw.map((c, i) => {\n if (!c || typeof c !== \"object\") {\n throw new ScenarioError(filePath, `checks[${i}] must be an object`);\n }\n const check = c as Record<string, unknown>;\n\n const validTypes = [\"grep\", \"file-exists\", \"file-absent\", \"max-lines\", \"custom\"];\n if (!validTypes.includes(check.type as string)) {\n throw new ScenarioError(filePath, `checks[${i}].type must be one of: ${validTypes.join(\", \")}`);\n }\n\n if (typeof check.target !== \"string\") {\n throw new ScenarioError(filePath, `checks[${i}].target must be a string`);\n }\n\n const validExpect = [\"present\", \"absent\"];\n if (!validExpect.includes(check.expect as string)) {\n throw new ScenarioError(filePath, `checks[${i}].expect must be \"present\" or \"absent\"`);\n }\n\n if (typeof check.points !== \"number\" || check.points < 0) {\n throw new ScenarioError(filePath, `checks[${i}].points must be a non-negative number`);\n }\n\n if (typeof check.label !== \"string\") {\n throw new ScenarioError(filePath, `checks[${i}].label must be a string`);\n }\n\n return {\n type: check.type as EvalCheck[\"type\"],\n pattern: typeof check.pattern === \"string\" ? check.pattern : undefined,\n target: check.target,\n expect: check.expect as EvalCheck[\"expect\"],\n points: check.points,\n label: check.label,\n };\n });\n}\n\n// ─── Helpers ───\n\nfunction requireString(obj: Record<string, unknown>, key: string, filePath: string): string {\n if (typeof obj[key] !== \"string\" || obj[key] === \"\") {\n throw new ScenarioError(filePath, `\"${key}\" must be a non-empty string`);\n }\n return obj[key] as string;\n}\n\nfunction requireNumber(obj: Record<string, unknown>, key: string, filePath: string): number {\n if (typeof obj[key] !== \"number\") {\n throw new ScenarioError(filePath, `\"${key}\" must be a number`);\n }\n return obj[key] as number;\n}\n\nfunction optionalNumber(obj: Record<string, unknown>, key: string): number | undefined {\n if (obj[key] === undefined) return undefined;\n if (typeof obj[key] !== \"number\") return undefined;\n return obj[key] as number;\n}\n\nclass ScenarioError extends Error {\n constructor(filePath: string, message: string) {\n super(`Invalid scenario ${filePath}: ${message}`);\n this.name = \"ScenarioError\";\n }\n}\n","import { mkdir, writeFile, readFile, readdir, rm } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { randomUUID } from \"node:crypto\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { EvalScenario, EvalRunResult, EvalCheck } from \"../../types/index.js\";\n\nconst exec = promisify(execFile);\n\ninterface RunOptions {\n readonly projectRoot: string;\n readonly timeout: number;\n readonly debug?: boolean;\n readonly model?: string;\n}\n\n/**\n * Execute a single eval scenario run using the Agent SDK.\n *\n * 1. Create a temp directory with the scenario's seed files\n * 2. Write a minimal CLAUDE.md with the scenario's instructions\n * 3. Run Claude via Agent SDK with explicit tool permissions\n * 4. Check the results against the scenario's checks\n * 5. Clean up\n */\nexport async function runScenario(\n scenario: EvalScenario,\n options: RunOptions,\n): Promise<EvalRunResult> {\n const sandboxDir = join(tmpdir(), `claude-eval-${randomUUID()}`);\n\n try {\n await setupSandbox(sandboxDir, scenario);\n await runClaudeInSandbox(sandboxDir, scenario.prompt, options.timeout, options.model);\n return await scoreResults(scenario, sandboxDir);\n } finally {\n if (options.debug) {\n console.log(` DEBUG: Sandbox preserved at ${sandboxDir}`);\n } else {\n await rm(sandboxDir, { recursive: true, force: true }).catch(() => {});\n }\n }\n}\n\n/**\n * Run a scenario multiple times and return the median result.\n */\nexport async function runScenarioWithRetries(\n scenario: EvalScenario,\n options: RunOptions,\n): Promise<EvalRunResult> {\n const results: EvalRunResult[] = [];\n\n for (let i = 0; i < scenario.runs; i++) {\n const result = await runScenario(scenario, options);\n results.push(result);\n }\n\n const sorted = [...results].sort((a, b) => a.score - b.score);\n return sorted[Math.floor(sorted.length / 2)];\n}\n\n// ─── Sandbox Setup ───\n\nasync function setupSandbox(sandboxDir: string, scenario: EvalScenario): Promise<void> {\n await mkdir(sandboxDir, { recursive: true });\n\n for (const file of scenario.setup.files) {\n const filePath = join(sandboxDir, file.path);\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, file.content);\n }\n\n if (scenario.setup.instructions) {\n await writeFile(\n join(sandboxDir, \"CLAUDE.md\"),\n `# Eval Scenario\\n\\n${scenario.setup.instructions}\\n`,\n );\n }\n\n await exec(\"git\", [\"init\", \"-q\"], { cwd: sandboxDir });\n await exec(\"git\", [\"add\", \"-A\"], { cwd: sandboxDir });\n await exec(\"git\", [\n \"-c\", \"user.name=eval\",\n \"-c\", \"user.email=eval@test\",\n \"commit\", \"-q\", \"-m\", \"eval setup\",\n ], { cwd: sandboxDir });\n}\n\n// ─── Claude Execution ───\n\nasync function runClaudeInSandbox(\n cwd: string,\n prompt: string,\n timeout: number,\n model?: string,\n): Promise<void> {\n // Try Agent SDK first, fall back to CLI subprocess\n try {\n const sdk = await import(\"@anthropic-ai/claude-agent-sdk\");\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n for await (const _message of sdk.query({\n prompt,\n options: {\n cwd,\n allowedTools: [\"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\"],\n permissionMode: \"dontAsk\",\n settingSources: [],\n maxTurns: 20,\n abortController: controller,\n ...(model ? { model } : {}),\n },\n })) {\n // Consume the stream — we only care about side effects (file edits)\n }\n } finally {\n clearTimeout(timeoutId);\n }\n } catch {\n // SDK not available or failed — fall back to CLI\n await runClaudeCli(cwd, prompt, timeout, model);\n }\n}\n\nasync function runClaudeCli(\n cwd: string,\n prompt: string,\n timeout: number,\n model?: string,\n): Promise<void> {\n try {\n const args = [\n \"-p\", prompt,\n \"--output-format\", \"text\",\n \"--max-turns\", \"20\",\n \"--dangerously-skip-permissions\",\n \"--allowedTools\", \"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\",\n ];\n if (model) args.push(\"--model\", model);\n await exec(\"claude\", args, { cwd, timeout, maxBuffer: 10 * 1024 * 1024 });\n } catch (error: unknown) {\n // Claude might exit non-zero but still produce usable output\n if (error && typeof error === \"object\" && \"stdout\" in error) {\n return; // Files may have been modified despite exit code\n }\n throw error;\n }\n}\n\n// ─── Scoring ───\n\nasync function scoreResults(\n scenario: EvalScenario,\n sandboxDir: string,\n): Promise<EvalRunResult> {\n const checkResults = await evaluateChecks(scenario.checks, sandboxDir);\n\n const score = checkResults\n .filter((c) => c.passed)\n .reduce((sum, c) => sum + c.points, 0);\n\n const maxScore = scenario.checks.reduce((sum, c) => sum + c.points, 0);\n\n return {\n scenario: scenario.name,\n score,\n maxScore,\n passed: score >= scenario.passingScore,\n checks: checkResults,\n };\n}\n\nasync function evaluateChecks(\n checks: ReadonlyArray<EvalCheck>,\n sandboxDir: string,\n): Promise<ReadonlyArray<{ label: string; passed: boolean; points: number }>> {\n const results: { label: string; passed: boolean; points: number }[] = [];\n\n for (const check of checks) {\n const passed = await evaluateSingleCheck(check, sandboxDir);\n results.push({ label: check.label, passed, points: check.points });\n }\n\n return results;\n}\n\nasync function evaluateSingleCheck(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n switch (check.type) {\n case \"grep\":\n return checkGrep(check, sandboxDir);\n case \"file-exists\":\n return checkFileExists(check, sandboxDir);\n case \"file-absent\":\n return checkFileAbsent(check, sandboxDir);\n case \"max-lines\":\n return checkMaxLines(check, sandboxDir);\n case \"custom\":\n return false;\n default:\n return false;\n }\n}\n\n// ─── Individual Check Implementations ───\n\nasync function checkGrep(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n if (!check.pattern) return false;\n try {\n const content = await readFile(join(sandboxDir, check.target), \"utf-8\");\n let found: boolean;\n try {\n found = new RegExp(check.pattern).test(content);\n } catch {\n return false; // Invalid regex\n }\n return check.expect === \"present\" ? found : !found;\n } catch {\n return check.expect === \"absent\";\n }\n}\n\nasync function checkFileExists(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n try {\n await readFile(join(sandboxDir, check.target));\n return check.expect === \"present\";\n } catch {\n return check.expect === \"absent\";\n }\n}\n\nasync function checkFileAbsent(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n try {\n await readFile(join(sandboxDir, check.target));\n return check.expect === \"absent\";\n } catch {\n return check.expect === \"present\";\n }\n}\n\nasync function checkMaxLines(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n const maxLines = parseInt(check.pattern ?? \"800\", 10);\n try {\n const files = await listAllFiles(join(sandboxDir, check.target));\n for (const file of files) {\n const content = await readFile(file, \"utf-8\");\n if (content.split(\"\\n\").length > maxLines) {\n return check.expect === \"absent\";\n }\n }\n return check.expect === \"present\";\n } catch {\n return check.expect === \"absent\";\n }\n}\n\n// ─── Utilities ───\n\nasync function listAllFiles(dir: string): Promise<string[]> {\n const results: string[] = [];\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...await listAllFiles(fullPath));\n } else {\n results.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist\n }\n return results;\n}\n","import { Command } from \"commander\";\nimport { spawn, execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { printBanner, log } from \"../../lib/output.js\";\n\nconst execAsync = promisify(execFile);\n\nconst ENHANCE_PROMPT = `Read CLAUDE.md and the project's codebase, then update CLAUDE.md to fill in missing or incomplete sections.\n\nCRITICAL BUDGET RULE: CLAUDE.md must stay UNDER 120 lines of actionable content (not counting headings, blank lines, or comments). Claude Code starts ignoring rules past ~150 instructions. If you need more detail, create .claude/rules/ files instead:\n- Create .claude/rules/conventions.md for detailed coding patterns\n- Create .claude/rules/architecture.md for detailed structure docs\n- Keep CLAUDE.md to HIGH-LEVEL summaries only (3-5 bullets per section max)\n\nSections to fill in or preserve (DO NOT remove any existing section):\n1. **## Stack** — if missing or incomplete, detect and add language, framework, package manager\n2. **## Architecture** — 3-5 bullet points describing the codebase shape (not a full directory tree)\n3. **## Conventions** — max 8 key patterns. Move detailed rules to .claude/rules/conventions.md\n4. **## Off-Limits** — max 8 guardrails specific to this project\n5. **## Key Decisions** — only decisions that affect how Claude should work in this codebase\n6. **MCP server suggestions** — look at what external services the project uses (databases, APIs, storage). If you spot Postgres, Redis, Stripe, GitHub API, or similar, suggest relevant MCP servers the user could add. Print these as suggestions at the end, not in CLAUDE.md.\n\nAlso review .claude/settings.json hooks:\n- Read the existing hooks in .claude/settings.json\n- If you see project-specific patterns that deserve hooks (e.g., protected directories, test file patterns, migration files), suggest adding them\n- DO NOT overwrite existing hooks — only add new ones that are specific to this project\n- Print hook suggestions at the end with the exact JSON to add, don't modify settings.json directly\n\nRules:\n- Don't remove existing content — only add or improve\n- Be specific to THIS project, not generic advice\n- Use bullet points, not paragraphs\n- If a section would exceed 8 bullets, split into a .claude/rules/ file and reference it\n- After editing, count the actionable lines. If over 120, move content to rules files until under`;\n\nexport function createEnhanceCommand(): Command {\n return new Command(\"enhance\")\n .description(\"Use Claude to analyze your codebase and complete CLAUDE.md\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .action(async (opts) => {\n printBanner();\n\n const root = opts.path;\n\n // Check CLAUDE.md exists\n const claudeMdPath = join(root, \"CLAUDE.md\");\n try {\n await access(claudeMdPath);\n } catch {\n log.error(\"No CLAUDE.md found. Run `claude-launchpad init` first.\");\n process.exit(1);\n }\n\n // Check Claude CLI is available\n try {\n await execAsync(\"claude\", [\"--version\"]);\n } catch {\n log.error(\"Claude CLI not found. Install it: https://docs.anthropic.com/en/docs/claude-code\");\n process.exit(1);\n }\n\n log.step(\"Launching Claude to enhance your CLAUDE.md...\");\n log.blank();\n\n const child = spawn(\n \"claude\",\n [ENHANCE_PROMPT],\n { cwd: root, stdio: \"inherit\" },\n );\n\n await new Promise<number>((resolve) => {\n child.on(\"close\", (code) => resolve(code ?? 0));\n });\n\n log.blank();\n log.success(\"Run `claude-launchpad doctor` to check your updated score.\");\n });\n}\n"],"mappings":"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","names":["Command","join","readFile","join","readdir","join","readFile","Command","access","join","join","access","readFile","basename","join","join","readFile","basename","access","readFile","writeFile","mkdir","access","join","join","readFile","writeFile","access","mkdir","readdir","join","join","readdir","Command","overallScore","Command","chalk","mkdir","writeFile","join","readFile","readdir","access","join","resolve","dirname","dirname","resolve","access","join","readFile","readdir","mkdir","writeFile","readFile","readdir","join","dirname","Command","chalk","join","mkdir","writeFile","execFile","promisify","exec","Command","execFile","promisify","access","join","promisify","execFile","Command","join","access","resolve","Command","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/init/index.ts","../src/lib/output.ts","../src/lib/fs-utils.ts","../src/lib/detect.ts","../src/commands/init/generators/claude-md.ts","../src/commands/init/generators/tasks-md.ts","../src/commands/init/generators/settings.ts","../src/commands/init/generators/claudeignore.ts","../src/commands/doctor/index.ts","../src/lib/parser.ts","../src/commands/doctor/analyzers/budget.ts","../src/commands/doctor/analyzers/settings.ts","../src/commands/doctor/analyzers/hooks.ts","../src/commands/doctor/analyzers/rules.ts","../src/commands/doctor/analyzers/permissions.ts","../src/commands/doctor/analyzers/mcp.ts","../src/commands/doctor/analyzers/quality.ts","../src/commands/doctor/fixer.ts","../src/commands/doctor/watcher.ts","../src/commands/eval/index.ts","../src/commands/eval/loader.ts","../src/commands/eval/schema.ts","../src/commands/eval/runner.ts","../src/commands/enhance/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { join } from \"node:path\";\nimport { createInitCommand } from \"./commands/init/index.js\";\nimport { createDoctorCommand } from \"./commands/doctor/index.js\";\nimport { createEvalCommand } from \"./commands/eval/index.js\";\nimport { createEnhanceCommand } from \"./commands/enhance/index.js\";\nimport { printBanner, log } from \"./lib/output.js\";\nimport { fileExists } from \"./lib/fs-utils.js\";\n\nconst program = new Command()\n .name(\"claude-launchpad\")\n .description(\"CLI toolkit that makes Claude Code setups measurably good\")\n .version(\"0.4.0\", \"-v, --version\")\n .action(async () => {\n // Default behavior: detect existing config and route accordingly\n const hasConfig = await fileExists(join(process.cwd(), \"CLAUDE.md\"))\n || await fileExists(join(process.cwd(), \".claude\", \"settings.json\"));\n\n if (hasConfig) {\n // Route directly to doctor — it prints its own banner\n await program.commands.find((c) => c.name() === \"doctor\")?.parseAsync([], { from: \"user\" });\n } else {\n printBanner();\n log.info(\"No Claude Code config found in this directory.\");\n log.blank();\n log.step(\"Run `claude-launchpad init` to set up your project\");\n log.step(\"Run `claude-launchpad doctor` to diagnose an existing config\");\n log.step(\"Run `claude-launchpad eval` to test your config quality\");\n log.blank();\n }\n });\n\nprogram.addCommand(createInitCommand());\nprogram.addCommand(createDoctorCommand());\nprogram.addCommand(createEnhanceCommand());\nprogram.addCommand(createEvalCommand());\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport { writeFile, mkdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { printBanner, log } from \"../../lib/output.js\";\nimport { fileExists } from \"../../lib/fs-utils.js\";\nimport { detectProject } from \"../../lib/detect.js\";\nimport type { InitOptions, DetectedProject } from \"../../types/index.js\";\nimport { generateClaudeMd } from \"./generators/claude-md.js\";\nimport { generateTasksMd } from \"./generators/tasks-md.js\";\nimport { generateSettings } from \"./generators/settings.js\";\nimport { generateClaudeignore } from \"./generators/claudeignore.js\";\n\nexport function createInitCommand(): Command {\n return new Command(\"init\")\n .description(\"Set up Claude Code configuration for any project\")\n .option(\"-n, --name <name>\", \"Project name\")\n .option(\"-y, --yes\", \"Accept all defaults\")\n .action(async (opts) => {\n printBanner();\n\n const root = process.cwd();\n\n // Detect what kind of project this is\n log.step(\"Detecting project...\");\n const detected = await detectProject(root);\n\n if (detected.language) {\n log.success(`Found ${detected.framework ?? detected.language} project`);\n if (detected.packageManager) log.info(`Package manager: ${detected.packageManager}`);\n if (detected.devCommand) log.info(`Dev command: ${detected.devCommand}`);\n if (detected.testCommand) log.info(`Test command: ${detected.testCommand}`);\n } else {\n log.warn(\"Could not detect project type — generating minimal config\");\n }\n log.blank();\n\n // Resolve options\n const name = opts.name ?? detected.name ?? await input({\n message: \"Project name:\",\n validate: (v: string) => (v.trim().length > 0 ? true : \"Name cannot be empty\"),\n });\n\n const description = opts.yes ? \"\" : await input({\n message: \"One-line description (optional):\",\n });\n\n const options: InitOptions = { name: name.trim(), description: description.trim() };\n\n // Check for existing files\n const hasClaudeMd = await fileExists(join(root, \"CLAUDE.md\"));\n if (hasClaudeMd && !opts.yes) {\n const overwrite = await confirm({\n message: \"CLAUDE.md already exists. Overwrite?\",\n default: false,\n });\n if (!overwrite) {\n log.info(\"Keeping existing CLAUDE.md\");\n log.step(\"Tip: run `claude-launchpad doctor` to check your existing config\");\n return;\n }\n }\n\n await scaffold(root, options, detected);\n });\n}\n\nasync function scaffold(root: string, options: InitOptions, detected: DetectedProject): Promise<void> {\n log.step(\"Generating configuration...\");\n\n const claudeMd = generateClaudeMd(options, detected);\n const tasksMd = generateTasksMd(options);\n const settings = generateSettings(detected);\n const claudeignore = generateClaudeignore(detected);\n\n await mkdir(join(root, \".claude\", \"rules\"), { recursive: true });\n\n // Merge with existing settings.json instead of overwriting\n const settingsPath = join(root, \".claude\", \"settings.json\");\n const mergedSettings = await mergeSettings(settingsPath, settings as unknown as Record<string, unknown>);\n\n // Only generate files that don't exist yet\n const claudeignorePath = join(root, \".claudeignore\");\n const hasClaudeignore = await fileExists(claudeignorePath);\n const claudeGitignorePath = join(root, \".claude\", \".gitignore\");\n const hasClaudeGitignore = await fileExists(claudeGitignorePath);\n const rulesPath = join(root, \".claude\", \"rules\", \"conventions.md\");\n const hasRules = await fileExists(rulesPath);\n\n const writes: Promise<void>[] = [\n writeFile(join(root, \"CLAUDE.md\"), claudeMd),\n writeFile(join(root, \"TASKS.md\"), tasksMd),\n writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2) + \"\\n\"),\n ];\n\n if (!hasClaudeignore) {\n writes.push(writeFile(claudeignorePath, claudeignore));\n }\n\n if (!hasClaudeGitignore) {\n writes.push(writeFile(claudeGitignorePath, [\n \"# Local-only Claude Code files (never commit these)\",\n \"settings.local.json\",\n \"plans/\",\n \"memory/\",\n \"sessions/\",\n \"tmp/\",\n \"\",\n ].join(\"\\n\")));\n }\n\n if (!hasRules) {\n const rulesContent = generateStarterRules(detected);\n writes.push(writeFile(rulesPath, rulesContent));\n }\n\n await Promise.all(writes);\n\n log.success(\"Generated CLAUDE.md\");\n log.success(\"Generated TASKS.md\");\n log.success(\"Generated .claude/settings.json (schema, permissions, hooks)\");\n if (!hasClaudeGitignore) log.success(\"Generated .claude/.gitignore\");\n if (!hasClaudeignore) log.success(\"Generated .claudeignore\");\n if (!hasRules) log.success(\"Generated .claude/rules/conventions.md\");\n\n log.blank();\n log.success(\"Done! Run `claude` to start.\");\n log.info(\"Run `claude-launchpad doctor` to check your config quality.\");\n log.blank();\n}\n\nfunction generateStarterRules(detected: DetectedProject): string {\n const lines = [\n \"# Project Conventions\",\n \"\",\n \"- Use conventional commits (feat:, fix:, docs:, refactor:, test:, chore:)\",\n \"- Keep files under 400 lines, functions under 50 lines\",\n \"- Handle errors explicitly - no empty catch blocks\",\n \"- Validate input at system boundaries\",\n ];\n\n if (detected.language === \"TypeScript\" || detected.language === \"JavaScript\") {\n lines.push(\"- Use named exports, no default exports except Next.js pages\");\n lines.push(\"- No `any` types in TypeScript\");\n }\n\n if (detected.language === \"Python\") {\n lines.push(\"- Type hints on all function signatures\");\n lines.push(\"- Async everywhere for I/O operations\");\n }\n\n if (detected.language === \"Go\") {\n lines.push(\"- Table-driven tests\");\n lines.push(\"- Errors are values - handle them, don't ignore them\");\n }\n\n if (detected.language === \"Rust\") {\n lines.push(\"- Prefer Result over unwrap/expect in library code\");\n lines.push(\"- No unsafe blocks without a safety comment\");\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n\nasync function mergeSettings(\n existingPath: string,\n generated: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n try {\n const existing = JSON.parse(await readFile(existingPath, \"utf-8\")) as Record<string, unknown>;\n\n // Merge hooks: keep existing hooks, add generated ones that don't conflict\n const existingHooks = (existing.hooks ?? {}) as Record<string, unknown[]>;\n const generatedHooks = (generated.hooks ?? {}) as Record<string, unknown[]>;\n\n const mergedHooks: Record<string, unknown[]> = { ...existingHooks };\n for (const [event, hookList] of Object.entries(generatedHooks)) {\n if (!mergedHooks[event]) {\n mergedHooks[event] = hookList;\n }\n // If event already exists, keep existing (don't duplicate)\n }\n\n return {\n ...existing,\n ...generated,\n hooks: Object.keys(mergedHooks).length > 0 ? mergedHooks : undefined,\n };\n } catch {\n // No existing file — just use generated\n return generated;\n }\n}\n","import chalk from \"chalk\";\nimport type { Severity, AnalyzerResult, DiagnosticIssue } from \"../types/index.js\";\n\n// ─── Colors ───\n\nexport const colors = {\n success: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n info: chalk.cyan,\n dim: chalk.dim,\n bold: chalk.bold,\n score: (score: number): string => {\n if (score >= 80) return chalk.green.bold(`${score}%`);\n if (score >= 60) return chalk.yellow.bold(`${score}%`);\n return chalk.red.bold(`${score}%`);\n },\n severity: (sev: Severity): string => {\n const map: Record<Severity, (s: string) => string> = {\n critical: chalk.bgRed.white.bold,\n high: chalk.red.bold,\n medium: chalk.yellow,\n low: chalk.cyan,\n info: chalk.dim,\n };\n return map[sev](` ${sev.toUpperCase()} `);\n },\n} as const;\n\n// ─── Prefixed Output ───\n\nexport const log = {\n success: (msg: string): void => console.log(` ${chalk.green(\"✓\")} ${msg}`),\n error: (msg: string): void => console.log(` ${chalk.red(\"✗\")} ${msg}`),\n warn: (msg: string): void => console.log(` ${chalk.yellow(\"!\")} ${msg}`),\n step: (msg: string): void => console.log(` ${chalk.cyan(\"→\")} ${msg}`),\n info: (msg: string): void => console.log(` ${chalk.dim(\"·\")} ${msg}`),\n blank: (): void => console.log(),\n} as const;\n\n// ─── Banner ───\n\nexport function printBanner(): void {\n log.blank();\n console.log(chalk.cyan.bold(\" Claude Launchpad\"));\n console.log(chalk.dim(\" Scaffold · Diagnose · Evaluate\"));\n log.blank();\n}\n\n// ─── Score Display ───\n\nexport function printScoreCard(label: string, score: number, max: number = 100): void {\n const pct = Math.round((score / max) * 100);\n const bar = renderBar(pct, 20);\n console.log(` ${chalk.bold(label.padEnd(22))} ${bar} ${colors.score(pct).padStart(12)}`);\n}\n\nfunction renderBar(pct: number, width: number): string {\n const filled = Math.round((pct / 100) * width);\n const empty = width - filled;\n const color = pct >= 80 ? chalk.green : pct >= 60 ? chalk.yellow : chalk.red;\n return color(\"━\".repeat(filled)) + chalk.dim(\"─\".repeat(empty));\n}\n\n// ─── Issues List (replaces table) ───\n\nexport function printIssue(severity: Severity, analyzer: string, message: string, fix?: string): void {\n const tag = colors.severity(severity);\n console.log(` ${tag} ${chalk.bold(analyzer)}`);\n console.log(` ${message}`);\n if (fix) {\n console.log(` ${chalk.dim(\"Fix:\")} ${chalk.dim(fix)}`);\n }\n console.log();\n}\n\n// ─── Report Rendering (shared by doctor + watcher) ───\n\nexport function renderDoctorReport(results: ReadonlyArray<AnalyzerResult>): {\n overallScore: number;\n actionableCount: number;\n} {\n const overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n\n for (const result of results) {\n printScoreCard(result.name, result.score);\n }\n log.blank();\n printScoreCard(\"Overall\", overallScore);\n log.blank();\n\n const allIssues = results.flatMap((r) => r.issues);\n const actionable = allIssues.filter((i) => i.severity !== \"info\");\n\n if (actionable.length === 0) {\n log.success(\"No issues found. Your configuration looks solid.\");\n return { overallScore, actionableCount: 0 };\n }\n\n const sorted = [...actionable].sort((a, b) => {\n const order: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };\n return (order[a.severity] ?? 4) - (order[b.severity] ?? 4);\n });\n\n for (const issue of sorted) {\n printIssue(issue.severity, issue.analyzer, issue.message, issue.fix);\n }\n\n log.info(`${actionable.length} issue(s) found. Fix critical/high first.`);\n return { overallScore, actionableCount: actionable.length };\n}\n","import { readFile, access } from \"node:fs/promises\";\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readFileOrNull(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nexport async function readJsonOrNull<T>(path: string): Promise<T | null> {\n try {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n","import { join, basename } from \"node:path\";\nimport { fileExists, readFileOrNull, readJsonOrNull } from \"./fs-utils.js\";\nimport type { DetectedProject } from \"../types/index.js\";\n\n/**\n * Detect project characteristics by scanning manifest files and directory structure.\n * Works with any stack — no hardcoded list of supported frameworks.\n */\nexport async function detectProject(root: string): Promise<DetectedProject> {\n const name = basename(root);\n\n const [pkgJson, goMod, pyProject, gemfile, cargo, pubspec, composerJson, pomXml, buildGradle, packageSwift, mixExs, csproj, lockfiles] = await Promise.all([\n readJsonOrNull<PackageJson>(join(root, \"package.json\")),\n fileExists(join(root, \"go.mod\")),\n readFileOrNull(join(root, \"pyproject.toml\")),\n fileExists(join(root, \"Gemfile\")),\n fileExists(join(root, \"Cargo.toml\")),\n fileExists(join(root, \"pubspec.yaml\")),\n readJsonOrNull<ComposerJson>(join(root, \"composer.json\")),\n fileExists(join(root, \"pom.xml\")),\n fileExists(join(root, \"build.gradle\")) || fileExists(join(root, \"build.gradle.kts\")),\n fileExists(join(root, \"Package.swift\")),\n fileExists(join(root, \"mix.exs\")),\n globExists(root, \"*.csproj\"),\n detectLockfiles(root),\n ]);\n\n const manifests: ManifestState = {\n pkgJson, goMod, pyProject, gemfile, cargo, pubspec,\n composerJson, pomXml, buildGradle, packageSwift, mixExs, csproj,\n };\n\n const language = detectLanguage(manifests);\n const framework = detectFramework(manifests);\n const packageManager = detectPackageManager(manifests, lockfiles);\n const scripts = detectScripts({ pkgJson, pyProject, goMod, gemfile, composerJson, language });\n\n return {\n name,\n language,\n framework,\n packageManager,\n hasTests: scripts.testCommand !== null,\n hasLinter: scripts.lintCommand !== null,\n hasFormatter: scripts.formatCommand !== null,\n ...scripts,\n };\n}\n\n// ─── Language Detection ───\n\ninterface ManifestState {\n pkgJson: PackageJson | null;\n goMod: boolean;\n pyProject: string | null;\n gemfile: boolean;\n cargo: boolean;\n pubspec: boolean;\n composerJson: ComposerJson | null;\n pomXml: boolean;\n buildGradle: boolean;\n packageSwift: boolean;\n mixExs: boolean;\n csproj: boolean;\n}\n\nfunction detectLanguage(m: ManifestState): string | null {\n if (m.pkgJson?.devDependencies?.typescript || m.pkgJson?.dependencies?.typescript) return \"TypeScript\";\n if (m.pkgJson) return \"JavaScript\";\n if (m.goMod) return \"Go\";\n if (m.pyProject) return \"Python\";\n if (m.gemfile) return \"Ruby\";\n if (m.cargo) return \"Rust\";\n if (m.pubspec) return \"Dart\";\n if (m.composerJson) return \"PHP\";\n if (m.buildGradle) return \"Kotlin\";\n if (m.pomXml) return \"Java\";\n if (m.packageSwift) return \"Swift\";\n if (m.mixExs) return \"Elixir\";\n if (m.csproj) return \"C#\";\n return null;\n}\n\n// ─── Framework Detection ───\n\nfunction detectFramework(m: ManifestState): string | null {\n const deps = { ...m.pkgJson?.dependencies, ...m.pkgJson?.devDependencies };\n\n // JS/TS frameworks\n if (deps.next) return \"Next.js\";\n if (deps.nuxt) return \"Nuxt\";\n if (deps.svelte || deps[\"@sveltejs/kit\"]) return \"SvelteKit\";\n if (deps.astro) return \"Astro\";\n if (deps[\"@angular/core\"]) return \"Angular\";\n if (deps.remix || deps[\"@remix-run/react\"]) return \"Remix\";\n if (deps.vue) return \"Vue\";\n if (deps.react && !deps.next) return \"React\";\n if (deps.express) return \"Express\";\n if (deps.fastify) return \"Fastify\";\n if (deps.hono) return \"Hono\";\n if (deps.nestjs || deps[\"@nestjs/core\"]) return \"NestJS\";\n\n // Python frameworks\n if (m.pyProject) {\n if (m.pyProject.includes(\"fastapi\")) return \"FastAPI\";\n if (m.pyProject.includes(\"django\")) return \"Django\";\n if (m.pyProject.includes(\"flask\")) return \"Flask\";\n }\n\n // PHP frameworks\n if (m.composerJson) {\n const phpDeps = { ...m.composerJson.require, ...m.composerJson[\"require-dev\"] };\n if (phpDeps[\"laravel/framework\"]) return \"Laravel\";\n if (phpDeps[\"symfony/framework-bundle\"]) return \"Symfony\";\n }\n\n // Ruby\n if (m.gemfile) return \"Rails\";\n\n // JVM\n if (m.buildGradle) return \"Gradle\"; // Could be Spring Boot, Android, etc.\n if (m.pomXml) return \"Maven\";\n\n return null;\n}\n\n// ─── Package Manager Detection ───\n\ninterface DetectedLockfiles {\n pnpmLock: boolean;\n yarnLock: boolean;\n bunLock: boolean;\n npmLock: boolean;\n}\n\nasync function detectLockfiles(root: string): Promise<DetectedLockfiles> {\n const [pnpmLock, yarnLock, bunLock, npmLock] = await Promise.all([\n fileExists(join(root, \"pnpm-lock.yaml\")),\n fileExists(join(root, \"yarn.lock\")),\n fileExists(join(root, \"bun.lockb\")),\n fileExists(join(root, \"package-lock.json\")),\n ]);\n return { pnpmLock, yarnLock, bunLock, npmLock };\n}\n\nfunction detectPackageManager(\n m: Pick<ManifestState, \"pkgJson\" | \"goMod\" | \"pyProject\" | \"gemfile\" | \"cargo\" | \"composerJson\">,\n lockfiles: DetectedLockfiles,\n): string | null {\n if (m.pkgJson) {\n // Check packageManager field first (most explicit)\n const pm = m.pkgJson.packageManager;\n if (pm?.startsWith(\"pnpm\")) return \"pnpm\";\n if (pm?.startsWith(\"yarn\")) return \"yarn\";\n if (pm?.startsWith(\"bun\")) return \"bun\";\n if (pm?.startsWith(\"npm\")) return \"npm\";\n\n // Fall back to lockfile detection\n if (lockfiles.pnpmLock) return \"pnpm\";\n if (lockfiles.yarnLock) return \"yarn\";\n if (lockfiles.bunLock) return \"bun\";\n if (lockfiles.npmLock) return \"npm\";\n\n return \"npm\";\n }\n if (m.goMod) return \"go modules\";\n if (m.pyProject) {\n if (m.pyProject.includes(\"[tool.uv]\")) return \"uv\";\n if (m.pyProject.includes(\"[tool.poetry]\")) return \"poetry\";\n return \"pip\";\n }\n if (m.gemfile) return \"bundler\";\n if (m.cargo) return \"cargo\";\n if (m.composerJson) return \"composer\";\n return null;\n}\n\n// ─── Script Detection ───\n\ninterface DetectedScripts {\n formatCommand: string | null;\n lintCommand: string | null;\n testCommand: string | null;\n devCommand: string | null;\n buildCommand: string | null;\n}\n\n// Language → default scripts config\nconst LANGUAGE_SCRIPTS: Record<string, DetectedScripts> = {\n Go: { devCommand: \"go run .\", buildCommand: \"go build .\", testCommand: \"go test ./...\", lintCommand: \"golangci-lint run\", formatCommand: \"gofmt -w .\" },\n Ruby: { devCommand: \"bin/dev\", buildCommand: null, testCommand: \"bin/rails test\", lintCommand: \"bin/rubocop\", formatCommand: null },\n PHP: { devCommand: \"php artisan serve\", buildCommand: null, testCommand: \"php artisan test\", lintCommand: \"vendor/bin/phpstan analyse\", formatCommand: \"vendor/bin/pint\" },\n Rust: { devCommand: \"cargo run\", buildCommand: \"cargo build\", testCommand: \"cargo test\", lintCommand: \"cargo clippy\", formatCommand: \"cargo fmt\" },\n Java: { devCommand: null, buildCommand: \"mvn package\", testCommand: \"mvn test\", lintCommand: null, formatCommand: null },\n Kotlin: { devCommand: null, buildCommand: \"mvn package\", testCommand: \"mvn test\", lintCommand: null, formatCommand: null },\n Swift: { devCommand: null, buildCommand: \"swift build\", testCommand: \"swift test\", lintCommand: \"swiftlint\", formatCommand: \"swift-format format -r .\" },\n Elixir: { devCommand: \"mix phx.server\", buildCommand: \"mix compile\", testCommand: \"mix test\", lintCommand: \"mix credo\", formatCommand: \"mix format\" },\n \"C#\": { devCommand: \"dotnet run\", buildCommand: \"dotnet build\", testCommand: \"dotnet test\", lintCommand: null, formatCommand: \"dotnet format\" },\n};\n\nfunction detectScripts(m: {\n pkgJson: PackageJson | null;\n pyProject: string | null;\n goMod: boolean;\n gemfile: boolean;\n composerJson: ComposerJson | null;\n language: string | null;\n}): DetectedScripts {\n // JS/TS: read from package.json scripts\n if (m.pkgJson) {\n const scripts = m.pkgJson.scripts ?? {};\n const run = pmRun(m.pkgJson);\n return {\n devCommand: scripts.dev ? `${run} dev` : null,\n buildCommand: scripts.build ? `${run} build` : null,\n testCommand: scripts.test ? `${run} test` : null,\n lintCommand: scripts.lint ? `${run} lint` : null,\n formatCommand: scripts.format ? `${run} format` : null,\n };\n }\n\n // Python: runner depends on uv vs pip\n if (m.language === \"Python\") {\n const r = m.pyProject?.includes(\"[tool.uv]\") ? \"uv run\" : \"python -m\";\n return { devCommand: null, buildCommand: null, testCommand: `${r} pytest`, lintCommand: `${r} ruff check .`, formatCommand: `${r} ruff format .` };\n }\n\n // Everything else: lookup table\n if (m.language && LANGUAGE_SCRIPTS[m.language]) {\n return LANGUAGE_SCRIPTS[m.language];\n }\n\n return { devCommand: null, buildCommand: null, testCommand: null, lintCommand: null, formatCommand: null };\n}\n\nfunction pmRun(pkg: PackageJson): string {\n const pm = pkg.packageManager;\n if (pm?.startsWith(\"pnpm\")) return \"pnpm\";\n if (pm?.startsWith(\"yarn\")) return \"yarn\";\n if (pm?.startsWith(\"bun\")) return \"bun\";\n return \"npm run\";\n}\n\n// ─── Utilities ───\n\ninterface PackageJson {\n name?: string;\n packageManager?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\ninterface ComposerJson {\n require?: Record<string, string>;\n \"require-dev\"?: Record<string, string>;\n}\n\nasync function globExists(dir: string, pattern: string): Promise<boolean> {\n const { readdir } = await import(\"node:fs/promises\");\n try {\n const entries = await readdir(dir);\n return entries.some((e) => e.endsWith(pattern.replace(\"*\", \"\")));\n } catch {\n return false;\n }\n}\n","import type { InitOptions, DetectedProject } from \"../../../types/index.js\";\n\nexport function generateClaudeMd(options: InitOptions, detected: DetectedProject): string {\n const sections: string[] = [];\n\n // Header\n sections.push(`# ${options.name}`);\n if (options.description) {\n sections.push(\"\", options.description);\n }\n\n // Stack (auto-detected)\n sections.push(\"\", \"## Stack\");\n if (detected.language) {\n const items: string[] = [];\n if (detected.framework) items.push(`- **Framework**: ${detected.framework}`);\n items.push(`- **Language**: ${detected.language}`);\n if (detected.packageManager) items.push(`- **Package Manager**: ${detected.packageManager}`);\n sections.push(items.join(\"\\n\"));\n } else {\n sections.push(\"<!-- TODO: Define your tech stack -->\");\n }\n\n // Commands (auto-detected)\n sections.push(\"\", \"## Commands\");\n const commands: string[] = [];\n if (detected.devCommand) commands.push(`- Dev: \\`${detected.devCommand}\\``);\n if (detected.buildCommand) commands.push(`- Build: \\`${detected.buildCommand}\\``);\n if (detected.testCommand) commands.push(`- Test: \\`${detected.testCommand}\\``);\n if (detected.lintCommand) commands.push(`- Lint: \\`${detected.lintCommand}\\``);\n if (detected.formatCommand) commands.push(`- Format: \\`${detected.formatCommand}\\``);\n if (commands.length > 0) {\n sections.push(commands.join(\"\\n\"));\n } else {\n sections.push(\"<!-- TODO: Add your dev/build/test commands -->\");\n }\n\n // Session Start\n sections.push(\"\", `## Session Start\n- ALWAYS read @TASKS.md first — it tracks progress across sessions\n- Check the Session Log at the bottom of TASKS.md for where we left off\n- Update TASKS.md as you complete work`);\n\n // Conventions\n sections.push(\"\", `## Conventions\n- Git: Conventional commits (\\`feat:\\`, \\`fix:\\`, \\`docs:\\`, \\`refactor:\\`, \\`test:\\`, \\`chore:\\`)`);\n\n // Off-Limits\n sections.push(\"\", `## Off-Limits\n- Never hardcode secrets — use environment variables\n- Never write to \\`.env\\` files\n- Never expose internal error details in API responses`);\n\n // Key Decisions\n sections.push(\"\", `## Key Decisions\n<!-- Record architectural decisions as you make them -->`);\n\n return sections.join(\"\\n\") + \"\\n\";\n}\n","import type { InitOptions } from \"../../../types/index.js\";\n\nexport function generateTasksMd(options: InitOptions): string {\n return `# ${options.name} — Task Tracker\n\n> Claude: Read this at session start. Keep this file SHORT — only current state matters.\n> Rules: (1) Only show current + next sprint tasks. (2) Completed sprints get one summary line. (3) Session log: max 3 lines per session, keep only last 3 sessions. (4) Target: under 80 lines total.\n\n## Completed Sprints\n\n## Current Sprint: Sprint 1 — Setup\n\n### In Progress\n\n### To Do\n- [ ] Project scaffolding and environment setup\n- [ ] Core feature implementation\n- [ ] Test infrastructure\n\n### Done\n\n## Next Sprint: Sprint 2 — Core Features\n- [ ] ...\n\n## Session Log\n<!-- Keep last 3 sessions only. Max 3 lines each. -->\n`;\n}\n","import type { DetectedProject } from \"../../../types/index.js\";\n\ninterface HookEntry {\n readonly type: \"command\";\n readonly command: string;\n}\n\ninterface HookGroup {\n readonly matcher: string;\n readonly hooks: ReadonlyArray<HookEntry>;\n}\n\ninterface ClaudeSettings {\n readonly $schema?: string;\n readonly permissions?: {\n readonly deny?: ReadonlyArray<string>;\n };\n readonly hooks?: Record<string, ReadonlyArray<HookGroup>>;\n}\n\n/**\n * Generate .claude/settings.json based on detected project.\n * Includes: schema for IDE autocomplete, security deny-lists, hooks.\n */\nexport function generateSettings(detected: DetectedProject): ClaudeSettings {\n const preToolUse: HookGroup[] = [];\n const postToolUse: HookGroup[] = [];\n\n // Universal: .env file protection (block read + write)\n preToolUse.push({\n matcher: \"Read|Write|Edit\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -qE '\\\\.(env|env\\\\..*)$' && ! echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -q '.env.example' && echo 'BLOCKED: .env files contain secrets' && exit 1; exit 0\",\n }],\n });\n\n // Universal: block destructive commands\n preToolUse.push({\n matcher: \"Bash\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_COMMAND\\\" | grep -qE 'rm\\\\s+-rf\\\\s+/|DROP\\\\s+TABLE|DROP\\\\s+DATABASE|push.*--force|push.*-f' && echo 'BLOCKED: Destructive command detected' && exit 1; exit 0\",\n }],\n });\n\n // Auto-format based on detected tooling\n const formatHook = buildFormatHook(detected);\n if (formatHook) {\n postToolUse.push(formatHook);\n }\n\n const hooks: Record<string, ReadonlyArray<HookGroup>> = {};\n if (preToolUse.length > 0) hooks.PreToolUse = preToolUse;\n if (postToolUse.length > 0) hooks.PostToolUse = postToolUse;\n\n return {\n $schema: \"https://json.schemastore.org/claude-code-settings.json\",\n permissions: {\n deny: [\n \"Bash(rm -rf /)\",\n \"Bash(rm -rf ~)\",\n \"Read(.env)\",\n \"Read(.env.*)\",\n \"Read(secrets/**)\",\n ],\n },\n hooks,\n };\n}\n\n// Safe formatter commands - never interpolate user-controlled strings\nconst SAFE_FORMATTERS: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: { extensions: [\"ts\", \"tsx\"], command: \"npx prettier --write\" },\n JavaScript: { extensions: [\"js\", \"jsx\"], command: \"npx prettier --write\" },\n Python: { extensions: [\"py\"], command: \"ruff format\" },\n Go: { extensions: [\"go\"], command: \"gofmt -w\" },\n Rust: { extensions: [\"rs\"], command: \"rustfmt\" },\n Ruby: { extensions: [\"rb\"], command: \"rubocop -A\" },\n Dart: { extensions: [\"dart\"], command: \"dart format\" },\n PHP: { extensions: [\"php\"], command: \"vendor/bin/pint\" },\n Kotlin: { extensions: [\"kt\", \"kts\"], command: \"ktlint -F\" },\n Java: { extensions: [\"java\"], command: \"google-java-format -i\" },\n Swift: { extensions: [\"swift\"], command: \"swift-format format -i\" },\n Elixir: { extensions: [\"ex\", \"exs\"], command: \"mix format\" },\n \"C#\": { extensions: [\"cs\"], command: \"dotnet format\" },\n};\n\nfunction buildFormatHook(detected: DetectedProject): HookGroup | null {\n if (!detected.language) return null;\n\n const config = SAFE_FORMATTERS[detected.language];\n if (!config) return null;\n\n const extChecks = config.extensions\n .map((ext) => `[ \"$ext\" = \"${ext}\" ]`)\n .join(\" || \");\n\n return {\n matcher: \"Write|Edit\",\n hooks: [{\n type: \"command\",\n command: `ext=\\${TOOL_INPUT_FILE_PATH##*.}; (${extChecks}) && ${config.command} \"$TOOL_INPUT_FILE_PATH\" 2>/dev/null; exit 0`,\n }],\n };\n}\n","import type { DetectedProject } from \"../../../types/index.js\";\n\n/**\n * Generate .claudeignore based on detected project type.\n * Prevents Claude from reading noise files that waste context.\n */\nexport function generateClaudeignore(detected: DetectedProject): string {\n const sections: string[] = [\"# Generated by claude-launchpad\"];\n\n // Universal ignores\n sections.push(`\n# Dependencies\nnode_modules/\n.pnp/\n.yarn/\n\n# Build output\ndist/\nbuild/\nout/\n.next/\n.nuxt/\n.output/\n.svelte-kit/\n.vercel/\n.turbo/\n\n# Package manager\npnpm-lock.yaml\npackage-lock.json\nyarn.lock\nbun.lockb\n\n# IDE & OS\n.vscode/\n.idea/\n*.swp\n*.swo\n.DS_Store\nThumbs.db\n\n# Test & coverage\ncoverage/\n.nyc_output/\n__snapshots__/\n\n# Environment (should never be read)\n.env\n.env.*\n!.env.example`);\n\n // Language-specific ignores\n const lang = detected.language;\n\n if (lang === \"Python\") {\n sections.push(`\n# Python\n__pycache__/\n*.pyc\n*.pyo\n.venv/\nvenv/\n.mypy_cache/\n.ruff_cache/\n.pytest_cache/\n*.egg-info/`);\n }\n\n if (lang === \"Go\") {\n sections.push(`\n# Go\nbin/\nvendor/`);\n }\n\n if (lang === \"Rust\") {\n sections.push(`\n# Rust\ntarget/\nCargo.lock`);\n }\n\n if (lang === \"Ruby\") {\n sections.push(`\n# Ruby\nvendor/bundle/\n.bundle/\ntmp/\nlog/`);\n }\n\n if (lang === \"Java\" || lang === \"Kotlin\") {\n sections.push(`\n# JVM\ntarget/\nbuild/\n.gradle/\n*.class\n*.jar`);\n }\n\n if (lang === \"Dart\") {\n sections.push(`\n# Dart/Flutter\n.dart_tool/\n.packages\nbuild/`);\n }\n\n if (lang === \"PHP\") {\n sections.push(`\n# PHP\nvendor/\ncomposer.lock`);\n }\n\n if (lang === \"C#\") {\n sections.push(`\n# .NET\nbin/\nobj/\n*.dll`);\n }\n\n if (lang === \"Elixir\") {\n sections.push(`\n# Elixir\n_build/\ndeps/\n.elixir_ls/`);\n }\n\n if (lang === \"Swift\") {\n sections.push(`\n# Swift\n.build/\nDerivedData/\n*.xcuserdata`);\n }\n\n return sections.join(\"\\n\") + \"\\n\";\n}\n","import { Command } from \"commander\";\nimport { printBanner, log, renderDoctorReport } from \"../../lib/output.js\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { analyzeBudget } from \"./analyzers/budget.js\";\nimport { analyzeSettings } from \"./analyzers/settings.js\";\nimport { analyzeHooks } from \"./analyzers/hooks.js\";\nimport { analyzeRules } from \"./analyzers/rules.js\";\nimport { analyzePermissions } from \"./analyzers/permissions.js\";\nimport { analyzeMcp } from \"./analyzers/mcp.js\";\nimport { analyzeQuality } from \"./analyzers/quality.js\";\nimport { applyFixes } from \"./fixer.js\";\nimport { watchConfig } from \"./watcher.js\";\nimport type { AnalyzerResult } from \"../../types/index.js\";\n\nexport function createDoctorCommand(): Command {\n return new Command(\"doctor\")\n .description(\"Diagnose your Claude Code configuration and report issues\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .option(\"--json\", \"Output as JSON\")\n .option(\"--min-score <n>\", \"Exit non-zero if overall score is below this threshold (for CI)\")\n .option(\"--fix\", \"Auto-apply deterministic fixes for detected issues\")\n .option(\"--watch\", \"Watch for config changes and re-run automatically\")\n .action(async (opts) => {\n if (opts.watch) {\n await watchConfig(opts.path);\n return;\n }\n\n if (!opts.json) {\n printBanner();\n log.step(\"Scanning Claude Code configuration...\");\n log.blank();\n }\n\n const config = await parseClaudeConfig(opts.path);\n\n if (config.claudeMdContent === null && config.settings === null) {\n log.error(\"No Claude Code configuration found in this directory.\");\n log.info(\"Run `claude-launchpad init` to set up a project, or cd into a configured project.\");\n process.exit(1);\n }\n\n const results: AnalyzerResult[] = await Promise.all([\n analyzeBudget(config),\n analyzeQuality(config),\n analyzeSettings(config),\n analyzeHooks(config),\n analyzeRules(config),\n analyzePermissions(config),\n analyzeMcp(config),\n ]);\n\n if (opts.json) {\n const overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n console.log(JSON.stringify({ overallScore, analyzers: results, timestamp: new Date().toISOString() }, null, 2));\n return;\n }\n\n const { overallScore } = renderDoctorReport(results);\n\n // Auto-fix mode\n if (opts.fix) {\n const allIssues = results.flatMap((r) => r.issues);\n const fixable = allIssues.filter((i) => i.severity !== \"info\");\n if (fixable.length > 0) {\n log.blank();\n log.step(\"Applying fixes...\");\n log.blank();\n const { fixed, skipped } = await applyFixes(fixable, opts.path);\n log.blank();\n if (fixed > 0) {\n log.success(`Applied ${fixed} fix(es). Run \\`claude-launchpad doctor\\` again to see your new score.`);\n }\n if (skipped > 0) {\n log.info(`${skipped} issue(s) require manual intervention.`);\n }\n }\n }\n\n // CI mode: exit non-zero if score is below threshold\n if (opts.minScore) {\n const threshold = parseInt(opts.minScore, 10);\n if (overallScore < threshold) {\n process.exit(1);\n }\n }\n });\n}\n","import { readdir, access } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { readFileOrNull } from \"./fs-utils.js\";\nimport type { ClaudeConfig, HookConfig, McpServerConfig } from \"../types/index.js\";\n\nconst CLAUDE_MD = \"CLAUDE.md\";\nconst CLAUDE_DIR = \".claude\";\nconst SETTINGS_FILE = \"settings.json\";\nconst RULES_DIR = \"rules\";\n\nexport async function parseClaudeConfig(projectRoot: string): Promise<ClaudeConfig> {\n const root = resolve(projectRoot);\n const claudeDir = join(root, CLAUDE_DIR);\n\n const [claudeMd, settings, hooks, rules, mcpServers, skills] = await Promise.all([\n readClaudeMd(root),\n readSettings(claudeDir),\n readHooks(claudeDir),\n readRules(claudeDir),\n readMcpServers(claudeDir),\n readSkills(claudeDir),\n ]);\n\n const instructionCount = claudeMd\n ? countInstructions(claudeMd)\n : 0;\n\n return {\n claudeMdPath: claudeMd !== null ? join(root, CLAUDE_MD) : null,\n claudeMdContent: claudeMd,\n claudeMdInstructionCount: instructionCount,\n settingsPath: settings !== null ? join(claudeDir, SETTINGS_FILE) : null,\n settings,\n hooks,\n rules,\n mcpServers,\n skills,\n };\n}\n\n// ─── CLAUDE.md ───\n\nasync function readClaudeMd(root: string): Promise<string | null> {\n return readFileOrNull(join(root, CLAUDE_MD));\n}\n\n/**\n * Count actionable instructions in CLAUDE.md.\n * Heuristic: non-empty, non-comment, non-heading-only lines that contain\n * imperative/declarative content (not blank lines or markdown structure).\n */\nexport function countInstructions(content: string): number {\n const lines = content.split(\"\\n\");\n let count = 0;\n\n for (const line of lines) {\n const trimmed = line.trim();\n // Skip empty lines\n if (trimmed === \"\") continue;\n // Skip pure comments\n if (trimmed.startsWith(\"<!--\") && trimmed.endsWith(\"-->\")) continue;\n // Skip code fence markers\n if (trimmed.startsWith(\"```\")) continue;\n // Skip headings that are just section markers (no instruction content)\n if (/^#{1,6}\\s+\\S/.test(trimmed)) continue;\n // Everything else is an instruction\n count++;\n }\n\n return count;\n}\n\n// ─── Settings ───\n\nasync function readSettings(claudeDir: string): Promise<Record<string, unknown> | null> {\n const raw = await readFileOrNull(join(claudeDir, SETTINGS_FILE));\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n// ─── Hooks ───\n\nasync function readHooks(claudeDir: string): Promise<ReadonlyArray<HookConfig>> {\n const settingsRaw = await readFileOrNull(join(claudeDir, SETTINGS_FILE));\n if (settingsRaw === null) return [];\n\n try {\n const settings = JSON.parse(settingsRaw) as Record<string, unknown>;\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks || typeof hooks !== \"object\") return [];\n\n const result: HookConfig[] = [];\n for (const [event, hookList] of Object.entries(hooks)) {\n if (!Array.isArray(hookList)) continue;\n for (const group of hookList) {\n const g = group as Record<string, unknown>;\n const matcher = g.matcher as string | undefined;\n\n // New schema: { matcher, hooks: [{ type, command }] }\n const nestedHooks = g.hooks as Record<string, unknown>[] | undefined;\n if (Array.isArray(nestedHooks)) {\n for (const hook of nestedHooks) {\n const h = hook as Record<string, unknown>;\n result.push({\n event: event as HookConfig[\"event\"],\n type: (h.type as HookConfig[\"type\"]) ?? \"command\",\n matcher,\n command: h.command as string | undefined,\n });\n }\n } else {\n // Legacy flat schema: { matcher, type, command }\n result.push({\n event: event as HookConfig[\"event\"],\n type: (g.type as HookConfig[\"type\"]) ?? \"command\",\n matcher,\n command: g.command as string | undefined,\n });\n }\n }\n }\n return result;\n } catch {\n return [];\n }\n}\n\n// ─── Rules ───\n\nasync function readRules(claudeDir: string): Promise<ReadonlyArray<string>> {\n const rulesDir = join(claudeDir, RULES_DIR);\n return listFilesRecursive(rulesDir, \".md\");\n}\n\n// ─── MCP Servers ───\n\nasync function readMcpServers(claudeDir: string): Promise<ReadonlyArray<McpServerConfig>> {\n const settingsRaw = await readFileOrNull(join(claudeDir, SETTINGS_FILE));\n if (settingsRaw === null) return [];\n\n try {\n const settings = JSON.parse(settingsRaw) as Record<string, unknown>;\n const servers = settings.mcpServers as Record<string, unknown> | undefined;\n if (!servers || typeof servers !== \"object\") return [];\n\n const result: McpServerConfig[] = [];\n for (const [name, config] of Object.entries(servers)) {\n const c = config as Record<string, unknown>;\n result.push({\n name,\n transport: (c.transport as McpServerConfig[\"transport\"]) ?? \"stdio\",\n command: c.command as string | undefined,\n url: c.url as string | undefined,\n });\n }\n return result;\n } catch {\n return [];\n }\n}\n\n// ─── Skills ───\n\nasync function readSkills(claudeDir: string): Promise<ReadonlyArray<string>> {\n const commandsDir = join(claudeDir, \"commands\");\n const skillsDir = join(claudeDir, \"skills\");\n\n const [commands, skills] = await Promise.all([\n listFilesRecursive(commandsDir, \".md\"),\n listFilesRecursive(skillsDir, \".md\"),\n ]);\n\n return [...commands, ...skills];\n}\n\n\nasync function listFilesRecursive(dir: string, ext: string): Promise<string[]> {\n try {\n await access(dir);\n } catch {\n return [];\n }\n\n const results: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const nested = await listFilesRecursive(fullPath, ext);\n results.push(...nested);\n } else if (entry.name.endsWith(ext)) {\n results.push(fullPath);\n }\n }\n\n return results;\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nconst BUDGET_WARN = 120;\nconst BUDGET_DANGER = 150;\nconst BUDGET_CRITICAL = 200;\n\nexport async function analyzeBudget(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n const count = config.claudeMdInstructionCount;\n\n if (config.claudeMdContent === null) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"high\",\n message: \"No CLAUDE.md found\",\n fix: \"Run `claude-launchpad init` or create CLAUDE.md manually\",\n });\n return { name: \"Instruction Budget\", issues, score: 0 };\n }\n\n if (count === 0) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"medium\",\n message: \"CLAUDE.md exists but has no actionable instructions\",\n fix: \"Add project-specific instructions to CLAUDE.md\",\n });\n return { name: \"Instruction Budget\", issues, score: 30 };\n }\n\n if (count > BUDGET_CRITICAL) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"critical\",\n message: `${count} instructions — way over the ~150 budget. Compliance drops significantly past 150.`,\n fix: \"Move detailed rules to .claude/rules/*.md files. Keep CLAUDE.md to essential project identity.\",\n });\n } else if (count > BUDGET_DANGER) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"high\",\n message: `${count} instructions — over the ~150 budget. Claude may start ignoring lower-priority rules.`,\n fix: \"Move verbose sections (conventions, off-limits details) to .claude/rules/ files.\",\n });\n } else if (count > BUDGET_WARN) {\n issues.push({\n analyzer: \"Budget\",\n severity: \"medium\",\n message: `${count} instructions — approaching the ~150 budget.`,\n fix: \"Consider moving some rules to .claude/rules/ to leave headroom.\",\n });\n }\n\n // Score: 100 if under warn, scales down from there\n let score: number;\n if (count <= BUDGET_WARN) {\n score = 100;\n } else if (count <= BUDGET_DANGER) {\n score = 100 - Math.round(((count - BUDGET_WARN) / (BUDGET_DANGER - BUDGET_WARN)) * 30);\n } else if (count <= BUDGET_CRITICAL) {\n score = 70 - Math.round(((count - BUDGET_DANGER) / (BUDGET_CRITICAL - BUDGET_DANGER)) * 40);\n } else {\n score = Math.max(0, 30 - Math.round((count - BUDGET_CRITICAL) / 5));\n }\n\n return { name: \"Instruction Budget\", issues, score };\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeSettings(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n\n if (config.settings === null) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"medium\",\n message: \"No .claude/settings.json found\",\n fix: \"Run `claude-launchpad init` or create .claude/settings.json\",\n });\n return { name: \"Settings\", issues, score: 40 };\n }\n\n // Check for hooks (the most important setting)\n const hooks = config.settings.hooks as Record<string, unknown> | undefined;\n if (!hooks || Object.keys(hooks).length === 0) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"medium\",\n message: \"settings.json has no hooks configured\",\n fix: \"Run `claude-launchpad doctor --fix` to generate hooks\",\n });\n }\n\n // Plugins are optional — info only, doesn't affect score\n const plugins = config.settings.enabledPlugins as Record<string, boolean> | undefined;\n if (!plugins || Object.keys(plugins).length === 0) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"info\",\n message: \"No plugins enabled — plugins are optional but can add capabilities\",\n });\n }\n\n // Permission rules — only flag if allowedTools is set without security hooks\n const allowedTools = config.settings.allowedTools as string[] | undefined;\n if (allowedTools && allowedTools.length > 0 && config.hooks.length === 0) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"medium\",\n message: \"Tools auto-allowed without any hooks — no safety net for dangerous operations\",\n fix: \"Add PreToolUse hooks for security or remove allowedTools to use interactive prompting\",\n });\n }\n\n // Score: deduct for actionable issues only (not info)\n const actionableCount = issues.filter((i) => i.severity !== \"info\").length;\n const score = Math.max(0, 100 - actionableCount * 20);\n return { name: \"Settings\", issues, score };\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeHooks(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n const hooks = config.hooks;\n\n if (hooks.length === 0) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"medium\",\n message: \"No hooks configured — CLAUDE.md rules are advisory (~80% compliance), hooks are 100%\",\n fix: \"Add PostToolUse hooks for auto-formatting and PreToolUse for security gates\",\n });\n return { name: \"Hooks\", issues, score: 30 };\n }\n\n // Check for auto-format hook (prettier, ruff, gofmt, rustfmt, etc.)\n const formatPatterns = [\"format\", \"prettier\", \"gofmt\", \"rustfmt\", \"rubocop\", \"pint\", \"ktlint\", \"swift-format\", \"dotnet format\"];\n const hasPostFormat = hooks.some(\n (h) => h.event === \"PostToolUse\" && h.matcher?.includes(\"Write\") && formatPatterns.some((p) => h.command?.includes(p)),\n );\n if (!hasPostFormat) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"low\",\n message: \"No auto-format hook found\",\n fix: \"Add a PostToolUse hook that runs your formatter on Write|Edit\",\n });\n }\n\n // Check for security gate (env file protection)\n const hasEnvProtection = hooks.some(\n (h) => h.event === \"PreToolUse\" && h.command?.includes(\".env\"),\n );\n if (!hasEnvProtection) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"medium\",\n message: \"No .env file protection hook — Claude could read or write secrets in .env files\",\n fix: \"Add a PreToolUse hook on Read|Write|Edit that blocks access to .env files\",\n });\n }\n\n // Check for PreToolUse hooks (security layer)\n const hasPreToolUse = hooks.some((h) => h.event === \"PreToolUse\");\n if (!hasPreToolUse) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"medium\",\n message: \"No PreToolUse hooks — this is your security enforcement layer\",\n fix: \"Add PreToolUse hooks for file protection and dangerous command blocking\",\n });\n }\n\n const score = Math.max(0, 100 - issues.length * 20);\n return { name: \"Hooks\", issues, score };\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename, join, dirname } from \"node:path\";\nimport { fileExists } from \"../../../lib/fs-utils.js\";\nimport type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeRules(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n\n // Check for .claudeignore\n const projectRoot = config.claudeMdPath ? dirname(config.claudeMdPath) : process.cwd();\n const hasClaudeignore = await fileExists(join(projectRoot, \".claudeignore\"));\n if (!hasClaudeignore) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No .claudeignore found — Claude may read noise files (node_modules, dist, lockfiles)\",\n fix: \"Run `claude-launchpad init` or `doctor --fix` to generate one\",\n });\n }\n\n if (config.rules.length === 0) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No .claude/rules/ files found\",\n fix: \"Move detailed conventions from CLAUDE.md to .claude/rules/*.md (auto-loaded, saves budget)\",\n });\n return { name: \"Rules\", issues, score: 60 };\n }\n\n // Check for empty or near-empty rule files\n for (const rulePath of config.rules) {\n try {\n const content = await readFile(rulePath, \"utf-8\");\n const trimmed = content.trim();\n if (trimmed.length === 0) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: `Empty rule file: ${basename(rulePath)}`,\n fix: `Add content to ${basename(rulePath)} or delete it`,\n });\n } else if (trimmed.length < 20) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"info\",\n message: `Very short rule file (${trimmed.length} chars): ${basename(rulePath)}`,\n });\n }\n } catch {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: `Could not read rule file: ${basename(rulePath)}`,\n });\n }\n }\n\n const score = Math.max(0, 100 - issues.length * 10);\n return { name: \"Rules\", issues, score };\n}\n\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzePermissions(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n\n // Check if Bash is allowed without security hooks\n const hasBashSecurity = config.hooks.some(\n (h) => h.event === \"PreToolUse\" && (h.matcher?.includes(\"Bash\") || !h.matcher),\n );\n\n const bashAllowed = config.settings?.allowedTools as string[] | undefined;\n const hasBashAutoAllow = bashAllowed?.some((t) =>\n typeof t === \"string\" && t.toLowerCase().includes(\"bash\"),\n );\n\n if (hasBashAutoAllow && !hasBashSecurity) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: \"Bash is auto-allowed without a security hook — dangerous commands could run unchecked\",\n fix: \"Add a PreToolUse hook for Bash that blocks destructive commands (rm -rf, git push --force)\",\n });\n }\n\n // Check for force push protection\n const hasForceProtection = config.hooks.some(\n (h) => h.event === \"PreToolUse\" && h.command?.includes(\"force\"),\n );\n if (!hasForceProtection) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"low\",\n message: \"No force-push protection hook\",\n fix: \"Add a PreToolUse hook that warns on `git push --force` commands\",\n });\n }\n\n // Check CLAUDE.md for off-limits section\n if (config.claudeMdContent) {\n const hasOffLimits = config.claudeMdContent.includes(\"## Off-Limits\") ||\n config.claudeMdContent.includes(\"## off-limits\");\n if (!hasOffLimits) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"medium\",\n message: \"No Off-Limits section in CLAUDE.md — Claude has no guardrails beyond defaults\",\n fix: \"Add an ## Off-Limits section with project-specific restrictions\",\n });\n }\n }\n\n const score = Math.max(0, 100 - issues.length * 20);\n return { name: \"Permissions\", issues, score };\n}\n","import { access } from \"node:fs/promises\";\nimport type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeMcp(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n const servers = config.mcpServers;\n\n if (servers.length === 0) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"info\",\n message: \"No MCP servers configured. Run `claude-launchpad enhance` to get stack-specific recommendations.\",\n });\n return { name: \"MCP Servers\", issues, score: 50 };\n }\n\n for (const server of servers) {\n if (server.transport === \"stdio\" && !server.command) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"high\",\n message: `MCP server \"${server.name}\" uses stdio transport but has no command`,\n fix: `Add a \"command\" field to the \"${server.name}\" MCP server config`,\n });\n }\n\n if ((server.transport === \"sse\" || server.transport === \"http\") && !server.url) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"high\",\n message: `MCP server \"${server.name}\" uses ${server.transport} transport but has no URL`,\n fix: `Add a \"url\" field to the \"${server.name}\" MCP server config`,\n });\n }\n\n if (server.transport === \"stdio\" && server.command) {\n const executable = server.command.split(\" \")[0];\n if (executable.startsWith(\"/\") || executable.startsWith(\"./\")) {\n try {\n await access(executable);\n } catch {\n issues.push({\n analyzer: \"MCP\",\n severity: \"medium\",\n message: `MCP server \"${server.name}\" command not found: ${executable}`,\n fix: \"Verify the path exists or install the required package\",\n });\n }\n }\n }\n }\n\n const score = Math.max(0, 100 - issues.filter((i) => i.severity !== \"info\").length * 25);\n return { name: \"MCP Servers\", issues, score };\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nconst ESSENTIAL_SECTIONS = [\n { pattern: /^##\\s+(Tech )?Stack/m, name: \"Stack\", why: \"Claude performs worse without knowing the tech stack\" },\n { pattern: /^##\\s+Commands/m, name: \"Commands\", why: \"Claude guesses wrong without explicit dev/build/test commands\" },\n { pattern: /^##\\s+Session Start/m, name: \"Session Start\", why: \"Without this, Claude won't read TASKS.md or maintain continuity\" },\n { pattern: /^##\\s+Off.?Limits/m, name: \"Off-Limits\", why: \"Without guardrails, Claude has no boundaries beyond defaults\" },\n { pattern: /^##\\s+(Architecture|Project Structure)/m, name: \"Architecture/Structure\", why: \"Claude makes better decisions when it understands the codebase shape\" },\n] as const;\n\nconst VAGUE_PATTERNS = [\n { pattern: /write (good|clean|quality|nice) code/i, label: \"write good code\" },\n { pattern: /be (careful|thorough|diligent)/i, label: \"be careful\" },\n { pattern: /follow best practices/i, label: \"follow best practices\" },\n { pattern: /make sure (everything|it) works/i, label: \"make sure it works\" },\n] as const;\n\nconst SECRET_PATTERNS = [\n { pattern: /sk-[a-zA-Z0-9]{20,}/, label: \"OpenAI API key\" },\n { pattern: /ghp_[a-zA-Z0-9]{36}/, label: \"GitHub personal token\" },\n { pattern: /AKIA[0-9A-Z]{16}/, label: \"AWS access key\" },\n { pattern: /xoxb-[0-9]+-[a-zA-Z0-9]+/, label: \"Slack bot token\" },\n] as const;\n\nexport async function analyzeQuality(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n const content = config.claudeMdContent;\n\n if (content === null) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"high\",\n message: \"No CLAUDE.md found\",\n fix: \"Run `claude-launchpad init` to generate one\",\n });\n return { name: \"CLAUDE.md Quality\", issues, score: 0 };\n }\n\n // Check essential sections\n let sectionsFound = 0;\n for (const section of ESSENTIAL_SECTIONS) {\n if (section.pattern.test(content)) {\n sectionsFound++;\n } else {\n issues.push({\n analyzer: \"Quality\",\n severity: \"medium\",\n message: `Missing \"## ${section.name}\" section — ${section.why}`,\n fix: `Add a ## ${section.name} section to CLAUDE.md`,\n });\n }\n }\n\n // Check for vague/useless instructions\n for (const vague of VAGUE_PATTERNS) {\n if (vague.pattern.test(content)) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"low\",\n message: `Vague instruction detected: \"${vague.label}\" — zero signal, wastes budget`,\n fix: \"Replace with specific, actionable instructions\",\n });\n }\n }\n\n // Check for hardcoded secrets\n for (const secret of SECRET_PATTERNS) {\n if (secret.pattern.test(content)) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"critical\",\n message: `Possible ${secret.label} found in CLAUDE.md — secrets must never be in config files`,\n fix: \"Remove the secret immediately and rotate it\",\n });\n }\n }\n\n // Check for TODO placeholders (unfinished config)\n const todoCount = (content.match(/<!--\\s*TODO/gi) ?? []).length;\n if (todoCount > 3) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"medium\",\n message: `${todoCount} TODO placeholders — CLAUDE.md is mostly unfinished`,\n fix: \"Fill in the TODO sections or remove them\",\n });\n }\n\n // Score: base 100, deduct per issue\n const criticals = issues.filter((i) => i.severity === \"critical\").length;\n const highs = issues.filter((i) => i.severity === \"high\").length;\n const mediums = issues.filter((i) => i.severity === \"medium\").length;\n const lows = issues.filter((i) => i.severity === \"low\").length;\n\n const score = Math.max(0, 100 - criticals * 40 - highs * 30 - mediums * 15 - lows * 5);\n return { name: \"CLAUDE.md Quality\", issues, score };\n}\n","import { readFile, writeFile, mkdir, access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { log } from \"../../lib/output.js\";\nimport { detectProject } from \"../../lib/detect.js\";\nimport { generateClaudeignore } from \"../init/generators/claudeignore.js\";\nimport type { DiagnosticIssue, DetectedProject } from \"../../types/index.js\";\n\ninterface FixResult {\n readonly fixed: number;\n readonly skipped: number;\n}\n\n/**\n * Auto-apply deterministic fixes for doctor issues.\n * Only applies fixes that are safe and unambiguous.\n */\nexport async function applyFixes(\n issues: ReadonlyArray<DiagnosticIssue>,\n projectRoot: string,\n): Promise<FixResult> {\n const detected = await detectProject(projectRoot);\n let fixed = 0;\n let skipped = 0;\n\n for (const issue of issues) {\n const applied = await tryFix(issue, projectRoot, detected);\n if (applied) {\n fixed++;\n } else {\n skipped++;\n }\n }\n\n return { fixed, skipped };\n}\n\n// Fix lookup table: [analyzer, message substring] → fix function\ntype FixFn = (root: string, detected: DetectedProject) => Promise<boolean>;\n\nconst FIX_TABLE: ReadonlyArray<{ analyzer: string; match: string; fix: FixFn }> = [\n { analyzer: \"Hooks\", match: \"No hooks configured\", fix: async (root, detected) => {\n const a = await addEnvProtectionHook(root);\n const b = await addAutoFormatHook(root, detected);\n const c = await addForcePushProtection(root);\n return a || b || c;\n }},\n { analyzer: \"Hooks\", match: \".env file protection\", fix: (root) => addEnvProtectionHook(root) },\n { analyzer: \"Hooks\", match: \"auto-format\", fix: (root, detected) => addAutoFormatHook(root, detected) },\n { analyzer: \"Hooks\", match: \"No PreToolUse\", fix: (root) => addEnvProtectionHook(root) },\n { analyzer: \"Quality\", match: \"Architecture\", fix: (root) => addClaudeMdSection(root, \"## Architecture\", \"<!-- TODO: Describe your codebase structure. Run `claude-launchpad enhance` to auto-fill this. -->\") },\n { analyzer: \"Quality\", match: \"Off-Limits\", fix: (root) => addClaudeMdSection(root, \"## Off-Limits\", \"- Never hardcode secrets - use environment variables\\n- Never write to `.env` files\\n- Never expose internal error details in API responses\") },\n { analyzer: \"Quality\", match: \"Commands\", fix: (root) => addClaudeMdSection(root, \"## Commands\", \"<!-- TODO: Add your dev/build/test commands -->\") },\n { analyzer: \"Quality\", match: \"Stack\", fix: (root, detected) => {\n const content = detected.language\n ? `- **Language**: ${detected.language}${detected.framework ? `\\n- **Framework**: ${detected.framework}` : \"\"}${detected.packageManager ? `\\n- **Package Manager**: ${detected.packageManager}` : \"\"}`\n : \"<!-- TODO: Define your tech stack -->\";\n return addClaudeMdSection(root, \"## Stack\", content);\n }},\n { analyzer: \"Quality\", match: \"Session Start\", fix: (root) => addClaudeMdSection(root, \"## Session Start\", \"- ALWAYS read @TASKS.md first - it tracks progress across sessions\\n- Update TASKS.md as you complete work\") },\n { analyzer: \"Rules\", match: \"No .claudeignore\", fix: (root, detected) => createClaudeignore(root, detected) },\n { analyzer: \"Rules\", match: \"No .claude/rules/\", fix: (root) => createStarterRules(root) },\n { analyzer: \"Permissions\", match: \"force-push\", fix: (root) => addForcePushProtection(root) },\n];\n\nasync function tryFix(\n issue: DiagnosticIssue,\n root: string,\n detected: DetectedProject,\n): Promise<boolean> {\n const entry = FIX_TABLE.find(\n (e) => e.analyzer === issue.analyzer && issue.message.includes(e.match),\n );\n return entry ? entry.fix(root, detected) : false;\n}\n\n// ─── Fix Implementations ───\n\nasync function addEnvProtectionHook(root: string): Promise<boolean> {\n const settings = await readSettingsJson(root);\n const hooks = (settings.hooks ?? {}) as Record<string, unknown>;\n const preToolUse = (hooks.PreToolUse as Record<string, unknown>[] | undefined) ?? [];\n\n // Check if already exists\n const alreadyHas = preToolUse.some((g: Record<string, unknown>) => {\n const nested = g.hooks as Record<string, unknown>[] | undefined;\n return nested?.some((h) => String(h.command ?? \"\").includes(\".env\"));\n });\n\n if (alreadyHas) return false;\n\n preToolUse.push({\n matcher: \"Read|Write|Edit\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -qE '\\\\.(env|env\\\\..*)$' && ! echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -q '.env.example' && echo 'BLOCKED: .env files contain secrets' && exit 1; exit 0\",\n }],\n });\n\n (settings as Record<string, unknown>).hooks = { ...hooks, PreToolUse: preToolUse };\n await writeSettingsJson(root, settings);\n log.success(\"Added .env file protection hook (PreToolUse)\");\n return true;\n}\n\nasync function addAutoFormatHook(root: string, detected: DetectedProject): Promise<boolean> {\n if (!detected.language) return false;\n\n // Safe formatter commands only — never use detected.formatCommand to prevent injection\n const formatters: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: { extensions: [\"ts\", \"tsx\"], command: \"npx prettier --write\" },\n JavaScript: { extensions: [\"js\", \"jsx\"], command: \"npx prettier --write\" },\n Python: { extensions: [\"py\"], command: \"ruff format\" },\n Go: { extensions: [\"go\"], command: \"gofmt -w\" },\n Rust: { extensions: [\"rs\"], command: \"rustfmt\" },\n Ruby: { extensions: [\"rb\"], command: \"rubocop -A\" },\n PHP: { extensions: [\"php\"], command: \"vendor/bin/pint\" },\n };\n\n const config = formatters[detected.language];\n if (!config) return false;\n\n const settings = await readSettingsJson(root);\n const hooks = (settings.hooks ?? {}) as Record<string, unknown>;\n const postToolUse = (hooks.PostToolUse as Record<string, unknown>[] | undefined) ?? [];\n\n const alreadyHas = postToolUse.some((g: Record<string, unknown>) => {\n const nested = g.hooks as Record<string, unknown>[] | undefined;\n return nested?.some((h) => String(h.command ?? \"\").includes(\"format\"));\n });\n\n if (alreadyHas) return false;\n\n const extChecks = config.extensions.map((ext) => `[ \"$ext\" = \"${ext}\" ]`).join(\" || \");\n\n postToolUse.push({\n matcher: \"Write|Edit\",\n hooks: [{\n type: \"command\",\n command: `ext=\\${TOOL_INPUT_FILE_PATH##*.}; (${extChecks}) && ${config.command} \"$TOOL_INPUT_FILE_PATH\" 2>/dev/null; exit 0`,\n }],\n });\n\n (settings as Record<string, unknown>).hooks = { ...hooks, PostToolUse: postToolUse };\n await writeSettingsJson(root, settings);\n log.success(`Added auto-format hook (PostToolUse → ${config.command})`);\n return true;\n}\n\nasync function addForcePushProtection(root: string): Promise<boolean> {\n const settings = await readSettingsJson(root);\n const hooks = (settings.hooks ?? {}) as Record<string, unknown>;\n const preToolUse = (hooks.PreToolUse as Record<string, unknown>[] | undefined) ?? [];\n\n const alreadyHas = preToolUse.some((g: Record<string, unknown>) => {\n const nested = g.hooks as Record<string, unknown>[] | undefined;\n return nested?.some((h) => String(h.command ?? \"\").includes(\"force\"));\n });\n\n if (alreadyHas) return false;\n\n preToolUse.push({\n matcher: \"Bash\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_COMMAND\\\" | grep -qE 'push.*--force|push.*-f' && echo 'WARNING: Force push detected — this can destroy remote history' && exit 1; exit 0\",\n }],\n });\n\n (settings as Record<string, unknown>).hooks = { ...hooks, PreToolUse: preToolUse };\n await writeSettingsJson(root, settings);\n log.success(\"Added force-push protection hook (PreToolUse → Bash)\");\n return true;\n}\n\nasync function addClaudeMdSection(root: string, heading: string, content: string): Promise<boolean> {\n const claudeMdPath = join(root, \"CLAUDE.md\");\n let existing: string;\n try {\n existing = await readFile(claudeMdPath, \"utf-8\");\n } catch {\n return false; // No CLAUDE.md to add to\n }\n\n // Don't add if section already exists\n if (existing.includes(heading)) return false;\n\n // Append before Key Decisions if it exists, otherwise at end\n const keyDecisionsIdx = existing.indexOf(\"## Key Decisions\");\n const insertAt = keyDecisionsIdx > -1 ? keyDecisionsIdx : existing.length;\n\n const section = `\\n${heading}\\n${content}\\n\\n`;\n const updated = existing.slice(0, insertAt) + section + existing.slice(insertAt);\n\n await writeFile(claudeMdPath, updated);\n log.success(`Added \"${heading}\" section to CLAUDE.md`);\n return true;\n}\n\nasync function createClaudeignore(root: string, detected: DetectedProject): Promise<boolean> {\n const ignorePath = join(root, \".claudeignore\");\n try {\n await access(ignorePath);\n return false; // Already exists\n } catch {\n // Create it\n }\n\n const content = generateClaudeignore(detected);\n await writeFile(ignorePath, content);\n log.success(\"Generated .claudeignore with language-specific ignore patterns\");\n return true;\n}\n\nasync function createStarterRules(root: string): Promise<boolean> {\n const rulesDir = join(root, \".claude\", \"rules\");\n try {\n await access(rulesDir);\n return false; // Already exists\n } catch {\n // Create it\n }\n\n await mkdir(rulesDir, { recursive: true });\n\n await writeFile(\n join(rulesDir, \"conventions.md\"),\n `# Project Conventions\n\n- Use conventional commits (feat:, fix:, docs:, refactor:, test:, chore:)\n- Keep files under 400 lines, functions under 50 lines\n- Handle errors explicitly — no empty catch blocks\n- Validate input at system boundaries\n`,\n );\n\n log.success(\"Created .claude/rules/conventions.md with starter rules\");\n return true;\n}\n\n// ─── Settings JSON helpers ───\n\nasync function readSettingsJson(root: string): Promise<Record<string, unknown>> {\n const path = join(root, \".claude\", \"settings.json\");\n try {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nasync function writeSettingsJson(root: string, settings: Record<string, unknown>): Promise<void> {\n const dir = join(root, \".claude\");\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, \"settings.json\"), JSON.stringify(settings, null, 2) + \"\\n\");\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { log, renderDoctorReport } from \"../../lib/output.js\";\nimport { analyzeBudget } from \"./analyzers/budget.js\";\nimport { analyzeSettings } from \"./analyzers/settings.js\";\nimport { analyzeHooks } from \"./analyzers/hooks.js\";\nimport { analyzeRules } from \"./analyzers/rules.js\";\nimport { analyzePermissions } from \"./analyzers/permissions.js\";\nimport { analyzeMcp } from \"./analyzers/mcp.js\";\nimport { analyzeQuality } from \"./analyzers/quality.js\";\nimport type { AnalyzerResult } from \"../../types/index.js\";\n\n/**\n * Watch config files for changes using polling (reliable on all OS).\n * Re-runs doctor on every detected change.\n */\nexport async function watchConfig(projectRoot: string): Promise<void> {\n await runAndDisplay(projectRoot);\n\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n\n let lastSnapshot = await getFileSnapshot(projectRoot);\n\n setInterval(async () => {\n const currentSnapshot = await getFileSnapshot(projectRoot);\n if (currentSnapshot !== lastSnapshot) {\n lastSnapshot = currentSnapshot;\n console.clear();\n await runAndDisplay(projectRoot);\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n }\n }, 1000);\n\n await new Promise(() => {});\n}\n\nasync function getFileSnapshot(projectRoot: string): Promise<string> {\n const files = [\n join(projectRoot, \"CLAUDE.md\"),\n join(projectRoot, \".claudeignore\"),\n ];\n\n const claudeDir = join(projectRoot, \".claude\");\n try {\n const entries = await readdir(claudeDir, { withFileTypes: true, recursive: true });\n for (const entry of entries) {\n if (entry.isFile()) {\n const parentPath = (entry as unknown as { parentPath?: string }).parentPath ?? claudeDir;\n files.push(join(parentPath, entry.name));\n }\n }\n } catch {\n // .claude/ doesn't exist\n }\n\n const mtimes: string[] = [];\n for (const file of files) {\n try {\n const s = await stat(file);\n mtimes.push(`${file}:${s.mtimeMs}`);\n } catch {\n mtimes.push(`${file}:missing`);\n }\n }\n\n return mtimes.join(\"|\");\n}\n\nasync function runAndDisplay(projectRoot: string): Promise<void> {\n console.log(\"\\x1b[36m\\x1b[1m Claude Launchpad\\x1b[0m\");\n console.log(\"\\x1b[2m Scaffold · Diagnose · Evaluate\\x1b[0m\");\n log.blank();\n\n const config = await parseClaudeConfig(projectRoot);\n\n if (config.claudeMdContent === null && config.settings === null) {\n log.error(\"No Claude Code configuration found.\");\n return;\n }\n\n const results: AnalyzerResult[] = await Promise.all([\n analyzeBudget(config),\n analyzeQuality(config),\n analyzeSettings(config),\n analyzeHooks(config),\n analyzeRules(config),\n analyzePermissions(config),\n analyzeMcp(config),\n ]);\n\n renderDoctorReport(results);\n}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { printBanner, log, printScoreCard } from \"../../lib/output.js\";\nimport { loadScenarios } from \"./loader.js\";\nimport { runScenarioWithRetries } from \"./runner.js\";\nimport type { EvalRunResult } from \"../../types/index.js\";\n\nexport function createEvalCommand(): Command {\n return new Command(\"eval\")\n .description(\"Test your Claude Code config against eval scenarios\")\n .option(\"-s, --suite <suite>\", \"Eval suite to run (e.g., security, conventions, workflow)\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .option(\"--scenarios <path>\", \"Custom scenarios directory\")\n .option(\"--runs <n>\", \"Runs per scenario (default: 3)\", \"3\")\n .option(\"--timeout <ms>\", \"Timeout per run in ms (default: 120000)\", \"120000\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--debug\", \"Keep sandbox directories for inspection\")\n .option(\"--model <model>\", \"Model to use for eval (e.g., sonnet, haiku, opus)\")\n .action(async (opts) => {\n printBanner();\n\n // Verify Claude CLI is available\n const claudeAvailable = await checkClaudeCli();\n if (!claudeAvailable) {\n log.error(\"Claude CLI not found. Install it: https://docs.anthropic.com/en/docs/claude-code\");\n log.info(\"The eval command runs Claude headless against scenarios — it requires the CLI.\");\n process.exit(1);\n }\n\n // Load scenarios\n log.step(\"Loading eval scenarios...\");\n const scenarios = await loadScenarios({\n suite: opts.suite,\n customPath: opts.scenarios,\n });\n\n if (scenarios.length === 0) {\n log.warn(\"No matching scenarios found.\");\n if (opts.suite) {\n log.info(`Check that the suite \"${opts.suite}\" exists in the scenarios directory.`);\n }\n return;\n }\n\n log.success(`Loaded ${scenarios.length} scenario(s)`);\n if (opts.model) {\n log.info(`Model: ${opts.model}`);\n }\n log.blank();\n\n const runs = parseInt(opts.runs, 10);\n const timeout = parseInt(opts.timeout, 10);\n\n // Run scenarios\n const results: EvalRunResult[] = [];\n\n for (const scenario of scenarios) {\n const spinner = ora({\n text: `Running: ${scenario.name} (${runs} run${runs > 1 ? \"s\" : \"\"})`,\n prefixText: \" \",\n }).start();\n\n try {\n const result = await runScenarioWithRetries(\n { ...scenario, runs },\n { projectRoot: opts.path, timeout, debug: opts.debug, model: opts.model },\n );\n results.push(result);\n\n if (result.passed) {\n spinner.succeed(`${scenario.name} ${result.score}/${result.maxScore}`);\n } else {\n spinner.fail(`${scenario.name} ${result.score}/${result.maxScore}`);\n }\n } catch (error: unknown) {\n spinner.fail(`${scenario.name} ERROR`);\n const msg = error instanceof Error ? error.message : String(error);\n log.error(` ${msg}`);\n results.push({\n scenario: scenario.name,\n score: 0,\n maxScore: scenario.checks.reduce((s, c) => s + c.points, 0),\n passed: false,\n checks: scenario.checks.map((c) => ({ label: c.label, passed: false, points: c.points })),\n });\n }\n }\n\n log.blank();\n\n if (opts.json) {\n const overallScore = results.reduce((s, r) => s + r.score, 0);\n const overallMax = results.reduce((s, r) => s + r.maxScore, 0);\n console.log(JSON.stringify({\n results,\n overallScore,\n overallMax,\n passed: overallScore >= overallMax * 0.8,\n timestamp: new Date().toISOString(),\n }, null, 2));\n return;\n }\n\n renderEvalReport(results);\n\n // Save report to .claude/eval/\n await saveEvalReport(results, opts.path, opts.suite, opts.model);\n });\n}\n\nfunction renderEvalReport(results: ReadonlyArray<EvalRunResult>): void {\n for (const result of results) {\n const icon = result.passed ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const status = result.passed ? chalk.green(\"PASS\") : chalk.red(\"FAIL\");\n const score = `${result.score}/${result.maxScore}`;\n\n console.log(` ${icon} ${chalk.bold(result.scenario)} ${score} ${status}`);\n\n const failedChecks = result.checks.filter((c) => !c.passed);\n for (const check of failedChecks) {\n console.log(` ${chalk.red(\"✗\")} ${chalk.dim(check.label)}`);\n }\n }\n\n log.blank();\n\n const totalScore = results.reduce((s, r) => s + r.score, 0);\n const totalMax = results.reduce((s, r) => s + r.maxScore, 0);\n const pct = totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0;\n\n printScoreCard(\"Config Eval Score\", pct);\n log.blank();\n\n const passed = results.filter((r) => r.passed).length;\n const failed = results.length - passed;\n\n if (failed === 0) {\n log.success(`All ${passed} scenario(s) passed.`);\n } else {\n log.warn(`${passed} passed, ${failed} failed out of ${results.length} scenario(s).`);\n }\n}\n\nasync function saveEvalReport(\n results: ReadonlyArray<EvalRunResult>,\n projectRoot: string,\n suite?: string,\n model?: string,\n): Promise<void> {\n const totalScore = results.reduce((s, r) => s + r.score, 0);\n const totalMax = results.reduce((s, r) => s + r.maxScore, 0);\n const pct = totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0;\n const passed = results.filter((r) => r.passed).length;\n const failed = results.length - passed;\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\").slice(0, 19);\n\n const lines: string[] = [\n `# Eval Report — ${timestamp}`,\n \"\",\n `**Score: ${pct}%** (${passed} passed, ${failed} failed out of ${results.length} scenarios)`,\n \"\",\n `- Suite: ${suite ?? \"all\"}`,\n `- Model: ${model ?? \"default\"}`,\n `- Date: ${new Date().toISOString().split(\"T\")[0]}`,\n \"\",\n \"## Results\",\n \"\",\n ];\n\n for (const result of results) {\n const status = result.passed ? \"PASS\" : \"FAIL\";\n lines.push(`### ${result.scenario} — ${result.score}/${result.maxScore} ${status}`);\n\n const failedChecks = result.checks.filter((c) => !c.passed);\n const passedChecks = result.checks.filter((c) => c.passed);\n\n for (const check of passedChecks) {\n lines.push(`- PASSED: ${check.label} (${check.points} pts)`);\n }\n for (const check of failedChecks) {\n lines.push(`- FAILED: ${check.label} (${check.points} pts)`);\n }\n lines.push(\"\");\n }\n\n if (failed > 0) {\n lines.push(\"## Recommendations\");\n lines.push(\"\");\n for (const result of results.filter((r) => !r.passed)) {\n lines.push(`### Fix: ${result.scenario}`);\n const failedChecks = result.checks.filter((c) => !c.passed);\n for (const check of failedChecks) {\n lines.push(`- ${check.label} — update CLAUDE.md instructions or add hooks to enforce this behavior`);\n }\n lines.push(\"\");\n }\n }\n\n const evalDir = join(projectRoot, \".claude\", \"eval\");\n await mkdir(evalDir, { recursive: true });\n const filename = `eval-${suite ?? \"all\"}-${timestamp}.md`;\n await writeFile(join(evalDir, filename), lines.join(\"\\n\"));\n log.success(`Report saved to .claude/eval/${filename}`);\n}\n\nasync function checkClaudeCli(): Promise<boolean> {\n const { execFile } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const exec = promisify(execFile);\n\n try {\n await exec(\"claude\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile, readdir, access } from \"node:fs/promises\";\nimport { join, resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parse as parseYaml } from \"yaml\";\nimport { validateScenario } from \"./schema.js\";\nimport type { EvalScenario } from \"../../types/index.js\";\n\n/**\n * Find the scenarios directory. Works both in dev (tsx) and bundled (tsup).\n * - Dev: __dirname is src/commands/eval/, scenarios is at ../../../scenarios/\n * - Bundled: __dirname is dist/, scenarios is at ../scenarios/\n * - npm installed: __dirname is node_modules/claude-launchpad/dist/, scenarios is at ../scenarios/\n */\nasync function findScenariosDir(): Promise<string> {\n const thisDir = dirname(fileURLToPath(import.meta.url));\n\n // Try relative to this file (dev mode: src/commands/eval/ → ../../../scenarios/)\n const devPath = resolve(thisDir, \"../../../scenarios\");\n if (await dirExists(devPath)) return devPath;\n\n // Try relative to dist/ (bundled: dist/ → ../scenarios/)\n const bundledPath = resolve(thisDir, \"../scenarios\");\n if (await dirExists(bundledPath)) return bundledPath;\n\n // Try relative to package root (fallback)\n const rootPath = resolve(thisDir, \"../../scenarios\");\n if (await dirExists(rootPath)) return rootPath;\n\n return devPath; // Fall through — will just find 0 scenarios\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Load eval scenarios from a directory. Supports:\n * - Built-in scenarios (shipped in scenarios/)\n * - Custom scenarios from a user-specified path\n */\nexport async function loadScenarios(options: {\n suite?: string;\n customPath?: string;\n}): Promise<ReadonlyArray<EvalScenario>> {\n const { suite, customPath } = options;\n\n const scenarioDir = customPath\n ? resolve(customPath)\n : await findScenariosDir();\n\n const dirs = suite\n ? [join(scenarioDir, suite)]\n : await getSubdirectories(scenarioDir);\n\n // Also check the root dir for flat YAML files\n const allDirs = [scenarioDir, ...dirs];\n\n const scenarios: EvalScenario[] = [];\n\n for (const dir of allDirs) {\n const files = await listYamlFiles(dir);\n for (const file of files) {\n try {\n const content = await readFile(file, \"utf-8\");\n const raw = parseYaml(content);\n const scenario = validateScenario(raw, file);\n scenarios.push(scenario);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.warn(` Warning: Skipping ${file}: ${msg}`);\n }\n }\n }\n\n return scenarios;\n}\n\nasync function getSubdirectories(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n\nasync function listYamlFiles(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isFile() && (e.name.endsWith(\".yaml\") || e.name.endsWith(\".yml\")))\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n","import type { EvalScenario, EvalCheck } from \"../../types/index.js\";\n\n/**\n * Validates a raw parsed YAML object against the EvalScenario schema.\n * Returns a validated scenario or throws with a descriptive error.\n */\nexport function validateScenario(raw: unknown, filePath: string): EvalScenario {\n if (!raw || typeof raw !== \"object\") {\n throw new ScenarioError(filePath, \"Scenario must be a YAML object\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n const name = requireString(obj, \"name\", filePath);\n const description = requireString(obj, \"description\", filePath);\n const prompt = requireString(obj, \"prompt\", filePath);\n const setup = validateSetup(obj.setup, filePath);\n const checks = validateChecks(obj.checks, filePath);\n const passingScore = requireNumber(obj, \"passingScore\", filePath);\n const runs = optionalNumber(obj, \"runs\") ?? 3;\n\n return { name, description, setup, prompt, checks, passingScore, runs };\n}\n\n// ─── Field Validators ───\n\nfunction validateSetup(\n raw: unknown,\n filePath: string,\n): EvalScenario[\"setup\"] {\n if (!raw || typeof raw !== \"object\") {\n throw new ScenarioError(filePath, '\"setup\" must be an object with a \"files\" array');\n }\n\n const obj = raw as Record<string, unknown>;\n const files = obj.files;\n\n if (!Array.isArray(files)) {\n throw new ScenarioError(filePath, '\"setup.files\" must be an array');\n }\n\n const validatedFiles = files.map((f, i) => {\n if (!f || typeof f !== \"object\") {\n throw new ScenarioError(filePath, `setup.files[${i}] must be an object`);\n }\n const file = f as Record<string, unknown>;\n if (typeof file.path !== \"string\" || typeof file.content !== \"string\") {\n throw new ScenarioError(filePath, `setup.files[${i}] must have \"path\" and \"content\" strings`);\n }\n return { path: file.path, content: file.content };\n });\n\n const instructions = typeof obj.instructions === \"string\" ? obj.instructions : undefined;\n\n return { files: validatedFiles, instructions };\n}\n\nfunction validateChecks(raw: unknown, filePath: string): ReadonlyArray<EvalCheck> {\n if (!Array.isArray(raw) || raw.length === 0) {\n throw new ScenarioError(filePath, '\"checks\" must be a non-empty array');\n }\n\n return raw.map((c, i) => {\n if (!c || typeof c !== \"object\") {\n throw new ScenarioError(filePath, `checks[${i}] must be an object`);\n }\n const check = c as Record<string, unknown>;\n\n const validTypes = [\"grep\", \"file-exists\", \"file-absent\", \"max-lines\", \"custom\"];\n if (!validTypes.includes(check.type as string)) {\n throw new ScenarioError(filePath, `checks[${i}].type must be one of: ${validTypes.join(\", \")}`);\n }\n\n if (typeof check.target !== \"string\") {\n throw new ScenarioError(filePath, `checks[${i}].target must be a string`);\n }\n\n const validExpect = [\"present\", \"absent\"];\n if (!validExpect.includes(check.expect as string)) {\n throw new ScenarioError(filePath, `checks[${i}].expect must be \"present\" or \"absent\"`);\n }\n\n if (typeof check.points !== \"number\" || check.points < 0) {\n throw new ScenarioError(filePath, `checks[${i}].points must be a non-negative number`);\n }\n\n if (typeof check.label !== \"string\") {\n throw new ScenarioError(filePath, `checks[${i}].label must be a string`);\n }\n\n return {\n type: check.type as EvalCheck[\"type\"],\n pattern: typeof check.pattern === \"string\" ? check.pattern : undefined,\n target: check.target,\n expect: check.expect as EvalCheck[\"expect\"],\n points: check.points,\n label: check.label,\n };\n });\n}\n\n// ─── Helpers ───\n\nfunction requireString(obj: Record<string, unknown>, key: string, filePath: string): string {\n if (typeof obj[key] !== \"string\" || obj[key] === \"\") {\n throw new ScenarioError(filePath, `\"${key}\" must be a non-empty string`);\n }\n return obj[key] as string;\n}\n\nfunction requireNumber(obj: Record<string, unknown>, key: string, filePath: string): number {\n if (typeof obj[key] !== \"number\") {\n throw new ScenarioError(filePath, `\"${key}\" must be a number`);\n }\n return obj[key] as number;\n}\n\nfunction optionalNumber(obj: Record<string, unknown>, key: string): number | undefined {\n if (obj[key] === undefined) return undefined;\n if (typeof obj[key] !== \"number\") return undefined;\n return obj[key] as number;\n}\n\nclass ScenarioError extends Error {\n constructor(filePath: string, message: string) {\n super(`Invalid scenario ${filePath}: ${message}`);\n this.name = \"ScenarioError\";\n }\n}\n","import { mkdir, writeFile, readFile, readdir, rm } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { randomUUID } from \"node:crypto\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { EvalScenario, EvalRunResult, EvalCheck } from \"../../types/index.js\";\n\nconst exec = promisify(execFile);\n\ninterface RunOptions {\n readonly projectRoot: string;\n readonly timeout: number;\n readonly debug?: boolean;\n readonly model?: string;\n}\n\n/**\n * Execute a single eval scenario run using the Agent SDK.\n *\n * 1. Create a temp directory with the scenario's seed files\n * 2. Write a minimal CLAUDE.md with the scenario's instructions\n * 3. Run Claude via Agent SDK with explicit tool permissions\n * 4. Check the results against the scenario's checks\n * 5. Clean up\n */\nexport async function runScenario(\n scenario: EvalScenario,\n options: RunOptions,\n): Promise<EvalRunResult> {\n const sandboxDir = join(tmpdir(), `claude-eval-${randomUUID()}`);\n\n try {\n await setupSandbox(sandboxDir, scenario);\n await runClaudeInSandbox(sandboxDir, scenario.prompt, options.timeout, options.model);\n return await scoreResults(scenario, sandboxDir);\n } finally {\n if (options.debug) {\n console.log(` DEBUG: Sandbox preserved at ${sandboxDir}`);\n } else {\n await rm(sandboxDir, { recursive: true, force: true }).catch(() => {});\n }\n }\n}\n\n/**\n * Run a scenario multiple times and return the median result.\n */\nexport async function runScenarioWithRetries(\n scenario: EvalScenario,\n options: RunOptions,\n): Promise<EvalRunResult> {\n const results: EvalRunResult[] = [];\n\n for (let i = 0; i < scenario.runs; i++) {\n const result = await runScenario(scenario, options);\n results.push(result);\n }\n\n const sorted = [...results].sort((a, b) => a.score - b.score);\n return sorted[Math.floor(sorted.length / 2)];\n}\n\n// ─── Sandbox Setup ───\n\nasync function setupSandbox(sandboxDir: string, scenario: EvalScenario): Promise<void> {\n await mkdir(sandboxDir, { recursive: true });\n\n for (const file of scenario.setup.files) {\n const filePath = join(sandboxDir, file.path);\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, file.content);\n }\n\n if (scenario.setup.instructions) {\n await writeFile(\n join(sandboxDir, \"CLAUDE.md\"),\n `# Eval Scenario\\n\\n${scenario.setup.instructions}\\n`,\n );\n }\n\n await exec(\"git\", [\"init\", \"-q\"], { cwd: sandboxDir });\n await exec(\"git\", [\"add\", \"-A\"], { cwd: sandboxDir });\n await exec(\"git\", [\n \"-c\", \"user.name=eval\",\n \"-c\", \"user.email=eval@test\",\n \"commit\", \"-q\", \"-m\", \"eval setup\",\n ], { cwd: sandboxDir });\n}\n\n// ─── Claude Execution ───\n\nasync function runClaudeInSandbox(\n cwd: string,\n prompt: string,\n timeout: number,\n model?: string,\n): Promise<void> {\n // Try Agent SDK first, fall back to CLI subprocess\n try {\n const sdk = await import(\"@anthropic-ai/claude-agent-sdk\");\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n for await (const _message of sdk.query({\n prompt,\n options: {\n cwd,\n allowedTools: [\"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\"],\n permissionMode: \"dontAsk\",\n settingSources: [],\n maxTurns: 20,\n abortController: controller,\n ...(model ? { model } : {}),\n },\n })) {\n // Consume the stream — we only care about side effects (file edits)\n }\n } finally {\n clearTimeout(timeoutId);\n }\n } catch {\n // SDK not available or failed — fall back to CLI\n await runClaudeCli(cwd, prompt, timeout, model);\n }\n}\n\nasync function runClaudeCli(\n cwd: string,\n prompt: string,\n timeout: number,\n model?: string,\n): Promise<void> {\n try {\n const args = [\n \"-p\", prompt,\n \"--output-format\", \"text\",\n \"--max-turns\", \"20\",\n \"--dangerously-skip-permissions\",\n \"--allowedTools\", \"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\",\n ];\n if (model) args.push(\"--model\", model);\n await exec(\"claude\", args, { cwd, timeout, maxBuffer: 10 * 1024 * 1024 });\n } catch (error: unknown) {\n // Claude might exit non-zero but still produce usable output\n if (error && typeof error === \"object\" && \"stdout\" in error) {\n return; // Files may have been modified despite exit code\n }\n throw error;\n }\n}\n\n// ─── Scoring ───\n\nasync function scoreResults(\n scenario: EvalScenario,\n sandboxDir: string,\n): Promise<EvalRunResult> {\n const checkResults = await evaluateChecks(scenario.checks, sandboxDir);\n\n const score = checkResults\n .filter((c) => c.passed)\n .reduce((sum, c) => sum + c.points, 0);\n\n const maxScore = scenario.checks.reduce((sum, c) => sum + c.points, 0);\n\n return {\n scenario: scenario.name,\n score,\n maxScore,\n passed: score >= scenario.passingScore,\n checks: checkResults,\n };\n}\n\nasync function evaluateChecks(\n checks: ReadonlyArray<EvalCheck>,\n sandboxDir: string,\n): Promise<ReadonlyArray<{ label: string; passed: boolean; points: number }>> {\n const results: { label: string; passed: boolean; points: number }[] = [];\n\n for (const check of checks) {\n const passed = await evaluateSingleCheck(check, sandboxDir);\n results.push({ label: check.label, passed, points: check.points });\n }\n\n return results;\n}\n\nasync function evaluateSingleCheck(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n switch (check.type) {\n case \"grep\":\n return checkGrep(check, sandboxDir);\n case \"file-exists\":\n return checkFileExists(check, sandboxDir);\n case \"file-absent\":\n return checkFileAbsent(check, sandboxDir);\n case \"max-lines\":\n return checkMaxLines(check, sandboxDir);\n case \"custom\":\n return false;\n default:\n return false;\n }\n}\n\n// ─── Individual Check Implementations ───\n\nasync function checkGrep(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n if (!check.pattern) return false;\n try {\n const content = await readFile(join(sandboxDir, check.target), \"utf-8\");\n let found: boolean;\n try {\n found = new RegExp(check.pattern).test(content);\n } catch {\n return false; // Invalid regex\n }\n return check.expect === \"present\" ? found : !found;\n } catch {\n return check.expect === \"absent\";\n }\n}\n\nasync function checkFileExists(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n try {\n await readFile(join(sandboxDir, check.target));\n return check.expect === \"present\";\n } catch {\n return check.expect === \"absent\";\n }\n}\n\nasync function checkFileAbsent(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n try {\n await readFile(join(sandboxDir, check.target));\n return check.expect === \"absent\";\n } catch {\n return check.expect === \"present\";\n }\n}\n\nasync function checkMaxLines(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n const maxLines = parseInt(check.pattern ?? \"800\", 10);\n try {\n const files = await listAllFiles(join(sandboxDir, check.target));\n for (const file of files) {\n const content = await readFile(file, \"utf-8\");\n if (content.split(\"\\n\").length > maxLines) {\n return check.expect === \"absent\";\n }\n }\n return check.expect === \"present\";\n } catch {\n return check.expect === \"absent\";\n }\n}\n\n// ─── Utilities ───\n\nasync function listAllFiles(dir: string): Promise<string[]> {\n const results: string[] = [];\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...await listAllFiles(fullPath));\n } else {\n results.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist\n }\n return results;\n}\n","import { Command } from \"commander\";\nimport { spawn, execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { printBanner, log } from \"../../lib/output.js\";\n\nconst execAsync = promisify(execFile);\n\nconst ENHANCE_PROMPT = `Read CLAUDE.md and the project's codebase, then update CLAUDE.md to fill in missing or incomplete sections.\n\nCRITICAL BUDGET RULE: CLAUDE.md must stay UNDER 120 lines of actionable content (not counting headings, blank lines, or comments). Claude Code starts ignoring rules past ~150 instructions. If you need more detail, create .claude/rules/ files instead:\n- Create .claude/rules/conventions.md for detailed coding patterns\n- Create .claude/rules/architecture.md for detailed structure docs\n- Keep CLAUDE.md to HIGH-LEVEL summaries only (3-5 bullets per section max)\n\nSections to fill in or preserve (DO NOT remove any existing section):\n1. **## Stack** — if missing or incomplete, detect and add language, framework, package manager\n2. **## Architecture** — 3-5 bullet points describing the codebase shape (not a full directory tree)\n3. **## Conventions** — max 8 key patterns. Move detailed rules to .claude/rules/conventions.md\n4. **## Off-Limits** — max 8 guardrails specific to this project\n5. **## Key Decisions** — only decisions that affect how Claude should work in this codebase\n6. **MCP server suggestions** — look at what external services the project uses (databases, APIs, storage). If you spot Postgres, Redis, Stripe, GitHub API, or similar, suggest relevant MCP servers the user could add. Print these as suggestions at the end, not in CLAUDE.md.\n\nAlso review .claude/settings.json hooks:\n- Read the existing hooks in .claude/settings.json\n- If you see project-specific patterns that deserve hooks (e.g., protected directories, test file patterns, migration files), suggest adding them\n- DO NOT overwrite existing hooks — only add new ones that are specific to this project\n- Print hook suggestions at the end with the exact JSON to add, don't modify settings.json directly\n\nRules:\n- Don't remove existing content — only add or improve\n- Be specific to THIS project, not generic advice\n- Use bullet points, not paragraphs\n- If a section would exceed 8 bullets, split into a .claude/rules/ file and reference it\n- After editing, count the actionable lines. If over 120, move content to rules files until under`;\n\nexport function createEnhanceCommand(): Command {\n return new Command(\"enhance\")\n .description(\"Use Claude to analyze your codebase and complete CLAUDE.md\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .action(async (opts) => {\n printBanner();\n\n const root = opts.path;\n\n // Check CLAUDE.md exists\n const claudeMdPath = join(root, \"CLAUDE.md\");\n try {\n await access(claudeMdPath);\n } catch {\n log.error(\"No CLAUDE.md found. Run `claude-launchpad init` first.\");\n process.exit(1);\n }\n\n // Check Claude CLI is available\n try {\n await execAsync(\"claude\", [\"--version\"]);\n } catch {\n log.error(\"Claude CLI not found. Install it: https://docs.anthropic.com/en/docs/claude-code\");\n process.exit(1);\n }\n\n log.step(\"Launching Claude to enhance your CLAUDE.md...\");\n log.blank();\n\n const child = spawn(\n \"claude\",\n [ENHANCE_PROMPT],\n { cwd: root, stdio: \"inherit\" },\n );\n\n await new Promise<number>((resolve) => {\n child.on(\"close\", (code) => resolve(code ?? 0));\n });\n\n log.blank();\n log.success(\"Run `claude-launchpad doctor` to check your updated score.\");\n });\n}\n"],"mappings":"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","names":["Command","join","readFile","join","readdir","join","readFile","Command","access","join","join","access","readFile","basename","join","join","readFile","basename","access","readFile","writeFile","mkdir","access","join","join","readFile","writeFile","access","mkdir","readdir","join","join","readdir","Command","overallScore","Command","chalk","mkdir","writeFile","join","readFile","readdir","access","join","resolve","dirname","dirname","resolve","access","join","readFile","readdir","mkdir","writeFile","readFile","readdir","join","dirname","Command","chalk","join","mkdir","writeFile","execFile","promisify","exec","Command","execFile","promisify","access","join","promisify","execFile","Command","join","access","resolve","Command","join"]}
|