codebase-ai 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/output.ts","../src/utils/glob.ts","../src/scanner/context.ts","../src/detectors/project.ts","../src/detectors/repo.ts","../src/detectors/structure.ts","../src/detectors/stack.ts","../src/detectors/commands.ts","../src/detectors/dependencies.ts","../src/detectors/config.ts","../src/detectors/git.ts","../src/detectors/quality.ts","../src/detectors/patterns.ts","../src/detectors/api-docs.ts","../src/detectors/index.ts","../src/utils/safe.ts","../src/github/graphql.ts","../src/github/sync.ts","../src/scanner/cache.ts","../src/scanner/engine.ts","../src/commands/scan.ts","../src/integrations/shared.ts","../src/integrations/claude.ts","../src/integrations/gitignore.ts","../src/integrations/githook.ts","../src/commands/setup.ts","../src/utils/help.ts","../src/utils/args.ts","../src/index.ts","../src/utils/update-check.ts","../src/commands/init.ts","../src/integrations/index.ts","../src/commands/brief.ts","../src/mcp/brief.ts","../src/commands/next.ts","../src/commands/query.ts","../src/utils/json-path.ts","../src/commands/issue.ts","../src/github/issues.ts","../src/commands/status.ts","../src/commands/mcp.ts","../src/mcp/server.ts","../src/commands/doctor.ts","../src/commands/fix.ts","../src/commands/release.ts","../src/commands/plan.ts","../src/commands/skills.ts","../src/server/index.ts","../src/server/routes.ts"],"sourcesContent":["const NO_COLOR = !!process.env.NO_COLOR;\n\nconst colors = {\n reset: NO_COLOR ? \"\" : \"\\x1b[0m\",\n green: NO_COLOR ? \"\" : \"\\x1b[32m\",\n red: NO_COLOR ? \"\" : \"\\x1b[31m\",\n yellow: NO_COLOR ? \"\" : \"\\x1b[33m\",\n cyan: NO_COLOR ? \"\" : \"\\x1b[36m\",\n blue: NO_COLOR ? \"\" : \"\\x1b[34m\",\n magenta: NO_COLOR ? \"\" : \"\\x1b[35m\",\n dim: NO_COLOR ? \"\" : \"\\x1b[2m\",\n bold: NO_COLOR ? \"\" : \"\\x1b[1m\",\n};\n\nlet isQuiet = false;\nlet isVerbose = false;\n\nexport function setQuiet(quiet: boolean): void {\n isQuiet = quiet;\n}\n\nexport function setVerbose(verbose: boolean): void {\n isVerbose = verbose;\n}\n\nexport function log(msg: string): void {\n if (!isQuiet) {\n console.log(msg);\n }\n}\n\nexport function success(msg: string): void {\n if (!isQuiet) {\n console.log(` ${colors.green}[✓]${colors.reset} ${msg}`);\n }\n}\n\nexport function error(msg: string): void {\n console.error(` ${colors.red}[✗]${colors.reset} ${msg}`);\n}\n\nexport function errorWithSuggestion(msg: string, suggestion: string): void {\n console.error(`\\n ${colors.red}[✗]${colors.reset} ${msg}`);\n console.error(` ${colors.cyan}→${colors.reset} ${suggestion}\\n`);\n}\n\nexport function warn(msg: string): void {\n if (!isQuiet) {\n console.log(` ${colors.yellow}[!]${colors.reset} ${msg}`);\n }\n}\n\nexport function info(msg: string): void {\n if (!isQuiet) {\n console.log(` ${colors.cyan}[i]${colors.reset} ${msg}`);\n }\n}\n\nexport function verbose(msg: string): void {\n if (isVerbose && !isQuiet) {\n console.log(` ${colors.dim}[verbose]${colors.reset} ${msg}`);\n }\n}\n\nexport function dim(msg: string): void {\n if (!isQuiet) {\n console.log(`${colors.dim}${msg}${colors.reset}`);\n }\n}\n\nexport function bold(msg: string): string {\n return `${colors.bold}${msg}${colors.reset}`;\n}\n\nexport function heading(msg: string): void {\n if (!isQuiet) {\n console.log(`\\n${colors.bold}${msg}${colors.reset}`);\n }\n}\n\nexport function link(text: string, url: string): string {\n if (process.stdout.isTTY && !NO_COLOR) {\n // ANSI hyperlinks\n return `\\x1b]8;;${url}\\x1b\\\\${text}\\x1b]8;;\\x1b\\\\`;\n }\n return `${text} (${url})`;\n}\n\nexport function code(text: string): string {\n return `${colors.dim}${text}${colors.reset}`;\n}\n\nexport function command(cmd: string): string {\n return `${colors.cyan}${cmd}${colors.reset}`;\n}\n\n// Progress indicator for long operations\nexport class Progress {\n private current = 0;\n private total: number;\n private label: string;\n private interval?: ReturnType<typeof setInterval>;\n\n constructor(label: string, total: number) {\n this.label = label;\n this.total = total;\n }\n\n start(): void {\n if (isQuiet) {\n return;\n }\n this.render();\n this.interval = setInterval(() => this.tick(), 100);\n }\n\n tick(): void {\n if (isQuiet) {\n return;\n }\n this.current = Math.min(this.current + 1, this.total);\n this.render();\n }\n\n increment(amount: number): void {\n if (isQuiet) {\n return;\n }\n this.current = Math.min(this.current + amount, this.total);\n this.render();\n }\n\n complete(): void {\n if (this.interval) {\n clearInterval(this.interval);\n }\n if (!isQuiet) {\n this.current = this.total;\n this.render();\n console.log();\n }\n }\n\n private render(): void {\n const percent = Math.round((this.current / this.total) * 100);\n const filled = Math.round(20 * (this.current / this.total));\n const bar = \"█\".repeat(filled) + \"░\".repeat(20 - filled);\n process.stdout.write(`\\r ${colors.cyan}[${bar}]${colors.reset} ${percent}% ${this.label}`);\n }\n}\n","/**\n * Minimal glob matcher — zero dependencies.\n * Supports: * (any chars except /), ** (any chars including /), ? (single char)\n */\nexport function globMatch(pattern: string, filepath: string): boolean {\n const regex = globToRegex(pattern);\n return regex.test(filepath);\n}\n\nexport function globFilter(files: string[], pattern: string): string[] {\n const regex = globToRegex(pattern);\n return files.filter((f) => regex.test(f));\n}\n\nfunction globToRegex(pattern: string): RegExp {\n let result = \"^\";\n let i = 0;\n\n while (i < pattern.length) {\n const char = pattern[i];\n\n if (char === \"*\") {\n if (pattern[i + 1] === \"*\") {\n // ** matches everything including /\n if (pattern[i + 2] === \"/\") {\n result += \"(?:.*/)?\";\n i += 3;\n } else {\n result += \".*\";\n i += 2;\n }\n } else {\n // * matches everything except /\n result += \"[^/]*\";\n i++;\n }\n } else if (char === \"?\") {\n result += \"[^/]\";\n i++;\n } else if (char === \"{\") {\n // {a,b,c} alternation\n const close = pattern.indexOf(\"}\", i);\n if (close !== -1) {\n const alternatives = pattern.slice(i + 1, close).split(\",\");\n result += \"(?:\" + alternatives.map(escapeRegex).join(\"|\") + \")\";\n i = close + 1;\n } else {\n result += escapeRegex(char);\n i++;\n }\n } else {\n result += escapeRegex(char);\n i++;\n }\n }\n\n result += \"$\";\n return new RegExp(result);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { readdir, readFile as fsReadFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport type { ScanContext } from \"../types.js\";\nimport { globFilter } from \"../utils/glob.js\";\n\nconst DEFAULT_IGNORE = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \".next\",\n \".nuxt\",\n \".output\",\n \"__pycache__\",\n \"vendor\",\n \".venv\",\n \"venv\",\n \"target\",\n \"coverage\",\n \".cache\",\n \".turbo\",\n \".vercel\",\n \".netlify\",\n \".parcel-cache\",\n \".svelte-kit\",\n \".angular\",\n \"out\",\n \"bin\",\n \"obj\",\n]);\n\nexport interface ContextOptions {\n depth?: number;\n ignore?: string[];\n}\n\nexport async function createScanContext(\n root: string,\n options: ContextOptions = {}\n): Promise<ScanContext> {\n const ignoreSet = new Set([...DEFAULT_IGNORE, ...(options.ignore ?? [])]);\n const files = await walkDirectory(root, root, ignoreSet, options.depth ?? 10);\n const fileSet = new Set(files);\n\n return {\n root,\n files,\n\n async readFile(path: string): Promise<string> {\n try {\n return await fsReadFile(join(root, path), \"utf-8\");\n } catch {\n return \"\";\n }\n },\n\n fileExists(path: string): boolean {\n // Fast O(1) check against walked files first\n if (fileSet.has(path)) {\n return true;\n }\n // Fallback: actual filesystem check (for files in ignored dirs or outside walk depth)\n return existsSync(join(root, path));\n },\n\n glob(pattern: string): string[] {\n return globFilter(files, pattern);\n },\n\n exec(cmd: string, args: string[]): Promise<string> {\n return new Promise((resolve) => {\n execFile(cmd, args, { cwd: root, timeout: 10_000 }, (err, stdout) => {\n resolve(err ? \"\" : stdout.trim());\n });\n });\n },\n };\n}\n\nasync function walkDirectory(\n base: string,\n dir: string,\n ignore: Set<string>,\n maxDepth: number,\n currentDepth = 0\n): Promise<string[]> {\n if (currentDepth > maxDepth) {\n return [];\n }\n\n const results: string[] = [];\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (ignore.has(entry.name)) {\n continue;\n }\n if (entry.isDirectory() && entry.name.startsWith(\".\")) {\n // Allow .github, .husky, .circleci — skip other hidden dirs\n const allowedDotDirs = new Set([\".github\", \".husky\", \".circleci\"]);\n if (!allowedDotDirs.has(entry.name)) {\n continue;\n }\n }\n\n const fullPath = join(dir, entry.name);\n const relPath = relative(base, fullPath);\n\n if (entry.isDirectory()) {\n results.push(relPath + \"/\");\n const children = await walkDirectory(base, fullPath, ignore, maxDepth, currentDepth + 1);\n results.push(...children);\n } else {\n results.push(relPath);\n }\n }\n } catch {\n // Permission denied, broken symlink, etc.\n }\n\n return results;\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\n/**\n * Detects project identity — what IS this project?\n * Reads README, package.json description, repo name to build a summary.\n * This is the first thing an AI needs to understand context.\n */\nexport const projectDetector: Detector = {\n name: \"project\",\n category: \"project\",\n\n async detect(ctx: ScanContext) {\n const [name, description, readme] = await Promise.all([\n detectProjectName(ctx),\n detectDescription(ctx),\n extractReadmeSummary(ctx),\n ]);\n\n return {\n name,\n description: description || readme || null,\n };\n },\n};\n\nasync function detectProjectName(ctx: ScanContext): Promise<string> {\n // Try package.json name\n const pkgContent = await ctx.readFile(\"package.json\");\n if (pkgContent) {\n try {\n const pkg = JSON.parse(pkgContent);\n if (pkg.name) {\n return pkg.name;\n }\n } catch {}\n }\n\n // Try Cargo.toml\n const cargoContent = await ctx.readFile(\"Cargo.toml\");\n if (cargoContent) {\n const match = cargoContent.match(/^name\\s*=\\s*\"([^\"]+)\"/m);\n if (match) {\n return match[1];\n }\n }\n\n // Try pyproject.toml\n const pyContent = await ctx.readFile(\"pyproject.toml\");\n if (pyContent) {\n const match = pyContent.match(/^name\\s*=\\s*\"([^\"]+)\"/m);\n if (match) {\n return match[1];\n }\n }\n\n // Try go.mod\n const goContent = await ctx.readFile(\"go.mod\");\n if (goContent) {\n const match = goContent.match(/^module\\s+(\\S+)/m);\n if (match) {\n return match[1].split(\"/\").pop() || match[1];\n }\n }\n\n // Fallback: directory name from git remote\n const remote = await ctx.exec(\"git\", [\"remote\", \"get-url\", \"origin\"]);\n if (remote) {\n const name = remote.replace(/.*[:/]/, \"\").replace(/\\.git$/, \"\");\n return name;\n }\n\n // Last resort: directory name\n return ctx.root.split(\"/\").pop() || \"unknown\";\n}\n\nasync function detectDescription(ctx: ScanContext): Promise<string | null> {\n // Try package.json description\n const pkgContent = await ctx.readFile(\"package.json\");\n if (pkgContent) {\n try {\n const pkg = JSON.parse(pkgContent);\n if (pkg.description) {\n return pkg.description;\n }\n } catch {}\n }\n\n // Try Cargo.toml description\n const cargoContent = await ctx.readFile(\"Cargo.toml\");\n if (cargoContent) {\n const match = cargoContent.match(/^description\\s*=\\s*\"([^\"]+)\"/m);\n if (match) {\n return match[1];\n }\n }\n\n // Try pyproject.toml description\n const pyContent = await ctx.readFile(\"pyproject.toml\");\n if (pyContent) {\n const match = pyContent.match(/^description\\s*=\\s*\"([^\"]+)\"/m);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n\nasync function extractReadmeSummary(ctx: ScanContext): Promise<string | null> {\n // Find README file\n const readmeNames = [\"README.md\", \"readme.md\", \"README\", \"README.txt\", \"README.rst\"];\n let readmeContent = \"\";\n\n for (const name of readmeNames) {\n readmeContent = await ctx.readFile(name);\n if (readmeContent) {\n break;\n }\n }\n\n if (!readmeContent) {\n return null;\n }\n\n // Extract the first meaningful paragraph (skip title, badges, blank lines)\n const lines = readmeContent.split(\"\\n\");\n let foundContent = false;\n const paragraphLines: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip markdown headers\n if (trimmed.startsWith(\"#\")) {\n if (foundContent) {\n break;\n } // Stop at next header after content\n continue;\n }\n\n // Skip badges, images, blank lines before content\n if (\n !trimmed ||\n trimmed.startsWith(\"![\") ||\n trimmed.startsWith(\"[![\") ||\n trimmed.startsWith(\"<\")\n ) {\n if (foundContent) {\n break;\n } // Blank line after content = end of paragraph\n continue;\n }\n\n foundContent = true;\n paragraphLines.push(trimmed);\n }\n\n const summary = paragraphLines.join(\" \").slice(0, 300);\n return summary || null;\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nexport const repoDetector: Detector = {\n name: \"repo\",\n category: \"repo\",\n\n async detect(ctx: ScanContext) {\n const [url, defaultBranch, branches, isMonorepo, workspaceManager] = await Promise.all([\n getRemoteUrl(ctx),\n getDefaultBranch(ctx),\n getActiveBranches(ctx),\n detectMonorepo(ctx),\n detectWorkspaceManager(ctx),\n ]);\n\n return {\n url,\n default_branch: defaultBranch,\n is_monorepo: isMonorepo,\n workspace_manager: isMonorepo ? workspaceManager : null,\n active_branches: branches,\n };\n },\n};\n\nasync function getRemoteUrl(ctx: ScanContext): Promise<string | null> {\n const result = await ctx.exec(\"git\", [\"remote\", \"get-url\", \"origin\"]);\n return result || null;\n}\n\nasync function getDefaultBranch(ctx: ScanContext): Promise<string | null> {\n // Try symbolic ref first\n const branch = await ctx.exec(\"git\", [\"symbolic-ref\", \"refs/remotes/origin/HEAD\"]);\n if (branch) {\n return branch.replace(\"refs/remotes/origin/\", \"\");\n }\n\n // Fallback: check if main or master exists\n const branches = await ctx.exec(\"git\", [\"branch\", \"--list\", \"main\", \"master\"]);\n if (branches.includes(\"main\")) {\n return \"main\";\n }\n if (branches.includes(\"master\")) {\n return \"master\";\n }\n\n // Last resort: current branch\n const current = await ctx.exec(\"git\", [\"branch\", \"--show-current\"]);\n return current || null;\n}\n\nasync function getActiveBranches(ctx: ScanContext): Promise<string[]> {\n const output = await ctx.exec(\"git\", [\n \"branch\",\n \"-a\",\n \"--sort=-committerdate\",\n \"--format=%(refname:short)\",\n ]);\n if (!output) {\n return [];\n }\n\n return output\n .split(\"\\n\")\n .map((b) => b.trim().replace(/^origin\\//, \"\"))\n .filter((b) => b && b !== \"HEAD\")\n .filter((b, i, arr) => arr.indexOf(b) === i) // dedupe\n .slice(0, 10);\n}\n\nasync function detectMonorepo(ctx: ScanContext): Promise<boolean> {\n // Check package.json workspaces\n const pkgContent = await ctx.readFile(\"package.json\");\n if (pkgContent) {\n try {\n const pkg = JSON.parse(pkgContent);\n if (pkg.workspaces) {\n return true;\n }\n } catch {}\n }\n\n // Check for monorepo tools\n return (\n ctx.fileExists(\"pnpm-workspace.yaml\") ||\n ctx.fileExists(\"lerna.json\") ||\n ctx.fileExists(\"turbo.json\") ||\n ctx.fileExists(\"nx.json\") ||\n ctx.fileExists(\"rush.json\")\n );\n}\n\nasync function detectWorkspaceManager(ctx: ScanContext): Promise<string | null> {\n if (ctx.fileExists(\"turbo.json\")) {\n return \"turborepo\";\n }\n if (ctx.fileExists(\"nx.json\")) {\n return \"nx\";\n }\n if (ctx.fileExists(\"lerna.json\")) {\n return \"lerna\";\n }\n if (ctx.fileExists(\"rush.json\")) {\n return \"rush\";\n }\n if (ctx.fileExists(\"pnpm-workspace.yaml\")) {\n return \"pnpm\";\n }\n\n const pkgContent = await ctx.readFile(\"package.json\");\n if (pkgContent) {\n try {\n const pkg = JSON.parse(pkgContent);\n if (pkg.workspaces) {\n return \"npm/yarn\";\n }\n } catch {}\n }\n\n return null;\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Detector, ScanContext } from \"../types.js\";\n\nconst KNOWN_ENTRY_POINTS = [\n \"src/index.ts\",\n \"src/index.js\",\n \"src/main.ts\",\n \"src/main.js\",\n \"src/app.ts\",\n \"src/app.js\",\n \"src/server.ts\",\n \"src/server.js\",\n \"src/app/layout.tsx\",\n \"src/app/page.tsx\",\n \"app/layout.tsx\",\n \"pages/_app.tsx\",\n \"pages/_app.js\",\n \"pages/index.tsx\",\n \"index.ts\",\n \"index.js\",\n \"main.ts\",\n \"main.js\",\n \"app/main.py\",\n \"main.py\",\n \"app.py\",\n \"manage.py\",\n \"main.go\",\n \"cmd/main.go\",\n \"src/main.rs\",\n \"src/lib.rs\",\n \"lib/main.dart\",\n \"Program.cs\",\n];\n\nconst KNOWN_BUILD_OUTPUTS = [\n \"dist\",\n \"build\",\n \".next\",\n \"out\",\n \"target\",\n \"bin\",\n \"obj\",\n \".output\",\n \".nuxt\",\n \".svelte-kit\",\n \".vercel\",\n];\n\nexport const structureDetector: Detector = {\n name: \"structure\",\n category: \"structure\",\n\n async detect(ctx: ScanContext) {\n const entryPoints = KNOWN_ENTRY_POINTS.filter((ep) => ctx.fileExists(ep));\n const buildOutput = KNOWN_BUILD_OUTPUTS.filter((d) => existsSync(join(ctx.root, d)));\n const tree = buildTree(ctx.files, 4);\n\n return {\n entry_points: entryPoints,\n build_output: buildOutput,\n tree,\n };\n },\n};\n\nfunction buildTree(files: string[], _maxDepth: number): Record<string, string[]> {\n const tree: Record<string, Set<string>> = {};\n const topLevelFiles: string[] = [];\n\n for (const file of files) {\n const clean = file.replace(/\\/$/, \"\");\n const parts = clean.split(\"/\");\n\n // Top-level files (no directory)\n if (parts.length === 1 && !file.endsWith(\"/\")) {\n topLevelFiles.push(parts[0]);\n continue;\n }\n\n if (parts.length < 2) {\n continue;\n }\n\n const topDir = parts[0] + \"/\";\n\n // Add second-level entries (files or dirs)\n if (parts.length === 2 && !file.endsWith(\"/\")) {\n // File directly in top-level dir\n if (!tree[topDir]) {\n tree[topDir] = new Set();\n }\n tree[topDir].add(parts[1]);\n } else if (parts.length >= 3) {\n // Subdirectory\n if (!tree[topDir]) {\n tree[topDir] = new Set();\n }\n tree[topDir].add(parts[1] + \"/\");\n }\n }\n\n // Convert sets to sorted arrays, limit children\n const result: Record<string, string[]> = {};\n\n // Add top-level files as \"./\" entry (config files, package.json, etc.)\n if (topLevelFiles.length > 0) {\n const sorted = topLevelFiles.sort();\n result[\"./\"] =\n sorted.length > 15 ? [...sorted.slice(0, 13), `... (${sorted.length} files)`] : sorted;\n }\n\n // Add directory entries\n for (const [dir, children] of Object.entries(tree)) {\n const arr = [...children].sort();\n result[dir] = arr.length > 20 ? [...arr.slice(0, 18), `... (${arr.length} items)`] : arr;\n }\n\n return result;\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nconst LANG_EXTENSIONS: Record<string, string> = {\n \".ts\": \"typescript\",\n \".tsx\": \"typescript-react\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript-react\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".pyi\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n \".java\": \"java\",\n \".kt\": \"kotlin\",\n \".kts\": \"kotlin\",\n \".cs\": \"csharp\",\n \".rb\": \"ruby\",\n \".php\": \"php\",\n \".swift\": \"swift\",\n \".dart\": \"dart\",\n \".ex\": \"elixir\",\n \".exs\": \"elixir\",\n \".zig\": \"zig\",\n \".scala\": \"scala\",\n \".sc\": \"scala\",\n \".cpp\": \"c++\",\n \".cc\": \"c++\",\n \".cxx\": \"c++\",\n \".hpp\": \"c++\",\n \".h\": \"c++\",\n \".c\": \"c\",\n \".sh\": \"shell\",\n \".bash\": \"shell\",\n \".zsh\": \"shell\",\n \".fish\": \"shell\",\n \".ps1\": \"powershell\",\n \".lua\": \"lua\",\n \".r\": \"r\",\n \".R\": \"r\",\n \".m\": \"matlab\",\n \".mlx\": \"matlab\",\n \".jl\": \"julia\",\n \".nim\": \"nim\",\n \".cr\": \"crystal\",\n \".v\": \"v\",\n \".wasm\": \"webassembly\",\n \".wat\": \"webassembly\",\n \".graphql\": \"graphql\",\n \".gql\": \"graphql\",\n \".sol\": \"solidity\",\n \".move\": \"move\",\n \".mo\": \"motoko\",\n \".toml\": \"toml\",\n \".yaml\": \"yaml\",\n \".yml\": \"yaml\",\n \".json\": \"json\",\n \".xml\": \"xml\",\n \".md\": \"markdown\",\n};\n\nconst FRAMEWORK_MAP: Record<string, string> = {\n next: \"next.js\",\n react: \"react\",\n \"react-dom\": \"react\",\n vue: \"vue\",\n nuxt: \"nuxt\",\n \"@angular/core\": \"angular\",\n svelte: \"svelte\",\n \"@sveltejs/kit\": \"sveltekit\",\n express: \"express\",\n fastify: \"fastify\",\n hono: \"hono\",\n koa: \"koa\",\n nestjs: \"nestjs\",\n \"@nestjs/core\": \"nestjs\",\n remix: \"remix\",\n \"@remix-run/react\": \"remix\",\n astro: \"astro\",\n gatsby: \"gatsby\",\n electron: \"electron\",\n tauri: \"tauri\",\n \"react-native\": \"react-native\",\n expo: \"expo\",\n \"@trpc/server\": \"trpc\",\n \"@trpc/client\": \"trpc\",\n};\n\nconst DB_MARKERS: Record<string, string> = {\n pg: \"postgresql\",\n postgres: \"postgresql\",\n \"pg-promise\": \"postgresql\",\n mysql2: \"mysql\",\n mysql: \"mysql\",\n \"@mysql/xdevapi\": \"mysql\",\n \"better-sqlite3\": \"sqlite\",\n sqlite3: \"sqlite\",\n \"sql.js\": \"sqlite\",\n mongodb: \"mongodb\",\n mongoose: \"mongodb\",\n mongoodb: \"mongodb\",\n redis: \"redis\",\n ioredis: \"redis\",\n \"@redis/client\": \"redis\",\n \"redis-mock\": \"redis\",\n \"cassandra-driver\": \"cassandra\",\n \"express-cassandra\": \"cassandra\",\n elasticsearch: \"elasticsearch\",\n \"@elastic/elasticsearch\": \"elasticsearch\",\n \"@elastic/elasticsearch-ng\": \"elasticsearch\",\n \"neo4j-driver\": \"neo4j\",\n neo4j: \"neo4j\",\n couchbase: \"couchbase\",\n ottoman: \"couchbase\",\n rethinkdb: \"rethinkdb\",\n rethinkdbdash: \"rethinkdb\",\n level: \"leveldb\",\n levelup: \"leveldb\",\n \"aws-sdk\": \"dynamodb\",\n \"@aws-sdk/client-dynamodb\": \"dynamodb\",\n mssql: \"mssql\",\n tedious: \"mssql\",\n msnodesqlv8: \"mssql\",\n oracledb: \"oracle\",\n \"node-oracledb\": \"oracle\",\n \"pg-copy-streams\": \"postgresql\",\n \"pg-pool\": \"postgresql\",\n \"pg-native\": \"postgresql\",\n \" knex\": \"knex\",\n minio: \"minio\",\n firebird: \"firebird\",\n \"node-firebird\": \"firebird\",\n \"hdb-pool\": \"sap-hana\",\n \"snowflake-sdk\": \"snowflake\",\n \"cassandra-client\": \"scylladb\",\n};\n\nconst ORM_MARKERS: Record<string, string> = {\n prisma: \"prisma\",\n \"@prisma/client\": \"prisma\",\n \"drizzle-orm\": \"drizzle\",\n typeorm: \"typeorm\",\n sequelize: \"sequelize\",\n \"@mikro-orm/core\": \"mikro-orm\",\n knex: \"knex\",\n mongoose: \"mongoose\",\n};\n\nconst STYLING_MARKERS: Record<string, string> = {\n tailwindcss: \"tailwindcss\",\n \"styled-components\": \"styled-components\",\n \"@emotion/react\": \"emotion\",\n sass: \"sass\",\n \"@chakra-ui/react\": \"chakra-ui\",\n \"@mui/material\": \"material-ui\",\n \"@mantine/core\": \"mantine\",\n};\n\nconst BUILD_TOOL_MARKERS: Record<string, string> = {\n vite: \"vite\",\n webpack: \"webpack\",\n esbuild: \"esbuild\",\n tsup: \"tsup\",\n rollup: \"rollup\",\n parcel: \"parcel\",\n turbopack: \"turbopack\",\n unbuild: \"unbuild\",\n pkgroll: \"pkgroll\",\n \"@swc/core\": \"swc\",\n snowpack: \"snowpack\",\n};\n\nexport const stackDetector: Detector = {\n name: \"stack\",\n category: \"stack\",\n\n async detect(ctx: ScanContext) {\n const languages = detectLanguages(ctx);\n const pkgData = await parsePkgJson(ctx);\n const frameworks = detectFrameworks(pkgData);\n const packageManager = detectPackageManager(ctx, pkgData);\n const databases = detectAllFromMap(pkgData, DB_MARKERS);\n const orm = detectFirstFromMap(pkgData, ORM_MARKERS);\n const styling = detectFirstFromMap(pkgData, STYLING_MARKERS);\n const buildTool = detectFirstFromMap(pkgData, BUILD_TOOL_MARKERS);\n\n // Prisma: parse schema for actual DB provider instead of guessing\n if (orm === \"prisma\") {\n const prismaDb = await detectPrismaProvider(ctx);\n if (prismaDb && !databases.includes(prismaDb)) {\n databases.unshift(prismaDb);\n }\n }\n\n // Enhanced database detection from files\n const fileBasedDatabases = await detectDatabasesFromFiles(ctx);\n for (const db of fileBasedDatabases) {\n if (!databases.includes(db)) {\n databases.push(db);\n }\n }\n\n // Multi-language framework detection\n const [\n pyFramework,\n goFramework,\n rustFramework,\n javaFramework,\n rubyFramework,\n phpFramework,\n csharpFramework,\n ] = await Promise.all([\n detectPythonFramework(ctx),\n detectGoFramework(ctx),\n detectRustFramework(ctx),\n detectJavaFramework(ctx),\n detectRubyFramework(ctx),\n detectPhpFramework(ctx),\n detectCSharpFramework(ctx),\n ]);\n\n if (pyFramework) {\n frameworks.push(pyFramework);\n }\n if (goFramework) {\n frameworks.push(goFramework);\n }\n if (rustFramework) {\n frameworks.push(rustFramework);\n }\n if (javaFramework) {\n frameworks.push(javaFramework);\n }\n if (rubyFramework) {\n frameworks.push(rubyFramework);\n }\n if (phpFramework) {\n frameworks.push(phpFramework);\n }\n if (csharpFramework) {\n frameworks.push(csharpFramework);\n }\n\n return {\n languages: [...new Set(languages)],\n frameworks: [...new Set(frameworks)],\n package_manager: packageManager,\n database: databases.length > 1 ? databases.join(\" + \") : databases[0] || null,\n orm,\n styling,\n build_tool: buildTool,\n };\n },\n};\n\nfunction detectLanguages(ctx: ScanContext): string[] {\n const counts: Record<string, number> = {};\n\n for (const file of ctx.files) {\n if (file.endsWith(\"/\")) {\n continue;\n }\n const ext = \".\" + file.split(\".\").pop();\n const lang = LANG_EXTENSIONS[ext];\n if (lang) {\n counts[lang] = (counts[lang] || 0) + 1;\n }\n }\n\n // Sort by frequency, return names\n return Object.entries(counts)\n .sort((a, b) => b[1] - a[1])\n .map(([lang]) => lang);\n}\n\nasync function parsePkgJson(ctx: ScanContext): Promise<Record<string, string>> {\n const content = await ctx.readFile(\"package.json\");\n if (!content) {\n return {};\n }\n\n try {\n const pkg = JSON.parse(content);\n return {\n ...(pkg.dependencies || {}),\n ...(pkg.devDependencies || {}),\n };\n } catch {\n return {};\n }\n}\n\nfunction detectFrameworks(deps: Record<string, string>): string[] {\n const frameworks: string[] = [];\n\n for (const [dep, version] of Object.entries(deps)) {\n const name = FRAMEWORK_MAP[dep];\n if (name) {\n const cleanVersion = version\n .replace(/^[\\^~>=<]+/, \"\")\n .split(\".\")\n .slice(0, 2)\n .join(\".\");\n frameworks.push(`${name}@${cleanVersion}`);\n }\n }\n\n // Enhanced framework detection from files\n const enhancedFrameworks = detectEnhancedFrameworks(deps);\n frameworks.push(...enhancedFrameworks);\n\n return [...new Set(frameworks)];\n}\n\n/**\n * Enhanced framework detection with detailed information\n */\nfunction detectEnhancedFrameworks(deps: Record<string, string>): string[] {\n const frameworks: string[] = [];\n const allDeps = Object.keys(deps).join(\" \");\n\n // Next.js detection (app router vs pages router)\n if (allDeps.includes(\"next\")) {\n const version = deps[\"next\"]\n ?.replace(/^[\\^~>=<]+/, \"\")\n .split(\".\")\n .slice(0, 2)\n .join(\".\");\n const details = [];\n\n if (version) {\n // Next.js 13+ has app router\n if (parseFloat(version) >= 13) {\n details.push(\"app-router available\");\n }\n details.push(version);\n }\n\n frameworks.push(details.length > 0 ? `next.js@${details.join(\" \")}` : \"next.js\");\n }\n\n // Vue detection (Vue 2 vs Vue 3)\n if (allDeps.includes(\"vue\")) {\n const version = deps[\"vue\"]?.replace(/^[\\^~>=<]+/, \"\");\n if (version) {\n const majorVersion = parseInt(version.split(\".\")[0], 10);\n frameworks.push(majorVersion >= 3 ? `vue@${version}` : `vue@${version}`);\n } else {\n frameworks.push(\"vue\");\n }\n\n // Nuxt detection\n if (allDeps.includes(\"nuxt\")) {\n const nuxtVersion = deps[\"nuxt\"]?.replace(/^[\\^~>=<]+/, \"\");\n if (nuxtVersion) {\n const majorVersion = parseInt(nuxtVersion.split(\".\")[0], 10);\n frameworks.push(\n majorVersion >= 3 ? `nuxt@${nuxtVersion} (Nuxt 3)` : `nuxt@${nuxtVersion} (Nuxt 2)`\n );\n } else {\n frameworks.push(\"nuxt\");\n }\n }\n }\n\n // SvelteKit detection\n if (allDeps.includes(\"@sveltejs/kit\")) {\n const version = deps[\"@sveltejs/kit\"]?.replace(/^[\\^~>=<]+/, \"\");\n frameworks.push(version ? `sveltekit@${version}` : \"sveltekit\");\n }\n\n // Astro detection\n if (allDeps.includes(\"astro\")) {\n const version = deps[\"astro\"]?.replace(/^[\\^~>=<]+/, \"\");\n const integrations: string[] = [];\n\n // Detect Astro integrations\n if (deps[\"@astrojs/react\"]) {\n integrations.push(\"react\");\n }\n if (deps[\"@astrojs/vue\"]) {\n integrations.push(\"vue\");\n }\n if (deps[\"@astrojs/svelte\"]) {\n integrations.push(\"svelte\");\n }\n if (deps[\"@astrojs/preact\"]) {\n integrations.push(\"preact\");\n }\n if (deps[\"@astrojs/solid-js\"]) {\n integrations.push(\"solid\");\n }\n\n if (integrations.length > 0) {\n frameworks.push(\n version\n ? `astro@${version} (${integrations.join(\", \")})`\n : `astro (${integrations.join(\", \")})`\n );\n } else {\n frameworks.push(version ? `astro@${version}` : \"astro\");\n }\n }\n\n // Remix detection\n if (allDeps.includes(\"@remix-run/react\") || allDeps.includes(\"@remix-run/node\")) {\n const version =\n deps[\"@remix-run/react\"]?.replace(/^[\\^~>=<]+/, \"\") ||\n deps[\"@remix-run/node\"]?.replace(/^[\\^~>=<]+/, \"\");\n frameworks.push(version ? `remix@${version}` : \"remix\");\n }\n\n // Angular detection\n if (allDeps.includes(\"@angular/core\")) {\n const version = deps[\"@angular/core\"]\n ?.replace(/^[\\^~>=<]+/, \"\")\n .split(\".\")\n .slice(0, 2)\n .join(\".\");\n frameworks.push(version ? `angular@${version}` : \"angular\");\n }\n\n // Gatsby detection\n if (allDeps.includes(\"gatsby\")) {\n const version = deps[\"gatsby\"]?.replace(/^[\\^~>=<]+/, \"\");\n frameworks.push(version ? `gatsby@${version}` : \"gatsby\");\n }\n\n return frameworks;\n}\n\nfunction detectPackageManager(ctx: ScanContext, deps: Record<string, string>): string | null {\n if (ctx.fileExists(\"pnpm-lock.yaml\")) {\n return \"pnpm\";\n }\n if (ctx.fileExists(\"yarn.lock\")) {\n return \"yarn\";\n }\n if (ctx.fileExists(\"bun.lockb\") || ctx.fileExists(\"bun.lock\")) {\n return \"bun\";\n }\n if (ctx.fileExists(\"package-lock.json\")) {\n return \"npm\";\n }\n if (ctx.fileExists(\"Cargo.lock\")) {\n return \"cargo\";\n }\n if (ctx.fileExists(\"poetry.lock\")) {\n return \"poetry\";\n }\n if (ctx.fileExists(\"Pipfile.lock\")) {\n return \"pipenv\";\n }\n if (ctx.fileExists(\"go.sum\")) {\n return \"go modules\";\n }\n if (ctx.fileExists(\"Gemfile.lock\")) {\n return \"bundler\";\n }\n if (ctx.fileExists(\"composer.lock\")) {\n return \"composer\";\n }\n // Fallback: if package.json has deps, npm is the default\n if (Object.keys(deps).length > 0) {\n return \"npm\";\n }\n return null;\n}\n\nfunction detectFirstFromMap(\n deps: Record<string, string>,\n markers: Record<string, string>\n): string | null {\n for (const dep of Object.keys(deps)) {\n if (markers[dep]) {\n return markers[dep];\n }\n }\n return null;\n}\n\nfunction detectAllFromMap(deps: Record<string, string>, markers: Record<string, string>): string[] {\n const found = new Set<string>();\n for (const dep of Object.keys(deps)) {\n if (markers[dep]) {\n found.add(markers[dep]);\n }\n }\n return [...found];\n}\n\nasync function detectPrismaProvider(ctx: ScanContext): Promise<string | null> {\n const schema = await ctx.readFile(\"prisma/schema.prisma\");\n if (!schema) {\n return null;\n }\n\n // Extract the datasource block specifically (not generator)\n const datasourceBlock = schema.match(/datasource\\s+\\w+\\s*\\{([^}]+)\\}/);\n if (!datasourceBlock) {\n return null;\n }\n\n const match = datasourceBlock[1].match(/provider\\s*=\\s*\"(.*?)\"/);\n if (!match) {\n return null;\n }\n\n const provider = match[1].toLowerCase();\n if (provider === \"postgresql\" || provider === \"postgres\") {\n return \"postgresql\";\n }\n if (provider === \"mysql\") {\n return \"mysql\";\n }\n if (provider === \"sqlite\") {\n return \"sqlite\";\n }\n if (provider === \"sqlserver\") {\n return \"sqlserver\";\n }\n if (provider === \"mongodb\") {\n return \"mongodb\";\n }\n if (provider === \"cockroachdb\") {\n return \"cockroachdb\";\n }\n return provider;\n}\n\nasync function detectDatabasesFromFiles(ctx: ScanContext): Promise<string[]> {\n const databases: string[] = [];\n\n // Detect from migration files\n const migrationDirs = [\n \"migrations/\",\n \"prisma/migrations/\",\n \"db/migrate/\",\n \"database/migrations/\",\n \"src/migrations/\",\n \"server/migrations/\",\n \"api/migrations/\",\n \"migrate/\",\n \"sql/\",\n \"db/sql/\",\n ];\n\n for (const dir of migrationDirs) {\n if (ctx.files.some((f) => f.startsWith(dir))) {\n // Try to detect DB type from migration files\n const dbType = await detectDBFromMigrations(ctx, dir);\n if (dbType && !databases.includes(dbType)) {\n databases.push(dbType);\n }\n }\n }\n\n // Detect from Docker Compose\n const dockerDatabases = await detectDBFromDockerCompose(ctx);\n for (const db of dockerDatabases) {\n if (!databases.includes(db)) {\n databases.push(db);\n }\n }\n\n // Detect from ORM configs\n const ormDatabases = await detectDBFromORMConfigs(ctx);\n for (const db of ormDatabases) {\n if (!databases.includes(db)) {\n databases.push(db);\n }\n }\n\n // Detect from SQL schema files\n const schemaDatabases = await detectDBFromSchemas(ctx);\n for (const db of schemaDatabases) {\n if (!databases.includes(db)) {\n databases.push(db);\n }\n }\n\n return databases;\n}\n\nasync function detectDBFromMigrations(ctx: ScanContext, dir: string): Promise<string | null> {\n const files = ctx.files.filter((f) => f.startsWith(dir));\n\n for (const file of files) {\n const content = await ctx.readFile(file);\n if (!content) {\n continue;\n }\n\n const lower = content.toLowerCase();\n if (lower.includes(\"create table\") || lower.includes(\"alter table\")) {\n if (lower.includes(\"postgresql\") || lower.includes(\"serial\") || lower.includes(\"bigserial\")) {\n return \"postgresql\";\n }\n if (lower.includes(\"mysql\") || lower.includes(\"engine=innodb\")) {\n return \"mysql\";\n }\n if (lower.includes(\"sqlite\")) {\n return \"sqlite\";\n }\n if (lower.includes(\"mongodb\") || lower.includes(\"mongoose\")) {\n return \"mongodb\";\n }\n if (lower.includes(\"redis\")) {\n return \"redis\";\n }\n if (lower.includes(\"elasticsearch\")) {\n return \"elasticsearch\";\n }\n }\n }\n\n return null;\n}\n\nasync function detectDBFromDockerCompose(ctx: ScanContext): Promise<string[]> {\n const found: string[] = [];\n const composeFiles = [\n \"docker-compose.yml\",\n \"docker-compose.yaml\",\n \"docker-compose.dev.yml\",\n \"docker-compose.prod.yml\",\n \"compose.yml\",\n \"compose.yaml\",\n ];\n\n for (const file of composeFiles) {\n if (!ctx.fileExists(file)) {\n continue;\n }\n\n const content = await ctx.readFile(file);\n if (!content) {\n continue;\n }\n\n const lower = content.toLowerCase();\n\n // Detect database services\n if (lower.includes(\"postgres\") || lower.includes(\"postgresql\")) {\n found.push(\"postgresql\");\n }\n if (lower.includes(\"mysql\")) {\n found.push(\"mysql\");\n }\n if (lower.includes(\"mariadb\")) {\n found.push(\"mariadb\");\n }\n if (lower.includes(\"mongodb\") || lower.includes(\"mongo\")) {\n found.push(\"mongodb\");\n }\n if (lower.includes(\"redis\")) {\n found.push(\"redis\");\n }\n if (lower.includes(\"elasticsearch\")) {\n found.push(\"elasticsearch\");\n }\n if (lower.includes(\"cassandra\")) {\n found.push(\"cassandra\");\n }\n if (lower.includes(\"couchdb\")) {\n found.push(\"couchdb\");\n }\n if (lower.includes(\"neo4j\")) {\n found.push(\"neo4j\");\n }\n if (lower.includes(\"rabbitmq\")) {\n found.push(\"rabbitmq\");\n }\n if (lower.includes(\"dynamodb\")) {\n found.push(\"dynamodb\");\n }\n }\n\n return found;\n}\n\nasync function detectDBFromORMConfigs(ctx: ScanContext): Promise<string[]> {\n const found: string[] = [];\n\n // TypeORM\n const typeormConfig =\n (await ctx.readFile(\"ormconfig.json\")) ||\n (await ctx.readFile(\"ormconfig.js\")) ||\n (await ctx.readFile(\"src/data-source.ts\"));\n if (typeormConfig) {\n const lower = typeormConfig.toLowerCase();\n if (lower.includes(\"postgres\") || lower.includes(\"pg\")) {\n found.push(\"postgresql\");\n }\n if (lower.includes(\"mysql\")) {\n found.push(\"mysql\");\n }\n if (lower.includes(\"sqlite\")) {\n found.push(\"sqlite\");\n }\n if (lower.includes(\"mongodb\")) {\n found.push(\"mongodb\");\n }\n }\n\n // Sequelize config\n const sequelizeFiles = [\".sequelizerc\", \"config/database.js\", \"config/config.js\"];\n for (const file of sequelizeFiles) {\n const content = await ctx.readFile(file);\n if (content) {\n const lower = content.toLowerCase();\n if (lower.includes(\"postgres\")) {\n found.push(\"postgresql\");\n }\n if (lower.includes(\"mysql\")) {\n found.push(\"mysql\");\n }\n if (lower.includes(\"sqlite\")) {\n found.push(\"sqlite\");\n }\n if (lower.includes(\"mariadb\")) {\n found.push(\"mariadb\");\n }\n }\n }\n\n // MikroORM\n const mikroOrmConfig =\n (await ctx.readFile(\"mikro-orm.config.ts\")) || (await ctx.readFile(\"mikro-orm.config.js\"));\n if (mikroOrmConfig) {\n const lower = mikroOrmConfig.toLowerCase();\n if (lower.includes(\"postgres\")) {\n found.push(\"postgresql\");\n }\n if (lower.includes(\"mysql\")) {\n found.push(\"mysql\");\n }\n if (lower.includes(\"sqlite\")) {\n found.push(\"sqlite\");\n }\n if (lower.includes(\"mongodb\")) {\n found.push(\"mongodb\");\n }\n }\n\n // Drizzle config\n const drizzleFiles = [\"drizzle.config.ts\", \"drizzle.config.js\", \"drizzle.config.json\"];\n for (const file of drizzleFiles) {\n const content = await ctx.readFile(file);\n if (content) {\n const lower = content.toLowerCase();\n if (lower.includes(\"postgres\") || lower.includes(\"pg\")) {\n found.push(\"postgresql\");\n }\n if (lower.includes(\"mysql\")) {\n found.push(\"mysql\");\n }\n if (lower.includes(\"sqlite\")) {\n found.push(\"sqlite\");\n }\n }\n }\n\n return found;\n}\n\nasync function detectDBFromSchemas(ctx: ScanContext): Promise<string[]> {\n const found: string[] = [];\n\n // Look for SQL schema files\n const schemaFiles = ctx.files.filter(\n (f) =>\n f.endsWith(\".sql\") || f.includes(\"schema\") || f.includes(\"migrate\") || f.includes(\"migration\")\n );\n\n for (const file of schemaFiles) {\n const content = await ctx.readFile(file);\n if (!content) {\n continue;\n }\n\n const lower = content.toLowerCase();\n\n // PostgreSQL-specific patterns\n if (\n lower.includes(\"serial\") ||\n lower.includes(\"bigserial\") ||\n lower.includes(\"text[]\") ||\n lower.includes(\"jsonb\") ||\n lower.includes(\"create extension\") ||\n lower.includes(\"pg_\")\n ) {\n if (!found.includes(\"postgresql\")) {\n found.push(\"postgresql\");\n }\n }\n\n // MySQL-specific patterns\n if (\n lower.includes(\"engine=innodb\") ||\n lower.includes(\"auto_increment\") ||\n lower.includes(\"tinyint\") ||\n lower.includes(\"mediumint\") ||\n lower.includes(\"enum(\")\n ) {\n if (!found.includes(\"mysql\")) {\n found.push(\"mysql\");\n }\n }\n\n // SQLite-specific patterns\n if (lower.includes(\"autoincrement\") || lower.includes(\"integer primary key\")) {\n if (!found.includes(\"sqlite\")) {\n found.push(\"sqlite\");\n }\n }\n }\n\n return found;\n}\n\nasync function detectPythonFramework(ctx: ScanContext): Promise<string | null> {\n const pyproject = await ctx.readFile(\"pyproject.toml\");\n const requirements = await ctx.readFile(\"requirements.txt\");\n const setup = await ctx.readFile(\"setup.py\");\n const combined = pyproject + \"\\n\" + requirements + \"\\n\" + setup;\n\n // Web frameworks\n if (combined.includes(\"fastapi\")) {\n const version = extractVersion(requirements, \"fastapi\") || extractVersion(pyproject, \"fastapi\");\n return version ? `fastapi@${version}` : \"fastapi\";\n }\n if (combined.includes(\"django\")) {\n const version = extractVersion(requirements, \"django\") || extractVersion(pyproject, \"django\");\n const djangoDetails: string[] = [];\n if (version) {\n djangoDetails.push(version);\n }\n\n // Detect Django apps\n const djangoApps = await detectDjangoApps(ctx);\n if (djangoApps.length > 0) {\n djangoDetails.push(`apps: ${djangoApps.join(\", \")}`);\n }\n\n // Detect Django settings\n const settingsModule = await detectDjangoSettings(ctx);\n if (settingsModule) {\n djangoDetails.push(settingsModule);\n }\n\n return djangoDetails.length > 0\n ? `django@${djangoDetails.join(\" \")}`\n : version\n ? `django@${version}`\n : \"django\";\n }\n if (combined.includes(\"flask\")) {\n const version = extractVersion(requirements, \"flask\") || extractVersion(pyproject, \"flask\");\n return version ? `flask@${version}` : \"flask\";\n }\n if (combined.includes(\"starlette\")) {\n return \"starlette\";\n }\n if (combined.includes(\"tornado\")) {\n return \"tornado\";\n }\n if (combined.includes(\"aiohttp\")) {\n return \"aiohttp\";\n }\n if (combined.includes(\"sanic\")) {\n return \"sanic\";\n }\n if (combined.includes(\"pyramid\")) {\n return \"pyramid\";\n }\n if (combined.includes(\"bottle\")) {\n return \"bottle\";\n }\n if (combined.includes(\"cherrypy\")) {\n return \"cherrypy\";\n }\n if (combined.includes(\"falcon\")) {\n return \"falcon\";\n }\n if (combined.includes(\"masonite\")) {\n return \"masonite\";\n }\n\n // ML frameworks\n if (combined.includes(\"torch\") || combined.includes(\"pytorch\")) {\n return \"pytorch\";\n }\n if (combined.includes(\"tensorflow\")) {\n return \"tensorflow\";\n }\n if (combined.includes(\"keras\")) {\n return \"keras\";\n }\n if (combined.includes(\"scikit-learn\")) {\n return \"scikit-learn\";\n }\n if (combined.includes(\"pandas\")) {\n return \"pandas\";\n }\n if (combined.includes(\"numpy\")) {\n return \"numpy\";\n }\n\n // Task queues\n if (combined.includes(\"celery\")) {\n return \"celery\";\n }\n if (combined.includes(\"rq\")) {\n return \"rq\";\n }\n\n return null;\n}\n\n/**\n * Detect Django apps from settings.py or settings/\n */\nasync function detectDjangoApps(ctx: ScanContext): Promise<string[]> {\n const apps: string[] = [];\n\n // Try to find settings file\n const settingsFiles = ctx.files.filter(\n (f) => f.includes(\"settings.py\") || f.includes(\"settings/\") || f.match(/settings.*\\.py$/)\n );\n\n for (const file of settingsFiles.slice(0, 3)) {\n // Check at most 3 files\n try {\n const content = await ctx.readFile(file);\n if (!content) {\n continue;\n }\n\n // Find INSTALLED_APPS\n const installedAppsMatch = content.match(/INSTALLED_APPS\\s*=\\s*\\[([\\s\\S]*?)\\]/);\n if (installedAppsMatch) {\n const appsContent = installedAppsMatch[1];\n // Extract app names (simple extraction)\n const appMatches = appsContent.match(/'([^']+)'/g) || appsContent.match(/\"([^\"]+)\"/g) || [];\n for (const app of appMatches) {\n const appName = app.replace(/['\"]/g, \"\");\n // Filter out django apps and third-party apps\n if (!appName.startsWith(\"django.\") && appName.includes(\".\")) {\n apps.push(appName.split(\".\")[0]);\n }\n }\n }\n } catch {\n // Skip errors reading settings files\n }\n }\n\n return [...new Set(apps)].slice(0, 5); // Return up to 5 apps\n}\n\n/**\n * Detect Django settings module\n */\nasync function detectDjangoSettings(ctx: ScanContext): Promise<string | null> {\n const hasSettingsPy = ctx.files.some((f) => f.endsWith(\"settings.py\"));\n const hasSettingsDir = ctx.files.some((f) => f.includes(\"settings/\") && f.endsWith(\".py\"));\n const hasDevSettings = ctx.files.some(\n (f) => f.includes(\"settings_dev.py\") || f.includes(\"settings.dev\")\n );\n\n if (hasDevSettings) {\n return \"settings:dev\";\n }\n if (hasSettingsDir) {\n return \"settings:dir\";\n }\n if (hasSettingsPy) {\n return \"settings:py\";\n }\n\n return null;\n}\n\nasync function detectGoFramework(ctx: ScanContext): Promise<string | null> {\n const gomod = await ctx.readFile(\"go.mod\");\n if (!gomod) {\n return null;\n }\n\n const versions: string[] = [];\n\n if (gomod.includes(\"github.com/gin-gonic/gin\")) {\n const version = extractGoVersion(gomod, \"github.com/gin-gonic/gin\");\n versions.push(version ? `gin@${version}` : \"gin\");\n }\n if (gomod.includes(\"github.com/gofiber/fiber\")) {\n const version = extractGoVersion(gomod, \"github.com/gofiber/fiber\");\n versions.push(version ? `fiber@${version}` : \"fiber\");\n }\n if (gomod.includes(\"github.com/labstack/echo\")) {\n const version = extractGoVersion(gomod, \"github.com/labstack/echo\");\n versions.push(version ? `echo@${version}` : \"echo\");\n }\n if (gomod.includes(\"github.com/gorilla/mux\")) {\n const version = extractGoVersion(gomod, \"github.com/gorilla/mux\");\n versions.push(version ? `gorilla/mux@${version}` : \"gorilla/mux\");\n }\n if (gomod.includes(\"go-chi/chi\")) {\n const version = extractGoVersion(gomod, \"go-chi/chi\");\n versions.push(version ? `chi@${version}` : \"chi\");\n }\n if (gomod.includes(\"grpc\")) {\n versions.push(\"grpc\");\n }\n if (gomod.includes(\"net/http\")) {\n versions.push(\"net/http (std)\");\n }\n\n return versions.length > 0 ? versions.join(\", \") : null;\n}\n\nasync function detectRustFramework(ctx: ScanContext): Promise<string | null> {\n const cargo = await ctx.readFile(\"Cargo.toml\");\n if (!cargo) {\n return null;\n }\n\n const versions: string[] = [];\n\n if (cargo.includes(\"actix-web\")) {\n const version = extractCargoVersion(cargo, \"actix-web\");\n versions.push(version ? `actix-web@${version}` : \"actix-web\");\n }\n if (cargo.includes(\"axum\")) {\n const version = extractCargoVersion(cargo, \"axum\");\n versions.push(version ? `axum@${version}` : \"axum\");\n }\n if (cargo.includes(\"rocket\")) {\n const version = extractCargoVersion(cargo, \"rocket\");\n versions.push(version ? `rocket@${version}` : \"rocket\");\n }\n if (cargo.includes(\"warp\")) {\n versions.push(\"warp\");\n }\n if (cargo.includes(\"tokio\")) {\n const version = extractCargoVersion(cargo, \"tokio\");\n versions.push(version ? `tokio@${version}` : \"tokio\");\n }\n if (cargo.includes(\"hyper\")) {\n versions.push(\"hyper\");\n }\n if (cargo.includes(\"tonic\")) {\n versions.push(\"tonic (grpc)\");\n }\n\n return versions.length > 0 ? versions.join(\", \") : null;\n}\n\nasync function detectJavaFramework(ctx: ScanContext): Promise<string | null> {\n const pom = await ctx.readFile(\"pom.xml\");\n const buildGradle = await ctx.readFile(\"build.gradle\");\n const buildGradleKts = await ctx.readFile(\"build.gradle.kts\");\n const combined = pom + \"\\n\" + buildGradle + \"\\n\" + buildGradleKts;\n\n if (combined.includes(\"spring-boot\")) {\n const version =\n extractFromXml(pom, \"spring-boot-starter-parent\") ||\n extractFromGradle(buildGradle, \"org.springframework.boot\");\n return version ? `spring boot@${version}` : \"spring boot\";\n }\n if (combined.includes(\"spring-framework\") || combined.includes(\"spring-core\")) {\n const version =\n extractFromXml(pom, \"spring-framework\") ||\n extractFromGradle(buildGradle, \"org.springframework\");\n return version ? `spring@${version}` : \"spring\";\n }\n if (combined.includes(\"micronaut\")) {\n const version =\n extractFromXml(pom, \"micronaut\") || extractFromGradle(buildGradle, \"io.micronaut\");\n return version ? `micronaut@${version}` : \"micronaut\";\n }\n if (combined.includes(\"quarkus\")) {\n const version = extractFromXml(pom, \"quarkus\") || extractFromGradle(buildGradle, \"io.quarkus\");\n return version ? `quarkus@${version}` : \"quarkus\";\n }\n if (combined.includes(\"jakarta\")) {\n return \"jakarta ee\";\n }\n if (combined.includes(\"javax\")) {\n return \"java ee\";\n }\n if (combined.includes(\"vertx\")) {\n return \"vert.x\";\n }\n if (combined.includes(\"kafka\")) {\n return \"kafka\";\n }\n\n return null;\n}\n\nasync function detectRubyFramework(ctx: ScanContext): Promise<string | null> {\n const gemfile = await ctx.readFile(\"Gemfile\");\n const gemspec = await ctx.readFile(\".gemspec\");\n const combined = gemfile + \"\\n\" + gemspec;\n\n if (combined.includes(\"rails\")) {\n const version = extractGemVersion(combined, \"rails\");\n const details: string[] = [];\n if (version) {\n details.push(version);\n }\n\n // Detect Rails middleware stack\n const middlewareStack = await detectRailsMiddleware(ctx);\n if (middlewareStack.length > 0) {\n details.push(middlewareStack.join(\", \"));\n }\n\n return details.length > 0 ? `rails@${details.join(\" \")}` : `rails@${version || \"unknown\"}`;\n }\n if (combined.includes(\"sinatra\")) {\n const version = extractGemVersion(combined, \"sinatra\");\n return version ? `sinatra@${version}` : \"sinatra\";\n }\n if (combined.includes(\"grape\")) {\n return \"grape\";\n }\n if (combined.includes(\"hanami\")) {\n return \"hanami\";\n }\n if (combined.includes(\"roda\")) {\n return \"roda\";\n }\n if (combined.includes(\"padrino\")) {\n return \"padrino\";\n }\n if (combined.includes(\"sidekiq\")) {\n return \"sidekiq\";\n }\n if (combined.includes(\"resque\")) {\n return \"resque\";\n }\n if (combined.includes(\"puma\")) {\n return \"puma\";\n }\n if (combined.includes(\"unicorn\")) {\n return \"unicorn\";\n }\n\n return null;\n}\n\n/**\n * Detect Rails middleware stack from config/application.rb or config/environment files\n */\nasync function detectRailsMiddleware(ctx: ScanContext): Promise<string[]> {\n const middleware: string[] = [];\n\n // Check for common Rails gems\n const gemfile = await ctx.readFile(\"Gemfile\");\n if (gemfile) {\n if (gemfile.includes(\"devise\")) {\n middleware.push(\"devise\");\n }\n if (gemfile.includes(\"pundit\")) {\n middleware.push(\"pundit\");\n }\n if (gemfile.includes(\"cancancan\")) {\n middleware.push(\"cancancan\");\n }\n if (gemfile.includes(\"rspec-rails\")) {\n middleware.push(\"rspec\");\n }\n if (gemfile.includes(\"minitest\")) {\n middleware.push(\"minitest\");\n }\n if (gemfile.includes(\"factory_bot_rails\")) {\n middleware.push(\"factory_bot\");\n }\n if (gemfile.includes(\"faker\")) {\n middleware.push(\"faker\");\n }\n if (gemfile.includes(\"sidekiq\")) {\n middleware.push(\"sidekiq\");\n }\n if (gemfile.includes(\"redis\") || gemfile.includes(\"redis-rails\")) {\n middleware.push(\"redis\");\n }\n if (gemfile.includes(\"pg\")) {\n middleware.push(\"postgresql\");\n }\n if (gemfile.includes(\"mysql2\")) {\n middleware.push(\"mysql\");\n }\n if (gemfile.includes(\"sqlite3\")) {\n middleware.push(\"sqlite\");\n }\n if (gemfile.includes(\"aws-sdk\")) {\n middleware.push(\"aws\");\n }\n if (gemfile.includes(\"bootstrap\")) {\n middleware.push(\"bootstrap\");\n }\n if (gemfile.includes(\"tailwindcss-rails\")) {\n middleware.push(\"tailwind\");\n }\n }\n\n return middleware.slice(0, 5); // Return up to 5 middleware components\n}\n\nasync function detectPhpFramework(ctx: ScanContext): Promise<string | null> {\n const composer = await ctx.readFile(\"composer.json\");\n if (!composer) {\n return null;\n }\n\n try {\n const pkg = JSON.parse(composer);\n const deps = { ...(pkg.require || {}), ...(pkg[\"require-dev\"] || {}) };\n const combined = Object.keys(deps).join(\" \");\n\n if (combined.includes(\"laravel\")) {\n const version = deps[\"laravel/framework\"] || deps[\"laravel/lumen\"];\n return version ? `laravel@${version.replace(/^[\\^~>=<]+/, \"\")}` : \"laravel\";\n }\n if (combined.includes(\"symfony\")) {\n const version = deps[\"symfony/framework-bundle\"];\n return version ? `symfony@${version.replace(/^[\\^~>=<]+/, \"\")}` : \"symfony\";\n }\n if (combined.includes(\"slim\")) {\n const version = deps[\"slim/slim\"];\n return version ? `slim@${version.replace(/^[\\^~>=<]+/, \"\")}` : \"slim\";\n }\n if (combined.includes(\"codeigniter\")) {\n return \"codeigniter\";\n }\n if (combined.includes(\"cakephp\")) {\n return \"cakephp\";\n }\n if (combined.includes(\"yii\")) {\n const version = deps[\"yiisoft/yii2\"];\n return version ? `yii@${version.replace(/^[\\^~>=<]+/, \"\")}` : \"yii\";\n }\n if (combined.includes(\"lumen\")) {\n return \"lumen\";\n }\n } catch {}\n\n return null;\n}\n\nasync function detectCSharpFramework(ctx: ScanContext): Promise<string | null> {\n const csprojFiles = ctx.files.filter((f) => f.endsWith(\".csproj\"));\n if (csprojFiles.length === 0) {\n return null;\n }\n\n const frameworks: string[] = [];\n\n for (const file of csprojFiles) {\n const content = await ctx.readFile(file);\n\n if (content.includes(\"Microsoft.AspNetCore\")) {\n const version = extractCsprojVersion(content, \"Microsoft.AspNetCore.App\");\n frameworks.push(version ? `asp.net core@${version}` : \"asp.net core\");\n }\n if (content.includes(\"EntityFramework\")) {\n frameworks.push(\"entity framework\");\n }\n if (content.includes(\"NUnit\")) {\n frameworks.push(\"nunit\");\n }\n if (content.includes(\"xUnit\")) {\n frameworks.push(\"xunit\");\n }\n if (content.includes(\"Moq\")) {\n frameworks.push(\"moq\");\n }\n }\n\n return frameworks.length > 0 ? frameworks.join(\", \") : null;\n}\n\n// Helper functions for version extraction\n\nfunction extractVersion(content: string, packageName: string): string | null {\n if (!content) {\n return null;\n }\n\n // Match patterns like \"package==1.2.3\", \"package>=1.2.3\", \"package@1.2.3\"\n const patterns = [\n new RegExp(`${packageName}===?\\\\s*([\\\\d.]+)`), // === or ==\n new RegExp(`${packageName}>=?\\\\s*([\\\\d.]+)`), // >= or >\n new RegExp(`${packageName}~=?\\\\s*([\\\\d.]+)`), // ~= or ~\n new RegExp(`${packageName}@([\\\\d.]+)`), // @\n new RegExp(`\"${packageName}\":\\\\s*\"([\\\\d.]+)\"`), // JSON format\n new RegExp(`'${packageName}':\\\\s*'([\\\\d.]+)'`), // JSON single quotes\n ];\n\n for (const pattern of patterns) {\n const match = content.match(pattern);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n\nfunction extractGoVersion(content: string, packageName: string): string | null {\n // Go modules format: package version v1.2.3\n const pattern = new RegExp(`${packageName}\\\\s+v([\\\\d.]+)`);\n const match = content.match(pattern);\n return match ? match[1] : null;\n}\n\nfunction extractCargoVersion(content: string, packageName: string): string | null {\n // Cargo.toml format: package = \"1.2.3\"\n const pattern = new RegExp(`${packageName}\\\\s*=\\\\s*\"([\\\\d.]+)\"`);\n const match = content.match(pattern);\n return match ? match[1] : null;\n}\n\nfunction extractFromXml(content: string, artifactId: string): string | null {\n if (!content) {\n return null;\n }\n\n // Match <version>1.2.3</version> within a dependency with matching artifactId\n const pattern = new RegExp(\n `<artifactId>${artifactId.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}</artifactId>[\\\\s\\\\S]*?<version>([\\\\d.]+)</version>`\n );\n const match = content.match(pattern);\n return match ? match[1] : null;\n}\n\nfunction extractFromGradle(content: string, group: string): string | null {\n if (!content) {\n return null;\n }\n\n // Match version: \"group:version:1.2.3\" or group/version patterns\n const patterns = [\n new RegExp(`${group.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}:[^:]*:([\\\\d.]+)`),\n new RegExp(`${group.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}:([\\\\d.]+)`),\n ];\n\n for (const pattern of patterns) {\n const match = content.match(pattern);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n\nfunction extractGemVersion(content: string, gemName: string): string | null {\n // Rubygems format: gem \"package\", \"1.2.3\" or gem \"package\", \"~> 1.2.3\"\n const pattern = new RegExp(`gem\\\\s+['\"]${gemName}['\"][^,]*,\\\\s*['\"]~?>?\\\\s*([\\\\d.]+)['\"]`);\n const match = content.match(pattern);\n return match ? match[1] : null;\n}\n\nfunction extractCsprojVersion(content: string, packageRef: string): string | null {\n // .csproj format: <PackageReference Include=\"...\" Version=\"1.2.3\" />\n const pattern = new RegExp(\n `<PackageReference\\\\s+Include=\"${packageRef.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\"[^>]*Version=\"([\\\\d.]+)\"`\n );\n const match = content.match(pattern);\n return match ? match[1] : null;\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nexport const commandsDetector: Detector = {\n name: \"commands\",\n category: \"commands\",\n\n async detect(ctx: ScanContext) {\n // Try package.json scripts first (most common)\n const pkgCommands = await detectFromPackageJson(ctx);\n if (Object.values(pkgCommands).some(Boolean)) {\n return pkgCommands;\n }\n\n // Try Makefile\n const makeCommands = await detectFromMakefile(ctx);\n if (Object.values(makeCommands).some(Boolean)) {\n return makeCommands;\n }\n\n // Try Cargo/Go/Python defaults\n const langCommands = await detectLanguageDefaults(ctx);\n return langCommands;\n },\n};\n\nasync function detectFromPackageJson(ctx: ScanContext): Promise<Record<string, string | null>> {\n const content = await ctx.readFile(\"package.json\");\n if (!content) {\n return emptyCommands();\n }\n\n try {\n const pkg = JSON.parse(content);\n const scripts = pkg.scripts || {};\n\n // Detect package manager for prefix\n let pm = \"npm run\";\n if (ctx.fileExists(\"pnpm-lock.yaml\")) {\n pm = \"pnpm\";\n } else if (ctx.fileExists(\"yarn.lock\")) {\n pm = \"yarn\";\n } else if (ctx.fileExists(\"bun.lockb\") || ctx.fileExists(\"bun.lock\")) {\n pm = \"bun run\";\n }\n\n const result: Record<string, string | null> = {\n dev: findScript(scripts, [\"dev\", \"start\", \"serve\"], pm),\n build: findScript(scripts, [\"build\", \"compile\"], pm),\n test: findScript(scripts, [\"test\", \"test:unit\", \"test:run\"], pm),\n lint: findScript(scripts, [\"lint\", \"lint:check\"], pm),\n format: findScript(scripts, [\"format\", \"fmt\", \"prettier\"], pm),\n };\n\n // Detect extra useful scripts\n const extras = [\n \"typecheck\",\n \"check\",\n \"deploy\",\n \"preview\",\n \"clean\",\n \"db:migrate\",\n \"db:seed\",\n \"generate\",\n \"codegen\",\n \"storybook\",\n ];\n for (const name of extras) {\n if (scripts[name]) {\n result[name] = `${pm} ${name}`;\n }\n }\n\n return result;\n } catch {\n return emptyCommands();\n }\n}\n\nfunction findScript(scripts: Record<string, string>, names: string[], pm: string): string | null {\n for (const name of names) {\n if (scripts[name]) {\n return `${pm} ${name}`;\n }\n }\n return null;\n}\n\nasync function detectFromMakefile(ctx: ScanContext): Promise<Record<string, string | null>> {\n const content = await ctx.readFile(\"Makefile\");\n if (!content) {\n return emptyCommands();\n }\n\n const targets = new Set<string>();\n for (const line of content.split(\"\\n\")) {\n const match = line.match(/^([a-zA-Z_-]+)\\s*:/);\n if (match) {\n targets.add(match[1]);\n }\n }\n\n return {\n dev: targets.has(\"dev\") ? \"make dev\" : targets.has(\"run\") ? \"make run\" : null,\n build: targets.has(\"build\") ? \"make build\" : null,\n test: targets.has(\"test\") ? \"make test\" : null,\n lint: targets.has(\"lint\") ? \"make lint\" : null,\n format: targets.has(\"format\") ? \"make format\" : targets.has(\"fmt\") ? \"make fmt\" : null,\n };\n}\n\nasync function detectLanguageDefaults(ctx: ScanContext): Promise<Record<string, string | null>> {\n // === Rust (Cargo) ===\n if (ctx.fileExists(\"Cargo.toml\")) {\n return {\n dev: \"cargo run\",\n build: \"cargo build\",\n test: \"cargo test\",\n lint: \"cargo clippy\",\n format: \"cargo fmt\",\n };\n }\n\n // === Go ===\n if (ctx.fileExists(\"go.mod\")) {\n return {\n dev: \"go run .\",\n build: \"go build .\",\n test: \"go test ./...\",\n lint:\n ctx.fileExists(\".golangci.yml\") || ctx.fileExists(\".golangci.yaml\")\n ? \"golangci-lint run\"\n : null,\n format: \"go fmt ./...\",\n };\n }\n\n // === Python ===\n if (\n ctx.fileExists(\"pyproject.toml\") ||\n ctx.fileExists(\"requirements.txt\") ||\n ctx.fileExists(\"setup.py\")\n ) {\n const pm = ctx.fileExists(\"poetry.lock\")\n ? \"poetry run\"\n : ctx.fileExists(\"Pipfile.lock\")\n ? \"pipenv run\"\n : ctx.fileExists(\"uv.lock\")\n ? \"uv run\"\n : \"python -m\";\n\n const hasPytest =\n ctx.files.some((f) => f.includes(\"pytest\") || f.includes(\"test_\")) ||\n ctx.fileExists(\"pytest.ini\");\n const hasRuff =\n ctx.fileExists(\"ruff.toml\") ||\n ctx.fileExists(\".ruff.toml\") ||\n ctx.fileExists(\"pyproject.toml\");\n const hasBlack = ctx.fileExists(\"pyproject.toml\") || ctx.fileExists(\".black\");\n const hasMypy = ctx.fileExists(\"mypy.ini\") || ctx.fileExists(\".mypy.ini\");\n const hasDjango = ctx.fileExists(\"manage.py\");\n const hasFastapi = ctx.files.some((f) => f.includes(\"main.py\") || f.includes(\"app.py\"));\n\n let devCmd: string | null = null;\n if (hasDjango) {\n devCmd = `${pm} python manage.py runserver`;\n } else if (hasFastapi) {\n devCmd = `${pm} uvicorn main:app --reload`;\n } else if (ctx.fileExists(\"vite.config.ts\")) {\n devCmd = `${pm} vite`;\n }\n\n let buildCmd: string | null = null;\n if (ctx.fileExists(\"pyproject.toml\")) {\n buildCmd = `${pm} build`;\n }\n\n return {\n dev: devCmd,\n build: buildCmd,\n test: hasPytest ? `${pm} pytest` : `${pm} unittest`,\n lint: hasRuff ? `${pm} ruff check .` : hasMypy ? `${pm} mypy .` : null,\n format: hasRuff ? `${pm} ruff format .` : hasBlack ? `${pm} black .` : null,\n };\n }\n\n // === Java (Maven/Gradle) ===\n if (ctx.fileExists(\"pom.xml\")) {\n return {\n dev: \"mvn spring-boot:run\",\n build: \"mvn compile\",\n test: \"mvn test\",\n lint: \"mvn checkstyle:check\",\n format: null,\n };\n }\n\n if (ctx.fileExists(\"build.gradle\") || ctx.fileExists(\"build.gradle.kts\")) {\n return {\n dev: \"./gradlew bootRun\",\n build: \"./gradlew build\",\n test: \"./gradlew test\",\n lint: \"./gradlew checkstyleMain\",\n format: null,\n };\n }\n\n // === Kotlin (Gradle) ===\n if (ctx.fileExists(\"build.gradle.kts\")) {\n return {\n dev: \"./gradlew run\",\n build: \"./gradlew build\",\n test: \"./gradlew test\",\n lint: \"./gradlew ktlintCheck\",\n format: \"./gradlew ktlintFormat\",\n };\n }\n\n // === C# (.NET) ===\n if (ctx.files.some((f) => f.endsWith(\".csproj\") || f.endsWith(\".sln\"))) {\n return {\n dev: \"dotnet run\",\n build: \"dotnet build\",\n test: \"dotnet test\",\n lint: null,\n format: \"dotnet format\",\n };\n }\n\n // === Ruby ===\n if (ctx.fileExists(\"Gemfile\")) {\n const pm = \"bundle exec\";\n const hasRails =\n ctx.fileExists(\"bin/rails\") || ctx.files.some((f) => f.includes(\"config/application.rb\"));\n const hasRake = ctx.fileExists(\"Rakefile\");\n\n return {\n dev: hasRails ? `${pm} rails server` : null,\n build: null,\n test: hasRails ? `${pm} rails test` : hasRake ? `${pm} rake test` : `${pm} rspec`,\n lint: ctx.fileExists(\".rubocop.yml\") ? `${pm} rubocop` : null,\n format: ctx.fileExists(\".rubocop.yml\") ? `${pm} rubocop -a` : null,\n };\n }\n\n // === PHP ===\n if (ctx.fileExists(\"composer.json\")) {\n const pm = \"composer\";\n const hasLaravel =\n ctx.fileExists(\"artisan\") || ctx.files.some((f) => f.includes(\"config/app.php\"));\n const hasSymfony = ctx.files.some((f) => f.includes(\"symfony\"));\n\n return {\n dev: hasLaravel\n ? \"php artisan serve\"\n : hasSymfony\n ? \"symfony server:start\"\n : \"php -S localhost:8000\",\n build: `${pm} install`,\n test: hasLaravel ? \"php artisan test\" : `${pm} test`,\n lint:\n ctx.fileExists(\"phpunit.xml\") || ctx.fileExists(\"phpunit.xml.dist\")\n ? `${pm} phpunit`\n : null,\n format: ctx.fileExists(\".php-cs-fixer.php\") ? \"vendor/bin/php-cs-fixer fix\" : null,\n };\n }\n\n // === Swift ===\n if (ctx.fileExists(\"Package.swift\") || ctx.files.some((f) => f.endsWith(\".xcodeproj\"))) {\n return {\n dev: \"swift run\",\n build: \"swift build\",\n test: \"swift test\",\n lint: null,\n format: \"swift format .\",\n };\n }\n\n // === Dart/Flutter ===\n if (ctx.fileExists(\"pubspec.yaml\")) {\n return {\n dev: ctx.fileExists(\"lib/main.dart\") ? \"flutter run\" : \"dart run\",\n build: ctx.fileExists(\"lib/main.dart\") ? \"flutter build\" : \"dart compile exe\",\n test: \"flutter test\",\n lint: \"flutter analyze\",\n format: \"dart format .\",\n };\n }\n\n // === Elixir ===\n if (ctx.fileExists(\"mix.exs\")) {\n return {\n dev: \"mix phx.server\",\n build: \"mix compile\",\n test: \"mix test\",\n lint: \"mix format --check-formatted\",\n format: \"mix format\",\n };\n }\n\n // === Scala (sbt) ===\n if (ctx.fileExists(\"build.sbt\")) {\n return {\n dev: \"sbt run\",\n build: \"sbt compile\",\n test: \"sbt test\",\n lint: \"sbt scalafmtCheck\",\n format: \"sbt scalafmt\",\n };\n }\n\n // === C/C++ (CMake/Make) ===\n if (ctx.fileExists(\"CMakeLists.txt\")) {\n return {\n dev: null,\n build: \"cmake --build build\",\n test: \"ctest --test-dir build\",\n lint: null,\n format: null,\n };\n }\n\n // Makefile should be checked last, as it's a generic build tool\n // Only use it if no language-specific files were found\n const hasLanguageFiles =\n ctx.fileExists(\"Cargo.toml\") ||\n ctx.fileExists(\"go.mod\") ||\n ctx.fileExists(\"pyproject.toml\") ||\n ctx.fileExists(\"requirements.txt\") ||\n ctx.fileExists(\"setup.py\") ||\n ctx.fileExists(\"pom.xml\") ||\n ctx.fileExists(\"build.gradle\") ||\n ctx.fileExists(\"build.gradle.kts\") ||\n ctx.fileExists(\"Gemfile\") ||\n ctx.fileExists(\"composer.json\") ||\n ctx.fileExists(\"Package.swift\") ||\n ctx.fileExists(\"pubspec.yaml\") ||\n ctx.fileExists(\"mix.exs\") ||\n ctx.fileExists(\"build.sbt\") ||\n ctx.fileExists(\"CMakeLists.txt\");\n\n if (ctx.fileExists(\"Makefile\") && !hasLanguageFiles) {\n // Return empty commands - let the Makefile-specific detection handle it\n return emptyCommands();\n }\n\n // === Shell ===\n if (ctx.files.some((f) => f.endsWith(\".sh\"))) {\n return {\n dev: null,\n build: null,\n test: null,\n lint: \"shellcheck *.sh\",\n format: \"shfmt -w *.sh\",\n };\n }\n\n return emptyCommands();\n}\n\nfunction emptyCommands(): Record<string, string | null> {\n return { dev: null, build: null, test: null, lint: null, format: null };\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nconst NOTABLE_PACKAGES = new Set([\n // === JavaScript/TypeScript ===\n // Frameworks\n \"next\",\n \"react\",\n \"vue\",\n \"angular\",\n \"svelte\",\n \"nuxt\",\n \"remix\",\n \"astro\",\n \"gatsby\",\n \"express\",\n \"fastify\",\n \"hono\",\n \"nestjs\",\n \"koa\",\n \"solid\",\n \"solid-js\",\n \"qwik\",\n // ORM / DB\n \"prisma\",\n \"@prisma/client\",\n \"drizzle-orm\",\n \"typeorm\",\n \"sequelize\",\n \"mongoose\",\n \"knex\",\n // State\n \"zustand\",\n \"redux\",\n \"@reduxjs/toolkit\",\n \"mobx\",\n \"jotai\",\n \"recoil\",\n \"pinia\",\n \"vuex\",\n \"@tanstack/react-query\",\n \"@swr/core\",\n \"react-query\",\n // Validation\n \"zod\",\n \"joi\",\n \"yup\",\n \"ajv\",\n \"class-validator\",\n // API\n \"@trpc/server\",\n \"graphql\",\n \"apollo-server\",\n \"@apollo/client\",\n \"graphql-yoga\",\n // Testing\n \"jest\",\n \"vitest\",\n \"mocha\",\n \"playwright\",\n \"@playwright/test\",\n \"cypress\",\n \"msw\",\n // Build\n \"webpack\",\n \"vite\",\n \"esbuild\",\n \"rollup\",\n \"turbo\",\n \"nx\",\n \"tsup\",\n \"unbuild\",\n \"pkgroll\",\n // Styling\n \"tailwindcss\",\n \"styled-components\",\n \"@emotion/react\",\n \"@chakra-ui/react\",\n \"@mui/material\",\n \"@mantine/core\",\n // Auth\n \"next-auth\",\n \"@auth/core\",\n \"passport\",\n \"jsonwebtoken\",\n \"lucia-auth\",\n // Deployment\n \"@vercel/node\",\n \"@netlify/functions\",\n \"serverless\",\n \"sst\",\n\n // === Python ===\n \"fastapi\",\n \"django\",\n \"flask\",\n \"starlette\",\n \"tornado\",\n \"aiohttp\",\n \"sqlalchemy\",\n \"alembic\",\n \"pydantic\",\n \"typer\",\n \"click\",\n \"pytest\",\n \"black\",\n \"ruff\",\n \"mypy\",\n \"pylint\",\n \"celery\",\n \"redis\",\n \"pymongo\",\n \"psycopg2\",\n \"numpy\",\n \"pandas\",\n \"torch\",\n \"tensorflow\",\n \"scikit-learn\",\n\n // === Go ===\n \"gin-gonic\",\n \"gorilla/mux\",\n \"go-chi/chi\",\n \"labstack/echo\",\n \"gofiber/fiber\",\n \"gorm\",\n \"sqlx\",\n \"lib/pq\",\n \"go-redis\",\n \"testify\",\n \"stretchr\",\n \"grpc\",\n \"protobuf\",\n \"cobra\",\n\n // === Rust ===\n \"actix-web\",\n \"axum\",\n \"rocket\",\n \"warp\",\n \"tokio\",\n \"serde\",\n \"diesel\",\n \"sqlx\",\n \"sea-orm\",\n \"clap\",\n \"anyhow\",\n \"thiserror\",\n \"tracing\",\n\n // === Ruby ===\n \"rails\",\n \"sinatra\",\n \"grape\",\n \"hanami\",\n \"roda\",\n \"activerecord\",\n \"pg\",\n \"mysql2\",\n \"redis\",\n \"sidekiq\",\n \"rspec\",\n \"rubocop\",\n \"pry\",\n \"byebug\",\n\n // === PHP ===\n \"laravel\",\n \"symfony\",\n \"slim\",\n \"guzzlehttp\",\n \"illuminate\",\n \"doctrine/orm\",\n \"ramsey/uuid\",\n \"phpunit\",\n \"mockery\",\n\n // === Java/Kotlin ===\n \"spring-boot\",\n \"spring-framework\",\n \"micronaut\",\n \"quarkus\",\n \"hibernate\",\n \"jakarta.persistence\",\n \"junit\",\n \"mockito\",\n \"testng\",\n\n // === C# ===\n \"Microsoft.AspNetCore\",\n \"EntityFramework\",\n \"Newtonsoft\",\n \"NUnit\",\n \"xUnit\",\n \"Moq\",\n\n // === Misc ===\n \"docker\",\n \"typescript\",\n \"kubernetes\",\n]);\n\nconst NOTABLE_PYTHON = new Set([\n \"django\",\n \"flask\",\n \"fastapi\",\n \"starlette\",\n \"tornado\",\n \"aiohttp\",\n \"sqlalchemy\",\n \"alembic\",\n \"pydantic\",\n \"celery\",\n \"redis\",\n \"pytest\",\n \"numpy\",\n \"pandas\",\n \"scipy\",\n \"scikit-learn\",\n \"tensorflow\",\n \"torch\",\n \"transformers\",\n \"langchain\",\n \"requests\",\n \"httpx\",\n \"boto3\",\n]);\n\nconst NOTABLE_RUST = new Set([\n \"serde\",\n \"tokio\",\n \"axum\",\n \"actix-web\",\n \"rocket\",\n \"warp\",\n \"hyper\",\n \"sqlx\",\n \"diesel\",\n \"sea-orm\",\n \"clap\",\n \"tracing\",\n \"anyhow\",\n \"thiserror\",\n \"reqwest\",\n \"tonic\",\n \"prost\",\n]);\n\nconst NOTABLE_GO = new Set([\n \"gin\",\n \"echo\",\n \"fiber\",\n \"chi\",\n \"mux\",\n \"gorm\",\n \"sqlx\",\n \"cobra\",\n \"viper\",\n \"zap\",\n \"testify\",\n \"grpc\",\n \"protobuf\",\n \"wire\",\n]);\n\nexport const dependenciesDetector: Detector = {\n name: \"dependencies\",\n category: \"dependencies\",\n\n async detect(ctx: ScanContext) {\n const lockFile = detectLockFile(ctx);\n\n // Node.js — package.json (highest priority)\n const pkgContent = await ctx.readFile(\"package.json\");\n if (pkgContent) {\n try {\n const pkg = JSON.parse(pkgContent);\n const deps = pkg.dependencies || {};\n const devDeps = pkg.devDependencies || {};\n const allDeps = { ...deps, ...devDeps };\n\n const notable = Object.keys(allDeps)\n .filter((d) => NOTABLE_PACKAGES.has(d))\n .sort();\n\n return {\n direct_count: Object.keys(deps).length,\n dev_count: Object.keys(devDeps).length,\n lock_file: lockFile,\n notable,\n };\n } catch {\n // malformed package.json — fall through\n }\n }\n\n // Python — pyproject.toml\n const pyprojectContent = await ctx.readFile(\"pyproject.toml\");\n if (pyprojectContent) {\n const result = parsePyprojectToml(pyprojectContent);\n if (result) {\n const notable = findNotable([...result.direct, ...result.dev], NOTABLE_PYTHON);\n return {\n direct_count: result.direct.length,\n dev_count: result.dev.length,\n lock_file: lockFile,\n notable,\n };\n }\n }\n\n // Python — requirements.txt\n const reqContent = await ctx.readFile(\"requirements.txt\");\n if (reqContent) {\n const names = parseRequirementsTxt(reqContent);\n const notable = findNotable(names, NOTABLE_PYTHON);\n return { direct_count: names.length, dev_count: 0, lock_file: lockFile, notable };\n }\n\n // Rust — Cargo.toml\n const cargoContent = await ctx.readFile(\"Cargo.toml\");\n if (cargoContent) {\n const result = parseCargoToml(cargoContent);\n const notable = findNotable([...result.direct, ...result.dev], NOTABLE_RUST);\n return {\n direct_count: result.direct.length,\n dev_count: result.dev.length,\n lock_file: lockFile,\n notable,\n };\n }\n\n // Go — go.mod\n const goModContent = await ctx.readFile(\"go.mod\");\n if (goModContent) {\n const names = parseGoMod(goModContent);\n const shortNames = names.map((n) => n.split(\"/\").pop()!);\n const notable = findNotable(shortNames, NOTABLE_GO);\n return { direct_count: names.length, dev_count: 0, lock_file: lockFile, notable };\n }\n\n // Ruby — Gemfile\n const rubyResult = await detectRubyDeps(ctx);\n if (rubyResult.direct_count > 0) {\n return { ...rubyResult, lock_file: lockFile };\n }\n\n // PHP — composer.json\n const phpResult = await detectPhpDeps(ctx);\n if (phpResult.direct_count > 0) {\n return { ...phpResult, lock_file: lockFile };\n }\n\n // Java — pom.xml / build.gradle\n const javaResult = await detectJavaDeps(ctx);\n if (javaResult.direct_count > 0) {\n return { ...javaResult, lock_file: lockFile };\n }\n\n // C# — .csproj\n const csharpResult = await detectCSharpDeps(ctx);\n if (csharpResult.direct_count > 0) {\n return { ...csharpResult, lock_file: lockFile };\n }\n\n return { direct_count: 0, dev_count: 0, lock_file: lockFile, notable: [] };\n },\n};\n\nfunction findNotable(names: string[], notableSet: Set<string>): string[] {\n return names.filter((n) => notableSet.has(n)).sort();\n}\n\nfunction parsePyprojectToml(content: string): { direct: string[]; dev: string[] } | null {\n const direct: string[] = [];\n const dev: string[] = [];\n\n // PEP 621: [project] dependencies = [\"flask>=2.0\", ...]\n const pep621Match = content.match(/\\[project\\]\\s[\\s\\S]*?dependencies\\s*=\\s*\\[([\\s\\S]*?)\\]/);\n if (pep621Match) {\n direct.push(...extractQuotedNames(pep621Match[1]));\n }\n\n // PEP 621: [project.optional-dependencies] dev = [\"pytest\", ...]\n const optDepsMatch = content.match(/\\[project\\.optional-dependencies\\]\\s*[\\s\\S]*?(?=\\n\\[|$)/);\n if (optDepsMatch) {\n const arrayMatches = optDepsMatch[0].matchAll(/\\w+\\s*=\\s*\\[([\\s\\S]*?)\\]/g);\n for (const m of arrayMatches) {\n dev.push(...extractQuotedNames(m[1]));\n }\n }\n\n // Poetry: [tool.poetry.dependencies]\n const poetryDepsMatch = content.match(/\\[tool\\.poetry\\.dependencies\\]\\s*\\n([\\s\\S]*?)(?=\\n\\[|$)/);\n if (poetryDepsMatch) {\n const names = extractTomlKeys(poetryDepsMatch[1]);\n direct.push(...names.filter((n) => n !== \"python\"));\n }\n\n // Poetry: [tool.poetry.group.dev.dependencies] or [tool.poetry.dev-dependencies]\n const poetryDevMatch = content.match(\n /\\[tool\\.poetry\\.(?:group\\.dev\\.|dev-)dependencies\\]\\s*\\n([\\s\\S]*?)(?=\\n\\[|$)/\n );\n if (poetryDevMatch) {\n dev.push(...extractTomlKeys(poetryDevMatch[1]));\n }\n\n if (direct.length === 0 && dev.length === 0) {\n return null;\n }\n return { direct, dev };\n}\n\nfunction extractQuotedNames(block: string): string[] {\n const names: string[] = [];\n const matches = block.matchAll(/\"([^\"]+)\"|'([^']+)'/g);\n for (const m of matches) {\n const raw = m[1] || m[2];\n const name = raw\n .split(/[>=<!;\\[]/)[0]\n .trim()\n .toLowerCase();\n if (name) {\n names.push(name);\n }\n }\n return names;\n}\n\nfunction extractTomlKeys(block: string): string[] {\n const names: string[] = [];\n for (const line of block.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n continue;\n }\n const match = trimmed.match(/^([a-zA-Z0-9_-]+)\\s*=/);\n if (match) {\n names.push(match[1].toLowerCase());\n }\n }\n return names;\n}\n\nfunction parseRequirementsTxt(content: string): string[] {\n const names: string[] = [];\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\") || trimmed.startsWith(\"-\")) {\n continue;\n }\n const name = trimmed\n .split(/[>=<!;\\[]/)[0]\n .trim()\n .toLowerCase();\n if (name) {\n names.push(name);\n }\n }\n return names;\n}\n\nfunction parseCargoToml(content: string): { direct: string[]; dev: string[] } {\n const direct: string[] = [];\n const dev: string[] = [];\n\n const depsMatch = content.match(/\\[dependencies\\]\\s*\\n([\\s\\S]*?)(?=\\n\\[|$)/);\n if (depsMatch) {\n direct.push(...extractTomlKeys(depsMatch[1]));\n }\n\n const devDepsMatch = content.match(/\\[dev-dependencies\\]\\s*\\n([\\s\\S]*?)(?=\\n\\[|$)/);\n if (devDepsMatch) {\n dev.push(...extractTomlKeys(devDepsMatch[1]));\n }\n\n return { direct, dev };\n}\n\nfunction parseGoMod(content: string): string[] {\n const names: string[] = [];\n\n // require ( ... ) blocks\n const blockMatches = content.matchAll(/require\\s*\\(([\\s\\S]*?)\\)/g);\n for (const m of blockMatches) {\n for (const line of m[1].split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"//\")) {\n continue;\n }\n const parts = trimmed.split(/\\s+/);\n if (parts[0]) {\n names.push(parts[0]);\n }\n }\n }\n\n // Single-line: require github.com/foo/bar v1.2.3\n const singleMatches = content.matchAll(/^require\\s+(\\S+)[ \\t]+\\S+/gm);\n for (const m of singleMatches) {\n names.push(m[1]);\n }\n\n return names;\n}\n\nasync function detectRubyDeps(\n ctx: ScanContext\n): Promise<{ direct_count: number; dev_count: number; notable: string[] }> {\n const gemfile = await ctx.readFile(\"Gemfile\");\n if (!gemfile) {\n return { direct_count: 0, dev_count: 0, notable: [] };\n }\n\n const deps: string[] = [];\n const notable: string[] = [];\n\n for (const line of gemfile.split(\"\\n\")) {\n const match = line.match(/gem\\s+[\"']([^\"']+)[\"']/);\n if (match) {\n deps.push(match[1]);\n if (NOTABLE_PACKAGES.has(match[1])) {\n notable.push(match[1]);\n }\n }\n }\n\n return {\n direct_count: deps.length,\n dev_count: 0,\n notable: [...new Set(notable)].sort(),\n };\n}\n\nasync function detectPhpDeps(\n ctx: ScanContext\n): Promise<{ direct_count: number; dev_count: number; notable: string[] }> {\n const composer = await ctx.readFile(\"composer.json\");\n if (!composer) {\n return { direct_count: 0, dev_count: 0, notable: [] };\n }\n\n try {\n const pkg = JSON.parse(composer);\n const deps = pkg.require || {};\n const devDeps = pkg[\"require-dev\"] || {};\n const allDeps = { ...deps, ...devDeps };\n\n const notable = Object.keys(allDeps)\n .filter((d) => NOTABLE_PACKAGES.has(d))\n .sort();\n\n return {\n direct_count: Object.keys(deps).length,\n dev_count: Object.keys(devDeps).length,\n notable,\n };\n } catch {\n return { direct_count: 0, dev_count: 0, notable: [] };\n }\n}\n\nasync function detectJavaDeps(\n ctx: ScanContext\n): Promise<{ direct_count: number; dev_count: number; notable: string[] }> {\n const pom = await ctx.readFile(\"pom.xml\");\n const gradle = await ctx.readFile(\"build.gradle\");\n const gradleKts = await ctx.readFile(\"build.gradle.kts\");\n const content = (pom || \"\") + \"\\n\" + (gradle || \"\") + \"\\n\" + (gradleKts || \"\");\n\n if (!content.trim()) {\n return { direct_count: 0, dev_count: 0, notable: [] };\n }\n\n const deps: string[] = [];\n const notable: string[] = [];\n\n const artifactIdRegex = /<artifactId>([^<]+)<\\/artifactId>/g;\n let match;\n while ((match = artifactIdRegex.exec(content)) !== null) {\n deps.push(match[1]);\n if (NOTABLE_PACKAGES.has(match[1])) {\n notable.push(match[1]);\n }\n }\n\n const gradleDepsRegex = /(?:implementation|compile|api)\\s+['\"]([^:'\"]+)/g;\n while ((match = gradleDepsRegex.exec(content)) !== null) {\n const dep = match[1].split(\":\").pop();\n if (dep) {\n deps.push(dep);\n if (NOTABLE_PACKAGES.has(dep)) {\n notable.push(dep);\n }\n }\n }\n\n return {\n direct_count: [...new Set(deps)].length,\n dev_count: 0,\n notable: [...new Set(notable)].sort(),\n };\n}\n\nasync function detectCSharpDeps(\n ctx: ScanContext\n): Promise<{ direct_count: number; dev_count: number; notable: string[] }> {\n const csprojFiles = ctx.files.filter((f) => f.endsWith(\".csproj\"));\n if (csprojFiles.length === 0) {\n return { direct_count: 0, dev_count: 0, notable: [] };\n }\n\n const deps: string[] = [];\n const notable: string[] = [];\n\n for (const file of csprojFiles) {\n const content = await ctx.readFile(file);\n const packageRegex = /<PackageReference\\s+Include=\"([^\"]+)\"/g;\n let match;\n while ((match = packageRegex.exec(content)) !== null) {\n deps.push(match[1]);\n const name = match[1].split(\".\")[0].toLowerCase();\n if (NOTABLE_PACKAGES.has(name)) {\n notable.push(match[1]);\n }\n }\n }\n\n return {\n direct_count: [...new Set(deps)].length,\n dev_count: 0,\n notable: [...new Set(notable)].sort(),\n };\n}\n\nfunction detectLockFile(ctx: ScanContext): string | null {\n // JavaScript/TypeScript\n if (ctx.fileExists(\"pnpm-lock.yaml\")) {\n return \"pnpm-lock.yaml\";\n }\n if (ctx.fileExists(\"yarn.lock\")) {\n return \"yarn.lock\";\n }\n if (ctx.fileExists(\"package-lock.json\")) {\n return \"package-lock.json\";\n }\n if (ctx.fileExists(\"bun.lockb\") || ctx.fileExists(\"bun.lock\")) {\n return \"bun.lock\";\n }\n // Rust\n if (ctx.fileExists(\"Cargo.lock\")) {\n return \"Cargo.lock\";\n }\n // Python\n if (ctx.fileExists(\"poetry.lock\")) {\n return \"poetry.lock\";\n }\n if (ctx.fileExists(\"Pipfile.lock\")) {\n return \"Pipfile.lock\";\n }\n if (ctx.fileExists(\"uv.lock\")) {\n return \"uv.lock\";\n }\n // Go\n if (ctx.fileExists(\"go.sum\")) {\n return \"go.sum\";\n }\n // Ruby\n if (ctx.fileExists(\"Gemfile.lock\")) {\n return \"Gemfile.lock\";\n }\n // PHP\n if (ctx.fileExists(\"composer.lock\")) {\n return \"composer.lock\";\n }\n // Java\n if (ctx.fileExists(\".mvn/jvm.config\")) {\n return \"maven\";\n }\n // Kotlin/Gradle\n if (ctx.fileExists(\".gradle\")) {\n return \"gradle\";\n }\n // Swift\n if (ctx.fileExists(\"Package.resolved\")) {\n return \"swift\";\n }\n // Dart/Flutter\n if (ctx.fileExists(\"pubspec.lock\")) {\n return \"pubspec.lock\";\n }\n // Elixir\n if (ctx.fileExists(\"mix.lock\")) {\n return \"mix.lock\";\n }\n // Scala\n if (ctx.fileExists(\"project/target/resolution-cache\")) {\n return \"sbt\";\n }\n // NuGet (.NET)\n if (ctx.fileExists(\"packages.lock.json\")) {\n return \"nuget\";\n }\n return null;\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nconst KNOWN_CONFIG_FILES = [\n // TypeScript / JavaScript\n \"tsconfig.json\",\n \"jsconfig.json\",\n // Bundlers / Build\n \"tsup.config.ts\",\n \"tsup.config.js\",\n \"next.config.js\",\n \"next.config.mjs\",\n \"next.config.ts\",\n \"vite.config.ts\",\n \"vite.config.js\",\n \"vite.config.mjs\",\n \"webpack.config.js\",\n \"webpack.config.ts\",\n \"rollup.config.js\",\n \"rollup.config.mjs\",\n \"esbuild.config.js\",\n \"esbuild.config.mjs\",\n \"turbo.json\",\n \"nx.json\",\n // Styling\n \"tailwind.config.js\",\n \"tailwind.config.ts\",\n \"tailwind.config.mjs\",\n \"postcss.config.js\",\n \"postcss.config.mjs\",\n \"postcss.config.ts\",\n // Transpilers\n \"babel.config.js\",\n \"babel.config.json\",\n \".babelrc\",\n \"swc.config.json\",\n \".swcrc\",\n // Testing\n \"jest.config.js\",\n \"jest.config.ts\",\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mts\",\n \"playwright.config.ts\",\n \"playwright.config.js\",\n \"cypress.config.ts\",\n \"cypress.config.js\",\n // Linting / Formatting\n \".prettierrc\",\n \".prettierrc.js\",\n \".prettierrc.json\",\n \"prettier.config.js\",\n \"prettier.config.mjs\",\n \".eslintrc.js\",\n \".eslintrc.json\",\n \".eslintrc.yml\",\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.ts\",\n \"biome.json\",\n \"biome.jsonc\",\n \"dprint.json\",\n \".editorconfig\",\n // Containers / Infra\n \"docker-compose.yml\",\n \"docker-compose.yaml\",\n \"compose.yml\",\n \"compose.yaml\",\n \"Dockerfile\",\n \"fly.toml\",\n \"render.yaml\",\n \"vercel.json\",\n \"netlify.toml\",\n // Python\n \"pyproject.toml\",\n \"setup.cfg\",\n \"setup.py\",\n \"tox.ini\",\n \"ruff.toml\",\n \".ruff.toml\",\n // Go\n \"go.mod\",\n // Rust\n \"Cargo.toml\",\n // Ruby\n \"Gemfile\",\n // PHP\n \"composer.json\",\n // Misc\n \"Makefile\",\n \"Taskfile.yml\",\n \".nvmrc\",\n \".node-version\",\n \".python-version\",\n \".ruby-version\",\n \".tool-versions\",\n];\n\nconst FEATURE_FLAG_MARKERS: Record<string, string> = {\n \"launchdarkly-node-server-sdk\": \"launchdarkly\",\n \"@unleash/proxy-client-react\": \"unleash\",\n flagsmith: \"flagsmith\",\n \"@growthbook/growthbook-react\": \"growthbook\",\n};\n\nexport const configDetector: Detector = {\n name: \"config\",\n category: \"config\",\n\n async detect(ctx: ScanContext) {\n const envFiles = ctx.files.filter((f) => f.match(/^\\.env(\\..+)?$/) || f.match(/^\\.env\\./));\n\n const configFiles = KNOWN_CONFIG_FILES.filter((f) => ctx.fileExists(f));\n\n const featureFlags = await detectFeatureFlags(ctx);\n\n const envVars = await detectEnvVars(ctx);\n\n return {\n env_files: envFiles,\n config_files: configFiles,\n feature_flags: featureFlags,\n env_vars: envVars,\n };\n },\n};\n\nasync function detectFeatureFlags(ctx: ScanContext): Promise<string | null> {\n const content = await ctx.readFile(\"package.json\");\n if (!content) {\n return null;\n }\n\n try {\n const pkg = JSON.parse(content);\n const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };\n for (const [dep, name] of Object.entries(FEATURE_FLAG_MARKERS)) {\n if (allDeps[dep]) {\n return name;\n }\n }\n } catch {}\n\n return null;\n}\n\nasync function detectEnvVars(\n ctx: ScanContext\n): Promise<Record<string, { description?: string; required: boolean }>> {\n const envVars: Record<string, { description?: string; required: boolean }> = {};\n\n // Try .env.example first (most common for documentation)\n const envExampleContent = await ctx.readFile(\".env.example\");\n if (envExampleContent) {\n parseEnvFile(envExampleContent, envVars, false); // .env.example vars are typically not marked as required\n }\n\n // Try .env (may have more vars)\n const envContent = await ctx.readFile(\".env\");\n if (envContent) {\n parseEnvFile(envContent, envVars, true);\n }\n\n // Try .env.sample\n const envSampleContent = await ctx.readFile(\".env.sample\");\n if (envSampleContent) {\n parseEnvFile(envSampleContent, envVars, false);\n }\n\n // Try .env.template\n const envTemplateContent = await ctx.readFile(\".env.template\");\n if (envTemplateContent) {\n parseEnvFile(envTemplateContent, envVars, false);\n }\n\n return envVars;\n}\n\nfunction parseEnvFile(\n content: string,\n envVars: Record<string, { description?: string; required: boolean }>,\n isProductionEnv: boolean\n): void {\n const lines = content.split(\"\\n\");\n let currentComment = \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines\n if (!trimmed) {\n continue;\n }\n\n // Capture comments as descriptions\n if (trimmed.startsWith(\"#\")) {\n currentComment += (currentComment ? \" \" : \"\") + trimmed.slice(1).trim();\n continue;\n }\n\n // Parse VAR=value syntax — capture name only, NEVER store the value (security: prevent secret leakage)\n const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)\\s*=\\s*(.*)$/);\n if (match) {\n const [, name, value] = match;\n // Use value only to determine if the var is unset/required — value is never written to manifest\n const isEmpty = value === '\"\"' || value === \"''\" || value === \"\";\n\n envVars[name] = {\n description: currentComment || undefined,\n required: isProductionEnv || isEmpty,\n };\n\n currentComment = \"\"; // Reset comment for next variable\n }\n }\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nexport const gitDetector: Detector = {\n name: \"git\",\n category: \"git\",\n\n async detect(ctx: ScanContext) {\n const [commits, committers, uncommitted] = await Promise.all([\n getRecentCommits(ctx),\n getLastCommitters(ctx),\n hasUncommittedChanges(ctx),\n ]);\n\n return {\n recent_commits: commits,\n last_committers: committers,\n uncommitted_changes: uncommitted,\n };\n },\n};\n\nasync function getRecentCommits(ctx: ScanContext): Promise<string[]> {\n const output = await ctx.exec(\"git\", [\"log\", \"--oneline\", \"-5\", \"--format=%s\"]);\n if (!output) {\n return [];\n }\n return output.split(\"\\n\").filter(Boolean);\n}\n\nasync function getLastCommitters(ctx: ScanContext): Promise<string[]> {\n const output = await ctx.exec(\"git\", [\"shortlog\", \"-sn\", \"--no-merges\", \"-5\"]);\n if (!output) {\n return [];\n }\n return output\n .split(\"\\n\")\n .map((line) => line.replace(/^\\s*\\d+\\s+/, \"\").trim())\n .filter(Boolean);\n}\n\nasync function hasUncommittedChanges(ctx: ScanContext): Promise<boolean> {\n const output = await ctx.exec(\"git\", [\"status\", \"--porcelain\"]);\n return output.length > 0;\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nexport const qualityDetector: Detector = {\n name: \"quality\",\n category: \"quality\",\n\n async detect(ctx: ScanContext) {\n const [test_framework, linter, formatter] = await Promise.all([\n detectTestFramework(ctx),\n detectLinter(ctx),\n detectFormatter(ctx),\n ]);\n\n return {\n test_framework,\n linter,\n formatter,\n ci: detectCI(ctx),\n pre_commit_hooks: detectPreCommitHooks(ctx),\n };\n },\n};\n\nasync function detectTestFramework(ctx: ScanContext): Promise<string | null> {\n // Config-file detection\n if (ctx.glob(\"vitest.config.*\").length > 0) {\n return \"vitest\";\n }\n if (ctx.glob(\"jest.config.*\").length > 0) {\n return \"jest\";\n }\n if (ctx.fileExists(\".mocharc.yml\") || ctx.fileExists(\".mocharc.json\")) {\n return \"mocha\";\n }\n if (ctx.glob(\"playwright.config.*\").length > 0) {\n return \"playwright\";\n }\n if (ctx.glob(\"cypress.config.*\").length > 0) {\n return \"cypress\";\n }\n\n // Fallback: check package.json devDependencies and scripts\n const pkgContent = await ctx.readFile(\"package.json\");\n if (pkgContent) {\n try {\n const pkg = JSON.parse(pkgContent);\n const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };\n const scripts = pkg.scripts || {};\n const testScript = scripts.test || \"\";\n\n if (allDeps[\"vitest\"] || testScript.includes(\"vitest\")) {\n return \"vitest\";\n }\n if (allDeps[\"jest\"] || testScript.includes(\"jest\")) {\n return \"jest\";\n }\n if (allDeps[\"mocha\"] || testScript.includes(\"mocha\")) {\n return \"mocha\";\n }\n if (allDeps[\"@playwright/test\"] || testScript.includes(\"playwright\")) {\n return \"playwright\";\n }\n if (allDeps[\"cypress\"]) {\n return \"cypress\";\n }\n if (allDeps[\"ava\"]) {\n return \"ava\";\n }\n if (allDeps[\"tap\"]) {\n return \"tap\";\n }\n } catch {}\n }\n\n // Python\n if (\n ctx.fileExists(\"pytest.ini\") ||\n ctx.fileExists(\"pyproject.toml\") ||\n ctx.fileExists(\"setup.cfg\") ||\n ctx.fileExists(\"tox.ini\")\n ) {\n const pyproject = await ctx.readFile(\"pyproject.toml\");\n const setupCfg = await ctx.readFile(\"setup.cfg\");\n const pytestIni = await ctx.readFile(\"pytest.ini\");\n if (pyproject?.includes(\"pytest\") || setupCfg?.includes(\"pytest\") || pytestIni) {\n return \"pytest\";\n }\n if (ctx.files.some((f) => f.includes(\"test_\") || f.includes(\"_test.py\"))) {\n return \"pytest\";\n }\n if (pyproject?.includes(\"unittest\") || setupCfg?.includes(\"unittest\")) {\n return \"unittest\";\n }\n if (pyproject?.includes(\"nose\")) {\n return \"nose\";\n }\n }\n // Go\n if (ctx.files.some((f) => f.endsWith(\"_test.go\"))) {\n return \"go test\";\n }\n // Rust\n if (\n ctx.files.some(\n (f) =>\n f.includes(\"/tests/\") ||\n f.startsWith(\"tests/\") ||\n f.endsWith(\"tests.rs\") ||\n f.match(/mod\\s+tests/)\n )\n ) {\n return \"cargo test\";\n }\n // Ruby\n if (ctx.fileExists(\"spec/spec_helper.rb\") || ctx.fileExists(\".rspec\")) {\n return \"rspec\";\n }\n if (ctx.files.some((f) => f.includes(\"/spec/\") && f.endsWith(\"_spec.rb\"))) {\n return \"rspec\";\n }\n if (ctx.fileExists(\"test/minitest_helper.rb\")) {\n return \"minitest\";\n }\n // Java\n if (ctx.files.some((f) => f.endsWith(\"Test.java\") || f.endsWith(\"Tests.java\"))) {\n return \"junit\";\n }\n if (ctx.fileExists(\"pom.xml\")) {\n const pom = await ctx.readFile(\"pom.xml\");\n if (pom?.includes(\"junit\") || pom?.includes(\"testng\")) {\n return pom?.includes(\"testng\") ? \"testng\" : \"junit\";\n }\n }\n // PHP\n if (ctx.fileExists(\"phpunit.xml\") || ctx.fileExists(\"phpunit.xml.dist\")) {\n return \"phpunit\";\n }\n if (ctx.files.some((f) => f.includes(\"tests/\") && f.endsWith(\".php\"))) {\n return \"phpunit\";\n }\n // C#\n if (ctx.files.some((f) => f.endsWith(\"Test.cs\") || f.endsWith(\"Tests.cs\"))) {\n return \"nunit\";\n }\n // Scala\n if (ctx.fileExists(\"build.sbt\")) {\n const build = await ctx.readFile(\"build.sbt\");\n if (build?.includes(\"scalatest\")) {\n return \"scalatest\";\n }\n if (build?.includes(\"specs2\")) {\n return \"specs2\";\n }\n }\n // Swift\n if (ctx.files.some((f) => f.endsWith(\"Tests.swift\") || f.endsWith(\"XCTest.swift\"))) {\n return \"xctest\";\n }\n\n return null;\n}\n\nasync function detectLinter(ctx: ScanContext): Promise<string | null> {\n // Config-file detection\n if (\n ctx.fileExists(\"eslint.config.js\") ||\n ctx.fileExists(\"eslint.config.mjs\") ||\n ctx.fileExists(\"eslint.config.ts\")\n ) {\n return \"eslint\";\n }\n if (ctx.glob(\".eslintrc*\").length > 0) {\n return \"eslint\";\n }\n if (ctx.fileExists(\"biome.json\") || ctx.fileExists(\"biome.jsonc\")) {\n return \"biome\";\n }\n if (ctx.fileExists(\"ruff.toml\") || ctx.fileExists(\".ruff.toml\")) {\n return \"ruff\";\n }\n if (ctx.fileExists(\".pylintrc\") || ctx.fileExists(\"pylintrc\")) {\n return \"pylint\";\n }\n if (ctx.fileExists(\".flake8\") || ctx.fileExists(\"setup.cfg\") || ctx.fileExists(\".flake8rc\")) {\n return \"flake8\";\n }\n if (\n ctx.fileExists(\".golangci.yml\") ||\n ctx.fileExists(\".golangci.yaml\") ||\n ctx.fileExists(\".golangci-lint.yml\")\n ) {\n return \"golangci-lint\";\n }\n if (ctx.fileExists(\"clippy.toml\")) {\n return \"clippy\";\n }\n if (ctx.fileExists(\".rubocop.yml\") || ctx.fileExists(\".rubocop.yaml\")) {\n return \"rubocop\";\n }\n if (\n ctx.fileExists(\".php_cs\") ||\n ctx.fileExists(\"phpstan.neon\") ||\n ctx.fileExists(\"phpunit.xml\")\n ) {\n return \"php-cs-fixer\";\n }\n if (ctx.fileExists(\"psalm.xml\")) {\n return \"psalm\";\n }\n if (ctx.fileExists(\".swiftlint.yml\") || ctx.fileExists(\".swiftlint.yaml\")) {\n return \"swiftlint\";\n }\n if (ctx.fileExists(\".kotlinlint.xml\")) {\n return \"ktlint\";\n }\n if (ctx.fileExists(\"detekt.yml\") || ctx.fileExists(\"detekt.yaml\")) {\n return \"detekt\";\n }\n if (ctx.fileExists(\"checkstyle.xml\")) {\n return \"checkstyle\";\n }\n if (ctx.fileExists(\"pmd.xml\")) {\n return \"pmd\";\n }\n if (ctx.fileExists(\".scalafix.conf\")) {\n return \"scalafix\";\n }\n\n // Check pyproject.toml for Python linters\n const pyproject = await ctx.readFile(\"pyproject.toml\");\n if (pyproject) {\n if (pyproject.includes(\"ruff\")) {\n return \"ruff\";\n }\n if (pyproject.includes(\"pylint\")) {\n return \"pylint\";\n }\n if (pyproject.includes(\"flake8\")) {\n return \"flake8\";\n }\n if (pyproject.includes(\"mypy\")) {\n return \"mypy\";\n }\n if (pyproject.includes(\"black\")) {\n return \"black\";\n }\n }\n\n // Fallback: check package.json\n const pkgContent = await ctx.readFile(\"package.json\");\n if (pkgContent) {\n try {\n const pkg = JSON.parse(pkgContent);\n const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };\n const scripts = pkg.scripts || {};\n const lintScript = scripts.lint || \"\";\n\n if (allDeps[\"eslint\"] || lintScript.includes(\"eslint\")) {\n return \"eslint\";\n }\n if (allDeps[\"@biomejs/biome\"] || lintScript.includes(\"biome\")) {\n return \"biome\";\n }\n if (allDeps[\"oxlint\"] || lintScript.includes(\"oxlint\")) {\n return \"oxlint\";\n }\n if (allDeps[\"standard\"]) {\n return \"standard\";\n }\n if (allDeps[\"xo\"]) {\n return \"xo\";\n }\n if (allDeps[\"@typescript-eslint/eslint-plugin\"]) {\n return \"eslint\";\n }\n if (allDeps[\"dprint\"]) {\n return \"dprint\";\n }\n } catch {}\n }\n\n // Go\n if (ctx.fileExists(\"golangci-lint.yml\") || ctx.fileExists(\".golangci.yml\")) {\n return \"golangci-lint\";\n }\n\n // Rust\n const cargo = await ctx.readFile(\"Cargo.toml\");\n if (cargo?.includes(\"clippy\")) {\n return \"clippy\";\n }\n\n // Ruby\n if (ctx.fileExists(\".rubocop.yml\")) {\n return \"rubocop\";\n }\n\n // PHP\n if (ctx.fileExists(\"phpstan.neon\")) {\n return \"phpstan\";\n }\n if (ctx.fileExists(\"ecs.php\") || ctx.fileExists(\"easy-coding-standard.yml\")) {\n return \"ecs\";\n }\n\n return null;\n}\n\nasync function detectFormatter(ctx: ScanContext): Promise<string | null> {\n // Config-file detection\n if (\n ctx.glob(\".prettierrc*\").length > 0 ||\n ctx.fileExists(\"prettier.config.js\") ||\n ctx.fileExists(\"prettier.config.mjs\") ||\n ctx.fileExists(\"prettier.config.cjs\") ||\n ctx.fileExists(\"prettier.config.ts\")\n ) {\n return \"prettier\";\n }\n if (ctx.fileExists(\"biome.json\") || ctx.fileExists(\"biome.jsonc\")) {\n return \"biome\";\n }\n if (ctx.fileExists(\"ruff.toml\") || ctx.fileExists(\".ruff.toml\")) {\n return \"ruff\";\n }\n if (ctx.fileExists(\"rustfmt.toml\") || ctx.fileExists(\".rustfmt.toml\")) {\n return \"rustfmt\";\n }\n if (ctx.fileExists(\"dprint.json\") || ctx.fileExists(\"dprint.jsonc\")) {\n return \"dprint\";\n }\n if (ctx.fileExists(\".editorconfig\")) {\n return \"editorconfig\";\n }\n if (ctx.fileExists(\".gofmt\")) {\n return \"gofmt\";\n }\n if (ctx.fileExists(\"gofmt.toml\")) {\n return \"gofmt\";\n }\n if (ctx.fileExists(\".scalafmt.conf\")) {\n return \"scalafmt\";\n }\n if (ctx.fileExists(\".black\") || ctx.fileExists(\"pyproject.toml\")) {\n return \"black\";\n }\n if (ctx.fileExists(\".isort.cfg\") || ctx.fileExists(\"pyproject.toml\")) {\n return \"isort\";\n }\n if (ctx.fileExists(\".swiftformat\")) {\n return \"swiftformat\";\n }\n if (ctx.fileExists(\".php-cs-fixer.php\") || ctx.fileExists(\".php-cs-fixer.dist.php\")) {\n return \"php-cs-fixer\";\n }\n if (ctx.fileExists(\".rubocop.yml\")) {\n return \"rubocop\";\n }\n if (ctx.fileExists(\"prettier.config.ts\")) {\n return \"prettier\";\n }\n if (ctx.fileExists(\".prettierignore\")) {\n return \"prettier\";\n }\n\n // Check pyproject.toml for Python formatters\n const pyproject = await ctx.readFile(\"pyproject.toml\");\n if (pyproject) {\n if (pyproject.includes(\"black\")) {\n return \"black\";\n }\n if (pyproject.includes(\"isort\")) {\n return \"isort\";\n }\n if (pyproject.includes(\"autopep8\")) {\n return \"autopep8\";\n }\n if (pyproject.includes(\"yapf\")) {\n return \"yapf\";\n }\n }\n\n // Fallback: check package.json\n const pkgContent = await ctx.readFile(\"package.json\");\n if (pkgContent) {\n try {\n const pkg = JSON.parse(pkgContent);\n const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };\n const scripts = pkg.scripts || {};\n const fmtScript = (scripts.format || \"\") + (scripts.fmt || \"\");\n\n if (allDeps[\"prettier\"] || fmtScript.includes(\"prettier\")) {\n return \"prettier\";\n }\n if (allDeps[\"@biomejs/biome\"] || fmtScript.includes(\"biome\")) {\n return \"biome\";\n }\n if (allDeps[\"dprint\"]) {\n return \"dprint\";\n }\n } catch {}\n }\n\n // Go\n if (ctx.fileExists(\".gofmtrc\") || ctx.fileExists(\"gofmt.toml\")) {\n return \"gofmt\";\n }\n\n // Rust\n if (ctx.fileExists(\"rustfmt.toml\")) {\n return \"rustfmt\";\n }\n\n // Ruby\n if (ctx.fileExists(\".rubocop.yml\")) {\n return \"rubocop\";\n }\n\n // Swift\n if (ctx.fileExists(\".swiftformat\")) {\n return \"swiftformat\";\n }\n\n // Scala\n if (ctx.fileExists(\".scalafmt.conf\")) {\n return \"scalafmt\";\n }\n\n return null;\n}\n\nfunction detectCI(ctx: ScanContext): string | null {\n if (ctx.files.some((f) => f.startsWith(\".github/workflows/\"))) {\n return \"github-actions\";\n }\n if (ctx.fileExists(\".gitlab-ci.yml\") || ctx.fileExists(\".gitlab-ci.yaml\")) {\n return \"gitlab-ci\";\n }\n if (ctx.fileExists(\"Jenkinsfile\") || ctx.fileExists(\"Jenkinsfile\")) {\n return \"jenkins\";\n }\n if (ctx.files.some((f) => f.startsWith(\".circleci/\"))) {\n return \"circleci\";\n }\n if (ctx.fileExists(\"bitbucket-pipelines.yml\")) {\n return \"bitbucket-pipelines\";\n }\n if (ctx.fileExists(\".travis.yml\")) {\n return \"travis-ci\";\n }\n if (ctx.fileExists(\"azure-pipelines.yml\") || ctx.fileExists(\"azure-pipelines.yaml\")) {\n return \"azure-pipelines\";\n }\n if (ctx.fileExists(\"buildspec.yml\")) {\n return \"aws-codebuild\";\n }\n if (ctx.fileExists(\"cloudbuild.yaml\") || ctx.fileExists(\"cloudbuild.yml\")) {\n return \"google-cloud-build\";\n }\n if (ctx.fileExists(\".drone.yml\")) {\n return \"drone-ci\";\n }\n if (ctx.fileExists(\"workflow.yml\")) {\n return \"gsuite-actions\";\n }\n if (ctx.fileExists(\"now.json\") || ctx.fileExists(\".vercelignore\")) {\n return \"vercel\";\n }\n if (ctx.fileExists(\"netlify.toml\")) {\n return \"netlify\";\n }\n if (ctx.fileExists(\".github/workflows/ci.yml\") || ctx.fileExists(\".github/workflows/cd.yml\")) {\n return \"github-actions\";\n }\n if (ctx.fileExists(\"procfile\") || ctx.fileExists(\"Procfile\")) {\n return \"heroku\";\n }\n if (ctx.fileExists(\"appveyor.yml\")) {\n return \"appveyor\";\n }\n if (ctx.fileExists(\"codeship-services.yml\") || ctx.fileExists(\"codeship-steps.yml\")) {\n return \"codeship\";\n }\n if (ctx.fileExists(\"semantic.yml\")) {\n return \"semantic-release\";\n }\n if (ctx.fileExists(\".rerun.yaml\") || ctx.fileExists(\".rerun.yml\")) {\n return \"rerun\";\n }\n if (ctx.fileExists(\"woodpecker.yml\")) {\n return \"woodpecker-ci\";\n }\n if (ctx.fileExists(\".forgejo\")) {\n return \"forgejo\";\n }\n return null;\n}\n\nfunction detectPreCommitHooks(ctx: ScanContext): boolean {\n // Husky\n if (ctx.files.some((f) => f.startsWith(\".husky/\"))) {\n return true;\n }\n // pre-commit framework (Python)\n if (ctx.fileExists(\".pre-commit-config.yaml\") || ctx.fileExists(\".pre-commit-config.yml\")) {\n return true;\n }\n // lint-staged\n if (\n ctx.fileExists(\".lintstagedrc\") ||\n ctx.fileExists(\"lint-staged.config.js\") ||\n ctx.fileExists(\"lint-staged.config.mjs\") ||\n ctx.fileExists(\"lint-staged.config.ts\")\n ) {\n return true;\n }\n // Lefthook\n if (\n ctx.fileExists(\"lefthook.yml\") ||\n ctx.fileExists(\"lefthook.yaml\") ||\n ctx.fileExists(\"lefthook-local.yml\")\n ) {\n return true;\n }\n // pre-commit hooks\n if (ctx.fileExists(\".git/hooks/pre-commit\")) {\n return true;\n }\n // simple-git-hooks\n if (ctx.fileExists(\".simple-git-hooks.cjs\") || ctx.fileExists(\".simple-git-hooks.js\")) {\n return true;\n }\n // yorkie (VueJS)\n if (ctx.fileExists(\".yorkielerc\") || ctx.fileExists(\".yorkie\")) {\n return true;\n }\n // husky 4\n if (\n ctx.fileExists(\".huskyrc\") ||\n ctx.fileExists(\".huskyrc.json\") ||\n ctx.fileExists(\".huskyrc.js\")\n ) {\n return true;\n }\n // pre-commit (Node)\n if (ctx.fileExists(\".pre-commit-hook.json\")) {\n return true;\n }\n return false;\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nconst MODULE_DESCRIPTIONS: Record<string, string> = {\n app: \"routes and pages\",\n api: \"API routes\",\n pages: \"page components\",\n components: \"reusable UI components\",\n lib: \"shared utilities\",\n utils: \"utility functions\",\n helpers: \"helper functions\",\n hooks: \"React hooks\",\n services: \"business logic / services\",\n models: \"data models\",\n controllers: \"request handlers\",\n middleware: \"middleware\",\n routes: \"routing\",\n store: \"state management\",\n stores: \"state stores\",\n types: \"type definitions\",\n interfaces: \"interface definitions\",\n schemas: \"validation schemas\",\n config: \"configuration\",\n constants: \"constants\",\n assets: \"static assets\",\n styles: \"stylesheets\",\n tests: \"test files\",\n __tests__: \"test files\",\n test: \"test files\",\n spec: \"test specifications\",\n features: \"feature modules\",\n modules: \"application modules\",\n plugins: \"plugin system\",\n providers: \"context providers\",\n contexts: \"React contexts\",\n // CLI / tool patterns\n commands: \"CLI commands\",\n cmd: \"CLI commands\",\n cli: \"CLI interface\",\n detectors: \"detection / analysis modules\",\n scanners: \"scanning modules\",\n scanner: \"scanning engine\",\n integrations: \"third-party integrations\",\n adapters: \"adapters / connectors\",\n handlers: \"event / request handlers\",\n resolvers: \"GraphQL resolvers\",\n guards: \"auth / route guards\",\n pipes: \"data transform pipes\",\n decorators: \"decorators\",\n validators: \"validation logic\",\n migrations: \"database migrations\",\n seeds: \"database seed data\",\n fixtures: \"test fixtures\",\n mocks: \"test mocks\",\n stubs: \"test stubs\",\n github: \"GitHub integration\",\n git: \"git integration\",\n mcp: \"MCP server / protocol\",\n server: \"HTTP / API server\",\n client: \"client-side code\",\n core: \"core business logic\",\n domain: \"domain logic\",\n infra: \"infrastructure\",\n db: \"database layer\",\n database: \"database layer\",\n auth: \"authentication / authorization\",\n email: \"email handling\",\n notifications: \"notification system\",\n jobs: \"background jobs / workers\",\n workers: \"background workers\",\n queues: \"job / message queues\",\n events: \"event system\",\n shared: \"shared / cross-cutting code\",\n common: \"common utilities\",\n internal: \"internal modules\",\n pkg: \"packages / library code\",\n proto: \"protobuf definitions\",\n generated: \"auto-generated code\",\n scripts: \"build / utility scripts\",\n tools: \"development tools\",\n docs: \"documentation\",\n};\n\nexport const patternsDetector: Detector = {\n name: \"patterns\",\n category: \"patterns\",\n\n async detect(ctx: ScanContext) {\n return {\n architecture: detectArchitecture(ctx),\n state_management: await detectStateManagement(ctx),\n api_style: await detectApiStyle(ctx),\n key_modules: detectKeyModules(ctx),\n };\n },\n};\n\nfunction detectArchitecture(ctx: ScanContext): string | null {\n // Next.js App Router\n if (ctx.files.some((f) => f.match(/^(src\\/)?app\\/layout\\.(tsx?|jsx?)$/))) {\n return \"app-router\";\n }\n\n // Next.js Pages Router\n if (ctx.files.some((f) => f.match(/^(src\\/)?pages\\/_app\\./))) {\n return \"pages-router\";\n }\n\n // MVC\n if (\n ctx.files.some((f) => f.includes(\"/controllers/\")) &&\n ctx.files.some((f) => f.includes(\"/models/\"))\n ) {\n return \"mvc\";\n }\n\n // Feature-sliced\n if (ctx.files.some((f) => f.startsWith(\"src/features/\"))) {\n return \"feature-sliced\";\n }\n\n // Modular (src/modules/)\n if (ctx.files.some((f) => f.startsWith(\"src/modules/\"))) {\n return \"modular\";\n }\n\n // Layered (services + repositories)\n if (\n ctx.files.some((f) => f.includes(\"/services/\")) &&\n ctx.files.some((f) => f.includes(\"/repositories/\"))\n ) {\n return \"layered\";\n }\n\n // File-based routing (SvelteKit, Remix)\n if (ctx.files.some((f) => f.startsWith(\"src/routes/\"))) {\n return \"file-based-routing\";\n }\n\n // CLI / command-based (src/commands/ or cmd/)\n if (ctx.files.some((f) => f.startsWith(\"src/commands/\") || f.startsWith(\"cmd/\"))) {\n return \"command-based\";\n }\n\n // Plugin / detector architecture\n if (ctx.files.some((f) => f.startsWith(\"src/detectors/\") || f.startsWith(\"src/plugins/\"))) {\n return \"plugin-based\";\n }\n\n // Hexagonal / clean architecture\n if (\n ctx.files.some((f) => f.includes(\"/domain/\")) &&\n ctx.files.some((f) => f.includes(\"/infra/\") || f.includes(\"/infrastructure/\"))\n ) {\n return \"hexagonal\";\n }\n\n // Monolith with clear layers\n if (\n ctx.files.some((f) => f.includes(\"/services/\")) &&\n ctx.files.some((f) => f.includes(\"/handlers/\") || f.includes(\"/controllers/\"))\n ) {\n return \"layered\";\n }\n\n // Package-per-feature (Go-style)\n if (ctx.files.some((f) => f.match(/^internal\\/.+\\/.+/))) {\n return \"package-per-feature\";\n }\n\n return null;\n}\n\nasync function detectStateManagement(ctx: ScanContext): Promise<string | null> {\n const content = await ctx.readFile(\"package.json\");\n if (!content) {\n return null;\n }\n\n try {\n const pkg = JSON.parse(content);\n const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };\n\n const stateLibs: string[] = [];\n if (allDeps[\"zustand\"]) {\n stateLibs.push(\"zustand\");\n }\n if (allDeps[\"@reduxjs/toolkit\"] || allDeps[\"redux\"]) {\n stateLibs.push(\"redux\");\n }\n if (allDeps[\"mobx\"]) {\n stateLibs.push(\"mobx\");\n }\n if (allDeps[\"jotai\"]) {\n stateLibs.push(\"jotai\");\n }\n if (allDeps[\"recoil\"]) {\n stateLibs.push(\"recoil\");\n }\n if (allDeps[\"pinia\"]) {\n stateLibs.push(\"pinia\");\n }\n if (allDeps[\"vuex\"]) {\n stateLibs.push(\"vuex\");\n }\n if (allDeps[\"@tanstack/react-query\"]) {\n stateLibs.push(\"react-query\");\n }\n if (allDeps[\"@tanstack/vue-query\"]) {\n stateLibs.push(\"vue-query\");\n }\n if (allDeps[\"swr\"]) {\n stateLibs.push(\"swr\");\n }\n\n return stateLibs.length > 0 ? stateLibs.join(\" + \") : null;\n } catch {\n return null;\n }\n}\n\nasync function detectApiStyle(ctx: ScanContext): Promise<string | null> {\n const content = await ctx.readFile(\"package.json\");\n const styles: string[] = [];\n\n if (content) {\n try {\n const pkg = JSON.parse(content);\n const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };\n\n if (allDeps[\"@trpc/server\"] || allDeps[\"@trpc/client\"]) {\n styles.push(\"trpc\");\n }\n if (allDeps[\"graphql\"] || allDeps[\"@apollo/server\"]) {\n styles.push(\"graphql\");\n }\n } catch {}\n }\n\n // Check for protobuf files (gRPC)\n if (ctx.glob(\"**/*.proto\").length > 0) {\n styles.push(\"grpc\");\n }\n\n // Check for REST patterns\n if (ctx.files.some((f) => f.match(/\\/api\\/.*route\\.(ts|js)$/))) {\n styles.push(\"route-handlers\");\n }\n if (ctx.files.some((f) => f.includes(\"/routes/\") || f.includes(\"/controllers/\"))) {\n styles.push(\"rest\");\n }\n\n // Check for server actions (Next.js)\n if (ctx.files.some((f) => f.match(/\\/actions?\\.(ts|js)$/))) {\n styles.push(\"server-actions\");\n }\n\n return styles.length > 0 ? styles.join(\" + \") : null;\n}\n\nfunction detectKeyModules(ctx: ScanContext): Record<string, string> {\n const modules: Record<string, string> = {};\n\n // Find src/ subdirectories\n const srcDirs = new Set<string>();\n for (const file of ctx.files) {\n const match = file.match(/^src\\/([^/]+)\\//);\n if (match) {\n srcDirs.add(match[1]);\n }\n }\n\n for (const dir of srcDirs) {\n const description = MODULE_DESCRIPTIONS[dir];\n if (description) {\n modules[`src/${dir}/`] = description;\n }\n }\n\n // Also check top-level dirs\n const topDirs = new Set<string>();\n for (const file of ctx.files) {\n const match = file.match(/^([^/]+)\\//);\n if (match && !match[1].startsWith(\".\") && match[1] !== \"src\" && match[1] !== \"node_modules\") {\n topDirs.add(match[1]);\n }\n }\n\n for (const dir of topDirs) {\n const description = MODULE_DESCRIPTIONS[dir];\n if (description && !modules[`src/${dir}/`]) {\n modules[`${dir}/`] = description;\n }\n }\n\n return modules;\n}\n","import type { Detector, ScanContext } from \"../types.js\";\n\nexport const apiDocsDetector: Detector = {\n name: \"api-docs\",\n category: \"config\",\n\n async detect(ctx: ScanContext): Promise<Record<string, unknown>> {\n const [openApiSpecs, graphqlSchemas, grpcProtos, postmanCollections] = await Promise.all([\n detectOpenAPI(ctx),\n detectGraphQL(ctx),\n detectGRPC(ctx),\n detectPostmanCollections(ctx),\n ]);\n\n return {\n openapi: openApiSpecs,\n graphql: graphqlSchemas,\n grpc: grpcProtos,\n postman: postmanCollections,\n };\n },\n};\n\nasync function detectOpenAPI(ctx: ScanContext): Promise<OpenAPIData | null> {\n const openApiFiles = [\n \"openapi.json\",\n \"openapi.yaml\",\n \"openapi.yml\",\n \"swagger.json\",\n \"swagger.yaml\",\n \"swagger.yml\",\n \"api-specs/openapi.json\",\n \"api-specs/openapi.yaml\",\n \"docs/openapi.json\",\n \"docs/openapi.yaml\",\n \"spec/openapi.json\",\n \"spec/openapi.yaml\",\n \"api/openapi.json\",\n \"api/openapi.yaml\",\n ];\n\n for (const file of openApiFiles) {\n if (ctx.fileExists(file)) {\n const content = await ctx.readFile(file);\n if (content) {\n try {\n const spec = JSON.parse(content);\n if (spec.openapi || spec.swagger) {\n return {\n version: spec.openapi || spec.swagger,\n title: spec.info?.title || null,\n file: file,\n type: spec.openapi ? \"openapi\" : \"swagger\",\n };\n }\n } catch {\n // Try YAML\n if (content.includes(\"openapi:\") || content.includes(\"swagger:\")) {\n return {\n version: extractYAMLField(content, \"openapi\") || extractYAMLField(content, \"swagger\"),\n title: extractYAMLField(content, \"title\"),\n file: file,\n type: content.includes(\"openapi:\") ? \"openapi\" : \"swagger\",\n };\n }\n }\n }\n }\n }\n\n return null;\n}\n\nasync function detectGraphQL(ctx: ScanContext): Promise<GraphQLData | null> {\n const graphqlFiles = ctx.files.filter(\n (f) =>\n f.endsWith(\".graphql\") ||\n f.endsWith(\".gql\") ||\n f.includes(\"/graphql/\") ||\n f.includes(\"/schema/\")\n );\n\n if (graphqlFiles.length === 0) {\n return null;\n }\n\n const schemas: string[] = [];\n const resolvers: string[] = [];\n\n for (const file of graphqlFiles) {\n const content = await ctx.readFile(file);\n if (!content) {\n continue;\n }\n\n if (\n content.includes(\"type Query\") ||\n content.includes(\"type Mutation\") ||\n content.includes(\"type Subscription\")\n ) {\n schemas.push(file);\n }\n if (\n content.includes(\"Query:\") ||\n content.includes(\"Mutation:\") ||\n content.includes(\"resolver\")\n ) {\n resolvers.push(file);\n }\n }\n\n if (schemas.length === 0 && resolvers.length === 0) {\n return null;\n }\n\n return {\n schema_files: schemas,\n resolver_files: resolvers,\n total_files: graphqlFiles.length,\n };\n}\n\nasync function detectGRPC(ctx: ScanContext): Promise<GRPCData | null> {\n const protoFiles = ctx.files.filter((f) => f.endsWith(\".proto\"));\n\n if (protoFiles.length === 0) {\n return null;\n }\n\n const services: string[] = [];\n\n for (const file of protoFiles) {\n const content = await ctx.readFile(file);\n if (!content) {\n continue;\n }\n\n if (content.includes(\"service \")) {\n services.push(file);\n }\n }\n\n return {\n proto_files: protoFiles,\n service_definitions: services,\n };\n}\n\nasync function detectPostmanCollections(ctx: ScanContext): Promise<PostmanData | null> {\n const postmanFiles = ctx.files.filter(\n (f) => f.includes(\"postman\") && (f.endsWith(\".json\") || f.endsWith(\".json.backup\"))\n );\n\n if (postmanFiles.length === 0) {\n return null;\n }\n\n const collections: Array<{ file: string; name: string | null }> = [];\n\n for (const file of postmanFiles) {\n const content = await ctx.readFile(file);\n if (!content) {\n continue;\n }\n\n try {\n const json = JSON.parse(content);\n if (json.info?.schema?.includes(\"postman\")) {\n collections.push({\n file: file,\n name: (json.info?.name as string | undefined) || null,\n });\n }\n } catch {}\n }\n\n if (collections.length === 0) {\n return null;\n }\n\n return {\n collections: collections,\n };\n}\n\nfunction extractYAMLField(content: string, field: string): string | null {\n const regex = new RegExp(`^${field}:\\\\s*(.+)$`, \"m\");\n const match = content.match(regex);\n return match ? match[1].trim() : null;\n}\n\ninterface OpenAPIData {\n version: string | null;\n title: string | null;\n file: string;\n type: \"openapi\" | \"swagger\";\n}\n\ninterface GraphQLData {\n schema_files: string[];\n resolver_files: string[];\n total_files: number;\n}\n\ninterface GRPCData {\n proto_files: string[];\n service_definitions: string[];\n}\n\ninterface PostmanData {\n collections: Array<{ file: string; name: string | null }>;\n}\n","import type { Detector } from \"../types.js\";\nimport { projectDetector } from \"./project.js\";\nimport { repoDetector } from \"./repo.js\";\nimport { structureDetector } from \"./structure.js\";\nimport { stackDetector } from \"./stack.js\";\nimport { commandsDetector } from \"./commands.js\";\nimport { dependenciesDetector } from \"./dependencies.js\";\nimport { configDetector } from \"./config.js\";\nimport { gitDetector } from \"./git.js\";\nimport { qualityDetector } from \"./quality.js\";\nimport { patternsDetector } from \"./patterns.js\";\nimport { apiDocsDetector } from \"./api-docs.js\";\n\nexport const detectors: Detector[] = [\n projectDetector,\n repoDetector,\n structureDetector,\n stackDetector,\n commandsDetector,\n dependenciesDetector,\n configDetector,\n gitDetector,\n qualityDetector,\n patternsDetector,\n apiDocsDetector,\n];\n","export const MAX_TITLE_LEN = 200;\nexport const MAX_LABEL_LEN = 50;\nexport const MAX_LOGIN_LEN = 100;\n\nexport function safe(s: string | null | undefined, max: number): string {\n if (!s) {\n return \"\";\n }\n return String(s).slice(0, max);\n}\n","import { execFile } from \"node:child_process\";\nimport { warn } from \"../utils/output.js\";\nimport { safe, MAX_TITLE_LEN, MAX_LABEL_LEN, MAX_LOGIN_LEN } from \"../utils/safe.js\";\n\n/**\n * GraphQL client for GitHub API using gh CLI\n * Provides proper error handling and fallbacks\n */\n\ninterface GraphQLResponse<T> {\n data?: T;\n errors?: Array<{ message: string; type?: string }>;\n}\n\ninterface GraphQLVariables {\n [key: string]: string | number | boolean | null;\n}\n\n/**\n * Execute a GraphQL query via gh CLI\n */\nasync function graphqlQuery<T>(\n cwd: string,\n query: string,\n variables: GraphQLVariables = {}\n): Promise<T | null> {\n return new Promise((resolve) => {\n const args = [\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-H\",\n \"Accept: application/vnd.github.v3+json\",\n ];\n\n // Add variables as separate -F flags\n for (const [key, value] of Object.entries(variables)) {\n args.push(\"-f\", `${key}=${JSON.stringify(value)}`);\n }\n\n execFile(\"gh\", args, { cwd, timeout: 30_000 }, (err, stdout, _stderr) => {\n if (err) {\n // Silently fail - caller should use fallback\n resolve(null);\n return;\n }\n\n try {\n const response = JSON.parse(stdout.trim()) as GraphQLResponse<T>;\n\n if (response.errors && response.errors.length > 0) {\n // Log but don't throw - allow fallback\n // console.error('GraphQL errors:', response.errors);\n resolve(null);\n return;\n }\n\n resolve(response.data || null);\n } catch {\n resolve(null);\n }\n });\n });\n}\n\n// ─── Queries ─────────────────────────────────────────────────────────\n\nconst ISSUES_QUERY = `\nquery($owner: String!, $repo: String!, $limit: Int) {\n repository(owner: $owner, name: $repo) {\n issues(first: $limit, orderBy: {field: UPDATED_AT, direction: DESC}) {\n nodes {\n number\n title\n state\n url\n labels(first: 10) { nodes { name } }\n assignees(first: 1) { nodes { login } }\n milestone { title }\n body\n createdAt\n updatedAt\n comments { totalCount }\n reactions {\n thumbsUp: reactionCount(for: THUMBS_UP)\n thumbsDown: reactionCount(for: THUMBS_DOWN)\n laugh: reactionCount(for: LAUGH)\n hooray: reactionCount(for: HOORAY)\n confused: reactionCount(for: CONFUSED)\n heart: reactionCount(for: HEART)\n rocket: reactionCount(for: ROCKET)\n eyes: reactionCount(for: EYES)\n }\n timelineItems(first: 1) { totalCount }\n }\n }\n }\n}\n`;\n\nconst PULL_REQUESTS_QUERY = `\nquery($owner: String!, $repo: String!, $limit: Int) {\n repository(owner: $owner, name: $repo) {\n pullRequests(first: $limit, orderBy: {field: UPDATED_AT, direction: DESC}) {\n nodes {\n number\n title\n state\n url\n author { login }\n headRefName\n labels(first: 10) { nodes { name } }\n reviewRequests(first: 5) { nodes { requestedReviewer { ... on User { login } } } }\n createdAt\n updatedAt\n additions\n deletions\n mergeable\n comments { totalCount }\n reviewDecision\n statusCheckRollup {\n state\n }\n }\n }\n }\n}\n`;\n\nconst MILESTONES_QUERY = `\nquery($owner: String!, $repo: String!) {\n repository(owner: $owner, name: $repo) {\n milestones(first: 20, orderBy: {field: DUE_DATE, direction: ASC}) {\n nodes {\n title\n description\n dueOn\n issues(first: 100) {\n totalCount\n nodes { number }\n }\n closedIssues: issues(states: CLOSED) { totalCount }\n }\n }\n }\n}\n`;\n\nconst RELEASES_QUERY = `\nquery($owner: String!, $repo: String!, $limit: Int) {\n repository(owner: $owner, name: $repo) {\n releases(first: $limit, orderBy: {field: CREATED_AT, direction: DESC}) {\n nodes {\n tagName\n name\n url\n createdAt\n isPrerelease\n author { login }\n }\n }\n }\n}\n`;\n\nconst PROJECTS_QUERY = `\nquery($owner: String!, $repo: String!) {\n repository(owner: $owner, name: $repo) {\n projectsV2(first: 10) {\n nodes {\n number\n title\n state\n url\n columns: fieldNodes(first: 20) {\n nodes {\n ... on ProjectV2FieldCommon {\n name\n }\n ... on ProjectV2SingleSelectField {\n options {\n name\n }\n }\n }\n }\n items(first: 100) {\n totalCount\n }\n }\n }\n }\n}\n`;\n\n// ─── Parsers ───────────────────────────────────────────────────────\n\nfunction parseOwnerRepo(remoteUrl: string): { owner: string; repo: string } | null {\n // Parse GitHub remote URL to extract owner and repo\n const patterns = [/github\\.com[:/]([^/]+)\\/(.+?)(\\.git)?$/, /github\\.com[:/]([^/]+)\\/(.+)$/];\n\n for (const pattern of patterns) {\n const match = remoteUrl.match(pattern);\n if (match) {\n return { owner: match[1], repo: match[2].replace(/\\.git$/, \"\") };\n }\n }\n\n return null;\n}\n\nfunction parseIssueNode(node: Record<string, unknown>): ReturnType<\n typeof import(\"./sync\").parseIssue\n> & {\n comments_count?: number;\n reactions?: {\n thumbs_up: number;\n thumbs_down: number;\n laugh: number;\n hooray: number;\n confused: number;\n heart: number;\n rocket: number;\n eyes: number;\n };\n timeline_events?: number;\n url?: string;\n} {\n const labels = (node.labels as { nodes: Array<{ name: string }> })?.nodes || [];\n const assignees = (node.assignees as { nodes: Array<{ login: string }> })?.nodes || [];\n const milestone = node.milestone as { title: string } | null;\n const reactions = (node.reactions as Record<string, number>) || {};\n const comments = node.comments as { totalCount: number } | null;\n const timeline = node.timelineItems as { totalCount: number } | null;\n\n return {\n number: node.number as number,\n title: safe(node.title as string, MAX_TITLE_LEN),\n state: (node.state as string)?.toLowerCase() === \"open\" ? \"open\" : \"closed\",\n url: (node.url as string) || undefined,\n labels: labels.map((l) => safe(l.name, MAX_LABEL_LEN)).filter(Boolean),\n assignee: safe(assignees[0]?.login, MAX_LOGIN_LEN) || null,\n milestone: milestone?.title || null,\n created_at: node.createdAt as string,\n updated_at: node.updatedAt as string,\n comments_count: comments?.totalCount || 0,\n reactions: {\n thumbs_up: reactions.thumbsUp || 0,\n thumbs_down: reactions.thumbsDown || 0,\n laugh: reactions.laugh || 0,\n hooray: reactions.hooray || 0,\n confused: reactions.confused || 0,\n heart: reactions.heart || 0,\n rocket: reactions.rocket || 0,\n eyes: reactions.eyes || 0,\n },\n timeline_events: timeline?.totalCount || 0,\n body: safe((node.body as string) || \"\", 2000),\n };\n}\n\nfunction parsePRNode(node: Record<string, unknown>): ReturnType<typeof import(\"./sync\").parsePR> & {\n checks_status?: \"pending\" | \"passing\" | \"failing\";\n mergeable?: boolean;\n merge_conflicts?: boolean;\n additions?: number;\n deletions?: number;\n comments_count?: number;\n review_decision?: \"approved\" | \"changes_requested\" | \"review_required\" | null;\n url?: string;\n} {\n const labels = (node.labels as { nodes: Array<{ name: string }> })?.nodes || [];\n const reviewRequests =\n (node.reviewRequests as { nodes: Array<{ requestedReviewer?: { login?: string } }> })?.nodes ||\n [];\n const author = node.author as { login: string } | null;\n const statusCheck = node.statusCheckRollup as { state: string } | null;\n const comments = node.comments as { totalCount: number } | null;\n\n let checksStatus: \"pending\" | \"passing\" | \"failing\" | undefined;\n if (statusCheck?.state) {\n const state = statusCheck.state.toLowerCase();\n if (state === \"success\" || state === \"completed\") {\n checksStatus = \"passing\";\n } else if (state === \"failure\" || state === \"error\") {\n checksStatus = \"failing\";\n } else {\n checksStatus = \"pending\";\n }\n }\n\n const mergeable = (node.mergeable as string) === \"MERGEABLE\";\n const mergeConflicts = (node.mergeable as string) === \"CONFLICTING\";\n\n return {\n number: node.number as number,\n title: safe(node.title as string, MAX_TITLE_LEN),\n state: ((node.state as string) || \"open\").toLowerCase() as \"open\" | \"closed\" | \"merged\",\n url: (node.url as string) || undefined,\n author: safe(author?.login, MAX_LOGIN_LEN) || \"unknown\",\n branch: safe(node.headRefName as string, MAX_TITLE_LEN),\n labels: labels.map((l) => safe(l.name, MAX_LABEL_LEN)).filter(Boolean),\n reviewers: reviewRequests\n .map((r) => safe(r.requestedReviewer?.login, MAX_LOGIN_LEN))\n .filter(Boolean),\n created_at: node.createdAt as string,\n updated_at: node.updatedAt as string,\n checks_status: checksStatus,\n mergeable,\n merge_conflicts: mergeConflicts,\n additions: (node.additions as number) || 0,\n deletions: (node.deletions as number) || 0,\n comments_count: comments?.totalCount || 0,\n review_decision:\n (node.reviewDecision as string)?.toLowerCase() === \"approved\"\n ? \"approved\"\n : (node.reviewDecision as string)?.toLowerCase() === \"changes_requested\"\n ? \"changes_requested\"\n : (node.reviewDecision as string)?.toLowerCase() === \"review_required\"\n ? \"review_required\"\n : null,\n };\n}\n\n// ─── Public API ─────────────────────────────────────────────────────\n\nexport interface GitHubGraphQLData {\n issues?: ReturnType<typeof parseIssueNode>[];\n pull_requests?: ReturnType<typeof parsePRNode>[];\n milestones?: Array<{\n title: string;\n description: string;\n due_date: string | null;\n progress: { open: number; closed: number; percent: number };\n issues: number[];\n }>;\n releases?: Array<{\n tag_name: string;\n name: string;\n created_at: string;\n url: string;\n author: string;\n prerelease: boolean;\n }>;\n project_boards?: Array<{\n number: number;\n title: string;\n state: \"open\" | \"closed\";\n columns: Array<{ name: string; cards_count: number }>;\n url: string;\n }>;\n}\n\n/**\n * Fetch comprehensive GitHub data using GraphQL\n * Falls back gracefully if GraphQL fails\n */\nexport async function fetchGitHubGraphQLData(\n cwd: string,\n remoteUrl: string,\n options: {\n includeIssues?: boolean;\n includePRs?: boolean;\n includeMilestones?: boolean;\n includeReleases?: boolean;\n includeProjects?: boolean;\n limit?: number;\n } = {}\n): Promise<GitHubGraphQLData> {\n const {\n includeIssues = true,\n includePRs = true,\n includeMilestones = true,\n includeReleases = true,\n includeProjects = true,\n limit = 50,\n } = options;\n\n const ownerRepo = parseOwnerRepo(remoteUrl);\n if (!ownerRepo) {\n return {};\n }\n\n const { owner, repo } = ownerRepo;\n const result: GitHubGraphQLData = {};\n\n // Run all independent queries in parallel\n const [issueData, prData, milestoneData, releaseData, projectData] = await Promise.all([\n includeIssues\n ? graphqlQuery<{ repository: { issues: { nodes: Record<string, unknown>[] } } }>(\n cwd,\n ISSUES_QUERY,\n { owner, repo, limit }\n ).catch((e: unknown) => {\n warn(`GitHub issues query failed: ${e instanceof Error ? e.message : String(e)}`);\n return null;\n })\n : Promise.resolve(null),\n includePRs\n ? graphqlQuery<{ repository: { pullRequests: { nodes: Record<string, unknown>[] } } }>(\n cwd,\n PULL_REQUESTS_QUERY,\n { owner, repo, limit: Math.min(limit, 30) }\n ).catch((e: unknown) => {\n warn(`GitHub pull requests query failed: ${e instanceof Error ? e.message : String(e)}`);\n return null;\n })\n : Promise.resolve(null),\n includeMilestones\n ? graphqlQuery<{ repository: { milestones: { nodes: Record<string, unknown>[] } } }>(\n cwd,\n MILESTONES_QUERY,\n { owner, repo }\n ).catch((e: unknown) => {\n warn(`GitHub milestones query failed: ${e instanceof Error ? e.message : String(e)}`);\n return null;\n })\n : Promise.resolve(null),\n includeReleases\n ? graphqlQuery<{ repository: { releases: { nodes: Record<string, unknown>[] } } }>(\n cwd,\n RELEASES_QUERY,\n { owner, repo, limit: 10 }\n ).catch((e: unknown) => {\n warn(`GitHub releases query failed: ${e instanceof Error ? e.message : String(e)}`);\n return null;\n })\n : Promise.resolve(null),\n includeProjects\n ? graphqlQuery<{ repository: { projectsV2: { nodes: Record<string, unknown>[] } } }>(\n cwd,\n PROJECTS_QUERY,\n { owner, repo }\n ).catch((e: unknown) => {\n warn(`GitHub projects query failed: ${e instanceof Error ? e.message : String(e)}`);\n return null;\n })\n : Promise.resolve(null),\n ]);\n\n // Process issues\n if (issueData?.repository?.issues?.nodes) {\n result.issues = issueData.repository.issues.nodes.map(parseIssueNode);\n }\n\n // Process pull requests\n if (prData?.repository?.pullRequests?.nodes) {\n result.pull_requests = prData.repository.pullRequests.nodes.map(parsePRNode);\n }\n\n // Process milestones\n if (milestoneData?.repository?.milestones?.nodes) {\n result.milestones = milestoneData.repository.milestones.nodes.map((m) => {\n const issues = (m.issues as { nodes: Array<{ number: number }> })?.nodes || [];\n const closed = (m.closedIssues as { totalCount: number })?.totalCount || 0;\n const total = (m.issues as { totalCount: number })?.totalCount || issues.length;\n const open = total - closed;\n\n return {\n title: m.title as string,\n description: (m.description as string) || \"\",\n due_date: (m.dueOn as string) || null,\n progress: {\n open,\n closed,\n percent: total > 0 ? Math.round((closed / total) * 100) : 0,\n },\n issues: issues.map((i) => i.number),\n };\n });\n }\n\n // Process releases\n if (releaseData?.repository?.releases?.nodes) {\n result.releases = releaseData.repository.releases.nodes.map((r) => ({\n tag_name: r.tagName as string,\n name: (r.name as string) || (r.tagName as string),\n created_at: r.createdAt as string,\n url: r.url as string,\n author: (r.author as { login: string })?.login || \"unknown\",\n prerelease: !!r.isPrerelease,\n }));\n }\n\n // Process project boards\n if (projectData?.repository?.projectsV2?.nodes) {\n result.project_boards = projectData.repository.projectsV2.nodes\n .filter((p) => p !== null)\n .map((p) => {\n const columns = (p.columns as { nodes: Array<{ name: string }> })?.nodes || [];\n const itemsCount = (p.items as { totalCount: number })?.totalCount || 0;\n\n return {\n number: p.number as number,\n title: p.title as string,\n state: ((p.state as string) || \"open\").toLowerCase() as \"open\" | \"closed\",\n url: p.url as string,\n columns: columns.map((c) => ({\n name: c.name,\n cards_count: itemsCount, // Approximate - actual per-column count requires more complex query\n })),\n };\n });\n }\n\n return result;\n}\n\n/**\n * Check if gh CLI supports GraphQL (requires gh >= 2.0)\n */\nexport async function checkGraphQLSupport(cwd: string): Promise<boolean> {\n return new Promise((resolve) => {\n execFile(\"gh\", [\"--version\"], { cwd, timeout: 5000 }, (err, stdout) => {\n if (err) {\n resolve(false);\n return;\n }\n\n const match = stdout.match(/gh version (\\d+)\\.(\\d+)/);\n if (match) {\n const major = parseInt(match[1], 10);\n const minor = parseInt(match[2], 10);\n // GraphQL support added in gh 2.0\n resolve(major > 2 || (major === 2 && minor >= 0));\n } else {\n resolve(false);\n }\n });\n });\n}\n","import { execFile } from \"node:child_process\";\nimport { readdirSync, readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type {\n StatusData,\n RoadmapData,\n DecisionsData,\n IssueData,\n PullRequestData,\n KanbanView,\n MilestoneData,\n DecisionEntry,\n ReleaseData,\n ProjectBoardData,\n} from \"../types.js\";\nimport { fetchGitHubGraphQLData, checkGraphQLSupport } from \"./graphql.js\";\nimport { safe, MAX_TITLE_LEN, MAX_LABEL_LEN, MAX_LOGIN_LEN } from \"../utils/safe.js\";\n\ninterface GitHubData {\n status: StatusData;\n roadmap: RoadmapData;\n decisions: DecisionsData;\n}\n\nexport async function syncGitHub(root: string): Promise<GitHubData | null> {\n // Check if `gh` CLI is available\n const ghAvailable = await ghExec(root, [\"--version\"]);\n if (!ghAvailable) {\n return null;\n }\n\n // Check if repo has a GitHub remote — if not, github_available should be false\n const remoteUrl = await shellExec(root, \"git\", [\"remote\", \"get-url\", \"origin\"]);\n const hasGitHubRemote =\n !!remoteUrl && (remoteUrl.includes(\"github.com\") || remoteUrl.includes(\"github.\"));\n\n if (!hasGitHubRemote) {\n return {\n status: {\n synced_at: new Date().toISOString(),\n github_available: false,\n issues: [],\n pull_requests: [],\n kanban: { backlog: [], in_progress: [], needs_verify: [], done: [] },\n priorities: [],\n },\n roadmap: { milestones: [] },\n decisions: { from_prs: [], from_adrs: [], manual: [] },\n };\n }\n\n // Check GitHub API rate limit before making requests\n const rateLimitOk = await checkRateLimit(root);\n if (!rateLimitOk) {\n return null;\n }\n\n // Try GraphQL first, fall back to REST API\n const hasGraphQL = await checkGraphQLSupport(root);\n let issues: IssueData[] = [];\n let prs: PullRequestData[] = [];\n let milestones: MilestoneData[] = [];\n let releases: ReleaseData[] = [];\n let projectBoards: ProjectBoardData[] = [];\n // Track whether GraphQL succeeded so we don't double-fetch on empty repos\n let graphqlSucceeded = false;\n\n if (hasGraphQL) {\n try {\n const graphqlData = await fetchGitHubGraphQLData(root, remoteUrl, {\n includeIssues: true,\n includePRs: true,\n includeMilestones: true,\n includeReleases: true,\n includeProjects: true,\n limit: 50,\n });\n\n issues = (graphqlData.issues || []) as IssueData[];\n prs = (graphqlData.pull_requests || []) as PullRequestData[];\n milestones = (graphqlData.milestones || []) as unknown as MilestoneData[];\n releases = (graphqlData.releases || []) as ReleaseData[];\n projectBoards = (graphqlData.project_boards || []) as ProjectBoardData[];\n graphqlSucceeded = true;\n } catch {\n // GraphQL failed, fall back to REST\n }\n }\n\n // Fallback to REST API only if GraphQL itself failed (not just returned empty data)\n if (!graphqlSucceeded) {\n issues = await fetchIssues(root);\n prs = await fetchPullRequests(root);\n milestones = await fetchMilestones(root);\n }\n\n const [decisionPRs] = await Promise.all([fetchDecisionPRs(root)]);\n\n const kanban = buildKanban(issues);\n const priorities = buildPriorities(issues);\n const adrDecisions = findADRFiles(root);\n\n return {\n status: {\n synced_at: new Date().toISOString(),\n github_available: true,\n issues,\n pull_requests: prs,\n kanban,\n priorities,\n releases,\n project_boards: projectBoards,\n },\n roadmap: {\n milestones,\n },\n decisions: {\n from_prs: decisionPRs,\n from_adrs: adrDecisions,\n manual: [],\n },\n };\n}\n\n// ─── GitHub CLI wrapper ──────────────────────────────────────────\n\nfunction ghExec(cwd: string, args: string[]): Promise<string> {\n return new Promise((resolve) => {\n execFile(\"gh\", args, { cwd, timeout: 30_000 }, (err, stdout) => {\n resolve(err ? \"\" : stdout.trim());\n });\n });\n}\n\nfunction shellExec(cwd: string, cmd: string, args: string[]): Promise<string> {\n return new Promise((resolve) => {\n execFile(cmd, args, { cwd, timeout: 10_000 }, (err, stdout) => {\n resolve(err ? \"\" : stdout.trim());\n });\n });\n}\n\nasync function checkRateLimit(root: string): Promise<boolean> {\n try {\n const output = await ghExec(root, [\"api\", \"rate_limit\"]);\n if (!output) {\n return true;\n } // Can't check — proceed optimistically\n const data = JSON.parse(output) as {\n resources?: { core?: { remaining?: number } };\n };\n const remaining = data.resources?.core?.remaining ?? 100;\n return remaining > 10; // Require at least 10 requests remaining\n } catch {\n return true; // Can't check — proceed optimistically\n }\n}\n\n// ─── Issues ──────────────────────────────────────────────────────\n\nasync function fetchIssues(root: string): Promise<IssueData[]> {\n const output = await ghExec(root, [\n \"issue\",\n \"list\",\n \"--limit\",\n \"50\",\n \"--state\",\n \"all\",\n \"--json\",\n \"number,title,state,labels,assignees,milestone,createdAt,updatedAt\",\n ]);\n if (!output) {\n return [];\n }\n\n try {\n const raw = JSON.parse(output) as Array<Record<string, unknown>>;\n return raw.map(parseIssue);\n } catch {\n return [];\n }\n}\n\nexport function parseIssue(raw: Record<string, unknown>): IssueData {\n const labels = (raw.labels as Array<{ name: string }>) || [];\n const assignees = (raw.assignees as Array<{ login: string }>) || [];\n const milestone = raw.milestone as { title: string } | null;\n const body = (raw.body as string) || \"\";\n\n return {\n number: raw.number as number,\n title: safe(raw.title as string, MAX_TITLE_LEN),\n state: (raw.state as string)?.toLowerCase() === \"open\" ? \"open\" : \"closed\",\n labels: labels.map((l) => safe(l.name, MAX_LABEL_LEN)).filter(Boolean),\n assignee: safe(assignees[0]?.login, MAX_LOGIN_LEN) || null,\n milestone: safe(milestone?.title, MAX_TITLE_LEN) || null,\n created_at: raw.createdAt as string,\n updated_at: raw.updatedAt as string,\n effort: parseEffort(body),\n body: safe((raw.body as string) || \"\", 2000),\n };\n}\n\n/** Extract effort estimate from structured issue body: **Effort:** S|M|L */\nfunction parseEffort(body: string): \"S\" | \"M\" | \"L\" | undefined {\n const match = body.match(/\\*\\*Effort:\\*\\*\\s*([SML])\\b/i);\n if (!match) {\n return undefined;\n }\n const v = match[1].toUpperCase();\n if (v === \"S\" || v === \"M\" || v === \"L\") {\n return v;\n }\n return undefined;\n}\n\n// ─── Pull Requests ───────────────────────────────────────────────\n\nasync function fetchPullRequests(root: string): Promise<PullRequestData[]> {\n const output = await ghExec(root, [\n \"pr\",\n \"list\",\n \"--limit\",\n \"30\",\n \"--state\",\n \"all\",\n \"--json\",\n \"number,title,state,author,headRefName,labels,reviewRequests,createdAt,updatedAt\",\n ]);\n if (!output) {\n return [];\n }\n\n try {\n const raw = JSON.parse(output) as Array<Record<string, unknown>>;\n return raw.map(parsePR);\n } catch {\n return [];\n }\n}\n\nconst MAX_BRANCH_LEN = 200;\n\nexport function parsePR(raw: Record<string, unknown>): PullRequestData {\n const labels = (raw.labels as Array<{ name: string }>) || [];\n const reviewRequests = (raw.reviewRequests as Array<{ login?: string; name?: string }>) || [];\n const author = raw.author as { login: string } | null;\n\n return {\n number: raw.number as number,\n title: safe(raw.title as string, MAX_TITLE_LEN),\n state: ((raw.state as string) || \"open\").toLowerCase() as \"open\" | \"closed\" | \"merged\",\n author: safe(author?.login, MAX_LOGIN_LEN) || \"unknown\",\n branch: safe(raw.headRefName as string, MAX_BRANCH_LEN),\n labels: labels.map((l) => safe(l.name, MAX_LABEL_LEN)).filter(Boolean),\n reviewers: reviewRequests.map((r) => safe(r.login || r.name, MAX_LOGIN_LEN)).filter(Boolean),\n created_at: raw.createdAt as string,\n updated_at: raw.updatedAt as string,\n };\n}\n\n// ─── Milestones ──────────────────────────────────────────────────\n\nasync function fetchMilestones(root: string): Promise<MilestoneData[]> {\n const output = await ghExec(root, [\n \"api\",\n \"repos/{owner}/{repo}/milestones\",\n \"--jq\",\n \".[] | {title,description,due_on,open_issues,closed_issues}\",\n ]);\n if (!output) {\n return [];\n }\n\n try {\n const lines = output.split(\"\\n\").filter(Boolean);\n return lines.map((line) => {\n const m = JSON.parse(line);\n const open = m.open_issues || 0;\n const closed = m.closed_issues || 0;\n const total = open + closed;\n return {\n title: m.title,\n description: m.description || \"\",\n due_date: m.due_on || null,\n progress: {\n open,\n closed,\n percent: total > 0 ? Math.round((closed / total) * 100) : 0,\n },\n issues: [],\n };\n });\n } catch {\n return [];\n }\n}\n\n// ─── Decisions from PRs ──────────────────────────────────────────\n\nasync function fetchDecisionPRs(root: string): Promise<DecisionEntry[]> {\n const output = await ghExec(root, [\n \"pr\",\n \"list\",\n \"--limit\",\n \"20\",\n \"--state\",\n \"merged\",\n \"--json\",\n \"number,title,body,mergedAt,url\",\n ]);\n if (!output) {\n return [];\n }\n\n try {\n const raw = JSON.parse(output) as Array<Record<string, unknown>>;\n return raw\n .filter((pr) => {\n const body = (pr.body as string) || \"\";\n // Look for decision markers in PR body\n return (\n body.toLowerCase().includes(\"decision\") ||\n body.toLowerCase().includes(\"why:\") ||\n body.toLowerCase().includes(\"rationale\") ||\n body.toLowerCase().includes(\"chose\") ||\n body.toLowerCase().includes(\"trade-off\")\n );\n })\n .map((pr) => ({\n title: safe(pr.title as string, MAX_TITLE_LEN),\n summary: extractDecisionSummary((pr.body as string) || \"\"),\n date: pr.mergedAt as string,\n source: `PR #${pr.number}`,\n url: pr.url as string,\n }));\n } catch {\n return [];\n }\n}\n\nfunction extractDecisionSummary(body: string): string {\n // Try to extract a summary from the PR body\n const lines = body.split(\"\\n\").filter((l) => l.trim());\n\n // Look for \"## Decision\" or \"## Why\" sections\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].match(/^#+\\s*(decision|why|rationale)/i)) {\n const summary = lines\n .slice(i + 1, i + 4)\n .join(\" \")\n .trim();\n return summary.slice(0, 200);\n }\n }\n\n // Fallback: first meaningful paragraph\n return lines[0]?.slice(0, 200) || \"\";\n}\n\n// ─── ADR Files ───────────────────────────────────────────────────\n\nfunction findADRFiles(root: string): DecisionEntry[] {\n const adrDirs = [\"docs/adr\", \"docs/decisions\", \"adr\", \"decisions\", \"docs/architecture/decisions\"];\n\n const adrFiles: string[] = [];\n\n for (const dir of adrDirs) {\n const fullPath = join(root, dir);\n if (!existsSync(fullPath)) {\n continue;\n }\n try {\n const files = readdirSync(fullPath)\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => join(dir, f));\n adrFiles.push(...files);\n } catch {\n /* permission errors, etc */\n }\n }\n\n const entries: DecisionEntry[] = [];\n for (const file of adrFiles.slice(0, 20)) {\n try {\n const content = readFileSync(join(root, file), \"utf-8\");\n const firstLines = content.split(\"\\n\").slice(0, 5);\n const title = firstLines.find((l) => l.startsWith(\"#\"))?.replace(/^#+\\s*/, \"\") || file;\n entries.push({\n title,\n summary: \"\",\n date: \"\",\n source: file,\n });\n } catch {\n /* skip unreadable files */\n }\n }\n\n return entries;\n}\n\n// ─── View Builders ───────────────────────────────────────────────\n\nfunction buildKanban(issues: IssueData[]): KanbanView {\n const open = issues.filter((i) => i.state === \"open\");\n const closed = issues.filter((i) => i.state === \"closed\");\n\n // In-progress: ONLY issues with an explicit in-progress label (not assignee)\n const IN_PROGRESS_LABELS = [\"in-progress\", \"in progress\", \"doing\", \"wip\"];\n const inProgress = open.filter((i) =>\n i.labels.some((l) => IN_PROGRESS_LABELS.includes(l.toLowerCase()))\n );\n\n // Needs-verify: built and awaiting simulation re-test before closing\n const NEEDS_VERIFY_LABELS = [\"status:needs-verify\", \"needs-verify\", \"needs-verification\"];\n const needsVerify = open.filter(\n (i) =>\n !inProgress.includes(i) && i.labels.some((l) => NEEDS_VERIFY_LABELS.includes(l.toLowerCase()))\n );\n\n // Backlog: open, not in-progress, not needs-verify\n const backlog = open.filter((i) => !inProgress.includes(i) && !needsVerify.includes(i));\n\n return {\n backlog,\n in_progress: inProgress,\n needs_verify: needsVerify,\n done: closed.slice(0, 20),\n };\n}\n\n/**\n * Canonical issue priority ranking — single source of truth used everywhere.\n * Lower number = higher priority.\n * Precedence: P0/critical/urgent > vibekit > P1/high/bug > P2/medium > arch > P3/low > feature > unlabeled\n * Tiebreaker: effort S < M < L (prefer quick wins at same severity)\n */\nexport function rankIssues(issues: IssueData[]): IssueData[] {\n const priorityOrder = (i: IssueData): number => {\n let best = 5;\n for (const label of i.labels) {\n const l = label.toLowerCase();\n // Skip status: prefix labels — they're workflow state, not priority\n if (l.startsWith(\"status:\")) {\n continue;\n }\n if (l.includes(\"p0\") || l.includes(\"critical\") || l.includes(\"urgent\")) {\n best = Math.min(best, 0);\n } else if (l === \"vibekit\") {\n best = Math.min(best, 1); // queued for autonomous build\n } else if (l.includes(\"p1\") || l.includes(\"high\") || l.includes(\"bug\")) {\n best = Math.min(best, 1);\n } else if (l.includes(\"p2\") || l.includes(\"medium\")) {\n best = Math.min(best, 2);\n } else if (l === \"arch\") {\n best = Math.min(best, 2); // architectural issues — high value\n } else if (l.includes(\"p3\") || l.includes(\"low\")) {\n best = Math.min(best, 3);\n } else if (l.includes(\"feature\")) {\n best = Math.min(best, 4);\n }\n }\n return best;\n };\n\n const effortOrder = (i: IssueData): number => {\n switch (i.effort) {\n case \"S\": {\n return 0;\n }\n case \"M\": {\n return 1;\n }\n case \"L\": {\n return 2;\n }\n default: {\n return 1;\n } // treat unknown as medium\n }\n };\n\n return [...issues].sort((a, b) => {\n const pa = priorityOrder(a);\n const pb = priorityOrder(b);\n if (pa !== pb) {\n return pa - pb;\n }\n // Same priority tier: prefer smaller effort (quick wins)\n return effortOrder(a) - effortOrder(b);\n });\n}\n\nfunction buildPriorities(issues: IssueData[]): IssueData[] {\n return rankIssues(issues.filter((i) => i.state === \"open\"));\n}\n","import { readFileSync, statSync } from \"node:fs\";\nimport { writeFile, rename } from \"node:fs/promises\";\nimport { execFile } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport type { Manifest } from \"../types.js\";\n\nconst CACHE_FILE = \".codebase.cache.json\";\nconst CACHE_VERSION = 2;\n\nconst TRACKED_FILES = [\n \"package.json\",\n \"package-lock.json\",\n \"pnpm-lock.yaml\",\n \"yarn.lock\",\n \"tsconfig.json\",\n \"tsconfig.build.json\",\n \"Cargo.toml\",\n \"Cargo.lock\",\n \"pyproject.toml\",\n \"requirements.txt\",\n \"poetry.lock\",\n \"go.mod\",\n \"go.sum\",\n \"Makefile\",\n \"Dockerfile\",\n \"docker-compose.yml\",\n];\n\ninterface CacheData {\n cache_version: number;\n timestamp: string;\n git_sha: string | null;\n file_count: number;\n file_mtimes: Record<string, number>;\n manifest: Manifest;\n}\n\nasync function getGitSha(root: string): Promise<string | null> {\n return new Promise((resolve) => {\n execFile(\"git\", [\"rev-parse\", \"HEAD\"], { cwd: root, timeout: 5_000 }, (err, stdout) => {\n if (err) {\n resolve(null);\n return;\n }\n resolve(stdout.trim());\n });\n });\n}\n\nexport function loadCache(root: string): CacheData | null {\n try {\n const raw = readFileSync(join(root, CACHE_FILE), \"utf-8\");\n const data = JSON.parse(raw) as CacheData;\n if (data.cache_version !== CACHE_VERSION) {\n return null;\n }\n return data;\n } catch {\n return null;\n }\n}\n\nexport async function saveCache(\n root: string,\n fileCount: number,\n manifest: Manifest\n): Promise<void> {\n const data: CacheData = {\n cache_version: CACHE_VERSION,\n timestamp: new Date().toISOString(),\n git_sha: await getGitSha(root),\n file_count: fileCount,\n file_mtimes: snapshotMtimes(root),\n manifest,\n };\n try {\n const tmpPath = join(root, CACHE_FILE + \".tmp\");\n await writeFile(tmpPath, JSON.stringify(data), \"utf-8\");\n await rename(tmpPath, join(root, CACHE_FILE));\n } catch {\n // Non-critical — scanning still works without cache\n }\n}\n\nexport async function isCacheValid(\n root: string,\n cache: CacheData,\n currentFileCount: number\n): Promise<boolean> {\n // Primary key: if we have git SHAs, use them — zero false positives\n const currentSha = await getGitSha(root);\n if (currentSha && cache.git_sha) {\n return currentSha === cache.git_sha;\n }\n\n // Fallback for non-git repos: file count + mtime check\n if (cache.file_count !== currentFileCount) {\n return false;\n }\n\n const currentMtimes = snapshotMtimes(root);\n for (const file of Object.keys({ ...cache.file_mtimes, ...currentMtimes })) {\n if ((cache.file_mtimes[file] ?? 0) !== (currentMtimes[file] ?? 0)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction snapshotMtimes(root: string): Record<string, number> {\n const mtimes: Record<string, number> = {};\n for (const file of TRACKED_FILES) {\n try {\n const s = statSync(join(root, file));\n mtimes[file] = s.mtimeMs;\n } catch {\n // File doesn't exist — that's fine, don't include it\n }\n }\n return mtimes;\n}\n","import type { Manifest } from \"../types.js\";\nimport { createScanContext } from \"./context.js\";\nimport { detectors } from \"../detectors/index.js\";\nimport { syncGitHub } from \"../github/sync.js\";\nimport { warn } from \"../utils/output.js\";\nimport { loadCache, saveCache, isCacheValid } from \"./cache.js\";\n\nexport interface ScanOptions {\n depth?: number;\n categories?: string[];\n incremental?: boolean;\n quiet?: boolean;\n sync?: boolean;\n}\n\nexport async function scan(root: string, options: ScanOptions = {}): Promise<Manifest> {\n const ctx = await createScanContext(root, { depth: options.depth });\n\n // Incremental: return cached manifest if nothing changed\n if (options.incremental) {\n const cache = loadCache(root);\n if (cache && (await isCacheValid(root, cache, ctx.files.length))) {\n return cache.manifest;\n }\n }\n\n let activeDetectors = detectors;\n if (options.categories?.length) {\n activeDetectors = detectors.filter((d) => options.categories!.includes(d.category));\n }\n\n // Run all detectors in parallel\n const results = await Promise.allSettled(\n activeDetectors.map(async (d) => ({\n category: d.category,\n data: await d.detect(ctx),\n }))\n );\n\n const manifest: Manifest = {\n version: \"1.0\",\n generated_at: new Date().toISOString(),\n };\n\n const warnings: string[] = [];\n\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n (manifest as unknown as Record<string, unknown>)[result.value.category] = result.value.data;\n } else {\n const msg = `Detector failed: ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`;\n warnings.push(msg);\n if (!options.quiet) {\n warn(msg);\n }\n }\n }\n\n if (warnings.length > 0) {\n manifest._warnings = warnings;\n }\n\n // GitHub sync (optional, requires `gh` CLI)\n if (options.sync) {\n try {\n const ghData = await syncGitHub(root);\n if (ghData) {\n manifest.status = ghData.status;\n manifest.roadmap = ghData.roadmap;\n manifest.decisions = ghData.decisions;\n }\n } catch {\n if (!options.quiet) {\n warn(\"GitHub sync failed (is `gh` CLI installed and authenticated?)\");\n }\n }\n }\n\n // Incremental: save cache for next run\n if (options.incremental) {\n await saveCache(root, ctx.files.length, manifest);\n }\n\n return manifest;\n}\n\nexport function summarizeCategory(category: string, data: Record<string, unknown>): string {\n switch (category) {\n case \"project\": {\n const name = data.name as string;\n const desc = data.description as string;\n return desc ? `${name} — ${desc.slice(0, 60)}` : name || \"unknown\";\n }\n case \"repo\": {\n const url = data.url as string;\n const branch = data.default_branch as string;\n const short = url ? url.replace(/.*[:/]/, \"\").replace(/\\.git$/, \"\") : \"local\";\n return `${short}, ${branch || \"unknown branch\"}`;\n }\n case \"structure\": {\n const entries = data.entry_points as string[];\n const tree = data.tree as Record<string, string[]>;\n const buildOut = data.build_output as string[];\n const dirs = Object.keys(tree || {}).filter((k) => k !== \"./\");\n const parts: string[] = [];\n if (entries?.length) {\n parts.push(`${entries.length} entry points`);\n }\n if (dirs.length) {\n parts.push(`${dirs.length} top-level dirs`);\n }\n if (buildOut?.length) {\n parts.push(`build: ${buildOut.join(\", \")}`);\n }\n return parts.join(\", \") || \"empty\";\n }\n case \"stack\": {\n const langs = data.languages as string[];\n const frameworks = data.frameworks as string[];\n const buildTool = data.build_tool as string | null;\n const parts = [...(langs || []), ...(frameworks || [])];\n if (buildTool) {\n parts.push(buildTool);\n }\n return parts.join(\", \") || \"unknown\";\n }\n case \"commands\": {\n const cmds = Object.entries(data)\n .filter(([, v]) => v)\n .map(([k]) => k);\n return cmds.join(\", \") || \"none detected\";\n }\n case \"dependencies\": {\n const count = data.direct_count as number;\n const devCount = data.dev_count as number;\n const lock = data.lock_file as string;\n const parts: string[] = [];\n if (count) {\n parts.push(`${count} direct`);\n }\n if (devCount) {\n parts.push(`${devCount} dev`);\n }\n if (!count && !devCount) {\n parts.push(\"0 deps\");\n }\n if (lock) {\n parts.push(lock);\n }\n return parts.join(\", \");\n }\n case \"config\": {\n const envs = data.env_files as string[];\n return `${envs?.length || 0} env files`;\n }\n case \"git\": {\n const commits = data.recent_commits as string[];\n const changes = data.uncommitted_changes as boolean;\n return `${commits?.length || 0} recent commits${changes ? \", uncommitted changes\" : \"\"}`;\n }\n case \"quality\": {\n const parts: string[] = [];\n if (data.test_framework) {\n parts.push(data.test_framework as string);\n }\n if (data.linter) {\n parts.push(data.linter as string);\n }\n if (data.ci) {\n parts.push(data.ci as string);\n }\n return parts.join(\", \") || \"none detected\";\n }\n case \"patterns\": {\n const arch = data.architecture as string;\n const state = data.state_management as string;\n return [arch, state].filter(Boolean).join(\", \") || \"unknown\";\n }\n case \"status\": {\n const issues = (data.issues as unknown[]) || [];\n const prs = (data.pull_requests as unknown[]) || [];\n return `${issues.length} issues, ${prs.length} PRs`;\n }\n default:\n return JSON.stringify(data).slice(0, 60);\n }\n}\n","import { resolve, join } from \"node:path\";\nimport { writeFile } from \"node:fs/promises\";\nimport type { CLIOptions } from \"../types.js\";\nimport { scan, summarizeCategory } from \"../scanner/engine.js\";\nimport { log, success, setQuiet } from \"../utils/output.js\";\n\nexport async function runScan(options: CLIOptions): Promise<void> {\n setQuiet(options.quiet);\n const root = resolve(options.path);\n\n log(`Scanning ${root}...`);\n\n const manifest = await scan(root, {\n depth: options.depth,\n categories: options.categories.length ? options.categories : undefined,\n incremental: options.incremental,\n quiet: options.quiet,\n sync: options.sync,\n });\n\n // Print summary per category\n for (const [category, data] of Object.entries(manifest)) {\n if (category === \"version\" || category === \"generated_at\") {\n continue;\n }\n if (typeof data !== \"object\" || data === null) {\n continue;\n }\n success(\n `${capitalize(category)} (${summarizeCategory(category, data as Record<string, unknown>)})`\n );\n }\n\n // Write to disk\n const outputPath = join(root, \".codebase.json\");\n const content = JSON.stringify(manifest, null, 2);\n await writeFile(outputPath, content, \"utf-8\");\n\n const sizeKB = (Buffer.byteLength(content) / 1024).toFixed(1);\n log(`\\nWritten: .codebase.json (${sizeKB} KB)`);\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n","import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Manifest } from \"../types.js\";\n\nconst START_MARKER = \"<!-- codebase:start -->\";\nconst END_MARKER = \"<!-- codebase:end -->\";\n\nconst HASH_START_MARKER = \"# codebase:start\";\nconst HASH_END_MARKER = \"# codebase:end\";\n\nconst INJECT_BLOCK_MD = `\n${START_MARKER}\n## Project Context (auto-generated by codebase)\n\n**This project uses \\`codebase\\` for AI context. Run commands below instead of exploring files.**\n\n### Session Start\n\\`\\`\\`\nnpx codebase brief\n\\`\\`\\`\nReturns: project identity, tech stack, commands, structure, current status, next task, blockers, decisions — everything you need in one call.\n\n### Commands (your interface — use these, don't read files)\n| Command | What it returns |\n|---|---|\n| \\`npx codebase brief\\` | Full project briefing — **run this first** |\n| \\`npx codebase next\\` | Highest-priority task + what's in progress |\n| \\`npx codebase status\\` | Kanban board, priorities, milestones |\n| \\`npx codebase query <path>\\` | Any data point (e.g. \\`stack.languages\\`, \\`commands.test\\`) |\n| \\`npx codebase issue create \"title\"\\` | Track a bug, feature, or TODO |\n| \\`npx codebase issue close <n> --reason \"why\"\\` | Close an issue after fixing it |\n\n### Maintenance\n| Command | What it does |\n|---|---|\n| \\`codebase doctor\\` | Health check — diagnose broken setup |\n| \\`codebase fix\\` | Auto-repair issues found by doctor |\n| \\`codebase skills\\` | List installed skills and their capabilities |\n\n### Rules\n- **Never explore the codebase to discover stack/commands/structure** — it's already in \\`brief\\`\n- **Check \\`next\\` before starting work** — don't duplicate in-progress tasks\n- **Create issues for bugs/TODOs you find** — keep the project brain alive\n- **Close issues when you fix them** — with a reason so the team knows why\n- **If any command fails, run \\`codebase doctor\\` then \\`codebase fix\\`** — self-heal before asking for help\n\n### Vibekit Workflow\n\\`\\`\\`\n/simulate → /build → /launch\n\\`\\`\\`\n- \\`/simulate\\` — agent-browser customer journeys find & fix bugs inline. Creates GitHub issues for arch problems.\n- \\`/build\\` — Implements architectural issues autonomously. Runs until all \\`arch\\`+\\`vibekit\\` issues are closed.\n- \\`/launch\\` — Gates on open bugs, generates GTM artifacts, creates GitHub release, merges to main.\n\n### MCP Tools (for IDE/agent integrations)\nIf using MCP instead of CLI: call \\`project_brief\\` (not \\`npx codebase brief\\`), \\`get_next_task\\`, \\`refresh_status\\`, \\`list_skills\\`. Full tool list via \\`list_commands\\` and \\`list_skills\\`.\n\n### Browser Automation (agent-browser)\nCommands: \\`open <url>\\`, \\`snapshot -i\\` (→ \\`@e1\\`/\\`@e2\\` refs), \\`click @e1\\`, \\`fill @e2 \"text\"\\`, \\`screenshot\\`, \\`auth save/login <profile>\\`, \\`state save/load <name>\\`.\n${END_MARKER}`;\n\nconst INJECT_BLOCK_PLAIN = `\n${HASH_START_MARKER}\n# Project Context (auto-generated by codebase)\n#\n# This project uses \\`codebase\\` for AI context. Run commands instead of exploring files.\n#\n# SESSION START: npx codebase brief\n# → Returns project identity, stack, commands, status, next task, blockers, decisions\n#\n# COMMANDS (your interface):\n# npx codebase brief → Full project briefing (run first)\n# npx codebase next → Highest-priority task + in-progress\n# npx codebase status → Kanban, priorities, milestones\n# npx codebase query <path> → Any data (e.g. stack.languages)\n# npx codebase issue create \"title\" → Track bugs/features/TODOs\n# npx codebase issue close <n> --reason \"why\" → Close after fixing\n#\n# MAINTENANCE:\n# codebase doctor → Health check — diagnose broken setup\n# codebase fix → Auto-repair issues found by doctor\n# codebase skills → List installed skills and their capabilities\n#\n# RULES:\n# - Never explore codebase to discover stack/commands — it's in brief\n# - Check next before starting work — don't duplicate in-progress tasks\n# - Create issues for bugs/TODOs — keep the project brain alive\n# - Close issues when fixed — with a reason\n# - If any command fails, run doctor then fix — self-heal before asking for help\n#\n# MCP TOOLS (for IDE/agent integrations):\n# If using MCP: call project_brief, get_next_task, refresh_status, list_skills\n${HASH_END_MARKER}`;\n\ninterface ManifestSummary {\n name: string;\n description: string | null;\n languages: string[];\n frameworks: string[];\n commands: Record<string, string | null>;\n}\n\nfunction readManifestSummary(root: string): ManifestSummary | null {\n try {\n const raw = readFileSync(join(root, \".codebase.json\"), \"utf-8\");\n const m = JSON.parse(raw) as Manifest;\n return {\n name: m.project?.name || \"Unknown\",\n description: m.project?.description || null,\n languages: m.stack?.languages || [],\n frameworks: m.stack?.frameworks || [],\n commands: m.commands || {},\n };\n } catch {\n return null;\n }\n}\n\nfunction buildDynamicBlockMd(root: string): string {\n const summary = readManifestSummary(root);\n if (!summary) {\n return INJECT_BLOCK_MD;\n }\n\n const stackParts = [...summary.languages, ...summary.frameworks].filter(Boolean);\n const stack = stackParts.length ? stackParts.join(\", \") : \"unknown\";\n\n const cmdEntries = Object.entries(summary.commands).filter(([, v]) => v);\n const cmdLines = cmdEntries.map(([k, v]) => `| \\`${k}\\` | \\`${v}\\` |`).join(\"\\n\");\n const cmdTable = cmdLines\n ? `\\n### Project Commands\\n| Task | Command |\\n|---|---|\\n${cmdLines}\\n`\n : \"\";\n\n return `\n${START_MARKER}\n## Project Context (auto-generated by codebase)\n\n**${summary.name}**${summary.description ? ` — ${summary.description}` : \"\"}\n**Stack:** ${stack}\n${cmdTable}\n**This project uses \\`codebase\\` for AI context. Run commands below instead of exploring files.**\n\n### Session Start\n\\`\\`\\`\nnpx codebase brief\n\\`\\`\\`\nReturns: project identity, tech stack, commands, structure, current status, next task, blockers, decisions — everything you need in one call.\n\n### Commands (your interface — use these, don't read files)\n| Command | What it returns |\n|---|---|\n| \\`npx codebase brief\\` | Full project briefing — **run this first** |\n| \\`npx codebase next\\` | Highest-priority task + what's in progress |\n| \\`npx codebase status\\` | Kanban board, priorities, milestones |\n| \\`npx codebase query <path>\\` | Any data point (e.g. \\`stack.languages\\`, \\`commands.test\\`) |\n| \\`npx codebase issue create \"title\"\\` | Track a bug, feature, or TODO |\n| \\`npx codebase issue close <n> --reason \"why\"\\` | Close an issue after fixing it |\n\n### Maintenance\n| Command | What it does |\n|---|---|\n| \\`codebase doctor\\` | Health check — diagnose broken setup |\n| \\`codebase fix\\` | Auto-repair issues found by doctor |\n| \\`codebase skills\\` | List installed skills and their capabilities |\n\n### Rules\n- **Never explore the codebase to discover stack/commands/structure** — it's already in \\`brief\\`\n- **Check \\`next\\` before starting work** — don't duplicate in-progress tasks\n- **Create issues for bugs/TODOs you find** — keep the project brain alive\n- **Close issues when you fix them** — with a reason so the team knows why\n- **If any command fails, run \\`codebase doctor\\` then \\`codebase fix\\`** — self-heal before asking for help\n\n### Vibekit Workflow\n\\`\\`\\`\n/simulate → /build → /launch\n\\`\\`\\`\n- \\`/simulate\\` — agent-browser customer journeys find & fix bugs inline. Creates GitHub issues for arch problems.\n- \\`/build\\` — Implements architectural issues autonomously. Runs until all \\`arch\\`+\\`vibekit\\` issues are closed.\n- \\`/launch\\` — Gates on open bugs, generates GTM artifacts, creates GitHub release, merges to main.\n\n### MCP Tools (for IDE/agent integrations)\nIf using MCP instead of CLI: call \\`project_brief\\` (not \\`npx codebase brief\\`), \\`get_next_task\\`, \\`refresh_status\\`, \\`list_skills\\`. Full tool list via \\`list_commands\\` and \\`list_skills\\`.\n\n### Browser Automation (agent-browser)\nCommands: \\`open <url>\\`, \\`snapshot -i\\` (→ \\`@e1\\`/\\`@e2\\` refs), \\`click @e1\\`, \\`fill @e2 \"text\"\\`, \\`screenshot\\`, \\`auth save/login <profile>\\`, \\`state save/load <name>\\`.\n${END_MARKER}`;\n}\n\nfunction buildDynamicBlockPlain(root: string): string {\n const summary = readManifestSummary(root);\n if (!summary) {\n return INJECT_BLOCK_PLAIN;\n }\n\n const stackParts = [...summary.languages, ...summary.frameworks].filter(Boolean);\n const stack = stackParts.length ? stackParts.join(\", \") : \"unknown\";\n\n const cmdEntries = Object.entries(summary.commands).filter(([, v]) => v);\n const cmdLines = cmdEntries.map(([k, v]) => `# ${k}: ${v}`).join(\"\\n\");\n const cmdSection = cmdLines ? `#\\n# PROJECT COMMANDS:\\n${cmdLines}\\n` : \"\";\n\n return `\n${HASH_START_MARKER}\n# Project Context (auto-generated by codebase)\n#\n# ${summary.name}${summary.description ? ` — ${summary.description}` : \"\"}\n# Stack: ${stack}\n${cmdSection}#\n# This project uses \\`codebase\\` for AI context. Run commands instead of exploring files.\n#\n# SESSION START: npx codebase brief\n# → Returns project identity, stack, commands, status, next task, blockers, decisions\n#\n# COMMANDS (your interface):\n# npx codebase brief → Full project briefing (run first)\n# npx codebase next → Highest-priority task + in-progress\n# npx codebase status → Kanban, priorities, milestones\n# npx codebase query <path> → Any data (e.g. stack.languages)\n# npx codebase issue create \"title\" → Track bugs/features/TODOs\n# npx codebase issue close <n> --reason \"why\" → Close after fixing\n#\n# MAINTENANCE:\n# codebase doctor → Health check — diagnose broken setup\n# codebase fix → Auto-repair issues found by doctor\n# codebase skills → List installed skills and their capabilities\n#\n# RULES:\n# - Never explore codebase to discover stack/commands — it's in brief\n# - Check next before starting work — don't duplicate in-progress tasks\n# - Create issues for bugs/TODOs — keep the project brain alive\n# - Close issues when fixed — with a reason\n# - If any command fails, run doctor then fix — self-heal before asking for help\n#\n# MCP TOOLS (for IDE/agent integrations):\n# If using MCP: call project_brief, get_next_task, refresh_status, list_skills\n${HASH_END_MARKER}`;\n}\n\nexport function fileExistsAt(root: string, file: string): boolean {\n return existsSync(join(root, file));\n}\n\nexport function injectMarkdown(root: string, file: string): void {\n const path = join(root, file);\n let content = existsSync(path) ? readFileSync(path, \"utf-8\") : \"\";\n\n if (content.includes(START_MARKER)) {\n // Already injected — replace with updated version\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n if (startIdx !== -1 && endIdx !== -1) {\n content = content.slice(0, startIdx) + content.slice(endIdx + END_MARKER.length);\n content = content.replace(/\\n{3,}/g, \"\\n\\n\").trimEnd();\n }\n }\n\n writeFileSync(path, content.trimEnd() + \"\\n\" + buildDynamicBlockMd(root) + \"\\n\", \"utf-8\");\n}\n\nexport function injectPlaintext(root: string, file: string): void {\n const path = join(root, file);\n let content = existsSync(path) ? readFileSync(path, \"utf-8\") : \"\";\n\n if (content.includes(HASH_START_MARKER)) {\n // Already injected — replace with updated version\n const startIdx = content.indexOf(HASH_START_MARKER);\n const endIdx = content.indexOf(HASH_END_MARKER);\n if (startIdx !== -1 && endIdx !== -1) {\n content = content.slice(0, startIdx) + content.slice(endIdx + HASH_END_MARKER.length);\n content = content.replace(/\\n{3,}/g, \"\\n\\n\").trimEnd();\n }\n }\n\n writeFileSync(path, content.trimEnd() + \"\\n\" + buildDynamicBlockPlain(root) + \"\\n\", \"utf-8\");\n}\n\nexport function removeMarkdown(root: string, file: string): void {\n const path = join(root, file);\n if (!existsSync(path)) {\n return;\n }\n\n let content = readFileSync(path, \"utf-8\");\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n // Only remove if both markers are present\n if (startIdx !== -1 && endIdx !== -1) {\n content = content.slice(0, startIdx) + content.slice(endIdx + END_MARKER.length);\n content = content.replace(/\\n{3,}/g, \"\\n\\n\").trim() + \"\\n\";\n writeFileSync(path, content, \"utf-8\");\n }\n}\n\nexport function removePlaintext(root: string, file: string): void {\n const path = join(root, file);\n if (!existsSync(path)) {\n return;\n }\n\n let content = readFileSync(path, \"utf-8\");\n const startIdx = content.indexOf(HASH_START_MARKER);\n const endIdx = content.indexOf(HASH_END_MARKER);\n\n if (startIdx !== -1 && endIdx !== -1) {\n content = content.slice(0, startIdx) + content.slice(endIdx + HASH_END_MARKER.length);\n content = content.replace(/\\n{3,}/g, \"\\n\\n\").trim() + \"\\n\";\n writeFileSync(path, content, \"utf-8\");\n }\n}\n","import type { Integration, InjectResult } from \"../types.js\";\nimport { fileExistsAt, injectMarkdown, removeMarkdown } from \"./shared.js\";\n\nexport const claudeIntegration: Integration = {\n name: \"claude\",\n detect: (root) => fileExistsAt(root, \"CLAUDE.md\"),\n async inject(root): Promise<InjectResult> {\n try {\n injectMarkdown(root, \"CLAUDE.md\");\n return { ok: true };\n } catch (err) {\n return { ok: false, message: (err as Error).message };\n }\n },\n remove: (root) => removeMarkdown(root, \"CLAUDE.md\"),\n};\n","import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst MANIFEST_ENTRY = \".codebase.json\";\nconst CACHE_ENTRY = \".codebase.cache.json\";\n\nexport function updateGitignore(root: string): void {\n const path = join(root, \".gitignore\");\n const content = existsSync(path) ? readFileSync(path, \"utf-8\") : \"\";\n\n const needsManifest = !content.includes(MANIFEST_ENTRY);\n const needsCache = !content.includes(CACHE_ENTRY);\n\n if (!needsManifest && !needsCache) {\n return;\n }\n\n let addition = \"\";\n if (needsManifest || needsCache) {\n addition += \"\\n# AI context manifest\\n\";\n if (needsManifest) {\n addition += `${MANIFEST_ENTRY}\\n`;\n }\n if (needsCache) {\n addition += `${CACHE_ENTRY}\\n`;\n }\n }\n\n writeFileSync(path, content.trimEnd() + addition, \"utf-8\");\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync, chmodSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst HOOK_MARKER = \"# codebase-auto-update\";\n\n/**\n * Install BOTH post-commit and post-checkout hooks.\n * If ghSync is true, the hooks also refresh GitHub data.\n * Also installs a pre-commit hook that runs typecheck + lint if available.\n */\nexport function installHooks(root: string, ghSync = false): boolean {\n if (!existsSync(join(root, \".git\"))) {\n return false;\n }\n\n const syncFlag = ghSync ? \" --sync\" : \"\";\n const hookCmd = `npx --yes codebase scan-only --incremental --quiet${syncFlag}`;\n\n installSingleHook(root, \"post-commit\", hookCmd);\n installSingleHook(root, \"post-checkout\", hookCmd);\n installPreCommitHook(root);\n\n return true;\n}\n\n/**\n * Legacy function — install only post-commit hook.\n */\nexport function installHook(root: string): boolean {\n return installHooks(root, false);\n}\n\nexport function uninstallHook(root: string): boolean {\n const removed1 = removeSingleHook(root, \"post-commit\");\n const removed2 = removeSingleHook(root, \"post-checkout\");\n return removed1 || removed2;\n}\n\n// ─── Internal ────────────────────────────────────────────────────\n\nconst PRE_COMMIT_MARKER = \"# codebase-pre-commit\";\n\nfunction installPreCommitHook(root: string): void {\n const hooksDir = join(root, \".git\", \"hooks\");\n const hookPath = join(hooksDir, \"pre-commit\");\n\n if (!existsSync(hooksDir)) {\n mkdirSync(hooksDir, { recursive: true });\n }\n\n // Only install if there's a package.json with a check or typecheck script\n const pkgPath = join(root, \"package.json\");\n if (!existsSync(pkgPath)) {\n return;\n }\n\n let hasCheck = false;\n let hasTypecheck = false;\n let hasLint = false;\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n hasCheck = !!pkg.scripts?.check;\n hasTypecheck = !!pkg.scripts?.typecheck;\n hasLint = !!pkg.scripts?.lint;\n } catch {\n return;\n }\n\n if (!hasCheck && !hasTypecheck && !hasLint) {\n return;\n }\n\n // Build the check command: prefer `check` (runs both), else typecheck + lint separately\n let checkCmd: string;\n if (hasCheck) {\n checkCmd = `npm run check --silent`;\n } else {\n const parts: string[] = [];\n if (hasTypecheck) {\n parts.push(`npm run typecheck --silent`);\n }\n if (hasLint) {\n parts.push(`npm run lint --silent`);\n }\n checkCmd = parts.join(\" && \");\n }\n\n const script = `#!/bin/sh\n${PRE_COMMIT_MARKER}\n# Run typecheck + lint before every commit. Fix errors before committing.\nif [ -f package.json ]; then\n ${checkCmd} || {\n echo \"\"\n echo \" Pre-commit check failed. Fix the errors above before committing.\"\n echo \" To skip (not recommended): git commit --no-verify\"\n echo \"\"\n exit 1\n }\nfi\n`;\n\n if (existsSync(hookPath)) {\n const existing = readFileSync(hookPath, \"utf-8\");\n if (!existing.includes(PRE_COMMIT_MARKER)) {\n writeFileSync(hookPath, existing.trimEnd() + \"\\n\\n\" + script, \"utf-8\");\n }\n } else {\n writeFileSync(hookPath, script, \"utf-8\");\n }\n chmodSync(hookPath, 0o755);\n}\n\nfunction installSingleHook(root: string, hookName: string, command: string): void {\n const hooksDir = join(root, \".git\", \"hooks\");\n const hookPath = join(hooksDir, hookName);\n\n if (!existsSync(hooksDir)) {\n mkdirSync(hooksDir, { recursive: true });\n }\n\n if (existsSync(hookPath)) {\n const content = readFileSync(hookPath, \"utf-8\");\n if (content.includes(HOOK_MARKER)) {\n // Already installed — update the command in case flags changed\n const updated = content.replace(\n new RegExp(`${HOOK_MARKER}\\\\n.*`, \"m\"),\n `${HOOK_MARKER}\\n${command}`\n );\n writeFileSync(hookPath, updated, \"utf-8\");\n return;\n }\n // Append to existing hook\n writeFileSync(hookPath, content.trimEnd() + `\\n\\n${HOOK_MARKER}\\n${command}\\n`, \"utf-8\");\n } else {\n writeFileSync(hookPath, `#!/bin/sh\\n\\n${HOOK_MARKER}\\n${command}\\n`, \"utf-8\");\n }\n\n chmodSync(hookPath, 0o755);\n}\n\nfunction removeSingleHook(root: string, hookName: string): boolean {\n const hookPath = join(root, \".git\", \"hooks\", hookName);\n if (!existsSync(hookPath)) {\n return false;\n }\n\n let content = readFileSync(hookPath, \"utf-8\");\n if (!content.includes(HOOK_MARKER)) {\n return false;\n }\n\n // Remove the marker and the line after it\n const lines = content.split(\"\\n\");\n const filtered: string[] = [];\n let skipNext = false;\n\n for (const line of lines) {\n if (line.includes(HOOK_MARKER)) {\n skipNext = true;\n continue;\n }\n if (skipNext) {\n skipNext = false;\n continue;\n }\n filtered.push(line);\n }\n\n content = filtered.join(\"\\n\");\n\n const trimmed = content.replace(/^#!.*\\n?/, \"\").trim();\n if (!trimmed) {\n unlinkSync(hookPath);\n } else {\n writeFileSync(hookPath, content, \"utf-8\");\n }\n\n return true;\n}\n","import { resolve, dirname, join } from \"node:path\";\nimport {\n writeFileSync,\n existsSync,\n mkdirSync,\n readFileSync,\n chmodSync,\n readdirSync,\n copyFileSync,\n} from \"node:fs\";\nimport { execFile } from \"node:child_process\";\nimport type { CLIOptions, Manifest } from \"../types.js\";\nimport { runScan } from \"./scan.js\";\nimport { claudeIntegration } from \"../integrations/claude.js\";\nimport { updateGitignore } from \"../integrations/gitignore.js\";\nimport { installHooks } from \"../integrations/githook.js\";\nimport { log, success, info, warn, heading } from \"../utils/output.js\";\n\n// ─── Vibekit labels ──────────────────────────────────────────────\nconst VIBEKIT_LABELS = [\n { name: \"bug\", color: \"d73a4a\", description: \"Something isn't working\" },\n { name: \"arch\", color: \"0075ca\", description: \"Architectural change needed\" },\n { name: \"sim\", color: \"e4e669\", description: \"Found by simulation\" },\n { name: \"carry\", color: \"ff6b35\", description: \"Bug surviving 2+ cycles\" },\n { name: \"cycle\", color: \"c5def5\", description: \"Simulation cycle summary\" },\n { name: \"critical\", color: \"b60205\", description: \"Critical severity\" },\n { name: \"high\", color: \"d93f0b\", description: \"High severity\" },\n { name: \"medium\", color: \"e99695\", description: \"Medium severity\" },\n { name: \"low\", color: \"fef2c0\", description: \"Low severity\" },\n { name: \"highlight\", color: \"0e8a16\", description: \"Positive product signal\" },\n { name: \"vibekit\", color: \"7057ff\", description: \"Queued for autonomous build\" },\n { name: \"performance\", color: \"ff8c00\", description: \"Performance issue\" },\n { name: \"review\", color: \"1d76db\", description: \"Found by code review\" },\n];\n\nexport async function runSetup(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n\n // ── Step 1: Full scan ──────────────────────────────────────────\n await runScan({ ...options, sync: true });\n\n // ── Step 2: Claude Code integration ──────────────────────────\n heading(\"Claude Code Integration\");\n if (!existsSync(join(root, \"CLAUDE.md\"))) {\n writeFileSync(join(root, \"CLAUDE.md\"), \"# Project Rules\\n\", \"utf-8\");\n }\n claudeIntegration.inject(root);\n success(\"CLAUDE.md - added .codebase.json reference\");\n\n // ── Step 3: Git hooks ─────────────────────────────────────────\n heading(\"Git Hooks\");\n const hookInstalled = installHooks(root, false);\n if (hookInstalled) {\n success(\"post-commit hook (auto-updates .codebase.json)\");\n success(\"pre-commit hook (runs typecheck + lint before every commit)\");\n installBranchHook(root);\n success(\"commit-msg hook (blocks direct commits to main/master)\");\n } else {\n info(\"Not a git repository - skipping hooks\");\n }\n\n // ── Step 3b: Claude Code hooks ────────────────────────────────\n heading(\"Claude Code Hooks\");\n installClaudeHooks(root);\n\n // ── Step 3c: agent-browser ────────────────────────────────────\n heading(\"Browser Automation\");\n await installAgentBrowser();\n\n // ── Step 4: Claude commands ───────────────────────────────────\n heading(\"Claude Commands\");\n const claudeAvailable = await checkClaude();\n if (!claudeAvailable) {\n warn(\"Claude Code CLI not detected — skipping slash commands\");\n warn(\"Install Claude Code then re-run: codebase setup\");\n } else {\n installClaudeCommands(root);\n }\n\n // ── Step 4b: Claude skills ──────────────────────────────────\n heading(\"Claude Skills\");\n installClaudeSkills(root);\n\n // ── Step 5: Gitignore ─────────────────────────────────────────\n updateGitignore(root);\n appendToGitignore(root, [\n \".vibekit/daemon.lock\",\n \".vibekit/daemon.log\",\n \".vibekit/build.lock\",\n \".vibekit/milestone.env\",\n \".mcp.json\",\n ]);\n success(\".gitignore updated\");\n\n // ── Step 6: .vibekit/ dir ─────────────────────────────────────\n heading(\"Vibekit Bootstrap\");\n const vibedir = join(root, \".vibekit\");\n if (!existsSync(vibedir)) {\n mkdirSync(vibedir, { recursive: true });\n success(\".vibekit/ directory created\");\n } else {\n info(\".vibekit/ already exists\");\n }\n\n // ── Step 7: GitHub labels ─────────────────────────────────────\n heading(\"GitHub Labels\");\n const ghAvailable = await checkGh();\n if (!ghAvailable) {\n warn(\"gh CLI not authenticated — skipping label/issue setup\");\n warn(\"Run: gh auth login then codebase setup\");\n } else {\n await installLabels(root);\n await ensureHighlightsIndex(root);\n }\n\n // ── Step 8: docs/PRODUCT.md ───────────────────────────────────\n heading(\"Product Brief\");\n const docsDir = join(root, \"docs\");\n if (!existsSync(docsDir)) {\n mkdirSync(docsDir, { recursive: true });\n }\n\n const productPath = join(docsDir, \"PRODUCT.md\");\n if (!existsSync(productPath)) {\n generateProductMd(root, productPath);\n success(\"docs/PRODUCT.md generated — review and fill in [INFERRED] sections\");\n } else {\n info(\"docs/PRODUCT.md already exists — skipping (delete to regenerate)\");\n }\n\n log(\"\\nDone! Your project is wired for AI + autonomous loop.\");\n log(\"\\n 0. codebase brief — load project context (AI agents: call this first)\");\n log(\" 1. Review docs/PRODUCT.md and fill in any [INFERRED] sections\");\n log(\" 2. /simulate — AI customer journeys find & fix bugs\");\n log(\" 3. /build — implement architectural issues autonomously\");\n log(\" 4. /launch — gate check, release, merge to main\");\n}\n\n// ─── Claude commands installation ────────────────────────────────\n\nexport function installClaudeCommandsForFix(root: string): void {\n installClaudeCommands(root);\n}\n\nfunction installClaudeCommands(root: string): void {\n // commands/ is always a sibling of dist/ in the npm package\n // (dist/commands/setup.js → ../commands/ OR dist/index.js → ../commands/)\n const commandsSource = join(dirname(new URL(import.meta.url).pathname), \"..\", \"commands\");\n\n if (!existsSync(commandsSource)) {\n warn(\"Claude commands not found in package — skipping\");\n return;\n }\n\n const files = readdirSync(commandsSource).filter((f) => f.endsWith(\".md\"));\n\n // Install to both project-local (.claude/commands/) and user-global (~/.claude/commands/)\n const destinations: Array<{ dir: string; label: string }> = [\n { dir: join(root, \".claude\", \"commands\"), label: \".claude/commands/\" },\n { dir: join(process.env[\"HOME\"] ?? \"~\", \".claude\", \"commands\"), label: \"~/.claude/commands/\" },\n ];\n\n let totalInstalled = 0;\n let totalUpdated = 0;\n\n for (const { dir, label } of destinations) {\n mkdirSync(dir, { recursive: true });\n\n let installed = 0;\n let updated = 0;\n let skipped = 0;\n\n for (const file of files) {\n const src = join(commandsSource, file);\n const dest = join(dir, file);\n if (existsSync(dest)) {\n // Update if source content differs (package upgrade)\n const srcContent = readFileSync(src, \"utf-8\");\n const destContent = readFileSync(dest, \"utf-8\");\n if (srcContent !== destContent) {\n copyFileSync(src, dest);\n updated++;\n } else {\n skipped++;\n }\n } else {\n copyFileSync(src, dest);\n installed++;\n }\n }\n\n const parts: string[] = [];\n if (installed > 0) {\n parts.push(`${installed} new`);\n }\n if (updated > 0) {\n parts.push(`${updated} updated`);\n }\n if (skipped > 0) {\n parts.push(`${skipped} unchanged`);\n }\n\n if (installed > 0 || updated > 0) {\n success(`Claude commands → ${label} (${parts.join(\", \")})`);\n } else {\n info(`Claude commands up to date → ${label}`);\n }\n\n totalInstalled += installed;\n totalUpdated += updated;\n }\n\n if (totalInstalled > 0 || totalUpdated > 0) {\n info(\"Available: /setup /simulate /build /launch /review /vibeloop\");\n info(\"Tip: commit .claude/commands/ to share these with your team\");\n }\n}\n\n// ─── Claude skills installation ──────────────────────────────────\n\nexport function installClaudeSkillsForFix(root: string): void {\n installClaudeSkills(root);\n}\n\nfunction installClaudeSkills(root: string): void {\n // skills/ is always a sibling of dist/ in the npm package\n const skillsSource = join(dirname(new URL(import.meta.url).pathname), \"..\", \"skills\");\n\n if (!existsSync(skillsSource)) {\n warn(\"Skills not found in package — skipping\");\n return;\n }\n\n const files = readdirSync(skillsSource).filter((f) => f.endsWith(\".skill\"));\n if (files.length === 0) {\n info(\"No skill files found in package\");\n return;\n }\n\n // Install to both project-local (.claude/skills/) and user-global (~/.claude/skills/)\n const destinations: Array<{ dir: string; label: string }> = [\n { dir: join(root, \".claude\", \"skills\"), label: \".claude/skills/\" },\n { dir: join(process.env[\"HOME\"] ?? \"~\", \".claude\", \"skills\"), label: \"~/.claude/skills/\" },\n ];\n\n let totalInstalled = 0;\n let totalUpdated = 0;\n\n for (const { dir, label } of destinations) {\n mkdirSync(dir, { recursive: true });\n\n let installed = 0;\n let updated = 0;\n let skipped = 0;\n\n for (const file of files) {\n const src = join(skillsSource, file);\n const dest = join(dir, file);\n if (existsSync(dest)) {\n const srcBuf = readFileSync(src);\n const destBuf = readFileSync(dest);\n if (!srcBuf.equals(destBuf)) {\n copyFileSync(src, dest);\n updated++;\n } else {\n skipped++;\n }\n } else {\n copyFileSync(src, dest);\n installed++;\n }\n }\n\n const parts: string[] = [];\n if (installed > 0) {\n parts.push(`${installed} new`);\n }\n if (updated > 0) {\n parts.push(`${updated} updated`);\n }\n if (skipped > 0) {\n parts.push(`${skipped} unchanged`);\n }\n\n if (installed > 0 || updated > 0) {\n success(`Skills → ${label} (${parts.join(\", \")})`);\n } else {\n info(`Skills up to date → ${label}`);\n }\n\n totalInstalled += installed;\n totalUpdated += updated;\n }\n\n const names = files.map((f) => f.replace(/\\.skill$/, \"\")).join(\", \");\n\n if (totalInstalled > 0 || totalUpdated > 0) {\n info(`Available: ${names}`);\n info(\"Tip: commit .claude/skills/ to share these with your team\");\n } else {\n info(`Available: ${names}`);\n }\n}\n\n// ─── Claude Code hooks ────────────────────────────────────────────\n\nexport function installClaudeHooksForFix(root: string): void {\n installClaudeHooks(root);\n}\n\nfunction installClaudeHooks(root: string): void {\n const hooksDir = join(root, \".claude\", \"hooks\");\n mkdirSync(hooksDir, { recursive: true });\n\n // ── git-guard.sh (PreToolUse) ──────────────────────────────────\n const guardPath = join(hooksDir, \"git-guard.sh\");\n const guardScript = `#!/bin/bash\n# codebase git-guard — PreToolUse hook\n# Reads Claude tool input JSON from stdin, enforces git safety rules.\n\nINPUT=$(cat)\nCMD=$(echo \"$INPUT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('command',''))\" 2>/dev/null || echo \"\")\n\nif [ -z \"$CMD\" ]; then exit 0; fi\n\n# ── Rule 1: No commits to protected branches ──────────────────\nif echo \"$CMD\" | grep -qE \"^git commit|&& git commit| git commit\"; then\n BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"\")\n if [[ \"$BRANCH\" == \"main\" || \"$BRANCH\" == \"master\" || \"$BRANCH\" == \"prod\" || \"$BRANCH\" == \"production\" ]]; then\n echo \"\"\n echo \" BLOCKED: Direct commits to '$BRANCH' are not allowed.\"\n echo \"\"\n echo \" Branch naming convention:\"\n echo \" feat/<slug> new features\"\n echo \" fix/<slug> bug fixes\"\n echo \" chore/<slug> maintenance\"\n echo \" hotfix/<slug> urgent prod fixes\"\n echo \" docs/<slug> documentation\"\n echo \" test/<slug> test additions\"\n echo \"\"\n echo \" Switch to develop first:\"\n echo \" git checkout develop && git pull origin develop\"\n echo \" git checkout -b feat/<your-feature>\"\n echo \"\"\n exit 2\n fi\nfi\n\n# ── Rule 2: No direct push to protected branches ──────────────\nif echo \"$CMD\" | grep -qE \"git push.*(origin )?(main|master|prod|production)(\\s|$|\\\"|\\')\"; then\n echo \"\"\n echo \" BLOCKED: Direct push to protected branch is not allowed.\"\n echo \" Use /launch to release to main.\"\n echo \"\"\n exit 2\nfi\n\n# ── Rule 3: No force push ever ────────────────────────────────\nif echo \"$CMD\" | grep -qE \"git push.*(--force|-f)( |$)\"; then\n echo \"\"\n echo \" BLOCKED: Force push is not allowed.\"\n echo \" If you need to undo a commit, use: git revert <sha>\"\n echo \"\"\n exit 2\nfi\n\n# ── Rule 4: Pull before commit if behind remote ───────────────\nif echo \"$CMD\" | grep -qE \"^git commit|&& git commit| git commit\"; then\n BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"\")\n if [ -n \"$BRANCH\" ] && [ \"$BRANCH\" != \"HEAD\" ]; then\n git fetch origin \"$BRANCH\" --quiet 2>/dev/null || true\n BEHIND=$(git rev-list HEAD..origin/\"$BRANCH\" --count 2>/dev/null || echo \"0\")\n if [[ \"$BEHIND\" -gt 0 ]]; then\n echo \"\"\n echo \" BLOCKED: Branch '$BRANCH' is $BEHIND commit(s) behind origin/$BRANCH.\"\n echo \" Pull first: git pull origin $BRANCH\"\n echo \"\"\n exit 2\n fi\n fi\nfi\n\nexit 0\n`;\n\n writeFileSync(guardPath, guardScript, \"utf-8\");\n chmodSync(guardPath, 0o755);\n success(\".claude/hooks/git-guard.sh (PreToolUse — blocks unsafe git ops)\");\n\n // ── git-post.sh (PostToolUse) ──────────────────────────────────\n const postPath = join(hooksDir, \"git-post.sh\");\n const postScript = `#!/bin/bash\n# codebase git-post — PostToolUse hook\n# Reads Claude tool input JSON from stdin. Reminds to raise PR after branch push.\n\nINPUT=$(cat)\nCMD=$(echo \"$INPUT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('command',''))\" 2>/dev/null || echo \"\")\n\nif [ -z \"$CMD\" ]; then exit 0; fi\n\n# ── Remind to raise PR after pushing a non-develop/main branch ──\nif echo \"$CMD\" | grep -qE \"git push origin [a-zA-Z0-9/_-]+\"; then\n PUSHED_BRANCH=$(echo \"$CMD\" | grep -oE \"git push origin [a-zA-Z0-9/_-]+\" | awk '{print $4}')\n if [[ -n \"$PUSHED_BRANCH\" ]] && \\\n [[ \"$PUSHED_BRANCH\" != \"main\" ]] && \\\n [[ \"$PUSHED_BRANCH\" != \"master\" ]] && \\\n [[ \"$PUSHED_BRANCH\" != \"develop\" ]] && \\\n [[ \"$PUSHED_BRANCH\" != \"prod\" ]]; then\n echo \"\"\n echo \" Branch '$PUSHED_BRANCH' pushed.\"\n echo \" Raise a PR to develop:\"\n echo \" gh pr create --base develop --head $PUSHED_BRANCH --title 'feat: <description>' --body 'Closes #<N>'\"\n echo \"\"\n fi\nfi\n\nexit 0\n`;\n\n writeFileSync(postPath, postScript, \"utf-8\");\n chmodSync(postPath, 0o755);\n success(\".claude/hooks/git-post.sh (PostToolUse — PR reminder after branch push)\");\n\n // ── .claude/settings.json ─────────────────────────────────────\n const settingsPath = join(root, \".claude\", \"settings.json\");\n let settings: Record<string, unknown> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = JSON.parse(readFileSync(settingsPath, \"utf-8\"));\n } catch {\n /* ignore */\n }\n }\n\n const hooks = (settings.hooks as Record<string, unknown[]> | undefined) ?? {};\n\n const guardCmd = `bash .claude/hooks/git-guard.sh`;\n const postCmd = `bash .claude/hooks/git-post.sh`;\n\n // PreToolUse — add guard if not already present\n const preHooks = (hooks[\"PreToolUse\"] as unknown[]) ?? [];\n const hasGuard = JSON.stringify(preHooks).includes(\"git-guard\");\n if (!hasGuard) {\n preHooks.push({\n matcher: \"Bash\",\n hooks: [{ type: \"command\", command: guardCmd }],\n });\n }\n hooks[\"PreToolUse\"] = preHooks;\n\n // PostToolUse — add post if not already present\n const postHooks = (hooks[\"PostToolUse\"] as unknown[]) ?? [];\n const hasPost = JSON.stringify(postHooks).includes(\"git-post\");\n if (!hasPost) {\n postHooks.push({\n matcher: \"Bash\",\n hooks: [{ type: \"command\", command: postCmd }],\n });\n }\n hooks[\"PostToolUse\"] = postHooks;\n\n settings.hooks = hooks;\n writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + \"\\n\", \"utf-8\");\n success(\".claude/settings.json (PreToolUse + PostToolUse hooks registered)\");\n}\n\n// ─── commit-msg hook: block commits directly to main/master ─────\n\nfunction installBranchHook(root: string): void {\n const hooksDir = join(root, \".git\", \"hooks\");\n const hookPath = join(hooksDir, \"commit-msg\");\n const marker = \"# codebase-branch-check\";\n\n const script = `#!/bin/sh\n${marker}\nBRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)\nif [ \"$BRANCH\" = \"main\" ] || [ \"$BRANCH\" = \"master\" ]; then\n echo \"\"\n echo \" Direct commits to $BRANCH are not allowed.\"\n echo \" Switch to develop: git checkout develop\"\n echo \" Release via: codebase release\"\n echo \"\"\n exit 1\nfi\n`;\n\n if (existsSync(hookPath)) {\n const existing = readFileSync(hookPath, \"utf-8\");\n if (!existing.includes(marker)) {\n writeFileSync(hookPath, existing.trimEnd() + \"\\n\\n\" + script, \"utf-8\");\n }\n } else {\n writeFileSync(hookPath, script, \"utf-8\");\n }\n chmodSync(hookPath, 0o755);\n}\n\n// ─── .gitignore helper ───────────────────────────────────────────\n\nfunction appendToGitignore(root: string, lines: string[]): void {\n const p = join(root, \".gitignore\");\n const existing = existsSync(p) ? readFileSync(p, \"utf-8\") : \"\";\n const toAdd = lines.filter((l) => !existing.includes(l)).join(\"\\n\");\n if (toAdd) {\n writeFileSync(p, existing.trimEnd() + \"\\n\" + toAdd + \"\\n\", \"utf-8\");\n }\n}\n\n// ─── gh helpers ──────────────────────────────────────────────────\n\nfunction execGh(root: string, args: string[]): Promise<{ ok: boolean; stdout: string }> {\n return new Promise((resolve) => {\n execFile(\"gh\", args, { cwd: root, timeout: 15_000 }, (err, stdout) => {\n resolve({ ok: !err, stdout: (stdout || \"\").trim() });\n });\n });\n}\n\nasync function installAgentBrowser(): Promise<void> {\n const installed = await new Promise<boolean>((resolve) => {\n execFile(\"agent-browser\", [\"--version\"], { timeout: 5_000 }, (err) => resolve(!err));\n });\n if (installed) {\n info(\"agent-browser already installed\");\n return;\n }\n\n log(\"Installing agent-browser...\");\n const ok = await new Promise<boolean>((resolve) => {\n execFile(\"npm\", [\"install\", \"-g\", \"agent-browser\"], { timeout: 120_000 }, (err) =>\n resolve(!err)\n );\n });\n if (!ok) {\n warn(\"agent-browser install failed — run: npm install -g agent-browser\");\n return;\n }\n\n const chrome = await new Promise<boolean>((resolve) => {\n execFile(\"agent-browser\", [\"install\"], { timeout: 300_000 }, (err) => resolve(!err));\n });\n if (chrome) {\n success(\"agent-browser installed (Chrome for Testing downloaded)\");\n } else {\n warn(\"agent-browser installed but Chrome download failed — run: agent-browser install\");\n }\n\n // Post-install validation\n const valid = await new Promise<boolean>((resolve) => {\n execFile(\"agent-browser\", [\"--version\"], { timeout: 5_000 }, (err) => resolve(!err));\n });\n if (!valid) {\n warn(\n \"agent-browser validation failed — it may not be on PATH. Try: npm install -g agent-browser\"\n );\n }\n}\n\nasync function checkClaude(): Promise<boolean> {\n return new Promise((resolve) => {\n execFile(\"claude\", [\"--version\"], { timeout: 5_000 }, (err) => resolve(!err));\n });\n}\n\nasync function checkGh(): Promise<boolean> {\n return new Promise((resolve) => {\n execFile(\"gh\", [\"auth\", \"status\"], { timeout: 5_000 }, (err) => resolve(!err));\n });\n}\n\nasync function installLabels(root: string): Promise<void> {\n const { stdout } = await execGh(root, [\n \"label\",\n \"list\",\n \"--limit\",\n \"100\",\n \"--json\",\n \"name\",\n \"--jq\",\n \".[].name\",\n ]);\n const existing = new Set(stdout.split(\"\\n\").filter(Boolean));\n\n let created = 0;\n for (const label of VIBEKIT_LABELS) {\n if (existing.has(label.name)) {\n continue;\n }\n const { ok } = await execGh(root, [\n \"label\",\n \"create\",\n label.name,\n \"--color\",\n label.color,\n \"--description\",\n label.description,\n ]);\n if (ok) {\n created++;\n }\n }\n\n const skipped = VIBEKIT_LABELS.length - created;\n if (created > 0) {\n success(`${created} GitHub labels created (${skipped} already existed)`);\n } else {\n info(`All ${VIBEKIT_LABELS.length} labels already exist`);\n }\n}\n\nasync function ensureHighlightsIndex(root: string): Promise<void> {\n const { stdout } = await execGh(root, [\n \"issue\",\n \"list\",\n \"--search\",\n \"Highlights Index\",\n \"--state\",\n \"all\",\n \"--limit\",\n \"1\",\n \"--json\",\n \"number\",\n \"--jq\",\n \".[0].number // empty\",\n ]);\n if (stdout) {\n info(\"Highlights Index issue already exists\");\n return;\n }\n\n const body = `# Product Highlights Index\n\nTracks positive signals from /simulate cycles. Updated automatically — do not edit manually.\n\n## Index\n<!-- /simulate appends here -->`;\n\n const { ok } = await execGh(root, [\n \"issue\",\n \"create\",\n \"--title\",\n \"Highlights Index\",\n \"--label\",\n \"highlight\",\n \"--body\",\n body,\n ]);\n if (ok) {\n success(\"Highlights Index issue created on GitHub\");\n } else {\n warn(\"Could not create Highlights Index issue\");\n }\n}\n\n// ─── PRODUCT.md skeleton from manifest ───────────────────────────\n\nfunction generateProductMd(root: string, outputPath: string): void {\n const manifestPath = join(root, \".codebase.json\");\n let manifest: Manifest | null = null;\n if (existsSync(manifestPath)) {\n try {\n manifest = JSON.parse(readFileSync(manifestPath, \"utf-8\")) as Manifest;\n } catch {\n /* ignore */\n }\n }\n\n const name = manifest?.project?.name ?? \"[INFERRED: project name]\";\n const description = manifest?.project?.description ?? \"[INFERRED: one-line description]\";\n const langs = (manifest?.stack?.languages ?? []).join(\", \") || \"[INFERRED]\";\n const frameworks = (manifest?.stack?.frameworks ?? []).join(\", \") || \"[INFERRED]\";\n const devCmd = manifest?.commands?.dev ?? \"[INFERRED]\";\n const buildCmd = manifest?.commands?.build ?? \"[INFERRED]\";\n const testCmd = manifest?.commands?.test ?? \"[INFERRED]\";\n\n writeFileSync(\n outputPath,\n `# PRODUCT.md — ${name}\n\n> Auto-generated by \\`codebase setup\\`. Fill in any [INFERRED] sections.\n\n## Summary\n\n${description}\n\n## ICP (Ideal Customer Profile)\n\n- **Company size:** [INFERRED: e.g. 10–500 employees]\n- **Industry:** [INFERRED: e.g. SaaS, FinTech, DevTools]\n- **Geography:** [INFERRED: e.g. North America, Europe]\n- **Buyer role:** [INFERRED: e.g. CTO, Engineering Manager]\n\n## User Roles\n\n| Role | Description | Primary Use Cases |\n|------|-------------|------------------|\n| [Role 1] | [INFERRED] | [INFERRED] |\n| [Role 2] | [INFERRED] | [INFERRED] |\n\n## Pain Points\n\n1. [INFERRED: primary pain point]\n2. [INFERRED: secondary pain point]\n3. [INFERRED: tertiary pain point]\n\n## Competitive Context\n\n- **Alternatives:** [INFERRED: what users do without this product]\n- **Key differentiators:** [INFERRED: why we win]\n\n## Tech Stack (auto-detected)\n\n- **Languages:** ${langs}\n- **Frameworks:** ${frameworks}\n- **Dev command:** \\`${devCmd}\\`\n- **Build command:** \\`${buildCmd}\\`\n- **Test command:** \\`${testCmd}\\`\n\n## Dev Credentials\n\n- **Default seed creds:** \\`{role}@dev.local\\` / \\`dev123456\\`\n- **Dev login path:** [INFERRED: e.g. /dev-login or /auth/login]\n\n## Known Constraints\n\n- [INFERRED: e.g. multi-tenant, RBAC, GDPR]\n`,\n \"utf-8\"\n );\n}\n","import { bold, code, command, link, dim } from \"./output.js\";\n\ninterface CommandHelp {\n description: string;\n usage: string;\n examples: Array<{ command: string; description: string }>;\n options?: Array<{ flag: string; description: string }>;\n seeAlso?: string[];\n}\n\nconst HELP: Record<string, CommandHelp> = {\n scan: {\n description:\n \"Scan project and update .codebase.json manifest (lightweight — no AI tool injection)\",\n usage: \"codebase scan [path] [options]\",\n examples: [\n { command: \"codebase scan\", description: \"Scan current directory\" },\n { command: \"codebase scan ./my-project\", description: \"Scan specific directory\" },\n { command: \"codebase scan --depth 6\", description: \"Include deeper directory structure\" },\n {\n command: \"codebase scan --categories stack,commands\",\n description: \"Scan only specific categories\",\n },\n ],\n options: [\n { flag: \"--path <dir>\", description: \"Target project directory (default: current)\" },\n { flag: \"--depth <n>\", description: \"Directory tree depth (default: 4)\" },\n { flag: \"--categories <list>\", description: \"Comma-separated categories to scan\" },\n { flag: \"--incremental\", description: \"Only re-scan changed areas\" },\n { flag: \"--quiet\", description: \"Suppress stdout output\" },\n { flag: \"--sync\", description: \"Sync GitHub data (requires gh CLI)\" },\n ],\n },\n\n init: {\n description: \"Initialize codebase with full setup (scan + AI tools + hooks)\",\n usage: \"codebase init [options]\",\n examples: [\n { command: \"codebase init\", description: \"One-time setup for current project\" },\n {\n command: \"codebase init --dry-run\",\n description: \"Preview changes without modifying files\",\n },\n { command: \"codebase init --sync\", description: \"Include GitHub data sync\" },\n ],\n options: [\n { flag: \"--dry-run\", description: \"Preview changes without applying\" },\n { flag: \"--sync\", description: \"Sync GitHub data (requires gh CLI)\" },\n { flag: \"--quiet\", description: \"Suppress output\" },\n ],\n seeAlso: [\"scan\", \"setup\"],\n },\n\n setup: {\n description: \"Wire .codebase.json into Claude Code and install slash commands\",\n usage: \"codebase setup [options]\",\n examples: [\n {\n command: \"codebase setup\",\n description: \"Configure Claude Code, git hooks, and slash commands\",\n },\n ],\n options: [{ flag: \"--dry-run\", description: \"Preview changes\" }],\n },\n\n brief: {\n description:\n \"Get comprehensive project briefing (AI-facing). (GitHub STATUS section requires gh CLI auth)\",\n usage: \"codebase brief [options]\",\n examples: [\n { command: \"codebase brief\", description: \"Full project overview in one call\" },\n {\n command: \"codebase brief --format json | jq '.stack'\",\n description: \"Extract specific section as JSON\",\n },\n {\n command: \"codebase brief --categories stack,commands\",\n description: \"Only include selected sections\",\n },\n ],\n options: [\n {\n flag: \"--format <fmt>\",\n description: \"Output format: text (default), json, markdown\",\n },\n {\n flag: \"--categories <list>\",\n description:\n \"Comma-separated sections to include: stack,commands,status,git,roadmap,decisions\",\n },\n ],\n seeAlso: [\"next\", \"status\"],\n },\n\n next: {\n description: \"Show highest-priority task, what's in progress, and what needs verification\",\n usage: \"codebase next\",\n examples: [\n { command: \"codebase next\", description: \"Show next task to work on\" },\n {\n command: \"# Output blocks: IN PROGRESS | NEXT TASK | NEEDS VERIFY | BLOCKERS\",\n description: \"Four sections covering current state at a glance\",\n },\n {\n command:\n \"# Priority order: P0/critical/urgent → vibekit/P1/high/bug → P2/medium/arch → P3/low → feature → unlabeled\",\n description: \"How issues are ranked\",\n },\n ],\n seeAlso: [\"brief\", \"status\"],\n },\n\n status: {\n description: \"Show kanban board, priorities, milestones, and decisions\",\n usage: \"codebase status [view]\",\n examples: [\n { command: \"codebase status\", description: \"Kanban board + priorities (default)\" },\n { command: \"codebase status milestones\", description: \"Milestone progress bars\" },\n { command: \"codebase status priorities\", description: \"Priority queue only\" },\n { command: \"codebase status decisions\", description: \"Architecture decisions log\" },\n { command: \"codebase status --mine\", description: \"Show only my assigned tasks\" },\n ],\n options: [\n { flag: \"[view]\", description: \"One of: (none), milestones, priorities, decisions\" },\n { flag: \"--mine\", description: \"Show only your assigned items\" },\n ],\n seeAlso: [\"brief\", \"next\"],\n },\n\n query: {\n description: \"Query specific field from manifest using dot-path\",\n usage: \"codebase query <path> [options]\",\n examples: [\n { command: \"codebase query stack.languages\", description: 'Get: [\"typescript\"]' },\n { command: \"codebase query commands.test --force | sh\", description: \"Run test command\" },\n { command: \"codebase query dependencies.notable\", description: \"List notable packages\" },\n ],\n options: [{ flag: \"--force\", description: \"Plain text output (no JSON)\" }],\n },\n\n issue: {\n description: \"Manage GitHub issues\",\n usage: \"codebase issue <subcommand> [args]\",\n examples: [\n { command: 'codebase issue create \"Fix auth bug\"', description: \"Create new issue\" },\n {\n command: 'codebase issue close 42 --reason \"Fixed in PR #123\"',\n description: \"Close with reason\",\n },\n {\n command: 'codebase issue comment 42 --message \"Fixed by refactoring auth flow\"',\n description: \"Add comment\",\n },\n { command: \"codebase issue list\", description: \"List all issues\" },\n { command: \"codebase issue list --mine\", description: \"List your issues\" },\n ],\n options: [\n { flag: \"--message <text>\", description: \"Issue body (for create) or comment text\" },\n { flag: \"-m <text>\", description: \"Shorthand for --message\" },\n { flag: \"--reason <text>\", description: \"Close reason\" },\n ],\n },\n\n mcp: {\n description:\n \"Start MCP server for AI tool integration (Transport: stdio, Protocol: 2024-11-05). .mcp.json is written automatically by `codebase init`\",\n usage: \"codebase mcp\",\n examples: [\n { command: \"codebase mcp\", description: \"Start stdio MCP server\" },\n {\n command:\n \"# Tools: project_brief, get_codebase, query_codebase, get_next_task, get_blockers,\",\n description: \"\",\n },\n {\n command: \"# create_issue, close_issue, update_issue, get_issue, get_pr,\",\n description: \"\",\n },\n {\n command:\n \"# list_commands, list_skills, get_plan, update_plan, rescan_project, refresh_status\",\n description: \"16 tools total\",\n },\n ],\n seeAlso: [\"serve\"],\n },\n\n serve: {\n description: \"Start HTTP server (REST alternative to MCP, default port 3000)\",\n usage: \"codebase serve [--port N]\",\n examples: [\n { command: \"codebase serve\", description: \"Start HTTP server on port 3000\" },\n { command: \"codebase serve --port 8080\", description: \"Start on custom port\" },\n ],\n options: [{ flag: \"--port <n>\", description: \"Port to listen on (default: 3000)\" }],\n seeAlso: [\"mcp\"],\n },\n\n skills: {\n description: \"List installed Claude skills\",\n usage: \"codebase skills\",\n examples: [\n { command: \"codebase skills\", description: \"List all installed skills with descriptions\" },\n ],\n seeAlso: [\"setup\"],\n },\n\n doctor: {\n description: \"Diagnose setup and configuration issues\",\n usage: \"codebase doctor\",\n examples: [{ command: \"codebase doctor\", description: \"Run health check\" }],\n seeAlso: [\"fix\"],\n },\n\n fix: {\n description: \"Auto-repair issues found by doctor\",\n usage: \"codebase fix\",\n examples: [{ command: \"codebase fix\", description: \"Auto-fix all issues\" }],\n seeAlso: [\"doctor\"],\n },\n\n release: {\n description: \"Gate check → tag → merge develop→main → GitHub release\",\n usage: \"codebase release [version] [options]\",\n examples: [\n { command: \"codebase release\", description: \"Auto-increment version and release\" },\n { command: \"codebase release v1.2.0\", description: \"Release with explicit version\" },\n { command: \"codebase release --dry-run\", description: \"Preview release without tagging\" },\n ],\n options: [\n { flag: \"--dry-run\", description: \"Preview release notes without creating tag or merge\" },\n ],\n seeAlso: [\"doctor\"],\n },\n};\n\nexport function printMainHelp(): void {\n console.log(`\n${bold(\"codebase\")} — One command. Every AI tool understands your project instantly.\n\n${bold(\"QUICK START\")}\n ${command(\"npx codebase\")} ← Run this once. That's it.\n\n${bold(\"AI INTERFACE\")}\n These are the commands your AI tools call:\n\n ${command(\"codebase brief\")} Full project briefing — run this first\n ${command(\"codebase next\")} What should I work on next?\n ${command(\"codebase status\")} Kanban board, priorities, milestones\n ${command(\"codebase query <path>\")} Query any field (e.g. ${code(\"stack.languages\")})\n\n${bold(\"AUTONOMOUS LOOP\")}\n After ${command(\"codebase setup\")}, these slash commands are available in Claude Code:\n\n ${command(\"/setup\")} Bootstrap project — labels, milestone, PRODUCT.md\n ${command(\"/simulate\")} AI customer journeys (agent-browser) + UX audit\n ${command(\"/build\")} Autonomous loop — build → test → simulate → repeat\n ${command(\"/launch\")} Gate check → tag → release → merge to main\n ${command(\"/review\")} Security, quality, deps, accessibility audit\n\n ${command(\"codebase skills\")} List installed Claude skills\n\n${bold(\"HUMAN COMMANDS\")}\n ${command(\"codebase init\")} Full setup (scan + AI tools + hooks)\n ${command(\"codebase scan\")} Update .codebase.json only (lightweight)\n ${command(\"codebase setup\")} Wire AI tools + install slash commands\n ${command(\"codebase release\")} Gate check → tag → develop→main\n ${command(\"codebase doctor\")} Health check & diagnostics\n\n${bold(\"OPTIONS\")}\n ${code(\"--help, -h\")} Show this help or command-specific help\n ${code(\"--version, -v\")} Show version\n ${code(\"--verbose\")} Show detailed progress\n ${code(\"--quiet\")} Suppress output\n\n${bold(\"EXAMPLES\")}\n ${command(\"npx codebase\")} # One-time setup\n ${command(\"codebase brief\")} # Project overview\n ${command(\"codebase next\")} # Next task\n ${command(\"codebase query commands.test --force | sh\")} # Run tests\n ${command('codebase issue create \"Fix bug\"')} # Track work\n\n${bold(\"GLOBAL OPTIONS\")}\n ${code(\"--path <dir>\")} Target directory (default: current)\n ${code(\"--verbose\")} Show detailed output\n ${code(\"--quiet\")} Minimal output\n\n${bold(\"LEARN MORE\")}\n Docs: ${link(\"https://github.com/ZySec-AI/codebase#readme\", \"README.md\")}\n Issues: ${link(\"https://github.com/ZySec-AI/codebase/issues\", \"Report a bug\")}\n Commands: ${command(\"codebase <command> --help\")} Show command-specific help\n`);\n}\n\nexport function printCommandHelp(commandName: string): void {\n const help = HELP[commandName];\n\n if (!help) {\n console.error(`\\n ${bold(\"✗\")} Unknown command: ${commandName}\\n`);\n console.log(` Run ${command(\"codebase --help\")} to see all commands.\\n`);\n process.exit(1);\n }\n\n console.log(`\n${bold(commandName)} — ${help.description}\n\n${bold(\"USAGE\")}\n ${code(help.usage)}\n${\n help.examples.length > 0\n ? `\n${bold(\"EXAMPLES\")}\n${help.examples.map((ex) => ` ${command(ex.command)}${dim(\" # \" + ex.description)}`).join(\"\\n\")}\n`\n : \"\"\n}${\n help.options\n ? `\n${bold(\"OPTIONS\")}\n${help.options.map((opt) => ` ${code(opt.flag.padEnd(25))} ${opt.description}`).join(\"\\n\")}\n`\n : \"\"\n }${\n help.seeAlso\n ? `\n${bold(\"SEE ALSO\")}\n ${help.seeAlso.map((c) => command(c)).join(\", \")}\n`\n : \"\"\n }${bold(\"MORE HELP\")}\n ${command(\"codebase --help\")} Show all commands\n ${link(\"https://github.com/ZySec-AI/codebase/docs\", \"Full documentation\")}\n`);\n}\n\n// Error messages with helpful suggestions\nexport const ERROR_SUGGESTIONS: Record<string, { message: string; suggestion: string }> = {\n E_NO_GIT: {\n message: \"Not a git repository\",\n suggestion: \"Initialize git first: \" + command(\"git init\"),\n },\n E_NO_PACKAGE_JSON: {\n message: \"No package.json found\",\n suggestion: \"Initialize project: \" + command(\"npm init\") + \" or \" + command(\"pnpm init\"),\n },\n E_GH_NOT_AUTHENTICATED: {\n message: \"GitHub CLI not authenticated\",\n suggestion: \"Run: \" + command(\"gh auth login\"),\n },\n E_MANIFEST_NOT_FOUND: {\n message: \".codebase.json not found\",\n suggestion: \"Run: \" + command(\"codebase init\") + \" to generate it\",\n },\n E_INVALID_PATH: {\n message: \"Invalid directory path\",\n suggestion: \"Use absolute path or path relative to current directory\",\n },\n E_PERMISSION_DENIED: {\n message: \"Permission denied\",\n suggestion: \"Check file permissions or run with appropriate access\",\n },\n};\n\nexport function getErrorSuggestion(\n errorCode: string\n): { message: string; suggestion: string } | undefined {\n return ERROR_SUGGESTIONS[errorCode];\n}\n","import type { CLIOptions } from \"../types.js\";\nimport { printMainHelp, printCommandHelp } from \"./help.js\";\n\nconst DEFAULTS: CLIOptions = {\n command: \"init\",\n subcommand: \"\",\n positionals: [],\n path: process.cwd(),\n format: \"text\",\n depth: 4,\n categories: [],\n incremental: false,\n quiet: false,\n force: false,\n verbose: false,\n port: 7432,\n tools: [],\n dryRun: false,\n since: \"\",\n sync: false,\n message: \"\",\n reason: \"\",\n examples: false,\n helpCommand: false,\n};\n\nconst COMMANDS = new Set([\n \"scan\",\n \"setup\",\n \"query\",\n \"mcp\",\n \"issue\",\n \"status\",\n \"init\",\n \"scan-only\",\n \"brief\",\n \"next\",\n \"doctor\",\n \"fix\",\n \"release\",\n \"plan\",\n \"skills\",\n \"serve\",\n]);\n\nexport function parseArgs(argv: string[]): CLIOptions {\n const opts: CLIOptions = { ...DEFAULTS };\n const positionals: string[] = [];\n\n // First pass: check for command to enable --help for specific commands\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (!arg.startsWith(\"-\") && COMMANDS.has(arg)) {\n opts.command = arg;\n // Check if next arg is --help\n if (argv[i + 1] === \"--help\" || argv[i + 1] === \"-h\") {\n opts.helpCommand = true;\n return opts;\n }\n break;\n }\n }\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n\n // Global help (no command specified yet)\n if ((arg === \"--help\" || arg === \"-h\") && !opts.command) {\n printMainHelp();\n process.exit(0);\n }\n\n if (arg === \"--version\" || arg === \"-v\") {\n console.log(`codebase ${__VERSION__}`);\n process.exit(0);\n }\n\n if (arg.startsWith(\"--\")) {\n const key = arg.slice(2);\n\n if (key === \"quiet\" || key === \"q\") {\n opts.quiet = true;\n continue;\n }\n if (key === \"force\") {\n opts.force = true;\n continue;\n }\n if (key === \"raw\") {\n console.error(\"Warning: --raw is deprecated, use --force instead\");\n opts.force = true;\n continue;\n }\n if (key === \"verbose\" || key === \"V\") {\n opts.verbose = true;\n continue;\n }\n if (key === \"incremental\") {\n opts.incremental = true;\n continue;\n }\n if (key === \"dry-run\") {\n opts.dryRun = true;\n continue;\n }\n if (key === \"sync\") {\n opts.sync = true;\n continue;\n }\n if (key === \"examples\") {\n opts.examples = true;\n continue;\n }\n if (key === \"mine\") {\n positionals.push(\"mine\");\n continue;\n }\n\n const next = argv[i + 1];\n if (!next || next.startsWith(\"--\")) {\n continue;\n }\n i++;\n\n if (key === \"path\") {\n opts.path = next;\n } else if (key === \"format\") {\n opts.format = next;\n } else if (key === \"depth\") {\n opts.depth = parseInt(next, 10) || 4;\n } else if (key === \"categories\") {\n opts.categories = next.split(\",\").map((s) => s.trim());\n } else if (key === \"port\") {\n opts.port = parseInt(next, 10) || 7432;\n } else if (key === \"tools\") {\n opts.tools = next.split(\",\").map((s) => s.trim());\n } else if (key === \"since\") {\n opts.since = next;\n } else if (key === \"message\" || key === \"m\") {\n opts.message = next;\n } else if (key === \"reason\") {\n opts.reason = next;\n }\n\n continue;\n }\n\n positionals.push(arg);\n }\n\n // First positional is command (if recognized)\n if (positionals.length > 0 && COMMANDS.has(positionals[0])) {\n opts.command = positionals.shift()!;\n }\n\n // Second positional could be subcommand (for hook install/uninstall, issue create/close/list)\n if (positionals.length > 0) {\n const sub = positionals[0];\n if ([\"install\", \"uninstall\", \"create\", \"close\", \"comment\", \"list\", \"map\"].includes(sub)) {\n opts.subcommand = positionals.shift()!;\n }\n }\n\n opts.positionals = positionals;\n\n // If remaining positional looks like a path (starts with / or . or ~), use it\n if (positionals.length > 0 && /^[\\/\\.~]/.test(positionals[0])) {\n opts.path = positionals[0];\n }\n\n // Env var overrides\n if (process.env.CODEBASE_OUTPUT) {\n opts.path = process.env.CODEBASE_OUTPUT;\n }\n if (process.env.CODEBASE_PORT) {\n opts.port = parseInt(process.env.CODEBASE_PORT, 10) || 7432;\n }\n if (process.env.CODEBASE_DEPTH) {\n opts.depth = parseInt(process.env.CODEBASE_DEPTH, 10) || 4;\n }\n if (process.env.CODEBASE_QUIET === \"true\") {\n opts.quiet = true;\n }\n\n return opts;\n}\n\nexport function showCommandHelp(commandName: string): void {\n printCommandHelp(commandName);\n process.exit(0);\n}\n","import { parseArgs, showCommandHelp } from \"./utils/args.js\";\nimport { setQuiet, setVerbose, error, info, bold } from \"./utils/output.js\";\nimport { checkForUpdate } from \"./utils/update-check.js\";\nimport { runScan } from \"./commands/scan.js\";\nimport { runSetup } from \"./commands/setup.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runBrief } from \"./commands/brief.js\";\nimport { runNext } from \"./commands/next.js\";\nimport { runQuery } from \"./commands/query.js\";\nimport { runIssue } from \"./commands/issue.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { runMcp } from \"./commands/mcp.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { runFix } from \"./commands/fix.js\";\nimport { runRelease } from \"./commands/release.js\";\nimport { runPlan } from \"./commands/plan.js\";\nimport { runSkills } from \"./commands/skills.js\";\nimport { startServer } from \"./server/index.js\";\nimport type { CLIOptions } from \"./types.js\";\n\nconst options = parseArgs(process.argv.slice(2));\n\n// Set global output options\nsetQuiet(options.quiet);\nsetVerbose(options.verbose);\n\n// Show command-specific help if requested\nif (options.helpCommand && options.command) {\n showCommandHelp(options.command);\n}\n\nconst commands: Record<string, (opts: CLIOptions) => Promise<void>> = {\n // \"scan\" updates .codebase.json only — lightweight, no AI tool injection\n scan: runScan,\n init: runInit,\n // AI-facing commands — these are the interface\n brief: runBrief,\n next: runNext,\n setup: runSetup,\n query: runQuery,\n issue: runIssue,\n status: runStatus,\n mcp: runMcp,\n doctor: runDoctor,\n fix: runFix,\n release: runRelease,\n plan: runPlan,\n skills: runSkills,\n serve: (opts: CLIOptions) => {\n startServer(opts.path, opts.port ?? 3000);\n return Promise.resolve();\n },\n // Keep \"scan-only\" for hooks that just want manifest refresh\n \"scan-only\": runScan,\n};\n\n// Non-blocking update check — runs in background, shows prompt if outdated\ncheckForUpdate().catch(() => {});\n\n// Node.js version check\nconst [major] = process.versions.node.split(\".\").map(Number);\nif (major < 20) {\n console.error(\n `Error: Node.js 20 or higher is required. You are running v${process.versions.node}.`\n );\n console.error(\"Upgrade: https://nodejs.org\");\n process.exit(1);\n}\n\nconst handler = commands[options.command];\nif (!handler) {\n error(`Unknown command: ${options.command}`);\n info(`Run ${bold(\"codebase --help\")} to see all commands.`);\n process.exit(1);\n}\n\nhandler(options).catch((err: Error) => {\n error(`Error: ${err.message}`);\n\n // Show helpful suggestions based on error message\n const msg = err.message.toLowerCase();\n if (msg.includes(\"not a git repository\")) {\n info(`Initialize git first: ${bold(\"git init\")}`);\n } else if (msg.includes(\"permission denied\")) {\n info(\"Check file permissions or run with appropriate access\");\n } else if (msg.includes(\"enoent\") && msg.includes(\"gh\")) {\n info(\n `GitHub CLI (gh) is not installed. Install it: ${bold(\"brew install gh && gh auth login\")}`\n );\n } else if (msg.includes(\"no such file\")) {\n info(\"Check that the path is correct\");\n } else if (msg.includes(\"github\")) {\n info(`Ensure GitHub CLI is installed: ${bold(\"gh --version\")}`);\n info(`Authenticate: ${bold(\"gh auth login\")}`);\n }\n\n process.exit(1);\n});\n","import { get } from \"https\";\nimport { readFileSync, writeFileSync, mkdirSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport { execSync, spawnSync } from \"child_process\";\n\nconst CACHE_DIR = join(homedir(), \".codebase\");\nconst CACHE_FILE = join(CACHE_DIR, \"update-check.json\");\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst NPM_PACKAGE = \"codebase-ai\";\n\nconst NO_COLOR = !!process.env.NO_COLOR;\nconst c = {\n yellow: NO_COLOR ? \"\" : \"\\x1b[33m\",\n cyan: NO_COLOR ? \"\" : \"\\x1b[36m\",\n green: NO_COLOR ? \"\" : \"\\x1b[32m\",\n bold: NO_COLOR ? \"\" : \"\\x1b[1m\",\n dim: NO_COLOR ? \"\" : \"\\x1b[2m\",\n reset: NO_COLOR ? \"\" : \"\\x1b[0m\",\n};\n\nfunction getCurrentVersion(): string {\n // __VERSION__ is injected at build time by tsup — works regardless of bundling\n if (typeof __VERSION__ !== \"undefined\") {\n return __VERSION__;\n }\n return \"0.0.0\";\n}\n\nfunction isNewer(latest: string, current: string): boolean {\n const parse = (v: string) => v.replace(/^v/, \"\").split(\".\").map(Number);\n const [lMaj, lMin, lPatch] = parse(latest);\n const [cMaj, cMin, cPatch] = parse(current);\n if (lMaj !== cMaj) {\n return lMaj > cMaj;\n }\n if (lMin !== cMin) {\n return lMin > cMin;\n }\n return lPatch > cPatch;\n}\n\nfunction readCache(): { version: string; checkedAt: number } | null {\n try {\n return JSON.parse(readFileSync(CACHE_FILE, \"utf8\")) as {\n version: string;\n checkedAt: number;\n };\n } catch {\n return null;\n }\n}\n\nfunction writeCache(version: string): void {\n try {\n mkdirSync(CACHE_DIR, { recursive: true });\n writeFileSync(CACHE_FILE, JSON.stringify({ version, checkedAt: Date.now() }));\n } catch {\n // ignore\n }\n}\n\nfunction fetchLatestVersion(): Promise<string> {\n return new Promise((resolve, reject) => {\n const req = get(\n `https://registry.npmjs.org/${NPM_PACKAGE}/latest`,\n { headers: { accept: \"application/json\" } },\n (res) => {\n let data = \"\";\n res.on(\"data\", (chunk: Buffer) => (data += chunk.toString()));\n res.on(\"end\", () => {\n try {\n resolve((JSON.parse(data) as { version: string }).version);\n } catch {\n reject(new Error(\"parse error\"));\n }\n });\n }\n );\n req.on(\"error\", reject);\n req.setTimeout(3000, () => {\n req.destroy();\n reject(new Error(\"timeout\"));\n });\n });\n}\n\n/** Detect how codebase was installed so we use the right upgrade command. */\nfunction detectInstallCommand(): string {\n try {\n // If installed via npm global, npm root -g will contain the package\n const npmGlobal = execSync(\"npm root -g 2>/dev/null\", { encoding: \"utf8\" }).trim();\n const found = npmGlobal && readFileSync(`${npmGlobal}/${NPM_PACKAGE}/package.json`, \"utf8\");\n if (found) {\n return `npm install -g ${NPM_PACKAGE}@latest`;\n }\n } catch {\n /* fall through */\n }\n\n try {\n execSync(\"pnpm --version 2>/dev/null\", { encoding: \"utf8\" });\n const pnpmGlobal = execSync(\"pnpm root -g 2>/dev/null\", { encoding: \"utf8\" }).trim();\n const found = pnpmGlobal && readFileSync(`${pnpmGlobal}/${NPM_PACKAGE}/package.json`, \"utf8\");\n if (found) {\n return `pnpm add -g ${NPM_PACKAGE}@latest`;\n }\n } catch {\n /* fall through */\n }\n\n try {\n execSync(\"yarn --version 2>/dev/null\", { encoding: \"utf8\" });\n return `yarn global add ${NPM_PACKAGE}@latest`;\n } catch {\n /* fall through */\n }\n\n return `npm install -g ${NPM_PACKAGE}@latest`;\n}\n\nfunction runUpgrade(cmd: string): boolean {\n const [bin, ...args] = cmd.split(\" \");\n const result = spawnSync(bin, args, { stdio: \"inherit\" });\n return result.status === 0;\n}\n\n/** Read a single keypress from stdin without requiring Enter. */\nfunction readKey(): Promise<string> {\n return new Promise((resolve) => {\n const stdin = process.stdin;\n const wasTTY = stdin.isTTY;\n\n if (wasTTY) {\n stdin.setRawMode(true);\n }\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n\n const onData = (key: string) => {\n if (wasTTY) {\n stdin.setRawMode(false);\n }\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n resolve(key);\n };\n\n stdin.on(\"data\", onData);\n\n // Timeout after 10s — treat as skip\n setTimeout(() => {\n if (wasTTY) {\n stdin.setRawMode(false);\n }\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n resolve(\"n\");\n }, 10_000);\n });\n}\n\nexport async function checkForUpdate(): Promise<void> {\n // Skip in CI, piped output, or explicitly disabled\n if (process.env.CI || process.env.NO_UPDATE_CHECK || process.env.CODEBASE_NO_UPDATE_CHECK) {\n return;\n }\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n return;\n }\n\n const current = getCurrentVersion();\n\n const cache = readCache();\n let latest: string;\n\n if (cache && Date.now() - cache.checkedAt < CACHE_TTL_MS) {\n latest = cache.version;\n } else {\n try {\n latest = await fetchLatestVersion();\n writeCache(latest);\n } catch {\n return;\n }\n }\n\n if (!isNewer(latest, current)) {\n return;\n }\n\n const installCmd = detectInstallCommand();\n\n // Banner\n console.log(`\\n ${c.yellow}┌─────────────────────────────────────────────────┐${c.reset}`);\n console.log(\n ` ${c.yellow}│${c.reset} ${c.bold}Update available${c.reset} ` +\n `${c.dim}${current}${c.reset} ${c.yellow}→${c.reset} ${c.bold}${c.cyan}${latest}${c.reset}`\n );\n console.log(\n ` ${c.yellow}│${c.reset} Press ${c.bold}Y${c.reset} to update now, any other key to skip`\n );\n console.log(` ${c.yellow}└─────────────────────────────────────────────────┘${c.reset}`);\n process.stdout.write(`\\n > `);\n\n const key = await readKey();\n const accepted = key.toLowerCase() === \"y\";\n\n console.log(accepted ? \"Updating…\" : \"Skipped.\\n\");\n\n if (!accepted) {\n return;\n }\n\n console.log(`\\n ${c.dim}$ ${installCmd}${c.reset}\\n`);\n const ok = runUpgrade(installCmd);\n\n if (ok) {\n console.log(\n `\\n ${c.green}✓${c.reset} ${c.bold}Updated to ${latest}!${c.reset} Restart codebase to use the new version.\\n`\n );\n } else {\n console.log(\n `\\n ${c.yellow}!${c.reset} Update failed. Run manually: ${c.bold}${installCmd}${c.reset}\\n`\n );\n }\n\n // Exit so the old binary doesn't continue running after upgrade\n process.exit(0);\n}\n","import { resolve, join } from \"node:path\";\nimport { existsSync, writeFileSync, readFileSync } from \"node:fs\";\nimport { execFile } from \"node:child_process\";\nimport { writeFile, rename } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport type { CLIOptions, Integration } from \"../types.js\";\nimport { scan, summarizeCategory } from \"../scanner/engine.js\";\nimport { detectTools } from \"../integrations/index.js\";\nimport { claudeIntegration } from \"../integrations/claude.js\";\nimport { updateGitignore } from \"../integrations/gitignore.js\";\nimport { installHooks } from \"../integrations/githook.js\";\nimport { log, success, info, warn, heading, setQuiet } from \"../utils/output.js\";\n\n/**\n * `npx codebase` — the ONE command that does everything:\n *\n * 1. Scans the project (code structure, stack, commands, patterns)\n * 2. Auto-detects `gh` CLI and syncs GitHub data (issues, PRs, milestones, decisions)\n * 3. Writes .codebase.json\n * 4. Detects all AI tools (project + global configs) and injects smart instructions\n * 5. Auto-configures MCP server in Claude Code\n * 6. Installs git hooks (post-commit + post-checkout) for auto-updates\n * 7. Updates .gitignore\n *\n * After this, the user never runs another codebase command manually.\n * Everything stays alive through hooks, MCP, and AI tool integrations.\n */\n/**\n * Detect if the project has already been initialized:\n * .codebase.json exists AND at least one AI tool has injection markers present.\n */\nfunction isAlreadyInitialized(root: string): boolean {\n if (!existsSync(join(root, \".codebase.json\"))) {\n return false;\n }\n // Check for Claude injection marker in CLAUDE.md — require BOTH start AND end markers\n const claudeMd = join(root, \"CLAUDE.md\");\n if (existsSync(claudeMd)) {\n try {\n const content = readFileSync(claudeMd, \"utf-8\");\n const hasHtmlMarkers =\n content.includes(\"<!-- codebase:start -->\") && content.includes(\"<!-- codebase:end -->\");\n const hasHashMarkers =\n content.includes(\"# codebase:start\") && content.includes(\"# codebase:end\");\n if (hasHtmlMarkers || hasHashMarkers) {\n return true;\n }\n } catch {\n /* unreadable */\n }\n }\n return false;\n}\n\nexport async function runInit(options: CLIOptions): Promise<void> {\n const _start = Date.now();\n setQuiet(options.quiet);\n const root = resolve(options.path);\n\n // If already initialized and not forced, just refresh the manifest\n if (isAlreadyInitialized(root) && !options.force) {\n heading(\"codebase — refreshing project manifest\\n\");\n const ghStatus = await checkGhDetailed();\n const ghAvailable = ghStatus === \"authenticated\";\n log(`Scanning ${root}...`);\n const manifest = await scan(root, {\n depth: options.depth,\n categories: options.categories.length ? options.categories : undefined,\n quiet: options.quiet,\n sync: ghAvailable,\n });\n const outputPath = join(root, \".codebase.json\");\n const content = JSON.stringify(manifest, null, 2);\n await writeFile(outputPath, content, \"utf-8\");\n const sizeKB = (Buffer.byteLength(content) / 1024).toFixed(1);\n success(`Manifest refreshed — .codebase.json (${sizeKB} KB)`);\n info(\"Already initialized. Run with --force to force full re-setup.\");\n return;\n }\n\n heading(\"codebase — activating project intelligence\\n\");\n\n // ─── Step 1: Detect GitHub CLI ──────────────────────────────────\n const ghStatus = await checkGhDetailed();\n\n if (ghStatus === \"authenticated\") {\n success(\"GitHub CLI — authenticated\");\n } else if (ghStatus === \"not-authenticated\") {\n warn(\"GitHub CLI installed but not logged in\");\n info(\"Run: gh auth login\");\n info(\"After login, re-run `npx codebase` for full GitHub integration\\n\");\n } else {\n info(\"GitHub CLI not found — GitHub features disabled\");\n info(\"To enable: brew install gh && gh auth login\\n\");\n }\n\n const ghAvailable = ghStatus === \"authenticated\";\n\n // ─── Step 2: Full scan + GitHub sync ───────────────────────────\n log(`Scanning ${root}...`);\n\n const manifest = await scan(root, {\n depth: options.depth,\n categories: options.categories.length ? options.categories : undefined,\n quiet: options.quiet,\n sync: ghAvailable,\n });\n\n for (const [category, data] of Object.entries(manifest)) {\n if (category === \"version\" || category === \"generated_at\") {\n continue;\n }\n if (typeof data !== \"object\" || data === null) {\n continue;\n }\n success(\n `${capitalize(category)} (${summarizeCategory(category, data as Record<string, unknown>)})`\n );\n }\n\n // Write manifest\n const outputPath = join(root, \".codebase.json\");\n const content = JSON.stringify(manifest, null, 2);\n await writeFile(outputPath, content, \"utf-8\");\n\n const sizeKB = (Buffer.byteLength(content) / 1024).toFixed(1);\n log(`\\nWritten: .codebase.json (${sizeKB} KB)`);\n\n // ─── Step 3: AI tool detection + integration ───────────────────\n heading(\"AI Tool Integration\");\n\n let tools = detectTools(root);\n const globalTools = detectGlobalTools();\n\n // Merge: project-level detection + global config detection\n const toolNames = new Set(tools.map((t) => t.name));\n for (const gt of globalTools) {\n if (!toolNames.has(gt.name)) {\n tools.push(gt);\n toolNames.add(gt.name);\n }\n }\n\n if (tools.length === 0) {\n // Nothing detected anywhere — create CLAUDE.md as universal default\n info(\"No AI tool detected in project or system configs\");\n info(\"Creating CLAUDE.md as default (works with Claude Code, and readable by all tools)\");\n writeFileSync(join(root, \"CLAUDE.md\"), \"# Project Rules\\n\\n\", \"utf-8\");\n tools = [claudeIntegration];\n } else {\n log(` Detected: ${tools.map((t) => t.name).join(\", \")}`);\n }\n\n for (const tool of tools) {\n const result = await tool.inject(root);\n if (result.ok) {\n success(`${tool.name} — instructions injected`);\n } else {\n warn(`${tool.name} — injection failed: ${result.message || \"unknown error\"}`);\n }\n }\n\n // ─── Step 4: Auto-configure MCP in supported tools ─────────────\n heading(\"MCP Server (native AI tool access)\");\n\n const mcpConfigured = await autoConfigureMcp(root, toolNames);\n if (mcpConfigured.length) {\n for (const tool of mcpConfigured) {\n success(`${tool} — MCP server auto-configured`);\n }\n info(\"AI tools can now call project_brief, get_next_task, create_issue, etc. natively\");\n } else {\n info(\"AI tools will read .codebase.json directly.\");\n info(\"To enable MCP later, add to your tool's MCP config:\");\n log(' { \"command\": \"npx\", \"args\": [\"codebase\", \"mcp\"] }');\n }\n\n // ─── Step 5: Git hooks (post-commit + post-checkout) ───────────\n heading(\"Auto-Update Hooks\");\n\n const hooksInstalled = installHooks(root, ghAvailable);\n if (hooksInstalled) {\n success(\"post-commit hook — manifest updates on every commit\");\n success(\"post-checkout hook — manifest updates on branch switch\");\n if (ghAvailable) {\n success(\"hooks include GitHub sync — issues/PRs stay current\");\n }\n } else {\n info(\"Not a git repository — skipping hooks\");\n }\n\n // ─── Step 6: Gitignore ─────────────────────────────────────────\n updateGitignore(root);\n success(\".gitignore updated\");\n\n // ─── Summary ───────────────────────────────────────────────────\n heading(\"Ready!\\n\");\n log(\"Your project is now fully activated. Here's what happens automatically:\\n\");\n log(\" On every commit → .codebase.json updates (code + GitHub data)\");\n log(\" On branch switch → .codebase.json updates\");\n log(\" When AI starts → reads .codebase.json or calls project_brief via MCP\");\n log(\" AI knows → stack, commands, open issues, priorities, blockers, decisions\");\n log(\" AI can → create issues, close issues, get next task, check blockers\\n\");\n\n if (ghAvailable) {\n const issueCount = manifest.status?.issues?.filter((i) => i.state === \"open\").length || 0;\n const prCount = manifest.status?.pull_requests?.filter((pr) => pr.state === \"open\").length || 0;\n if (issueCount || prCount) {\n log(` GitHub synced: ${issueCount} open issues, ${prCount} open PRs`);\n }\n }\n\n // ─── Sparse project hint ───────────────────────────────────────\n const langs = manifest.stack?.languages ?? [];\n const hasCommands = Object.keys(manifest.commands ?? {}).length > 0;\n const isSparse =\n !hasCommands && langs.every((l) => l === \"json\" || l === \"yaml\" || l === \"markdown\");\n if (isSparse) {\n log(\" Next steps for a new project:\");\n log(\" 1. Add your source files (e.g. src/index.ts, src/index.js)\");\n log(\" 2. Add scripts to package.json (build, test, dev, etc.)\");\n log(\" 3. Re-run `codebase` — the manifest will update automatically\\n\");\n }\n\n log(\"\\n You don't need to run this again. Everything stays alive.\\n\");\n const elapsed = ((Date.now() - _start) / 1000).toFixed(1);\n success(`Done (${elapsed}s)`);\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport type GhStatus = \"authenticated\" | \"not-authenticated\" | \"not-installed\";\n\n/**\n * Check gh CLI: not installed → installed but not logged in → fully authenticated.\n */\nexport function checkGhDetailed(): Promise<GhStatus> {\n return new Promise((resolve) => {\n // First check if gh is even installed\n execFile(\"sh\", [\"-c\", \"which gh 2>/dev/null\"], { timeout: 5_000 }, (err) => {\n if (err) {\n resolve(\"not-installed\");\n return;\n }\n // gh exists, check auth\n execFile(\n \"sh\",\n [\"-c\", \"gh auth status 2>&1\"],\n { timeout: 10_000 },\n (authErr, stdout, stderr) => {\n const output = (stdout || \"\") + (stderr || \"\");\n if (!authErr && output.includes(\"Logged in\")) {\n resolve(\"authenticated\");\n } else {\n resolve(\"not-authenticated\");\n }\n }\n );\n });\n });\n}\n\n/**\n * Detect AI tools from global/system-level config files.\n * Checks if Claude Code is installed globally.\n */\nexport function detectGlobalTools(): Integration[] {\n const home = homedir();\n const found: Integration[] = [];\n\n if (existsSync(join(home, \".claude\"))) {\n found.push(claudeIntegration);\n }\n\n return found;\n}\n\n/**\n * Auto-configure MCP server in Claude Code via project-level .mcp.json.\n */\nexport async function autoConfigureMcp(\n root: string,\n detectedTools: Set<string>\n): Promise<string[]> {\n const configured: string[] = [];\n const mcpEntry = {\n command: \"npx\",\n args: [\"codebase\", \"mcp\"],\n cwd: root,\n };\n\n if (detectedTools.has(\"claude\") || detectedTools.size === 0) {\n const projectMcpPath = join(root, \".mcp.json\");\n if (await configureMcpFile(projectMcpPath, \"codebase\", mcpEntry)) {\n configured.push(\"Claude Code (project .mcp.json)\");\n }\n }\n\n return configured;\n}\n\nexport async function configureMcpFile(\n filePath: string,\n serverName: string,\n entry: Record<string, unknown>\n): Promise<boolean> {\n let config: Record<string, unknown> = {};\n\n if (existsSync(filePath)) {\n try {\n config = JSON.parse(readFileSync(filePath, \"utf-8\"));\n } catch {\n config = {};\n }\n\n // Already configured?\n const servers = config.mcpServers as Record<string, unknown> | undefined;\n if (servers && servers[serverName]) {\n return false;\n }\n }\n\n if (!config.mcpServers) {\n config.mcpServers = {};\n }\n (config.mcpServers as Record<string, unknown>)[serverName] = entry;\n\n const tmpPath = `${filePath}.tmp`;\n await writeFile(tmpPath, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n await rename(tmpPath, filePath);\n return true;\n}\n","import type { Integration } from \"../types.js\";\nimport { claudeIntegration } from \"./claude.js\";\n\nexport const integrations: Integration[] = [claudeIntegration];\n\nexport function detectTools(root: string): Integration[] {\n return integrations.filter((i) => i.detect(root));\n}\n","import { resolve, join } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport type { CLIOptions, Manifest } from \"../types.js\";\nimport { generateBrief } from \"../mcp/brief.js\";\nimport { error, warn } from \"../utils/output.js\";\n\n/**\n * `codebase brief` — outputs a complete project briefing for AI consumption.\n *\n * This is THE interface for AI tools. They run this command and get back\n * everything they need to start working: project identity, stack, commands,\n * current status, next task, blockers, decisions, and available actions.\n *\n * Supports:\n * - --categories <list>: filter to specific sections (e.g., \"stack,commands,status\")\n * - --format <fmt>: output format (text, json, markdown) - default is text (markdown)\n *\n * No file reading. No JSON parsing. Just run the command, get the answer.\n */\nexport async function runBrief(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n const manifestPath = join(root, \".codebase.json\");\n\n if (!existsSync(manifestPath)) {\n console.error(\"No manifest found. Run 'codebase init' to set up this project first.\");\n process.exit(1);\n }\n\n let manifest: Manifest;\n try {\n const content = await readFile(manifestPath, \"utf-8\");\n manifest = JSON.parse(content);\n } catch {\n error(\"No .codebase.json found (or it's corrupted). Run `npx codebase` first.\");\n process.exit(1);\n }\n\n // Warn if GitHub data is absent\n if (!options.quiet && !manifest.status && !manifest.roadmap) {\n warn(\n \"GitHub data unavailable (gh not authenticated or --sync not used). Issues, PRs and milestones not included.\"\n );\n }\n\n // Filter by categories if specified\n let filteredManifest = manifest;\n if (options.categories.length > 0) {\n filteredManifest = filterManifest(manifest, options.categories);\n }\n\n // Generate output based on format\n const output = generateOutput(filteredManifest, options.format);\n process.stdout.write(output + \"\\n\");\n}\n\n/**\n * Filter manifest to only include specified categories.\n * Always includes 'project' for title/header context.\n *\n * Categories: repo, structure, stack, commands, dependencies,\n * config, git, quality, patterns, status, roadmap, decisions\n */\nfunction filterManifest(manifest: Manifest, categories: string[]): Manifest {\n const result: Manifest = {\n version: manifest.version,\n generated_at: manifest.generated_at,\n // Always include project for header\n project: manifest.project,\n };\n\n const categoryMap: Record<string, keyof Manifest> = {\n project: \"project\",\n repo: \"repo\",\n structure: \"structure\",\n stack: \"stack\",\n commands: \"commands\",\n dependencies: \"dependencies\",\n config: \"config\",\n git: \"git\",\n quality: \"quality\",\n patterns: \"patterns\",\n status: \"status\",\n roadmap: \"roadmap\",\n decisions: \"decisions\",\n };\n\n for (const cat of categories) {\n const key = categoryMap[cat.toLowerCase()];\n if (key && manifest[key]) {\n (result as unknown as Record<string, unknown>)[key] = manifest[key];\n }\n }\n\n return result;\n}\n\n/**\n * Generate output in the specified format.\n */\nfunction generateOutput(manifest: Manifest, format: string): string {\n if (format === \"json\") {\n return JSON.stringify(manifest, null, 2);\n }\n\n // Both \"text\" and \"markdown\" use the brief generator (markdown format)\n return generateBrief(manifest);\n}\n","import type { Manifest } from \"../types.js\";\n\n/**\n * Generates a natural-language project briefing for AI assistants.\n * This is the single most important output — it tells the AI everything\n * it needs to start working immediately.\n */\nexport function generateBrief(m: Manifest): string {\n const sections: string[] = [];\n\n // ─── Header ────────────────────────────────────────────────────\n const projectName = m.project?.name || \"Unknown Project\";\n sections.push(`# PROJECT BRIEF: ${projectName}`);\n if (m.project?.description) {\n sections.push(m.project.description);\n }\n sections.push(`\\nGenerated: ${m.generated_at}\\n`);\n\n // ─── What is this project? ─────────────────────────────────────\n sections.push(\"## Technical Overview\");\n const projectParts: string[] = [];\n\n if (m.repo?.url) {\n projectParts.push(`Repository: ${m.repo.url}`);\n projectParts.push(`Default branch: ${m.repo.default_branch || \"unknown\"}`);\n if (m.repo.is_monorepo) {\n projectParts.push(`Monorepo: yes (${m.repo.workspace_manager || \"workspaces\"})`);\n }\n }\n\n if (m.stack) {\n const techParts: string[] = [];\n if (m.stack.languages?.length) {\n techParts.push(`Languages: ${m.stack.languages.join(\", \")}`);\n }\n if (m.stack.frameworks?.length) {\n techParts.push(`Frameworks: ${m.stack.frameworks.join(\", \")}`);\n }\n if (m.stack.package_manager) {\n techParts.push(`Package manager: ${m.stack.package_manager}`);\n }\n if (m.stack.database) {\n techParts.push(`Database: ${m.stack.database}`);\n }\n if (m.stack.orm) {\n techParts.push(`ORM: ${m.stack.orm}`);\n }\n if (m.stack.styling) {\n techParts.push(`Styling: ${m.stack.styling}`);\n }\n if (m.stack.build_tool) {\n techParts.push(`Build tool: ${m.stack.build_tool}`);\n }\n projectParts.push(techParts.join(\"\\n\"));\n }\n\n if (m.patterns) {\n if (m.patterns.architecture) {\n projectParts.push(`Architecture: ${m.patterns.architecture}`);\n }\n if (m.patterns.state_management) {\n projectParts.push(`State management: ${m.patterns.state_management}`);\n }\n if (m.patterns.api_style) {\n projectParts.push(`API style: ${m.patterns.api_style}`);\n }\n }\n\n sections.push(projectParts.join(\"\\n\"));\n\n // ─── How to run things ─────────────────────────────────────────\n if (m.commands) {\n const cmds = Object.entries(m.commands).filter(([, v]) => v);\n if (cmds.length) {\n sections.push(\"\\n## Commands\");\n for (const [name, cmd] of cmds) {\n sections.push(`- ${name}: \\`${cmd}\\``);\n }\n }\n }\n\n // ─── Project structure ─────────────────────────────────────────\n if (m.structure) {\n sections.push(\"\\n## Key Paths\");\n if (m.structure.entry_points?.length) {\n sections.push(`Entry points: ${m.structure.entry_points.join(\", \")}`);\n }\n if (m.patterns?.key_modules && Object.keys(m.patterns.key_modules).length) {\n for (const [dir, desc] of Object.entries(m.patterns.key_modules)) {\n sections.push(`- ${dir} → ${desc}`);\n }\n }\n }\n\n // ─── CURRENT STATUS (most important for \"what should I work on?\") ───\n if (m.status && m.status.github_available) {\n const statusParts: string[] = [];\n\n // What's in progress?\n const inProgress = m.status.kanban?.in_progress || [];\n if (inProgress.length) {\n statusParts.push(\"\\n### In Progress NOW\");\n for (const i of inProgress) {\n const assignee = i.assignee ? ` → @${i.assignee}` : \"\";\n const files = i.mapped_files?.length ? ` (files: ${i.mapped_files.join(\", \")})` : \"\";\n statusParts.push(`- #${i.number}: ${i.title}${assignee}${files}`);\n }\n }\n\n // What should I work on next?\n const priorities = m.status.priorities || [];\n const nextTask = priorities[0];\n if (nextTask) {\n statusParts.push(\"\\n### NEXT TASK (highest priority)\");\n const labels = nextTask.labels.length ? ` [${nextTask.labels.join(\", \")}]` : \"\";\n statusParts.push(`#${nextTask.number}: ${nextTask.title}${labels}`);\n if (nextTask.body) {\n const snippet =\n nextTask.body.length > 300 ? nextTask.body.slice(0, 300) + \"…\" : nextTask.body;\n statusParts.push(snippet);\n }\n if (nextTask.mapped_files?.length) {\n statusParts.push(`Start in: ${nextTask.mapped_files.join(\", \")}`);\n }\n }\n\n // What's in the backlog?\n const backlog = m.status.kanban?.backlog || [];\n if (backlog.length > 0) {\n statusParts.push(`\\n### Backlog (${backlog.length} items)`);\n for (const i of backlog.slice(0, 5)) {\n const labels = i.labels.length ? ` [${i.labels.join(\", \")}]` : \"\";\n statusParts.push(`- #${i.number}: ${i.title}${labels}`);\n }\n if (backlog.length > 5) {\n statusParts.push(` ... and ${backlog.length - 5} more`);\n }\n }\n\n // Blockers\n const blocked = (m.status.issues || []).filter(\n (i) =>\n i.state === \"open\" &&\n i.labels.some(\n (l) => l.toLowerCase().includes(\"blocked\") || l.toLowerCase().includes(\"blocker\")\n )\n );\n if (blocked.length) {\n statusParts.push(\"\\n### BLOCKERS\");\n for (const i of blocked) {\n statusParts.push(`- #${i.number}: ${i.title} [${i.labels.join(\", \")}]`);\n }\n }\n\n // Open PRs\n const openPRs = (m.status.pull_requests || []).filter((pr) => pr.state === \"open\");\n if (openPRs.length) {\n statusParts.push(`\\n### Open PRs (${openPRs.length})`);\n for (const pr of openPRs.slice(0, 5)) {\n const reviewers = pr.reviewers.length ? ` → waiting on: ${pr.reviewers.join(\", \")}` : \"\";\n statusParts.push(`- PR #${pr.number}: ${pr.title} (${pr.branch})${reviewers}`);\n }\n }\n\n // Only show section if there's actual content\n if (statusParts.length > 0) {\n sections.push(\"\\n## CURRENT STATUS\");\n sections.push(...statusParts);\n }\n }\n // Don't show empty \"CURRENT STATUS\" for projects without GitHub sync\n\n // ─── Roadmap ───────────────────────────────────────────────────\n if (m.roadmap?.milestones?.length) {\n sections.push(\"\\n## Roadmap\");\n for (const ms of m.roadmap.milestones) {\n const due = ms.due_date ? ` (due: ${ms.due_date.split(\"T\")[0]})` : \"\";\n sections.push(\n `- ${ms.title}: ${ms.progress.percent}% complete (${ms.progress.closed}/${ms.progress.open + ms.progress.closed} done)${due}`\n );\n }\n }\n\n // ─── Decisions ─────────────────────────────────────────────────\n const allDecisions = [\n ...(m.decisions?.from_prs || []),\n ...(m.decisions?.from_adrs || []),\n ...(m.decisions?.manual || []),\n ];\n if (allDecisions.length) {\n sections.push(\"\\n## Recent Decisions\");\n for (const d of allDecisions.slice(0, 5)) {\n sections.push(`- ${d.title} (${d.source})`);\n if (d.summary) {\n sections.push(` ${d.summary.slice(0, 150)}`);\n }\n }\n }\n\n // ─── Git status ────────────────────────────────────────────────\n if (m.git) {\n if (m.git.uncommitted_changes) {\n sections.push(\"\\n## WARNING\");\n sections.push(\"There are uncommitted changes in the working directory.\");\n }\n if (m.git.recent_commits?.length) {\n sections.push(\"\\n## Recent Commits\");\n for (const c of m.git.recent_commits.slice(0, 3)) {\n sections.push(`- ${c}`);\n }\n }\n }\n\n return sections.join(\"\\n\");\n}\n","import { resolve, join } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport type { CLIOptions, Manifest } from \"../types.js\";\nimport { error, log, bold, info } from \"../utils/output.js\";\nimport { rankIssues } from \"../github/sync.js\";\n\nfunction priorityReason(labels: string[]): string {\n for (const label of labels) {\n const l = label.toLowerCase();\n if (l.startsWith(\"status:\")) {\n continue;\n }\n if (l.includes(\"p0\") || l.includes(\"critical\") || l.includes(\"urgent\")) {\n return \"critical (P0)\";\n }\n }\n for (const label of labels) {\n const l = label.toLowerCase();\n if (l.startsWith(\"status:\")) {\n continue;\n }\n if (l === \"vibekit\" || l.includes(\"p1\") || l.includes(\"high\") || l.includes(\"bug\")) {\n return \"high (P1)\";\n }\n }\n for (const label of labels) {\n const l = label.toLowerCase();\n if (l.startsWith(\"status:\")) {\n continue;\n }\n if (l.includes(\"p2\") || l.includes(\"medium\") || l === \"arch\") {\n return \"medium (P2)\";\n }\n }\n for (const label of labels) {\n const l = label.toLowerCase();\n if (l.startsWith(\"status:\")) {\n continue;\n }\n if (l.includes(\"p3\") || l.includes(\"low\")) {\n return \"low (P3)\";\n }\n }\n for (const label of labels) {\n const l = label.toLowerCase();\n if (l.includes(\"feature\")) {\n return \"feature\";\n }\n }\n return \"unlabeled (lowest)\";\n}\n\n/**\n * `codebase next` — returns the highest-priority task to work on.\n *\n * Output is structured for both human and AI consumption:\n * - Issue number, title, labels\n * - Mapped files (where to start)\n * - What's currently in progress (so you don't collide)\n */\nexport async function runNext(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n\n if (!existsSync(join(root, \".codebase.json\"))) {\n console.error(\"No manifest found. Run 'codebase init' to set up this project first.\");\n process.exit(1);\n }\n\n let manifest: Manifest;\n try {\n const content = await readFile(join(root, \".codebase.json\"), \"utf-8\");\n manifest = JSON.parse(content);\n } catch {\n error(\"No .codebase.json found (or it's corrupted). Run `npx codebase` first.\");\n process.exit(1);\n }\n\n const status = manifest.status;\n if (!status || !status.github_available) {\n info(\"No GitHub data. Run `npx codebase` with `gh` CLI authenticated.\");\n return;\n }\n\n // Show what's in progress first (awareness)\n const inProgress = status.kanban?.in_progress || [];\n if (inProgress.length) {\n log(bold(\"IN PROGRESS (don't duplicate):\"));\n for (const i of inProgress) {\n const assignee = i.assignee ? ` → @${i.assignee}` : \"\";\n log(` #${i.number}: ${i.title}${assignee}`);\n }\n log(\"\");\n }\n\n // Show next task — fall back to live ranking if priorities list is stale/empty\n let priorities = status.priorities ?? [];\n if (!priorities.length) {\n const allOpen = (manifest.status?.issues ?? []).filter((i) => i.state === \"open\");\n priorities = rankIssues(allOpen);\n }\n const next = priorities[0];\n if (!next) {\n log(\"No open tasks in the backlog. Create one:\");\n log(' codebase issue create \"task title\"');\n return;\n }\n\n log(bold(\"NEXT TASK:\"));\n log(` #${next.number}: ${next.title}`);\n if (next.labels.length) {\n log(` Labels: ${next.labels.join(\", \")}`);\n }\n log(` Priority: ${priorityReason(next.labels)}`);\n if (next.effort) {\n const effortLabel = { S: \"Small (hours)\", M: \"Medium (days)\", L: \"Large (weeks)\" }[next.effort];\n log(` Effort: ${effortLabel}`);\n }\n if (next.assignee) {\n log(` Assignee: @${next.assignee}`);\n }\n if (next.milestone) {\n log(` Milestone: ${next.milestone}`);\n }\n if (next.mapped_files?.length) {\n log(` Start in: ${next.mapped_files.join(\", \")}`);\n }\n\n // Show needs-verify queue\n const needsVerify = status.kanban?.needs_verify ?? [];\n if (needsVerify.length > 0) {\n log(`\\n${bold(\"NEEDS VERIFY (simulate to close):\")}`);\n for (const i of needsVerify.slice(0, 5)) {\n log(` #${i.number}: ${i.title}`);\n }\n }\n\n // Show blockers\n const blocked =\n status.issues?.filter(\n (i) =>\n i.state === \"open\" &&\n i.labels.some(\n (l) => l.toLowerCase().includes(\"blocked\") || l.toLowerCase().includes(\"blocker\")\n )\n ) || [];\n\n if (blocked.length) {\n log(`\\n${bold(\"BLOCKERS:\")}`);\n for (const i of blocked) {\n log(` #${i.number}: ${i.title} [${i.labels.join(\", \")}]`);\n }\n }\n}\n","import { resolve, join } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport type { CLIOptions } from \"../types.js\";\nimport { queryPath } from \"../utils/json-path.js\";\nimport { error } from \"../utils/output.js\";\n\nexport async function runQuery(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n const manifestPath = join(root, \".codebase.json\");\n\n if (!existsSync(manifestPath)) {\n console.error(\"No manifest found. Run 'codebase init' to set up this project first.\");\n process.exit(1);\n }\n\n let manifest: Record<string, unknown>;\n try {\n const content = await readFile(manifestPath, \"utf-8\");\n manifest = JSON.parse(content);\n } catch {\n error(\"No .codebase.json found (or it's corrupted). Run `npx codebase` first.\");\n process.exit(1);\n }\n const path = options.positionals[0];\n\n if (!path) {\n // No path = full manifest\n process.stdout.write(JSON.stringify(manifest, null, 2) + \"\\n\");\n return;\n }\n\n const value = queryPath(manifest, path);\n\n if (value === undefined) {\n error(`Path \"${path}\" not found in manifest.`);\n process.exit(1);\n }\n\n if (options.force) {\n if (typeof value === \"string\") {\n process.stdout.write(value + \"\\n\");\n } else if (Array.isArray(value)) {\n process.stdout.write(value.join(\"\\n\") + \"\\n\");\n } else {\n process.stdout.write(JSON.stringify(value) + \"\\n\");\n }\n } else {\n process.stdout.write(JSON.stringify(value, null, 2) + \"\\n\");\n }\n}\n","/**\n * Simple dot-path query for objects.\n * queryPath({ a: { b: [1, 2] } }, \"a.b\") → [1, 2]\n * queryPath({ a: { b: \"hi\" } }, \"a.b\") → \"hi\"\n * queryPath({ a: 1 }, \"a.b.c\") → undefined\n */\nexport function queryPath(obj: unknown, path: string): unknown {\n const parts = path.split(\".\");\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined;\n }\n if (typeof current !== \"object\") {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n}\n\n/**\n * Deep diff two objects. Returns list of changes.\n */\nexport interface DiffEntry {\n type: \"added\" | \"removed\" | \"changed\";\n path: string;\n oldValue?: unknown;\n newValue?: unknown;\n}\n\nexport function deepDiff(\n oldObj: Record<string, unknown>,\n newObj: Record<string, unknown>,\n prefix = \"\"\n): DiffEntry[] {\n const diffs: DiffEntry[] = [];\n const allKeys = new Set([...Object.keys(oldObj), ...Object.keys(newObj)]);\n\n for (const key of allKeys) {\n const path = prefix ? `${prefix}.${key}` : key;\n const oldVal = oldObj[key];\n const newVal = newObj[key];\n\n if (!(key in oldObj)) {\n diffs.push({ type: \"added\", path, newValue: newVal });\n } else if (!(key in newObj)) {\n diffs.push({ type: \"removed\", path, oldValue: oldVal });\n } else if (isObject(oldVal) && isObject(newVal)) {\n diffs.push(\n ...deepDiff(oldVal as Record<string, unknown>, newVal as Record<string, unknown>, path)\n );\n } else if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {\n diffs.push({ type: \"changed\", path, oldValue: oldVal, newValue: newVal });\n }\n }\n\n return diffs;\n}\n\nfunction isObject(val: unknown): val is Record<string, unknown> {\n return val !== null && typeof val === \"object\" && !Array.isArray(val);\n}\n","import { resolve } from \"node:path\";\nimport type { CLIOptions } from \"../types.js\";\nimport {\n createIssue,\n closeIssue,\n commentIssue,\n listIssues,\n mapIssueToFiles,\n} from \"../github/issues.js\";\nimport { error } from \"../utils/output.js\";\n\nexport async function runIssue(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n\n switch (options.subcommand) {\n case \"create\": {\n const title = options.positionals[0];\n if (!title) {\n error('Usage: codebase issue create \"Issue title\" [--message \"body\"]');\n process.exit(1);\n }\n await createIssue(root, title, options.message || undefined);\n break;\n }\n case \"close\": {\n const number = options.positionals[0];\n if (!number) {\n error('Usage: codebase issue close <number> [--reason \"reason\"]');\n process.exit(1);\n }\n await closeIssue(root, number, options.reason || undefined);\n break;\n }\n case \"comment\": {\n const number = options.positionals[0];\n const body = options.message;\n if (!number || !body) {\n error('Usage: codebase issue comment <number> --message \"text\"');\n process.exit(1);\n }\n await commentIssue(root, number, body);\n break;\n }\n case \"list\": {\n const filter = options.positionals[0]; // \"mine\" from --mine flag\n await listIssues(root, filter);\n break;\n }\n case \"map\": {\n const number = options.positionals[0];\n const files = options.positionals.slice(1);\n if (!number || files.length === 0) {\n error(\"Usage: codebase issue map <number> <file1> <file2> ...\");\n process.exit(1);\n }\n await mapIssueToFiles(root, number, files);\n break;\n }\n default:\n error(\"Usage: codebase issue create|close|comment|list|map\");\n process.exit(1);\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { log, success, error } from \"../utils/output.js\";\n\n/**\n * Execute gh CLI with proper argument passing (no shell interpolation).\n */\nfunction ghExec(cwd: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\"gh\", args, { cwd, timeout: 30_000 }, (err, stdout, stderr) => {\n if (err) {\n reject(new Error(stderr || err.message));\n } else {\n resolve(stdout.trim());\n }\n });\n });\n}\n\nexport async function createIssue(\n root: string,\n title: string,\n body?: string,\n labels?: string[]\n): Promise<void> {\n const issueBody =\n body ||\n `## Summary\\n\\n${title}\\n\\n## Steps to Reproduce\\n\\n1. \\n\\n## Expected\\n\\n\\n\\n## Actual\\n\\n`;\n const args = [\"issue\", \"create\", \"--title\", title, \"--body\", issueBody];\n if (labels?.length) {\n args.push(\"--label\", labels.join(\",\"));\n }\n\n try {\n const url = await ghExec(root, args);\n const number = url.split(\"/\").pop() ?? \"\";\n success(`Created #${number} — ${url}`);\n } catch (e) {\n error(`Failed to create issue: ${(e as Error).message}`);\n }\n}\n\nexport async function closeIssue(root: string, number: string, reason?: string): Promise<void> {\n try {\n const args = [\"issue\", \"close\", number];\n if (reason) {\n args.push(\"--comment\", reason);\n }\n await ghExec(root, args);\n\n // Fetch issue title and URL for richer output\n try {\n const json = await ghExec(root, [\"issue\", \"view\", number, \"--json\", \"title,url\"]);\n const { title, url } = JSON.parse(json) as { title: string; url: string };\n success(`Closed #${number}: ${title}`);\n log(` ${url}`);\n } catch {\n success(`Closed issue #${number}`);\n }\n } catch (e) {\n error(`Failed to close issue: ${(e as Error).message}`);\n }\n}\n\nexport async function listIssues(root: string, filter?: string): Promise<void> {\n try {\n const args = [\"issue\", \"list\", \"--limit\", \"30\"];\n if (filter === \"mine\") {\n args.push(\"--assignee\", \"@me\");\n }\n\n const output = await ghExec(root, args);\n if (output) {\n log(output);\n } else {\n log(\"No issues found.\");\n }\n } catch (e) {\n error(`Failed to list issues: ${(e as Error).message}`);\n }\n}\n\nexport async function commentIssue(root: string, number: string, body: string): Promise<void> {\n try {\n const url = await ghExec(root, [\"issue\", \"comment\", number, \"--body\", body]);\n if (url) {\n success(`Comment added to #${number} — ${url}`);\n } else {\n success(`Comment added to #${number}`);\n }\n } catch (e) {\n error(`Failed to comment on issue: ${(e as Error).message}`);\n }\n}\n\nexport async function mapIssueToFiles(\n root: string,\n issueNumber: string,\n files: string[]\n): Promise<void> {\n try {\n const body = `**Mapped files:**\\n${files.map((f) => `- \\`${f}\\``).join(\"\\n\")}`;\n await ghExec(root, [\"issue\", \"comment\", issueNumber, \"--body\", body]);\n success(`Mapped issue #${issueNumber} to ${files.length} files`);\n } catch (e) {\n error(`Failed to map issue: ${(e as Error).message}`);\n }\n}\n","import { resolve, join } from \"node:path\";\nimport { readFile, writeFile, rename } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport type { CLIOptions, Manifest } from \"../types.js\";\nimport { syncGitHub } from \"../github/sync.js\";\nimport { log, heading, error, info, bold, dim } from \"../utils/output.js\";\n\nexport async function runStatus(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n\n if (!existsSync(join(root, \".codebase.json\"))) {\n console.error(\"No manifest found. Run 'codebase init' to set up this project first.\");\n process.exit(1);\n }\n\n // Try to read existing manifest first\n let manifest: Manifest | null = null;\n try {\n manifest = JSON.parse(await readFile(join(root, \".codebase.json\"), \"utf-8\"));\n } catch {}\n\n // If no status data, sync from GitHub\n if (!manifest?.status) {\n info(\"Syncing from GitHub...\");\n const ghData = await syncGitHub(root);\n if (!ghData) {\n error(\"Could not sync. Is `gh` CLI installed and authenticated?\");\n process.exit(1);\n }\n if (ghData && manifest) {\n manifest.status = ghData.status;\n manifest.roadmap = ghData.roadmap;\n manifest.decisions = ghData.decisions;\n\n // Persist synced data back to .codebase.json atomically\n try {\n const manifestPath = join(root, \".codebase.json\");\n const existing = JSON.parse(await readFile(manifestPath, \"utf-8\")) as Manifest;\n const updated = {\n ...existing,\n status: ghData.status,\n roadmap: ghData.roadmap,\n decisions: ghData.decisions,\n };\n const tmpPath = manifestPath + \".tmp\";\n await writeFile(tmpPath, JSON.stringify(updated, null, 2), \"utf-8\");\n await rename(tmpPath, manifestPath);\n } catch {\n // Non-fatal: display continues even if write fails\n }\n }\n }\n\n const status = manifest?.status;\n if (!status) {\n error(\"No status data available.\");\n return;\n }\n\n // Query specific view\n const view = options.positionals[0];\n\n if (view === \"kanban\" || !view) {\n printKanban(status);\n }\n\n if (view === \"priorities\" || !view) {\n printPriorities(status);\n }\n\n if (view === \"milestones\" && manifest?.roadmap) {\n printMilestones(manifest.roadmap);\n }\n\n if (view === \"decisions\" && manifest?.decisions) {\n printDecisions(manifest.decisions);\n }\n\n if (!view) {\n dim(\n \"\\n Also try: codebase status milestones | codebase status priorities | codebase status decisions\"\n );\n }\n}\n\nfunction printKanban(status: NonNullable<Manifest[\"status\"]>): void {\n heading(\"Kanban Board\");\n\n const { kanban } = status;\n\n log(`\\n${bold(\"BACKLOG\")} (${kanban.backlog.length})`);\n for (const i of kanban.backlog.slice(0, 10)) {\n log(` #${i.number} ${i.title}`);\n }\n if (kanban.backlog.length > 10) {\n dim(` … and ${kanban.backlog.length - 10} more`);\n }\n\n log(`\\n${bold(\"IN PROGRESS\")} (${kanban.in_progress.length})`);\n for (const i of kanban.in_progress.slice(0, 10)) {\n const assignee = i.assignee ? ` @${i.assignee}` : \"\";\n log(` #${i.number} ${i.title}${assignee}`);\n }\n if (kanban.in_progress.length > 10) {\n dim(` … and ${kanban.in_progress.length - 10} more`);\n }\n\n const needsVerify = kanban.needs_verify ?? [];\n if (needsVerify.length > 0) {\n log(`\\n${bold(\"NEEDS VERIFY\")} (${needsVerify.length})`);\n for (const i of needsVerify.slice(0, 10)) {\n log(` #${i.number} ${i.title}`);\n }\n if (needsVerify.length > 10) {\n dim(` … and ${needsVerify.length - 10} more`);\n }\n }\n\n log(`\\n${bold(\"DONE\")} (${kanban.done.length} recent)`);\n for (const i of kanban.done.slice(0, 5)) {\n log(` #${i.number} ${i.title}`);\n }\n if (kanban.done.length > 5) {\n dim(` … and ${kanban.done.length - 5} more`);\n }\n}\n\nfunction printPriorities(status: NonNullable<Manifest[\"status\"]>): void {\n heading(\"Priority Queue\");\n\n for (const i of status.priorities.slice(0, 15)) {\n const labels = i.labels.length ? ` [${i.labels.join(\", \")}]` : \"\";\n const assignee = i.assignee ? ` → @${i.assignee}` : \"\";\n log(` #${i.number} ${i.title}${labels}${assignee}`);\n }\n}\n\nfunction printMilestones(roadmap: NonNullable<Manifest[\"roadmap\"]>): void {\n heading(\"Milestones\");\n\n for (const ms of roadmap.milestones) {\n const bar = progressBar(ms.progress.percent);\n const due = ms.due_date ? ` (due: ${ms.due_date.split(\"T\")[0]})` : \"\";\n log(`\\n ${bold(ms.title)} ${bar} ${ms.progress.percent}%${due}`);\n log(` ${ms.progress.closed}/${ms.progress.open + ms.progress.closed} issues closed`);\n }\n}\n\nfunction printDecisions(decisions: NonNullable<Manifest[\"decisions\"]>): void {\n heading(\"Decisions\");\n\n const all = [\n ...decisions.from_prs.map((d) => ({ ...d, type: \"PR\" })),\n ...decisions.from_adrs.map((d) => ({ ...d, type: \"ADR\" })),\n ...decisions.manual.map((d) => ({ ...d, type: \"Manual\" })),\n ].sort((a, b) => (b.date || \"\").localeCompare(a.date || \"\"));\n\n for (const d of all.slice(0, 15)) {\n log(` [${d.type}] ${d.title}`);\n if (d.summary) {\n log(` ${d.summary.slice(0, 100)}`);\n }\n }\n}\n\nfunction progressBar(percent: number): string {\n const filled = Math.round(percent / 5);\n const empty = 20 - filled;\n return `[${\"█\".repeat(filled)}${\"░\".repeat(empty)}]`;\n}\n","import { resolve } from \"node:path\";\nimport type { CLIOptions } from \"../types.js\";\nimport { startMcpServer } from \"../mcp/server.js\";\n\nexport async function runMcp(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n await startMcpServer(root);\n}\n","import { createInterface } from \"node:readline\";\nimport { readFile, writeFile, rename } from \"node:fs/promises\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { execFile } from \"node:child_process\";\nimport { queryPath } from \"../utils/json-path.js\";\nimport { scan } from \"../scanner/engine.js\";\nimport { generateBrief } from \"./brief.js\";\nimport { rankIssues, syncGitHub } from \"../github/sync.js\";\nimport type { Manifest } from \"../types.js\";\n\ninterface JsonRpcRequest {\n jsonrpc: string;\n id: number | string;\n method: string;\n params?: Record<string, unknown>;\n}\n\ninterface JsonRpcResponse {\n jsonrpc: string;\n id: number | string;\n result?: unknown;\n error?: { code: number; message: string };\n}\n\nconst TOOL_DEFINITIONS = [\n // ─── Session Start ─────────────────────────────────────────────\n {\n name: \"project_brief\",\n description:\n \"CALL THIS FIRST at the start of every session. Returns a complete project briefing: what the project is, tech stack, current priorities, open issues, blockers, what to work on next, and recent decisions. This is your single source of truth — call it before doing anything else.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n\n // ─── Context Queries ───────────────────────────────────────────\n {\n name: \"get_codebase\",\n description:\n \"Get codebase data by category with optional sparse field selection. Use the 'fields' array to request only specific fields (e.g. fields: ['languages', 'frameworks'] from category: 'stack'). For single dot-path lookups use query_codebase instead.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n category: {\n type: \"string\" as const,\n description:\n \"Section to retrieve: repo, structure, stack, commands, dependencies, config, git, quality, patterns, status, roadmap, decisions\",\n },\n fields: {\n type: \"array\" as const,\n items: { type: \"string\" as const },\n description:\n \"Optional. When category is specified, return only these keys from that section. E.g. ['languages', 'frameworks'] for stack.\",\n },\n },\n },\n },\n {\n name: \"query_codebase\",\n description:\n \"Query a specific field using dot-path notation. Handles both targeted dot-path queries (e.g. 'stack.languages') and full category reads (e.g. 'stack'). Examples: 'stack.languages', 'commands.test', 'status.kanban.in_progress', 'roadmap.milestones'.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n path: {\n type: \"string\" as const,\n description:\n \"Dot-path query, e.g. 'stack.languages', 'commands.test', 'status.priorities'\",\n },\n fields: {\n type: \"array\" as const,\n items: { type: \"string\" as const },\n description: \"Optional: return only these fields from the result object\",\n },\n },\n required: [\"path\"],\n },\n },\n\n // ─── Task Management ───────────────────────────────────────────\n {\n name: \"get_next_task\",\n description:\n \"Get the highest-priority task you should work on next. Returns the top open issue ranked by priority labels (P0 > P1 > bugs > features), including mapped files so you know where to start coding.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n {\n name: \"get_blockers\",\n description:\n \"Get all current blockers — issues labeled as blocked, PRs waiting for review, PRs with failing CI checks, PRs with merge conflicts, and uncommitted changes. Shows what's preventing progress.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n\n // ─── Issue Actions ─────────────────────────────────────────────\n {\n name: \"create_issue\",\n description:\n \"Create a new GitHub issue. Use this when you discover a bug, identify needed work, or the user asks to track something. Returns the issue URL.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n title: { type: \"string\" as const, description: \"Issue title\" },\n body: { type: \"string\" as const, description: \"Issue body/description (markdown)\" },\n labels: {\n type: \"array\" as const,\n items: { type: \"string\" as const },\n description: \"Labels to apply: bug, feature, enhancement, P0, P1, P2, etc.\",\n },\n },\n required: [\"title\"],\n },\n },\n {\n name: \"close_issue\",\n description: \"Close a GitHub issue after fixing it. Add a comment explaining what was done.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n number: { type: \"number\" as const, description: \"Issue number to close\" },\n comment: { type: \"string\" as const, description: \"Comment explaining resolution\" },\n },\n required: [\"number\"],\n },\n },\n\n {\n name: \"update_issue\",\n description:\n \"Update a GitHub issue — add/remove labels, set assignee. Use this to advance issues through the pipeline (e.g., add 'status:in-progress', remove 'status:backlog').\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n number: { type: \"number\" as const, description: \"Issue number\" },\n add_labels: {\n type: \"array\" as const,\n items: { type: \"string\" as const },\n description: \"Labels to add\",\n },\n remove_labels: {\n type: \"array\" as const,\n items: { type: \"string\" as const },\n description: \"Labels to remove\",\n },\n assignee: {\n type: \"string\" as const,\n description: \"GitHub username to assign (or empty string to unassign)\",\n },\n },\n required: [\"number\"],\n },\n },\n\n // ─── Commands ──────────────────────────────────────────────────\n {\n name: \"list_commands\",\n description:\n \"List installed Claude Code slash commands in this project. Returns names of available commands (e.g. /setup, /simulate, /build, /launch, /review).\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n {\n name: \"list_skills\",\n description:\n \"List installed Claude Code skills with their names and descriptions. Skills extend /review and other commands with stack-specific analysis.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n\n // ─── Plan (PLAN.md) ────────────────────────────────────────────\n {\n name: \"get_plan\",\n description:\n \"Read the project's PLAN.md — Claude's persistent working memory across sessions. Contains current sprint goals, in-flight work, decisions log, and blockers. Call this after project_brief to restore loop context.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n {\n name: \"update_plan\",\n description:\n \"Append a status update to PLAN.md. Use this at the end of each build or simulate cycle to record what was done, decisions made, and what's next. Creates PLAN.md if it doesn't exist.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n message: {\n type: \"string\" as const,\n description: \"Status update text to append to PLAN.md Update Log section\",\n },\n },\n required: [\"message\"],\n },\n },\n\n // ─── Issue & PR Detail ─────────────────────────────────────────\n {\n name: \"get_issue\",\n description:\n \"Get full details of a specific GitHub issue by number, including body, comments, and linked PRs. Use this when working on an issue and need its complete specification.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n number: { type: \"number\" as const, description: \"Issue number\" },\n },\n required: [\"number\"],\n },\n },\n {\n name: \"get_pr\",\n description:\n \"Get full details of a specific pull request by number, including body, review status, checks, and diff stats.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n number: { type: \"number\" as const, description: \"PR number\" },\n },\n required: [\"number\"],\n },\n },\n\n // ─── Rescan ────────────────────────────────────────────────────\n {\n name: \"rescan_project\",\n description:\n \"Rescan the project to refresh the manifest after making changes. Call this after major refactors, dependency updates, or when your cached data feels stale.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n sync: {\n type: \"boolean\" as const,\n description: \"Also refresh GitHub data (issues, PRs, milestones). Default: true.\",\n },\n incremental: {\n type: \"boolean\" as const,\n description: \"Only re-scan changed areas (faster). Default: false.\",\n },\n },\n },\n },\n {\n name: \"refresh_status\",\n description:\n \"Refresh only GitHub data (issues, PRs, milestones) without re-scanning the filesystem. Much faster than rescan_project. Call this after creating/closing issues to get fresh priority data.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n];\n\nexport async function startMcpServer(root: string): Promise<void> {\n const rl = createInterface({ input: process.stdin, terminal: false });\n\n for await (const line of rl) {\n if (!line.trim()) {\n continue;\n }\n\n let request: JsonRpcRequest;\n try {\n request = JSON.parse(line);\n } catch {\n writeResponse({ jsonrpc: \"2.0\", id: 0, error: { code: -32700, message: \"Parse error\" } });\n continue;\n }\n\n const response = await handleRequest(request, root);\n if (response) {\n writeResponse(response);\n }\n }\n}\n\nasync function handleRequest(req: JsonRpcRequest, root: string): Promise<JsonRpcResponse | null> {\n switch (req.method) {\n case \"initialize\":\n return respond(req.id, {\n protocolVersion: \"2024-11-05\",\n serverInfo: { name: \"codebase\", version: __VERSION__ },\n capabilities: { tools: {} },\n });\n\n case \"notifications/initialized\":\n return null; // Notifications are one-way — no response per JSON-RPC spec\n\n case \"tools/list\":\n return respond(req.id, { tools: TOOL_DEFINITIONS });\n\n case \"tools/call\":\n return handleToolCall(req, root);\n\n default:\n return {\n jsonrpc: \"2.0\",\n id: req.id,\n error: { code: -32601, message: `Method not found: ${req.method}` },\n };\n }\n}\n\nasync function handleToolCall(req: JsonRpcRequest, root: string): Promise<JsonRpcResponse> {\n const params = req.params || {};\n const toolName = params.name as string;\n const args = (params.arguments || {}) as Record<string, unknown>;\n\n try {\n switch (toolName) {\n case \"project_brief\": {\n const manifest = await loadOrScanManifest(root, true);\n const brief = generateBrief(manifest);\n return respond(req.id, {\n content: [{ type: \"text\", text: brief }],\n });\n }\n\n case \"get_codebase\": {\n const manifest = await loadOrScanManifest(root);\n const category = args.category as string | undefined;\n const fields = args.fields as string[] | undefined;\n if (category) {\n const data = (manifest as unknown as Record<string, unknown>)[category];\n if (fields?.length && data && typeof data === \"object\" && data !== null) {\n const sparse: Record<string, unknown> = {};\n for (const f of fields) {\n sparse[f] = (data as Record<string, unknown>)[f];\n }\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(sparse, null, 2) }],\n });\n }\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(data ?? null, null, 2) }],\n });\n }\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(manifest, null, 2) }],\n });\n }\n\n case \"query_codebase\": {\n const manifest = await loadOrScanManifest(root);\n const path = args.path as string;\n const fields = args.fields as string[] | undefined;\n let value = queryPath(manifest as unknown as Record<string, unknown>, path);\n if (\n fields?.length &&\n value !== null &&\n value !== undefined &&\n typeof value === \"object\" &&\n !Array.isArray(value)\n ) {\n const sparse: Record<string, unknown> = {};\n for (const f of fields) {\n sparse[f] = (value as Record<string, unknown>)[f];\n }\n value = sparse;\n }\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(value ?? null, null, 2) }],\n });\n }\n\n case \"get_next_task\": {\n const manifest = await loadOrScanManifest(root, true);\n const result = getNextTask(manifest);\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n });\n }\n\n case \"get_blockers\": {\n const manifest = await loadOrScanManifest(root, true);\n const result = getBlockers(manifest);\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n });\n }\n\n case \"create_issue\": {\n const result = await ghCreateIssue(root, args);\n await invalidateManifest(root);\n return respond(req.id, {\n content: [{ type: \"text\", text: result }],\n });\n }\n\n case \"close_issue\": {\n const result = await ghCloseIssue(root, args);\n await invalidateManifest(root);\n return respond(req.id, {\n content: [{ type: \"text\", text: result }],\n });\n }\n\n case \"update_issue\": {\n const result = await ghUpdateIssue(root, args);\n await invalidateManifest(root);\n return respond(req.id, {\n content: [{ type: \"text\", text: result }],\n });\n }\n\n case \"list_commands\": {\n const projectCommandsDir = join(root, \".claude\", \"commands\");\n const globalCommandsDir = join(homedir(), \".claude\", \"commands\");\n\n const seenNames = new Set<string>();\n const allFiles: string[] = [];\n\n for (const dir of [projectCommandsDir, globalCommandsDir]) {\n if (existsSync(dir)) {\n for (const f of readdirSync(dir)) {\n if (f.endsWith(\".md\") && !seenNames.has(f)) {\n seenNames.add(f);\n allFiles.push(f);\n }\n }\n }\n }\n\n if (allFiles.length === 0) {\n return respond(req.id, {\n content: [{ type: \"text\", text: \"No slash commands installed. Run: codebase setup\" }],\n });\n }\n\n const names = allFiles.map((f) => \"/\" + f.replace(/\\.md$/, \"\")).join(\", \");\n return respond(req.id, {\n content: [\n {\n type: \"text\",\n text: `Installed commands (${allFiles.length}): ${names}\\n\\nLoop: /simulate → /build → /launch`,\n },\n ],\n });\n }\n\n case \"list_skills\": {\n const globalSkillsDir = join(homedir(), \".claude\", \"skills\");\n const projectSkillsDir = join(root, \".claude\", \"skills\");\n\n const seenFiles = new Set<string>();\n const skillFiles: Array<{ file: string; dir: string }> = [];\n\n // Project-local takes precedence — add first, then global (skip duplicates)\n for (const dir of [projectSkillsDir, globalSkillsDir]) {\n if (existsSync(dir)) {\n for (const f of readdirSync(dir)) {\n if (f.endsWith(\".skill\") && !seenFiles.has(f)) {\n seenFiles.add(f);\n skillFiles.push({ file: f, dir });\n }\n }\n }\n }\n\n if (skillFiles.length === 0) {\n return respond(req.id, {\n content: [\n {\n type: \"text\",\n text: \"No skills installed in ~/.claude/skills/ or <project>/.claude/skills/. Run: codebase setup\",\n },\n ],\n });\n }\n\n const skills: Array<{ name: string; description: string; file: string }> = [];\n\n await Promise.all(\n skillFiles.map(\n ({ file, dir }) =>\n new Promise<void>((resolveSkill) => {\n const filePath = join(dir, file);\n execFile(\n \"unzip\",\n [\"-p\", filePath, \"*/SKILL.md\"],\n { timeout: 10_000 },\n (err, stdout) => {\n if (err || !stdout.trim()) {\n resolveSkill();\n return;\n }\n // Parse YAML frontmatter between --- markers\n const match = stdout.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!match) {\n resolveSkill();\n return;\n }\n const frontmatter = match[1];\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m);\n const descMatch = frontmatter.match(/^description:\\s*(.+)$/m);\n const name = nameMatch ? nameMatch[1].trim() : file.replace(/\\.skill$/, \"\");\n const description = descMatch ? descMatch[1].trim() : \"\";\n skills.push({ name, description, file });\n resolveSkill();\n }\n );\n })\n )\n );\n\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(skills, null, 2) }],\n });\n }\n\n case \"get_plan\": {\n const planPath = join(resolve(root), \"PLAN.md\");\n if (!existsSync(planPath)) {\n return respond(req.id, {\n content: [{ type: \"text\", text: \"No PLAN.md found. Use update_plan to create one.\" }],\n });\n }\n const planContent = await readFile(planPath, \"utf-8\");\n return respond(req.id, {\n content: [{ type: \"text\", text: planContent }],\n });\n }\n\n case \"update_plan\": {\n const planPath = join(resolve(root), \"PLAN.md\");\n const message = args.message as string;\n const timestamp = new Date().toISOString().split(\"T\")[0];\n const entry = `\\n<!-- updated: ${timestamp} -->\\n${message.trim()}\\n`;\n\n let planContent: string;\n if (!existsSync(planPath)) {\n planContent = `# PLAN.md — Autonomous Loop State\\n\\n> Managed by Claude. Updated each build/simulate cycle.\\n\\n## Current Sprint\\n\\n\\n## In Flight\\n\\n\\n## Decisions Log\\n\\n\\n## Blocked\\n\\n\\n## Update Log\\n${entry}`;\n } else {\n const existing = await readFile(planPath, \"utf-8\");\n if (existing.includes(\"## Update Log\")) {\n planContent = existing.replace(/(## Update Log\\n)/, `$1${entry}`);\n } else {\n planContent = existing + `\\n## Update Log\\n${entry}`;\n }\n }\n\n const tmpPath = planPath + \".tmp\";\n await writeFile(tmpPath, planContent, \"utf-8\");\n await rename(tmpPath, planPath);\n return respond(req.id, {\n content: [{ type: \"text\", text: `PLAN.md updated.` }],\n });\n }\n\n case \"get_issue\": {\n const number = args.number as number;\n const raw = await ghExecArgs(root, [\n \"issue\",\n \"view\",\n String(number),\n \"--json\",\n \"number,title,state,body,labels,assignees,milestone,comments,url\",\n ]);\n const issue = JSON.parse(raw) as unknown;\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(issue, null, 2) }],\n });\n }\n\n case \"get_pr\": {\n const number = args.number as number;\n const raw = await ghExecArgs(root, [\n \"pr\",\n \"view\",\n String(number),\n \"--json\",\n \"number,title,state,body,author,labels,reviewRequests,reviewDecision,statusCheckRollup,additions,deletions,comments,url\",\n ]);\n const pr = JSON.parse(raw) as unknown;\n return respond(req.id, {\n content: [{ type: \"text\", text: JSON.stringify(pr, null, 2) }],\n });\n }\n\n case \"rescan_project\": {\n const syncGh = args.sync !== false;\n const manifest = await scan(root, {\n quiet: true,\n sync: syncGh,\n incremental: args.incremental === true,\n });\n const manifestPath = join(root, \".codebase.json\");\n const tmpPath = manifestPath + \".tmp\";\n // Atomic write: write to temp file first, then rename to avoid torn reads\n await writeFile(tmpPath, JSON.stringify(manifest, null, 2), \"utf-8\");\n await rename(tmpPath, manifestPath);\n return respond(req.id, {\n content: [\n {\n type: \"text\",\n text: `Project rescanned. Manifest updated at ${manifest.generated_at}`,\n },\n ],\n });\n }\n\n case \"refresh_status\": {\n const manifestPath = join(root, \".codebase.json\");\n const ghData = await syncGitHub(root);\n if (ghData) {\n const content = await readFile(manifestPath, \"utf-8\");\n const manifest = JSON.parse(content) as Manifest;\n manifest.status = ghData.status;\n manifest.roadmap = ghData.roadmap;\n manifest.decisions = ghData.decisions;\n const merged = manifest;\n merged.generated_at = new Date().toISOString();\n const tmpPath = manifestPath + \".tmp\";\n await writeFile(tmpPath, JSON.stringify(merged, null, 2), \"utf-8\");\n await rename(tmpPath, manifestPath);\n }\n return respond(req.id, {\n content: [{ type: \"text\", text: `GitHub data refreshed at ${new Date().toISOString()}` }],\n });\n }\n\n default:\n return {\n jsonrpc: \"2.0\",\n id: req.id,\n error: { code: -32602, message: `Unknown tool: ${toolName}` },\n };\n }\n } catch (err) {\n return respond(req.id, {\n content: [{ type: \"text\", text: `Error: ${(err as Error).message}` }],\n isError: true,\n });\n }\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────\n\nconst _rawTtlHours = Number(process.env.CODEBASE_MANIFEST_TTL_HOURS);\nconst MANIFEST_TTL_MS =\n (Number.isFinite(_rawTtlHours) && _rawTtlHours > 0 ? _rawTtlHours : 24) * 60 * 60 * 1000;\n\nasync function loadOrScanManifest(root: string, withSync = false): Promise<Manifest> {\n try {\n const content = await readFile(join(root, \".codebase.json\"), \"utf-8\");\n const manifest = JSON.parse(content) as Manifest;\n // Serve cached manifest only if it is fresh enough\n if (manifest.generated_at) {\n const age = Date.now() - new Date(manifest.generated_at).getTime();\n if (age <= MANIFEST_TTL_MS) {\n return manifest;\n }\n }\n // Manifest is stale — rescan silently\n return (await scan(root, { quiet: true, sync: withSync })) as Manifest;\n } catch {\n return (await scan(root, { quiet: true, sync: withSync })) as Manifest;\n }\n}\n\nfunction getNextTask(manifest: Manifest): Record<string, unknown> {\n const allOpen = (manifest.status?.issues || []).filter((i) => i.state === \"open\");\n const priorities = manifest.status?.priorities?.length\n ? manifest.status.priorities\n : rankIssues(allOpen);\n\n if (!priorities.length) {\n return {\n summary:\n \"No open issues found. The project has no tracked tasks. You can create issues with the create_issue tool when you identify work to do.\",\n task: null,\n queue: [],\n };\n }\n\n const top = priorities[0];\n const queue = priorities.slice(1, 4).map((i) => ({\n number: i.number,\n title: i.title,\n labels: i.labels,\n }));\n\n const summaryParts = [`NEXT TASK: #${top.number} — ${top.title}`];\n if (top.labels.length) {\n summaryParts.push(`[${top.labels.join(\", \")}]`);\n }\n if (top.assignee) {\n summaryParts.push(`(assigned to @${top.assignee})`);\n }\n if (top.mapped_files?.length) {\n summaryParts.push(`Start in: ${top.mapped_files.join(\", \")}`);\n }\n\n const effortLabel = top.effort\n ? { S: \"Small (hours)\", M: \"Medium (days)\", L: \"Large (weeks)\" }[top.effort]\n : undefined;\n\n if (effortLabel) {\n summaryParts.push(`Effort: ${effortLabel}`);\n }\n\n // Surface needs_verify queue so AI knows what's pending simulation\n const needsVerify = (manifest.status?.kanban?.needs_verify ?? []).map((i) => ({\n number: i.number,\n title: i.title,\n }));\n\n return {\n summary: summaryParts.join(\" \"),\n task: {\n number: top.number,\n title: top.title,\n labels: top.labels,\n effort: top.effort,\n assignee: top.assignee,\n mapped_files: top.mapped_files || [],\n url: top.url,\n body: top.body || \"\",\n },\n queue,\n needs_verify: needsVerify,\n };\n}\n\nfunction getBlockers(manifest: Manifest): Record<string, unknown> {\n const blocked = (manifest.status?.issues || []).filter(\n (i) =>\n i.state === \"open\" &&\n i.labels.some(\n (l) => l.toLowerCase().includes(\"blocked\") || l.toLowerCase().includes(\"blocker\")\n )\n );\n\n const waitingReview = (manifest.status?.pull_requests || []).filter(\n (pr) => pr.state === \"open\" && pr.reviewers.length > 0 && pr.review_decision !== \"approved\"\n );\n\n const failingChecks = (manifest.status?.pull_requests || []).filter(\n (pr) => pr.state === \"open\" && pr.checks_status === \"failing\"\n );\n\n const withConflicts = (manifest.status?.pull_requests || []).filter(\n (pr) => pr.state === \"open\" && pr.merge_conflicts === true\n );\n\n const uncommittedChanges = manifest.git?.uncommitted_changes ?? false;\n const hasBlockers =\n blocked.length > 0 ||\n waitingReview.length > 0 ||\n failingChecks.length > 0 ||\n withConflicts.length > 0 ||\n uncommittedChanges;\n\n const summaryParts: string[] = [];\n if (!hasBlockers) {\n summaryParts.push(\"No blockers found. All clear to proceed with the next task.\");\n } else {\n if (blocked.length) {\n summaryParts.push(`${blocked.length} blocked issue(s)`);\n }\n if (waitingReview.length) {\n summaryParts.push(`${waitingReview.length} PR(s) awaiting review`);\n }\n if (failingChecks.length) {\n summaryParts.push(`${failingChecks.length} PR(s) with failing checks`);\n }\n if (withConflicts.length) {\n summaryParts.push(`${withConflicts.length} PR(s) with merge conflicts`);\n }\n if (uncommittedChanges) {\n summaryParts.push(\"uncommitted changes in working directory\");\n }\n }\n\n return {\n summary: summaryParts.join(\", \"),\n has_blockers: hasBlockers,\n blocked_issues: blocked.map((i) => ({\n number: i.number,\n title: i.title,\n labels: i.labels,\n url: i.url,\n })),\n prs_waiting_review: waitingReview.map((pr) => ({\n number: pr.number,\n title: pr.title,\n reviewers: pr.reviewers,\n url: pr.url,\n })),\n prs_failing_checks: failingChecks.map((pr) => ({\n number: pr.number,\n title: pr.title,\n url: pr.url,\n })),\n prs_with_conflicts: withConflicts.map((pr) => ({\n number: pr.number,\n title: pr.title,\n url: pr.url,\n })),\n uncommitted_changes: uncommittedChanges,\n };\n}\n\nfunction ghExecArgs(cwd: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\"gh\", args, { cwd, timeout: 30_000 }, (err, stdout, stderr) => {\n if (err) {\n reject(new Error(stderr || err.message));\n } else {\n resolve(stdout.trim());\n }\n });\n });\n}\n\nasync function ghCreateIssue(root: string, args: Record<string, unknown>): Promise<string> {\n const title = args.title as string;\n const body = (args.body as string) || title;\n const labels = args.labels as string[] | undefined;\n\n const ghArgs = [\"issue\", \"create\", \"--title\", title, \"--body\", body];\n if (labels?.length) {\n const safeLabels = labels.filter((l) => !l.includes(\",\"));\n if (safeLabels.length) {\n ghArgs.push(\"--label\", safeLabels.join(\",\"));\n }\n }\n\n const url = await ghExecArgs(root, ghArgs);\n return `Issue created: ${url}`;\n}\n\nasync function ghCloseIssue(root: string, args: Record<string, unknown>): Promise<string> {\n const number = args.number as number;\n const comment = args.comment as string | undefined;\n\n if (comment) {\n await ghExecArgs(root, [\"issue\", \"comment\", String(number), \"--body\", comment]);\n }\n await ghExecArgs(root, [\"issue\", \"close\", String(number)]);\n return `Issue #${number} closed.`;\n}\n\nasync function ghUpdateIssue(root: string, args: Record<string, unknown>): Promise<string> {\n const number = args.number as number;\n const addLabels = args.add_labels as string[] | undefined;\n const removeLabels = args.remove_labels as string[] | undefined;\n const assignee = args.assignee as string | undefined;\n\n const updates: string[] = [];\n\n if (addLabels?.length) {\n await ghExecArgs(root, [\"issue\", \"edit\", String(number), \"--add-label\", addLabels.join(\",\")]);\n updates.push(`added labels: ${addLabels.join(\", \")}`);\n }\n\n if (removeLabels?.length) {\n await ghExecArgs(root, [\n \"issue\",\n \"edit\",\n String(number),\n \"--remove-label\",\n removeLabels.join(\",\"),\n ]);\n updates.push(`removed labels: ${removeLabels.join(\", \")}`);\n }\n\n if (assignee !== undefined) {\n if (assignee === \"\") {\n // Fetch current assignees so we know who to remove\n const raw = await ghExecArgs(root, [\"issue\", \"view\", String(number), \"--json\", \"assignees\"]);\n const { assignees } = JSON.parse(raw) as { assignees: Array<{ login: string }> };\n for (const a of assignees) {\n await ghExecArgs(root, [\"issue\", \"edit\", String(number), \"--remove-assignee\", a.login]);\n }\n updates.push(\"unassigned all assignees\");\n } else {\n await ghExecArgs(root, [\"issue\", \"edit\", String(number), \"--add-assignee\", assignee]);\n updates.push(`assigned to @${assignee}`);\n }\n }\n\n if (updates.length === 0) {\n return `Issue #${number}: no changes requested.`;\n }\n return `Issue #${number} updated: ${updates.join(\"; \")}.`;\n}\n\nasync function invalidateManifest(root: string): Promise<void> {\n try {\n const manifestPath = join(root, \".codebase.json\");\n const content = await readFile(manifestPath, \"utf-8\");\n const manifest = JSON.parse(content) as Manifest;\n manifest.generated_at = \"1970-01-01T00:00:00.000Z\";\n const tmpPath = manifestPath + \".tmp\";\n await writeFile(tmpPath, JSON.stringify(manifest, null, 2), \"utf-8\");\n await rename(tmpPath, manifestPath);\n } catch {\n // If manifest doesn't exist yet, nothing to invalidate\n }\n}\n\nfunction respond(id: number | string, result: unknown): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, result };\n}\n\nfunction writeResponse(response: JsonRpcResponse): void {\n process.stdout.write(JSON.stringify(response) + \"\\n\");\n}\n","import { resolve, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { existsSync, readFileSync, statSync, readdirSync } from \"node:fs\";\nimport type { CLIOptions, Manifest } from \"../types.js\";\nimport { checkGhDetailed } from \"./init.js\";\nimport { setQuiet, log, success, heading, dim, bold } from \"../utils/output.js\";\n\nconst HOOK_MARKER = \"# codebase-auto-update\";\n\ninterface CheckResult {\n label: string;\n ok: boolean;\n detail: string;\n}\n\n/**\n * `codebase doctor` — health check for project intelligence setup.\n *\n * Runs all checks and prints a diagnostic report. No mutations.\n * Exit code 0 if all pass, 1 if any issues.\n */\nexport async function runDoctor(options: CLIOptions): Promise<void> {\n const _start = Date.now();\n setQuiet(options.quiet);\n const root = resolve(options.path);\n const results: CheckResult[] = [];\n\n heading(\"codebase doctor\\n\");\n\n // ─── 1. Manifest exists ──────────────────────────────────────\n const manifestPath = join(root, \".codebase.json\");\n let manifest: Manifest | null = null;\n\n if (existsSync(manifestPath)) {\n try {\n const raw = readFileSync(manifestPath, \"utf-8\");\n manifest = JSON.parse(raw) as Manifest;\n const stat = statSync(manifestPath);\n const sizeKB = (stat.size / 1024).toFixed(1);\n const ageMs = Date.now() - stat.mtimeMs;\n const age = formatAge(ageMs);\n results.push({\n label: \"Manifest\",\n ok: true,\n detail: `.codebase.json (${sizeKB} KB, ${age})`,\n });\n } catch {\n results.push({ label: \"Manifest\", ok: false, detail: \"Corrupted — run `codebase fix`\" });\n }\n } else {\n results.push({ label: \"Manifest\", ok: false, detail: \"Missing — run `codebase fix`\" });\n }\n\n // ─── 2. Manifest freshness ──────────────────────────────────\n if (manifest) {\n const generatedAt = manifest.generated_at ? new Date(manifest.generated_at).getTime() : 0;\n const ageHours = (Date.now() - generatedAt) / (1000 * 60 * 60);\n\n // Check if src/ files are newer than manifest\n let stale = false;\n if (existsSync(join(root, \"src\"))) {\n try {\n const srcStat = statSync(join(root, \"src\"));\n if (srcStat.mtimeMs > generatedAt) {\n stale = true;\n }\n } catch {\n /* ignore */\n }\n }\n\n if (stale) {\n results.push({\n label: \"Freshness\",\n ok: false,\n detail: `Stale (${Math.round(ageHours)} hours old)`,\n });\n } else {\n results.push({ label: \"Freshness\", ok: true, detail: \"Up to date\" });\n }\n\n // ─── 3. Detector categories ──────────────────────────────\n const expectedCategories = [\n \"project\",\n \"repo\",\n \"structure\",\n \"stack\",\n \"commands\",\n \"dependencies\",\n \"config\",\n \"git\",\n \"quality\",\n \"patterns\",\n ];\n const presentCategories = expectedCategories.filter((c) => c in manifest!);\n if (presentCategories.length === expectedCategories.length) {\n results.push({ label: \"Detectors\", ok: true, detail: \"10/10 categories present\" });\n } else {\n const missing = expectedCategories.filter((c) => !presentCategories.includes(c));\n results.push({ label: \"Detectors\", ok: false, detail: `Missing: ${missing.join(\", \")}` });\n }\n\n // ─── 3b. Detector warnings ───────────────────────────────\n const warnings = (manifest as unknown as Record<string, unknown>)._warnings;\n if (Array.isArray(warnings) && warnings.length > 0) {\n for (const w of warnings) {\n results.push({ label: \"Detector Warning\", ok: false, detail: `(non-fatal) ${w}` });\n }\n }\n }\n\n // ─── 4. GitHub CLI ──────────────────────────────────────────\n const ghStatus = await checkGhDetailed();\n const ghAvailable = ghStatus === \"authenticated\";\n\n if (ghStatus === \"authenticated\") {\n results.push({ label: \"GitHub CLI\", ok: true, detail: \"Authenticated\" });\n } else if (ghStatus === \"not-authenticated\") {\n results.push({\n label: \"GitHub CLI\",\n ok: false,\n detail: \"Not authenticated — run `gh auth login`\",\n });\n } else {\n results.push({ label: \"GitHub CLI\", ok: false, detail: \"Not installed — brew install gh\" });\n }\n\n // ─── 5. GitHub consistency ─────────────────────────────────\n if (manifest) {\n const repoUrl = manifest.repo?.url;\n const githubAvailable = manifest.status?.github_available;\n const hasGithubRemote = repoUrl?.includes(\"github.com\");\n\n if (hasGithubRemote && githubAvailable === false) {\n results.push({\n label: \"GitHub Sync\",\n ok: false,\n detail: \"Repo has GitHub remote but github_available is false\",\n });\n } else if (!hasGithubRemote && githubAvailable === true) {\n results.push({\n label: \"GitHub Sync\",\n ok: false,\n detail: \"No GitHub remote but github_available is true\",\n });\n } else {\n results.push({ label: \"GitHub Sync\", ok: true, detail: \"Consistent\" });\n }\n }\n\n // ─── 6. Claude Code injection ──────────────────────────────\n const claudeInjected = checkInjection(root);\n results.push({\n label: \"Claude Code\",\n ok: claudeInjected,\n detail: claudeInjected\n ? \"CLAUDE.md injected\"\n : \"CLAUDE.md injection missing — run `codebase fix`\",\n });\n\n // ─── 7. MCP ────────────────────────────────────────────────\n const mcpOk = checkMcpConfig(root);\n results.push({\n label: \"MCP\",\n ok: mcpOk,\n detail: mcpOk ? \".mcp.json configured\" : \".mcp.json missing — run `codebase fix`\",\n });\n\n // ─── 9. Git hooks ─────────────────────────────────────────\n if (existsSync(join(root, \".git\"))) {\n const postCommitOk = checkHook(root, \"post-commit\");\n const postCheckoutOk = checkHook(root, \"post-checkout\");\n const hookHasSync = checkHookSync(root);\n\n if (postCommitOk && postCheckoutOk) {\n const syncDetail = ghAvailable ? (hookHasSync ? \" (with --sync)\" : \"\") : \"\";\n results.push({\n label: \"Git Hooks\",\n ok: true,\n detail: `post-commit + post-checkout${syncDetail}`,\n });\n } else {\n const missing: string[] = [];\n if (!postCommitOk) {\n missing.push(\"post-commit\");\n }\n if (!postCheckoutOk) {\n missing.push(\"post-checkout\");\n }\n results.push({ label: \"Git Hooks\", ok: false, detail: `${missing.join(\" + \")} missing` });\n }\n\n // ─── 10. Hook sync flag ─────────────────────────────────\n if (ghAvailable && postCommitOk && !hookHasSync) {\n results.push({ label: \"Hook Sync\", ok: false, detail: \"Missing --sync flag\" });\n }\n } else {\n results.push({ label: \"Git Hooks\", ok: true, detail: \"Not a git repo — skipped\" });\n }\n\n // ─── 10b. commit-msg hook (branch enforcement) ────────────\n if (existsSync(join(root, \".git\"))) {\n const commitMsgOk = checkCommitMsgHook(root);\n if (commitMsgOk) {\n results.push({\n label: \"Branch Hook\",\n ok: true,\n detail: \"commit-msg blocks direct commits to main/master\",\n });\n } else {\n results.push({\n label: \"Branch Hook\",\n ok: false,\n detail: \"commit-msg hook missing — run `codebase fix`\",\n });\n }\n }\n\n // ─── 10e. pre-commit hook (lint + typecheck) ───────────────\n if (existsSync(join(root, \".git\"))) {\n const preCommitOk = checkPreCommitHook(root);\n const hasPkgScripts = (() => {\n try {\n const pkg = JSON.parse(readFileSync(join(root, \"package.json\"), \"utf-8\"));\n return !!(pkg.scripts?.check || pkg.scripts?.typecheck || pkg.scripts?.lint);\n } catch {\n return false;\n }\n })();\n if (!hasPkgScripts) {\n results.push({\n label: \"Pre-commit\",\n ok: true,\n detail: \"No lint/typecheck scripts — skipped\",\n });\n } else if (preCommitOk) {\n results.push({\n label: \"Pre-commit\",\n ok: true,\n detail: \"Runs lint + typecheck before every commit\",\n });\n } else {\n results.push({\n label: \"Pre-commit\",\n ok: false,\n detail: \"pre-commit hook missing — run `codebase fix`\",\n });\n }\n }\n\n // ─── 10c. Claude commands ──────────────────────────────────\n const claudeCommandsDir = join(root, \".claude\", \"commands\");\n if (existsSync(claudeCommandsDir)) {\n const cmdFiles = readdirSync(claudeCommandsDir).filter((f) => f.endsWith(\".md\"));\n results.push({\n label: \"Claude Commands\",\n ok: cmdFiles.length > 0,\n detail: `${cmdFiles.length} commands in .claude/commands/`,\n });\n } else {\n results.push({\n label: \"Claude Commands\",\n ok: false,\n detail: \".claude/commands/ missing — run `codebase setup`\",\n });\n }\n\n // ─── 10c-ii. Claude Skills ─────────────────────────────────\n const skillsDir = join(homedir(), \".claude\", \"skills\");\n if (existsSync(skillsDir)) {\n const skillFiles = readdirSync(skillsDir).filter((f) => f.endsWith(\".skill\"));\n if (skillFiles.length > 0) {\n const names = skillFiles.map((f) => f.replace(/\\.skill$/, \"\")).join(\", \");\n results.push({\n label: \"Claude Skills\",\n ok: true,\n detail: `${skillFiles.length} skill${skillFiles.length > 1 ? \"s\" : \"\"} installed: ${names}`,\n });\n } else {\n results.push({\n label: \"Claude Skills\",\n ok: false,\n detail: \"No skills installed — run: codebase setup\",\n });\n }\n } else {\n results.push({\n label: \"Claude Skills\",\n ok: false,\n detail: \"No skills installed — run: codebase setup\",\n });\n }\n\n // ─── 10d. Claude Code hooks ────────────────────────────────\n const guardHook = join(root, \".claude\", \"hooks\", \"git-guard.sh\");\n const postHook = join(root, \".claude\", \"hooks\", \"git-post.sh\");\n const settingsFile = join(root, \".claude\", \"settings.json\");\n const hooksInstalled = existsSync(guardHook) && existsSync(postHook);\n const settingsOk = (() => {\n if (!existsSync(settingsFile)) {\n return false;\n }\n try {\n const s = JSON.parse(readFileSync(settingsFile, \"utf-8\"));\n const pre = JSON.stringify(s.hooks?.PreToolUse ?? \"\");\n const post = JSON.stringify(s.hooks?.PostToolUse ?? \"\");\n return pre.includes(\"git-guard\") && post.includes(\"git-post\");\n } catch {\n return false;\n }\n })();\n if (hooksInstalled && settingsOk) {\n results.push({\n label: \"Claude Hooks\",\n ok: true,\n detail: \"git-guard + git-post wired in settings.json\",\n });\n } else {\n const missing: string[] = [];\n if (!hooksInstalled) {\n missing.push(\"hook scripts\");\n }\n if (!settingsOk) {\n missing.push(\"settings.json wiring\");\n }\n results.push({\n label: \"Claude Hooks\",\n ok: false,\n detail: `Missing: ${missing.join(\", \")} — run \\`codebase setup\\``,\n });\n }\n\n // ─── 11. Gitignore ────────────────────────────────────────\n const gitignorePath = join(root, \".gitignore\");\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, \"utf-8\");\n if (content.includes(\".codebase.json\")) {\n results.push({ label: \"Gitignore\", ok: true, detail: \".codebase.json in .gitignore\" });\n } else {\n results.push({ label: \"Gitignore\", ok: false, detail: \".codebase.json not in .gitignore\" });\n }\n } else {\n results.push({ label: \"Gitignore\", ok: false, detail: \".gitignore missing\" });\n }\n\n // ─── Print results ────────────────────────────────────────\n const NO_COLOR = !!process.env.NO_COLOR;\n const green = NO_COLOR ? \"\" : \"\\x1b[32m\";\n const red = NO_COLOR ? \"\" : \"\\x1b[31m\";\n const reset = NO_COLOR ? \"\" : \"\\x1b[0m\";\n\n const LABEL_WIDTH = 20;\n\n type Section = \"MANIFEST\" | \"GITHUB\" | \"AI TOOLS\" | \"GIT\";\n\n function sectionFor(label: string): Section {\n if ([\"Manifest\", \"Freshness\", \"Detectors\", \"Detector Warning\"].includes(label)) {\n return \"MANIFEST\";\n }\n if ([\"GitHub CLI\", \"GitHub Sync\"].includes(label)) {\n return \"GITHUB\";\n }\n if (\n [\"Claude Code\", \"MCP\", \"Claude Commands\", \"Claude Skills\", \"Claude Hooks\"].includes(label)\n ) {\n return \"AI TOOLS\";\n }\n return \"GIT\";\n }\n\n let lastSection: Section | null = null;\n\n for (const r of results) {\n const section = sectionFor(r.label.trimStart());\n if (section !== lastSection) {\n log(\"\");\n dim(` ${section}`);\n lastSection = section;\n }\n const icon = r.ok ? `${green}\\u2713${reset}` : `${red}\\u2717${reset}`;\n log(` ${r.label.trimStart().padEnd(LABEL_WIDTH)} ${icon} ${r.detail}`);\n }\n\n const issues = results.filter((r) => !r.ok);\n const total = results.length;\n const passing = total - issues.length;\n\n log(\"\");\n if (issues.length === 0) {\n log(` ${bold(`Health: ${passing}/${total}`)} — All checks passed.`);\n } else {\n log(\n ` ${bold(`Health: ${passing}/${total}`)} — ${issues.length} issue${issues.length > 1 ? \"s\" : \"\"} found. Run \\`codebase fix\\` to repair.`\n );\n }\n log(\"\");\n const elapsed = ((Date.now() - _start) / 1000).toFixed(1);\n success(`Done (${elapsed}s)`);\n\n if (issues.length > 0) {\n process.exit(1);\n }\n}\n\n// ─── Check helpers ──────────────────────────────────────────────\n\nfunction checkInjection(root: string): boolean {\n const filePath = join(root, \"CLAUDE.md\");\n if (!existsSync(filePath)) {\n return false;\n }\n const content = readFileSync(filePath, \"utf-8\");\n return content.includes(\"<!-- codebase:start -->\");\n}\n\nfunction checkMcpConfig(root: string): boolean {\n const mcpPath = join(root, \".mcp.json\");\n if (!existsSync(mcpPath)) {\n return false;\n }\n try {\n const config = JSON.parse(readFileSync(mcpPath, \"utf-8\"));\n return !!config.mcpServers?.codebase;\n } catch {\n return false;\n }\n}\n\nfunction checkHook(root: string, hookName: string): boolean {\n const hookPath = join(root, \".git\", \"hooks\", hookName);\n if (!existsSync(hookPath)) {\n return false;\n }\n const content = readFileSync(hookPath, \"utf-8\");\n return content.includes(HOOK_MARKER);\n}\n\nfunction checkCommitMsgHook(root: string): boolean {\n const hookPath = join(root, \".git\", \"hooks\", \"commit-msg\");\n if (!existsSync(hookPath)) {\n return false;\n }\n const content = readFileSync(hookPath, \"utf-8\");\n return content.includes(\"codebase-branch-check\");\n}\n\nfunction checkPreCommitHook(root: string): boolean {\n const hookPath = join(root, \".git\", \"hooks\", \"pre-commit\");\n if (!existsSync(hookPath)) {\n return false;\n }\n const content = readFileSync(hookPath, \"utf-8\");\n return content.includes(\"codebase-pre-commit\");\n}\n\nfunction checkHookSync(root: string): boolean {\n const hookPath = join(root, \".git\", \"hooks\", \"post-commit\");\n if (!existsSync(hookPath)) {\n return false;\n }\n const content = readFileSync(hookPath, \"utf-8\");\n return content.includes(\"--sync\");\n}\n\nfunction formatAge(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n if (seconds < 60) {\n return `${seconds} sec ago`;\n }\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) {\n return `${minutes} min ago`;\n }\n const hours = Math.floor(minutes / 60);\n if (hours < 24) {\n return `${hours} hr ago`;\n }\n const days = Math.floor(hours / 24);\n return `${days} day${days > 1 ? \"s\" : \"\"} ago`;\n}\n","import { resolve, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { writeFile } from \"node:fs/promises\";\nimport type { CLIOptions } from \"../types.js\";\nimport { scan } from \"../scanner/engine.js\";\nimport { checkGhDetailed, autoConfigureMcp } from \"./init.js\";\nimport { installHooks } from \"../integrations/githook.js\";\nimport { updateGitignore } from \"../integrations/gitignore.js\";\nimport { setQuiet, log, success, heading, info } from \"../utils/output.js\";\n\nconst HOOK_MARKER = \"# codebase-auto-update\";\n\nconst NO_COLOR = !!process.env.NO_COLOR;\nconst green = NO_COLOR ? \"\" : \"\\x1b[32m\";\nconst reset = NO_COLOR ? \"\" : \"\\x1b[0m\";\n\nfunction fixed(msg: string): void {\n console.log(` ${green}\\u2713${reset} ${msg}`);\n}\n\n/**\n * `codebase fix` — auto-repair everything `doctor` would flag.\n *\n * Re-runs relevant parts of init for anything broken or missing.\n * Shows what it fixed.\n */\nexport async function runFix(options: CLIOptions): Promise<void> {\n const _start = Date.now();\n setQuiet(options.quiet);\n const root = resolve(options.path);\n let fixCount = 0;\n\n heading(\"codebase fix\\n\");\n\n // ─── Check GitHub CLI (won't auto-fix) ─────────────────────\n const ghStatus = await checkGhDetailed();\n const ghAvailable = ghStatus === \"authenticated\";\n\n if (ghStatus === \"not-installed\") {\n info(\"GitHub CLI not installed — install with: brew install gh\");\n info(\"(Cannot auto-fix — requires manual installation)\\n\");\n } else if (ghStatus === \"not-authenticated\") {\n info(\"GitHub CLI not authenticated — run: gh auth login\");\n info(\"(Cannot auto-fix — requires manual login)\\n\");\n }\n\n // ─── 1 & 2. Manifest missing, corrupted, or stale → rescan ─\n const manifestPath = join(root, \".codebase.json\");\n let needsScan = false;\n\n if (!existsSync(manifestPath)) {\n needsScan = true;\n } else {\n try {\n const raw = readFileSync(manifestPath, \"utf-8\");\n JSON.parse(raw); // validate JSON\n } catch {\n needsScan = true;\n }\n }\n\n // Check freshness if manifest exists\n if (!needsScan && existsSync(manifestPath)) {\n try {\n const raw = readFileSync(manifestPath, \"utf-8\");\n const manifest = JSON.parse(raw);\n const generatedAt = manifest.generated_at ? new Date(manifest.generated_at).getTime() : 0;\n if (existsSync(join(root, \"src\"))) {\n const { statSync } = await import(\"node:fs\");\n const srcStat = statSync(join(root, \"src\"));\n if (srcStat.mtimeMs > generatedAt) {\n needsScan = true;\n }\n }\n } catch {\n needsScan = true;\n }\n }\n\n if (needsScan) {\n const manifest = await scan(root, {\n depth: options.depth,\n quiet: true,\n sync: ghAvailable,\n });\n const content = JSON.stringify(manifest, null, 2);\n await writeFile(manifestPath, content, \"utf-8\");\n const sizeKB = (Buffer.byteLength(content) / 1024).toFixed(1);\n fixed(`Re-scanned project \\u2192 .codebase.json (${sizeKB} KB)`);\n fixCount++;\n }\n\n // ─── 3. Re-inject CLAUDE.md if missing ────────────────────\n const { claudeIntegration } = await import(\"../integrations/claude.js\");\n if (!checkInjection(root)) {\n claudeIntegration.inject(root);\n fixed(\"Re-injected Claude Code instructions into CLAUDE.md\");\n fixCount++;\n }\n\n // ─── 4. Fix missing MCP config ────────────────────────────\n const toolNames = new Set([\"claude\"]);\n const mcpConfigured = await autoConfigureMcp(root, toolNames);\n for (const entry of mcpConfigured) {\n fixed(`Added MCP entry to ${entry}`);\n fixCount++;\n }\n\n // ─── 5 & 7. Git hooks ─────────────────────────────────────\n if (existsSync(join(root, \".git\"))) {\n const postCommitOk = checkHook(root, \"post-commit\");\n const postCheckoutOk = checkHook(root, \"post-checkout\");\n const hookHasSync = checkHookSync(root);\n const preCommitOk = checkPreCommitHook(root);\n const needsReinstall =\n !postCommitOk || !postCheckoutOk || (ghAvailable && !hookHasSync) || !preCommitOk;\n\n if (needsReinstall) {\n installHooks(root, ghAvailable);\n const fixes: string[] = [];\n if (!postCommitOk) {\n fixes.push(\"post-commit\");\n }\n if (!postCheckoutOk) {\n fixes.push(\"post-checkout\");\n }\n if (ghAvailable && !hookHasSync) {\n fixes.push(\"--sync flag\");\n }\n if (!preCommitOk) {\n fixes.push(\"pre-commit\");\n }\n fixed(`Installed ${fixes.join(\" + \")} hook${fixes.length > 1 ? \"s\" : \"\"}`);\n fixCount++;\n }\n }\n\n // ─── 6. Gitignore ─────────────────────────────────────────\n const gitignorePath = join(root, \".gitignore\");\n const gitignoreContent = existsSync(gitignorePath) ? readFileSync(gitignorePath, \"utf-8\") : \"\";\n if (!gitignoreContent.includes(\".codebase.json\")) {\n updateGitignore(root);\n fixed(\"Added .codebase.json to .gitignore\");\n fixCount++;\n }\n\n // ─── 7. Claude commands ───────────────────────────────────\n const claudeCommandsDir = join(root, \".claude\", \"commands\");\n if (!existsSync(claudeCommandsDir)) {\n const { installClaudeCommandsForFix } = await import(\"./setup.js\");\n installClaudeCommandsForFix(root);\n fixed(\"Installed Claude commands → .claude/commands/\");\n fixCount++;\n }\n\n // ─── 7b. Claude skills ────────────────────────────────────\n const skillsDir = join(homedir(), \".claude\", \"skills\");\n const hasSkills =\n existsSync(skillsDir) && readdirSync(skillsDir).some((f) => f.endsWith(\".skill\"));\n if (!hasSkills) {\n const { installClaudeSkillsForFix } = await import(\"./setup.js\");\n installClaudeSkillsForFix(root);\n fixed(\"Installed Claude skills → ~/.claude/skills/\");\n fixCount++;\n }\n\n // ─── 8. Claude Code hooks ─────────────────────────────────\n const guardHook = join(root, \".claude\", \"hooks\", \"git-guard.sh\");\n const postHook = join(root, \".claude\", \"hooks\", \"git-post.sh\");\n const settingsFile = join(root, \".claude\", \"settings.json\");\n const hooksOk = existsSync(guardHook) && existsSync(postHook);\n const settingsOk = (() => {\n if (!existsSync(settingsFile)) {\n return false;\n }\n try {\n const s = JSON.parse(readFileSync(settingsFile, \"utf-8\"));\n const pre = JSON.stringify(s.hooks?.PreToolUse ?? \"\");\n const post = JSON.stringify(s.hooks?.PostToolUse ?? \"\");\n return pre.includes(\"git-guard\") && post.includes(\"git-post\");\n } catch {\n return false;\n }\n })();\n if (!hooksOk || !settingsOk) {\n const { installClaudeHooksForFix } = await import(\"./setup.js\");\n installClaudeHooksForFix(root);\n fixed(\"Installed Claude Code hooks → .claude/hooks/ + settings.json\");\n fixCount++;\n }\n\n // ─── Summary ──────────────────────────────────────────────\n log(\"\");\n if (fixCount === 0) {\n log(\" Nothing to fix. Your project is healthy.\");\n } else {\n log(` Fixed ${fixCount} issue${fixCount > 1 ? \"s\" : \"\"}. Run \\`codebase doctor\\` to verify.`);\n }\n log(\"\");\n const elapsed = ((Date.now() - _start) / 1000).toFixed(1);\n success(`Done (${elapsed}s)`);\n}\n\n// ─── Check helpers (duplicated from doctor for independence) ──\n\nfunction checkInjection(root: string): boolean {\n const filePath = join(root, \"CLAUDE.md\");\n if (!existsSync(filePath)) {\n return false;\n }\n const content = readFileSync(filePath, \"utf-8\");\n return content.includes(\"<!-- codebase:start -->\");\n}\n\nfunction checkHook(root: string, hookName: string): boolean {\n const hookPath = join(root, \".git\", \"hooks\", hookName);\n if (!existsSync(hookPath)) {\n return false;\n }\n const content = readFileSync(hookPath, \"utf-8\");\n return content.includes(HOOK_MARKER);\n}\n\nfunction checkHookSync(root: string): boolean {\n const hookPath = join(root, \".git\", \"hooks\", \"post-commit\");\n if (!existsSync(hookPath)) {\n return false;\n }\n const content = readFileSync(hookPath, \"utf-8\");\n return content.includes(\"--sync\");\n}\n\nfunction checkPreCommitHook(root: string): boolean {\n const hookPath = join(root, \".git\", \"hooks\", \"pre-commit\");\n if (!existsSync(hookPath)) {\n return false;\n }\n const content = readFileSync(hookPath, \"utf-8\");\n return content.includes(\"codebase-pre-commit\");\n}\n","import { resolve, join } from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport type { CLIOptions } from \"../types.js\";\nimport { log, success, warn, error, heading, info } from \"../utils/output.js\";\n\nexport async function runRelease(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n const dryRun = options.dryRun;\n const versionOverride = options.positionals[0] ?? null;\n\n heading(`codebase release${dryRun ? \" (dry run)\" : \"\"}`);\n\n // ── Prerequisites ─────────────────────────────────────────────\n const ghOk = await checkGhAuth();\n if (!ghOk) {\n error(\"gh CLI not authenticated. Run: gh auth login\");\n process.exit(1);\n }\n const hasRemote = await execGitStr(root, \"remote\", \"get-url\", \"origin\");\n if (!hasRemote) {\n error(\"No git remote. Run: git remote add origin <url>\");\n process.exit(1);\n }\n\n // ── Gate 1a: No open bugs ─────────────────────────────────────\n log(\"\\nChecking launch gates...\");\n\n // Check manifest for open bug issues (fast, no API call needed)\n const manifestPath = join(root, \".codebase.json\");\n if (existsSync(manifestPath) && !options.dryRun) {\n try {\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf-8\"));\n const openBugs = (manifest.status?.issues || []).filter(\n (i: { state: string; labels: string[] }) =>\n i.state === \"open\" && i.labels.some((l: string) => l.toLowerCase().includes(\"bug\"))\n );\n if (openBugs.length > 0 && !options.force) {\n error(`Gate 1a FAILED — ${openBugs.length} open bug issue(s) in manifest`);\n for (const b of openBugs.slice(0, 5)) {\n log(` #${b.number}: ${b.title} [${b.labels.join(\", \")}]`);\n }\n log(\"\\n Fix: resolve open bugs or run /simulate. Use --force to skip this gate.\");\n process.exit(1);\n }\n } catch {\n /* manifest unreadable — fall through to live check */\n }\n }\n\n const [critical, high] = await Promise.all([\n countIssues(root, [\"bug\", \"critical\"]),\n countIssues(root, [\"bug\", \"high\"]),\n ]);\n if (critical > 0 || high > 0) {\n error(\"Gate 1a FAILED — open blocking bugs:\");\n if (critical > 0) {\n log(` Critical: ${critical}`);\n }\n if (high > 0) {\n log(` High: ${high}`);\n }\n log(\"\\n Fix: run /simulate, or close with wontfix label\");\n process.exit(1);\n }\n success(\"Gate 1a — no open bugs\");\n\n // ── Gate 1b: Test suite ───────────────────────────────────────\n const testCmd = detectTestCmd(root);\n if (testCmd) {\n const testResult = await runTestSuite(root, testCmd);\n if (!testResult.ok) {\n error(\"Gate 1b FAILED — test suite has failures\");\n log(testResult.output.split(\"\\n\").slice(-10).join(\"\\n\"));\n log(\"\\n Fix: run /review to repair failing tests\");\n process.exit(1);\n }\n success(`Gate 1b — tests pass (${testCmd})`);\n } else {\n warn(\"Gate 1b — no test runner detected (skipping)\");\n }\n\n // ── Gate 1c: World-class score ≥ 7.0 ─────────────────────────\n const wcScore = await getWorldClassScore(root);\n if (wcScore !== null && wcScore < 7.0) {\n error(`Gate 1c FAILED — world-class score ${wcScore}/10 (minimum 7.0)`);\n log(\" Fix: run /simulate to improve UX score\");\n process.exit(1);\n }\n if (wcScore !== null) {\n success(`Gate 1c — world-class score ${wcScore}/10`);\n } else {\n warn(\"Gate 1c — no simulation data yet (run /simulate first)\");\n }\n\n // ── Gate 2: Carry bugs (warning only) ────────────────────────\n const carry = await countIssues(root, [\"carry\"]);\n if (carry > 0) {\n warn(`Gate 2 — ${carry} carry bug(s) will appear in release notes`);\n } else {\n success(\"Gate 2 — no carry bugs\");\n }\n\n // ── Gate 3: Branch clean and current ─────────────────────────\n const dirty = await execGitStr(root, \"status\", \"--short\");\n if (dirty) {\n error(\"Gate 3 FAILED — uncommitted changes\");\n log(dirty);\n process.exit(1);\n }\n await execGitStr(root, \"fetch\", \"origin\", \"develop\");\n const behind = await execGitStr(root, \"log\", \"HEAD..origin/develop\", \"--oneline\");\n if (behind) {\n error(\"Gate 3 FAILED — branch is behind origin/develop\");\n log(\" Fix: git pull origin develop\");\n process.exit(1);\n }\n success(\"Gate 3 — branch clean and current\");\n\n log(\"\\nAll gates passed.\");\n\n // ── Version ───────────────────────────────────────────────────\n const version = versionOverride ?? (await nextVersion(root));\n log(`\\nRelease version: ${version}`);\n\n // ── Release notes ─────────────────────────────────────────────\n const notes = await buildReleaseNotes(root, version, carry);\n\n if (dryRun) {\n log(\"\\n--- DRY RUN — release notes preview ---\");\n log(notes);\n log(\"--- DRY RUN — no tag, no merge, no GitHub release created ---\");\n return;\n }\n\n // ── Tag ───────────────────────────────────────────────────────\n await gitRun(root, [\"tag\", \"-a\", version, \"-m\", `Release ${version}`]);\n await gitRun(root, [\"push\", \"origin\", version]);\n success(`Tagged ${version}`);\n\n // ── Merge develop → main ──────────────────────────────────────\n await gitRun(root, [\"checkout\", \"main\"]);\n await gitRun(root, [\"pull\", \"origin\", \"main\"]);\n await gitRun(root, [\"merge\", \"develop\", \"--no-ff\", \"-m\", `Release ${version}`]);\n await gitRun(root, [\"push\", \"origin\", \"main\"]);\n await gitRun(root, [\"checkout\", \"develop\"]);\n success(\"Merged develop → main\");\n\n // ── GitHub release ────────────────────────────────────────────\n const { ok: releaseOk, stdout: releaseUrl } = await ghRun(root, [\n \"release\",\n \"create\",\n version,\n \"--title\",\n version,\n \"--notes\",\n notes,\n \"--target\",\n \"develop\",\n ]);\n if (releaseOk) {\n success(`GitHub release: ${releaseUrl}`);\n } else {\n warn(\"Could not create GitHub release — tag and merge succeeded\");\n }\n\n // ── Milestone rotation ────────────────────────────────────────\n await rotateMilestone(root);\n\n log(`\\ncodebase release ${version} complete.`);\n log(\"develop → main merged. Tag pushed. Ready.\");\n}\n\n// ─── Release gate helpers ────────────────────────────────────────\n\nfunction execGitStr(root: string, ...args: string[]): Promise<string> {\n return new Promise((resolve) => {\n execFile(\"git\", args, { cwd: root, timeout: 30_000 }, (err, stdout) => {\n resolve(err ? \"\" : stdout.trim());\n });\n });\n}\n\nfunction gitRun(root: string, args: string[]): Promise<void> {\n return new Promise((resolve, reject) => {\n execFile(\"git\", args, { cwd: root, timeout: 30_000 }, (err, _stdout, stderr) => {\n if (err) {\n reject(new Error(stderr || err.message));\n } else {\n resolve();\n }\n });\n });\n}\n\nfunction ghRun(root: string, args: string[]): Promise<{ ok: boolean; stdout: string }> {\n return new Promise((resolve) => {\n execFile(\"gh\", args, { cwd: root, timeout: 30_000 }, (err, stdout) => {\n resolve({ ok: !err, stdout: (stdout || \"\").trim() });\n });\n });\n}\n\nasync function checkGhAuth(): Promise<boolean> {\n return new Promise((resolve) => {\n execFile(\"gh\", [\"auth\", \"status\"], { timeout: 5_000 }, (err) => resolve(!err));\n });\n}\n\nasync function countIssues(root: string, labels: string[]): Promise<number> {\n const { stdout } = await ghRun(root, [\n \"issue\",\n \"list\",\n \"--label\",\n labels.join(\",\"),\n \"--state\",\n \"open\",\n \"--limit\",\n \"100\",\n \"--json\",\n \"number\",\n \"--jq\",\n \"length\",\n ]);\n return parseInt(stdout, 10) || 0;\n}\n\nfunction detectTestCmd(root: string): string | null {\n try {\n const pkg = JSON.parse(readFileSync(join(root, \"package.json\"), \"utf-8\"));\n if (pkg.devDependencies?.vitest || pkg.dependencies?.vitest) {\n return \"npx vitest run\";\n }\n if (pkg.devDependencies?.jest || pkg.dependencies?.jest) {\n return \"npx jest\";\n }\n if (pkg.scripts?.test) {\n return \"npm test\";\n }\n } catch {\n /* ignore */\n }\n if (existsSync(join(root, \"pyproject.toml\"))) {\n try {\n if (readFileSync(join(root, \"pyproject.toml\"), \"utf-8\").includes(\"pytest\")) {\n return \"uv run pytest\";\n }\n } catch {\n /* ignore */\n }\n }\n return null;\n}\n\nfunction runTestSuite(root: string, cmd: string): Promise<{ ok: boolean; output: string }> {\n const [bin, ...args] = cmd.split(\" \");\n return new Promise((resolve) => {\n execFile(bin, args, { cwd: root, timeout: 120_000 }, (err, stdout, stderr) => {\n resolve({ ok: !err, output: stdout + stderr });\n });\n });\n}\n\nasync function getWorldClassScore(root: string): Promise<number | null> {\n const { stdout } = await ghRun(root, [\n \"issue\",\n \"list\",\n \"--label\",\n \"cycle\",\n \"--state\",\n \"all\",\n \"--limit\",\n \"1\",\n \"--json\",\n \"body\",\n \"--jq\",\n \".[0].body // empty\",\n ]);\n if (!stdout) {\n return null;\n }\n const match = stdout.match(/[Ww]orld[- ]class[^0-9]*([0-9]+(?:\\.[0-9]+)?)\\/10/);\n return match ? parseFloat(match[1]) : null;\n}\n\nasync function nextVersion(root: string): Promise<string> {\n const latest = await execGitStr(root, \"describe\", \"--tags\", \"--abbrev=0\");\n if (!latest) {\n return \"v0.1.0\";\n }\n const m = latest.match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!m) {\n return \"v0.1.0\";\n }\n return `v${m[1]}.${m[2]}.${parseInt(m[3], 10) + 1}`;\n}\n\nasync function buildReleaseNotes(\n root: string,\n version: string,\n carryCount: number\n): Promise<string> {\n const date = new Date().toISOString().split(\"T\")[0];\n const [arch, bugs, openCarry, openArch] = await Promise.all([\n ghRun(root, [\n \"issue\",\n \"list\",\n \"--label\",\n \"arch\",\n \"--state\",\n \"closed\",\n \"--limit\",\n \"50\",\n \"--json\",\n \"number,title\",\n \"--jq\",\n '.[] | \"- #\\(.number) \\(.title)\"',\n ]),\n ghRun(root, [\n \"issue\",\n \"list\",\n \"--label\",\n \"bug,sim\",\n \"--state\",\n \"closed\",\n \"--limit\",\n \"50\",\n \"--json\",\n \"number,title\",\n \"--jq\",\n '.[] | \"- #\\(.number) \\(.title)\"',\n ]),\n ghRun(root, [\n \"issue\",\n \"list\",\n \"--label\",\n \"carry\",\n \"--state\",\n \"open\",\n \"--limit\",\n \"20\",\n \"--json\",\n \"number,title\",\n \"--jq\",\n '.[] | \"- #\\(.number) \\(.title)\"',\n ]),\n ghRun(root, [\n \"issue\",\n \"list\",\n \"--label\",\n \"arch\",\n \"--state\",\n \"open\",\n \"--limit\",\n \"20\",\n \"--json\",\n \"number,title\",\n \"--jq\",\n '.[] | \"- #\\(.number) \\(.title)\"',\n ]),\n ]);\n\n let notes = `# Release ${version} — ${date}\\n\\n`;\n if (arch.stdout) {\n notes += `## What's New\\n\\n${arch.stdout}\\n\\n`;\n }\n if (bugs.stdout) {\n notes += `## Bug Fixes\\n\\n${bugs.stdout}\\n\\n`;\n }\n if (openCarry.stdout || openArch.stdout) {\n notes += `## Known Issues\\n\\n`;\n if (openCarry.stdout) {\n notes += `### Carry Bugs (${carryCount})\\n${openCarry.stdout}\\n\\n`;\n }\n if (openArch.stdout) {\n notes += `### Pending Architecture\\n${openArch.stdout}\\n\\n`;\n }\n }\n return notes;\n}\n\nasync function rotateMilestone(root: string): Promise<void> {\n const envPath = join(root, \".vibekit\", \"milestone.env\");\n if (!existsSync(envPath)) {\n return;\n }\n const content = readFileSync(envPath, \"utf-8\");\n const numMatch = content.match(/MILESTONE_NUMBER=(\\d+)/);\n const titleMatch = content.match(/MILESTONE_TITLE=(v[\\d.]+)/);\n if (!numMatch || !titleMatch) {\n return;\n }\n\n const { stdout: repo } = await ghRun(root, [\n \"repo\",\n \"view\",\n \"--json\",\n \"nameWithOwner\",\n \"--jq\",\n \".nameWithOwner\",\n ]);\n if (!repo) {\n return;\n }\n\n await ghRun(root, [\n \"api\",\n `repos/${repo}/milestones/${numMatch[1]}`,\n \"-X\",\n \"PATCH\",\n \"-f\",\n \"state=closed\",\n ]);\n info(`Milestone ${titleMatch[1]} closed`);\n\n const m = titleMatch[1].match(/^v(\\d+)\\.(\\d+)$/);\n if (!m) {\n return;\n }\n const nextTitle = `v${m[1]}.${parseInt(m[2], 10) + 1}`;\n const { stdout: newMs } = await ghRun(root, [\n \"api\",\n `repos/${repo}/milestones`,\n \"-X\",\n \"POST\",\n \"-f\",\n `title=${nextTitle}`,\n \"-f\",\n \"state=open\",\n \"-f\",\n \"description=Next release cycle — managed by vibekit\",\n \"--jq\",\n \".number\",\n ]);\n if (newMs) {\n writeFileSync(envPath, `MILESTONE_NUMBER=${newMs}\\nMILESTONE_TITLE=${nextTitle}\\n`, \"utf-8\");\n success(`Next milestone created: ${nextTitle}`);\n }\n}\n","import { resolve, join } from \"node:path\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport type { CLIOptions } from \"../types.js\";\nimport { log, heading, info, bold } from \"../utils/output.js\";\n\nconst PLAN_FILENAME = \"PLAN.md\";\n\n/**\n * `codebase plan` — read or update PLAN.md, Claude's persistent working memory.\n *\n * Usage:\n * codebase plan → print current PLAN.md\n * codebase plan --message \"text\" → append a status update to PLAN.md\n */\nexport async function runPlan(options: CLIOptions): Promise<void> {\n const root = resolve(options.path);\n const planPath = join(root, PLAN_FILENAME);\n\n // Write mode: append a status update\n if (options.message) {\n await appendPlanUpdate(planPath, options.message);\n return;\n }\n\n // Read mode: print PLAN.md\n if (!existsSync(planPath)) {\n info(\"No PLAN.md found. Create one by running:\");\n log(\"\");\n log(' codebase plan --message \"Started sprint. Working on auth refactor.\"');\n log(\"\");\n log(\"Or create PLAN.md manually with the vibeloop schema:\");\n log(\" ## Current Sprint\");\n log(\" ## In Flight\");\n log(\" ## Decisions Log\");\n log(\" ## Blocked\");\n return;\n }\n\n const content = await readFile(planPath, \"utf-8\");\n heading(\"PLAN.md\");\n log(content);\n}\n\nasync function appendPlanUpdate(planPath: string, message: string): Promise<void> {\n const timestamp = new Date().toISOString().split(\"T\")[0];\n const entry = `\\n<!-- updated: ${timestamp} -->\\n${message.trim()}\\n`;\n\n if (!existsSync(planPath)) {\n // Bootstrap PLAN.md with vibeloop schema\n const initial = `# PLAN.md — Autonomous Loop State\n\n> Managed by Claude. Updated each build/simulate cycle.\n\n## Current Sprint\n\n\n## In Flight\n\n\n## Decisions Log\n\n\n## Blocked\n\n\n## Update Log\n${entry}`;\n await writeFile(planPath, initial, \"utf-8\");\n log(`${bold(\"Created\")} PLAN.md`);\n return;\n }\n\n // Append to Update Log section or end of file\n let content = await readFile(planPath, \"utf-8\");\n if (content.includes(\"## Update Log\")) {\n content = content.replace(/(## Update Log\\n)/, `$1${entry}`);\n } else {\n content += `\\n## Update Log\\n${entry}`;\n }\n\n await writeFile(planPath, content, \"utf-8\");\n log(`${bold(\"Updated\")} PLAN.md`);\n}\n","import { join, resolve } from \"node:path\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport { execFile } from \"node:child_process\";\nimport type { CLIOptions } from \"../types.js\";\nimport { log, info } from \"../utils/output.js\";\n\nfunction extractSkillMd(skillPath: string): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\"unzip\", [\"-p\", skillPath, \"*/SKILL.md\"], (err, stdout) => {\n if (err && !stdout) {\n reject(err);\n } else {\n resolve(stdout ?? \"\");\n }\n });\n });\n}\n\nfunction parseYamlFrontmatter(content: string): Record<string, string> {\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!match) {\n return {};\n }\n const result: Record<string, string> = {};\n for (const line of match[1].split(\"\\n\")) {\n const colon = line.indexOf(\":\");\n if (colon === -1) {\n continue;\n }\n const key = line.slice(0, colon).trim();\n const value = line\n .slice(colon + 1)\n .trim()\n .replace(/^['\"]|['\"]$/g, \"\");\n if (key) {\n result[key] = value;\n }\n }\n return result;\n}\n\nexport async function runSkills(options: CLIOptions): Promise<void> {\n const globalSkillsDir = join(process.env[\"HOME\"] ?? \"~\", \".claude\", \"skills\");\n const projectSkillsDir = join(resolve(options.path ?? \".\"), \".claude\", \"skills\");\n\n const seenFiles = new Set<string>();\n const entries: Array<{ file: string; dir: string }> = [];\n\n // Project-local takes precedence — add first, then global (skip duplicates)\n for (const dir of [projectSkillsDir, globalSkillsDir]) {\n if (existsSync(dir)) {\n for (const f of readdirSync(dir)) {\n if (f.endsWith(\".skill\") && !seenFiles.has(f)) {\n seenFiles.add(f);\n entries.push({ file: f, dir });\n }\n }\n }\n }\n\n if (entries.length === 0) {\n log(\"No skills installed. Run: codebase setup\");\n return;\n }\n\n const rows: Array<{ name: string; description: string; file: string }> = [];\n\n for (const { file, dir } of entries) {\n const skillPath = join(dir, file);\n let name = file.replace(/\\.skill$/, \"\");\n let description = \"\";\n\n try {\n const content = await extractSkillMd(skillPath);\n const fm = parseYamlFrontmatter(content);\n if (fm[\"name\"]) {\n name = fm[\"name\"];\n }\n if (fm[\"description\"]) {\n description = fm[\"description\"];\n }\n } catch {\n // If unzip fails (e.g. not a zip), fall back to filename\n }\n\n rows.push({ name, description, file });\n }\n\n if (rows.length === 0) {\n log(\"No skills installed. Run: codebase setup\");\n return;\n }\n\n // Calculate column widths\n const nameWidth = Math.max(4, ...rows.map((r) => r.name.length));\n const descWidth = Math.max(11, ...rows.map((r) => r.description.length));\n const fileWidth = Math.max(4, ...rows.map((r) => r.file.length));\n\n const pad = (s: string, w: number): string => s.padEnd(w);\n const sep = ` ${\"─\".repeat(nameWidth)} ${\"─\".repeat(descWidth)} ${\"─\".repeat(fileWidth)}`;\n\n info(`\\n ${pad(\"Name\", nameWidth)} ${pad(\"Description\", descWidth)} ${\"File\"}`);\n log(sep);\n for (const row of rows) {\n log(` ${pad(row.name, nameWidth)} ${pad(row.description, descWidth)} ${row.file}`);\n }\n log(\"\");\n}\n","import { createServer } from \"node:http\";\nimport { handleRoute } from \"./routes.js\";\n\nexport function startServer(root: string, port: number): void {\n const server = createServer(async (req, res) => {\n // CORS\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type\");\n res.setHeader(\"Content-Type\", \"application/json\");\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(200);\n res.end();\n return;\n }\n\n try {\n const route = await handleRoute(req.url || \"/\", req.method || \"GET\", root);\n res.writeHead(route.status);\n res.end(JSON.stringify(route.body, null, 2));\n } catch {\n res.writeHead(500);\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n });\n\n server.listen(port, () => {\n console.log(`codebase server running on http://localhost:${port}`);\n console.log(`\\nEndpoints:`);\n console.log(` GET /health Health check`);\n console.log(` GET /codebase Full manifest`);\n console.log(` GET /codebase/:category Single category`);\n console.log(` GET /codebase/query?path=stack.languages`);\n console.log(` POST /codebase/scan Trigger re-scan`);\n });\n\n process.on(\"SIGINT\", () => {\n server.close();\n process.exit(0);\n });\n\n process.on(\"SIGTERM\", () => {\n server.close();\n process.exit(0);\n });\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { scan } from \"../scanner/engine.js\";\nimport { queryPath } from \"../utils/json-path.js\";\n\ninterface RouteResult {\n status: number;\n body: unknown;\n}\n\nexport async function handleRoute(url: string, method: string, root: string): Promise<RouteResult> {\n const parsed = new URL(url, \"http://localhost\");\n const path = parsed.pathname;\n\n // Health check\n if (path === \"/health\") {\n return { status: 200, body: { status: \"ok\", version: __VERSION__ } };\n }\n\n // Query endpoint\n if (path === \"/codebase/query\" && method === \"GET\") {\n const queryStr = parsed.searchParams.get(\"path\");\n if (!queryStr) {\n return { status: 400, body: { error: \"Missing 'path' query parameter\" } };\n }\n const manifest = await loadManifest(root);\n if (!manifest) {\n return { status: 404, body: { error: \"No manifest. POST /codebase/scan first.\" } };\n }\n const value = queryPath(manifest, queryStr);\n return { status: 200, body: value ?? null };\n }\n\n // Trigger scan\n if (path === \"/codebase/scan\" && method === \"POST\") {\n const manifest = await scan(root, { quiet: true });\n await writeFile(join(root, \".codebase.json\"), JSON.stringify(manifest, null, 2), \"utf-8\");\n return { status: 200, body: manifest };\n }\n\n // Full manifest\n if (path === \"/codebase\" && method === \"GET\") {\n const manifest = await loadManifest(root);\n if (!manifest) {\n return { status: 404, body: { error: \"No manifest. POST /codebase/scan first.\" } };\n }\n return { status: 200, body: manifest };\n }\n\n // Category endpoint\n if (path.startsWith(\"/codebase/\") && method === \"GET\") {\n const category = path.split(\"/\")[2];\n const manifest = await loadManifest(root);\n if (!manifest) {\n return { status: 404, body: { error: \"No manifest.\" } };\n }\n const data = (manifest as Record<string, unknown>)[category];\n if (data === undefined) {\n return { status: 404, body: { error: `Category '${category}' not found.` } };\n }\n return { status: 200, body: data };\n }\n\n return { status: 404, body: { error: \"Not found\" } };\n}\n\nasync function loadManifest(root: string): Promise<Record<string, unknown> | null> {\n try {\n const content = await readFile(join(root, \".codebase.json\"), \"utf-8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n"],"mappings":"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BACA,mBACA,gBACA,gBAEA,YACA,aACA,WACA,eACA,aAEA,eACA,qBACA,aACA,MAGA,UACA,SACA,QACA,YACA,UACA,UACA,aACA,UACA,WACA,QACA,QACA,SACA,QACA,OACA,OACA,SACA,SACA,QACA,UACA,WACA,QACA,SACA,QACA,aACA,eAGA,YACA,cACA,aACA,gBACA,gBACA,OACA,OACA,SACA,WACA,UACA,WACA,OACA,WACA,QAGA,YACA,OACA,SACA,OACA,QACA,QACA,SACA,OACA,UACA,OACA,SACA,YACA,UAGA,QACA,UACA,QACA,SACA,OACA,eACA,KACA,SACA,QACA,UACA,QACA,UACA,MACA,SAGA,UACA,UACA,OACA,aACA,aACA,eACA,cACA,UACA,UAGA,cACA,mBACA,YACA,UACA,YACA,sBACA,QACA,UACA,SAGA,uBACA,kBACA,aACA,QACA,QACA,MAGA,SACA,aACA,YACF,CAAC,EAEKoB,GAAiB,IAAI,IAAI,CAC7B,SACA,QACA,UACA,YACA,UACA,UACA,aACA,UACA,WACA,SACA,QACA,SACA,QACA,SACA,QACA,eACA,aACA,QACA,eACA,YACA,WACA,QACA,OACF,CAAC,EAEKC,GAAe,IAAI,IAAI,CAC3B,QACA,QACA,OACA,YACA,SACA,OACA,QACA,OACA,SACA,UACA,OACA,UACA,SACA,YACA,UACA,QACA,OACF,CAAC,EAEKC,GAAa,IAAI,IAAI,CACzB,MACA,OACA,QACA,MACA,MACA,OACA,OACA,QACA,QACA,MACA,UACA,OACA,WACA,MACF,CAAC,EAEYC,GAAiC,CAC5C,KAAM,eACN,SAAU,eAEV,MAAM,OAAO3B,EAAkB,CAC7B,IAAM8B,EAAWP,GAAevB,CAAG,EAG7B+B,EAAa,MAAM/B,EAAI,SAAS,cAAc,EACpD,GAAI+B,EACF,GAAI,CACF,IAAMxB,EAAM,KAAK,MAAMwB,CAAU,EAC3B7B,EAAOK,EAAI,cAAgB,CAAC,EAC5BC,EAAUD,EAAI,iBAAmB,CAAC,EAClCE,EAAU,CAAE,GAAGP,EAAM,GAAGM,CAAQ,EAEhCL,EA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","names":["setQuiet","quiet","isQuiet","setVerbose","verbose","isVerbose","log","msg","success","colors","error","warn","info","dim","bold","heading","link","text","url","NO_COLOR","code","command","cmd","init_output","__esmMin","globFilter","files","pattern","regex","globToRegex","f","result","i","char","close","alternatives","escapeRegex","str","init_glob","__esmMin","readdir","fsReadFile","existsSync","join","relative","execFile","createScanContext","root","options","ignoreSet","DEFAULT_IGNORE","files","walkDirectory","fileSet","path","pattern","globFilter","cmd","args","resolve","err","stdout","base","dir","ignore","maxDepth","currentDepth","results","entries","entry","fullPath","relPath","children","init_context","__esmMin","init_glob","detectProjectName","ctx","pkgContent","pkg","cargoContent","match","pyContent","goContent","remote","detectDescription","extractReadmeSummary","readmeNames","readmeContent","name","lines","foundContent","paragraphLines","line","trimmed","projectDetector","init_project","__esmMin","description","readme","getRemoteUrl","ctx","getDefaultBranch","branch","branches","getActiveBranches","output","b","i","arr","detectMonorepo","pkgContent","detectWorkspaceManager","repoDetector","init_repo","__esmMin","url","defaultBranch","isMonorepo","workspaceManager","existsSync","join","buildTree","files","_maxDepth","tree","topLevelFiles","file","parts","topDir","result","sorted","dir","children","arr","KNOWN_ENTRY_POINTS","KNOWN_BUILD_OUTPUTS","structureDetector","init_structure","__esmMin","ctx","entryPoints","ep","buildOutput","d","detectLanguages","ctx","counts","file","ext","lang","LANG_EXTENSIONS","a","b","parsePkgJson","content","pkg","detectFrameworks","deps","frameworks","dep","version","name","FRAMEWORK_MAP","cleanVersion","enhancedFrameworks","detectEnhancedFrameworks","allDeps","details","majorVersion","nuxtVersion","integrations","detectPackageManager","detectFirstFromMap","markers","detectAllFromMap","found","detectPrismaProvider","schema","datasourceBlock","match","provider","detectDatabasesFromFiles","databases","migrationDirs","dir","f","dbType","detectDBFromMigrations","dockerDatabases","detectDBFromDockerCompose","db","ormDatabases","detectDBFromORMConfigs","schemaDatabases","detectDBFromSchemas","files","lower","composeFiles","typeormConfig","sequelizeFiles","mikroOrmConfig","drizzleFiles","schemaFiles","detectPythonFramework","pyproject","requirements","setup","combined","extractVersion","djangoDetails","djangoApps","detectDjangoApps","settingsModule","detectDjangoSettings","apps","settingsFiles","installedAppsMatch","appsContent","appMatches","app","appName","hasSettingsPy","hasSettingsDir","detectGoFramework","gomod","versions","extractGoVersion","detectRustFramework","cargo","extractCargoVersion","detectJavaFramework","pom","buildGradle","buildGradleKts","extractFromXml","extractFromGradle","detectRubyFramework","gemfile","gemspec","extractGemVersion","middlewareStack","detectRailsMiddleware","middleware","detectPhpFramework","composer","detectCSharpFramework","csprojFiles","extractCsprojVersion","packageName","patterns","pattern","artifactId","group","gemName","packageRef","DB_MARKERS","ORM_MARKERS","STYLING_MARKERS","BUILD_TOOL_MARKERS","stackDetector","init_stack","__esmMin","languages","pkgData","packageManager","orm","styling","buildTool","prismaDb","fileBasedDatabases","pyFramework","goFramework","rustFramework","javaFramework","rubyFramework","phpFramework","csharpFramework","detectFromPackageJson","ctx","content","emptyCommands","scripts","pm","result","findScript","extras","name","names","detectFromMakefile","targets","line","match","detectLanguageDefaults","hasPytest","f","hasRuff","hasBlack","hasMypy","hasDjango","hasFastapi","devCmd","buildCmd","hasRails","hasRake","hasLaravel","hasSymfony","hasLanguageFiles","commandsDetector","init_commands","__esmMin","pkgCommands","makeCommands","findNotable","names","notableSet","n","parsePyprojectToml","content","direct","dev","pep621Match","extractQuotedNames","optDepsMatch","arrayMatches","m","poetryDepsMatch","extractTomlKeys","poetryDevMatch","block","matches","name","line","trimmed","match","parseRequirementsTxt","parseCargoToml","depsMatch","devDepsMatch","parseGoMod","blockMatches","parts","singleMatches","detectRubyDeps","ctx","gemfile","deps","notable","NOTABLE_PACKAGES","detectPhpDeps","composer","pkg","devDeps","allDeps","d","detectJavaDeps","pom","gradle","gradleKts","artifactIdRegex","gradleDepsRegex","dep","detectCSharpDeps","csprojFiles","f","file","packageRegex","detectLockFile","NOTABLE_PYTHON","NOTABLE_RUST","NOTABLE_GO","dependenciesDetector","init_dependencies","__esmMin","lockFile","pkgContent","pyprojectContent","result","reqContent","cargoContent","goModContent","shortNames","rubyResult","phpResult","javaResult","csharpResult","detectFeatureFlags","ctx","content","pkg","allDeps","dep","name","FEATURE_FLAG_MARKERS","detectEnvVars","envVars","envExampleContent","parseEnvFile","envContent","envSampleContent","envTemplateContent","isProductionEnv","lines","currentComment","line","trimmed","match","value","isEmpty","KNOWN_CONFIG_FILES","configDetector","init_config","__esmMin","envFiles","f","configFiles","featureFlags","getRecentCommits","ctx","output","getLastCommitters","line","hasUncommittedChanges","gitDetector","init_git","__esmMin","commits","committers","uncommitted","detectTestFramework","ctx","pkgContent","pkg","allDeps","testScript","pyproject","setupCfg","pytestIni","f","pom","build","detectLinter","lintScript","detectFormatter","scripts","fmtScript","detectCI","detectPreCommitHooks","qualityDetector","init_quality","__esmMin","test_framework","linter","formatter","detectArchitecture","ctx","f","detectStateManagement","content","pkg","allDeps","stateLibs","detectApiStyle","styles","detectKeyModules","modules","srcDirs","file","match","dir","description","MODULE_DESCRIPTIONS","topDirs","patternsDetector","init_patterns","__esmMin","detectOpenAPI","ctx","openApiFiles","file","content","spec","extractYAMLField","detectGraphQL","graphqlFiles","f","schemas","resolvers","detectGRPC","protoFiles","services","detectPostmanCollections","postmanFiles","collections","json","field","regex","match","apiDocsDetector","init_api_docs","__esmMin","openApiSpecs","graphqlSchemas","grpcProtos","postmanCollections","detectors","init_detectors","__esmMin","init_project","init_repo","init_structure","init_stack","init_commands","init_dependencies","init_config","init_git","init_quality","init_patterns","init_api_docs","projectDetector","repoDetector","structureDetector","stackDetector","commandsDetector","dependenciesDetector","configDetector","gitDetector","qualityDetector","patternsDetector","apiDocsDetector","safe","s","max","init_safe","__esmMin","execFile","graphqlQuery","cwd","query","variables","resolve","args","key","value","err","stdout","_stderr","response","parseOwnerRepo","remoteUrl","patterns","pattern","match","parseIssueNode","node","labels","assignees","milestone","reactions","comments","timeline","safe","l","parsePRNode","reviewRequests","author","statusCheck","checksStatus","state","mergeable","mergeConflicts","r","fetchGitHubGraphQLData","options","includeIssues","includePRs","includeMilestones","includeReleases","includeProjects","limit","ownerRepo","owner","repo","result","issueData","prData","milestoneData","releaseData","projectData","ISSUES_QUERY","e","warn","PULL_REQUESTS_QUERY","MILESTONES_QUERY","RELEASES_QUERY","PROJECTS_QUERY","m","issues","closed","total","open","i","p","columns","itemsCount","c","checkGraphQLSupport","major","minor","init_graphql","__esmMin","init_output","init_safe","execFile","readdirSync","readFileSync","existsSync","join","syncGitHub","root","ghExec","remoteUrl","shellExec","checkRateLimit","hasGraphQL","checkGraphQLSupport","issues","prs","milestones","releases","projectBoards","graphqlSucceeded","graphqlData","fetchGitHubGraphQLData","fetchIssues","fetchPullRequests","fetchMilestones","decisionPRs","fetchDecisionPRs","kanban","buildKanban","priorities","buildPriorities","adrDecisions","findADRFiles","cwd","args","resolve","err","stdout","cmd","output","parseIssue","raw","labels","assignees","milestone","body","safe","l","parseEffort","match","v","parsePR","reviewRequests","author","MAX_BRANCH_LEN","r","line","m","open","closed","total","pr","extractDecisionSummary","lines","i","adrDirs","adrFiles","dir","fullPath","files","f","entries","file","title","IN_PROGRESS_LABELS","inProgress","NEEDS_VERIFY_LABELS","needsVerify","rankIssues","priorityOrder","best","label","effortOrder","a","b","pa","pb","init_sync","__esmMin","init_graphql","init_safe","readFileSync","statSync","writeFile","rename","execFile","join","getGitSha","root","resolve","err","stdout","loadCache","raw","CACHE_FILE","data","CACHE_VERSION","saveCache","fileCount","manifest","snapshotMtimes","tmpPath","isCacheValid","cache","currentFileCount","currentSha","currentMtimes","file","mtimes","TRACKED_FILES","s","init_cache","__esmMin","scan","root","options","ctx","createScanContext","cache","loadCache","isCacheValid","activeDetectors","detectors","d","results","manifest","warnings","result","msg","warn","ghData","syncGitHub","saveCache","summarizeCategory","category","data","name","desc","url","branch","entries","tree","buildOut","dirs","k","parts","langs","frameworks","buildTool","v","count","devCount","lock","commits","changes","arch","state","issues","prs","init_engine","__esmMin","init_context","init_detectors","init_sync","init_output","init_cache","resolve","join","writeFile","runScan","options","setQuiet","root","log","manifest","scan","category","data","success","capitalize","summarizeCategory","outputPath","content","sizeKB","s","init_scan","__esmMin","init_engine","init_output","readFileSync","writeFileSync","existsSync","join","readManifestSummary","root","raw","m","buildDynamicBlockMd","summary","INJECT_BLOCK_MD","stackParts","stack","cmdLines","v","k","cmdTable","START_MARKER","END_MARKER","fileExistsAt","file","injectMarkdown","path","content","startIdx","endIdx","removeMarkdown","HASH_START_MARKER","HASH_END_MARKER","INJECT_BLOCK_PLAIN","init_shared","__esmMin","claude_exports","__export","claudeIntegration","init_claude","__esmMin","init_shared","root","fileExistsAt","injectMarkdown","err","removeMarkdown","readFileSync","writeFileSync","existsSync","join","updateGitignore","root","path","content","needsManifest","MANIFEST_ENTRY","needsCache","CACHE_ENTRY","addition","init_gitignore","__esmMin","readFileSync","writeFileSync","existsSync","mkdirSync","chmodSync","unlinkSync","join","installHooks","root","ghSync","hookCmd","installSingleHook","installPreCommitHook","hooksDir","hookPath","pkgPath","hasCheck","hasTypecheck","hasLint","pkg","checkCmd","parts","script","PRE_COMMIT_MARKER","existing","hookName","command","content","HOOK_MARKER","updated","init_githook","__esmMin","setup_exports","__export","installClaudeCommandsForFix","installClaudeHooksForFix","installClaudeSkillsForFix","runSetup","resolve","dirname","join","writeFileSync","existsSync","mkdirSync","readFileSync","chmodSync","readdirSync","copyFileSync","execFile","options","root","runScan","heading","claudeIntegration","success","installHooks","installBranchHook","info","installClaudeHooks","installAgentBrowser","checkClaude","installClaudeCommands","warn","installClaudeSkills","updateGitignore","appendToGitignore","vibedir","checkGh","installLabels","ensureHighlightsIndex","docsDir","productPath","generateProductMd","log","commandsSource","files","f","destinations","totalInstalled","totalUpdated","dir","label","installed","updated","skipped","file","src","dest","srcContent","destContent","parts","skillsSource","srcBuf","destBuf","names","hooksDir","guardPath","postPath","settingsPath","settings","hooks","guardCmd","postCmd","preHooks","postHooks","hookPath","marker","script","existing","lines","p","toAdd","l","execGh","args","err","stdout","created","VIBEKIT_LABELS","ok","body","outputPath","manifestPath","manifest","name","description","langs","frameworks","devCmd","buildCmd","testCmd","init_setup","__esmMin","init_scan","init_claude","init_gitignore","init_githook","init_output","init_output","HELP","printMainHelp","bold","command","code","link","printCommandHelp","commandName","help","ex","dim","opt","c","ERROR_SUGGESTIONS","DEFAULTS","COMMANDS","parseArgs","argv","opts","positionals","i","arg","printMainHelp","key","next","s","sub","showCommandHelp","commandName","printCommandHelp","init_output","get","readFileSync","writeFileSync","mkdirSync","homedir","join","execSync","spawnSync","CACHE_DIR","CACHE_FILE","CACHE_TTL_MS","NPM_PACKAGE","NO_COLOR","c","getCurrentVersion","isNewer","latest","current","parse","v","lMaj","lMin","lPatch","cMaj","cMin","cPatch","readCache","writeCache","version","fetchLatestVersion","resolve","reject","req","res","data","chunk","detectInstallCommand","npmGlobal","pnpmGlobal","runUpgrade","cmd","bin","args","readKey","stdin","wasTTY","onData","key","checkForUpdate","cache","installCmd","accepted","ok","init_scan","init_setup","init_engine","resolve","join","existsSync","writeFileSync","readFileSync","execFile","writeFile","rename","homedir","init_claude","integrations","claudeIntegration","detectTools","root","i","init_claude","init_gitignore","init_githook","init_output","isAlreadyInitialized","root","existsSync","join","claudeMd","content","readFileSync","hasHtmlMarkers","hasHashMarkers","runInit","options","_start","setQuiet","resolve","heading","ghAvailable","checkGhDetailed","log","manifest","scan","outputPath","writeFile","sizeKB","success","info","ghStatus","warn","category","data","capitalize","summarizeCategory","tools","detectTools","globalTools","detectGlobalTools","toolNames","t","gt","writeFileSync","claudeIntegration","tool","result","mcpConfigured","autoConfigureMcp","installHooks","updateGitignore","issueCount","i","prCount","pr","langs","l","elapsed","s","execFile","err","authErr","stdout","stderr","output","home","homedir","found","detectedTools","configured","mcpEntry","projectMcpPath","configureMcpFile","filePath","serverName","entry","config","servers","tmpPath","rename","resolve","join","readFile","existsSync","generateBrief","m","sections","projectName","projectParts","techParts","cmds","v","name","cmd","dir","desc","statusParts","inProgress","i","assignee","files","nextTask","labels","snippet","backlog","blocked","l","openPRs","pr","reviewers","ms","due","allDecisions","d","c","init_output","runBrief","options","root","resolve","manifestPath","join","existsSync","manifest","content","readFile","error","warn","filteredManifest","filterManifest","output","generateOutput","categories","result","categoryMap","cat","key","format","generateBrief","init_output","init_sync","resolve","join","readFile","existsSync","priorityReason","labels","label","l","runNext","options","root","manifest","content","error","status","info","inProgress","log","bold","i","assignee","priorities","allOpen","rankIssues","next","effortLabel","needsVerify","blocked","resolve","join","readFile","existsSync","queryPath","obj","path","parts","current","part","init_output","runQuery","options","root","resolve","manifestPath","join","existsSync","manifest","content","readFile","error","path","value","queryPath","resolve","init_output","execFile","ghExec","cwd","args","resolve","reject","err","stdout","stderr","createIssue","root","title","body","labels","issueBody","url","number","success","e","error","closeIssue","reason","json","log","listIssues","filter","output","commentIssue","mapIssueToFiles","issueNumber","files","f","init_output","runIssue","options","root","resolve","title","error","createIssue","number","closeIssue","body","commentIssue","filter","listIssues","files","mapIssueToFiles","init_sync","init_output","resolve","join","readFile","writeFile","rename","existsSync","runStatus","options","root","manifest","info","ghData","syncGitHub","error","manifestPath","updated","tmpPath","status","view","printKanban","printPriorities","printMilestones","printDecisions","dim","heading","kanban","log","bold","i","assignee","needsVerify","labels","roadmap","ms","bar","progressBar","due","decisions","all","d","a","b","percent","filled","empty","resolve","createInterface","readFile","writeFile","rename","existsSync","readdirSync","join","resolve","homedir","execFile","init_engine","init_sync","TOOL_DEFINITIONS","startMcpServer","root","rl","createInterface","line","request","writeResponse","response","handleRequest","req","respond","handleToolCall","params","toolName","args","manifest","loadOrScanManifest","brief","generateBrief","category","fields","data","sparse","f","path","value","queryPath","result","getNextTask","getBlockers","ghCreateIssue","invalidateManifest","ghCloseIssue","ghUpdateIssue","projectCommandsDir","join","globalCommandsDir","homedir","seenNames","allFiles","dir","existsSync","readdirSync","names","globalSkillsDir","projectSkillsDir","seenFiles","skillFiles","skills","file","resolveSkill","filePath","execFile","err","stdout","match","frontmatter","nameMatch","descMatch","name","description","planPath","resolve","planContent","readFile","message","entry","existing","tmpPath","writeFile","rename","number","raw","ghExecArgs","issue","pr","syncGh","scan","manifestPath","ghData","syncGitHub","content","merged","_rawTtlHours","MANIFEST_TTL_MS","withSync","allOpen","i","priorities","rankIssues","top","queue","summaryParts","effortLabel","needsVerify","blocked","waitingReview","failingChecks","withConflicts","uncommittedChanges","hasBlockers","cwd","reject","stderr","title","body","labels","ghArgs","safeLabels","l","comment","addLabels","removeLabels","assignee","updates","assignees","a","id","runMcp","options","root","resolve","startMcpServer","resolve","join","homedir","existsSync","readFileSync","statSync","readdirSync","init_output","HOOK_MARKER","runDoctor","options","_start","setQuiet","root","resolve","results","heading","manifestPath","join","manifest","existsSync","raw","readFileSync","stat","statSync","sizeKB","ageMs","age","formatAge","generatedAt","ageHours","stale","expectedCategories","presentCategories","c","missing","warnings","w","ghStatus","checkGhDetailed","ghAvailable","repoUrl","githubAvailable","hasGithubRemote","claudeInjected","checkInjection","mcpOk","checkMcpConfig","postCommitOk","checkHook","postCheckoutOk","hookHasSync","checkHookSync","syncDetail","checkCommitMsgHook","preCommitOk","checkPreCommitHook","pkg","claudeCommandsDir","cmdFiles","readdirSync","f","skillsDir","homedir","skillFiles","names","guardHook","postHook","settingsFile","hooksInstalled","settingsOk","s","pre","post","gitignorePath","NO_COLOR","green","red","reset","LABEL_WIDTH","sectionFor","label","lastSection","r","section","log","dim","icon","issues","total","passing","bold","elapsed","success","filePath","mcpPath","hookName","hookPath","ms","seconds","minutes","hours","days","init_engine","resolve","join","homedir","existsSync","readFileSync","readdirSync","writeFile","init_githook","init_gitignore","init_output","HOOK_MARKER","NO_COLOR","green","reset","fixed","msg","runFix","options","_start","setQuiet","root","resolve","fixCount","heading","ghStatus","checkGhDetailed","ghAvailable","info","manifestPath","join","needsScan","existsSync","raw","readFileSync","manifest","generatedAt","statSync","scan","content","writeFile","sizeKB","claudeIntegration","checkInjection","mcpConfigured","autoConfigureMcp","entry","postCommitOk","checkHook","postCheckoutOk","hookHasSync","checkHookSync","preCommitOk","checkPreCommitHook","installHooks","fixes","gitignorePath","updateGitignore","claudeCommandsDir","installClaudeCommandsForFix","skillsDir","homedir","readdirSync","f","installClaudeSkillsForFix","guardHook","postHook","settingsFile","hooksOk","settingsOk","s","pre","post","installClaudeHooksForFix","log","elapsed","success","filePath","hookName","hookPath","init_output","resolve","join","execFile","existsSync","readFileSync","writeFileSync","runRelease","options","root","dryRun","versionOverride","heading","checkGhAuth","error","execGitStr","log","manifestPath","openBugs","i","l","b","critical","high","countIssues","success","testCmd","detectTestCmd","testResult","runTestSuite","warn","wcScore","getWorldClassScore","carry","dirty","version","nextVersion","notes","buildReleaseNotes","gitRun","releaseOk","releaseUrl","ghRun","rotateMilestone","args","err","stdout","reject","_stdout","stderr","labels","pkg","cmd","bin","match","latest","m","carryCount","date","arch","bugs","openCarry","openArch","envPath","content","numMatch","titleMatch","repo","info","nextTitle","newMs","init_output","resolve","join","readFile","writeFile","existsSync","PLAN_FILENAME","runPlan","options","root","planPath","appendPlanUpdate","info","log","content","heading","message","entry","initial","bold","init_output","join","resolve","existsSync","readdirSync","execFile","extractSkillMd","skillPath","reject","err","stdout","parseYamlFrontmatter","content","match","result","line","colon","key","value","runSkills","options","globalSkillsDir","projectSkillsDir","seenFiles","entries","dir","f","log","rows","file","name","description","fm","nameWidth","r","descWidth","fileWidth","pad","s","w","sep","info","row","createServer","init_engine","readFile","writeFile","join","handleRoute","url","method","root","parsed","path","queryStr","manifest","loadManifest","queryPath","scan","writeFile","join","category","data","content","readFile","startServer","root","port","server","createServer","req","res","route","handleRoute","options","parseArgs","setQuiet","setVerbose","showCommandHelp","commands","runScan","runInit","runBrief","runNext","runSetup","runQuery","runIssue","runStatus","runMcp","runDoctor","runFix","runRelease","runPlan","runSkills","opts","startServer","checkForUpdate","major","handler","error","info","bold","err","msg"]}