claude-launchpad 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -2148,7 +2148,7 @@ function createEnhanceCommand() {
2148
2148
  }
2149
2149
 
2150
2150
  // src/cli.ts
2151
- var program = new Command5().name("claude-launchpad").description("CLI toolkit that makes Claude Code setups measurably good").version("0.2.1").action(async () => {
2151
+ var program = new Command5().name("claude-launchpad").description("CLI toolkit that makes Claude Code setups measurably good").version("0.2.2", "-v, --version").action(async () => {
2152
2152
  const hasConfig = await fileExists3(join9(process.cwd(), "CLAUDE.md")) || await fileExists3(join9(process.cwd(), ".claude", "settings.json"));
2153
2153
  if (hasConfig) {
2154
2154
  await program.commands.find((c) => c.name() === "doctor")?.parseAsync([], { from: "user" });
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/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 { access } from \"node:fs/promises\";\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\";\n\nconst program = new Command()\n .name(\"claude-launchpad\")\n .description(\"CLI toolkit that makes Claude Code setups measurably good\")\n .version(\"0.2.1\")\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\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\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 { 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\"), { 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 .claudeignore if it doesn't exist\n const claudeignorePath = join(root, \".claudeignore\");\n const hasClaudeignore = await fileExists(claudeignorePath);\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 await Promise.all(writes);\n\n log.success(\"Generated CLAUDE.md\");\n log.success(\"Generated TASKS.md\");\n log.success(\"Generated .claude/settings.json (merged with existing)\");\n if (!hasClaudeignore) {\n log.success(\"Generated .claudeignore\");\n }\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\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await readFile(path);\n return true;\n } catch {\n return false;\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 } 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","import { readFile, access } from \"node:fs/promises\";\nimport { join, basename } from \"node:path\";\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 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\nasync function readFileOrNull(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\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 hooks?: Record<string, ReadonlyArray<HookGroup>>;\n}\n\n/**\n * Generate .claude/settings.json based on detected project.\n * No third-party plugin dependencies — just hooks that match the project's tooling.\n *\n * Claude Code hook schema:\n * { \"PostToolUse\": [{ \"matcher\": \"Write|Edit\", \"hooks\": [{ \"type\": \"command\", \"command\": \"...\" }] }] }\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 — use .env.example for documentation' && 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 Object.keys(hooks).length > 0 ? { hooks } : {};\n}\n\nfunction buildFormatHook(detected: DetectedProject): HookGroup | null {\n if (!detected.language) return null;\n\n const formatters: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: {\n extensions: [\"ts\", \"tsx\"],\n command: detected.formatCommand ?? \"npx prettier --write\",\n },\n JavaScript: {\n extensions: [\"js\", \"jsx\"],\n command: detected.formatCommand ?? \"npx prettier --write\",\n },\n Python: {\n extensions: [\"py\"],\n command: detected.formatCommand ?? \"ruff format\",\n },\n Go: {\n extensions: [\"go\"],\n command: \"gofmt -w\",\n },\n Rust: {\n extensions: [\"rs\"],\n command: \"rustfmt\",\n },\n Ruby: {\n extensions: [\"rb\"],\n command: \"rubocop -A\",\n },\n Dart: {\n extensions: [\"dart\"],\n command: \"dart format\",\n },\n PHP: {\n extensions: [\"php\"],\n command: detected.formatCommand ?? \"vendor/bin/pint\",\n },\n Kotlin: {\n extensions: [\"kt\", \"kts\"],\n command: \"ktlint -F\",\n },\n Java: {\n extensions: [\"java\"],\n command: \"google-java-format -i\",\n },\n Swift: {\n extensions: [\"swift\"],\n command: \"swift-format format -i\",\n },\n Elixir: {\n extensions: [\"ex\", \"exs\"],\n command: \"mix format\",\n },\n \"C#\": {\n extensions: [\"cs\"],\n command: \"dotnet format\",\n },\n };\n\n const config = 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, printScoreCard, printIssue } 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, DiagnosticIssue } 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 printBanner();\n log.step(\"Scanning Claude Code configuration...\");\n log.blank();\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 renderReport(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 overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n const threshold = parseInt(opts.minScore, 10);\n if (overallScore < threshold) {\n process.exit(1);\n }\n }\n });\n}\n\nfunction renderReport(results: ReadonlyArray<AnalyzerResult>): void {\n const overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n\n // Score cards\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 // Issues list\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;\n }\n\n for (const issue of sortBySeverity(actionable)) {\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}\n\nfunction sortBySeverity(issues: ReadonlyArray<DiagnosticIssue>): ReadonlyArray<DiagnosticIssue> {\n const order: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };\n return [...issues].sort((a, b) => (order[a.severity] ?? 4) - (order[b.severity] ?? 4));\n}\n","import { readFile, readdir, access } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\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// ─── Utilities ───\n\nasync function readFileOrNull(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return null;\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 } from \"node:path\";\nimport type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeRules(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\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","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 — Claude can't connect to external tools\",\n fix: \"Add MCP servers in .claude/settings.json for GitHub, database, docs, etc.\",\n });\n return { name: \"MCP Servers\", issues, score: 50 };\n }\n\n for (const server of servers) {\n // Check stdio servers have a command\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 // Check HTTP/SSE servers have a URL\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 // Check stdio commands point to existing executables\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+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 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 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 const formatters: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: { extensions: [\"ts\", \"tsx\"], command: detected.formatCommand ?? \"npx prettier --write\" },\n JavaScript: { extensions: [\"js\", \"jsx\"], command: detected.formatCommand ?? \"npx prettier --write\" },\n Python: { extensions: [\"py\"], command: detected.formatCommand ?? \"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: detected.formatCommand ?? \"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 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 { watch } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { log, printScoreCard, printIssue } 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 .claude/ and CLAUDE.md for changes. Re-run doctor on every save.\n * Clears screen and shows live score.\n */\nexport async function watchConfig(projectRoot: string): Promise<void> {\n const claudeDir = join(projectRoot, \".claude\");\n const claudeMd = join(projectRoot, \"CLAUDE.md\");\n const claudeignore = join(projectRoot, \".claudeignore\");\n\n // Initial run\n await runAndDisplay(projectRoot);\n\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n\n let debounce: ReturnType<typeof setTimeout> | null = null;\n\n const onChange = () => {\n if (debounce) clearTimeout(debounce);\n debounce = setTimeout(async () => {\n console.clear();\n await runAndDisplay(projectRoot);\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n }, 300);\n };\n\n // Watch .claude/ directory\n try {\n watch(claudeDir, { recursive: true }, onChange);\n } catch {\n // .claude/ might not exist yet\n }\n\n // Watch CLAUDE.md\n try {\n watch(claudeMd, onChange);\n } catch {\n // CLAUDE.md might not exist yet\n }\n\n // Watch .claudeignore\n try {\n watch(claudeignore, onChange);\n } catch {\n // .claudeignore might not exist yet\n }\n\n // Keep process alive\n await new Promise(() => {});\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 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;\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}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\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 .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 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 },\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}\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.dim(\"─\")} ${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 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}\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);\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): 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 },\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);\n }\n}\n\nasync function runClaudeCli(\n cwd: string,\n prompt: string,\n timeout: number,\n): Promise<void> {\n try {\n await exec(\n \"claude\",\n [\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 { cwd, timeout, maxBuffer: 10 * 1024 * 1024 },\n );\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\n1. **## Architecture** or **## Project Structure** — describe the actual codebase structure (directories, key files, data flow)\n2. **## Conventions** — add project-specific patterns you observe (naming, imports, state management, API patterns)\n3. **## Off-Limits** — add guardrails based on what you see (protected files, patterns to avoid, things that should never change)\n4. **## Key Decisions** — document any architectural decisions visible in the code\n\nRules:\n- Keep CLAUDE.md under 150 instructions (lines of actionable content)\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\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","access","join","readFile","join","readdir","fileExists","join","readFile","Command","readFile","access","join","readFileOrNull","readFile","basename","access","readFile","writeFile","mkdir","access","join","join","readFile","writeFile","access","mkdir","join","join","Command","Command","chalk","readFile","readdir","access","join","resolve","resolve","access","join","readFile","readdir","mkdir","writeFile","readFile","readdir","join","dirname","Command","chalk","execFile","promisify","exec","Command","execFile","promisify","access","join","promisify","execFile","Command","join","access","resolve","Command","fileExists","join","access"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/init/index.ts","../src/lib/output.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 { access } from \"node:fs/promises\";\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\";\n\nconst program = new Command()\n .name(\"claude-launchpad\")\n .description(\"CLI toolkit that makes Claude Code setups measurably good\")\n .version(\"0.2.2\", \"-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\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\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 { 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\"), { 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 .claudeignore if it doesn't exist\n const claudeignorePath = join(root, \".claudeignore\");\n const hasClaudeignore = await fileExists(claudeignorePath);\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 await Promise.all(writes);\n\n log.success(\"Generated CLAUDE.md\");\n log.success(\"Generated TASKS.md\");\n log.success(\"Generated .claude/settings.json (merged with existing)\");\n if (!hasClaudeignore) {\n log.success(\"Generated .claudeignore\");\n }\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\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await readFile(path);\n return true;\n } catch {\n return false;\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 } 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","import { readFile, access } from \"node:fs/promises\";\nimport { join, basename } from \"node:path\";\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 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\nasync function readFileOrNull(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\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 hooks?: Record<string, ReadonlyArray<HookGroup>>;\n}\n\n/**\n * Generate .claude/settings.json based on detected project.\n * No third-party plugin dependencies — just hooks that match the project's tooling.\n *\n * Claude Code hook schema:\n * { \"PostToolUse\": [{ \"matcher\": \"Write|Edit\", \"hooks\": [{ \"type\": \"command\", \"command\": \"...\" }] }] }\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 — use .env.example for documentation' && 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 Object.keys(hooks).length > 0 ? { hooks } : {};\n}\n\nfunction buildFormatHook(detected: DetectedProject): HookGroup | null {\n if (!detected.language) return null;\n\n const formatters: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: {\n extensions: [\"ts\", \"tsx\"],\n command: detected.formatCommand ?? \"npx prettier --write\",\n },\n JavaScript: {\n extensions: [\"js\", \"jsx\"],\n command: detected.formatCommand ?? \"npx prettier --write\",\n },\n Python: {\n extensions: [\"py\"],\n command: detected.formatCommand ?? \"ruff format\",\n },\n Go: {\n extensions: [\"go\"],\n command: \"gofmt -w\",\n },\n Rust: {\n extensions: [\"rs\"],\n command: \"rustfmt\",\n },\n Ruby: {\n extensions: [\"rb\"],\n command: \"rubocop -A\",\n },\n Dart: {\n extensions: [\"dart\"],\n command: \"dart format\",\n },\n PHP: {\n extensions: [\"php\"],\n command: detected.formatCommand ?? \"vendor/bin/pint\",\n },\n Kotlin: {\n extensions: [\"kt\", \"kts\"],\n command: \"ktlint -F\",\n },\n Java: {\n extensions: [\"java\"],\n command: \"google-java-format -i\",\n },\n Swift: {\n extensions: [\"swift\"],\n command: \"swift-format format -i\",\n },\n Elixir: {\n extensions: [\"ex\", \"exs\"],\n command: \"mix format\",\n },\n \"C#\": {\n extensions: [\"cs\"],\n command: \"dotnet format\",\n },\n };\n\n const config = 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, printScoreCard, printIssue } 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, DiagnosticIssue } 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 printBanner();\n log.step(\"Scanning Claude Code configuration...\");\n log.blank();\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 renderReport(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 overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n const threshold = parseInt(opts.minScore, 10);\n if (overallScore < threshold) {\n process.exit(1);\n }\n }\n });\n}\n\nfunction renderReport(results: ReadonlyArray<AnalyzerResult>): void {\n const overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n\n // Score cards\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 // Issues list\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;\n }\n\n for (const issue of sortBySeverity(actionable)) {\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}\n\nfunction sortBySeverity(issues: ReadonlyArray<DiagnosticIssue>): ReadonlyArray<DiagnosticIssue> {\n const order: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };\n return [...issues].sort((a, b) => (order[a.severity] ?? 4) - (order[b.severity] ?? 4));\n}\n","import { readFile, readdir, access } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\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// ─── Utilities ───\n\nasync function readFileOrNull(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return null;\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 } from \"node:path\";\nimport type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeRules(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\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","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 — Claude can't connect to external tools\",\n fix: \"Add MCP servers in .claude/settings.json for GitHub, database, docs, etc.\",\n });\n return { name: \"MCP Servers\", issues, score: 50 };\n }\n\n for (const server of servers) {\n // Check stdio servers have a command\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 // Check HTTP/SSE servers have a URL\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 // Check stdio commands point to existing executables\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+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 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 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 const formatters: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: { extensions: [\"ts\", \"tsx\"], command: detected.formatCommand ?? \"npx prettier --write\" },\n JavaScript: { extensions: [\"js\", \"jsx\"], command: detected.formatCommand ?? \"npx prettier --write\" },\n Python: { extensions: [\"py\"], command: detected.formatCommand ?? \"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: detected.formatCommand ?? \"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 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 { watch } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { log, printScoreCard, printIssue } 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 .claude/ and CLAUDE.md for changes. Re-run doctor on every save.\n * Clears screen and shows live score.\n */\nexport async function watchConfig(projectRoot: string): Promise<void> {\n const claudeDir = join(projectRoot, \".claude\");\n const claudeMd = join(projectRoot, \"CLAUDE.md\");\n const claudeignore = join(projectRoot, \".claudeignore\");\n\n // Initial run\n await runAndDisplay(projectRoot);\n\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n\n let debounce: ReturnType<typeof setTimeout> | null = null;\n\n const onChange = () => {\n if (debounce) clearTimeout(debounce);\n debounce = setTimeout(async () => {\n console.clear();\n await runAndDisplay(projectRoot);\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n }, 300);\n };\n\n // Watch .claude/ directory\n try {\n watch(claudeDir, { recursive: true }, onChange);\n } catch {\n // .claude/ might not exist yet\n }\n\n // Watch CLAUDE.md\n try {\n watch(claudeMd, onChange);\n } catch {\n // CLAUDE.md might not exist yet\n }\n\n // Watch .claudeignore\n try {\n watch(claudeignore, onChange);\n } catch {\n // .claudeignore might not exist yet\n }\n\n // Keep process alive\n await new Promise(() => {});\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 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;\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}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\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 .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 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 },\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}\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.dim(\"─\")} ${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 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}\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);\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): 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 },\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);\n }\n}\n\nasync function runClaudeCli(\n cwd: string,\n prompt: string,\n timeout: number,\n): Promise<void> {\n try {\n await exec(\n \"claude\",\n [\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 { cwd, timeout, maxBuffer: 10 * 1024 * 1024 },\n );\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\n1. **## Architecture** or **## Project Structure** — describe the actual codebase structure (directories, key files, data flow)\n2. **## Conventions** — add project-specific patterns you observe (naming, imports, state management, API patterns)\n3. **## Off-Limits** — add guardrails based on what you see (protected files, patterns to avoid, things that should never change)\n4. **## Key Decisions** — document any architectural decisions visible in the code\n\nRules:\n- Keep CLAUDE.md under 150 instructions (lines of actionable content)\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\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","access","join","readFile","join","readdir","fileExists","join","readFile","Command","readFile","access","join","readFileOrNull","readFile","basename","access","readFile","writeFile","mkdir","access","join","join","readFile","writeFile","access","mkdir","join","join","Command","Command","chalk","readFile","readdir","access","join","resolve","resolve","access","join","readFile","readdir","mkdir","writeFile","readFile","readdir","join","dirname","Command","chalk","execFile","promisify","exec","Command","execFile","promisify","access","join","promisify","execFile","Command","join","access","resolve","Command","fileExists","join","access"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-launchpad",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "CLI toolkit that makes Claude Code setups measurably good — scaffold, diagnose, evaluate",
5
5
  "type": "module",
6
6
  "bin": {