claude-launchpad 1.7.2 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +2 -1
  2. package/dist/{chunk-XL4ZMHA7.js → chunk-COGKNJJB.js} +14 -20
  3. package/dist/chunk-COGKNJJB.js.map +1 -0
  4. package/dist/{chunk-XJZZJEXT.js → chunk-H2E7QMF4.js} +2 -2
  5. package/dist/{chunk-UHZ2B7BE.js → chunk-IY3Z54UK.js} +166 -117
  6. package/dist/chunk-IY3Z54UK.js.map +1 -0
  7. package/dist/{chunk-N4GESFQC.js → chunk-RDID5P4K.js} +2 -2
  8. package/dist/{chunk-VLB5TDFF.js → chunk-THDBKJAV.js} +3 -3
  9. package/dist/cli.js +124 -32
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands/memory/server.js +3 -3
  12. package/dist/{context-USZJ232G.js → context-BCTOCTZD.js} +5 -5
  13. package/dist/{install-FUXDR2HU.js → install-L23C4YWJ.js} +58 -5
  14. package/dist/install-L23C4YWJ.js.map +1 -0
  15. package/dist/{pull-IZB5D5FC.js → pull-5KYLJ6TH.js} +7 -7
  16. package/dist/{push-IUNXSJZ5.js → push-UOVLT5HO.js} +7 -7
  17. package/dist/{require-deps-Z3CV2I3V.js → require-deps-T2QOGQQ3.js} +3 -3
  18. package/dist/{stats-FMKE3T6J.js → stats-GL7P24U7.js} +6 -6
  19. package/dist/{sync-clean-33V4VWRI.js → sync-clean-7RNYS7EH.js} +3 -3
  20. package/dist/{sync-status-5GMPSUQF.js → sync-status-ULZCMBQJ.js} +14 -9
  21. package/dist/sync-status-ULZCMBQJ.js.map +1 -0
  22. package/dist/{tui-7YXGNXCP.js → tui-UGBWF2WT.js} +4 -4
  23. package/package.json +1 -1
  24. package/dist/chunk-UHZ2B7BE.js.map +0 -1
  25. package/dist/chunk-XL4ZMHA7.js.map +0 -1
  26. package/dist/install-FUXDR2HU.js.map +0 -1
  27. package/dist/sync-status-5GMPSUQF.js.map +0 -1
  28. /package/dist/{chunk-XJZZJEXT.js.map → chunk-H2E7QMF4.js.map} +0 -0
  29. /package/dist/{chunk-N4GESFQC.js.map → chunk-RDID5P4K.js.map} +0 -0
  30. /package/dist/{chunk-VLB5TDFF.js.map → chunk-THDBKJAV.js.map} +0 -0
  31. /package/dist/{context-USZJ232G.js.map → context-BCTOCTZD.js.map} +0 -0
  32. /package/dist/{pull-IZB5D5FC.js.map → pull-5KYLJ6TH.js.map} +0 -0
  33. /package/dist/{push-IUNXSJZ5.js.map → push-UOVLT5HO.js.map} +0 -0
  34. /package/dist/{require-deps-Z3CV2I3V.js.map → require-deps-T2QOGQQ3.js.map} +0 -0
  35. /package/dist/{stats-FMKE3T6J.js.map → stats-GL7P24U7.js.map} +0 -0
  36. /package/dist/{sync-clean-33V4VWRI.js.map → sync-clean-7RNYS7EH.js.map} +0 -0
  37. /package/dist/{tui-7YXGNXCP.js.map → tui-UGBWF2WT.js.map} +0 -0
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/init/index.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/backlog.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/hook-resolver.ts","../src/commands/doctor/analyzers/memory.ts","../src/commands/doctor/analyzers/quality-intents.ts","../src/commands/doctor/analyzers/quality.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/memory/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { join } from \"node:path\";\nimport { createInitCommand } from \"./commands/init/index.js\";\nimport { createDoctorCommand } from \"./commands/doctor/index.js\";\nimport { createEvalCommand } from \"./commands/eval/index.js\";\nimport { createMemoryCommand } from \"./commands/memory/index.js\";\nimport { printBanner, log } from \"./lib/output.js\";\nimport { fileExists } from \"./lib/fs-utils.js\";\n\nconst program = new Command()\n .name(\"claude-launchpad\")\n .description(\"CLI toolkit that makes Claude Code setups measurably good\")\n .version(\"1.7.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(\"Use `/lp-enhance` skill inside Claude Code to AI-complete your CLAUDE.md\");\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(createEvalCommand());\nprogram.addCommand(createMemoryCommand());\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { input, confirm, select } from \"@inquirer/prompts\";\nimport { writeFile, mkdir, readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { printBanner, log } from \"../../lib/output.js\";\nimport { fileExists } from \"../../lib/fs-utils.js\";\nimport { detectProject } from \"../../lib/detect.js\";\nimport type { InitOptions, DetectedProject } from \"../../types/index.js\";\nimport { generateClaudeMd } from \"./generators/claude-md.js\";\nimport { generateTasksMd } from \"./generators/tasks-md.js\";\nimport { generateSettings } from \"./generators/settings.js\";\nimport { generateClaudeignore } from \"./generators/claudeignore.js\";\nimport { generateEnhanceSkill } from \"./generators/skill-enhance.js\";\nimport { generateBacklogMd } from \"./generators/backlog.js\";\nimport { SKILL_AUTHORING_CONTENT } from \"../../lib/sections.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) {\n if (opts.yes) {\n log.info(\"CLAUDE.md already exists. Use `doctor --fix` to update, or re-run without --yes to overwrite.\");\n return;\n }\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 await createEnhanceSkillPrompt(root, false);\n log.step(\"Tip: run `claude-launchpad doctor` to check your existing config\");\n return;\n }\n }\n\n await scaffold(root, options, detected, opts.yes);\n });\n}\n\nasync function scaffold(root: string, options: InitOptions, detected: DetectedProject, skipPrompts: boolean): Promise<void> {\n log.step(\"Generating configuration...\");\n\n const claudeMd = generateClaudeMd(options, detected);\n const tasksMd = generateTasksMd(options);\n const backlogMd = generateBacklogMd(options);\n const settings = generateSettings(detected);\n const claudeignore = generateClaudeignore(detected);\n\n await mkdir(join(root, \".claude\", \"rules\"), { recursive: true });\n\n // Merge with existing settings.json instead of overwriting\n const settingsPath = join(root, \".claude\", \"settings.json\");\n const mergedSettings = await mergeSettings(settingsPath, settings as unknown as Record<string, unknown>);\n\n // Only generate files that don't exist yet\n const backlogPath = join(root, \"BACKLOG.md\");\n const hasBacklog = await fileExists(backlogPath);\n const claudeignorePath = join(root, \".claudeignore\");\n const hasClaudeignore = await fileExists(claudeignorePath);\n const claudeGitignorePath = join(root, \".claude\", \".gitignore\");\n const hasClaudeGitignore = await fileExists(claudeGitignorePath);\n const rulesPath = join(root, \".claude\", \"rules\", \"conventions.md\");\n const hasRules = await fileExists(rulesPath);\n\n const writes: Promise<void>[] = [\n writeFile(join(root, \"CLAUDE.md\"), claudeMd),\n writeFile(join(root, \"TASKS.md\"), tasksMd),\n writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2) + \"\\n\"),\n ];\n\n if (!hasBacklog) {\n writes.push(writeFile(backlogPath, backlogMd));\n }\n\n if (!hasClaudeignore) {\n writes.push(writeFile(claudeignorePath, claudeignore));\n }\n\n if (!hasClaudeGitignore) {\n writes.push(writeFile(claudeGitignorePath, [\n \"# Local-only Claude Code files (never commit these)\",\n \"CLAUDE.md\",\n \"settings.local.json\",\n \"plans/\",\n \"memory/\",\n \"sessions/\",\n \"tmp/\",\n \"\",\n ].join(\"\\n\")));\n }\n\n if (!hasRules) {\n const rulesContent = generateStarterRules(detected);\n writes.push(writeFile(rulesPath, rulesContent));\n }\n\n await Promise.all(writes);\n\n log.success(\"Generated CLAUDE.md\");\n log.success(\"Generated TASKS.md\");\n if (!hasBacklog) log.success(\"Generated BACKLOG.md\");\n log.success(\"Generated .claude/settings.json (schema, permissions, hooks)\");\n if (!hasClaudeGitignore) log.success(\"Generated .claude/.gitignore\");\n if (!hasClaudeignore) log.success(\"Generated .claudeignore\");\n if (!hasRules) log.success(\"Generated .claude/rules/conventions.md\");\n\n // Offer to create the /lp-enhance skill\n await createEnhanceSkillPrompt(root, skipPrompts);\n\n log.blank();\n log.success(\"Done! Run `claude` to start.\");\n log.info(\"Use `/lp-enhance` inside Claude Code to have AI complete your CLAUDE.md.\");\n log.info(\"Run `claude-launchpad doctor` to check your config quality.\");\n log.blank();\n}\n\nfunction generateStarterRules(detected: DetectedProject): string {\n const lines = [\n \"# Project Conventions\",\n \"\",\n \"- Use conventional commits (feat:, fix:, docs:, refactor:, test:, chore:)\",\n \"- Keep files under 400 lines, functions under 50 lines\",\n \"- Handle errors explicitly - no empty catch blocks\",\n \"- Validate input at system boundaries\",\n ];\n\n if (detected.language === \"TypeScript\" || detected.language === \"JavaScript\") {\n lines.push(\"- Use named exports, no default exports except Next.js pages\");\n lines.push(\"- No `any` types in TypeScript\");\n }\n\n if (detected.language === \"Python\") {\n lines.push(\"- Type hints on all function signatures\");\n lines.push(\"- Async everywhere for I/O operations\");\n }\n\n if (detected.language === \"Go\") {\n lines.push(\"- Table-driven tests\");\n lines.push(\"- Errors are values - handle them, don't ignore them\");\n }\n\n if (detected.language === \"Rust\") {\n lines.push(\"- Prefer Result over unwrap/expect in library code\");\n lines.push(\"- No unsafe blocks without a safety comment\");\n }\n\n // Skill authoring conventions\n lines.push(\"\", \"## Skill Authoring\", \"\", SKILL_AUTHORING_CONTENT);\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n\nasync function createEnhanceSkillPrompt(root: string, skipPrompts: boolean): Promise<void> {\n const projectPath = join(root, \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\");\n const globalPath = join(homedir(), \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\");\n // Also check legacy commands/ location\n const legacyProject = join(root, \".claude\", \"commands\", \"lp-enhance.md\");\n const legacyGlobal = join(homedir(), \".claude\", \"commands\", \"lp-enhance.md\");\n\n if (await fileExists(projectPath) || await fileExists(globalPath)\n || await fileExists(legacyProject) || await fileExists(legacyGlobal)) return;\n\n const scope = skipPrompts ? \"project\" : await select({\n message: \"Install /lp-enhance skill (AI-powered CLAUDE.md improver):\",\n choices: [\n { value: \"project\", name: \"Project scope (.claude/skills/)\" },\n { value: \"global\", name: \"Global scope (~/.claude/skills/)\" },\n { value: \"skip\", name: \"Skip\" },\n ],\n });\n\n if (scope === \"skip\") return;\n\n const targetDir = scope === \"global\"\n ? join(homedir(), \".claude\", \"skills\", \"lp-enhance\")\n : join(root, \".claude\", \"skills\", \"lp-enhance\");\n\n await mkdir(targetDir, { recursive: true });\n await writeFile(join(targetDir, \"SKILL.md\"), generateEnhanceSkill());\n log.success(`Generated /lp-enhance skill (${scope} scope)`);\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 type { InitOptions, DetectedProject } from \"../../../types/index.js\";\nimport {\n SESSION_START_CONTENT, BACKLOG_CONTENT, STOP_AND_SWARM_CONTENT, OFF_LIMITS_CONTENT,\n} from \"../../../lib/sections.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${SESSION_START_CONTENT}`);\n\n // Backlog\n sections.push(\"\", `## Backlog\\n${BACKLOG_CONTENT}`);\n\n // Sprint Reviews\n sections.push(\"\", `## Sprint Reviews\nWhen all tasks in the current sprint are complete, do a quick quality check before committing:\n- Scan changed files for dead code, debug logs, and TODO hacks\n- Run tests and type-checker if available\n- Check for convention violations and hardcoded values\n- Fix any issues, then commit\n- Skip if the sprint was trivial (docs, config-only changes)`);\n\n // Conventions\n sections.push(\"\", `## Conventions\n- Git: Conventional commits (\\`feat:\\`, \\`fix:\\`, \\`docs:\\`, \\`refactor:\\`, \\`test:\\`, \\`chore:\\`)`);\n\n // Stop-and-Swarm\n sections.push(\"\", `## Stop-and-Swarm\\n${STOP_AND_SWARM_CONTENT}`);\n\n // Off-Limits\n sections.push(\"\", `## Off-Limits\\n${OFF_LIMITS_CONTENT}`);\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 at session start. Keep SHORT — only current state matters.\n> Completed sprints: one-liner. Session log: 3 lines max, last 3 sessions. Under 80 lines.\n\n## Completed Sprints\n\n## Current: Sprint 1 — Setup\n- [ ] Project scaffolding and environment setup\n- [ ] Core feature implementation\n- [ ] Test infrastructure\n\n## Session Log\n`;\n}\n","import type { DetectedProject } from \"../../../types/index.js\";\n\ninterface HookEntry {\n readonly type: \"command\";\n readonly command: string;\n}\n\ninterface HookGroup {\n readonly matcher: string;\n readonly hooks: ReadonlyArray<HookEntry>;\n}\n\ninterface ClaudeSettings {\n readonly $schema?: string;\n readonly permissions?: {\n readonly deny?: ReadonlyArray<string>;\n };\n readonly hooks?: Record<string, ReadonlyArray<HookGroup>>;\n readonly disableBypassPermissionsMode?: \"disable\";\n}\n\n/**\n * Generate .claude/settings.json based on detected project.\n * Includes: schema for IDE autocomplete, security deny-lists, hooks.\n */\nexport function generateSettings(detected: DetectedProject): ClaudeSettings {\n const preToolUse: HookGroup[] = [];\n const postToolUse: HookGroup[] = [];\n\n // Universal: .env file protection (block read + write)\n preToolUse.push({\n matcher: \"Read|Write|Edit\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -qE '\\\\.(env|env\\\\..*)$' && ! echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -q '.env.example' && echo 'BLOCKED: .env files contain secrets' && exit 1; exit 0\",\n }],\n });\n\n // Universal: block destructive commands\n preToolUse.push({\n matcher: \"Bash\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_COMMAND\\\" | grep -qE 'rm\\\\s+-rf\\\\s+/|DROP\\\\s+TABLE|DROP\\\\s+DATABASE|push.*--force|push.*-f' && echo 'BLOCKED: Destructive command detected' && exit 1; exit 0\",\n }],\n });\n\n // Auto-format based on detected tooling\n const formatHook = buildFormatHook(detected);\n if (formatHook) {\n postToolUse.push(formatHook);\n }\n\n // Sprint review: nudge when all current sprint tasks are complete\n postToolUse.push({\n matcher: \"Edit|Write\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -q TASKS.md || exit 0; section=$(sed -n '/^## Current Sprint/,/^## /p' TASKS.md 2>/dev/null); [ -z \\\"$section\\\" ] && exit 0; unchecked=$(echo \\\"$section\\\" | grep -cF '- [ ]' || true); checked=$(echo \\\"$section\\\" | grep -cF '- [x]' || true); [ \\\"$unchecked\\\" -eq 0 ] && [ \\\"$checked\\\" -gt 0 ] && echo 'Sprint complete — all current tasks done. Consider a quick quality check before committing: scan for dead code, debug artifacts, TODO hacks, and convention violations. Run tests if available. Skip if trivial.'; exit 0\",\n }],\n });\n\n // SessionStart: inject TASKS.md at session startup\n const sessionStart: HookGroup[] = [{\n matcher: \"startup|resume\",\n hooks: [{\n type: \"command\",\n command: \"cat TASKS.md 2>/dev/null; exit 0\",\n }],\n }];\n\n // PostCompact: re-inject TASKS.md so session continuity survives compaction\n const postCompact: HookGroup[] = [{\n matcher: \"\",\n hooks: [{\n type: \"command\",\n command: \"cat TASKS.md 2>/dev/null; exit 0\",\n }],\n }];\n\n const hooks: Record<string, ReadonlyArray<HookGroup>> = {};\n hooks.SessionStart = sessionStart;\n if (preToolUse.length > 0) hooks.PreToolUse = preToolUse;\n if (postToolUse.length > 0) hooks.PostToolUse = postToolUse;\n hooks.PostCompact = postCompact;\n\n return {\n $schema: \"https://json.schemastore.org/claude-code-settings.json\",\n permissions: {\n deny: [\n \"Bash(rm -rf /)\",\n \"Bash(rm -rf ~)\",\n \"Read(.env)\",\n \"Read(.env.*)\",\n \"Read(secrets/**)\",\n \"Read(~/.ssh/*)\",\n \"Read(~/.aws/*)\",\n \"Read(~/.npmrc)\",\n ],\n },\n hooks,\n disableBypassPermissionsMode: \"disable\",\n };\n}\n\n// Safe formatter commands - never interpolate user-controlled strings\nconst SAFE_FORMATTERS: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: { extensions: [\"ts\", \"tsx\"], command: \"npx prettier --write\" },\n JavaScript: { extensions: [\"js\", \"jsx\"], command: \"npx prettier --write\" },\n Python: { extensions: [\"py\"], command: \"ruff format\" },\n Go: { extensions: [\"go\"], command: \"gofmt -w\" },\n Rust: { extensions: [\"rs\"], command: \"rustfmt\" },\n Ruby: { extensions: [\"rb\"], command: \"rubocop -A\" },\n Dart: { extensions: [\"dart\"], command: \"dart format\" },\n PHP: { extensions: [\"php\"], command: \"vendor/bin/pint\" },\n Kotlin: { extensions: [\"kt\", \"kts\"], command: \"ktlint -F\" },\n Java: { extensions: [\"java\"], command: \"google-java-format -i\" },\n Swift: { extensions: [\"swift\"], command: \"swift-format format -i\" },\n Elixir: { extensions: [\"ex\", \"exs\"], command: \"mix format\" },\n \"C#\": { extensions: [\"cs\"], command: \"dotnet format\" },\n};\n\nfunction buildFormatHook(detected: DetectedProject): HookGroup | null {\n if (!detected.language) return null;\n\n const config = SAFE_FORMATTERS[detected.language];\n if (!config) return null;\n\n const extChecks = config.extensions\n .map((ext) => `[ \"$ext\" = \"${ext}\" ]`)\n .join(\" || \");\n\n return {\n matcher: \"Write|Edit\",\n hooks: [{\n type: \"command\",\n command: `ext=\\${TOOL_INPUT_FILE_PATH##*.}; (${extChecks}) && ${config.command} \"$TOOL_INPUT_FILE_PATH\" 2>/dev/null; exit 0`,\n }],\n };\n}\n","import type { InitOptions } from \"../../../types/index.js\";\n\nexport function generateBacklogMd(options: InitOptions): string {\n return `# ${options.name} - Backlog\n\n> Features discussed but deferred. Pick up when relevant.\n> Priority: P0 = next sprint, P1 = soon, P2 = when relevant.\n\n<!-- Add deferred features here. Format:\n## [P1] Feature Name\nOne-line description. Context for why it was deferred and when to revisit.\n-->\n`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { printBanner, log, renderDoctorReport } from \"../../lib/output.js\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { analyzeBudget } from \"./analyzers/budget.js\";\nimport { analyzeSettings } from \"./analyzers/settings.js\";\nimport { analyzeHooks } from \"./analyzers/hooks.js\";\nimport { analyzeRules } from \"./analyzers/rules.js\";\nimport { analyzePermissions } from \"./analyzers/permissions.js\";\nimport { analyzeMcp } from \"./analyzers/mcp.js\";\nimport { analyzeQuality } from \"./analyzers/quality.js\";\nimport { analyzeMemory } from \"./analyzers/memory.js\";\nimport { applyFixes } from \"./fixer.js\";\nimport { watchConfig } from \"./watcher.js\";\nimport type { AnalyzerResult } from \"../../types/index.js\";\n\nexport function createDoctorCommand(): Command {\n return new Command(\"doctor\")\n .description(\"Diagnose your Claude Code configuration and report issues\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .option(\"--json\", \"Output as JSON\")\n .option(\"--min-score <n>\", \"Exit non-zero if overall score is below this threshold (for CI)\")\n .option(\"--fix\", \"Auto-apply deterministic fixes for detected issues\")\n .option(\"--dry-run\", \"Preview what --fix would change without applying\")\n .option(\"--watch\", \"Watch for config changes and re-run automatically\")\n .action(async (opts) => {\n if (opts.watch) {\n await watchConfig(opts.path);\n return;\n }\n\n if (!opts.json) {\n printBanner();\n log.step(\"Scanning Claude Code configuration...\");\n log.blank();\n }\n\n const config = await parseClaudeConfig(opts.path);\n\n if (config.claudeMdContent === null && config.settings === null) {\n log.error(\"No Claude Code configuration found in this directory.\");\n log.info(\"Run `claude-launchpad init` to set up a project, or cd into a configured project.\");\n process.exit(1);\n }\n\n const results: AnalyzerResult[] = await Promise.all([\n analyzeBudget(config),\n analyzeQuality(config, opts.path),\n analyzeSettings(config),\n analyzeHooks(config),\n analyzeRules(config),\n analyzePermissions(config),\n analyzeMcp(config),\n ]);\n\n const memoryResult = await analyzeMemory(config, opts.path);\n if (memoryResult) {\n results.push(memoryResult);\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 // Skip rendering the initial report when --fix is used — only show the post-fix result\n let overallScore = Math.round(results.reduce((sum, r) => sum + r.score, 0) / results.length);\n if (!opts.fix) {\n renderDoctorReport(results);\n }\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 renderDoctorReport(results);\n log.success(\"Nothing to fix.\");\n } else if (fixable.length > 0) {\n // Dry-run: preview only\n if (opts.dryRun) {\n const withFix = fixable.filter((i) => i.fix);\n log.blank();\n log.step(\"Dry run — would apply:\");\n log.blank();\n for (const issue of withFix) {\n log.info(` ${issue.fix}`);\n }\n const skipped = fixable.length - withFix.length;\n log.blank();\n log.success(`${withFix.length} fix(es) available. Run --fix without --dry-run to apply.`);\n if (skipped > 0) {\n log.info(`${skipped} issue(s) require manual intervention.`);\n }\n log.info(`Then use ${chalk.bold(\"/lp-enhance\")} inside Claude Code to have Claude restructure and complete your CLAUDE.md.`);\n return;\n }\n\n log.blank();\n log.step(\"Applying fixes...\");\n log.blank();\n const { fixed } = await applyFixes(fixable, opts.path);\n log.blank();\n if (fixed > 0) {\n log.success(`Applied ${fixed} fix(es). Re-scanning...`);\n log.blank();\n }\n\n // Always re-scan and show report after --fix attempt\n const updatedConfig = await parseClaudeConfig(opts.path);\n const updatedResults: AnalyzerResult[] = await Promise.all([\n analyzeBudget(updatedConfig),\n analyzeQuality(updatedConfig, opts.path),\n analyzeSettings(updatedConfig),\n analyzeHooks(updatedConfig),\n analyzeRules(updatedConfig),\n analyzePermissions(updatedConfig),\n analyzeMcp(updatedConfig),\n ]);\n\n const updatedMemoryResult = await analyzeMemory(updatedConfig, opts.path);\n if (updatedMemoryResult) {\n updatedResults.push(updatedMemoryResult);\n }\n renderDoctorReport(updatedResults, { afterFix: true });\n log.info(`Then use ${chalk.bold(\"/lp-enhance\")} inside Claude Code to have Claude restructure and complete your CLAUDE.md.`);\n }\n }\n\n // CI mode: exit non-zero if score is below threshold\n if (opts.minScore) {\n const threshold = parseInt(opts.minScore, 10);\n if (overallScore < threshold) {\n process.exit(1);\n }\n }\n });\n}\n","import { readdir, access } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { readFileOrNull } from \"./fs-utils.js\";\nimport type { ClaudeConfig, HookConfig, McpServerConfig } from \"../types/index.js\";\n\nconst CLAUDE_MD = \"CLAUDE.md\";\nconst CLAUDE_DIR = \".claude\";\nconst SETTINGS_FILE = \"settings.json\";\nconst SETTINGS_LOCAL_FILE = \"settings.local.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, localClaudeMd, settings, localSettings, hooks, rules, mcpServers, skills, claudeignore] = await Promise.all([\n readClaudeMd(root),\n readFileOrNull(join(claudeDir, CLAUDE_MD)),\n readSettings(claudeDir),\n readSettingsFromFile(claudeDir, SETTINGS_LOCAL_FILE),\n readHooks(claudeDir),\n readRules(claudeDir),\n readMcpServers(claudeDir, root),\n readSkills(claudeDir),\n readFileOrNull(join(root, \".claudeignore\")),\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 localClaudeMdContent: localClaudeMd,\n localSettings,\n hooks,\n rules,\n mcpServers,\n skills,\n claudeignorePath: claudeignore !== null ? join(root, \".claudeignore\") : null,\n claudeignoreContent: claudeignore,\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 return readSettingsFromFile(claudeDir, SETTINGS_FILE);\n}\n\nasync function readSettingsFromFile(claudeDir: string, filename: string): Promise<Record<string, unknown> | null> {\n const raw = await readFileOrNull(join(claudeDir, filename));\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 [shared, local] = await Promise.all([\n readHooksFromFile(join(claudeDir, SETTINGS_FILE)),\n readHooksFromFile(join(claudeDir, SETTINGS_LOCAL_FILE)),\n ]);\n return [...shared, ...local];\n}\n\nasync function readHooksFromFile(settingsPath: string): Promise<ReadonlyArray<HookConfig>> {\n const settingsRaw = await readFileOrNull(settingsPath);\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 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 timeout: h.timeout as number | undefined,\n });\n }\n } else {\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 timeout: g.timeout as number | 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, projectRoot: string): Promise<ReadonlyArray<McpServerConfig>> {\n const [fromMcpJson, fromSettings, fromLocalSettings] = await Promise.all([\n readMcpJsonFile(join(projectRoot, \".mcp.json\")),\n readMcpServersFromSettings(join(claudeDir, SETTINGS_FILE)),\n readMcpServersFromSettings(join(claudeDir, SETTINGS_LOCAL_FILE)),\n ]);\n // Deduplicate by name — .mcp.json > local settings > shared settings\n const seen = new Set<string>();\n const result: McpServerConfig[] = [];\n for (const server of [...fromMcpJson, ...fromLocalSettings, ...fromSettings]) {\n if (!seen.has(server.name)) {\n seen.add(server.name);\n result.push(server);\n }\n }\n return result;\n}\n\n/** Read .mcp.json (project-scoped MCP config created by `claude mcp add --scope project`) */\nasync function readMcpJsonFile(mcpJsonPath: string): Promise<ReadonlyArray<McpServerConfig>> {\n const raw = await readFileOrNull(mcpJsonPath);\n if (raw === null) return [];\n\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n const servers = parsed.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 ?? c.type) 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\nasync function readMcpServersFromSettings(settingsPath: string): Promise<ReadonlyArray<McpServerConfig>> {\n const settingsRaw = await readFileOrNull(settingsPath);\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 ?? c.type) as McpServerConfig[\"transport\"]) ?? \"stdio\",\n command: c.command as string | undefined,\n url: c.url as string | undefined,\n });\n }\n return result;\n } catch {\n return [];\n }\n}\n\n// ─── Skills ───\n\nasync function readSkills(claudeDir: string): Promise<ReadonlyArray<string>> {\n const commandsDir = join(claudeDir, \"commands\");\n const skillsDir = join(claudeDir, \"skills\");\n\n const [commands, skills] = await Promise.all([\n listFilesRecursive(commandsDir, \".md\"),\n listFilesRecursive(skillsDir, \".md\"),\n ]);\n\n return [...commands, ...skills];\n}\n\n\nasync function listFilesRecursive(dir: string, ext: string): Promise<string[]> {\n try {\n await access(dir);\n } catch {\n return [];\n }\n\n const results: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const nested = await listFilesRecursive(fullPath, ext);\n results.push(...nested);\n } else if (entry.name.endsWith(ext)) {\n results.push(fullPath);\n }\n }\n\n return results;\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nconst BUDGET_WARN = 150;\nconst BUDGET_DANGER = 200;\nconst BUDGET_CRITICAL = 250;\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 ~200 budget. Compliance drops significantly past 200.`,\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 ~200 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 ~200 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 // 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 // Deprecated includeCoAuthoredBy\n if (config.settings.includeCoAuthoredBy !== undefined) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"low\",\n message: \"Deprecated includeCoAuthoredBy — use attribution: { commit: \\\"\\\", pr: \\\"\\\" } instead\",\n fix: \"Replace includeCoAuthoredBy with the attribution object in settings.json\",\n });\n }\n\n // Monorepo hint — claudeMdExcludes\n if (!config.settings.claudeMdExcludes) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"info\",\n message: \"No claudeMdExcludes configured — consider adding this if you have a monorepo\",\n });\n }\n\n\n // Auto-memory disabled\n if (config.settings.autoMemoryEnabled === false) {\n const hasMemorySection = config.claudeMdContent?.includes(\"## Memory\") ?? false;\n if (!hasMemorySection) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"medium\",\n message: \"Auto-memory is disabled with no manual memory strategy in CLAUDE.md\",\n fix: \"Re-enable autoMemoryEnabled or add a ## Memory section to CLAUDE.md\",\n });\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 // Check for PostCompact hook (session continuity)\n const hasPostCompact = hooks.some((h) => h.event === \"PostCompact\");\n if (!hasPostCompact) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"low\",\n message: \"No PostCompact hook — session context is lost when conversation is compacted\",\n fix: \"Add a PostCompact hook that re-injects TASKS.md after compaction\",\n });\n }\n\n // Check for SessionStart hook\n const hasSessionStart = hooks.some((h) => h.event === \"SessionStart\");\n if (!hasSessionStart) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"low\",\n message: \"No SessionStart hook — session starts without project context loaded\",\n fix: \"Add a SessionStart hook that injects TASKS.md at startup\",\n });\n }\n\n const score = Math.max(0, 100 - issues.length * 15);\n return { name: \"Hooks\", issues, score };\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename, join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { fileExists } from \"../../../lib/fs-utils.js\";\nimport { ENHANCE_SKILL_VERSION } from \"../../init/generators/skill-enhance.js\";\nimport type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeRules(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n\n const projectRoot = config.claudeMdPath ? dirname(config.claudeMdPath) : process.cwd();\n\n // Check for BACKLOG.md\n const hasBacklog = await fileExists(join(projectRoot, \"BACKLOG.md\"));\n if (!hasBacklog) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No BACKLOG.md found — deferred features get lost in conversation history\",\n fix: \"Run `claude-launchpad init` or `doctor --fix` to generate one\",\n });\n }\n\n // Check for .claudeignore\n const hasClaudeignore = await fileExists(join(projectRoot, \".claudeignore\"));\n if (!hasClaudeignore) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No .claudeignore found — Claude may read noise files (node_modules, dist, lockfiles)\",\n fix: \"Run `claude-launchpad init` or `doctor --fix` to generate one\",\n });\n }\n\n // Check for /lp-enhance skill (new skills/ format or legacy commands/ format)\n const hasSkillInProject = config.skills.some((s) =>\n basename(s) === \"SKILL.md\" && s.includes(\"lp-enhance\") || basename(s) === \"lp-enhance.md\",\n );\n const hasSkillGlobal = await fileExists(join(homedir(), \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\"))\n || await fileExists(join(homedir(), \".claude\", \"commands\", \"lp-enhance.md\"));\n if (!hasSkillInProject && !hasSkillGlobal) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No /lp-enhance skill found — use it inside Claude Code to AI-complete your CLAUDE.md\",\n fix: \"Run `claude-launchpad init` or `doctor --fix` to generate the skill\",\n });\n } else {\n const installedVersion = await getSkillVersion(projectRoot);\n if (installedVersion !== null && installedVersion < ENHANCE_SKILL_VERSION) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: `/lp-enhance skill is outdated (v${installedVersion}, latest v${ENHANCE_SKILL_VERSION})`,\n fix: \"Run `doctor --fix` to update the skill\",\n });\n }\n }\n\n if (config.rules.length === 0) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No .claude/rules/ files found\",\n fix: \"Move detailed conventions from CLAUDE.md to .claude/rules/*.md (auto-loaded, saves budget)\",\n });\n return { name: \"Rules\", issues, score: 60 };\n }\n\n // Check for skill authoring conventions in any rules file\n let hasSkillAuthoring = false;\n for (const rulePath of config.rules) {\n try {\n const content = await readFile(rulePath, \"utf-8\");\n if (/^##\\s+Skill\\s+Authoring/im.test(content)) {\n hasSkillAuthoring = true;\n break;\n }\n } catch {\n continue;\n }\n }\n if (!hasSkillAuthoring) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No skill authoring conventions found in .claude/rules/\",\n fix: \"Run `doctor --fix` to add a Skill Authoring section to conventions.md\",\n });\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\nasync function getSkillVersion(projectRoot: string): Promise<number | null> {\n const paths = [\n join(projectRoot, \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\"),\n join(homedir(), \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\"),\n ];\n\n for (const p of paths) {\n try {\n const content = await readFile(p, \"utf-8\");\n const match = content.match(/<!-- lp-enhance-version: (\\d+) -->/);\n if (match) return parseInt(match[1], 10);\n // Skill exists but has no version tag — treat as v0 (pre-versioning)\n return 0;\n } catch {\n continue;\n }\n }\n return null;\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 const settings = config.settings;\n const permissions = settings?.permissions as Record<string, unknown> | undefined;\n const denyList = (permissions?.deny as string[] | undefined) ?? [];\n const allowList = (permissions?.allow as string[] | undefined) ?? [];\n\n // Credential file exposure\n const credentialPatterns = [\"Read(~/.ssh/*)\", \"Read(~/.aws/*)\", \"Read(~/.npmrc)\"];\n const missingCreds = credentialPatterns.filter((p) => !denyList.includes(p));\n if (missingCreds.length > 0) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: `Credential files not blocked: ${missingCreds.join(\", \")} — Claude can read SSH keys, AWS creds, or npm tokens`,\n fix: \"Add Read(~/.ssh/*), Read(~/.aws/*), Read(~/.npmrc) to permissions.deny\",\n });\n }\n\n // Blanket Bash approval\n const hasBlanketBash = allowList.some((a) => a === \"Bash\" || (a.startsWith(\"Bash\") && !a.includes(\"(\")));\n if (hasBlanketBash) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: \"Bash is blanket-allowed without pattern restriction — all shell commands are auto-approved\",\n fix: \"Replace blanket Bash with scoped patterns like Bash(npm test) or remove it\",\n });\n }\n\n // Bypass mode unprotected\n if (settings?.disableBypassPermissionsMode !== \"disable\") {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: \"Bypass permissions mode not disabled — --dangerously-skip-permissions bypasses all checks\",\n fix: 'Add \"disableBypassPermissionsMode\": \"disable\" to settings.json',\n });\n }\n\n // Filesystem sandbox actively breaks cross-project tooling (memory MCP, ~/.claude reads)\n const sandbox = settings?.sandbox as Record<string, unknown> | undefined;\n if (sandbox?.enabled === true) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: \"Filesystem sandbox enabled — blocks memory MCP and other cross-project tooling. Deny rules already cover the threat model.\",\n fix: 'Remove the \"sandbox\" block from settings.json',\n });\n }\n\n // .env gap: hooks protect but .claudeignore doesn't\n const hasEnvHook = config.hooks.some((h) => h.command?.includes(\".env\"));\n if (hasEnvHook && config.claudeignoreContent !== null) {\n const lines = config.claudeignoreContent.split(\"\\n\").map((l) => l.trim());\n const hasEnvInIgnore = lines.some((l) => l === \".env\" || l === \".env.*\" || l === \".env*\");\n if (!hasEnvInIgnore) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"medium\",\n message: \".env is protected by hooks but not in .claudeignore — cat .env via Bash bypasses hooks\",\n fix: \"Add .env to .claudeignore for defense in depth\",\n });\n }\n }\n\n // Bash auto-allow without security hooks (existing check)\n const hasBashSecurity = config.hooks.some(\n (h) => h.event === \"PreToolUse\" && (h.matcher?.includes(\"Bash\") || !h.matcher),\n );\n const bashAllowed = settings?.allowedTools as string[] | undefined;\n const hasBashAutoAllow = bashAllowed?.some((t) =>\n typeof t === \"string\" && t.toLowerCase().includes(\"bash\"),\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\",\n });\n }\n\n // 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 // Off-Limits section in CLAUDE.md\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 * 15);\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. Use `/lp-enhance` in Claude Code to get stack-specific recommendations.\",\n });\n return { name: \"MCP Servers\", issues, score: 50 };\n }\n\n for (const server of servers) {\n if (server.transport === \"stdio\" && !server.command) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"high\",\n message: `MCP server \"${server.name}\" uses stdio transport but has no command`,\n fix: `Add a \"command\" field to the \"${server.name}\" MCP server config`,\n });\n }\n\n if ((server.transport === \"sse\" || server.transport === \"http\") && !server.url) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"high\",\n message: `MCP server \"${server.name}\" uses ${server.transport} transport but has no URL`,\n fix: `Add a \"url\" field to the \"${server.name}\" MCP server config`,\n });\n }\n\n if (server.transport === \"stdio\" && server.command) {\n const executable = server.command.split(\" \")[0];\n if (executable.startsWith(\"/\") || executable.startsWith(\"./\")) {\n try {\n await access(executable);\n } catch {\n issues.push({\n analyzer: \"MCP\",\n severity: \"medium\",\n message: `MCP server \"${server.name}\" command not found: ${executable}`,\n fix: \"Verify the path exists or install the required package\",\n });\n }\n }\n }\n }\n\n // Check for allowedMcpServers when servers are configured\n if (servers.length > 0) {\n const settings = config.settings ?? {};\n const localSettings = config.localSettings ?? {};\n const hasAllowList = settings.allowedMcpServers || localSettings.allowedMcpServers;\n if (!hasAllowList) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"medium\",\n message: \"MCP servers configured but no allowedMcpServers list — any added server is auto-trusted\",\n fix: \"Add allowedMcpServers to settings.json listing only trusted server names\",\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","/**\n * Hook command resolver — transitively expands one level of shell-wrapper indirection.\n *\n * A Claude Code hook like `bash .claude/session-start.sh` delegates capability to a\n * wrapper script. Analyzers inspecting only the literal `command` string miss the\n * wrapper's body. This resolver returns the command text + bodies of referenced .sh\n * files inside the project root so analyzers can run `.includes()` against a single\n * \"effective command\" string.\n *\n * Depth limit: 1 (no recursion into scripts-that-call-scripts).\n * Extension limit: only `.sh` is followed.\n * Root boundary: only paths resolving (via realpath) inside projectRoot are read.\n */\n\nimport { readFile, realpath } from \"node:fs/promises\";\nimport { resolve, sep } from \"node:path\";\nimport { parse } from \"shell-quote\";\n\nexport interface HookExpansion {\n readonly path: string;\n readonly body: string;\n}\n\nexport interface ResolvedHookCommand {\n readonly command: string;\n readonly expansions: readonly HookExpansion[];\n readonly missingScripts: readonly string[];\n}\n\nexport async function resolveHookCommand(\n hook: { readonly command?: string | null },\n projectRoot: string,\n): Promise<ResolvedHookCommand> {\n const command = hook.command ?? \"\";\n if (!command) return { command: \"\", expansions: [], missingScripts: [] };\n\n const scriptPaths = extractShellScripts(command);\n if (scriptPaths.length === 0) return { command, expansions: [], missingScripts: [] };\n\n let projectRootReal: string;\n try {\n projectRootReal = await realpath(projectRoot);\n } catch {\n return { command, expansions: [], missingScripts: [] };\n }\n\n const expansions: HookExpansion[] = [];\n const missingScripts: string[] = [];\n\n for (const relPath of scriptPaths) {\n const resolved = resolve(projectRoot, relPath);\n let realResolved: string;\n try {\n realResolved = await realpath(resolved);\n } catch {\n missingScripts.push(relPath);\n continue;\n }\n if (realResolved !== projectRootReal && !realResolved.startsWith(projectRootReal + sep)) {\n continue;\n }\n try {\n const body = await readFile(realResolved, \"utf-8\");\n expansions.push({ path: relPath, body });\n } catch {\n missingScripts.push(relPath);\n }\n }\n\n return { command, expansions, missingScripts };\n}\n\nexport function effectiveCommandText(resolved: ResolvedHookCommand): string {\n if (resolved.expansions.length === 0) return resolved.command;\n return resolved.command + \"\\n\" + resolved.expansions.map((e) => e.body).join(\"\\n\");\n}\n\nfunction extractShellScripts(command: string): readonly string[] {\n const tokens = parse(command);\n const scripts: string[] = [];\n for (const token of tokens) {\n if (typeof token !== \"string\") continue;\n if (!token.endsWith(\".sh\")) continue;\n if (token.startsWith(\"~\") || token.startsWith(\"$\")) continue;\n scripts.push(token);\n }\n return scripts;\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\nimport { readSyncConfig } from \"../../memory/utils/gist-transport.js\";\nimport {\n resolveHookCommand,\n effectiveCommandText,\n type ResolvedHookCommand,\n} from \"./hook-resolver.js\";\n\nconst MEMORY_MCP_TOOLS = [\n \"mcp__agentic-memory__memory_store\",\n \"mcp__agentic-memory__memory_search\",\n \"mcp__agentic-memory__memory_recent\",\n \"mcp__agentic-memory__memory_forget\",\n \"mcp__agentic-memory__memory_relate\",\n \"mcp__agentic-memory__memory_stats\",\n \"mcp__agentic-memory__memory_update\",\n] as const;\n\nasync function resolveAllHooks(\n hooks: ClaudeConfig[\"hooks\"],\n projectRoot: string,\n): Promise<ResolvedHookCommand[]> {\n return Promise.all(hooks.map((h) => resolveHookCommand(h, projectRoot)));\n}\n\nexport async function hasMemoryIndicators(\n config: ClaudeConfig,\n projectRoot: string,\n): Promise<boolean> {\n // MCP server in project settings (shared or local)\n if (config.mcpServers.some((s) => s.name === \"agentic-memory\")) return true;\n\n // Tool permissions referencing agentic-memory (server may be registered via `claude mcp add`)\n const permissions = (config.settings?.permissions as Record<string, unknown> | undefined) ?? {};\n const localPermissions = (config.localSettings?.permissions as Record<string, unknown> | undefined) ?? {};\n const allowList = [\n ...((permissions.allow as string[] | undefined) ?? []),\n ...((localPermissions.allow as string[] | undefined) ?? []),\n ];\n if (allowList.some((t) => t.startsWith(\"mcp__agentic-memory__\"))) return true;\n\n // SessionStart hook referencing memory context injection — see through 1-level wrappers\n const resolved = await resolveAllHooks(config.hooks, projectRoot);\n return config.hooks.some((h, i) =>\n h.event === \"SessionStart\" && effectiveCommandText(resolved[i]).includes(\"memory context\"),\n );\n}\n\n/**\n * Analyzes agentic-memory configuration.\n * Returns null if memory is not detected — doctor skips it for non-memory users.\n */\nexport async function analyzeMemory(\n config: ClaudeConfig,\n projectRoot: string,\n): Promise<AnalyzerResult | null> {\n if (!await hasMemoryIndicators(config, projectRoot)) return null;\n\n const issues: DiagnosticIssue[] = [];\n const resolved = await resolveAllHooks(config.hooks, projectRoot);\n const effectiveAt = (i: number): string => effectiveCommandText(resolved[i]);\n\n // 1. SessionStart hook with memory context (wrapper-aware)\n const hasSessionStart = config.hooks.some(\n (h, i) => h.event === \"SessionStart\" && effectiveAt(i).includes(\"memory context\"),\n );\n if (!hasSessionStart) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"high\",\n message: \"No SessionStart hook with memory context injection\",\n fix: \"Add a SessionStart hook that runs `memory context` to inject relevant memories\",\n });\n }\n\n // 2. Deprecated Stop hook with memory extract (removed in v0.14.0)\n const hasStaleStopHook = config.hooks.some(\n (h, i) => h.event === \"Stop\" && effectiveAt(i).includes(\"memory extract\"),\n );\n if (hasStaleStopHook) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"low\",\n message: \"Deprecated Stop hook found (memory extract) — auto-extraction was removed, Claude stores memories directly via MCP tools\",\n fix: \"Run `doctor --fix` to remove the stale Stop hook\",\n });\n }\n\n // 3. autoMemoryEnabled should be false (built-in memory conflicts with agentic-memory)\n const autoMemoryDisabled = config.settings?.autoMemoryEnabled === false\n || config.localSettings?.autoMemoryEnabled === false;\n if (!autoMemoryDisabled) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"medium\",\n message: \"autoMemoryEnabled not disabled — built-in memory may conflict with agentic-memory\",\n fix: \"Set autoMemoryEnabled: false in settings.json or settings.local.json\",\n });\n }\n\n // 5. CLAUDE.md memory guidance (check both shared and local)\n const hasMemoryGuidance = config.claudeMdContent?.includes(\"agentic-memory\")\n || config.claudeMdContent?.includes(\"## Memory\")\n || config.localClaudeMdContent?.includes(\"agentic-memory\")\n || config.localClaudeMdContent?.includes(\"## Memory\");\n if (!hasMemoryGuidance) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"low\",\n message: \"CLAUDE.md missing memory guidance section\",\n fix: \"Add a ## Memory section to CLAUDE.md describing when and how to use agentic-memory\",\n });\n }\n\n // 6. MCP tool permissions (check both shared and local settings)\n const permissions = (config.settings?.permissions as Record<string, unknown> | undefined) ?? {};\n const localPermissions = (config.localSettings?.permissions as Record<string, unknown> | undefined) ?? {};\n const allowList = [\n ...((permissions.allow as string[] | undefined) ?? []),\n ...((localPermissions.allow as string[] | undefined) ?? []),\n ];\n const missingTools = MEMORY_MCP_TOOLS.filter((t) => !allowList.includes(t));\n if (missingTools.length > 0) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"low\",\n message: `${missingTools.length} agentic-memory MCP tool permission(s) missing from allowedTools`,\n fix: \"Add all agentic-memory tool names to allowedTools in .claude/settings.json\",\n });\n }\n\n // 7. Sync hooks when sync is configured (wrapper-aware)\n const syncConfig = readSyncConfig();\n if (syncConfig) {\n const hasSessionStartPull = config.hooks.some(\n (h, i) => h.event === \"SessionStart\" && effectiveAt(i).includes(\"memory pull\"),\n );\n if (!hasSessionStartPull) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"medium\",\n message: \"Sync configured but no SessionStart hook to auto-pull memories before context injection\",\n fix: \"Run `doctor --fix` to add a SessionStart hook that pulls memories automatically\",\n });\n }\n\n const hasSessionEndPush = config.hooks.some(\n (h, i) => h.event === \"SessionEnd\" && effectiveAt(i).includes(\"memory push\"),\n );\n if (!hasSessionEndPush) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"medium\",\n message: \"Sync configured but no SessionEnd hook to auto-push memories after each session\",\n fix: \"Run `doctor --fix` to add a SessionEnd hook that pushes memories automatically\",\n });\n }\n\n // nohup check stays on the literal command — wrappers are expected to handle their own daemonisation.\n const hasNonNohupPush = config.hooks.some(\n (h) => h.event === \"SessionEnd\"\n && h.command?.includes(\"memory push\")\n && !h.command.includes(\"nohup\"),\n );\n if (hasNonNohupPush) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"high\",\n message: \"SessionEnd push hook is not nohup-wrapped — Claude Code cancels it on exit before the push completes\",\n fix: \"Run `doctor --fix` to upgrade the hook to a nohup-wrapped push\",\n });\n }\n }\n\n // 8. Broken wrappers — hook references a .sh script inside the project that doesn't exist.\n // Only report for SessionStart/SessionEnd hooks (the ones this analyzer inspects).\n for (let i = 0; i < config.hooks.length; i++) {\n const h = config.hooks[i];\n if (h.event !== \"SessionStart\" && h.event !== \"SessionEnd\") continue;\n for (const missing of resolved[i].missingScripts) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"low\",\n message: `${h.event} hook references \\`${missing}\\` but the file is missing — wrapper can't run`,\n fix: `Create ${missing} or remove the broken hook from .claude/settings.json`,\n });\n }\n }\n\n const critical = issues.filter((i) => i.severity === \"critical\").length;\n const high = issues.filter((i) => i.severity === \"high\").length;\n const medium = issues.filter((i) => i.severity === \"medium\").length;\n const low = issues.filter((i) => i.severity === \"low\").length;\n const score = Math.max(0, 100 - (critical * 40 + high * 20 + medium * 10 + low * 5));\n\n return { name: \"Memory\", issues, score };\n}\n","/**\n * Intent-based section detection for CLAUDE.md quality analysis.\n *\n * Replaces the old BASE_SECTIONS regex loop that required an exact heading match\n * (e.g. `## Session Start`). Now a section satisfies an intent when either its\n * heading matches a pattern OR its body contains enough intent-signalling keywords.\n * A section wrapped in LP-STUB markers never satisfies an intent — stubs are\n * scaffolding, not real content.\n */\n\nimport { LP_STUB_OPEN } from \"../../../lib/stub-marker.js\";\n\nexport interface IntentRule {\n readonly name: string;\n readonly why: string;\n readonly headingPatterns: readonly RegExp[];\n readonly bodyKeywords: readonly RegExp[];\n readonly minBodyKeywords: number;\n}\n\nexport interface ParsedSection {\n readonly heading: string;\n readonly body: string;\n readonly isStub: boolean;\n}\n\nexport const INTENT_RULES: readonly IntentRule[] = [\n {\n name: \"Stack\",\n why: \"Claude performs worse without knowing the tech stack\",\n headingPatterns: [/^tech\\s+stack$/i, /^stack$/i, /^technology$/i, /^tech$/i],\n bodyKeywords: [\n /\\blanguage:/i,\n /\\bframework:/i,\n /\\bpackage\\s+manager:/i,\n /\\bruntime:/i,\n /\\b(typescript|javascript|python|ruby|go|rust|java|php|swift|kotlin)\\b/i,\n /\\b(react|next\\.?js|vue|svelte|angular|express|fastify|laravel|rails|django|flask)\\b/i,\n /\\b(node(?:\\.?js)?|deno|bun|cpython)\\b/i,\n ],\n minBodyKeywords: 2,\n },\n {\n name: \"Commands\",\n why: \"Claude guesses wrong without explicit dev/build/test commands\",\n headingPatterns: [/^commands?$/i, /^scripts$/i, /^dev\\s+commands$/i, /^development$/i],\n bodyKeywords: [\n /\\b(pnpm|npm|yarn|bun)\\s+\\w+/i,\n /\\b(build|test|dev|lint|typecheck|start):/i,\n /\\brun\\s+(tests?|build|dev)/i,\n /\\bmake\\s+\\w+/i,\n /\\bcargo\\s+\\w+/i,\n ],\n minBodyKeywords: 2,\n },\n {\n name: \"Session Start\",\n why: \"Without this, Claude won't read TASKS.md or maintain continuity\",\n headingPatterns: [\n /^session\\s+start$/i,\n /^session$/i,\n /^sprint\\s+planning$/i,\n /^workflow$/i,\n /^getting\\s+started$/i,\n /^at\\s+session\\s+start$/i,\n ],\n bodyKeywords: [\n /\\btasks?\\.md\\b/i,\n /\\bsession\\s+(start|log)\\b/i,\n /\\bsprint\\s+(log|planning)\\b/i,\n /\\b(read|check).*at\\s+(session|start)/i,\n /\\btrack\\s+progress/i,\n ],\n minBodyKeywords: 1,\n },\n {\n name: \"Off-Limits\",\n why: \"Without guardrails, Claude has no boundaries beyond defaults\",\n headingPatterns: [\n /^off.?limits$/i,\n /^constraints$/i,\n /^don'?t$/i,\n /^rules$/i,\n /^guardrails$/i,\n /^forbidden$/i,\n /^security\\s+notes$/i,\n ],\n bodyKeywords: [\n /\\bnever\\s+\\w+/i,\n /\\bforbidden/i,\n /\\bdo\\s+not\\b/i,\n /\\b(secret|credential|api\\s+key|password|token)/i,\n /\\.env\\b/,\n ],\n minBodyKeywords: 2,\n },\n {\n name: \"Architecture/Structure\",\n why: \"Claude makes better decisions when it understands the codebase shape\",\n headingPatterns: [\n /^architecture$/i,\n /^project\\s+structure$/i,\n /^structure$/i,\n /^codebase$/i,\n /^layout$/i,\n /^repo\\s+layout$/i,\n ],\n bodyKeywords: [\n /\\bsrc\\//,\n /\\b(directory|directories|folder|module|layer)\\b/i,\n /\\barchitecture\\b/i,\n ],\n minBodyKeywords: 1,\n },\n {\n name: \"Backlog\",\n why: \"Without backlog instructions, deferred features get lost in conversation history\",\n headingPatterns: [\n /^backlog$/i,\n /^roadmap$/i,\n /^parked$/i,\n /^future\\s+work$/i,\n /^parked\\s+features?$/i,\n ],\n bodyKeywords: [\n /\\bbacklog\\.md\\b/i,\n /\\bbacklog\\b/i,\n /\\bdeferred\\b/i,\n /\\bparked\\s+features?\\b/i,\n ],\n minBodyKeywords: 1,\n },\n {\n name: \"Stop-and-Swarm\",\n why: \"Without a stop-and-swarm rule, Claude keeps guessing in circles instead of parallelizing research\",\n headingPatterns: [\n /^stop.and.swarm$/i,\n /^when\\s+stuck$/i,\n /^debug$/i,\n /^escalation$/i,\n /^swarm$/i,\n /^parallel\\s+agents?$/i,\n ],\n bodyKeywords: [\n /\\bstop-and-swarm\\b/i,\n /\\bparallel\\s+agents?\\b/i,\n /\\bspin\\s+up\\b/i,\n /\\b(3|three)\\s+(parallel\\s+)?agents?\\b/i,\n /\\bfailed\\s+iterations?\\b/i,\n ],\n minBodyKeywords: 1,\n },\n] as const;\n\nexport const MEMORY_INTENT: IntentRule = {\n name: \"Memory & Learnings\",\n why: \"Without memory instructions, Claude forgets learnings and repeats mistakes across sessions\",\n headingPatterns: [/^memory$/i, /^learnings?$/i, /^memory\\s*(&|and)\\s*learnings?$/i],\n bodyKeywords: [\n /\\bmemory_search\\b/i,\n /\\bmemory_store\\b/i,\n /\\bagentic-memory\\b/i,\n /\\bstore\\s+memories?\\b/i,\n /\\binject(ed)?\\s+(at|in|into)\\s+(session|startup)/i,\n ],\n minBodyKeywords: 1,\n} as const;\n\nexport function parseSections(content: string): ParsedSection[] {\n const lines = content.split(\"\\n\");\n const sections: ParsedSection[] = [];\n let currentHeading: string | null = null;\n let currentBody: string[] = [];\n\n const flush = (): void => {\n if (currentHeading === null) return;\n const body = currentBody.join(\"\\n\");\n sections.push({\n heading: currentHeading,\n body,\n isStub: body.includes(LP_STUB_OPEN),\n });\n };\n\n for (const line of lines) {\n const match = line.match(/^##\\s+(.+?)\\s*$/);\n if (match) {\n flush();\n currentHeading = match[1];\n currentBody = [];\n } else if (currentHeading !== null) {\n currentBody.push(line);\n }\n }\n flush();\n\n return sections;\n}\n\nexport function sectionSatisfiesIntent(section: ParsedSection, rule: IntentRule): boolean {\n if (section.isStub) return false;\n\n const headingMatch = rule.headingPatterns.some((p) => p.test(section.heading));\n if (headingMatch) return true;\n\n const keywordHits = rule.bodyKeywords.reduce(\n (n, p) => (p.test(section.body) ? n + 1 : n),\n 0,\n );\n return keywordHits >= rule.minBodyKeywords;\n}\n\nexport function documentSatisfiesIntent(\n sections: readonly ParsedSection[],\n rule: IntentRule,\n): boolean {\n return sections.some((s) => sectionSatisfiesIntent(s, rule));\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\nimport { hasMemoryIndicators } from \"./memory.js\";\nimport {\n INTENT_RULES,\n MEMORY_INTENT,\n parseSections,\n documentSatisfiesIntent,\n} from \"./quality-intents.js\";\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, projectRoot: string): 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 via intent detection (keyword-based, not exact heading match).\n // Memory intent only checked if memory is installed.\n const rules = await hasMemoryIndicators(config, projectRoot)\n ? [...INTENT_RULES, MEMORY_INTENT]\n : [...INTENT_RULES];\n const combinedContent = [content, config.localClaudeMdContent].filter(Boolean).join(\"\\n\\n\");\n const sections = parseSections(combinedContent);\n for (const rule of rules) {\n if (!documentSatisfiesIntent(sections, rule)) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"medium\",\n message: `Missing \"## ${rule.name}\" section — ${rule.why}`,\n fix: `Add a ## ${rule.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 { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { log, renderDoctorReport } from \"../../lib/output.js\";\nimport { analyzeBudget } from \"./analyzers/budget.js\";\nimport { analyzeSettings } from \"./analyzers/settings.js\";\nimport { analyzeHooks } from \"./analyzers/hooks.js\";\nimport { analyzeRules } from \"./analyzers/rules.js\";\nimport { analyzePermissions } from \"./analyzers/permissions.js\";\nimport { analyzeMcp } from \"./analyzers/mcp.js\";\nimport { analyzeQuality } from \"./analyzers/quality.js\";\nimport type { AnalyzerResult } from \"../../types/index.js\";\n\n/**\n * Watch config files for changes using polling (reliable on all OS).\n * Re-runs doctor on every detected change.\n */\nexport async function watchConfig(projectRoot: string): Promise<void> {\n await runAndDisplay(projectRoot);\n\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n\n let lastSnapshot = await getFileSnapshot(projectRoot);\n\n setInterval(async () => {\n const currentSnapshot = await getFileSnapshot(projectRoot);\n if (currentSnapshot !== lastSnapshot) {\n lastSnapshot = currentSnapshot;\n console.clear();\n await runAndDisplay(projectRoot);\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n }\n }, 1000);\n\n await new Promise(() => {});\n}\n\nasync function getFileSnapshot(projectRoot: string): Promise<string> {\n const files = [\n join(projectRoot, \"CLAUDE.md\"),\n join(projectRoot, \".claudeignore\"),\n ];\n\n const claudeDir = join(projectRoot, \".claude\");\n try {\n const entries = await readdir(claudeDir, { withFileTypes: true, recursive: true });\n for (const entry of entries) {\n if (entry.isFile()) {\n const parentPath = (entry as unknown as { parentPath?: string }).parentPath ?? claudeDir;\n files.push(join(parentPath, entry.name));\n }\n }\n } catch {\n // .claude/ doesn't exist\n }\n\n const mtimes: string[] = [];\n for (const file of files) {\n try {\n const s = await stat(file);\n mtimes.push(`${file}:${s.mtimeMs}`);\n } catch {\n mtimes.push(`${file}:missing`);\n }\n }\n\n return mtimes.join(\"|\");\n}\n\nasync function runAndDisplay(projectRoot: string): Promise<void> {\n console.log(\"\\x1b[36m\\x1b[1m Claude Launchpad\\x1b[0m\");\n console.log(\"\\x1b[2m Scaffold · Diagnose · Evaluate · Remember\\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, projectRoot),\n analyzeSettings(config),\n analyzeHooks(config),\n analyzeRules(config),\n analyzePermissions(config),\n analyzeMcp(config),\n ]);\n\n renderDoctorReport(results);\n}\n","import { Command } from \"commander\";\nimport { select } from \"@inquirer/prompts\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { printBanner, log, printScoreCard } from \"../../lib/output.js\";\nimport { loadScenarios } from \"./loader.js\";\nimport { runScenarioWithRetries } from \"./runner.js\";\nimport type { EvalRunResult } from \"../../types/index.js\";\n\nexport function createEvalCommand(): Command {\n return new Command(\"eval\")\n .description(\"Test your Claude Code config against eval scenarios\")\n .option(\"-s, --suite <suite>\", \"Eval suite to run (e.g., security, conventions, workflow)\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .option(\"--scenarios <path>\", \"Custom scenarios directory\")\n .option(\"--runs <n>\", \"Runs per scenario (default: 3)\", \"3\")\n .option(\"--timeout <ms>\", \"Timeout per run in ms (default: 120000)\", \"120000\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--debug\", \"Keep sandbox directories for inspection\")\n .option(\"--model <model>\", \"Model to use for eval (e.g., sonnet, haiku, opus)\")\n .action(async (opts) => {\n printBanner();\n\n // Interactive mode when no flags provided\n const hasFlags = opts.suite\n || opts.model\n || opts.runs !== \"3\"\n || opts.timeout !== \"120000\"\n || opts.path !== process.cwd()\n || Boolean(opts.scenarios)\n || opts.json\n || opts.debug;\n if (!hasFlags) {\n opts.suite = await select({\n message: \"Suite\",\n choices: [\n { name: \"security (6 scenarios)\", value: \"security\" },\n { name: \"conventions (5 scenarios)\", value: \"conventions\" },\n { name: \"workflow (4 scenarios)\", value: \"workflow\" },\n { name: \"all (15 scenarios)\", value: undefined },\n ],\n });\n opts.runs = await select({\n message: \"Runs per scenario\",\n choices: [\n { name: \"1 — fast\", value: \"1\" },\n { name: \"3 — default\", value: \"3\" },\n { name: \"5 — thorough\", value: \"5\" },\n ],\n });\n opts.model = await select({\n message: \"Model\",\n choices: [\n { name: \"haiku — cheapest\", value: \"haiku\" },\n { name: \"sonnet — balanced\", value: \"sonnet\" },\n { name: \"opus — best\", value: \"opus\" },\n ],\n });\n log.blank();\n }\n\n // Verify Claude CLI is available\n const claudeAvailable = await checkClaudeCli();\n if (!claudeAvailable) {\n log.error(\"Claude CLI not found. Install it: https://docs.anthropic.com/en/docs/claude-code\");\n log.info(\"The eval command runs Claude headless against scenarios — it requires the CLI.\");\n process.exit(1);\n }\n\n // Load scenarios\n log.step(\"Loading eval scenarios...\");\n const scenarios = await loadScenarios({\n suite: opts.suite,\n customPath: opts.scenarios,\n });\n\n if (scenarios.length === 0) {\n log.warn(\"No matching scenarios found.\");\n if (opts.suite) {\n log.info(`Check that the suite \"${opts.suite}\" exists in the scenarios directory.`);\n }\n return;\n }\n\n log.success(`Loaded ${scenarios.length} scenario(s)`);\n if (opts.model) {\n log.info(`Model: ${opts.model}`);\n }\n log.blank();\n\n const runs = parseInt(opts.runs, 10);\n const timeout = parseInt(opts.timeout, 10);\n\n // Run scenarios\n const results: EvalRunResult[] = [];\n\n for (const scenario of scenarios) {\n const spinner = ora({\n text: `Running: ${scenario.name} (${runs} run${runs > 1 ? \"s\" : \"\"})`,\n prefixText: \" \",\n }).start();\n\n try {\n const result = await runScenarioWithRetries(\n { ...scenario, runs },\n { projectRoot: opts.path, timeout, debug: opts.debug, model: opts.model },\n );\n results.push(result);\n\n if (result.passed) {\n spinner.succeed(`${scenario.name} ${result.score}/${result.maxScore}`);\n } else {\n spinner.fail(`${scenario.name} ${result.score}/${result.maxScore}`);\n }\n } catch (error: unknown) {\n spinner.fail(`${scenario.name} ERROR`);\n const msg = error instanceof Error ? error.message : String(error);\n log.error(` ${msg}`);\n results.push({\n scenario: scenario.name,\n score: 0,\n maxScore: scenario.checks.reduce((s, c) => s + c.points, 0),\n passed: false,\n checks: scenario.checks.map((c) => ({ label: c.label, passed: false, points: c.points })),\n });\n }\n }\n\n log.blank();\n\n if (opts.json) {\n const overallScore = results.reduce((s, r) => s + r.score, 0);\n const overallMax = results.reduce((s, r) => s + r.maxScore, 0);\n console.log(JSON.stringify({\n results,\n overallScore,\n overallMax,\n passed: overallScore >= overallMax * 0.8,\n timestamp: new Date().toISOString(),\n }, null, 2));\n return;\n }\n\n renderEvalReport(results);\n\n // Save report to .claude/eval/\n await saveEvalReport(results, opts.path, opts.suite, opts.model);\n });\n}\n\nfunction renderEvalReport(results: ReadonlyArray<EvalRunResult>): void {\n for (const result of results) {\n const icon = result.passed ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const status = result.passed ? chalk.green(\"PASS\") : chalk.red(\"FAIL\");\n const score = `${result.score}/${result.maxScore}`;\n\n console.log(` ${icon} ${chalk.bold(result.scenario)} ${score} ${status}`);\n\n const failedChecks = result.checks.filter((c) => !c.passed);\n for (const check of failedChecks) {\n console.log(` ${chalk.red(\"✗\")} ${chalk.dim(check.label)}`);\n }\n }\n\n log.blank();\n\n const totalScore = results.reduce((s, r) => s + r.score, 0);\n const totalMax = results.reduce((s, r) => s + r.maxScore, 0);\n const pct = totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0;\n\n printScoreCard(\"Config Eval Score\", pct);\n log.blank();\n\n const passed = results.filter((r) => r.passed).length;\n const failed = results.length - passed;\n\n if (failed === 0) {\n log.success(`All ${passed} scenario(s) passed.`);\n } else {\n log.warn(`${passed} passed, ${failed} failed out of ${results.length} scenario(s).`);\n }\n}\n\nasync function saveEvalReport(\n results: ReadonlyArray<EvalRunResult>,\n projectRoot: string,\n suite?: string,\n model?: string,\n): Promise<void> {\n const totalScore = results.reduce((s, r) => s + r.score, 0);\n const totalMax = results.reduce((s, r) => s + r.maxScore, 0);\n const pct = totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0;\n const passed = results.filter((r) => r.passed).length;\n const failed = results.length - passed;\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\").slice(0, 19);\n\n const lines: string[] = [\n `# Eval Report — ${timestamp}`,\n \"\",\n `**Score: ${pct}%** (${passed} passed, ${failed} failed out of ${results.length} scenarios)`,\n \"\",\n `- Suite: ${suite ?? \"all\"}`,\n `- Model: ${model ?? \"default\"}`,\n `- Date: ${new Date().toISOString().split(\"T\")[0]}`,\n \"\",\n \"## Results\",\n \"\",\n ];\n\n for (const result of results) {\n const status = result.passed ? \"PASS\" : \"FAIL\";\n lines.push(`### ${result.scenario} — ${result.score}/${result.maxScore} ${status}`);\n\n const failedChecks = result.checks.filter((c) => !c.passed);\n const passedChecks = result.checks.filter((c) => c.passed);\n\n for (const check of passedChecks) {\n lines.push(`- PASSED: ${check.label} (${check.points} pts)`);\n }\n for (const check of failedChecks) {\n lines.push(`- FAILED: ${check.label} (${check.points} pts)`);\n }\n lines.push(\"\");\n }\n\n if (failed > 0) {\n lines.push(\"## Recommendations\");\n lines.push(\"\");\n for (const result of results.filter((r) => !r.passed)) {\n lines.push(`### Fix: ${result.scenario}`);\n const failedChecks = result.checks.filter((c) => !c.passed);\n for (const check of failedChecks) {\n lines.push(`- ${check.label} — update CLAUDE.md instructions or add hooks to enforce this behavior`);\n }\n lines.push(\"\");\n }\n }\n\n const evalDir = join(projectRoot, \".claude\", \"eval\");\n await mkdir(evalDir, { recursive: true });\n const filename = `eval-${suite ?? \"all\"}-${timestamp}.md`;\n await writeFile(join(evalDir, filename), lines.join(\"\\n\"));\n log.success(`Report saved to .claude/eval/${filename}`);\n}\n\nasync function checkClaudeCli(): Promise<boolean> {\n const { execFile } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const exec = promisify(execFile);\n\n try {\n await exec(\"claude\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile, readdir, access } from \"node:fs/promises\";\nimport { join, resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parse as parseYaml } from \"yaml\";\nimport { validateScenario } from \"./schema.js\";\nimport type { EvalScenario } from \"../../types/index.js\";\n\n/**\n * Find the scenarios directory. Works both in dev (tsx) and bundled (tsup).\n * - Dev: __dirname is src/commands/eval/, scenarios is at ../../../scenarios/\n * - Bundled: __dirname is dist/, scenarios is at ../scenarios/\n * - npm installed: __dirname is node_modules/claude-launchpad/dist/, scenarios is at ../scenarios/\n */\nasync function findScenariosDir(): Promise<string> {\n const thisDir = dirname(fileURLToPath(import.meta.url));\n\n // Try relative to this file (dev mode: src/commands/eval/ → ../../../scenarios/)\n const devPath = resolve(thisDir, \"../../../scenarios\");\n if (await dirExists(devPath)) return devPath;\n\n // Try relative to dist/ (bundled: dist/ → ../scenarios/)\n const bundledPath = resolve(thisDir, \"../scenarios\");\n if (await dirExists(bundledPath)) return bundledPath;\n\n // Try relative to package root (fallback)\n const rootPath = resolve(thisDir, \"../../scenarios\");\n if (await dirExists(rootPath)) return rootPath;\n\n return devPath; // Fall through — will just find 0 scenarios\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Load eval scenarios from a directory. Supports:\n * - Built-in scenarios (shipped in scenarios/)\n * - Custom scenarios from a user-specified path\n */\nexport async function loadScenarios(options: {\n suite?: string;\n customPath?: string;\n}): Promise<ReadonlyArray<EvalScenario>> {\n const { suite, customPath } = options;\n\n const scenarioDir = customPath\n ? resolve(customPath)\n : await findScenariosDir();\n\n const dirs = suite\n ? [join(scenarioDir, suite)]\n : await getSubdirectories(scenarioDir);\n\n // Also check the root dir for flat YAML files\n const allDirs = [scenarioDir, ...dirs];\n\n const scenarios: EvalScenario[] = [];\n\n for (const dir of allDirs) {\n const files = await listYamlFiles(dir);\n for (const file of files) {\n try {\n const content = await readFile(file, \"utf-8\");\n const raw = parseYaml(content);\n const scenario = validateScenario(raw, file);\n scenarios.push(scenario);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.warn(` Warning: Skipping ${file}: ${msg}`);\n }\n }\n }\n\n return scenarios;\n}\n\nasync function getSubdirectories(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n\nasync function listYamlFiles(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isFile() && (e.name.endsWith(\".yaml\") || e.name.endsWith(\".yml\")))\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n","import type { EvalScenario, EvalCheck } from \"../../types/index.js\";\n\n/**\n * Validates a raw parsed YAML object against the EvalScenario schema.\n * Returns a validated scenario or throws with a descriptive error.\n */\nexport function validateScenario(raw: unknown, filePath: string): EvalScenario {\n if (!raw || typeof raw !== \"object\") {\n throw new ScenarioError(filePath, \"Scenario must be a YAML object\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n const name = requireString(obj, \"name\", filePath);\n const description = requireString(obj, \"description\", filePath);\n const prompt = requireString(obj, \"prompt\", filePath);\n const setup = validateSetup(obj.setup, filePath);\n const checks = validateChecks(obj.checks, filePath);\n const passingScore = requireNumber(obj, \"passingScore\", filePath);\n const runs = optionalNumber(obj, \"runs\") ?? 3;\n\n return { name, description, setup, prompt, checks, passingScore, runs };\n}\n\n// ─── Field Validators ───\n\nfunction validateSetup(\n raw: unknown,\n filePath: string,\n): EvalScenario[\"setup\"] {\n if (!raw || typeof raw !== \"object\") {\n throw new ScenarioError(filePath, '\"setup\" must be an object with a \"files\" array');\n }\n\n const obj = raw as Record<string, unknown>;\n const files = obj.files;\n\n if (!Array.isArray(files)) {\n throw new ScenarioError(filePath, '\"setup.files\" must be an array');\n }\n\n const validatedFiles = files.map((f, i) => {\n if (!f || typeof f !== \"object\") {\n throw new ScenarioError(filePath, `setup.files[${i}] must be an object`);\n }\n const file = f as Record<string, unknown>;\n if (typeof file.path !== \"string\" || typeof file.content !== \"string\") {\n throw new ScenarioError(filePath, `setup.files[${i}] must have \"path\" and \"content\" strings`);\n }\n return { path: file.path, content: file.content };\n });\n\n const instructions = typeof obj.instructions === \"string\" ? obj.instructions : undefined;\n\n return { files: validatedFiles, instructions };\n}\n\nfunction validateChecks(raw: unknown, filePath: string): ReadonlyArray<EvalCheck> {\n if (!Array.isArray(raw) || raw.length === 0) {\n throw new ScenarioError(filePath, '\"checks\" must be a non-empty array');\n }\n\n return raw.map((c, i) => {\n if (!c || typeof c !== \"object\") {\n throw new ScenarioError(filePath, `checks[${i}] must be an object`);\n }\n const check = c as Record<string, unknown>;\n\n const validTypes = [\"grep\", \"file-exists\", \"file-absent\", \"max-lines\", \"custom\"];\n if (!validTypes.includes(check.type as string)) {\n throw new ScenarioError(filePath, `checks[${i}].type must be one of: ${validTypes.join(\", \")}`);\n }\n\n if (typeof check.target !== \"string\") {\n throw new ScenarioError(filePath, `checks[${i}].target must be a string`);\n }\n\n const validExpect = [\"present\", \"absent\"];\n if (!validExpect.includes(check.expect as string)) {\n throw new ScenarioError(filePath, `checks[${i}].expect must be \"present\" or \"absent\"`);\n }\n\n if (typeof check.points !== \"number\" || check.points < 0) {\n throw new ScenarioError(filePath, `checks[${i}].points must be a non-negative number`);\n }\n\n if (typeof check.label !== \"string\") {\n throw new ScenarioError(filePath, `checks[${i}].label must be a string`);\n }\n\n return {\n type: check.type as EvalCheck[\"type\"],\n pattern: typeof check.pattern === \"string\" ? check.pattern : undefined,\n target: check.target,\n expect: check.expect as EvalCheck[\"expect\"],\n points: check.points,\n label: check.label,\n };\n });\n}\n\n// ─── Helpers ───\n\nfunction requireString(obj: Record<string, unknown>, key: string, filePath: string): string {\n if (typeof obj[key] !== \"string\" || obj[key] === \"\") {\n throw new ScenarioError(filePath, `\"${key}\" must be a non-empty string`);\n }\n return obj[key] as string;\n}\n\nfunction requireNumber(obj: Record<string, unknown>, key: string, filePath: string): number {\n if (typeof obj[key] !== \"number\") {\n throw new ScenarioError(filePath, `\"${key}\" must be a number`);\n }\n return obj[key] as number;\n}\n\nfunction optionalNumber(obj: Record<string, unknown>, key: string): number | undefined {\n if (obj[key] === undefined) return undefined;\n if (typeof obj[key] !== \"number\") return undefined;\n return obj[key] as number;\n}\n\nclass ScenarioError extends Error {\n constructor(filePath: string, message: string) {\n super(`Invalid scenario ${filePath}: ${message}`);\n this.name = \"ScenarioError\";\n }\n}\n","import { mkdir, writeFile, readFile, readdir, rm, cp } 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\";\nimport { fileExists } from \"../../lib/fs-utils.js\";\n\nconst exec = promisify(execFile);\n\ninterface RunOptions {\n readonly projectRoot: string;\n readonly timeout: number;\n readonly debug?: boolean;\n readonly model?: string;\n}\n\n/**\n * Execute a single eval scenario run using the Agent SDK.\n *\n * 1. Create a temp directory with the scenario's seed files\n * 2. Write a minimal CLAUDE.md with the scenario's instructions\n * 3. Run Claude via Agent SDK with explicit tool permissions\n * 4. Check the results against the scenario's checks\n * 5. Clean up\n */\nexport async function runScenario(\n scenario: EvalScenario,\n options: RunOptions,\n): Promise<EvalRunResult> {\n const sandboxDir = join(tmpdir(), `claude-eval-${randomUUID()}`);\n\n try {\n await setupSandbox(sandboxDir, scenario, options.projectRoot);\n await runClaudeInSandbox(sandboxDir, scenario.prompt, options.timeout, options.model);\n return await scoreResults(scenario, sandboxDir);\n } finally {\n if (options.debug) {\n console.log(` DEBUG: Sandbox preserved at ${sandboxDir}`);\n } else {\n await rm(sandboxDir, { recursive: true, force: true }).catch(() => {});\n }\n }\n}\n\n/**\n * Run a scenario multiple times and return the median result.\n */\nexport async function runScenarioWithRetries(\n scenario: EvalScenario,\n options: RunOptions,\n): Promise<EvalRunResult> {\n const results: EvalRunResult[] = [];\n\n for (let i = 0; i < scenario.runs; i++) {\n const result = await runScenario(scenario, options);\n results.push(result);\n }\n\n const sorted = [...results].sort((a, b) => a.score - b.score);\n return sorted[Math.floor(sorted.length / 2)];\n}\n\n// ─── Sandbox Setup ───\n\nasync function setupSandbox(\n sandboxDir: string,\n scenario: EvalScenario,\n projectRoot: string,\n): Promise<void> {\n await mkdir(sandboxDir, { recursive: true });\n\n // Write scenario seed files\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 // Copy user's full config surface into sandbox\n await copyProjectConfig(sandboxDir, projectRoot);\n\n // Write scenario CLAUDE.md (after config copy so it takes precedence)\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/**\n * Copy the user's .claude/ config (settings, rules, hooks) and .claudeignore\n * into the sandbox so eval tests the full configuration surface.\n */\nasync function copyProjectConfig(sandboxDir: string, projectRoot: string): Promise<void> {\n const claudeDir = join(projectRoot, \".claude\");\n const sandboxClaudeDir = join(sandboxDir, \".claude\");\n\n // Copy .claude/settings.json (hooks, permissions, schema)\n const settingsPath = join(claudeDir, \"settings.json\");\n if (await fileExists(settingsPath)) {\n await mkdir(sandboxClaudeDir, { recursive: true });\n await cp(settingsPath, join(sandboxClaudeDir, \"settings.json\"));\n }\n\n // Copy .claude/rules/ (all convention and path-scoped rule files)\n const rulesDir = join(claudeDir, \"rules\");\n if (await fileExists(rulesDir)) {\n await cp(rulesDir, join(sandboxClaudeDir, \"rules\"), { recursive: true });\n }\n\n // Copy .claudeignore\n const ignorePath = join(projectRoot, \".claudeignore\");\n if (await fileExists(ignorePath)) {\n await cp(ignorePath, join(sandboxDir, \".claudeignore\"));\n }\n}\n\n// ─── Claude Execution ───\n\nasync function runClaudeInSandbox(\n cwd: string,\n prompt: string,\n timeout: number,\n model?: string,\n): Promise<void> {\n // Try Agent SDK first, fall back to CLI subprocess\n try {\n const sdk = await import(\"@anthropic-ai/claude-agent-sdk\");\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n for await (const _message of sdk.query({\n prompt,\n options: {\n cwd,\n allowedTools: [\"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\"],\n permissionMode: \"dontAsk\",\n settingSources: [],\n maxTurns: 20,\n abortController: controller,\n ...(model ? { model } : {}),\n },\n })) {\n // Consume the stream — we only care about side effects (file edits)\n }\n } finally {\n clearTimeout(timeoutId);\n }\n } catch {\n // SDK not available or failed — fall back to CLI\n await runClaudeCli(cwd, prompt, timeout, model);\n }\n}\n\nasync function runClaudeCli(\n cwd: string,\n prompt: string,\n timeout: number,\n model?: string,\n): Promise<void> {\n try {\n const args = [\n \"-p\", prompt,\n \"--output-format\", \"text\",\n \"--max-turns\", \"20\",\n \"--dangerously-skip-permissions\",\n \"--allowedTools\", \"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\",\n ];\n if (model) args.push(\"--model\", model);\n await exec(\"claude\", args, { cwd, timeout, maxBuffer: 10 * 1024 * 1024 });\n } catch (error: unknown) {\n // Claude might exit non-zero but still produce usable output\n if (error && typeof error === \"object\" && \"stdout\" in error) {\n return; // Files may have been modified despite exit code\n }\n throw error;\n }\n}\n\n// ─── Scoring ───\n\nasync function scoreResults(\n scenario: EvalScenario,\n sandboxDir: string,\n): Promise<EvalRunResult> {\n const checkResults = await evaluateChecks(scenario.checks, sandboxDir);\n\n const score = checkResults\n .filter((c) => c.passed)\n .reduce((sum, c) => sum + c.points, 0);\n\n const maxScore = scenario.checks.reduce((sum, c) => sum + c.points, 0);\n\n return {\n scenario: scenario.name,\n score,\n maxScore,\n passed: score >= scenario.passingScore,\n checks: checkResults,\n };\n}\n\nasync function evaluateChecks(\n checks: ReadonlyArray<EvalCheck>,\n sandboxDir: string,\n): Promise<ReadonlyArray<{ label: string; passed: boolean; points: number }>> {\n const results: { label: string; passed: boolean; points: number }[] = [];\n\n for (const check of checks) {\n const passed = await evaluateSingleCheck(check, sandboxDir);\n results.push({ label: check.label, passed, points: check.points });\n }\n\n return results;\n}\n\nasync function evaluateSingleCheck(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n switch (check.type) {\n case \"grep\":\n return checkGrep(check, sandboxDir);\n case \"file-exists\":\n case \"file-absent\":\n return checkFilePresence(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 checkFilePresence(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 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 { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport { confirm } from \"@inquirer/prompts\";\nimport { log } from \"../../lib/output.js\";\n\nasync function handleSyncErrors(fn: () => Promise<void>): Promise<void> {\n try {\n await fn();\n } catch (err) {\n log.error(err instanceof Error ? err.message : String(err));\n }\n}\n\nfunction isMemoryInstalled(): boolean {\n const cwd = process.cwd();\n return hasMemoryHook(join(cwd, \".claude\", \"settings.json\"))\n || hasMemoryHook(join(cwd, \".claude\", \"settings.local.json\"));\n}\n\nfunction hasMemoryHook(path: string): boolean {\n try {\n const settings = JSON.parse(readFileSync(path, \"utf-8\")) as Record<string, unknown>;\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks) return false;\n const sessionStart = hooks.SessionStart as Record<string, unknown>[] | undefined;\n return sessionStart?.some((h) => {\n const inner = h.hooks as Record<string, unknown>[] | undefined;\n return inner?.some((ih) => String(ih.command ?? \"\").includes(\"memory context\"));\n }) ?? false;\n } catch {\n return false;\n }\n}\n\nexport function createMemoryCommand(): Command {\n const memory = new Command(\"memory\")\n .description(\"Project-scoped memory with decay, sync, and a TUI dashboard\")\n .option(\"--dashboard\", \"Open the memory dashboard\")\n .action(async (opts) => {\n if (opts.dashboard) {\n if (!isMemoryInstalled()) {\n log.error(\"Knowledge base not set up yet. Run `claude-launchpad memory` first.\");\n return;\n }\n const { requireMemoryDeps } = await import(\"./utils/require-deps.js\");\n await requireMemoryDeps();\n const { startTui } = await import(\"./dashboard/tui.js\");\n await startTui();\n return;\n }\n\n // Smart default: install or show stats\n if (!isMemoryInstalled()) {\n // Check if config was already written (e.g. by doctor --fix) even though db isn't set up\n const { detectExistingSetup } = await import(\"./subcommands/install.js\");\n const existing = detectExistingSetup(process.cwd());\n if (existing) {\n const location = existing === \"local\"\n ? \".claude/CLAUDE.md + settings.local.json\"\n : \"CLAUDE.md + settings.json\";\n log.blank();\n log.success(`Memory config found (${location}) but database not set up.`);\n log.info(\"Run the install to complete setup.\");\n log.blank();\n } else {\n log.blank();\n log.step(\"Claude doesn't have a knowledge base for this project yet.\");\n log.blank();\n log.info(\"After setup, Claude will:\");\n log.info(\" - Remember decisions, gotchas, and learnings across sessions\");\n log.info(\" - Automatically recall relevant context when you start a session\");\n log.info(\" - Save important facts as you work, so nothing gets lost\");\n log.blank();\n }\n\n const proceed = await confirm({\n message: \"Set up knowledge base?\",\n default: true,\n });\n\n if (!proceed) {\n log.info(\"Skipped.\");\n return;\n }\n\n const { runInstall } = await import(\"./subcommands/install.js\");\n await runInstall({});\n } else {\n const { requireMemoryDeps } = await import(\"./utils/require-deps.js\");\n await requireMemoryDeps();\n const { runStats } = await import(\"./subcommands/stats.js\");\n await runStats({});\n }\n });\n\n // Hidden internal commands (used by hooks and MCP, not user-facing)\n memory.addCommand(\n new Command(\"context\")\n .description(\"Load session context (hook handler)\")\n .option(\"--json\", \"JSON output\")\n .action(async (opts) => {\n const { runContext } = await import(\"./subcommands/context.js\");\n await runContext(opts);\n })\n .helpCommand(false),\n { hidden: true },\n );\n\n memory.addCommand(\n new Command(\"serve\")\n .description(\"Start MCP server (Claude Code)\")\n .action(async () => {\n const { startServer } = await import(\"./server.js\");\n await startServer();\n })\n .helpCommand(false),\n { hidden: true },\n );\n\n // User-facing sync commands\n memory.addCommand(\n new Command(\"push\")\n .description(\"Push current project's memories to GitHub Gist\")\n .option(\"--all\", \"Push all projects\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (opts) => {\n await handleSyncErrors(async () => {\n const { runPush } = await import(\"./subcommands/push.js\");\n await runPush(opts);\n });\n }),\n );\n\n memory.addCommand(\n new Command(\"pull\")\n .description(\"Pull current project's memories from GitHub Gist\")\n .option(\"--all\", \"Pull all projects\")\n .option(\"-y, --yes\", \"Non-interactive (accepted for symmetry with push; pull never prompts)\")\n .action(async (opts) => {\n await handleSyncErrors(async () => {\n const { runPull } = await import(\"./subcommands/pull.js\");\n await runPull(opts);\n });\n }),\n );\n\n // Sync management commands\n const sync = new Command(\"sync\")\n .description(\"Manage memory sync\");\n\n sync.addCommand(\n new Command(\"status\")\n .description(\"Show local vs remote memory counts per project\")\n .action(async () => {\n await handleSyncErrors(async () => {\n const { runSyncStatus } = await import(\"./subcommands/sync-status.js\");\n await runSyncStatus();\n });\n }),\n );\n\n sync.addCommand(\n new Command(\"clean\")\n .description(\"Remove a project from the sync gist\")\n .argument(\"<project>\", \"Project slug to remove\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (project: string, opts) => {\n await handleSyncErrors(async () => {\n const { runSyncClean } = await import(\"./subcommands/sync-clean.js\");\n await runSyncClean(project, opts);\n });\n }),\n );\n\n memory.addCommand(sync);\n\n return memory;\n}\n"],"mappings":"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","names":["Command","join","Command","join","join","readFile","join","homedir","join","homedir","readFile","access","readFile","resolve","readdir","join","join","readdir","Command","overallScore","Command","select","chalk","mkdir","writeFile","join","readFile","readdir","access","join","resolve","dirname","dirname","resolve","access","join","readFile","readdir","mkdir","writeFile","readFile","readdir","join","dirname","join","mkdir","dirname","writeFile","readFile","readdir","Command","select","chalk","join","mkdir","writeFile","execFile","promisify","exec","join","Command","confirm","join","Command","confirm","Command","join"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/init/index.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/backlog.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/hook-resolver.ts","../src/commands/doctor/analyzers/memory.ts","../src/commands/doctor/analyzers/quality-intents.ts","../src/commands/doctor/analyzers/quality.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/memory/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { join } from \"node:path\";\nimport { createInitCommand } from \"./commands/init/index.js\";\nimport { createDoctorCommand } from \"./commands/doctor/index.js\";\nimport { createEvalCommand } from \"./commands/eval/index.js\";\nimport { createMemoryCommand } from \"./commands/memory/index.js\";\nimport { printBanner, log } from \"./lib/output.js\";\nimport { fileExists } from \"./lib/fs-utils.js\";\n\nconst program = new Command()\n .name(\"claude-launchpad\")\n .description(\"CLI toolkit that makes Claude Code setups measurably good\")\n .version(\"1.8.1\", \"-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(\"Use `/lp-enhance` skill inside Claude Code to AI-complete your CLAUDE.md\");\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(createEvalCommand());\nprogram.addCommand(createMemoryCommand());\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { input, confirm, select } from \"@inquirer/prompts\";\nimport { writeFile, mkdir, readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { printBanner, log } from \"../../lib/output.js\";\nimport { fileExists } from \"../../lib/fs-utils.js\";\nimport { detectProject } from \"../../lib/detect.js\";\nimport type { InitOptions, DetectedProject } from \"../../types/index.js\";\nimport { generateClaudeMd } from \"./generators/claude-md.js\";\nimport { generateTasksMd } from \"./generators/tasks-md.js\";\nimport { generateSettings } from \"./generators/settings.js\";\nimport { generateClaudeignore } from \"./generators/claudeignore.js\";\nimport { generateEnhanceSkill } from \"./generators/skill-enhance.js\";\nimport { generateBacklogMd } from \"./generators/backlog.js\";\nimport { SKILL_AUTHORING_CONTENT } from \"../../lib/sections.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 (does not overwrite existing files)\")\n .option(\"-f, --force\", \"Overwrite existing CLAUDE.md\")\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) {\n if (opts.force) {\n log.warn(\"Overwriting existing CLAUDE.md (--force)\");\n } else if (opts.yes) {\n log.error(\"CLAUDE.md already exists. `--yes` will not overwrite existing files.\");\n log.info(\"Run `claude-launchpad doctor --fix` to update in place,\");\n log.info(\"or re-run with `--force` to overwrite.\");\n process.exitCode = 1;\n return;\n } else {\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 await createEnhanceSkillPrompt(root, false);\n log.step(\"Tip: run `claude-launchpad doctor` to check your existing config\");\n return;\n }\n }\n }\n\n await scaffold(root, options, detected, opts.yes);\n });\n}\n\nasync function scaffold(root: string, options: InitOptions, detected: DetectedProject, skipPrompts: boolean): Promise<void> {\n log.step(\"Generating configuration...\");\n\n const claudeMd = generateClaudeMd(options, detected);\n const tasksMd = generateTasksMd(options);\n const backlogMd = generateBacklogMd(options);\n const settings = generateSettings(detected);\n const claudeignore = generateClaudeignore(detected);\n\n await mkdir(join(root, \".claude\", \"rules\"), { recursive: true });\n\n // Merge with existing settings.json instead of overwriting\n const settingsPath = join(root, \".claude\", \"settings.json\");\n const mergedSettings = await mergeSettings(settingsPath, settings as unknown as Record<string, unknown>);\n\n // Only generate files that don't exist yet\n const backlogPath = join(root, \"BACKLOG.md\");\n const hasBacklog = await fileExists(backlogPath);\n const claudeignorePath = join(root, \".claudeignore\");\n const hasClaudeignore = await fileExists(claudeignorePath);\n const claudeGitignorePath = join(root, \".claude\", \".gitignore\");\n const hasClaudeGitignore = await fileExists(claudeGitignorePath);\n const rulesPath = join(root, \".claude\", \"rules\", \"conventions.md\");\n const hasRules = await fileExists(rulesPath);\n\n const writes: Promise<void>[] = [\n writeFile(join(root, \"CLAUDE.md\"), claudeMd),\n writeFile(join(root, \"TASKS.md\"), tasksMd),\n writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2) + \"\\n\"),\n ];\n\n if (!hasBacklog) {\n writes.push(writeFile(backlogPath, backlogMd));\n }\n\n if (!hasClaudeignore) {\n writes.push(writeFile(claudeignorePath, claudeignore));\n }\n\n if (!hasClaudeGitignore) {\n writes.push(writeFile(claudeGitignorePath, [\n \"# Local-only Claude Code files (never commit these)\",\n \"CLAUDE.md\",\n \"settings.local.json\",\n \"plans/\",\n \"memory/\",\n \"sessions/\",\n \"tmp/\",\n \"\",\n ].join(\"\\n\")));\n }\n\n if (!hasRules) {\n const rulesContent = generateStarterRules(detected);\n writes.push(writeFile(rulesPath, rulesContent));\n }\n\n await Promise.all(writes);\n\n log.success(\"Generated CLAUDE.md\");\n log.success(\"Generated TASKS.md\");\n if (!hasBacklog) log.success(\"Generated BACKLOG.md\");\n log.success(\"Generated .claude/settings.json (schema, permissions, hooks)\");\n if (!hasClaudeGitignore) log.success(\"Generated .claude/.gitignore\");\n if (!hasClaudeignore) log.success(\"Generated .claudeignore\");\n if (!hasRules) log.success(\"Generated .claude/rules/conventions.md\");\n\n // Offer to create the /lp-enhance skill\n await createEnhanceSkillPrompt(root, skipPrompts);\n\n log.blank();\n log.success(\"Done! Run `claude` to start.\");\n log.info(\"Use `/lp-enhance` inside Claude Code to have AI complete your CLAUDE.md.\");\n log.info(\"Run `claude-launchpad doctor` to check your config quality.\");\n log.blank();\n}\n\nfunction generateStarterRules(detected: DetectedProject): string {\n const lines = [\n \"# Project Conventions\",\n \"\",\n \"- Use conventional commits (feat:, fix:, docs:, refactor:, test:, chore:)\",\n \"- Keep files under 400 lines, functions under 50 lines\",\n \"- Handle errors explicitly - no empty catch blocks\",\n \"- Validate input at system boundaries\",\n ];\n\n if (detected.language === \"TypeScript\" || detected.language === \"JavaScript\") {\n lines.push(\"- Use named exports, no default exports except Next.js pages\");\n lines.push(\"- No `any` types in TypeScript\");\n }\n\n if (detected.language === \"Python\") {\n lines.push(\"- Type hints on all function signatures\");\n lines.push(\"- Async everywhere for I/O operations\");\n }\n\n if (detected.language === \"Go\") {\n lines.push(\"- Table-driven tests\");\n lines.push(\"- Errors are values - handle them, don't ignore them\");\n }\n\n if (detected.language === \"Rust\") {\n lines.push(\"- Prefer Result over unwrap/expect in library code\");\n lines.push(\"- No unsafe blocks without a safety comment\");\n }\n\n // Skill authoring conventions\n lines.push(\"\", \"## Skill Authoring\", \"\", SKILL_AUTHORING_CONTENT);\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n\nasync function createEnhanceSkillPrompt(root: string, skipPrompts: boolean): Promise<void> {\n const projectPath = join(root, \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\");\n const globalPath = join(homedir(), \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\");\n // Also check legacy commands/ location\n const legacyProject = join(root, \".claude\", \"commands\", \"lp-enhance.md\");\n const legacyGlobal = join(homedir(), \".claude\", \"commands\", \"lp-enhance.md\");\n\n if (await fileExists(projectPath) || await fileExists(globalPath)\n || await fileExists(legacyProject) || await fileExists(legacyGlobal)) return;\n\n const scope = skipPrompts ? \"project\" : await select({\n message: \"Install /lp-enhance skill (AI-powered CLAUDE.md improver):\",\n choices: [\n { value: \"project\", name: \"Project scope (.claude/skills/)\" },\n { value: \"global\", name: \"Global scope (~/.claude/skills/)\" },\n { value: \"skip\", name: \"Skip\" },\n ],\n });\n\n if (scope === \"skip\") return;\n\n const targetDir = scope === \"global\"\n ? join(homedir(), \".claude\", \"skills\", \"lp-enhance\")\n : join(root, \".claude\", \"skills\", \"lp-enhance\");\n\n await mkdir(targetDir, { recursive: true });\n await writeFile(join(targetDir, \"SKILL.md\"), generateEnhanceSkill());\n log.success(`Generated /lp-enhance skill (${scope} scope)`);\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 type { InitOptions, DetectedProject } from \"../../../types/index.js\";\nimport {\n SESSION_START_CONTENT, BACKLOG_CONTENT, STOP_AND_SWARM_CONTENT, OFF_LIMITS_CONTENT,\n} from \"../../../lib/sections.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${SESSION_START_CONTENT}`);\n\n // Backlog\n sections.push(\"\", `## Backlog\\n${BACKLOG_CONTENT}`);\n\n // Sprint Reviews\n sections.push(\"\", `## Sprint Reviews\nWhen all tasks in the current sprint are complete, do a quick quality check before committing:\n- Scan changed files for dead code, debug logs, and TODO hacks\n- Run tests and type-checker if available\n- Check for convention violations and hardcoded values\n- Fix any issues, then commit\n- Skip if the sprint was trivial (docs, config-only changes)`);\n\n // Conventions\n sections.push(\"\", `## Conventions\n- Git: Conventional commits (\\`feat:\\`, \\`fix:\\`, \\`docs:\\`, \\`refactor:\\`, \\`test:\\`, \\`chore:\\`)`);\n\n // Stop-and-Swarm\n sections.push(\"\", `## Stop-and-Swarm\\n${STOP_AND_SWARM_CONTENT}`);\n\n // Off-Limits\n sections.push(\"\", `## Off-Limits\\n${OFF_LIMITS_CONTENT}`);\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 at session start. Keep SHORT — only current state matters.\n> Completed sprints: one-liner. Session log: 3 lines max, last 3 sessions. Under 80 lines.\n\n## Completed Sprints\n\n## Current: Sprint 1 — Setup\n- [ ] Project scaffolding and environment setup\n- [ ] Core feature implementation\n- [ ] Test infrastructure\n\n## Session Log\n`;\n}\n","import type { DetectedProject } from \"../../../types/index.js\";\n\ninterface HookEntry {\n readonly type: \"command\";\n readonly command: string;\n}\n\ninterface HookGroup {\n readonly matcher: string;\n readonly hooks: ReadonlyArray<HookEntry>;\n}\n\ninterface ClaudeSettings {\n readonly $schema?: string;\n readonly permissions?: {\n readonly deny?: ReadonlyArray<string>;\n };\n readonly hooks?: Record<string, ReadonlyArray<HookGroup>>;\n readonly disableBypassPermissionsMode?: \"disable\";\n}\n\n/**\n * Generate .claude/settings.json based on detected project.\n * Includes: schema for IDE autocomplete, security deny-lists, hooks.\n */\nexport function generateSettings(detected: DetectedProject): ClaudeSettings {\n const preToolUse: HookGroup[] = [];\n const postToolUse: HookGroup[] = [];\n\n // Universal: .env file protection (block read + write)\n preToolUse.push({\n matcher: \"Read|Write|Edit\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -qE '\\\\.(env|env\\\\..*)$' && ! echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -q '.env.example' && echo 'BLOCKED: .env files contain secrets' && exit 1; exit 0\",\n }],\n });\n\n // Universal: block destructive commands\n preToolUse.push({\n matcher: \"Bash\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_COMMAND\\\" | grep -qE 'rm\\\\s+-rf\\\\s+/|DROP\\\\s+TABLE|DROP\\\\s+DATABASE|push.*--force|push.*-f' && echo 'BLOCKED: Destructive command detected' && exit 1; exit 0\",\n }],\n });\n\n // Auto-format based on detected tooling\n const formatHook = buildFormatHook(detected);\n if (formatHook) {\n postToolUse.push(formatHook);\n }\n\n // Sprint review: nudge when all current sprint tasks are complete\n postToolUse.push({\n matcher: \"Edit|Write\",\n hooks: [{\n type: \"command\",\n command: \"echo \\\"$TOOL_INPUT_FILE_PATH\\\" | grep -q TASKS.md || exit 0; section=$(sed -n '/^## Current Sprint/,/^## /p' TASKS.md 2>/dev/null); [ -z \\\"$section\\\" ] && exit 0; unchecked=$(echo \\\"$section\\\" | grep -cF '- [ ]' || true); checked=$(echo \\\"$section\\\" | grep -cF '- [x]' || true); [ \\\"$unchecked\\\" -eq 0 ] && [ \\\"$checked\\\" -gt 0 ] && echo 'Sprint complete — all current tasks done. Consider a quick quality check before committing: scan for dead code, debug artifacts, TODO hacks, and convention violations. Run tests if available. Skip if trivial.'; exit 0\",\n }],\n });\n\n // SessionStart: inject TASKS.md at session startup\n const sessionStart: HookGroup[] = [{\n matcher: \"startup|resume\",\n hooks: [{\n type: \"command\",\n command: \"cat TASKS.md 2>/dev/null; exit 0\",\n }],\n }];\n\n // PostCompact: re-inject TASKS.md so session continuity survives compaction\n const postCompact: HookGroup[] = [{\n matcher: \"\",\n hooks: [{\n type: \"command\",\n command: \"cat TASKS.md 2>/dev/null; exit 0\",\n }],\n }];\n\n const hooks: Record<string, ReadonlyArray<HookGroup>> = {};\n hooks.SessionStart = sessionStart;\n if (preToolUse.length > 0) hooks.PreToolUse = preToolUse;\n if (postToolUse.length > 0) hooks.PostToolUse = postToolUse;\n hooks.PostCompact = postCompact;\n\n return {\n $schema: \"https://json.schemastore.org/claude-code-settings.json\",\n permissions: {\n deny: [\n \"Bash(rm -rf /)\",\n \"Bash(rm -rf ~)\",\n \"Read(.env)\",\n \"Read(.env.*)\",\n \"Read(secrets/**)\",\n \"Read(~/.ssh/*)\",\n \"Read(~/.aws/*)\",\n \"Read(~/.npmrc)\",\n ],\n },\n hooks,\n disableBypassPermissionsMode: \"disable\",\n };\n}\n\n// Safe formatter commands - never interpolate user-controlled strings\nconst SAFE_FORMATTERS: Record<string, { extensions: string[]; command: string }> = {\n TypeScript: { extensions: [\"ts\", \"tsx\"], command: \"npx prettier --write\" },\n JavaScript: { extensions: [\"js\", \"jsx\"], command: \"npx prettier --write\" },\n Python: { extensions: [\"py\"], command: \"ruff format\" },\n Go: { extensions: [\"go\"], command: \"gofmt -w\" },\n Rust: { extensions: [\"rs\"], command: \"rustfmt\" },\n Ruby: { extensions: [\"rb\"], command: \"rubocop -A\" },\n Dart: { extensions: [\"dart\"], command: \"dart format\" },\n PHP: { extensions: [\"php\"], command: \"vendor/bin/pint\" },\n Kotlin: { extensions: [\"kt\", \"kts\"], command: \"ktlint -F\" },\n Java: { extensions: [\"java\"], command: \"google-java-format -i\" },\n Swift: { extensions: [\"swift\"], command: \"swift-format format -i\" },\n Elixir: { extensions: [\"ex\", \"exs\"], command: \"mix format\" },\n \"C#\": { extensions: [\"cs\"], command: \"dotnet format\" },\n};\n\nfunction buildFormatHook(detected: DetectedProject): HookGroup | null {\n if (!detected.language) return null;\n\n const config = SAFE_FORMATTERS[detected.language];\n if (!config) return null;\n\n const extChecks = config.extensions\n .map((ext) => `[ \"$ext\" = \"${ext}\" ]`)\n .join(\" || \");\n\n return {\n matcher: \"Write|Edit\",\n hooks: [{\n type: \"command\",\n command: `ext=\\${TOOL_INPUT_FILE_PATH##*.}; (${extChecks}) && ${config.command} \"$TOOL_INPUT_FILE_PATH\" 2>/dev/null; exit 0`,\n }],\n };\n}\n","import type { InitOptions } from \"../../../types/index.js\";\n\nexport function generateBacklogMd(options: InitOptions): string {\n return `# ${options.name} - Backlog\n\n> Features discussed but deferred. Pick up when relevant.\n> Priority: P0 = next sprint, P1 = soon, P2 = when relevant.\n\n<!-- Add deferred features here. Format:\n## [P1] Feature Name\nOne-line description. Context for why it was deferred and when to revisit.\n-->\n`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { printBanner, log, renderDoctorReport } from \"../../lib/output.js\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { analyzeBudget } from \"./analyzers/budget.js\";\nimport { analyzeSettings } from \"./analyzers/settings.js\";\nimport { analyzeHooks } from \"./analyzers/hooks.js\";\nimport { analyzeRules } from \"./analyzers/rules.js\";\nimport { analyzePermissions } from \"./analyzers/permissions.js\";\nimport { analyzeMcp } from \"./analyzers/mcp.js\";\nimport { analyzeQuality } from \"./analyzers/quality.js\";\nimport { analyzeMemory } from \"./analyzers/memory.js\";\nimport { applyFixes } from \"./fixer.js\";\nimport { watchConfig } from \"./watcher.js\";\nimport type { AnalyzerResult } from \"../../types/index.js\";\n\nexport function createDoctorCommand(): Command {\n return new Command(\"doctor\")\n .description(\"Diagnose your Claude Code configuration and report issues\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .option(\"--json\", \"Output as JSON\")\n .option(\"--min-score <n>\", \"Exit non-zero if overall score is below this threshold (for CI)\")\n .option(\"--fix\", \"Auto-apply deterministic fixes for detected issues\")\n .option(\"--dry-run\", \"Preview what --fix would change without applying\")\n .option(\"--watch\", \"Watch for config changes and re-run automatically\")\n .action(async (opts) => {\n if (opts.watch) {\n await watchConfig(opts.path);\n return;\n }\n\n if (!opts.json) {\n printBanner();\n log.step(\"Scanning Claude Code configuration...\");\n log.blank();\n }\n\n const config = await parseClaudeConfig(opts.path);\n\n if (config.claudeMdContent === null && config.settings === null) {\n log.error(\"No Claude Code configuration found in this directory.\");\n log.info(\"Run `claude-launchpad init` to set up a project, or cd into a configured project.\");\n process.exit(1);\n }\n\n const results: AnalyzerResult[] = await Promise.all([\n analyzeBudget(config),\n analyzeQuality(config, opts.path),\n analyzeSettings(config),\n analyzeHooks(config),\n analyzeRules(config),\n analyzePermissions(config),\n analyzeMcp(config),\n ]);\n\n const memoryResult = await analyzeMemory(config, opts.path);\n if (memoryResult) {\n results.push(memoryResult);\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 // Skip rendering the initial report when --fix is used — only show the post-fix result\n let overallScore = Math.round(results.reduce((sum, r) => sum + r.score, 0) / results.length);\n if (!opts.fix) {\n renderDoctorReport(results);\n }\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 renderDoctorReport(results);\n log.success(\"Nothing to fix.\");\n } else if (fixable.length > 0) {\n // Dry-run: preview only\n if (opts.dryRun) {\n const withFix = fixable.filter((i) => i.fix);\n log.blank();\n log.step(\"Dry run — would apply:\");\n log.blank();\n for (const issue of withFix) {\n log.info(` ${issue.fix}`);\n }\n const skipped = fixable.length - withFix.length;\n log.blank();\n log.success(`${withFix.length} fix(es) available. Run --fix without --dry-run to apply.`);\n if (skipped > 0) {\n log.info(`${skipped} issue(s) require manual intervention.`);\n }\n log.info(`Then use ${chalk.bold(\"/lp-enhance\")} inside Claude Code to have Claude restructure and complete your CLAUDE.md.`);\n return;\n }\n\n log.blank();\n log.step(\"Applying fixes...\");\n log.blank();\n const { fixed } = await applyFixes(fixable, opts.path);\n log.blank();\n if (fixed > 0) {\n log.success(`Applied ${fixed} fix(es). Re-scanning...`);\n log.blank();\n }\n\n // Always re-scan and show report after --fix attempt\n const updatedConfig = await parseClaudeConfig(opts.path);\n const updatedResults: AnalyzerResult[] = await Promise.all([\n analyzeBudget(updatedConfig),\n analyzeQuality(updatedConfig, opts.path),\n analyzeSettings(updatedConfig),\n analyzeHooks(updatedConfig),\n analyzeRules(updatedConfig),\n analyzePermissions(updatedConfig),\n analyzeMcp(updatedConfig),\n ]);\n\n const updatedMemoryResult = await analyzeMemory(updatedConfig, opts.path);\n if (updatedMemoryResult) {\n updatedResults.push(updatedMemoryResult);\n }\n renderDoctorReport(updatedResults, { afterFix: true });\n log.info(`Then use ${chalk.bold(\"/lp-enhance\")} inside Claude Code to have Claude restructure and complete your CLAUDE.md.`);\n }\n }\n\n // CI mode: exit non-zero if score is below threshold\n if (opts.minScore) {\n const threshold = parseInt(opts.minScore, 10);\n if (overallScore < threshold) {\n process.exit(1);\n }\n }\n });\n}\n","import { readdir, access } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { readFileOrNull } from \"./fs-utils.js\";\nimport { log } from \"./output.js\";\nimport type { ClaudeConfig, HookConfig, McpServerConfig } from \"../types/index.js\";\n\nconst CLAUDE_MD = \"CLAUDE.md\";\nconst CLAUDE_DIR = \".claude\";\nconst SETTINGS_FILE = \"settings.json\";\nconst SETTINGS_LOCAL_FILE = \"settings.local.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, localClaudeMd, settings, localSettings, hooks, rules, mcpServers, skills, claudeignore] = await Promise.all([\n readClaudeMd(root),\n readFileOrNull(join(claudeDir, CLAUDE_MD)),\n readSettings(claudeDir),\n readSettingsFromFile(claudeDir, SETTINGS_LOCAL_FILE),\n readHooks(claudeDir),\n readRules(claudeDir),\n readMcpServers(claudeDir, root),\n readSkills(claudeDir),\n readFileOrNull(join(root, \".claudeignore\")),\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 localClaudeMdContent: localClaudeMd,\n localSettings,\n hooks,\n rules,\n mcpServers,\n skills,\n claudeignorePath: claudeignore !== null ? join(root, \".claudeignore\") : null,\n claudeignoreContent: claudeignore,\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 return readSettingsFromFile(claudeDir, SETTINGS_FILE);\n}\n\nasync function readSettingsFromFile(claudeDir: string, filename: string): Promise<Record<string, unknown> | null> {\n const path = join(claudeDir, filename);\n const raw = await readFileOrNull(path);\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n log.warnOnce(`parse:${path}`, `${path} is not valid JSON: ${(err as Error).message}. Treating as unreadable to avoid clobbering it.`);\n return null;\n }\n}\n\n// ─── Hooks ───\n\nasync function readHooks(claudeDir: string): Promise<ReadonlyArray<HookConfig>> {\n const [shared, local] = await Promise.all([\n readHooksFromFile(join(claudeDir, SETTINGS_FILE)),\n readHooksFromFile(join(claudeDir, SETTINGS_LOCAL_FILE)),\n ]);\n return [...shared, ...local];\n}\n\nasync function readHooksFromFile(settingsPath: string): Promise<ReadonlyArray<HookConfig>> {\n const settingsRaw = await readFileOrNull(settingsPath);\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 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 timeout: h.timeout as number | undefined,\n });\n }\n } else {\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 timeout: g.timeout as number | 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, projectRoot: string): Promise<ReadonlyArray<McpServerConfig>> {\n const [fromMcpJson, fromSettings, fromLocalSettings] = await Promise.all([\n readMcpJsonFile(join(projectRoot, \".mcp.json\")),\n readMcpServersFromSettings(join(claudeDir, SETTINGS_FILE)),\n readMcpServersFromSettings(join(claudeDir, SETTINGS_LOCAL_FILE)),\n ]);\n // Deduplicate by name — .mcp.json > local settings > shared settings\n const seen = new Set<string>();\n const result: McpServerConfig[] = [];\n for (const server of [...fromMcpJson, ...fromLocalSettings, ...fromSettings]) {\n if (!seen.has(server.name)) {\n seen.add(server.name);\n result.push(server);\n }\n }\n return result;\n}\n\n/** Read .mcp.json (project-scoped MCP config created by `claude mcp add --scope project`) */\nasync function readMcpJsonFile(mcpJsonPath: string): Promise<ReadonlyArray<McpServerConfig>> {\n const raw = await readFileOrNull(mcpJsonPath);\n if (raw === null) return [];\n\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n const servers = parsed.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 ?? c.type) 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\nasync function readMcpServersFromSettings(settingsPath: string): Promise<ReadonlyArray<McpServerConfig>> {\n const settingsRaw = await readFileOrNull(settingsPath);\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 ?? c.type) as McpServerConfig[\"transport\"]) ?? \"stdio\",\n command: c.command as string | undefined,\n url: c.url as string | undefined,\n });\n }\n return result;\n } catch {\n return [];\n }\n}\n\n// ─── Skills ───\n\nasync function readSkills(claudeDir: string): Promise<ReadonlyArray<string>> {\n const commandsDir = join(claudeDir, \"commands\");\n const skillsDir = join(claudeDir, \"skills\");\n\n const [commands, skills] = await Promise.all([\n listFilesRecursive(commandsDir, \".md\"),\n listFilesRecursive(skillsDir, \".md\"),\n ]);\n\n return [...commands, ...skills];\n}\n\n\nasync function listFilesRecursive(dir: string, ext: string): Promise<string[]> {\n try {\n await access(dir);\n } catch {\n return [];\n }\n\n const results: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const nested = await listFilesRecursive(fullPath, ext);\n results.push(...nested);\n } else if (entry.name.endsWith(ext)) {\n results.push(fullPath);\n }\n }\n\n return results;\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nconst BUDGET_WARN = 150;\nconst BUDGET_DANGER = 200;\nconst BUDGET_CRITICAL = 250;\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 ~200 budget. Compliance drops significantly past 200.`,\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 ~200 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 ~200 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 // 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 // Deprecated includeCoAuthoredBy\n if (config.settings.includeCoAuthoredBy !== undefined) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"low\",\n message: \"Deprecated includeCoAuthoredBy — use attribution: { commit: \\\"\\\", pr: \\\"\\\" } instead\",\n fix: \"Replace includeCoAuthoredBy with the attribution object in settings.json\",\n });\n }\n\n // Monorepo hint — claudeMdExcludes\n if (!config.settings.claudeMdExcludes) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"info\",\n message: \"No claudeMdExcludes configured — consider adding this if you have a monorepo\",\n });\n }\n\n\n // Auto-memory disabled\n if (config.settings.autoMemoryEnabled === false) {\n const hasMemorySection = config.claudeMdContent?.includes(\"## Memory\") ?? false;\n if (!hasMemorySection) {\n issues.push({\n analyzer: \"Settings\",\n severity: \"medium\",\n message: \"Auto-memory is disabled with no manual memory strategy in CLAUDE.md\",\n fix: \"Re-enable autoMemoryEnabled or add a ## Memory section to CLAUDE.md\",\n });\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 // Check for PostCompact hook (session continuity)\n const hasPostCompact = hooks.some((h) => h.event === \"PostCompact\");\n if (!hasPostCompact) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"low\",\n message: \"No PostCompact hook — session context is lost when conversation is compacted\",\n fix: \"Add a PostCompact hook that re-injects TASKS.md after compaction\",\n });\n }\n\n // Check for SessionStart hook\n const hasSessionStart = hooks.some((h) => h.event === \"SessionStart\");\n if (!hasSessionStart) {\n issues.push({\n analyzer: \"Hooks\",\n severity: \"low\",\n message: \"No SessionStart hook — session starts without project context loaded\",\n fix: \"Add a SessionStart hook that injects TASKS.md at startup\",\n });\n }\n\n const score = Math.max(0, 100 - issues.length * 15);\n return { name: \"Hooks\", issues, score };\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename, join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { fileExists } from \"../../../lib/fs-utils.js\";\nimport { ENHANCE_SKILL_VERSION } from \"../../init/generators/skill-enhance.js\";\nimport type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\n\nexport async function analyzeRules(config: ClaudeConfig): Promise<AnalyzerResult> {\n const issues: DiagnosticIssue[] = [];\n\n const projectRoot = config.claudeMdPath ? dirname(config.claudeMdPath) : process.cwd();\n\n // Check for BACKLOG.md\n const hasBacklog = await fileExists(join(projectRoot, \"BACKLOG.md\"));\n if (!hasBacklog) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No BACKLOG.md found — deferred features get lost in conversation history\",\n fix: \"Run `claude-launchpad init` or `doctor --fix` to generate one\",\n });\n }\n\n // Check for .claudeignore\n const hasClaudeignore = await fileExists(join(projectRoot, \".claudeignore\"));\n if (!hasClaudeignore) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No .claudeignore found — Claude may read noise files (node_modules, dist, lockfiles)\",\n fix: \"Run `claude-launchpad init` or `doctor --fix` to generate one\",\n });\n }\n\n // Check for /lp-enhance skill (new skills/ format or legacy commands/ format)\n const hasSkillInProject = config.skills.some((s) =>\n basename(s) === \"SKILL.md\" && s.includes(\"lp-enhance\") || basename(s) === \"lp-enhance.md\",\n );\n const hasSkillGlobal = await fileExists(join(homedir(), \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\"))\n || await fileExists(join(homedir(), \".claude\", \"commands\", \"lp-enhance.md\"));\n if (!hasSkillInProject && !hasSkillGlobal) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No /lp-enhance skill found — use it inside Claude Code to AI-complete your CLAUDE.md\",\n fix: \"Run `claude-launchpad init` or `doctor --fix` to generate the skill\",\n });\n } else {\n const installedVersion = await getSkillVersion(projectRoot);\n if (installedVersion !== null && installedVersion < ENHANCE_SKILL_VERSION) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: `/lp-enhance skill is outdated (v${installedVersion}, latest v${ENHANCE_SKILL_VERSION})`,\n fix: \"Run `doctor --fix` to update the skill\",\n });\n }\n }\n\n if (config.rules.length === 0) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No .claude/rules/ files found\",\n fix: \"Move detailed conventions from CLAUDE.md to .claude/rules/*.md (auto-loaded, saves budget)\",\n });\n return { name: \"Rules\", issues, score: 60 };\n }\n\n // Check for skill authoring conventions in any rules file\n let hasSkillAuthoring = false;\n for (const rulePath of config.rules) {\n try {\n const content = await readFile(rulePath, \"utf-8\");\n if (/^##\\s+Skill\\s+Authoring/im.test(content)) {\n hasSkillAuthoring = true;\n break;\n }\n } catch {\n continue;\n }\n }\n if (!hasSkillAuthoring) {\n issues.push({\n analyzer: \"Rules\",\n severity: \"low\",\n message: \"No skill authoring conventions found in .claude/rules/\",\n fix: \"Run `doctor --fix` to add a Skill Authoring section to conventions.md\",\n });\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\nasync function getSkillVersion(projectRoot: string): Promise<number | null> {\n const paths = [\n join(projectRoot, \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\"),\n join(homedir(), \".claude\", \"skills\", \"lp-enhance\", \"SKILL.md\"),\n ];\n\n for (const p of paths) {\n try {\n const content = await readFile(p, \"utf-8\");\n const match = content.match(/<!-- lp-enhance-version: (\\d+) -->/);\n if (match) return parseInt(match[1], 10);\n // Skill exists but has no version tag — treat as v0 (pre-versioning)\n return 0;\n } catch {\n continue;\n }\n }\n return null;\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 const settings = config.settings;\n const permissions = settings?.permissions as Record<string, unknown> | undefined;\n const denyList = (permissions?.deny as string[] | undefined) ?? [];\n const allowList = (permissions?.allow as string[] | undefined) ?? [];\n\n // Credential file exposure\n const credentialPatterns = [\"Read(~/.ssh/*)\", \"Read(~/.aws/*)\", \"Read(~/.npmrc)\"];\n const missingCreds = credentialPatterns.filter((p) => !denyList.includes(p));\n if (missingCreds.length > 0) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: `Credential files not blocked: ${missingCreds.join(\", \")} — Claude can read SSH keys, AWS creds, or npm tokens`,\n fix: \"Add Read(~/.ssh/*), Read(~/.aws/*), Read(~/.npmrc) to permissions.deny\",\n });\n }\n\n // Blanket Bash approval\n const hasBlanketBash = allowList.some((a) => a === \"Bash\" || (a.startsWith(\"Bash\") && !a.includes(\"(\")));\n if (hasBlanketBash) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: \"Bash is blanket-allowed without pattern restriction — all shell commands are auto-approved\",\n fix: \"Replace blanket Bash with scoped patterns like Bash(npm test) or remove it\",\n });\n }\n\n // Bypass mode unprotected\n if (settings?.disableBypassPermissionsMode !== \"disable\") {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: \"Bypass permissions mode not disabled — --dangerously-skip-permissions bypasses all checks\",\n fix: 'Add \"disableBypassPermissionsMode\": \"disable\" to settings.json',\n });\n }\n\n // Filesystem sandbox actively breaks cross-project tooling (memory MCP, ~/.claude reads)\n const sandbox = settings?.sandbox as Record<string, unknown> | undefined;\n if (sandbox?.enabled === true) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"high\",\n message: \"Filesystem sandbox enabled — blocks memory MCP and other cross-project tooling. Deny rules already cover the threat model.\",\n fix: 'Remove the \"sandbox\" block from settings.json',\n });\n }\n\n // .env gap: hooks protect but .claudeignore doesn't\n const hasEnvHook = config.hooks.some((h) => h.command?.includes(\".env\"));\n if (hasEnvHook && config.claudeignoreContent !== null) {\n const lines = config.claudeignoreContent.split(\"\\n\").map((l) => l.trim());\n const hasEnvInIgnore = lines.some((l) => l === \".env\" || l === \".env.*\" || l === \".env*\");\n if (!hasEnvInIgnore) {\n issues.push({\n analyzer: \"Permissions\",\n severity: \"medium\",\n message: \".env is protected by hooks but not in .claudeignore — cat .env via Bash bypasses hooks\",\n fix: \"Add .env to .claudeignore for defense in depth\",\n });\n }\n }\n\n // Bash auto-allow without security hooks (existing check)\n const hasBashSecurity = config.hooks.some(\n (h) => h.event === \"PreToolUse\" && (h.matcher?.includes(\"Bash\") || !h.matcher),\n );\n const bashAllowed = settings?.allowedTools as string[] | undefined;\n const hasBashAutoAllow = bashAllowed?.some((t) =>\n typeof t === \"string\" && t.toLowerCase().includes(\"bash\"),\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\",\n });\n }\n\n // 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 // Off-Limits section in CLAUDE.md\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 * 15);\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. Use `/lp-enhance` in Claude Code to get stack-specific recommendations.\",\n });\n return { name: \"MCP Servers\", issues, score: 50 };\n }\n\n for (const server of servers) {\n if (server.transport === \"stdio\" && !server.command) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"high\",\n message: `MCP server \"${server.name}\" uses stdio transport but has no command`,\n fix: `Add a \"command\" field to the \"${server.name}\" MCP server config`,\n });\n }\n\n if ((server.transport === \"sse\" || server.transport === \"http\") && !server.url) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"high\",\n message: `MCP server \"${server.name}\" uses ${server.transport} transport but has no URL`,\n fix: `Add a \"url\" field to the \"${server.name}\" MCP server config`,\n });\n }\n\n if (server.transport === \"stdio\" && server.command) {\n const executable = server.command.split(\" \")[0];\n if (executable.startsWith(\"/\") || executable.startsWith(\"./\")) {\n try {\n await access(executable);\n } catch {\n issues.push({\n analyzer: \"MCP\",\n severity: \"medium\",\n message: `MCP server \"${server.name}\" command not found: ${executable}`,\n fix: \"Verify the path exists or install the required package\",\n });\n }\n }\n }\n }\n\n // Check for allowedMcpServers when servers are configured\n if (servers.length > 0) {\n const settings = config.settings ?? {};\n const localSettings = config.localSettings ?? {};\n const hasAllowList = settings.allowedMcpServers || localSettings.allowedMcpServers;\n if (!hasAllowList) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"medium\",\n message: \"MCP servers configured but no allowedMcpServers list — any added server is auto-trusted\",\n fix: \"Add allowedMcpServers to settings.json listing only trusted server names\",\n });\n }\n }\n\n // Detect orphaned mcp__<server>__* permission entries (stale after rename/removal)\n const orphanedServers = findOrphanedMcpPermissions(config, servers.map((s) => s.name));\n for (const orphan of orphanedServers) {\n issues.push({\n analyzer: \"MCP\",\n severity: \"medium\",\n message: `permissions.allow contains \"mcp__${orphan}__*\" entries but no MCP server named \"${orphan}\" is registered — stale entries silently block tool calls`,\n fix: `Register the \"${orphan}\" MCP server, or remove its mcp__${orphan}__* entries from permissions.allow`,\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\nfunction findOrphanedMcpPermissions(config: ClaudeConfig, registeredNames: ReadonlyArray<string>): ReadonlyArray<string> {\n const registered = new Set(registeredNames);\n const allowEntries: string[] = [\n ...extractAllow(config.settings),\n ...extractAllow(config.localSettings),\n ];\n\n const orphaned = new Set<string>();\n for (const entry of allowEntries) {\n const parts = entry.split(\"__\");\n if (parts.length < 3 || parts[0] !== \"mcp\") continue;\n const serverName = parts[1];\n if (!serverName || registered.has(serverName)) continue;\n orphaned.add(serverName);\n }\n return [...orphaned];\n}\n\nfunction extractAllow(settings: Record<string, unknown> | null | undefined): ReadonlyArray<string> {\n const permissions = settings?.permissions as Record<string, unknown> | undefined;\n const allow = permissions?.allow as unknown;\n return Array.isArray(allow) ? allow.filter((e): e is string => typeof e === \"string\") : [];\n}\n","/**\n * Hook command resolver — transitively expands one level of shell-wrapper indirection.\n *\n * A Claude Code hook like `bash .claude/session-start.sh` delegates capability to a\n * wrapper script. Analyzers inspecting only the literal `command` string miss the\n * wrapper's body. This resolver returns the command text + bodies of referenced .sh\n * files inside the project root so analyzers can run `.includes()` against a single\n * \"effective command\" string.\n *\n * Depth limit: 1 (no recursion into scripts-that-call-scripts).\n * Extension limit: only `.sh` is followed.\n * Root boundary: only paths resolving (via realpath) inside projectRoot are read.\n */\n\nimport { readFile, realpath } from \"node:fs/promises\";\nimport { resolve, sep } from \"node:path\";\nimport { parse } from \"shell-quote\";\n\nexport interface HookExpansion {\n readonly path: string;\n readonly body: string;\n}\n\nexport interface ResolvedHookCommand {\n readonly command: string;\n readonly expansions: readonly HookExpansion[];\n readonly missingScripts: readonly string[];\n}\n\nexport async function resolveHookCommand(\n hook: { readonly command?: string | null },\n projectRoot: string,\n): Promise<ResolvedHookCommand> {\n const command = hook.command ?? \"\";\n if (!command) return { command: \"\", expansions: [], missingScripts: [] };\n\n const scriptPaths = extractShellScripts(command);\n if (scriptPaths.length === 0) return { command, expansions: [], missingScripts: [] };\n\n let projectRootReal: string;\n try {\n projectRootReal = await realpath(projectRoot);\n } catch {\n return { command, expansions: [], missingScripts: [] };\n }\n\n const expansions: HookExpansion[] = [];\n const missingScripts: string[] = [];\n\n for (const relPath of scriptPaths) {\n const resolved = resolve(projectRoot, relPath);\n let realResolved: string;\n try {\n realResolved = await realpath(resolved);\n } catch {\n missingScripts.push(relPath);\n continue;\n }\n if (realResolved !== projectRootReal && !realResolved.startsWith(projectRootReal + sep)) {\n continue;\n }\n try {\n const body = await readFile(realResolved, \"utf-8\");\n expansions.push({ path: relPath, body });\n } catch {\n missingScripts.push(relPath);\n }\n }\n\n return { command, expansions, missingScripts };\n}\n\nexport function effectiveCommandText(resolved: ResolvedHookCommand): string {\n if (resolved.expansions.length === 0) return resolved.command;\n return resolved.command + \"\\n\" + resolved.expansions.map((e) => e.body).join(\"\\n\");\n}\n\nfunction extractShellScripts(command: string): readonly string[] {\n const tokens = parse(command);\n const scripts: string[] = [];\n for (const token of tokens) {\n if (typeof token !== \"string\") continue;\n if (!token.endsWith(\".sh\")) continue;\n if (token.startsWith(\"~\") || token.startsWith(\"$\")) continue;\n scripts.push(token);\n }\n return scripts;\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\nimport { readSyncConfig } from \"../../memory/utils/gist-transport.js\";\nimport {\n resolveHookCommand,\n effectiveCommandText,\n type ResolvedHookCommand,\n} from \"./hook-resolver.js\";\n\nconst MEMORY_MCP_TOOLS = [\n \"mcp__agentic-memory__memory_store\",\n \"mcp__agentic-memory__memory_search\",\n \"mcp__agentic-memory__memory_recent\",\n \"mcp__agentic-memory__memory_forget\",\n \"mcp__agentic-memory__memory_relate\",\n \"mcp__agentic-memory__memory_stats\",\n \"mcp__agentic-memory__memory_update\",\n] as const;\n\nasync function resolveAllHooks(\n hooks: ClaudeConfig[\"hooks\"],\n projectRoot: string,\n): Promise<ResolvedHookCommand[]> {\n return Promise.all(hooks.map((h) => resolveHookCommand(h, projectRoot)));\n}\n\nexport async function hasMemoryIndicators(\n config: ClaudeConfig,\n projectRoot: string,\n): Promise<boolean> {\n // MCP server in project settings (shared or local)\n if (config.mcpServers.some((s) => s.name === \"agentic-memory\")) return true;\n\n // Tool permissions referencing agentic-memory (server may be registered via `claude mcp add`)\n const permissions = (config.settings?.permissions as Record<string, unknown> | undefined) ?? {};\n const localPermissions = (config.localSettings?.permissions as Record<string, unknown> | undefined) ?? {};\n const allowList = [\n ...((permissions.allow as string[] | undefined) ?? []),\n ...((localPermissions.allow as string[] | undefined) ?? []),\n ];\n if (allowList.some((t) => t.startsWith(\"mcp__agentic-memory__\"))) return true;\n\n // SessionStart hook referencing memory context injection — see through 1-level wrappers\n const resolved = await resolveAllHooks(config.hooks, projectRoot);\n return config.hooks.some((h, i) =>\n h.event === \"SessionStart\" && effectiveCommandText(resolved[i]).includes(\"memory context\"),\n );\n}\n\n/**\n * Analyzes agentic-memory configuration.\n * Returns null if memory is not detected — doctor skips it for non-memory users.\n */\nexport async function analyzeMemory(\n config: ClaudeConfig,\n projectRoot: string,\n): Promise<AnalyzerResult | null> {\n if (!await hasMemoryIndicators(config, projectRoot)) return null;\n\n const issues: DiagnosticIssue[] = [];\n const resolved = await resolveAllHooks(config.hooks, projectRoot);\n const effectiveAt = (i: number): string => effectiveCommandText(resolved[i]);\n\n // 1. SessionStart hook with memory context (wrapper-aware)\n const hasSessionStart = config.hooks.some(\n (h, i) => h.event === \"SessionStart\" && effectiveAt(i).includes(\"memory context\"),\n );\n if (!hasSessionStart) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"high\",\n message: \"No SessionStart hook with memory context injection\",\n fix: \"Add a SessionStart hook that runs `memory context` to inject relevant memories\",\n });\n }\n\n // 2. Deprecated Stop hook with memory extract (removed in v0.14.0)\n const hasStaleStopHook = config.hooks.some(\n (h, i) => h.event === \"Stop\" && effectiveAt(i).includes(\"memory extract\"),\n );\n if (hasStaleStopHook) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"low\",\n message: \"Deprecated Stop hook found (memory extract) — auto-extraction was removed, Claude stores memories directly via MCP tools\",\n fix: \"Run `doctor --fix` to remove the stale Stop hook\",\n });\n }\n\n // 3. autoMemoryEnabled should be false (built-in memory conflicts with agentic-memory)\n const autoMemoryDisabled = config.settings?.autoMemoryEnabled === false\n || config.localSettings?.autoMemoryEnabled === false;\n if (!autoMemoryDisabled) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"medium\",\n message: \"autoMemoryEnabled not disabled — built-in memory may conflict with agentic-memory\",\n fix: \"Set autoMemoryEnabled: false in settings.json or settings.local.json\",\n });\n }\n\n // 5. CLAUDE.md memory guidance (check both shared and local)\n const hasMemoryGuidance = config.claudeMdContent?.includes(\"agentic-memory\")\n || config.claudeMdContent?.includes(\"## Memory\")\n || config.localClaudeMdContent?.includes(\"agentic-memory\")\n || config.localClaudeMdContent?.includes(\"## Memory\");\n if (!hasMemoryGuidance) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"low\",\n message: \"CLAUDE.md missing memory guidance section\",\n fix: \"Add a ## Memory section to CLAUDE.md describing when and how to use agentic-memory\",\n });\n }\n\n // 6. MCP tool permissions (check both shared and local settings)\n const permissions = (config.settings?.permissions as Record<string, unknown> | undefined) ?? {};\n const localPermissions = (config.localSettings?.permissions as Record<string, unknown> | undefined) ?? {};\n const allowList = [\n ...((permissions.allow as string[] | undefined) ?? []),\n ...((localPermissions.allow as string[] | undefined) ?? []),\n ];\n const missingTools = MEMORY_MCP_TOOLS.filter((t) => !allowList.includes(t));\n if (missingTools.length > 0) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"low\",\n message: `${missingTools.length} agentic-memory MCP tool permission(s) missing from allowedTools`,\n fix: \"Add all agentic-memory tool names to allowedTools in .claude/settings.json\",\n });\n }\n\n // 6b. allowedMcpServers present but missing agentic-memory — silently blocks MCP registration\n const sharedAllowed = config.settings?.allowedMcpServers as unknown;\n const localAllowed = config.localSettings?.allowedMcpServers as unknown;\n const allowedServers = [\n ...(Array.isArray(sharedAllowed) ? sharedAllowed : []),\n ...(Array.isArray(localAllowed) ? localAllowed : []),\n ] as Array<{ serverName?: unknown }>;\n const hasAllowlist = Array.isArray(sharedAllowed) || Array.isArray(localAllowed);\n const memoryInAllowlist = allowedServers.some(\n (e) => e && typeof e === \"object\" && e.serverName === \"agentic-memory\",\n );\n if (hasAllowlist && !memoryInAllowlist) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"high\",\n message: \"allowedMcpServers is set but does not include agentic-memory — MCP registration will be blocked\",\n fix: \"Run `doctor --fix` to add agentic-memory to allowedMcpServers\",\n });\n }\n\n // 7. Sync hooks when sync is configured (wrapper-aware)\n const syncConfig = readSyncConfig();\n if (syncConfig) {\n const hasSessionStartPull = config.hooks.some(\n (h, i) => h.event === \"SessionStart\" && effectiveAt(i).includes(\"memory pull\"),\n );\n if (!hasSessionStartPull) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"medium\",\n message: \"Sync configured but no SessionStart hook to auto-pull memories before context injection\",\n fix: \"Run `doctor --fix` to add a SessionStart hook that pulls memories automatically\",\n });\n }\n\n const hasSessionEndPush = config.hooks.some(\n (h, i) => h.event === \"SessionEnd\" && effectiveAt(i).includes(\"memory push\"),\n );\n if (!hasSessionEndPush) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"medium\",\n message: \"Sync configured but no SessionEnd hook to auto-push memories after each session\",\n fix: \"Run `doctor --fix` to add a SessionEnd hook that pushes memories automatically\",\n });\n }\n\n // nohup check stays on the literal command — wrappers are expected to handle their own daemonisation.\n const hasNonNohupPush = config.hooks.some(\n (h) => h.event === \"SessionEnd\"\n && h.command?.includes(\"memory push\")\n && !h.command.includes(\"nohup\"),\n );\n if (hasNonNohupPush) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"high\",\n message: \"SessionEnd push hook is not nohup-wrapped — Claude Code cancels it on exit before the push completes\",\n fix: \"Run `doctor --fix` to upgrade the hook to a nohup-wrapped push\",\n });\n }\n }\n\n // 8. Broken wrappers — hook references a .sh script inside the project that doesn't exist.\n // Only report for SessionStart/SessionEnd hooks (the ones this analyzer inspects).\n for (let i = 0; i < config.hooks.length; i++) {\n const h = config.hooks[i];\n if (h.event !== \"SessionStart\" && h.event !== \"SessionEnd\") continue;\n for (const missing of resolved[i].missingScripts) {\n issues.push({\n analyzer: \"Memory\",\n severity: \"low\",\n message: `${h.event} hook references \\`${missing}\\` but the file is missing — wrapper can't run`,\n fix: `Create ${missing} or remove the broken hook from .claude/settings.json`,\n });\n }\n }\n\n const critical = issues.filter((i) => i.severity === \"critical\").length;\n const high = issues.filter((i) => i.severity === \"high\").length;\n const medium = issues.filter((i) => i.severity === \"medium\").length;\n const low = issues.filter((i) => i.severity === \"low\").length;\n const score = Math.max(0, 100 - (critical * 40 + high * 20 + medium * 10 + low * 5));\n\n return { name: \"Memory\", issues, score };\n}\n","/**\n * Intent-based section detection for CLAUDE.md quality analysis.\n *\n * Replaces the old BASE_SECTIONS regex loop that required an exact heading match\n * (e.g. `## Session Start`). Now a section satisfies an intent when either its\n * heading matches a pattern OR its body contains enough intent-signalling keywords.\n * A section wrapped in LP-STUB markers never satisfies an intent — stubs are\n * scaffolding, not real content.\n */\n\nimport { LP_STUB_OPEN } from \"../../../lib/stub-marker.js\";\n\nexport interface IntentRule {\n readonly name: string;\n readonly why: string;\n readonly headingPatterns: readonly RegExp[];\n readonly bodyKeywords: readonly RegExp[];\n readonly minBodyKeywords: number;\n}\n\nexport interface ParsedSection {\n readonly heading: string;\n readonly body: string;\n readonly isStub: boolean;\n}\n\nexport const INTENT_RULES: readonly IntentRule[] = [\n {\n name: \"Stack\",\n why: \"Claude performs worse without knowing the tech stack\",\n headingPatterns: [/^tech\\s+stack$/i, /^stack$/i, /^technology$/i, /^tech$/i],\n bodyKeywords: [\n /\\blanguage:/i,\n /\\bframework:/i,\n /\\bpackage\\s+manager:/i,\n /\\bruntime:/i,\n /\\b(typescript|javascript|python|ruby|go|rust|java|php|swift|kotlin)\\b/i,\n /\\b(react|next\\.?js|vue|svelte|angular|express|fastify|laravel|rails|django|flask)\\b/i,\n /\\b(node(?:\\.?js)?|deno|bun|cpython)\\b/i,\n ],\n minBodyKeywords: 2,\n },\n {\n name: \"Commands\",\n why: \"Claude guesses wrong without explicit dev/build/test commands\",\n headingPatterns: [/^commands?$/i, /^scripts$/i, /^dev\\s+commands$/i, /^development$/i],\n bodyKeywords: [\n /\\b(pnpm|npm|yarn|bun)\\s+\\w+/i,\n /\\b(build|test|dev|lint|typecheck|start):/i,\n /\\brun\\s+(tests?|build|dev)/i,\n /\\bmake\\s+\\w+/i,\n /\\bcargo\\s+\\w+/i,\n ],\n minBodyKeywords: 2,\n },\n {\n name: \"Session Start\",\n why: \"Without this, Claude won't read TASKS.md or maintain continuity\",\n headingPatterns: [\n /^session\\s+start$/i,\n /^session$/i,\n /^sprint\\s+planning$/i,\n /^workflow$/i,\n /^getting\\s+started$/i,\n /^at\\s+session\\s+start$/i,\n ],\n bodyKeywords: [\n /\\btasks?\\.md\\b/i,\n /\\bsession\\s+(start|log)\\b/i,\n /\\bsprint\\s+(log|planning)\\b/i,\n /\\b(read|check).*at\\s+(session|start)/i,\n /\\btrack\\s+progress/i,\n ],\n minBodyKeywords: 1,\n },\n {\n name: \"Off-Limits\",\n why: \"Without guardrails, Claude has no boundaries beyond defaults\",\n headingPatterns: [\n /^off.?limits$/i,\n /^constraints$/i,\n /^don'?t$/i,\n /^rules$/i,\n /^guardrails$/i,\n /^forbidden$/i,\n /^security\\s+notes$/i,\n ],\n bodyKeywords: [\n /\\bnever\\s+\\w+/i,\n /\\bforbidden/i,\n /\\bdo\\s+not\\b/i,\n /\\b(secret|credential|api\\s+key|password|token)/i,\n /\\.env\\b/,\n ],\n minBodyKeywords: 2,\n },\n {\n name: \"Architecture/Structure\",\n why: \"Claude makes better decisions when it understands the codebase shape\",\n headingPatterns: [\n /^architecture$/i,\n /^project\\s+structure$/i,\n /^structure$/i,\n /^codebase$/i,\n /^layout$/i,\n /^repo\\s+layout$/i,\n ],\n bodyKeywords: [\n /\\bsrc\\//,\n /\\b(directory|directories|folder|module|layer)\\b/i,\n /\\barchitecture\\b/i,\n ],\n minBodyKeywords: 1,\n },\n {\n name: \"Backlog\",\n why: \"Without backlog instructions, deferred features get lost in conversation history\",\n headingPatterns: [\n /^backlog$/i,\n /^roadmap$/i,\n /^parked$/i,\n /^future\\s+work$/i,\n /^parked\\s+features?$/i,\n ],\n bodyKeywords: [\n /\\bbacklog\\.md\\b/i,\n /\\bbacklog\\b/i,\n /\\bdeferred\\b/i,\n /\\bparked\\s+features?\\b/i,\n ],\n minBodyKeywords: 1,\n },\n {\n name: \"Stop-and-Swarm\",\n why: \"Without a stop-and-swarm rule, Claude keeps guessing in circles instead of parallelizing research\",\n headingPatterns: [\n /^stop.and.swarm$/i,\n /^when\\s+stuck$/i,\n /^debug$/i,\n /^escalation$/i,\n /^swarm$/i,\n /^parallel\\s+agents?$/i,\n ],\n bodyKeywords: [\n /\\bstop-and-swarm\\b/i,\n /\\bparallel\\s+agents?\\b/i,\n /\\bspin\\s+up\\b/i,\n /\\b(3|three)\\s+(parallel\\s+)?agents?\\b/i,\n /\\bfailed\\s+iterations?\\b/i,\n ],\n minBodyKeywords: 1,\n },\n] as const;\n\nexport const MEMORY_INTENT: IntentRule = {\n name: \"Memory & Learnings\",\n why: \"Without memory instructions, Claude forgets learnings and repeats mistakes across sessions\",\n headingPatterns: [/^memory$/i, /^learnings?$/i, /^memory\\s*(&|and)\\s*learnings?$/i],\n bodyKeywords: [\n /\\bmemory_search\\b/i,\n /\\bmemory_store\\b/i,\n /\\bagentic-memory\\b/i,\n /\\bstore\\s+memories?\\b/i,\n /\\binject(ed)?\\s+(at|in|into)\\s+(session|startup)/i,\n ],\n minBodyKeywords: 1,\n} as const;\n\nexport function parseSections(content: string): ParsedSection[] {\n const lines = content.split(\"\\n\");\n const sections: ParsedSection[] = [];\n let currentHeading: string | null = null;\n let currentBody: string[] = [];\n\n const flush = (): void => {\n if (currentHeading === null) return;\n const body = currentBody.join(\"\\n\");\n sections.push({\n heading: currentHeading,\n body,\n isStub: body.includes(LP_STUB_OPEN),\n });\n };\n\n for (const line of lines) {\n const match = line.match(/^##\\s+(.+?)\\s*$/);\n if (match) {\n flush();\n currentHeading = match[1];\n currentBody = [];\n } else if (currentHeading !== null) {\n currentBody.push(line);\n }\n }\n flush();\n\n return sections;\n}\n\nexport function sectionSatisfiesIntent(section: ParsedSection, rule: IntentRule): boolean {\n if (section.isStub) return false;\n\n const headingMatch = rule.headingPatterns.some((p) => p.test(section.heading));\n if (headingMatch) return true;\n\n const keywordHits = rule.bodyKeywords.reduce(\n (n, p) => (p.test(section.body) ? n + 1 : n),\n 0,\n );\n return keywordHits >= rule.minBodyKeywords;\n}\n\nexport function documentSatisfiesIntent(\n sections: readonly ParsedSection[],\n rule: IntentRule,\n): boolean {\n return sections.some((s) => sectionSatisfiesIntent(s, rule));\n}\n","import type { ClaudeConfig, AnalyzerResult, DiagnosticIssue } from \"../../../types/index.js\";\nimport { hasMemoryIndicators } from \"./memory.js\";\nimport {\n INTENT_RULES,\n MEMORY_INTENT,\n parseSections,\n documentSatisfiesIntent,\n} from \"./quality-intents.js\";\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, projectRoot: string): 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 via intent detection (keyword-based, not exact heading match).\n // Memory intent only checked if memory is installed.\n const rules = await hasMemoryIndicators(config, projectRoot)\n ? [...INTENT_RULES, MEMORY_INTENT]\n : [...INTENT_RULES];\n const combinedContent = [content, config.localClaudeMdContent].filter(Boolean).join(\"\\n\\n\");\n const sections = parseSections(combinedContent);\n for (const rule of rules) {\n if (!documentSatisfiesIntent(sections, rule)) {\n issues.push({\n analyzer: \"Quality\",\n severity: \"medium\",\n message: `Missing \"## ${rule.name}\" section — ${rule.why}`,\n fix: `Add a ## ${rule.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 { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parseClaudeConfig } from \"../../lib/parser.js\";\nimport { log, renderDoctorReport } from \"../../lib/output.js\";\nimport { analyzeBudget } from \"./analyzers/budget.js\";\nimport { analyzeSettings } from \"./analyzers/settings.js\";\nimport { analyzeHooks } from \"./analyzers/hooks.js\";\nimport { analyzeRules } from \"./analyzers/rules.js\";\nimport { analyzePermissions } from \"./analyzers/permissions.js\";\nimport { analyzeMcp } from \"./analyzers/mcp.js\";\nimport { analyzeQuality } from \"./analyzers/quality.js\";\nimport type { AnalyzerResult } from \"../../types/index.js\";\n\n/**\n * Watch config files for changes using polling (reliable on all OS).\n * Re-runs doctor on every detected change.\n */\nexport async function watchConfig(projectRoot: string): Promise<void> {\n await runAndDisplay(projectRoot);\n\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n\n let lastSnapshot = await getFileSnapshot(projectRoot);\n\n setInterval(async () => {\n const currentSnapshot = await getFileSnapshot(projectRoot);\n if (currentSnapshot !== lastSnapshot) {\n lastSnapshot = currentSnapshot;\n console.clear();\n await runAndDisplay(projectRoot);\n log.blank();\n log.info(\"Watching for changes... (Ctrl+C to stop)\");\n log.blank();\n }\n }, 1000);\n\n await new Promise(() => {});\n}\n\nasync function getFileSnapshot(projectRoot: string): Promise<string> {\n const files = [\n join(projectRoot, \"CLAUDE.md\"),\n join(projectRoot, \".claudeignore\"),\n ];\n\n const claudeDir = join(projectRoot, \".claude\");\n try {\n const entries = await readdir(claudeDir, { withFileTypes: true, recursive: true });\n for (const entry of entries) {\n if (entry.isFile()) {\n const parentPath = (entry as unknown as { parentPath?: string }).parentPath ?? claudeDir;\n files.push(join(parentPath, entry.name));\n }\n }\n } catch {\n // .claude/ doesn't exist\n }\n\n const mtimes: string[] = [];\n for (const file of files) {\n try {\n const s = await stat(file);\n mtimes.push(`${file}:${s.mtimeMs}`);\n } catch {\n mtimes.push(`${file}:missing`);\n }\n }\n\n return mtimes.join(\"|\");\n}\n\nasync function runAndDisplay(projectRoot: string): Promise<void> {\n console.log(\"\\x1b[36m\\x1b[1m Claude Launchpad\\x1b[0m\");\n console.log(\"\\x1b[2m Scaffold · Diagnose · Evaluate · Remember\\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, projectRoot),\n analyzeSettings(config),\n analyzeHooks(config),\n analyzeRules(config),\n analyzePermissions(config),\n analyzeMcp(config),\n ]);\n\n renderDoctorReport(results);\n}\n","import { Command } from \"commander\";\nimport { select } from \"@inquirer/prompts\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { printBanner, log, printScoreCard } from \"../../lib/output.js\";\nimport { loadScenarios } from \"./loader.js\";\nimport { runScenarioWithRetries } from \"./runner.js\";\nimport type { EvalRunResult } from \"../../types/index.js\";\n\nexport function createEvalCommand(): Command {\n return new Command(\"eval\")\n .description(\"Test your Claude Code config against eval scenarios\")\n .option(\"-s, --suite <suite>\", \"Eval suite to run (e.g., security, conventions, workflow)\")\n .option(\"-p, --path <path>\", \"Project root path\", process.cwd())\n .option(\"--scenarios <path>\", \"Custom scenarios directory\")\n .option(\"--runs <n>\", \"Runs per scenario (default: 3)\", \"3\")\n .option(\"--timeout <ms>\", \"Timeout per run in ms (default: 120000)\", \"120000\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--debug\", \"Keep sandbox directories for inspection\")\n .option(\"--model <model>\", \"Model to use for eval (e.g., sonnet, haiku, opus)\")\n .action(async (opts) => {\n printBanner();\n\n // Interactive mode when no flags provided\n const hasFlags = opts.suite\n || opts.model\n || opts.runs !== \"3\"\n || opts.timeout !== \"120000\"\n || opts.path !== process.cwd()\n || Boolean(opts.scenarios)\n || opts.json\n || opts.debug;\n if (!hasFlags) {\n opts.suite = await select({\n message: \"Suite\",\n choices: [\n { name: \"security (6 scenarios)\", value: \"security\" },\n { name: \"conventions (5 scenarios)\", value: \"conventions\" },\n { name: \"workflow (4 scenarios)\", value: \"workflow\" },\n { name: \"all (15 scenarios)\", value: undefined },\n ],\n });\n opts.runs = await select({\n message: \"Runs per scenario\",\n choices: [\n { name: \"1 — fast\", value: \"1\" },\n { name: \"3 — default\", value: \"3\" },\n { name: \"5 — thorough\", value: \"5\" },\n ],\n });\n opts.model = await select({\n message: \"Model\",\n choices: [\n { name: \"haiku — cheapest\", value: \"haiku\" },\n { name: \"sonnet — balanced\", value: \"sonnet\" },\n { name: \"opus — best\", value: \"opus\" },\n ],\n });\n log.blank();\n }\n\n // Verify Claude CLI is available\n const claudeAvailable = await checkClaudeCli();\n if (!claudeAvailable) {\n log.error(\"Claude CLI not found. Install it: https://docs.anthropic.com/en/docs/claude-code\");\n log.info(\"The eval command runs Claude headless against scenarios — it requires the CLI.\");\n process.exit(1);\n }\n\n // Load scenarios\n log.step(\"Loading eval scenarios...\");\n const scenarios = await loadScenarios({\n suite: opts.suite,\n customPath: opts.scenarios,\n });\n\n if (scenarios.length === 0) {\n log.warn(\"No matching scenarios found.\");\n if (opts.suite) {\n log.info(`Check that the suite \"${opts.suite}\" exists in the scenarios directory.`);\n }\n return;\n }\n\n log.success(`Loaded ${scenarios.length} scenario(s)`);\n if (opts.model) {\n log.info(`Model: ${opts.model}`);\n }\n log.blank();\n\n const runs = parseInt(opts.runs, 10);\n const timeout = parseInt(opts.timeout, 10);\n\n // Run scenarios\n const results: EvalRunResult[] = [];\n\n for (const scenario of scenarios) {\n const spinner = ora({\n text: `Running: ${scenario.name} (${runs} run${runs > 1 ? \"s\" : \"\"})`,\n prefixText: \" \",\n }).start();\n\n try {\n const result = await runScenarioWithRetries(\n { ...scenario, runs },\n { projectRoot: opts.path, timeout, debug: opts.debug, model: opts.model },\n );\n results.push(result);\n\n if (result.passed) {\n spinner.succeed(`${scenario.name} ${result.score}/${result.maxScore}`);\n } else {\n spinner.fail(`${scenario.name} ${result.score}/${result.maxScore}`);\n }\n } catch (error: unknown) {\n spinner.fail(`${scenario.name} ERROR`);\n const msg = error instanceof Error ? error.message : String(error);\n log.error(` ${msg}`);\n results.push({\n scenario: scenario.name,\n score: 0,\n maxScore: scenario.checks.reduce((s, c) => s + c.points, 0),\n passed: false,\n checks: scenario.checks.map((c) => ({ label: c.label, passed: false, points: c.points })),\n });\n }\n }\n\n log.blank();\n\n if (opts.json) {\n const overallScore = results.reduce((s, r) => s + r.score, 0);\n const overallMax = results.reduce((s, r) => s + r.maxScore, 0);\n console.log(JSON.stringify({\n results,\n overallScore,\n overallMax,\n passed: overallScore >= overallMax * 0.8,\n timestamp: new Date().toISOString(),\n }, null, 2));\n return;\n }\n\n renderEvalReport(results);\n\n // Save report to .claude/eval/\n await saveEvalReport(results, opts.path, opts.suite, opts.model);\n });\n}\n\nfunction renderEvalReport(results: ReadonlyArray<EvalRunResult>): void {\n for (const result of results) {\n const icon = result.passed ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const status = result.passed ? chalk.green(\"PASS\") : chalk.red(\"FAIL\");\n const score = `${result.score}/${result.maxScore}`;\n\n console.log(` ${icon} ${chalk.bold(result.scenario)} ${score} ${status}`);\n\n const failedChecks = result.checks.filter((c) => !c.passed);\n for (const check of failedChecks) {\n console.log(` ${chalk.red(\"✗\")} ${chalk.dim(check.label)}`);\n }\n }\n\n log.blank();\n\n const totalScore = results.reduce((s, r) => s + r.score, 0);\n const totalMax = results.reduce((s, r) => s + r.maxScore, 0);\n const pct = totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0;\n\n printScoreCard(\"Config Eval Score\", pct);\n log.blank();\n\n const passed = results.filter((r) => r.passed).length;\n const failed = results.length - passed;\n\n if (failed === 0) {\n log.success(`All ${passed} scenario(s) passed.`);\n } else {\n log.warn(`${passed} passed, ${failed} failed out of ${results.length} scenario(s).`);\n }\n}\n\nasync function saveEvalReport(\n results: ReadonlyArray<EvalRunResult>,\n projectRoot: string,\n suite?: string,\n model?: string,\n): Promise<void> {\n const totalScore = results.reduce((s, r) => s + r.score, 0);\n const totalMax = results.reduce((s, r) => s + r.maxScore, 0);\n const pct = totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0;\n const passed = results.filter((r) => r.passed).length;\n const failed = results.length - passed;\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\").slice(0, 19);\n\n const lines: string[] = [\n `# Eval Report — ${timestamp}`,\n \"\",\n `**Score: ${pct}%** (${passed} passed, ${failed} failed out of ${results.length} scenarios)`,\n \"\",\n `- Suite: ${suite ?? \"all\"}`,\n `- Model: ${model ?? \"default\"}`,\n `- Date: ${new Date().toISOString().split(\"T\")[0]}`,\n \"\",\n \"## Results\",\n \"\",\n ];\n\n for (const result of results) {\n const status = result.passed ? \"PASS\" : \"FAIL\";\n lines.push(`### ${result.scenario} — ${result.score}/${result.maxScore} ${status}`);\n\n const failedChecks = result.checks.filter((c) => !c.passed);\n const passedChecks = result.checks.filter((c) => c.passed);\n\n for (const check of passedChecks) {\n lines.push(`- PASSED: ${check.label} (${check.points} pts)`);\n }\n for (const check of failedChecks) {\n lines.push(`- FAILED: ${check.label} (${check.points} pts)`);\n }\n lines.push(\"\");\n }\n\n if (failed > 0) {\n lines.push(\"## Recommendations\");\n lines.push(\"\");\n for (const result of results.filter((r) => !r.passed)) {\n lines.push(`### Fix: ${result.scenario}`);\n const failedChecks = result.checks.filter((c) => !c.passed);\n for (const check of failedChecks) {\n lines.push(`- ${check.label} — update CLAUDE.md instructions or add hooks to enforce this behavior`);\n }\n lines.push(\"\");\n }\n }\n\n const evalDir = join(projectRoot, \".claude\", \"eval\");\n await mkdir(evalDir, { recursive: true });\n const filename = `eval-${suite ?? \"all\"}-${timestamp}.md`;\n await writeFile(join(evalDir, filename), lines.join(\"\\n\"));\n log.success(`Report saved to .claude/eval/${filename}`);\n}\n\nasync function checkClaudeCli(): Promise<boolean> {\n const { execFile } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const exec = promisify(execFile);\n\n try {\n await exec(\"claude\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile, readdir, access } from \"node:fs/promises\";\nimport { join, resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parse as parseYaml } from \"yaml\";\nimport { validateScenario } from \"./schema.js\";\nimport type { EvalScenario } from \"../../types/index.js\";\n\n/**\n * Find the scenarios directory. Works both in dev (tsx) and bundled (tsup).\n * - Dev: __dirname is src/commands/eval/, scenarios is at ../../../scenarios/\n * - Bundled: __dirname is dist/, scenarios is at ../scenarios/\n * - npm installed: __dirname is node_modules/claude-launchpad/dist/, scenarios is at ../scenarios/\n */\nasync function findScenariosDir(): Promise<string> {\n const thisDir = dirname(fileURLToPath(import.meta.url));\n\n // Try relative to this file (dev mode: src/commands/eval/ → ../../../scenarios/)\n const devPath = resolve(thisDir, \"../../../scenarios\");\n if (await dirExists(devPath)) return devPath;\n\n // Try relative to dist/ (bundled: dist/ → ../scenarios/)\n const bundledPath = resolve(thisDir, \"../scenarios\");\n if (await dirExists(bundledPath)) return bundledPath;\n\n // Try relative to package root (fallback)\n const rootPath = resolve(thisDir, \"../../scenarios\");\n if (await dirExists(rootPath)) return rootPath;\n\n return devPath; // Fall through — will just find 0 scenarios\n}\n\nasync function dirExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Load eval scenarios from a directory. Supports:\n * - Built-in scenarios (shipped in scenarios/)\n * - Custom scenarios from a user-specified path\n */\nexport async function loadScenarios(options: {\n suite?: string;\n customPath?: string;\n}): Promise<ReadonlyArray<EvalScenario>> {\n const { suite, customPath } = options;\n\n const scenarioDir = customPath\n ? resolve(customPath)\n : await findScenariosDir();\n\n const dirs = suite\n ? [join(scenarioDir, suite)]\n : await getSubdirectories(scenarioDir);\n\n // Also check the root dir for flat YAML files\n const allDirs = [scenarioDir, ...dirs];\n\n const scenarios: EvalScenario[] = [];\n\n for (const dir of allDirs) {\n const files = await listYamlFiles(dir);\n for (const file of files) {\n try {\n const content = await readFile(file, \"utf-8\");\n const raw = parseYaml(content);\n const scenario = validateScenario(raw, file);\n scenarios.push(scenario);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.warn(` Warning: Skipping ${file}: ${msg}`);\n }\n }\n }\n\n return scenarios;\n}\n\nasync function getSubdirectories(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n\nasync function listYamlFiles(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isFile() && (e.name.endsWith(\".yaml\") || e.name.endsWith(\".yml\")))\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n","import type { EvalScenario, EvalCheck } from \"../../types/index.js\";\n\n/**\n * Validates a raw parsed YAML object against the EvalScenario schema.\n * Returns a validated scenario or throws with a descriptive error.\n */\nexport function validateScenario(raw: unknown, filePath: string): EvalScenario {\n if (!raw || typeof raw !== \"object\") {\n throw new ScenarioError(filePath, \"Scenario must be a YAML object\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n const name = requireString(obj, \"name\", filePath);\n const description = requireString(obj, \"description\", filePath);\n const prompt = requireString(obj, \"prompt\", filePath);\n const setup = validateSetup(obj.setup, filePath);\n const checks = validateChecks(obj.checks, filePath);\n const passingScore = requireNumber(obj, \"passingScore\", filePath);\n const runs = optionalNumber(obj, \"runs\") ?? 3;\n\n return { name, description, setup, prompt, checks, passingScore, runs };\n}\n\n// ─── Field Validators ───\n\nfunction validateSetup(\n raw: unknown,\n filePath: string,\n): EvalScenario[\"setup\"] {\n if (!raw || typeof raw !== \"object\") {\n throw new ScenarioError(filePath, '\"setup\" must be an object with a \"files\" array');\n }\n\n const obj = raw as Record<string, unknown>;\n const files = obj.files;\n\n if (!Array.isArray(files)) {\n throw new ScenarioError(filePath, '\"setup.files\" must be an array');\n }\n\n const validatedFiles = files.map((f, i) => {\n if (!f || typeof f !== \"object\") {\n throw new ScenarioError(filePath, `setup.files[${i}] must be an object`);\n }\n const file = f as Record<string, unknown>;\n if (typeof file.path !== \"string\" || typeof file.content !== \"string\") {\n throw new ScenarioError(filePath, `setup.files[${i}] must have \"path\" and \"content\" strings`);\n }\n return { path: file.path, content: file.content };\n });\n\n const instructions = typeof obj.instructions === \"string\" ? obj.instructions : undefined;\n\n return { files: validatedFiles, instructions };\n}\n\nfunction validateChecks(raw: unknown, filePath: string): ReadonlyArray<EvalCheck> {\n if (!Array.isArray(raw) || raw.length === 0) {\n throw new ScenarioError(filePath, '\"checks\" must be a non-empty array');\n }\n\n return raw.map((c, i) => {\n if (!c || typeof c !== \"object\") {\n throw new ScenarioError(filePath, `checks[${i}] must be an object`);\n }\n const check = c as Record<string, unknown>;\n\n const validTypes = [\"grep\", \"file-exists\", \"file-absent\", \"max-lines\", \"custom\"];\n if (!validTypes.includes(check.type as string)) {\n throw new ScenarioError(filePath, `checks[${i}].type must be one of: ${validTypes.join(\", \")}`);\n }\n\n if (typeof check.target !== \"string\") {\n throw new ScenarioError(filePath, `checks[${i}].target must be a string`);\n }\n\n const validExpect = [\"present\", \"absent\"];\n if (!validExpect.includes(check.expect as string)) {\n throw new ScenarioError(filePath, `checks[${i}].expect must be \"present\" or \"absent\"`);\n }\n\n if (typeof check.points !== \"number\" || check.points < 0) {\n throw new ScenarioError(filePath, `checks[${i}].points must be a non-negative number`);\n }\n\n if (typeof check.label !== \"string\") {\n throw new ScenarioError(filePath, `checks[${i}].label must be a string`);\n }\n\n return {\n type: check.type as EvalCheck[\"type\"],\n pattern: typeof check.pattern === \"string\" ? check.pattern : undefined,\n target: check.target,\n expect: check.expect as EvalCheck[\"expect\"],\n points: check.points,\n label: check.label,\n };\n });\n}\n\n// ─── Helpers ───\n\nfunction requireString(obj: Record<string, unknown>, key: string, filePath: string): string {\n if (typeof obj[key] !== \"string\" || obj[key] === \"\") {\n throw new ScenarioError(filePath, `\"${key}\" must be a non-empty string`);\n }\n return obj[key] as string;\n}\n\nfunction requireNumber(obj: Record<string, unknown>, key: string, filePath: string): number {\n if (typeof obj[key] !== \"number\") {\n throw new ScenarioError(filePath, `\"${key}\" must be a number`);\n }\n return obj[key] as number;\n}\n\nfunction optionalNumber(obj: Record<string, unknown>, key: string): number | undefined {\n if (obj[key] === undefined) return undefined;\n if (typeof obj[key] !== \"number\") return undefined;\n return obj[key] as number;\n}\n\nclass ScenarioError extends Error {\n constructor(filePath: string, message: string) {\n super(`Invalid scenario ${filePath}: ${message}`);\n this.name = \"ScenarioError\";\n }\n}\n","import { mkdir, writeFile, readFile, readdir, rm, cp } 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\";\nimport { fileExists } from \"../../lib/fs-utils.js\";\n\nconst exec = promisify(execFile);\n\ninterface RunOptions {\n readonly projectRoot: string;\n readonly timeout: number;\n readonly debug?: boolean;\n readonly model?: string;\n}\n\n/**\n * Execute a single eval scenario run using the Agent SDK.\n *\n * 1. Create a temp directory with the scenario's seed files\n * 2. Write a minimal CLAUDE.md with the scenario's instructions\n * 3. Run Claude via Agent SDK with explicit tool permissions\n * 4. Check the results against the scenario's checks\n * 5. Clean up\n */\nexport async function runScenario(\n scenario: EvalScenario,\n options: RunOptions,\n): Promise<EvalRunResult> {\n const sandboxDir = join(tmpdir(), `claude-eval-${randomUUID()}`);\n\n try {\n await setupSandbox(sandboxDir, scenario, options.projectRoot);\n await runClaudeInSandbox(sandboxDir, scenario.prompt, options.timeout, options.model);\n return await scoreResults(scenario, sandboxDir);\n } finally {\n if (options.debug) {\n console.log(` DEBUG: Sandbox preserved at ${sandboxDir}`);\n } else {\n await rm(sandboxDir, { recursive: true, force: true }).catch(() => {});\n }\n }\n}\n\n/**\n * Run a scenario multiple times and return the median result.\n */\nexport async function runScenarioWithRetries(\n scenario: EvalScenario,\n options: RunOptions,\n): Promise<EvalRunResult> {\n const results: EvalRunResult[] = [];\n\n for (let i = 0; i < scenario.runs; i++) {\n const result = await runScenario(scenario, options);\n results.push(result);\n }\n\n const sorted = [...results].sort((a, b) => a.score - b.score);\n return sorted[Math.floor(sorted.length / 2)];\n}\n\n// ─── Sandbox Setup ───\n\nasync function setupSandbox(\n sandboxDir: string,\n scenario: EvalScenario,\n projectRoot: string,\n): Promise<void> {\n await mkdir(sandboxDir, { recursive: true });\n\n // Write scenario seed files\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 // Copy user's full config surface into sandbox\n await copyProjectConfig(sandboxDir, projectRoot);\n\n // Write scenario CLAUDE.md (after config copy so it takes precedence)\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/**\n * Copy the user's .claude/ config (settings, rules, hooks) and .claudeignore\n * into the sandbox so eval tests the full configuration surface.\n */\nasync function copyProjectConfig(sandboxDir: string, projectRoot: string): Promise<void> {\n const claudeDir = join(projectRoot, \".claude\");\n const sandboxClaudeDir = join(sandboxDir, \".claude\");\n\n // Copy .claude/settings.json (hooks, permissions, schema)\n const settingsPath = join(claudeDir, \"settings.json\");\n if (await fileExists(settingsPath)) {\n await mkdir(sandboxClaudeDir, { recursive: true });\n await cp(settingsPath, join(sandboxClaudeDir, \"settings.json\"));\n }\n\n // Copy .claude/rules/ (all convention and path-scoped rule files)\n const rulesDir = join(claudeDir, \"rules\");\n if (await fileExists(rulesDir)) {\n await cp(rulesDir, join(sandboxClaudeDir, \"rules\"), { recursive: true });\n }\n\n // Copy .claudeignore\n const ignorePath = join(projectRoot, \".claudeignore\");\n if (await fileExists(ignorePath)) {\n await cp(ignorePath, join(sandboxDir, \".claudeignore\"));\n }\n}\n\n// ─── Claude Execution ───\n\nasync function runClaudeInSandbox(\n cwd: string,\n prompt: string,\n timeout: number,\n model?: string,\n): Promise<void> {\n // Try Agent SDK first, fall back to CLI subprocess\n try {\n const sdk = await import(\"@anthropic-ai/claude-agent-sdk\");\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n for await (const _message of sdk.query({\n prompt,\n options: {\n cwd,\n allowedTools: [\"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\"],\n permissionMode: \"dontAsk\",\n settingSources: [],\n maxTurns: 20,\n abortController: controller,\n ...(model ? { model } : {}),\n },\n })) {\n // Consume the stream — we only care about side effects (file edits)\n }\n } finally {\n clearTimeout(timeoutId);\n }\n } catch {\n // SDK not available or failed — fall back to CLI\n await runClaudeCli(cwd, prompt, timeout, model);\n }\n}\n\nasync function runClaudeCli(\n cwd: string,\n prompt: string,\n timeout: number,\n model?: string,\n): Promise<void> {\n try {\n const args = [\n \"-p\", prompt,\n \"--output-format\", \"text\",\n \"--max-turns\", \"20\",\n \"--dangerously-skip-permissions\",\n \"--allowedTools\", \"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\",\n ];\n if (model) args.push(\"--model\", model);\n await exec(\"claude\", args, { cwd, timeout, maxBuffer: 10 * 1024 * 1024 });\n } catch (error: unknown) {\n // Claude might exit non-zero but still produce usable output\n if (error && typeof error === \"object\" && \"stdout\" in error) {\n return; // Files may have been modified despite exit code\n }\n throw error;\n }\n}\n\n// ─── Scoring ───\n\nasync function scoreResults(\n scenario: EvalScenario,\n sandboxDir: string,\n): Promise<EvalRunResult> {\n const checkResults = await evaluateChecks(scenario.checks, sandboxDir);\n\n const score = checkResults\n .filter((c) => c.passed)\n .reduce((sum, c) => sum + c.points, 0);\n\n const maxScore = scenario.checks.reduce((sum, c) => sum + c.points, 0);\n\n return {\n scenario: scenario.name,\n score,\n maxScore,\n passed: score >= scenario.passingScore,\n checks: checkResults,\n };\n}\n\nasync function evaluateChecks(\n checks: ReadonlyArray<EvalCheck>,\n sandboxDir: string,\n): Promise<ReadonlyArray<{ label: string; passed: boolean; points: number }>> {\n const results: { label: string; passed: boolean; points: number }[] = [];\n\n for (const check of checks) {\n const passed = await evaluateSingleCheck(check, sandboxDir);\n results.push({ label: check.label, passed, points: check.points });\n }\n\n return results;\n}\n\nasync function evaluateSingleCheck(check: EvalCheck, sandboxDir: string): Promise<boolean> {\n switch (check.type) {\n case \"grep\":\n return checkGrep(check, sandboxDir);\n case \"file-exists\":\n case \"file-absent\":\n return checkFilePresence(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 checkFilePresence(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 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 { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { Command } from \"commander\";\nimport { confirm } from \"@inquirer/prompts\";\nimport { log } from \"../../lib/output.js\";\n\nasync function handleSyncErrors(fn: () => Promise<void>): Promise<void> {\n try {\n await fn();\n } catch (err) {\n log.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\n/**\n * Memory is \"installed\" when BOTH:\n * (1) the SessionStart context hook is present in project settings\n * (2) the agentic-memory MCP server is registered in project (.mcp.json),\n * local (settings.local.json), or user scope (~/.claude.json)\n * Missing either half means the setup is half-broken (hooks fire but no tools, or tools present but no context injection).\n */\nexport function isMemoryInstalled(): boolean {\n const cwd = process.cwd();\n const hookPresent = hasMemoryHook(join(cwd, \".claude\", \"settings.json\"))\n || hasMemoryHook(join(cwd, \".claude\", \"settings.local.json\"));\n if (!hookPresent) return false;\n return isMemoryMcpRegistered(cwd);\n}\n\nexport function isMemoryMcpRegistered(projectRoot: string): boolean {\n return hasMemoryServerInJson(join(projectRoot, \".mcp.json\"), \"mcpServers\")\n || hasMemoryServerInJson(join(projectRoot, \".claude\", \"settings.local.json\"), \"mcpServers\")\n || hasMemoryServerInUserConfig(projectRoot);\n}\n\nfunction hasMemoryServerInJson(path: string, key: string): boolean {\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf-8\")) as Record<string, unknown>;\n const servers = parsed[key] as Record<string, unknown> | undefined;\n return !!servers && typeof servers === \"object\" && \"agentic-memory\" in servers;\n } catch {\n return false;\n }\n}\n\nfunction hasMemoryServerInUserConfig(projectRoot: string): boolean {\n try {\n const parsed = JSON.parse(readFileSync(join(homedir(), \".claude.json\"), \"utf-8\")) as Record<string, unknown>;\n // User-scope registration lives under projects[projectRoot].mcpServers\n const projects = parsed.projects as Record<string, unknown> | undefined;\n const project = projects?.[projectRoot] as Record<string, unknown> | undefined;\n const scoped = project?.mcpServers as Record<string, unknown> | undefined;\n if (scoped && \"agentic-memory\" in scoped) return true;\n // Global user scope (~/.claude.json top-level mcpServers, if Claude Code ever uses it)\n const global = parsed.mcpServers as Record<string, unknown> | undefined;\n return !!global && \"agentic-memory\" in global;\n } catch {\n return false;\n }\n}\n\nfunction hasMemoryHook(path: string): boolean {\n try {\n const settings = JSON.parse(readFileSync(path, \"utf-8\")) as Record<string, unknown>;\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks) return false;\n const sessionStart = hooks.SessionStart as Record<string, unknown>[] | undefined;\n return sessionStart?.some((h) => {\n const inner = h.hooks as Record<string, unknown>[] | undefined;\n return inner?.some((ih) => String(ih.command ?? \"\").includes(\"memory context\"));\n }) ?? false;\n } catch {\n return false;\n }\n}\n\nexport function createMemoryCommand(): Command {\n const memory = new Command(\"memory\")\n .description(\"Project-scoped memory with decay, sync, and a TUI dashboard\")\n .option(\"--dashboard\", \"Open the memory dashboard\")\n .action(async (opts) => {\n if (opts.dashboard) {\n if (!isMemoryInstalled()) {\n log.error(\"Knowledge base not set up yet. Run `claude-launchpad memory` first.\");\n return;\n }\n const { requireMemoryDeps } = await import(\"./utils/require-deps.js\");\n await requireMemoryDeps();\n const { startTui } = await import(\"./dashboard/tui.js\");\n await startTui();\n return;\n }\n\n // Smart default: install or show stats\n if (!isMemoryInstalled()) {\n // Check if config was already written (e.g. by doctor --fix) even though db isn't set up\n const { detectExistingSetup } = await import(\"./subcommands/install.js\");\n const existing = detectExistingSetup(process.cwd());\n const mcpMissing = existing !== null && !isMemoryMcpRegistered(process.cwd());\n if (existing) {\n const location = existing === \"local\"\n ? \".claude/CLAUDE.md + settings.local.json\"\n : \"CLAUDE.md + settings.json\";\n log.blank();\n log.success(`Memory config found (${location}) but ${mcpMissing ? \"MCP server not registered\" : \"database not set up\"}.`);\n log.info(\"Run `claude-launchpad memory install` to complete setup.\");\n log.blank();\n } else {\n log.blank();\n log.step(\"Claude doesn't have a knowledge base for this project yet.\");\n log.blank();\n log.info(\"After setup, Claude will:\");\n log.info(\" - Remember decisions, gotchas, and learnings across sessions\");\n log.info(\" - Automatically recall relevant context when you start a session\");\n log.info(\" - Save important facts as you work, so nothing gets lost\");\n log.blank();\n }\n\n const proceed = await confirm({\n message: \"Set up knowledge base?\",\n default: true,\n });\n\n if (!proceed) {\n log.info(\"Skipped.\");\n return;\n }\n\n const { runInstall } = await import(\"./subcommands/install.js\");\n await runInstall({});\n } else {\n const { requireMemoryDeps } = await import(\"./utils/require-deps.js\");\n await requireMemoryDeps();\n const { runStats } = await import(\"./subcommands/stats.js\");\n await runStats({});\n }\n });\n\n // Explicit install subcommand — always re-runs the flow.\n // Use when `memory` detects a half-broken state (hook OK, MCP missing, etc.) or after a purge.\n memory.addCommand(\n new Command(\"install\")\n .description(\"Install (or re-install) the knowledge base for this project\")\n .option(\"--db-path <path>\", \"Override the default data directory\")\n .action(async (opts) => {\n const { runInstall } = await import(\"./subcommands/install.js\");\n await runInstall(opts.dbPath ? { dbPath: opts.dbPath } : {});\n }),\n );\n\n // Hidden internal commands (used by hooks and MCP, not user-facing)\n memory.addCommand(\n new Command(\"context\")\n .description(\"Load session context (hook handler)\")\n .option(\"--json\", \"JSON output\")\n .action(async (opts) => {\n const { runContext } = await import(\"./subcommands/context.js\");\n await runContext(opts);\n })\n .helpCommand(false),\n { hidden: true },\n );\n\n memory.addCommand(\n new Command(\"serve\")\n .description(\"Start MCP server (Claude Code)\")\n .action(async () => {\n const { startServer } = await import(\"./server.js\");\n await startServer();\n })\n .helpCommand(false),\n { hidden: true },\n );\n\n // User-facing sync commands\n memory.addCommand(\n new Command(\"push\")\n .description(\"Push current project's memories to GitHub Gist\")\n .option(\"--all\", \"Push all projects\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (opts) => {\n await handleSyncErrors(async () => {\n const { runPush } = await import(\"./subcommands/push.js\");\n await runPush(opts);\n });\n }),\n );\n\n memory.addCommand(\n new Command(\"pull\")\n .description(\"Pull current project's memories from GitHub Gist\")\n .option(\"--all\", \"Pull all projects\")\n .option(\"-y, --yes\", \"Non-interactive (accepted for symmetry with push; pull never prompts)\")\n .action(async (opts) => {\n await handleSyncErrors(async () => {\n const { runPull } = await import(\"./subcommands/pull.js\");\n await runPull(opts);\n });\n }),\n );\n\n // Sync management commands\n const sync = new Command(\"sync\")\n .description(\"Manage memory sync\");\n\n sync.addCommand(\n new Command(\"status\")\n .description(\"Show local vs remote memory counts per project\")\n .action(async () => {\n await handleSyncErrors(async () => {\n const { runSyncStatus } = await import(\"./subcommands/sync-status.js\");\n await runSyncStatus();\n });\n }),\n );\n\n sync.addCommand(\n new Command(\"clean\")\n .description(\"Remove a project from the sync gist\")\n .argument(\"<project>\", \"Project slug to remove\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (project: string, opts) => {\n await handleSyncErrors(async () => {\n const { runSyncClean } = await import(\"./subcommands/sync-clean.js\");\n await runSyncClean(project, opts);\n });\n }),\n );\n\n memory.addCommand(sync);\n\n return memory;\n}\n"],"mappings":"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","names":["Command","join","Command","join","join","readFile","join","homedir","join","homedir","readFile","access","readFile","resolve","readdir","join","join","readdir","Command","overallScore","Command","select","chalk","mkdir","writeFile","join","readFile","readdir","access","join","resolve","dirname","dirname","resolve","access","join","readFile","readdir","mkdir","writeFile","readFile","readdir","join","dirname","join","mkdir","dirname","writeFile","readFile","readdir","Command","select","chalk","join","mkdir","writeFile","execFile","promisify","exec","join","homedir","Command","confirm","join","homedir","Command","confirm","Command","join"]}