@better-vibe/branch-narrator 1.0.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map DELETED
@@ -1,101 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/core/errors.ts", "../src/core/version.ts", "../src/core/analyzer-runner.ts", "../src/core/change-set.ts", "../src/git/collector.ts", "../src/core/filters.ts", "../src/analyzers/file-summary.ts", "../src/analyzers/file-category.ts", "../src/git/parser.ts", "../src/core/evidence.ts", "../src/analyzers/route-detector.ts", "../src/analyzers/supabase.ts", "../src/analyzers/env-var.ts", "../src/analyzers/cloudflare.ts", "../src/analyzers/vitest.ts", "../src/analyzers/dependencies.ts", "../src/analyzers/security-files.ts", "../src/git/batch.ts", "../src/analyzers/reactRouterRoutes.ts", "../src/analyzers/test-parity.ts", "../src/analyzers/impact.ts", "../src/analyzers/large-diff.ts", "../src/analyzers/lockfiles.ts", "../src/analyzers/test-gaps.ts", "../src/analyzers/sql-risks.ts", "../src/analyzers/ci-workflows.ts", "../src/analyzers/infra.ts", "../src/analyzers/api-contracts.ts", "../src/analyzers/stencil.ts", "../src/analyzers/next-routes.ts", "../src/analyzers/graphql.ts", "../src/analyzers/typescript-config.ts", "../src/analyzers/tailwind.ts", "../src/analyzers/monorepo.ts", "../src/analyzers/package-exports.ts", "../src/analyzers/vue-routes.ts", "../src/analyzers/astro-routes.ts", "../src/analyzers/index.ts", "../src/profiles/default.ts", "../src/profiles/sveltekit.ts", "../src/profiles/react.ts", "../src/profiles/stencil.ts", "../src/profiles/next.ts", "../src/profiles/vue.ts", "../src/profiles/astro.ts", "../src/profiles/library.ts", "../src/profiles/index.ts", "../src/render/risk-score.ts", "../src/commands/facts/categories.ts", "../src/commands/facts/actions.ts", "../src/commands/facts/highlights.ts", "../src/core/sorting.ts", "../src/core/ids.ts", "../src/commands/facts/builder.ts", "../src/core/delta.ts", "../src/commands/facts/delta.ts", "../src/commands/facts/index.ts", "../src/render/sarif.ts", "../src/commands/risk/exclusions.ts", "../src/commands/risk/redaction.ts", "../src/commands/risk/scoring.ts", "../src/commands/risk/findings-to-flags.ts", "../src/commands/risk/renderers.ts", "../src/commands/risk/delta.ts", "../src/commands/risk/index.ts", "../src/commands/zoom/index.ts", "../src/commands/zoom/renderers.ts", "../src/commands/integrate/shared.ts", "../src/commands/integrate/fs.ts", "../src/commands/integrate/providers/claude.ts", "../src/commands/integrate/providers/cursor.ts", "../src/commands/integrate/providers/jules-rules.ts", "../src/commands/integrate/providers/jules.ts", "../src/commands/integrate/providers/opencode.ts", "../src/commands/integrate/commands/legacy_stub.ts", "../src/commands/integrate.ts", "../src/commands/snap/storage.ts", "../src/commands/snap/git-ops.ts", "../src/commands/snap/save.ts", "../src/commands/snap/list.ts", "../src/commands/snap/show.ts", "../src/commands/snap/diff.ts", "../src/commands/snap/restore.ts", "../src/commands/snap/index.ts", "../src/cli.ts", "../src/commands/dump-diff/index.ts", "../src/core/logger.ts", "../src/commands/dump-diff/core.ts", "../src/commands/dump-diff/git.ts", "../src/render/markdown.ts", "../src/render/json.ts", "../src/render/terminal.ts"],
4
- "sourcesContent": [
5
- "/**\n * Custom error classes for branch-narrator.\n */\n\nexport class BranchNarratorError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number = 1\n ) {\n super(message);\n this.name = \"BranchNarratorError\";\n }\n}\n\nexport class NotAGitRepoError extends BranchNarratorError {\n constructor(path: string = process.cwd()) {\n super(\n `Not a git repository: ${path}\\n` +\n \"Please run this command from within a git repository.\",\n 1\n );\n this.name = \"NotAGitRepoError\";\n }\n}\n\nexport class InvalidRefError extends BranchNarratorError {\n constructor(ref: string) {\n super(\n `Invalid git reference: ${ref}\\n` +\n \"Please ensure the branch or commit exists.\",\n 1\n );\n this.name = \"InvalidRefError\";\n }\n}\n\nexport class NoDiffError extends BranchNarratorError {\n constructor(base: string, head: string) {\n super(\n `No differences found between ${base} and ${head}.\\n` +\n \"The branches may be identical or one may not exist.\",\n 1\n );\n this.name = \"NoDiffError\";\n }\n}\n\nexport class GitCommandError extends BranchNarratorError {\n constructor(\n command: string,\n public readonly stderr: string\n ) {\n super(`Git command failed: ${command}\\n${stderr}`, 1);\n this.name = \"GitCommandError\";\n }\n}\n\n",
6
- "/**\n * Version information for the CLI.\n *\n * This is read from package.json at runtime to ensure consistency.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nlet cachedVersion: string | null = null;\n\n/**\n * Try to read and parse package.json from a given path.\n */\nasync function tryReadPackageJson(path: string): Promise<string | null> {\n try {\n const content = await readFile(path, \"utf-8\");\n const pkg = JSON.parse(content);\n return pkg.version || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the current version from package.json.\n * Result is cached for subsequent calls.\n *\n * Tries multiple paths to handle different execution contexts:\n * 1. Bundled CLI in dist/ -> ../package.json\n * 2. Unbundled source in src/core/ -> ../../package.json\n * 3. npm installed package -> package.json relative to dist/\n */\nexport async function getVersion(): Promise<string> {\n if (cachedVersion) {\n return cachedVersion;\n }\n\n // Try different paths to find package.json\n const possiblePaths = [\n // Bundled: dist/cli.js -> package.json is at ../package.json\n join(__dirname, \"..\", \"package.json\"),\n // Unbundled: src/core/version.ts -> package.json is at ../../package.json\n join(__dirname, \"..\", \"..\", \"package.json\"),\n // npm install: node_modules/@better-vibe/branch-narrator/dist/ -> ../package.json\n join(__dirname, \"package.json\"),\n ];\n\n for (const path of possiblePaths) {\n const version = await tryReadPackageJson(path);\n if (version) {\n cachedVersion = version;\n return version;\n }\n }\n\n // Fallback if we can't find package.json\n return \"unknown\";\n}\n\n/**\n * Get version synchronously (returns cached value or \"unknown\").\n * Use getVersion() for the first call to ensure version is loaded.\n */\nexport function getVersionSync(): string {\n return cachedVersion ?? \"unknown\";\n}\n",
7
- "/**\n * Utility for running analyzers efficiently.\n *\n * Analyzers are pure functions that operate on the same ChangeSet independently,\n * making them ideal candidates for parallel execution.\n */\n\nimport type { Analyzer, ChangeSet, Finding } from \"./types.js\";\n\n/**\n * Run all analyzers in parallel and collect findings.\n *\n * Since analyzers are independent pure functions operating on the same ChangeSet,\n * they can safely run concurrently for better performance.\n *\n * @param analyzers - Array of analyzers to run\n * @param changeSet - The change set to analyze\n * @returns Promise resolving to flattened array of all findings\n */\nexport async function runAnalyzersInParallel(\n analyzers: Analyzer[],\n changeSet: ChangeSet\n): Promise<Finding[]> {\n // Run all analyzers concurrently\n const findingsArrays = await Promise.all(\n analyzers.map(analyzer => analyzer.analyze(changeSet))\n );\n\n // Flatten results into single array\n return findingsArrays.flat();\n}\n",
8
- "/**\n * ChangeSet builder utilities.\n */\n\nimport type {\n ChangeSet,\n FileChange,\n FileDiff,\n FileStatus,\n Hunk,\n} from \"./types.js\";\n\n/**\n * Parse git diff --name-status output into FileChange array.\n */\nexport function parseNameStatus(output: string): FileChange[] {\n const lines = output.trim().split(\"\\n\").filter(Boolean);\n const changes: FileChange[] = [];\n\n for (const line of lines) {\n const parts = line.split(\"\\t\");\n const statusCode = parts[0];\n\n if (statusCode.startsWith(\"R\")) {\n // Rename: R100\\told\\tnew\n changes.push({\n path: parts[2],\n status: \"renamed\",\n oldPath: parts[1],\n });\n } else if (statusCode === \"A\") {\n changes.push({ path: parts[1], status: \"added\" });\n } else if (statusCode === \"M\") {\n changes.push({ path: parts[1], status: \"modified\" });\n } else if (statusCode === \"D\") {\n changes.push({ path: parts[1], status: \"deleted\" });\n }\n }\n\n return changes;\n}\n\n/**\n * Convert parse-diff File to our FileDiff structure.\n */\nexport function convertParsedDiff(\n parsed: ParseDiffFile[],\n fileChanges: FileChange[]\n): FileDiff[] {\n const statusMap = new Map<string, FileStatus>();\n const oldPathMap = new Map<string, string>();\n\n for (const fc of fileChanges) {\n statusMap.set(fc.path, fc.status);\n if (fc.oldPath) {\n oldPathMap.set(fc.path, fc.oldPath);\n statusMap.set(fc.oldPath, fc.status);\n }\n }\n\n return parsed.map((file) => {\n const path = file.to === \"/dev/null\" ? file.from! : file.to!;\n const normalizedPath = path.replace(/^[ab]\\//, \"\");\n const status = statusMap.get(normalizedPath) ?? \"modified\";\n\n const hunks: Hunk[] = (file.chunks || []).map((chunk) => {\n const additions: string[] = [];\n const deletions: string[] = [];\n\n for (const change of chunk.changes || []) {\n if (change.type === \"add\") {\n additions.push(change.content.slice(1)); // Remove leading +\n } else if (change.type === \"del\") {\n deletions.push(change.content.slice(1)); // Remove leading -\n }\n }\n\n return {\n oldStart: chunk.oldStart,\n oldLines: chunk.oldLines,\n newStart: chunk.newStart,\n newLines: chunk.newLines,\n content: chunk.content,\n additions,\n deletions,\n };\n });\n\n return {\n path: normalizedPath,\n status,\n oldPath: oldPathMap.get(normalizedPath),\n hunks,\n };\n });\n}\n\n/**\n * Build a ChangeSet from raw git outputs.\n */\nexport function buildChangeSet(params: {\n base: string;\n head: string;\n nameStatusOutput: string;\n parsedDiffs: ParseDiffFile[];\n basePackageJson?: Record<string, unknown>;\n headPackageJson?: Record<string, unknown>;\n}): ChangeSet {\n const files = parseNameStatus(params.nameStatusOutput);\n const diffs = convertParsedDiff(params.parsedDiffs, files);\n\n return {\n base: params.base,\n head: params.head,\n files,\n diffs,\n basePackageJson: params.basePackageJson,\n headPackageJson: params.headPackageJson,\n };\n}\n\n// ============================================================================\n// Type definitions for parse-diff (simplified)\n// ============================================================================\n\nexport interface ParseDiffChange {\n type: \"add\" | \"del\" | \"normal\";\n content: string;\n ln?: number;\n ln1?: number;\n ln2?: number;\n}\n\nexport interface ParseDiffChunk {\n content: string;\n oldStart: number;\n oldLines: number;\n newStart: number;\n newLines: number;\n changes: ParseDiffChange[];\n}\n\nexport interface ParseDiffFile {\n from?: string;\n to?: string;\n chunks: ParseDiffChunk[];\n deletions: number;\n additions: number;\n}\n\n// ============================================================================\n// Test Helpers\n// ============================================================================\n\n/**\n * Create a minimal ChangeSet for testing purposes.\n */\nexport function createTestChangeSet(\n overrides: Partial<ChangeSet> = {}\n): ChangeSet {\n return {\n base: \"main\",\n head: \"HEAD\",\n files: [],\n diffs: [],\n ...overrides,\n };\n}\n\n/**\n * Create a FileDiff with additions for testing.\n */\nexport function createTestFileDiff(\n path: string,\n additions: string[],\n status: FileStatus = \"modified\"\n): FileDiff {\n return {\n path,\n status,\n hunks: [\n {\n oldStart: 1,\n oldLines: 0,\n newStart: 1,\n newLines: additions.length,\n content: \"@@ -0,0 +1 @@\",\n additions,\n deletions: [],\n },\n ],\n };\n}\n\n",
9
- "/**\n * Git command execution and data collection.\n */\n\nimport { execa } from \"execa\";\nimport parseDiff from \"parse-diff\";\nimport {\n buildChangeSet,\n type ParseDiffFile,\n} from \"../core/change-set.js\";\nimport {\n GitCommandError,\n InvalidRefError,\n NotAGitRepoError,\n} from \"../core/errors.js\";\nimport type { ChangeSet, DiffMode } from \"../core/types.js\";\n\n/**\n * Check if the current directory is inside a git repository.\n */\nexport async function isGitRepo(cwd: string = process.cwd()): Promise<boolean> {\n try {\n const result = await execa(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n cwd,\n reject: false,\n });\n return result.exitCode === 0 && result.stdout.trim() === \"true\";\n } catch {\n return false;\n }\n}\n\n/**\n * Detect the default branch of the remote origin.\n * Falls back to \"main\" if detection fails.\n */\nexport async function getDefaultBranch(cwd: string = process.cwd()): Promise<string> {\n try {\n // Try to get the symbolic ref for origin/HEAD\n const result = await execa(\"git\", [\"symbolic-ref\", \"refs/remotes/origin/HEAD\"], {\n cwd,\n reject: false,\n });\n\n if (result.exitCode === 0) {\n // Output is like \"refs/remotes/origin/main\"\n // Split by slash and get the last part\n const parts = result.stdout.trim().split(\"/\");\n if (parts.length > 0) {\n return parts[parts.length - 1];\n }\n }\n } catch {\n // Ignore errors\n }\n\n return \"main\";\n}\n\n/**\n * Validate that a git reference exists.\n */\nexport async function refExists(\n ref: string,\n cwd: string = process.cwd()\n): Promise<boolean> {\n try {\n const result = await execa(\"git\", [\"rev-parse\", \"--verify\", ref], {\n cwd,\n reject: false,\n });\n return result.exitCode === 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Build git diff --name-status arguments based on mode.\n */\nfunction buildNameStatusArgs(options: {\n mode: DiffMode;\n base?: string;\n head?: string;\n}): string[] {\n const args = [\"diff\", \"--name-status\", \"--find-renames\"];\n\n switch (options.mode) {\n case \"branch\":\n args.push(`${options.base}..${options.head}`);\n break;\n case \"unstaged\":\n // Working tree vs index (no additional args)\n break;\n case \"staged\":\n args.push(\"--staged\");\n break;\n case \"all\":\n args.push(\"HEAD\");\n break;\n }\n\n return args;\n}\n\n/**\n * Build git diff arguments based on mode.\n */\nfunction buildUnifiedDiffArgs(options: {\n mode: DiffMode;\n base?: string;\n head?: string;\n}): string[] {\n const args = [\"diff\", \"--unified=3\"];\n\n switch (options.mode) {\n case \"branch\":\n args.push(`${options.base}..${options.head}`);\n break;\n case \"unstaged\":\n // Working tree vs index (no additional args)\n break;\n case \"staged\":\n args.push(\"--staged\");\n break;\n case \"all\":\n args.push(\"HEAD\");\n break;\n }\n\n return args;\n}\n\n/**\n * Get git diff --name-status output based on mode.\n */\nexport async function getNameStatusByMode(\n options: {\n mode: DiffMode;\n base?: string;\n head?: string;\n },\n cwd: string = process.cwd()\n): Promise<string> {\n const args = buildNameStatusArgs(options);\n\n try {\n const result = await execa(\"git\", args, { cwd });\n return result.stdout;\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\n `git ${args.join(\" \")}`,\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\n/**\n * Get unified diff output based on mode.\n */\nexport async function getUnifiedDiffByMode(\n options: {\n mode: DiffMode;\n base?: string;\n head?: string;\n },\n cwd: string = process.cwd()\n): Promise<string> {\n const args = buildUnifiedDiffArgs(options);\n\n try {\n const result = await execa(\"git\", args, { cwd });\n return result.stdout;\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\n `git ${args.join(\" \")}`,\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\n/**\n * Get git diff --name-status output.\n * If head is null, compares working directory against base.\n * @deprecated Use getNameStatusByMode instead\n */\nexport async function getNameStatus(\n base: string,\n head: string | null,\n cwd: string = process.cwd()\n): Promise<string> {\n try {\n const args = head\n ? [\"diff\", \"--name-status\", \"--find-renames\", `${base}..${head}`]\n : [\"diff\", \"--name-status\", \"--find-renames\", base];\n const result = await execa(\"git\", args, { cwd });\n return result.stdout;\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n const ref = head ? `${base}..${head}` : base;\n throw new GitCommandError(\n `git diff --name-status ${ref}`,\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\n/**\n * Get unified diff output.\n * If head is null, compares working directory against base.\n * @deprecated Use getUnifiedDiffByMode instead\n */\nexport async function getUnifiedDiff(\n base: string,\n head: string | null,\n cwd: string = process.cwd()\n): Promise<string> {\n try {\n const args = head\n ? [\"diff\", \"--unified=3\", `${base}..${head}`]\n : [\"diff\", \"--unified=3\", base];\n const result = await execa(\"git\", args, { cwd });\n return result.stdout;\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n const ref = head ? `${base}..${head}` : base;\n throw new GitCommandError(\n `git diff ${ref}`,\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\n/**\n * Get file content at a specific ref.\n */\nexport async function getFileAtRef(\n ref: string,\n filePath: string,\n cwd: string = process.cwd()\n): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"show\", `${ref}:${filePath}`], {\n cwd,\n reject: false,\n });\n if (result.exitCode === 0) {\n return result.stdout;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse package.json content safely.\n */\nfunction parsePackageJson(content: string | null): Record<string, unknown> | undefined {\n if (!content) return undefined;\n try {\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Get untracked files (new files not yet added to git).\n */\nexport async function getUntrackedFiles(\n cwd: string = process.cwd()\n): Promise<string[]> {\n try {\n const result = await execa(\n \"git\",\n [\"ls-files\", \"--others\", \"--exclude-standard\"],\n { cwd }\n );\n return result.stdout.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Read file content from working directory.\n */\nasync function readWorkingFile(\n filePath: string,\n cwd: string\n): Promise<string | null> {\n try {\n const { readFile } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n return await readFile(join(cwd, filePath), \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * Create synthetic diff entries for untracked files.\n */\nasync function createUntrackedDiffs(\n untrackedFiles: string[],\n cwd: string\n): Promise<{ nameStatus: string; diffs: ParseDiffFile[] }> {\n const nameStatusLines: string[] = [];\n const diffs: ParseDiffFile[] = [];\n\n for (const file of untrackedFiles) {\n // Skip binary files and very large files\n if (isBinaryFile(file)) {\n nameStatusLines.push(`A\\t${file}`);\n continue;\n }\n\n const content = await readWorkingFile(file, cwd);\n if (content === null) continue;\n\n nameStatusLines.push(`A\\t${file}`);\n\n // Create a synthetic diff for the file\n const lines = content.split(\"\\n\");\n const changes = lines.map((line, idx) => ({\n type: \"add\" as const,\n content: \"+\" + line,\n ln: idx + 1,\n }));\n\n diffs.push({\n from: \"/dev/null\",\n to: file,\n chunks: [\n {\n content: `@@ -0,0 +1,${lines.length} @@`,\n oldStart: 0,\n oldLines: 0,\n newStart: 1,\n newLines: lines.length,\n changes,\n },\n ],\n deletions: 0,\n additions: lines.length,\n });\n }\n\n return {\n nameStatus: nameStatusLines.join(\"\\n\"),\n diffs,\n };\n}\n\n/**\n * Set of binary file extensions for O(1) lookup.\n * Pre-compiled at module load time for maximum performance.\n */\nconst BINARY_EXTENSIONS = new Set([\n \".png\", \".jpg\", \".jpeg\", \".gif\", \".webp\", \".ico\", \".svg\",\n \".woff\", \".woff2\", \".ttf\", \".eot\", \".otf\",\n \".zip\", \".tar\", \".gz\", \".tgz\", \".rar\",\n \".pdf\", \".doc\", \".docx\", \".xls\", \".xlsx\",\n \".exe\", \".dll\", \".so\", \".dylib\",\n \".mp3\", \".mp4\", \".wav\", \".avi\", \".mov\",\n \".lockb\", // bun.lockb is binary\n]);\n\n/**\n * Check if a file is likely binary based on extension.\n * Uses Set lookup for O(1) performance.\n */\nfunction isBinaryFile(path: string): boolean {\n const lowerPath = path.toLowerCase();\n // Find the last dot to extract extension\n const lastDot = lowerPath.lastIndexOf(\".\");\n if (lastDot === -1) return false;\n const ext = lowerPath.slice(lastDot);\n return BINARY_EXTENSIONS.has(ext);\n}\n\n/**\n * Get current package.json from working directory.\n */\nasync function getWorkingPackageJson(\n cwd: string\n): Promise<Record<string, unknown> | undefined> {\n try {\n const { readFile } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n const content = await readFile(join(cwd, \"package.json\"), \"utf-8\");\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n}\n\n/**\n * @deprecated Use CollectChangeSetOptionsV2 with mode instead\n */\nexport interface CollectChangeSetOptions {\n base: string;\n head: string;\n cwd?: string;\n uncommitted?: boolean;\n}\n\nexport interface CollectChangeSetOptionsV2 {\n mode: DiffMode;\n base?: string;\n head?: string;\n cwd?: string;\n includeUntracked?: boolean;\n}\n\n/**\n * Collect all git diff data and build a ChangeSet.\n * Supports both legacy options (base/head/uncommitted) and new mode-based options.\n */\nexport async function collectChangeSet(\n baseOrOptions: string | CollectChangeSetOptions | CollectChangeSetOptionsV2,\n head?: string,\n cwd: string = process.cwd()\n): Promise<ChangeSet> {\n // Handle v2 options with mode\n if (typeof baseOrOptions === \"object\" && \"mode\" in baseOrOptions) {\n return collectChangeSetByMode(baseOrOptions);\n }\n\n // Handle both old signature and legacy options object\n let options: CollectChangeSetOptions;\n if (typeof baseOrOptions === \"string\") {\n options = { base: baseOrOptions, head: head!, cwd };\n } else {\n options = baseOrOptions;\n cwd = options.cwd ?? process.cwd();\n }\n\n const { base, uncommitted } = options;\n const headRef = uncommitted ? null : options.head;\n\n // Validate git repo\n if (!(await isGitRepo(cwd))) {\n throw new NotAGitRepoError(cwd);\n }\n\n // Validate refs\n if (!(await refExists(base, cwd))) {\n throw new InvalidRefError(base);\n }\n if (headRef && !(await refExists(headRef, cwd))) {\n throw new InvalidRefError(headRef);\n }\n\n // Collect data for tracked files\n const [nameStatusOutput, unifiedDiff, basePackageContent] = await Promise.all([\n getNameStatus(base, headRef, cwd),\n getUnifiedDiff(base, headRef, cwd),\n getFileAtRef(base, \"package.json\", cwd),\n ]);\n\n // Parse unified diff for tracked files\n let parsedDiffs = parseDiff(unifiedDiff) as ParseDiffFile[];\n let finalNameStatus = nameStatusOutput;\n\n // If uncommitted mode, also include untracked files\n if (uncommitted) {\n const untrackedFiles = await getUntrackedFiles(cwd);\n if (untrackedFiles.length > 0) {\n const untrackedData = await createUntrackedDiffs(untrackedFiles, cwd);\n\n // Merge untracked files into results\n if (untrackedData.nameStatus) {\n finalNameStatus = finalNameStatus\n ? `${finalNameStatus}\\n${untrackedData.nameStatus}`\n : untrackedData.nameStatus;\n }\n parsedDiffs = [...parsedDiffs, ...untrackedData.diffs];\n }\n }\n\n // Get head package.json (from ref or working directory)\n const headPackageContent = uncommitted\n ? await getWorkingPackageJson(cwd)\n : parsePackageJson(await getFileAtRef(headRef!, \"package.json\", cwd));\n\n // Build ChangeSet\n return buildChangeSet({\n base,\n head: uncommitted ? \"WORKING\" : options.head,\n nameStatusOutput: finalNameStatus,\n parsedDiffs,\n basePackageJson: parsePackageJson(basePackageContent),\n headPackageJson: uncommitted ? headPackageContent : parsePackageJson(\n await getFileAtRef(options.head, \"package.json\", cwd)\n ),\n });\n}\n\n/**\n * Collect all git diff data and build a ChangeSet using mode-based options.\n */\nasync function collectChangeSetByMode(\n options: CollectChangeSetOptionsV2\n): Promise<ChangeSet> {\n const cwd = options.cwd ?? process.cwd();\n const includeUntracked = options.includeUntracked ?? (options.mode === \"all\" || options.mode === \"unstaged\");\n\n // Validate git repo\n if (!(await isGitRepo(cwd))) {\n throw new NotAGitRepoError(cwd);\n }\n\n // Validate refs only for branch mode\n if (options.mode === \"branch\") {\n if (!options.base) {\n throw new InvalidRefError(\"base (required for branch mode)\");\n }\n if (!options.head) {\n throw new InvalidRefError(\"head (required for branch mode)\");\n }\n if (!(await refExists(options.base, cwd))) {\n throw new InvalidRefError(options.base);\n }\n if (!(await refExists(options.head, cwd))) {\n throw new InvalidRefError(options.head);\n }\n }\n\n // For non-branch modes that reference HEAD, validate HEAD exists\n if (options.mode === \"staged\" || options.mode === \"all\") {\n if (!(await refExists(\"HEAD\", cwd))) {\n throw new InvalidRefError(\"HEAD\");\n }\n }\n\n // Collect data based on mode\n const [nameStatusOutput, unifiedDiff] = await Promise.all([\n getNameStatusByMode(options, cwd),\n getUnifiedDiffByMode(options, cwd),\n ]);\n\n // Parse unified diff for tracked files\n let parsedDiffs = parseDiff(unifiedDiff) as ParseDiffFile[];\n let finalNameStatus = nameStatusOutput;\n\n // Include untracked files if requested (default for \"all\" mode)\n if (includeUntracked && options.mode !== \"branch\") {\n const untrackedFiles = await getUntrackedFiles(cwd);\n if (untrackedFiles.length > 0) {\n const untrackedData = await createUntrackedDiffs(untrackedFiles, cwd);\n\n // Merge untracked files into results\n if (untrackedData.nameStatus) {\n finalNameStatus = finalNameStatus\n ? `${finalNameStatus}\\n${untrackedData.nameStatus}`\n : untrackedData.nameStatus;\n }\n parsedDiffs = [...parsedDiffs, ...untrackedData.diffs];\n }\n }\n\n // Determine base/head for ChangeSet based on mode\n let base: string;\n let head: string;\n let basePackageJson: Record<string, unknown> | undefined;\n let headPackageJson: Record<string, unknown> | undefined;\n\n switch (options.mode) {\n case \"branch\":\n base = options.base!;\n head = options.head!;\n basePackageJson = parsePackageJson(await getFileAtRef(base, \"package.json\", cwd));\n headPackageJson = parsePackageJson(await getFileAtRef(head, \"package.json\", cwd));\n break;\n\n case \"unstaged\":\n base = \"INDEX\";\n head = \"WORKING\";\n // For unstaged, the \"base\" is the index - get from HEAD since that's what's staged\n basePackageJson = await getWorkingPackageJson(cwd); // Index is close to working for most cases\n headPackageJson = await getWorkingPackageJson(cwd);\n break;\n\n case \"staged\":\n base = \"HEAD\";\n head = \"INDEX\";\n basePackageJson = parsePackageJson(await getFileAtRef(\"HEAD\", \"package.json\", cwd));\n headPackageJson = await getWorkingPackageJson(cwd); // Staged content\n break;\n\n case \"all\":\n base = \"HEAD\";\n head = \"WORKING\";\n basePackageJson = parsePackageJson(await getFileAtRef(\"HEAD\", \"package.json\", cwd));\n headPackageJson = await getWorkingPackageJson(cwd);\n break;\n }\n\n // Build ChangeSet\n return buildChangeSet({\n base,\n head,\n nameStatusOutput: finalNameStatus,\n parsedDiffs,\n basePackageJson,\n headPackageJson,\n });\n}\n\n/**\n * Get git repository root.\n */\nexport async function getRepoRoot(cwd: string = process.cwd()): Promise<string> {\n try {\n const result = await execa(\"git\", [\n \"rev-parse\",\n \"--show-toplevel\",\n ], { cwd });\n return result.stdout.trim();\n } catch {\n return cwd;\n }\n}\n\n/**\n * Check if working directory is dirty.\n */\nexport async function isWorkingDirDirty(cwd: string = process.cwd()): Promise<boolean> {\n try {\n const result = await execa(\"git\", [\n \"diff-index\",\n \"--quiet\",\n \"HEAD\",\n \"--\",\n ], { cwd, reject: false });\n return result.exitCode !== 0;\n } catch {\n return false;\n }\n}\n",
10
- "/**\n * File filtering utilities to exclude build artifacts and generated files.\n */\n\n// Default exclusion patterns\nexport const DEFAULT_EXCLUDES = [\n \"**/*.d.ts\",\n \"**/*.map\",\n \"**/*.min.js\",\n \"**/*.min.css\",\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.next/**\",\n \"**/.svelte-kit/**\",\n \"**/.nuxt/**\",\n \"**/out/**\",\n \"**/.cache/**\",\n \"**/.parcel-cache/**\",\n \"**/vendor/**\",\n \"**/*.log\",\n \"**/package-lock.json\",\n \"**/yarn.lock\",\n \"**/pnpm-lock.yaml\",\n \"**/bun.lock\",\n // Archive files\n \"**/*.tgz\",\n \"**/*.tar.gz\",\n \"**/*.zip\",\n];\n\n// Patterns for files that should be excluded from analysis\nconst EXCLUDED_PATTERNS: RegExp[] = [\n // Build output\n /^dist\\//,\n /^build\\//,\n /^\\.next\\//,\n /^\\.svelte-kit\\//,\n /^\\.nuxt\\//,\n /^out\\//,\n\n // Dependencies\n /^node_modules\\//,\n /^vendor\\//,\n\n // Source maps\n /\\.map$/,\n\n // Generated types\n /\\.d\\.ts$/,\n\n // Minified files\n /\\.min\\.(js|css)$/,\n\n // Bundled files\n /^\\.cache\\//,\n /^\\.parcel-cache\\//,\n];\n\n/**\n * Check if a file path should be excluded from analysis.\n */\nexport function shouldExcludeFile(path: string): boolean {\n return EXCLUDED_PATTERNS.some((pattern) => pattern.test(path));\n}\n\n/**\n * Filter out excluded files from a list of paths.\n */\nexport function filterExcludedFiles(paths: string[]): string[] {\n return paths.filter((path) => !shouldExcludeFile(path));\n}\n\n",
11
- "/**\n * File summary analyzer - lists added/modified/deleted/renamed paths.\n */\n\nimport { shouldExcludeFile } from \"../core/filters.js\";\nimport type {\n Analyzer,\n ChangeSet,\n FileDiff,\n FileSummaryFinding,\n Finding,\n} from \"../core/types.js\";\n\n/**\n * Represents a detected change pattern with priority for ranking.\n */\ninterface DetectedChange {\n description: string;\n priority: number; // Higher = more significant\n}\n\n/**\n * Detect all changes in added/removed lines and return prioritized list.\n */\nfunction detectChanges(\n addedLines: string,\n removedLines: string,\n status: string\n): DetectedChange[] {\n const changes: DetectedChange[] = [];\n\n // --- Function declarations (priority 100) ---\n // Standard function declarations\n const funcAddMatches = addedLines.matchAll(/(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)/g);\n for (const match of funcAddMatches) {\n const name = match[1];\n const wasRemoved = removedLines.includes(`function ${name}`);\n if (wasRemoved) {\n changes.push({ description: `Modified function: ${name}()`, priority: 100 });\n } else if (status === \"modified\") {\n changes.push({ description: `Added function: ${name}()`, priority: 100 });\n } else {\n changes.push({ description: `Added function: ${name}()`, priority: 100 });\n }\n }\n\n // Arrow function exports: export const foo = () => {} or export const foo = async () => {}\n const arrowFuncMatches = addedLines.matchAll(/export\\s+const\\s+(\\w+)\\s*=\\s*(?:async\\s*)?\\([^)]*\\)\\s*(?::\\s*[^=]+)?\\s*=>/g);\n for (const match of arrowFuncMatches) {\n const name = match[1];\n const wasRemoved = removedLines.includes(`const ${name}`);\n if (wasRemoved) {\n changes.push({ description: `Modified: ${name}()`, priority: 95 });\n } else {\n changes.push({ description: `Added: ${name}()`, priority: 95 });\n }\n }\n\n // --- Class declarations (priority 90) ---\n const classMatches = addedLines.matchAll(/(?:export\\s+)?class\\s+(\\w+)/g);\n for (const match of classMatches) {\n const name = match[1];\n const wasRemoved = removedLines.includes(`class ${name}`);\n if (wasRemoved) {\n changes.push({ description: `Modified class: ${name}`, priority: 90 });\n } else {\n changes.push({ description: `Added class: ${name}`, priority: 90 });\n }\n }\n\n // --- Interface/type declarations (priority 80) ---\n const interfaceMatches = addedLines.matchAll(/(?:export\\s+)?interface\\s+(\\w+)/g);\n for (const match of interfaceMatches) {\n const name = match[1];\n const wasRemoved = removedLines.includes(`interface ${name}`);\n if (wasRemoved) {\n changes.push({ description: `Modified interface: ${name}`, priority: 80 });\n } else {\n changes.push({ description: `Added interface: ${name}`, priority: 80 });\n }\n }\n\n const typeMatches = addedLines.matchAll(/(?:export\\s+)?type\\s+(\\w+)\\s*=/g);\n for (const match of typeMatches) {\n const name = match[1];\n const wasRemoved = removedLines.includes(`type ${name}`);\n if (wasRemoved) {\n changes.push({ description: `Modified type: ${name}`, priority: 80 });\n } else {\n changes.push({ description: `Added type: ${name}`, priority: 80 });\n }\n }\n\n // --- Enum declarations (priority 75) ---\n const enumMatches = addedLines.matchAll(/(?:export\\s+)?enum\\s+(\\w+)/g);\n for (const match of enumMatches) {\n const name = match[1];\n const wasRemoved = removedLines.includes(`enum ${name}`);\n if (wasRemoved) {\n changes.push({ description: `Modified enum: ${name}`, priority: 75 });\n } else {\n changes.push({ description: `Added enum: ${name}`, priority: 75 });\n }\n }\n\n // --- Const exports (priority 70) ---\n // Match exported constants that are NOT arrow functions (already handled above)\n const constMatches = addedLines.matchAll(/export\\s+const\\s+(\\w+)\\s*(?::\\s*[^=]+)?\\s*=/g);\n for (const match of constMatches) {\n const name = match[1];\n // Skip if already detected as arrow function\n const isArrowFunc = new RegExp(`export\\\\s+const\\\\s+${name}\\\\s*=\\\\s*(?:async\\\\s*)?\\\\(`).test(addedLines);\n if (isArrowFunc) continue;\n \n const wasRemoved = removedLines.includes(`const ${name}`);\n if (wasRemoved) {\n changes.push({ description: `Modified const: ${name}`, priority: 70 });\n } else {\n changes.push({ description: `Added const: ${name}`, priority: 70 });\n }\n }\n\n // --- Re-exports (priority 60) ---\n // export * from \"./module\"\n const starReexportMatch = addedLines.match(/export\\s+\\*\\s+from\\s+['\"]([^'\"]+)['\"]/);\n if (starReexportMatch) {\n changes.push({ description: `Re-exports from: ${starReexportMatch[1]}`, priority: 60 });\n }\n\n // export { x, y } from \"./module\"\n const namedReexportMatch = addedLines.match(/export\\s+\\{([^}]+)\\}\\s+from\\s+['\"]([^'\"]+)['\"]/);\n if (namedReexportMatch) {\n const symbols = namedReexportMatch[1].split(\",\").map(s => s.trim().split(\" \")[0]).slice(0, 3);\n const suffix = namedReexportMatch[1].split(\",\").length > 3 ? \" ...\" : \"\";\n changes.push({ description: `Re-exports: ${symbols.join(\", \")}${suffix}`, priority: 60 });\n }\n\n // --- Object method changes (priority 65) ---\n // Detect method definitions in objects: { methodName() { } } or { methodName: function() { } }\n const methodMatches = addedLines.matchAll(/^\\s*(?:async\\s+)?(\\w+)\\s*\\([^)]*\\)\\s*\\{/gm);\n for (const match of methodMatches) {\n const name = match[1];\n // Skip common non-method patterns\n if ([\"if\", \"for\", \"while\", \"switch\", \"catch\", \"function\"].includes(name)) continue;\n const wasRemoved = new RegExp(`\\\\b${name}\\\\s*\\\\(`).test(removedLines);\n if (wasRemoved) {\n changes.push({ description: `Modified method: ${name}()`, priority: 65 });\n }\n // Only report new methods if the file is new\n else if (status === \"added\") {\n changes.push({ description: `Added method: ${name}()`, priority: 65 });\n }\n }\n\n // --- Import changes (priority 40) ---\n const importMatches = addedLines.matchAll(/^import\\s+(?:\\{[^}]+\\}|[^{}\\s]+)\\s+from\\s+['\"]([^'\"]+)['\"]/gm);\n const newImports: string[] = [];\n for (const match of importMatches) {\n const module = match[1];\n // Only report if not in removed lines (actually new)\n if (!removedLines.includes(module)) {\n newImports.push(module);\n }\n }\n if (newImports.length > 0) {\n const displayImports = newImports.slice(0, 2).map(m => m.split(\"/\").pop() || m);\n const suffix = newImports.length > 2 ? ` (+${newImports.length - 2} more)` : \"\";\n changes.push({ description: `New imports: ${displayImports.join(\", \")}${suffix}`, priority: 40 });\n }\n\n // --- Switch case changes (priority 50) ---\n const caseMatches = addedLines.matchAll(/case\\s+['\"]?([^'\":\\s]+)['\"]?\\s*:/g);\n const newCases: string[] = [];\n for (const match of caseMatches) {\n const caseName = match[1];\n if (!removedLines.includes(`case ${caseName}`) && !removedLines.includes(`case \"${caseName}\"`) && !removedLines.includes(`case '${caseName}'`)) {\n newCases.push(caseName);\n }\n }\n if (newCases.length > 0) {\n const displayCases = newCases.slice(0, 2);\n const suffix = newCases.length > 2 ? ` (+${newCases.length - 2} more)` : \"\";\n changes.push({ description: `Added cases: ${displayCases.join(\", \")}${suffix}`, priority: 50 });\n }\n\n // --- CLI option changes (priority 85) ---\n // Detect .option() calls in CLI files\n const optionMatches = addedLines.matchAll(/\\.option\\s*\\(\\s*['\"]([^'\"]+)['\"]/g);\n const newOptions: string[] = [];\n for (const match of optionMatches) {\n const optionName = match[1];\n if (!removedLines.includes(optionName)) {\n newOptions.push(optionName);\n }\n }\n if (newOptions.length > 0) {\n const displayOptions = newOptions.slice(0, 2);\n const suffix = newOptions.length > 2 ? ` (+${newOptions.length - 2} more)` : \"\";\n changes.push({ description: `Added CLI options: ${displayOptions.join(\", \")}${suffix}`, priority: 85 });\n }\n\n // --- React component changes (priority 70) ---\n // Detect JSX elements being added\n if (/<[A-Z]\\w+/.test(addedLines) && (addedLines.includes(\"return\") || addedLines.includes(\"=>\"))) {\n changes.push({ description: \"Component JSX updated\", priority: 30 });\n }\n\n return changes;\n}\n\n/**\n * Generate a heuristic-based description of what changed in a file.\n * Analyzes diff hunks to identify patterns like new exports, function changes, etc.\n */\nfunction describeChange(diff: FileDiff): string | null {\n // Collect all added lines from hunks\n const addedLines = diff.hunks.flatMap(h => h.additions).join(\"\\n\");\n const removedLines = diff.hunks.flatMap(h => h.deletions).join(\"\\n\");\n\n // --- Path-based detections (highest priority) ---\n \n // Detect new CLI command module\n if (diff.path.startsWith(\"src/commands/\") && diff.status === \"added\") {\n if (diff.path.endsWith(\"index.ts\")) {\n return \"New command module\";\n }\n return \"New command helper\";\n }\n \n // Detect new test files\n if (/\\.test\\.[jt]sx?$/.test(diff.path) || /\\.spec\\.[jt]sx?$/.test(diff.path)) {\n if (diff.status === \"added\") {\n return \"New test file\";\n }\n return \"Updated tests\";\n }\n \n // Detect documentation changes\n if (diff.path.endsWith(\".md\") || diff.path.startsWith(\"docs/\")) {\n if (diff.status === \"added\") {\n return \"New documentation\";\n }\n return \"Documentation update\";\n }\n \n // Detect config file changes\n const isConfigFile = diff.path.includes(\"config\") || \n diff.path.endsWith(\".json\") || \n diff.path.endsWith(\".yaml\") ||\n diff.path.endsWith(\".yml\") ||\n diff.path.endsWith(\".toml\") ||\n diff.path.includes(\".env\");\n if (isConfigFile) {\n if (diff.status === \"added\") {\n return \"New configuration\";\n }\n return \"Configuration update\";\n }\n\n // --- Content-based detections ---\n const changes = detectChanges(addedLines, removedLines, diff.status);\n \n if (changes.length === 0) {\n return null;\n }\n\n // Sort by priority (highest first) and take the most significant\n changes.sort((a, b) => b.priority - a.priority);\n \n // Deduplicate by description\n const seen = new Set<string>();\n const unique = changes.filter(c => {\n if (seen.has(c.description)) return false;\n seen.add(c.description);\n return true;\n });\n\n const primary = unique[0];\n \n // If there are multiple significant changes, append count\n if (unique.length > 1) {\n return `${primary.description} (+${unique.length - 1} more)`;\n }\n \n return primary.description;\n}\n\nexport const fileSummaryAnalyzer: Analyzer = {\n name: \"file-summary\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const added: string[] = [];\n const modified: string[] = [];\n const deleted: string[] = [];\n const renamed: Array<{ from: string; to: string }> = [];\n const changeDescriptions: Array<{ file: string; description: string }> = [];\n\n for (const file of changeSet.files) {\n // Skip build artifacts and generated files\n if (shouldExcludeFile(file.path)) {\n continue;\n }\n\n switch (file.status) {\n case \"added\":\n added.push(file.path);\n break;\n case \"modified\":\n modified.push(file.path);\n break;\n case \"deleted\":\n deleted.push(file.path);\n break;\n case \"renamed\":\n renamed.push({\n from: file.oldPath ?? file.path,\n to: file.path,\n });\n break;\n }\n }\n \n // Generate change descriptions from diffs\n for (const diff of changeSet.diffs) {\n if (shouldExcludeFile(diff.path)) continue;\n \n const description = describeChange(diff);\n if (description) {\n changeDescriptions.push({ file: diff.path, description });\n }\n }\n\n // Only emit if there are changes\n if (\n added.length === 0 &&\n modified.length === 0 &&\n deleted.length === 0 &&\n renamed.length === 0\n ) {\n return [];\n }\n\n const finding: FileSummaryFinding = {\n type: \"file-summary\",\n kind: \"file-summary\",\n category: \"unknown\",\n confidence: \"high\",\n evidence: [],\n added,\n modified,\n deleted,\n renamed,\n changeDescriptions: changeDescriptions.length > 0 ? changeDescriptions : undefined,\n };\n\n return [finding];\n },\n};\n\n",
12
- "/**\n * File category classifier - groups files into meaningful categories.\n */\n\nimport type {\n Analyzer,\n ChangeSet,\n FileCategory,\n FileCategoryFinding,\n Finding,\n} from \"../core/types.js\";\n\n// Category detection rules (order matters - first match wins)\nconst CATEGORY_RULES: Array<{\n category: FileCategory;\n patterns: RegExp[];\n}> = [\n // Tests (check before product to exclude test files from product)\n {\n category: \"tests\",\n patterns: [\n /^tests?\\//i,\n /^__tests__\\//i,\n /\\/tests?\\//i, // matches src/tests/, lib/tests/, etc.\n /\\/__tests__\\//i,\n /\\.test\\.[jt]sx?$/i,\n /\\.spec\\.[jt]sx?$/i,\n /\\.e2e\\.[jt]sx?$/i,\n /vitest\\.config/i,\n /jest\\.config/i,\n /cypress\\//i,\n /playwright\\//i,\n ],\n },\n // CI/CD\n {\n category: \"ci\",\n patterns: [\n /^\\.github\\/workflows\\//,\n /^\\.github\\/actions\\//,\n /^\\.gitlab-ci\\.yml$/,\n /^\\.circleci\\//,\n /^Jenkinsfile$/,\n /^\\.travis\\.yml$/,\n /^azure-pipelines\\.yml$/,\n /^bitbucket-pipelines\\.yml$/,\n ],\n },\n // Infrastructure\n {\n category: \"infra\",\n patterns: [\n /^Dockerfile/i,\n /^docker-compose/i,\n /^\\.dockerignore$/,\n /^helm\\//i,\n /^charts?\\//i,\n /^terraform\\//i,\n /^\\.tf$/,\n /^k8s\\//i,\n /^kubernetes\\//i,\n /^pulumi\\//i,\n /^ansible\\//i,\n /^Vagrantfile$/,\n ],\n },\n // Database (migrations, schemas, seeds)\n {\n category: \"database\",\n patterns: [\n /^supabase\\/migrations\\//,\n /^supabase\\/seed/,\n /^prisma\\/migrations\\//,\n /^prisma\\/schema\\.prisma$/,\n /^drizzle\\/migrations\\//,\n /^drizzle\\.config/,\n /^migrations?\\//i,\n /\\/migrations?\\//i, // matches db/migrations/, database/migrations/, etc.\n /\\.sql$/i,\n ],\n },\n // Documentation\n {\n category: \"docs\",\n patterns: [\n /^docs?\\//i,\n /^documentation\\//i,\n /\\.md$/i,\n /\\.mdx$/i,\n /^README/i,\n /^CHANGELOG/i,\n /^CONTRIBUTING/i,\n /^LICENSE/i,\n /^\\.all-contributorsrc$/,\n ],\n },\n // Dependencies\n {\n category: \"dependencies\",\n patterns: [\n /^package\\.json$/,\n /^package-lock\\.json$/,\n /^yarn\\.lock$/,\n /^pnpm-lock\\.yaml$/,\n /^bun\\.lock$/,\n /^bun\\.lockb$/,\n /^requirements\\.txt$/,\n /^Pipfile(\\.lock)?$/,\n /^poetry\\.lock$/,\n /^pyproject\\.toml$/,\n /^Cargo\\.(toml|lock)$/,\n /^go\\.(mod|sum)$/,\n /^Gemfile(\\.lock)?$/,\n /^composer\\.(json|lock)$/,\n ],\n },\n // Configuration\n {\n category: \"config\",\n patterns: [\n /^\\.[a-z]+rc(\\.json|\\.js|\\.cjs|\\.mjs|\\.yaml|\\.yml)?$/i,\n /\\.config\\.[jt]s$/i,\n /\\.config\\.[a-z]+\\.[jt]s$/i, // e.g., vite.config.e2e.ts\n /^\\.env/i,\n /^wrangler\\.(toml|json)$/i,\n /^tsconfig.*\\.json$/i,\n /^\\.eslintrc/i,\n /^\\.prettierrc/i,\n /^\\.editorconfig$/,\n /^\\.gitignore$/,\n /^\\.nvmrc$/,\n /^\\.node-version$/,\n ],\n },\n // Artifacts (build outputs, packages, binaries)\n {\n category: \"artifacts\",\n patterns: [\n /\\.tgz$/i, // npm/bun pack tarballs\n /\\.tar\\.gz$/i, // compressed archives\n /\\.zip$/i, // zip archives\n /\\.whl$/i, // Python wheels\n /\\.jar$/i, // Java archives\n /\\.war$/i, // Java web archives\n /\\.gem$/i, // Ruby gems\n /\\.nupkg$/i, // NuGet packages\n /\\.deb$/i, // Debian packages\n /\\.rpm$/i, // RPM packages\n /\\.dmg$/i, // macOS disk images\n /\\.exe$/i, // Windows executables\n /\\.dll$/i, // Windows libraries\n /\\.so$/i, // Linux shared objects\n /\\.dylib$/i, // macOS dynamic libraries\n /\\.a$/i, // Static libraries\n /\\.o$/i, // Object files\n /\\.wasm$/i, // WebAssembly binaries\n ],\n },\n // Product code (src, lib, app - excluding already matched patterns)\n {\n category: \"product\",\n patterns: [\n /^src\\//,\n /^lib\\//,\n /^app\\//,\n /^pages\\//,\n /^components\\//,\n /^hooks\\//,\n /^utils\\//,\n /^services\\//,\n /^api\\//,\n /^server\\//,\n /^client\\//,\n /\\.[jt]sx?$/, // Any JS/TS file not matched above\n /\\.svelte$/,\n /\\.vue$/,\n /\\.astro$/,\n ],\n },\n];\n\n/**\n * Determine the category of a file path.\n */\nexport function categorizeFile(path: string): FileCategory {\n for (const rule of CATEGORY_RULES) {\n if (rule.patterns.some((pattern) => pattern.test(path))) {\n return rule.category;\n }\n }\n return \"other\";\n}\n\n/**\n * Get a human-readable label for a category.\n */\nexport function getCategoryLabel(category: FileCategory): string {\n const labels: Record<FileCategory, string> = {\n product: \"Product Code\",\n tests: \"Tests\",\n ci: \"CI/CD\",\n infra: \"Infrastructure\",\n database: \"Database\",\n docs: \"Documentation\",\n dependencies: \"Dependencies\",\n config: \"Configuration\",\n artifacts: \"Build Artifacts\",\n other: \"Other\",\n };\n return labels[category];\n}\n\nexport const fileCategoryAnalyzer: Analyzer = {\n name: \"file-category\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const categories: Record<FileCategory, string[]> = {\n product: [],\n tests: [],\n ci: [],\n infra: [],\n database: [],\n docs: [],\n dependencies: [],\n config: [],\n artifacts: [],\n other: [],\n };\n\n // Categorize all changed files\n for (const file of changeSet.files) {\n const category = categorizeFile(file.path);\n categories[category].push(file.path);\n }\n\n // Build summary (only categories with files)\n const summary = (Object.entries(categories) as [FileCategory, string[]][])\n .filter(([, files]) => files.length > 0)\n .map(([category, files]) => ({\n category,\n count: files.length,\n }))\n .sort((a, b) => b.count - a.count);\n\n // Only emit if there are categorized files\n if (summary.length === 0) {\n return [];\n }\n\n // Note: category is \"unknown\" because file-category is a meta-finding\n // that summarizes all files - it doesn't belong to a specific domain area.\n // This finding is skipped during category aggregation (see categories.ts).\n const finding: FileCategoryFinding = {\n type: \"file-category\",\n kind: \"file-category\",\n category: \"unknown\",\n confidence: \"high\",\n evidence: [],\n categories,\n summary,\n };\n\n return [finding as unknown as Finding];\n },\n};\n\n",
13
- "/**\n * Diff parsing utilities.\n */\n\nimport type { FileDiff, Hunk } from \"../core/types.js\";\n\n/**\n * Line with its position in the new file.\n */\nexport interface LineWithNumber {\n line: string;\n lineNumber: number;\n}\n\n/**\n * Get all additions from a FileDiff.\n */\nexport function getAdditions(diff: FileDiff): string[] {\n return diff.hunks.flatMap((hunk) => hunk.additions);\n}\n\n/**\n * Get all additions from a FileDiff with their line numbers in the new file.\n * This is useful for SARIF output and other tools that need precise locations.\n */\nexport function getAdditionsWithLineNumbers(diff: FileDiff): LineWithNumber[] {\n const result: LineWithNumber[] = [];\n\n for (const hunk of diff.hunks) {\n let currentLine = hunk.newStart;\n\n // Parse hunk content to track line numbers accurately\n const lines = hunk.content.split('\\n');\n for (const line of lines) {\n if (line.startsWith('@@')) {\n // Skip hunk header\n continue;\n }\n\n if (line.startsWith('+') && !line.startsWith('+++')) {\n // This is an addition\n result.push({\n line: line.slice(1), // Remove leading +\n lineNumber: currentLine,\n });\n currentLine++;\n } else if (!line.startsWith('-')) {\n // Context line or empty - increment line number\n currentLine++;\n }\n // Deletion lines don't increment the new file line number\n }\n }\n\n return result;\n}\n\n/**\n * Get all deletions from a FileDiff.\n */\nexport function getDeletions(diff: FileDiff): string[] {\n return diff.hunks.flatMap((hunk) => hunk.deletions);\n}\n\n/**\n * Get all changes (additions + deletions) from a FileDiff.\n * Optimized to iterate hunks once instead of twice.\n */\nexport function getAllChanges(diff: FileDiff): string[] {\n const changes: string[] = [];\n for (const hunk of diff.hunks) {\n changes.push(...hunk.additions, ...hunk.deletions);\n }\n return changes;\n}\n\n/**\n * Get combined content of all hunks.\n */\nexport function getHunkContent(hunks: Hunk[]): string {\n return hunks.map((h) => [...h.additions, ...h.deletions].join(\"\\n\")).join(\"\\n\");\n}\n\n/**\n * Check if a file path matches a pattern.\n */\nexport function matchesPattern(path: string, pattern: RegExp): boolean {\n return pattern.test(path);\n}\n\n/**\n * Filter diffs by path pattern.\n */\nexport function filterDiffsByPath(\n diffs: FileDiff[],\n pattern: RegExp\n): FileDiff[] {\n return diffs.filter((diff) => matchesPattern(diff.path, pattern));\n}\n\n/**\n * Check if any addition line matches a pattern.\n */\nexport function hasAdditionMatching(diff: FileDiff, pattern: RegExp): boolean {\n return getAdditions(diff).some((line) => pattern.test(line));\n}\n\n/**\n * Find all matches of a pattern in additions.\n */\nexport function findAdditionMatches(\n diff: FileDiff,\n pattern: RegExp\n): RegExpMatchArray[] {\n const matches: RegExpMatchArray[] = [];\n // Optimization: Hoist RegExp creation out of the loop\n const globalPattern = new RegExp(pattern.source, \"g\" + pattern.flags.replace(\"g\", \"\"));\n\n for (const line of getAdditions(diff)) {\n // Reset lastIndex for each line since we are reusing the same RegExp instance\n globalPattern.lastIndex = 0;\n\n let match;\n while ((match = globalPattern.exec(line)) !== null) {\n matches.push(match);\n }\n }\n return matches;\n}\n\n/**\n * Match with its line number in the new file.\n */\nexport interface MatchWithLineNumber {\n match: RegExpMatchArray;\n lineNumber: number;\n line: string;\n}\n\n/**\n * Find all matches of a pattern in additions with line numbers.\n * This is useful for SARIF output and other tools that need precise locations.\n */\nexport function findAdditionMatchesWithLineNumbers(\n diff: FileDiff,\n pattern: RegExp\n): MatchWithLineNumber[] {\n const matches: MatchWithLineNumber[] = [];\n const globalPattern = new RegExp(pattern.source, \"g\" + pattern.flags.replace(\"g\", \"\"));\n\n const additionsWithLines = getAdditionsWithLineNumbers(diff);\n\n for (const { line, lineNumber } of additionsWithLines) {\n globalPattern.lastIndex = 0;\n\n let match;\n while ((match = globalPattern.exec(line)) !== null) {\n matches.push({\n match,\n lineNumber,\n line,\n });\n }\n }\n\n return matches;\n}\n",
14
- "/**\n * Evidence extraction and redaction utilities.\n */\n\nimport type { Evidence, Hunk } from \"./types.js\";\n\n/**\n * Create evidence from a file with excerpt.\n */\nexport function createEvidence(\n file: string,\n excerpt: string,\n options?: {\n line?: number;\n hunk?: Hunk;\n }\n): Evidence {\n return {\n file,\n excerpt: excerpt.trim(),\n line: options?.line,\n hunk: options?.hunk\n ? {\n oldStart: options.hunk.oldStart,\n oldLines: options.hunk.oldLines,\n newStart: options.hunk.newStart,\n newLines: options.hunk.newLines,\n }\n : undefined,\n };\n}\n\n/**\n * Redact obvious secrets from evidence excerpts.\n * Masks values but preserves keys for env vars.\n */\nexport function redactEvidence(evidence: Evidence): Evidence {\n return {\n ...evidence,\n excerpt: redactSecrets(evidence.excerpt),\n };\n}\n\n/**\n * Redact secrets from text.\n * Patterns:\n * - API keys: sk_live_..., pk_test_..., etc.\n * - JWT tokens: eyJ...\n * - AWS keys: AKIA...\n * - Generic secrets: password=..., secret=..., token=...\n */\nexport function redactSecrets(text: string): string {\n let redacted = text;\n\n // Stripe-like keys (must be at least 24 chars after prefix)\n redacted = redacted.replace(\n /\\b(sk|pk|rk)_(live|test)_[A-Za-z0-9]{24,}/g,\n \"$1_$2_***REDACTED***\"\n );\n\n // JWT tokens (must have 3 base64 parts separated by dots)\n redacted = redacted.replace(\n /\\beyJ[A-Za-z0-9_-]{30,}\\.[A-Za-z0-9_-]{30,}\\.[A-Za-z0-9_-]{30,}/g,\n \"eyJ***REDACTED***\"\n );\n\n // AWS keys (exactly 20 chars: AKIA + 16 alphanumeric)\n redacted = redacted.replace(\n /\\bAKIA[0-9A-Z]{16}\\b/g,\n \"AKIA***REDACTED***\"\n );\n\n // Generic secret patterns (only match assignment contexts)\n // Match: password=value, secret: value, token=\"value\", api_key='value'\n // Skip values that contain ***REDACTED*** to avoid double-redaction\n redacted = redacted.replace(\n /(password|secret|token|apikey|api_key)(\\s*[:=]\\s*)([\"'])(?!.*\\*\\*\\*REDACTED\\*\\*\\*)([^\"']+?)\\3/gi,\n \"$1$2$3***REDACTED***$3\"\n );\n \n // Also match unquoted values (skip values that contain ***REDACTED***)\n redacted = redacted.replace(\n /(password|secret|token|apikey|api_key)(\\s*[:=]\\s*)(?!.*\\*\\*\\*REDACTED\\*\\*\\*)([^\\s\"',;)]+)/gi,\n \"$1$2***REDACTED***\"\n );\n\n return redacted;\n}\n\n/**\n * Truncate excerpt to max length.\n */\nexport function truncateExcerpt(\n excerpt: string,\n maxLength: number = 200\n): string {\n if (excerpt.length <= maxLength) {\n return excerpt;\n }\n return excerpt.substring(0, maxLength - 3) + \"...\";\n}\n\n/**\n * Extract a representative excerpt from additions.\n */\nexport function extractRepresentativeExcerpt(\n additions: string[],\n maxLength: number = 200\n): string {\n if (additions.length === 0) {\n return \"\";\n }\n\n // Find first non-empty, non-comment line\n for (const line of additions) {\n const trimmed = line.trim();\n if (\n trimmed.length > 0 &&\n !trimmed.startsWith(\"//\") &&\n !trimmed.startsWith(\"/*\") &&\n !trimmed.startsWith(\"*\") &&\n !trimmed.startsWith(\"#\")\n ) {\n return truncateExcerpt(trimmed, maxLength);\n }\n }\n\n // Fallback to first line\n return truncateExcerpt(additions[0].trim(), maxLength);\n}\n",
15
- "/**\n * SvelteKit route detector - detects changes under src/routes.\n */\n\nimport { getAdditions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n FileDiff,\n FileStatus,\n Finding,\n RouteChangeFinding,\n RouteType,\n} from \"../core/types.js\";\n\n// Route file patterns\nconst ROUTE_FILE_PATTERNS: Record<string, RouteType> = {\n \"+page.svelte\": \"page\",\n \"+page.ts\": \"page\",\n \"+page.server.ts\": \"page\",\n \"+layout.svelte\": \"layout\",\n \"+layout.ts\": \"layout\",\n \"+layout.server.ts\": \"layout\",\n \"+server.ts\": \"endpoint\",\n \"+error.svelte\": \"error\",\n};\n\n// HTTP method detection pattern\nconst METHOD_PATTERN = /export\\s+const\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b/g;\n\n/**\n * Check if a path is a SvelteKit route file.\n */\nexport function isRouteFile(path: string): boolean {\n return path.startsWith(\"src/routes/\") && hasRouteFilePattern(path);\n}\n\n/**\n * Check if path ends with a route file pattern.\n */\nfunction hasRouteFilePattern(path: string): boolean {\n const fileName = path.split(\"/\").pop() ?? \"\";\n return Object.keys(ROUTE_FILE_PATTERNS).some((pattern) =>\n fileName.startsWith(pattern.replace(\".svelte\", \"\").replace(\".ts\", \"\")) &&\n (fileName.endsWith(\".svelte\") || fileName.endsWith(\".ts\"))\n );\n}\n\n/**\n * Get the route type from a file path.\n */\nexport function getRouteType(path: string): RouteType {\n const fileName = path.split(\"/\").pop() ?? \"\";\n for (const [pattern, type] of Object.entries(ROUTE_FILE_PATTERNS)) {\n if (fileName === pattern) {\n return type;\n }\n }\n return \"unknown\";\n}\n\n/**\n * Convert a file path to a SvelteKit route ID.\n *\n * Rules:\n * - Strip `src/routes` prefix\n * - Remove route groups `(name)` from URL (but keep in route ID)\n * - Keep param notation: [slug], [[id]], [...rest]\n * - Remove file name (the route is the directory)\n */\nexport function pathToRouteId(path: string): string {\n // Remove src/routes prefix\n let routeId = path.replace(/^src\\/routes/, \"\");\n\n // Remove the file name\n const parts = routeId.split(\"/\");\n parts.pop(); // Remove file name\n\n routeId = parts.join(\"/\");\n\n // If empty, it's the root route\n if (routeId === \"\" || routeId === \"/\") {\n return \"/\";\n }\n\n // Ensure leading slash\n if (!routeId.startsWith(\"/\")) {\n routeId = \"/\" + routeId;\n }\n\n return routeId;\n}\n\n/**\n * Convert route ID to URL path (for display).\n * Removes route groups from the path.\n */\nexport function routeIdToUrlPath(routeId: string): string {\n // Remove route groups: (name)\n return routeId.replace(/\\/\\([^)]+\\)/g, \"\");\n}\n\n/**\n * Detect HTTP methods from endpoint file content.\n */\nexport function detectMethods(diff: FileDiff): string[] {\n const methods = new Set<string>();\n const content = getAdditions(diff).join(\"\\n\");\n\n let match;\n const pattern = new RegExp(METHOD_PATTERN.source, \"g\");\n while ((match = pattern.exec(content)) !== null) {\n methods.add(match[1]);\n }\n\n return Array.from(methods).sort();\n}\n\nexport const routeDetectorAnalyzer: Analyzer = {\n name: \"route-detector\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n const routeFiles = new Map<string, { diff?: FileDiff; status: FileStatus }>();\n\n // Collect route files from file changes\n for (const file of changeSet.files) {\n if (isRouteFile(file.path)) {\n routeFiles.set(file.path, { status: file.status });\n }\n }\n\n // Add diff data\n for (const diff of changeSet.diffs) {\n if (isRouteFile(diff.path)) {\n const existing = routeFiles.get(diff.path);\n if (existing) {\n existing.diff = diff;\n } else {\n routeFiles.set(diff.path, { diff, status: diff.status });\n }\n }\n }\n\n // Generate findings\n for (const [path, { diff, status }] of routeFiles) {\n const routeId = pathToRouteId(path);\n const routeType = getRouteType(path);\n\n // Extract evidence\n const evidence = [];\n if (diff && diff.hunks.length > 0) {\n const additions = getAdditions(diff);\n if (additions.length > 0) {\n const excerpt = extractRepresentativeExcerpt(additions);\n if (excerpt) {\n evidence.push(createEvidence(path, excerpt));\n }\n }\n }\n\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"high\",\n evidence,\n routeId,\n file: path,\n change: status,\n routeType,\n };\n\n // Detect methods for endpoints\n if (routeType === \"endpoint\" && diff) {\n const methods = detectMethods(diff);\n if (methods.length > 0) {\n finding.methods = methods;\n // Add method export as evidence if available\n const methodsExcerpt = methods.map(m => `export const ${m}`).join(\", \");\n if (!evidence.length) {\n evidence.push(createEvidence(path, methodsExcerpt));\n }\n }\n }\n\n findings.push(finding);\n }\n\n return findings;\n },\n};\n\n",
16
- "/**\n * Supabase migration detector with dangerous SQL scanning.\n */\n\nimport { getAdditions } from \"../git/parser.js\";\nimport { createEvidence } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n DbMigrationFinding,\n Finding,\n MigrationRisk,\n RiskFlagFinding,\n} from \"../core/types.js\";\n\n// Migration file pattern\nconst MIGRATION_PATTERN = /^supabase\\/migrations\\/.*\\.sql$/;\n\n// Seed/config patterns (lower risk)\nconst SEED_PATTERN = /^supabase\\/(seed|config)/;\n\n// Destructive SQL patterns\nconst DESTRUCTIVE_PATTERNS: Array<{ pattern: RegExp; description: string }> = [\n { pattern: /DROP\\s+TABLE/i, description: \"DROP TABLE\" },\n { pattern: /DROP\\s+COLUMN/i, description: \"DROP COLUMN\" },\n { pattern: /TRUNCATE/i, description: \"TRUNCATE\" },\n { pattern: /ALTER\\s+COLUMN/i, description: \"ALTER COLUMN\" },\n { pattern: /ALTER\\s+TABLE\\s+\\w+\\s+.*\\s+TYPE/i, description: \"ALTER TYPE\" },\n {\n pattern: /DELETE\\s+FROM\\s+\\w+\\s*(?:;|$)/i,\n description: \"DELETE without WHERE\",\n },\n];\n\n/**\n * Check if a path is a Supabase migration file.\n */\nexport function isMigrationFile(path: string): boolean {\n return MIGRATION_PATTERN.test(path);\n}\n\n/**\n * Check if a path is a seed or config file.\n */\nexport function isSeedOrConfig(path: string): boolean {\n return SEED_PATTERN.test(path);\n}\n\n/**\n * Scan SQL content for destructive patterns.\n */\nexport function scanForDestructivePatterns(\n content: string\n): Array<{ pattern: string; description: string }> {\n const matches: Array<{ pattern: string; description: string }> = [];\n\n for (const { pattern, description } of DESTRUCTIVE_PATTERNS) {\n if (pattern.test(content)) {\n matches.push({ pattern: pattern.source, description });\n }\n }\n\n return matches;\n}\n\n/**\n * Determine migration risk level based on content.\n * Returns risk level, reasons, and evidence.\n */\nexport function determineMigrationRisk(\n files: string[],\n changeSet: ChangeSet\n): {\n risk: MigrationRisk;\n reasons: string[];\n evidence: Array<{ file: string; excerpt: string }>;\n} {\n const reasons: string[] = [];\n const evidence: Array<{ file: string; excerpt: string }> = [];\n let hasDestructive = false;\n\n for (const file of files) {\n const diff = changeSet.diffs.find((d) => d.path === file);\n if (!diff) continue;\n\n const additions = getAdditions(diff);\n const additionsText = additions.join(\"\\n\");\n const destructive = scanForDestructivePatterns(additionsText);\n\n for (const { description } of destructive) {\n hasDestructive = true;\n reasons.push(`${description} detected in ${file}`);\n \n // Find the line with the destructive pattern\n const lineWithPattern = additions.find((line) =>\n DESTRUCTIVE_PATTERNS.some((p) => p.pattern.test(line))\n );\n if (lineWithPattern) {\n evidence.push({\n file,\n excerpt: lineWithPattern.trim(),\n });\n }\n }\n }\n\n if (hasDestructive) {\n return { risk: \"high\", reasons, evidence };\n }\n\n // Check if only seeds/config\n const onlySeedsOrConfig = files.every((f) => isSeedOrConfig(f));\n if (onlySeedsOrConfig) {\n return {\n risk: \"low\",\n reasons: [\"Only seed/config files changed\"],\n evidence,\n };\n }\n\n return {\n risk: \"medium\",\n reasons: [\"Migration files changed\"],\n evidence,\n };\n}\n\nexport const supabaseAnalyzer: Analyzer = {\n name: \"supabase\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n const migrationFiles: string[] = [];\n const supabaseFiles: string[] = [];\n\n // Collect migration and Supabase files\n for (const file of changeSet.files) {\n if (file.path.startsWith(\"supabase/\")) {\n supabaseFiles.push(file.path);\n if (isMigrationFile(file.path)) {\n migrationFiles.push(file.path);\n }\n }\n }\n\n // If no Supabase files, skip\n if (supabaseFiles.length === 0) {\n return [];\n }\n\n // Determine risk\n const { risk, reasons, evidence: evidenceData } = determineMigrationRisk(\n migrationFiles.length > 0 ? migrationFiles : supabaseFiles,\n changeSet\n );\n\n // Convert evidence data to Evidence type\n const evidence = evidenceData.map((e) =>\n createEvidence(e.file, e.excerpt)\n );\n\n const migrationFinding: DbMigrationFinding = {\n type: \"db-migration\",\n kind: \"db-migration\",\n category: \"database\",\n confidence: \"high\",\n evidence,\n tool: \"supabase\",\n files: migrationFiles.length > 0 ? migrationFiles : supabaseFiles,\n risk,\n reasons,\n };\n\n findings.push(migrationFinding);\n\n // Add risk flag for high risk\n if (risk === \"high\") {\n const riskFinding: RiskFlagFinding = {\n type: \"risk-flag\",\n kind: \"risk-flag\",\n category: \"database\",\n confidence: \"high\",\n evidence,\n risk: \"high\",\n evidenceText: `Destructive SQL detected: ${reasons.join(\", \")}`,\n };\n findings.push(riskFinding);\n }\n\n return findings;\n },\n};\n\n",
17
- "/**\n * Environment variable detector.\n */\n\nimport { shouldExcludeFile } from \"../core/filters.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n EnvVarFinding,\n Finding,\n} from \"../core/types.js\";\nimport { getAdditions } from \"../git/parser.js\";\n\n// File extensions that should be scanned for env vars (actual code files)\nconst CODE_FILE_EXTENSIONS = new Set([\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n \".svelte\",\n \".vue\",\n \".astro\",\n]);\n\n// Config files that might contain env var references\nconst CONFIG_FILE_PATTERNS = [\n /\\.env(\\..+)?$/, // .env, .env.local, .env.production\n /vite\\.config\\.(ts|js|mjs)$/,\n /svelte\\.config\\.(ts|js|mjs)$/,\n /next\\.config\\.(ts|js|mjs)$/,\n /nuxt\\.config\\.(ts|js|mjs)$/,\n /astro\\.config\\.(ts|js|mjs)$/,\n];\n\n/**\n * Check if a file should be scanned for env vars.\n * Only scan actual code files and config files, not documentation or tests.\n */\nfunction shouldScanForEnvVars(path: string): boolean {\n // Skip documentation\n if (path.endsWith(\".md\") || path.startsWith(\"docs/\")) {\n return false;\n }\n\n // Skip test files (they often contain example env vars)\n if (\n path.includes(\"/tests/\") ||\n path.includes(\"/__tests__/\") ||\n path.includes(\".test.\") ||\n path.includes(\".spec.\") ||\n path.startsWith(\"tests/\")\n ) {\n return false;\n }\n\n // Skip fixture files\n if (path.includes(\"/fixtures/\") || path.includes(\"/__fixtures__/\")) {\n return false;\n }\n\n // Check if it's a config file\n for (const pattern of CONFIG_FILE_PATTERNS) {\n if (pattern.test(path)) {\n return true;\n }\n }\n\n // Check if it has a code file extension\n const ext = path.substring(path.lastIndexOf(\".\"));\n return CODE_FILE_EXTENSIONS.has(ext);\n}\n\n// Patterns for env var detection\nconst ENV_PATTERNS = {\n // process.env.VAR_NAME (including REACT_APP_ and NEXT_PUBLIC_ prefixes)\n processEnv: /process\\.env\\.([A-Z_][A-Z0-9_]*)/g,\n\n // import.meta.env.VITE_VAR_NAME (Vite)\n viteEnv: /import\\.meta\\.env\\.VITE_([A-Z0-9_]+)/g,\n\n // PUBLIC_VAR (SvelteKit public env vars)\n publicVar: /\\bPUBLIC_([A-Z0-9_]+)/g,\n\n // $env/static/public imports\n envStaticPublic:\n /import\\s*\\{([^}]+)\\}\\s*from\\s*[\"']\\$env\\/static\\/public[\"']/g,\n\n // $env/static/private imports\n envStaticPrivate:\n /import\\s*\\{([^}]+)\\}\\s*from\\s*[\"']\\$env\\/static\\/private[\"']/g,\n\n // $env/dynamic/public imports\n envDynamicPublic:\n /import\\s*\\{([^}]+)\\}\\s*from\\s*[\"']\\$env\\/dynamic\\/public[\"']/g,\n\n // $env/dynamic/private imports\n envDynamicPrivate:\n /import\\s*\\{([^}]+)\\}\\s*from\\s*[\"']\\$env\\/dynamic\\/private[\"']/g,\n};\n\n/**\n * Extract variable names from an import statement's destructured list.\n */\nexport function extractImportedVars(importList: string): string[] {\n return importList\n .split(\",\")\n .map((v) => v.trim())\n .filter((v) => v.length > 0)\n .map((v) => {\n // Handle \"VAR as alias\" syntax\n const parts = v.split(/\\s+as\\s+/);\n return parts[0].trim();\n });\n}\n\n/**\n * Extract environment variable names from content.\n */\nexport function extractEnvVars(content: string): Set<string> {\n const vars = new Set<string>();\n\n // process.env.VAR\n // Reset lastIndex to ensure consistent results since we're reusing global Regexps\n ENV_PATTERNS.processEnv.lastIndex = 0;\n let match;\n while ((match = ENV_PATTERNS.processEnv.exec(content)) !== null) {\n vars.add(match[1]);\n }\n\n // import.meta.env.VITE_VAR (Vite)\n ENV_PATTERNS.viteEnv.lastIndex = 0;\n while ((match = ENV_PATTERNS.viteEnv.exec(content)) !== null) {\n vars.add(`VITE_${match[1]}`);\n }\n\n // PUBLIC_VAR\n ENV_PATTERNS.publicVar.lastIndex = 0;\n while ((match = ENV_PATTERNS.publicVar.exec(content)) !== null) {\n vars.add(`PUBLIC_${match[1]}`);\n }\n\n // $env imports (all types)\n const importPatterns = [\n ENV_PATTERNS.envStaticPublic,\n ENV_PATTERNS.envStaticPrivate,\n ENV_PATTERNS.envDynamicPublic,\n ENV_PATTERNS.envDynamicPrivate,\n ];\n\n for (const pattern of importPatterns) {\n pattern.lastIndex = 0;\n while ((match = pattern.exec(content)) !== null) {\n const importedVars = extractImportedVars(match[1]);\n for (const v of importedVars) {\n vars.add(v);\n }\n }\n }\n\n return vars;\n}\n\nexport const envVarAnalyzer: Analyzer = {\n name: \"env-var\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n const varToFilesAndExcerpts = new Map<\n string,\n Array<{ file: string; excerpt: string }>\n >();\n\n // Scan code files for env vars in additions\n for (const diff of changeSet.diffs) {\n // Skip build artifacts and generated files\n if (shouldExcludeFile(diff.path)) {\n continue;\n }\n\n // Only scan actual code files (not docs, tests, fixtures)\n if (!shouldScanForEnvVars(diff.path)) {\n continue;\n }\n\n const additions = getAdditions(diff);\n const additionsText = additions.join(\"\\n\");\n const vars = extractEnvVars(additionsText);\n\n for (const varName of vars) {\n if (!varToFilesAndExcerpts.has(varName)) {\n varToFilesAndExcerpts.set(varName, []);\n }\n \n // Find line with this var\n const lineWithVar = additions.find(line => \n line.includes(varName)\n );\n const excerpt = lineWithVar \n ? lineWithVar.trim()\n : extractRepresentativeExcerpt(additions);\n \n varToFilesAndExcerpts.get(varName)!.push({\n file: diff.path,\n excerpt,\n });\n }\n }\n\n // Create findings\n for (const [name, fileExcerpts] of varToFilesAndExcerpts) {\n const files = Array.from(\n new Set(fileExcerpts.map((fe) => fe.file))\n );\n \n // Create evidence (up to 3 excerpts)\n const evidence = fileExcerpts\n .slice(0, 3)\n .map((fe) => createEvidence(fe.file, fe.excerpt));\n\n const finding: EnvVarFinding = {\n type: \"env-var\",\n kind: \"env-var\",\n category: \"config_env\",\n confidence: \"high\",\n evidence,\n name,\n change: \"added\", // MVP heuristic: if in additions, treat as added\n evidenceFiles: files,\n };\n findings.push(finding);\n }\n\n return findings;\n },\n};\n",
18
- "/**\n * Cloudflare change detector.\n */\n\nimport { getAdditions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n CloudflareArea,\n CloudflareChangeFinding,\n Finding,\n} from \"../core/types.js\";\n\n// Wrangler config patterns\nconst WRANGLER_PATTERNS = [/^wrangler\\.toml$/, /^wrangler\\.json$/];\n\n// GitHub workflow patterns\nconst WORKFLOW_PATTERN = /^\\.github\\/workflows\\/.*\\.(yml|yaml)$/;\n\n// Cloudflare keywords in CI\nconst CLOUDFLARE_CI_KEYWORDS = /\\b(wrangler|cloudflare|workers|pages)\\b/i;\n\n/**\n * Check if a file is a wrangler config.\n */\nexport function isWranglerConfig(path: string): boolean {\n return WRANGLER_PATTERNS.some((pattern) => pattern.test(path));\n}\n\n/**\n * Check if a file is a GitHub workflow.\n */\nexport function isGitHubWorkflow(path: string): boolean {\n return WORKFLOW_PATTERN.test(path);\n}\n\n/**\n * Check if workflow content mentions Cloudflare.\n */\nexport function workflowMentionsCloudflare(content: string): boolean {\n return CLOUDFLARE_CI_KEYWORDS.test(content);\n}\n\nexport const cloudflareAnalyzer: Analyzer = {\n name: \"cloudflare\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n const areaFilesAndEvidence = new Map<\n CloudflareArea,\n Array<{ file: string; excerpt: string }>\n >();\n\n // Check for wrangler config changes\n for (const file of changeSet.files) {\n if (isWranglerConfig(file.path)) {\n if (!areaFilesAndEvidence.has(\"wrangler\")) {\n areaFilesAndEvidence.set(\"wrangler\", []);\n }\n // Try to get excerpt from diff\n const diff = changeSet.diffs.find((d) => d.path === file.path);\n const excerpt = diff\n ? extractRepresentativeExcerpt(getAdditions(diff))\n : file.path;\n areaFilesAndEvidence.get(\"wrangler\")!.push({\n file: file.path,\n excerpt,\n });\n }\n }\n\n // Check for CI changes that mention Cloudflare\n for (const diff of changeSet.diffs) {\n if (isGitHubWorkflow(diff.path)) {\n const additions = getAdditions(diff);\n const additionsText = additions.join(\"\\n\");\n if (workflowMentionsCloudflare(additionsText)) {\n if (!areaFilesAndEvidence.has(\"ci\")) {\n areaFilesAndEvidence.set(\"ci\", []);\n }\n const excerpt = extractRepresentativeExcerpt(additions);\n areaFilesAndEvidence.get(\"ci\")!.push({\n file: diff.path,\n excerpt,\n });\n }\n }\n }\n\n // Create findings\n for (const [area, fileExcerpts] of areaFilesAndEvidence) {\n const files = fileExcerpts.map((fe) => fe.file);\n const evidence = fileExcerpts\n .slice(0, 3)\n .map((fe) => createEvidence(fe.file, fe.excerpt));\n\n const finding: CloudflareChangeFinding = {\n type: \"cloudflare-change\",\n kind: \"cloudflare-change\",\n category: \"cloudflare\",\n confidence: \"high\",\n evidence,\n area,\n files,\n };\n findings.push(finding);\n }\n\n return findings;\n },\n};\n\n",
19
- "/**\n * Vitest test change detector.\n */\n\nimport { createEvidence } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n TestChangeFinding,\n} from \"../core/types.js\";\n\n// Test file patterns\nconst TEST_PATTERNS = [\n /\\.test\\.ts$/,\n /\\.spec\\.ts$/,\n /\\.test\\.js$/,\n /\\.spec\\.js$/,\n /^tests?\\//,\n];\n\n// Vitest config patterns (matches vitest.config.ts, vitest.config.e2e.ts, etc.)\nconst VITEST_CONFIG_PATTERNS = [\n /^vitest\\.config(\\.[a-z0-9]+)?\\.(ts|js|mts|mjs)$/,\n /^vite\\.config(\\.[a-z0-9]+)?\\.(ts|js|mts|mjs)$/, // Vite config might include vitest\n];\n\n/**\n * Check if a file is a test file.\n */\nexport function isTestFile(path: string): boolean {\n return TEST_PATTERNS.some((pattern) => pattern.test(path));\n}\n\n/**\n * Check if a file is a vitest config.\n */\nexport function isVitestConfig(path: string): boolean {\n return VITEST_CONFIG_PATTERNS.some((pattern) => pattern.test(path));\n}\n\nexport const vitestAnalyzer: Analyzer = {\n name: \"vitest\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const testFiles: string[] = [];\n\n // Collect test files\n for (const file of changeSet.files) {\n if (isTestFile(file.path) || isVitestConfig(file.path)) {\n testFiles.push(file.path);\n }\n }\n\n // Only emit if there are test changes\n if (testFiles.length === 0) {\n return [];\n }\n\n // Create evidence from file list\n const evidence = testFiles\n .slice(0, 3)\n .map((file) => createEvidence(file, `Test file ${file}`));\n\n const finding: TestChangeFinding = {\n type: \"test-change\",\n kind: \"test-change\",\n category: \"tests\",\n confidence: \"high\",\n evidence,\n framework: \"vitest\",\n files: testFiles,\n };\n\n return [finding];\n },\n};\n\n",
20
- "/**\n * Dependency change analyzer.\n */\n\nimport * as semver from \"semver\";\nimport { createEvidence } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n DependencyChangeFinding,\n Finding,\n RiskFlagFinding,\n} from \"../core/types.js\";\n\ntype DependencySection = \"dependencies\" | \"devDependencies\";\n\ninterface PackageDeps {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\n// Critical packages that warrant a risk flag on major bump\nconst CRITICAL_PACKAGES = [\"@sveltejs/kit\", \"svelte\", \"vite\"];\n\n// Risky package categories\ntype RiskyCategory = \"auth\" | \"database\" | \"native\" | \"payment\";\n\n/**\n * Pre-built Map for O(1) risky package category lookup.\n * Built at module load time for maximum performance.\n */\nconst RISKY_PACKAGE_MAP: Map<string, RiskyCategory> = new Map([\n // auth packages\n ...[\"passport\", \"jsonwebtoken\", \"bcrypt\", \"bcryptjs\", \"oauth\", \"auth0\",\n \"@auth0/auth0-spa-js\", \"clerk\", \"@clerk/clerk-sdk-node\", \"@clerk/nextjs\",\n \"next-auth\", \"@auth/core\", \"@auth/sveltekit\", \"lucia\", \"lucia-auth\",\n \"arctic\", \"oslo\", \"express-session\", \"cookie-session\", \"passport-local\",\n \"passport-jwt\", \"passport-oauth2\", \"jose\", \"jwks-rsa\", \"supertokens-node\",\n \"@supabase/auth-helpers-sveltekit\", \"@supabase/ssr\"\n ].map(pkg => [pkg, \"auth\" as RiskyCategory] as const),\n\n // database packages\n ...[\"prisma\", \"@prisma/client\", \"drizzle-orm\", \"typeorm\", \"sequelize\",\n \"knex\", \"mongoose\", \"pg\", \"mysql\", \"mysql2\", \"sqlite3\", \"better-sqlite3\",\n \"mongodb\", \"redis\", \"ioredis\", \"@neondatabase/serverless\",\n \"@planetscale/database\", \"@libsql/client\", \"kysely\"\n ].map(pkg => [pkg, \"database\" as RiskyCategory] as const),\n\n // native packages (note: bcrypt appears in both auth and native)\n ...[\"sharp\", \"canvas\", \"node-gyp\", \"node-pre-gyp\", \"node-addon-api\",\n \"nan\", \"ffi-napi\", \"ref-napi\", \"argon2\", \"libsodium-wrappers\",\n \"sodium-native\", \"cpu-features\", \"usb\", \"serialport\"\n ].map(pkg => [pkg, \"native\" as RiskyCategory] as const),\n\n // payment packages\n ...[\"stripe\", \"@stripe/stripe-js\", \"paypal-rest-sdk\",\n \"@paypal/checkout-server-sdk\", \"braintree\", \"square\", \"@square/web-sdk\",\n \"adyen-api-library\", \"razorpay\", \"mollie-api-node\", \"lemon-squeezy\",\n \"@polar-sh/sdk\", \"polar-sdk\"\n ].map(pkg => [pkg, \"payment\" as RiskyCategory] as const),\n]);\n\n/**\n * Check if a package is in a risky category.\n * Uses Map lookup for O(1) performance.\n */\nfunction getRiskyCategory(packageName: string): RiskyCategory | undefined {\n return RISKY_PACKAGE_MAP.get(packageName);\n}\n\n/**\n * Pre-compiled regex for version string cleaning.\n * Compiled once at module load time for performance.\n */\nconst VERSION_PREFIX_REGEX = /^[\\^~>=<]+/;\n\n/**\n * Clean version string for semver parsing.\n */\nfunction cleanVersion(version: string): string {\n // Remove common prefixes: ^, ~, >=, etc.\n return version.replace(VERSION_PREFIX_REGEX, \"\").trim();\n}\n\n/**\n * Determine version impact.\n */\nexport function determineImpact(\n from: string | undefined,\n to: string | undefined\n): \"major\" | \"minor\" | \"patch\" | \"unknown\" {\n if (!from || !to) {\n return \"unknown\";\n }\n\n const cleanFrom = cleanVersion(from);\n const cleanTo = cleanVersion(to);\n\n const parsedFrom = semver.parse(cleanFrom);\n const parsedTo = semver.parse(cleanTo);\n\n if (!parsedFrom || !parsedTo) {\n return \"unknown\";\n }\n\n if (parsedTo.major > parsedFrom.major) {\n return \"major\";\n }\n if (parsedTo.minor > parsedFrom.minor) {\n return \"minor\";\n }\n if (parsedTo.patch > parsedFrom.patch) {\n return \"patch\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Compare dependencies between two package.json versions.\n */\nexport function compareDependencies(\n basePkg: PackageDeps | undefined,\n headPkg: PackageDeps | undefined\n): DependencyChangeFinding[] {\n const findings: DependencyChangeFinding[] = [];\n\n const sections: DependencySection[] = [\"dependencies\", \"devDependencies\"];\n\n for (const section of sections) {\n const baseDeps = basePkg?.[section] ?? {};\n const headDeps = headPkg?.[section] ?? {};\n\n const allPackages = new Set([\n ...Object.keys(baseDeps),\n ...Object.keys(headDeps),\n ]);\n\n for (const name of allPackages) {\n const from = baseDeps[name];\n const to = headDeps[name];\n\n if (from === to) {\n continue; // No change\n }\n\n const riskCategory = getRiskyCategory(name);\n\n if (!from && to) {\n // Added\n const excerpt = `\"${name}\": \"${to}\"`;\n findings.push({\n type: \"dependency-change\",\n kind: \"dependency-change\",\n category: \"dependencies\",\n confidence: \"high\",\n evidence: [createEvidence(\"package.json\", excerpt)],\n name,\n section,\n to,\n impact: \"new\",\n riskCategory,\n });\n } else if (from && !to) {\n // Removed\n const excerpt = `\"${name}\": \"${from}\" (removed)`;\n findings.push({\n type: \"dependency-change\",\n kind: \"dependency-change\",\n category: \"dependencies\",\n confidence: \"high\",\n evidence: [createEvidence(\"package.json\", excerpt)],\n name,\n section,\n from,\n impact: \"removed\",\n riskCategory,\n });\n } else {\n // Changed\n const impact = determineImpact(from, to);\n const excerpt = `\"${name}\": \"${from}\" → \"${to}\"`;\n findings.push({\n type: \"dependency-change\",\n kind: \"dependency-change\",\n category: \"dependencies\",\n confidence: \"high\",\n evidence: [createEvidence(\"package.json\", excerpt)],\n name,\n section,\n from,\n to,\n impact,\n riskCategory,\n });\n }\n }\n }\n\n return findings;\n}\n\nexport const dependencyAnalyzer: Analyzer = {\n name: \"dependencies\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n\n const depFindings = compareDependencies(\n changeSet.basePackageJson as PackageDeps | undefined,\n changeSet.headPackageJson as PackageDeps | undefined\n );\n\n findings.push(...depFindings);\n\n // Check for critical package major bumps\n for (const depFinding of depFindings) {\n if (\n CRITICAL_PACKAGES.includes(depFinding.name) &&\n depFinding.impact === \"major\" &&\n depFinding.from &&\n depFinding.to\n ) {\n const excerpt = `${depFinding.name}: ${depFinding.from} → ${depFinding.to}`;\n const riskFinding: RiskFlagFinding = {\n type: \"risk-flag\",\n kind: \"risk-flag\",\n category: \"dependencies\",\n confidence: \"high\",\n evidence: [createEvidence(\"package.json\", excerpt)],\n risk: \"high\",\n evidenceText: `Major version bump: ${depFinding.name} ${depFinding.from} → ${depFinding.to}`,\n };\n findings.push(riskFinding);\n }\n\n // Flag risky packages\n if (depFinding.riskCategory && depFinding.impact === \"new\") {\n const categoryLabels: Record<RiskyCategory, string> = {\n auth: \"Authentication/Security\",\n database: \"Database/ORM\",\n native: \"Native Module\",\n payment: \"Payment Processing\",\n };\n const excerpt = `${depFinding.name}: ${depFinding.to}`;\n const riskFinding: RiskFlagFinding = {\n type: \"risk-flag\",\n kind: \"risk-flag\",\n category: \"dependencies\",\n confidence: \"medium\",\n evidence: [createEvidence(\"package.json\", excerpt)],\n risk: \"medium\",\n evidenceText: `New ${categoryLabels[depFinding.riskCategory]} package: ${depFinding.name}`,\n };\n findings.push(riskFinding);\n }\n }\n\n return findings;\n },\n};\n\n",
21
- "/**\n * Security-sensitive file change detector.\n */\n\nimport { createEvidence } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n RiskFlagFinding,\n SecurityFileFinding,\n SecurityFileReason,\n} from \"../core/types.js\";\n\n// Patterns for security-sensitive paths\nconst SECURITY_PATH_PATTERNS: Array<{\n pattern: RegExp;\n reason: SecurityFileReason;\n}> = [\n // Auth-related paths\n { pattern: /\\bauth\\b/i, reason: \"auth-path\" },\n { pattern: /\\blogin\\b/i, reason: \"auth-path\" },\n { pattern: /\\blogout\\b/i, reason: \"auth-path\" },\n { pattern: /\\bsignin\\b/i, reason: \"auth-path\" },\n { pattern: /\\bsignout\\b/i, reason: \"auth-path\" },\n { pattern: /\\bsignup\\b/i, reason: \"auth-path\" },\n { pattern: /\\bregister\\b/i, reason: \"auth-path\" },\n\n // Session-related\n { pattern: /\\bsession\\b/i, reason: \"session-path\" },\n { pattern: /\\bjwt\\b/i, reason: \"session-path\" },\n { pattern: /\\btoken\\b/i, reason: \"session-path\" },\n { pattern: /\\bcookie\\b/i, reason: \"session-path\" },\n { pattern: /\\boauth\\b/i, reason: \"session-path\" },\n\n // Permission-related\n { pattern: /\\bpermission\\b/i, reason: \"permission-path\" },\n { pattern: /\\brbac\\b/i, reason: \"permission-path\" },\n { pattern: /\\bacl\\b/i, reason: \"permission-path\" },\n { pattern: /\\brole\\b/i, reason: \"permission-path\" },\n { pattern: /\\bauthoriz/i, reason: \"permission-path\" }, // authorize, authorization\n\n // Middleware (common in auth flows)\n { pattern: /middleware\\.[jt]sx?$/i, reason: \"middleware\" },\n { pattern: /\\/middleware\\//, reason: \"middleware\" },\n\n // Guards (route protection)\n { pattern: /guard\\.[jt]sx?$/i, reason: \"guard\" },\n { pattern: /\\/guards?\\//, reason: \"guard\" },\n\n // Policies\n { pattern: /policy\\.[jt]sx?$/i, reason: \"policy\" },\n { pattern: /\\/policies\\//, reason: \"policy\" },\n];\n\n/**\n * Check if a file path is security-sensitive.\n */\nexport function isSecurityFile(path: string): SecurityFileReason | null {\n for (const { pattern, reason } of SECURITY_PATH_PATTERNS) {\n if (pattern.test(path)) {\n return reason;\n }\n }\n return null;\n}\n\n/**\n * Get a human-readable label for a security reason.\n */\nexport function getSecurityReasonLabel(reason: SecurityFileReason): string {\n const labels: Record<SecurityFileReason, string> = {\n \"auth-path\": \"Authentication\",\n \"session-path\": \"Session/Token\",\n \"permission-path\": \"Permissions/RBAC\",\n middleware: \"Middleware\",\n guard: \"Route Guard\",\n policy: \"Policy\",\n };\n return labels[reason];\n}\n\nexport const securityFilesAnalyzer: Analyzer = {\n name: \"security-files\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n const securityFiles: string[] = [];\n const reasons = new Set<SecurityFileReason>();\n\n // Check all changed files\n for (const file of changeSet.files) {\n const reason = isSecurityFile(file.path);\n if (reason) {\n securityFiles.push(file.path);\n reasons.add(reason);\n }\n }\n\n // Only emit if there are security-sensitive files\n if (securityFiles.length === 0) {\n return [];\n }\n\n // Create evidence from file paths\n const evidence = securityFiles\n .slice(0, 3)\n .map((file) => createEvidence(file, `Security file: ${file}`));\n\n const securityFinding: SecurityFileFinding = {\n type: \"security-file\",\n kind: \"security-file\",\n category: \"infra\",\n confidence: \"medium\",\n evidence,\n files: securityFiles,\n reasons: Array.from(reasons),\n };\n findings.push(securityFinding);\n\n // Add risk flag for security file changes\n const reasonLabels = Array.from(reasons)\n .map(getSecurityReasonLabel)\n .join(\", \");\n const riskFinding: RiskFlagFinding = {\n type: \"risk-flag\",\n kind: \"risk-flag\",\n category: \"infra\",\n confidence: \"medium\",\n evidence,\n risk: \"medium\",\n evidenceText: `Security-sensitive files changed (${reasonLabels}): ${securityFiles.length} file(s)`,\n };\n findings.push(riskFinding);\n\n return findings;\n },\n};\n\n",
22
- "/**\n * Batch git operations.\n */\n\nimport { execa as execaDefault } from \"execa\";\n\n/**\n * Fetch content for multiple file:ref pairs using git cat-file --batch.\n * @param items Array of { ref, path }\n * @param cwd Working directory\n * @returns Map of \"ref:path\" -> content\n */\nexport async function batchGetFileContent(\n items: Array<{ ref: string; path: string }>,\n cwd: string = process.cwd(),\n exec: typeof execaDefault = execaDefault\n): Promise<Map<string, string>> {\n if (items.length === 0) return new Map();\n\n const resultMap = new Map<string, string>();\n\n // Format input for git cat-file --batch: \"ref:path\"\n const inputs = items.map(item => `${item.ref}:${item.path}`);\n // IMPORTANT: git cat-file --batch expects a newline after the last item to process it\n const inputString = inputs.join(\"\\n\") + \"\\n\";\n\n try {\n const subprocess = exec(\"git\", [\"cat-file\", \"--batch\"], {\n cwd,\n input: inputString,\n // NOTE: We intentionally do NOT use execa's `encoding: \"buffer\"` here.\n // In Bun, execa's buffer mode can throw (attempting to write to readonly streams).\n // We parse using byte offsets by converting the UTF-8 string output to a Buffer.\n });\n\n const { stdout: stdoutRaw } = await subprocess;\n const stdout = Buffer.isBuffer(stdoutRaw)\n ? stdoutRaw\n : Buffer.from(String(stdoutRaw), \"utf-8\");\n\n let currentIndex = 0;\n for (const inputKey of inputs) {\n if (currentIndex >= stdout.length) break;\n\n // Find the header line (ends with newline)\n const newlineIndex = stdout.indexOf(\"\\n\", currentIndex);\n if (newlineIndex === -1) break;\n\n const headerBuffer = stdout.subarray(currentIndex, newlineIndex);\n const headerString = headerBuffer.toString(\"utf-8\");\n\n const [sha1, type, sizeStr] = headerString.split(\" \");\n\n if (!sha1 || !type || !sizeStr) {\n // Should not happen on standard success output\n currentIndex = newlineIndex + 1;\n continue;\n }\n\n if (type === \"missing\") {\n // \"<object> missing\"\n currentIndex = newlineIndex + 1;\n continue;\n }\n\n const size = parseInt(sizeStr, 10);\n const contentStart = newlineIndex + 1;\n const contentEnd = contentStart + size;\n\n // Extract content based on byte offsets\n const contentBuffer = stdout.subarray(contentStart, contentEnd);\n resultMap.set(inputKey, contentBuffer.toString(\"utf-8\"));\n\n // Advance index: content + newline\n currentIndex = contentEnd + 1;\n }\n\n } catch (error) {\n console.warn(\"Failed to batch fetch files:\", error);\n }\n\n return resultMap;\n}\n",
23
- "/**\n * React Router route detector - detects changes in React Router routes.\n * Supports both JSX routes (<Route>) and data routers (createBrowserRouter).\n */\n\nimport { parse } from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\nimport * as t from \"@babel/types\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n RouteChangeFinding,\n} from \"../core/types.js\";\nimport { createEvidence } from \"../core/evidence.js\";\nimport { batchGetFileContent as defaultBatchGetFileContent } from \"../git/batch.js\";\n\n// Allow injection for testing\nexport const dependencies = {\n batchGetFileContent: defaultBatchGetFileContent,\n};\n\n// ============================================================================\n// Route Extraction\n// ============================================================================\n\ninterface ExtractedRoute {\n path: string;\n file: string;\n}\n\nfunction isCandidateFile(path: string): boolean {\n // Check extension\n const validExtensions = [\".ts\", \".tsx\", \".js\", \".jsx\"];\n if (!validExtensions.some((ext) => path.endsWith(ext))) {\n return false;\n }\n\n // We previously checked diffContent for react-router keywords,\n // but that causes us to miss modifications where imports aren't touched.\n // We accept the cost of checking all JS/TS files in exchange for correctness.\n return true;\n}\n\n/**\n * Normalize route path.\n * - Collapse multiple slashes\n * - Remove trailing slash unless path is exactly \"/\"\n */\nexport function normalizePath(path: string): string {\n // Collapse multiple slashes\n let normalized = path.replace(/\\/+/g, \"/\");\n\n // Remove trailing slash unless it's the root path\n if (normalized !== \"/\" && normalized.endsWith(\"/\")) {\n normalized = normalized.slice(0, -1);\n }\n\n return normalized;\n}\n\n/**\n * Join parent and child paths.\n */\nexport function joinPaths(parent: string, child: string): string {\n // If child starts with \"/\", treat as absolute\n if (child.startsWith(\"/\")) {\n return normalizePath(child);\n }\n\n // Join with \"/\"\n const joined = parent === \"/\" ? `/${child}` : `${parent}/${child}`;\n return normalizePath(joined);\n}\n\n/**\n * Extract routes from JSX <Route> elements.\n */\nexport function extractJsxRoutes(\n ast: t.File,\n filePath: string,\n parentPath = \"/\"\n): ExtractedRoute[] {\n const routes: ExtractedRoute[] = [];\n\n traverse(ast, {\n JSXElement(path) {\n const openingElement = path.node.openingElement;\n const name = openingElement.name;\n\n // Check if this is a <Route> element\n if (t.isJSXIdentifier(name) && name.name === \"Route\") {\n let routePath: string | null = null;\n let isIndex = false;\n let children: t.JSXElement[] = [];\n\n // Extract path attribute\n for (const attr of openingElement.attributes) {\n if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {\n if (attr.name.name === \"path\" && attr.value) {\n if (t.isStringLiteral(attr.value)) {\n routePath = attr.value.value;\n } else if (\n t.isJSXExpressionContainer(attr.value) &&\n t.isStringLiteral(attr.value.expression)\n ) {\n routePath = attr.value.expression.value;\n }\n } else if (attr.name.name === \"index\") {\n isIndex = true;\n }\n }\n }\n\n // Handle index routes\n if (isIndex) {\n routes.push({\n path: normalizePath(parentPath),\n file: filePath,\n });\n } else if (routePath) {\n const fullPath = joinPaths(parentPath, routePath);\n routes.push({\n path: fullPath,\n file: filePath,\n });\n\n // Extract nested routes\n for (const child of path.node.children) {\n if (t.isJSXElement(child)) {\n children.push(child);\n }\n }\n\n // Process children with current route as parent\n for (const child of children) {\n const childAst: t.File = t.file(t.program([t.expressionStatement(child)]));\n const childRoutes = extractJsxRoutes(childAst, filePath, fullPath);\n routes.push(...childRoutes);\n }\n }\n\n // We've manually processed this Route's children; avoid traversing them again\n path.skip();\n }\n },\n });\n\n return routes;\n}\n\n/**\n * Extract routes from data router configuration.\n */\nexport function extractDataRoutes(\n ast: t.File,\n filePath: string,\n parentPath = \"/\"\n): ExtractedRoute[] {\n const routes: ExtractedRoute[] = [];\n const routeConfigs = new Map<string, t.Expression>();\n\n // First pass: collect route config variables\n traverse(ast, {\n VariableDeclarator(path) {\n if (\n t.isIdentifier(path.node.id) &&\n (t.isArrayExpression(path.node.init) ||\n t.isObjectExpression(path.node.init))\n ) {\n routeConfigs.set(path.node.id.name, path.node.init);\n }\n },\n });\n\n // Second pass: find createBrowserRouter/createHashRouter/createMemoryRouter calls\n traverse(ast, {\n CallExpression(path) {\n const callee = path.node.callee;\n if (\n t.isIdentifier(callee) &&\n (callee.name === \"createBrowserRouter\" ||\n callee.name === \"createHashRouter\" ||\n callee.name === \"createMemoryRouter\")\n ) {\n const firstArg = path.node.arguments[0];\n let routesArray: t.ArrayExpression | null = null;\n\n // Check if first argument is an array literal\n if (t.isArrayExpression(firstArg)) {\n routesArray = firstArg;\n }\n // Check if first argument is an identifier referencing a routes variable\n else if (t.isIdentifier(firstArg)) {\n const config = routeConfigs.get(firstArg.name);\n if (config && t.isArrayExpression(config)) {\n routesArray = config;\n }\n }\n\n if (routesArray) {\n const extracted = extractRoutesFromArray(\n routesArray,\n filePath,\n parentPath\n );\n routes.push(...extracted);\n }\n }\n },\n });\n\n return routes;\n}\n\n/**\n * Extract routes from route configuration array.\n */\nfunction extractRoutesFromArray(\n array: t.ArrayExpression,\n filePath: string,\n parentPath = \"/\"\n): ExtractedRoute[] {\n const routes: ExtractedRoute[] = [];\n\n for (const element of array.elements) {\n if (t.isObjectExpression(element)) {\n const routeConfig = extractRouteConfig(element);\n \n if (routeConfig.index) {\n routes.push({\n path: normalizePath(parentPath),\n file: filePath,\n });\n } else if (routeConfig.path) {\n const fullPath = joinPaths(parentPath, routeConfig.path);\n routes.push({\n path: fullPath,\n file: filePath,\n });\n\n // Process children\n if (routeConfig.children) {\n const childRoutes = extractRoutesFromArray(\n routeConfig.children,\n filePath,\n fullPath\n );\n routes.push(...childRoutes);\n }\n }\n }\n }\n\n return routes;\n}\n\n/**\n * Extract route configuration from an object expression.\n */\nfunction extractRouteConfig(obj: t.ObjectExpression): {\n path?: string;\n index?: boolean;\n children?: t.ArrayExpression;\n} {\n const config: {\n path?: string;\n index?: boolean;\n children?: t.ArrayExpression;\n } = {};\n\n for (const prop of obj.properties) {\n if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) {\n if (prop.key.name === \"path\" && t.isStringLiteral(prop.value)) {\n config.path = prop.value.value;\n } else if (prop.key.name === \"index\") {\n if (t.isBooleanLiteral(prop.value) && prop.value.value) {\n config.index = true;\n }\n } else if (prop.key.name === \"children\" && t.isArrayExpression(prop.value)) {\n config.children = prop.value;\n }\n }\n }\n\n return config;\n}\n\n/**\n * Extract all routes from file content.\n */\nexport function extractRoutesFromContent(\n content: string,\n filePath: string\n): ExtractedRoute[] {\n try {\n const ast = parse(content, {\n sourceType: \"module\",\n plugins: [\"typescript\", \"jsx\"],\n });\n\n const jsxRoutes = extractJsxRoutes(ast, filePath);\n const dataRoutes = extractDataRoutes(ast, filePath);\n\n return [...jsxRoutes, ...dataRoutes];\n } catch (error) {\n // Parsing failed, skip silently\n return [];\n }\n}\n\n// ============================================================================\n// Analyzer\n// ============================================================================\n\nexport const reactRouterRoutesAnalyzer: Analyzer = {\n name: \"react-router-routes\",\n\n async analyze(changeSet: ChangeSet): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n // Select candidate files\n const candidateFiles = changeSet.files.filter((file) => {\n // We assume isCandidateFile logic is correct\n return isCandidateFile(file.path);\n });\n\n if (candidateFiles.length === 0) return [];\n\n // Prepare batch request\n const batchRequest: Array<{ ref: string; path: string }> = [];\n for (const file of candidateFiles) {\n batchRequest.push({ ref: changeSet.base, path: file.path });\n batchRequest.push({ ref: changeSet.head, path: file.path });\n }\n\n // Determine CWD (implicitly handled if batchGetFileContent uses process.cwd(),\n // but ideally ChangeSet should provide it. Since we don't have it in ChangeSet,\n // we assume process.cwd() is correct as per other analyzers).\n // Note: In benchmarks we chdir to the repo.\n const contentMap = await dependencies.batchGetFileContent(batchRequest);\n\n // Extract routes from base and head for each file\n for (const file of candidateFiles) {\n const baseKey = `${changeSet.base}:${file.path}`;\n const headKey = `${changeSet.head}:${file.path}`;\n\n const baseContent = contentMap.get(baseKey);\n const headContent = contentMap.get(headKey);\n\n // Heuristic: If content doesn't contain \"react-router\", \"Route\", etc., skip AST parsing\n // This saves time on files that are .tsx but not routes.\n const hasRouterKeywords = (content: string) =>\n content.includes(\"react-router\") ||\n content.includes(\"<Route\") ||\n content.includes(\"createBrowserRouter\") ||\n content.includes(\"createHashRouter\") ||\n content.includes(\"createMemoryRouter\");\n\n if (baseContent && !hasRouterKeywords(baseContent) && headContent && !hasRouterKeywords(headContent)) {\n continue;\n }\n\n const baseRoutes = baseContent\n ? extractRoutesFromContent(baseContent, file.path)\n : [];\n const headRoutes = headContent\n ? extractRoutesFromContent(headContent, file.path)\n : [];\n\n // Create sets for comparison\n const basePaths = new Set(baseRoutes.map((r) => r.path));\n const headPaths = new Set(headRoutes.map((r) => r.path));\n\n // Find added routes\n for (const route of headRoutes) {\n if (!basePaths.has(route.path)) {\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `Route: ${route.path}`)],\n routeId: route.path,\n file: file.path,\n change: \"added\",\n routeType: \"page\",\n };\n findings.push(finding);\n }\n }\n\n // Find deleted routes\n for (const route of baseRoutes) {\n if (!headPaths.has(route.path)) {\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `Route: ${route.path}`)],\n routeId: route.path,\n file: file.path,\n change: \"deleted\",\n routeType: \"page\",\n };\n findings.push(finding);\n }\n }\n }\n\n // Deduplicate findings by routeId + change + file\n const uniqueFindings = Array.from(\n new Map(\n findings.map((f) => {\n const key = `${(f as RouteChangeFinding).routeId}-${\n (f as RouteChangeFinding).change\n }-${(f as RouteChangeFinding).file}`;\n return [key, f];\n })\n ).values()\n );\n\n // Sort by routeId for deterministic output\n return uniqueFindings.sort((a, b) => {\n const aRoute = (a as RouteChangeFinding).routeId;\n const bRoute = (b as RouteChangeFinding).routeId;\n return aRoute.localeCompare(bRoute);\n });\n },\n};\n",
24
- "/**\n * Test Parity Analyzer.\n * Checks if modified source files have corresponding test files.\n *\n * This analyzer is opt-in only - it must be explicitly enabled via CLI flag\n * as it requires git file system operations which can be resource-intensive.\n */\n\nimport path from \"node:path\";\nimport { execa as execaDefault } from \"execa\";\nimport { createEvidence } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Confidence,\n Finding,\n TestParityConfig,\n TestParityViolationFinding,\n} from \"../core/types.js\";\nimport { isTestFile } from \"./vitest.js\";\n\n// ============================================================================\n// Default Configuration\n// ============================================================================\n\n/** Default patterns for files to exclude from parity check */\nconst DEFAULT_EXCLUDED_PATTERNS: RegExp[] = [\n /\\.d\\.ts$/, // Type definitions\n /\\.config\\.(ts|js|mts|mjs|cjs)$/, // Config files\n /index\\.(ts|js|tsx|jsx)$/, // Barrel files (often don't need direct tests)\n /^docs\\//, // Documentation\n /^tests\\//, // Tests themselves\n /^test\\//, // Alternative test directory\n /^__tests__\\//, // Jest-style test directory\n /^scripts\\//, // Build scripts\n /^dist\\//, // Build artifacts\n /^build\\//, // Build artifacts\n /^\\./, // Dotfiles and directories\n /types?\\.(ts|js)$/, // Type-only files\n /constants?\\.(ts|js)$/, // Constants files (often just exports)\n];\n\n/** Default test file extensions to search for */\nconst DEFAULT_TEST_PATTERNS = [\".test.ts\", \".spec.ts\", \".test.js\", \".spec.js\", \".test.tsx\", \".spec.tsx\"];\n\n/** Default test directories */\nconst DEFAULT_TEST_DIRECTORIES = [\"tests\", \"test\", \"__tests__\", \"spec\"];\n\n/** Default source directories */\nconst DEFAULT_SOURCE_DIRECTORIES = [\"src\", \"lib\", \"app\"];\n\n// ============================================================================\n// Cache Management\n// ============================================================================\n\n/** Cache for files per directory (more granular than entire repo) */\nconst directoryFileCache = new Map<string, Set<string>>();\n\n/** Full file list cache (fallback) */\nlet cachedFullFileList: Set<string> | null = null;\n\n/**\n * Reset all caches - for testing purposes.\n */\nexport function _resetCacheForTesting(): void {\n directoryFileCache.clear();\n cachedFullFileList = null;\n}\n\n// ============================================================================\n// File Discovery (Optimized)\n// ============================================================================\n\n/**\n * Get files in specific directories using git ls-files.\n * More efficient than loading entire repo for targeted lookups.\n */\nasync function getFilesInDirectories(\n directories: string[],\n exec: typeof execaDefault\n): Promise<Set<string>> {\n // Check cache first\n const cachedResults = new Set<string>();\n const uncachedDirs: string[] = [];\n\n for (const dir of directories) {\n const cached = directoryFileCache.get(dir);\n if (cached) {\n for (const file of cached) {\n cachedResults.add(file);\n }\n } else {\n uncachedDirs.push(dir);\n }\n }\n\n // If all directories are cached, return combined results\n if (uncachedDirs.length === 0) {\n return cachedResults;\n }\n\n try {\n // Query git for uncached directories\n const { stdout } = await exec(\n \"git\",\n [\"ls-files\", \"--cached\", \"--others\", \"--exclude-standard\", \"--\", ...uncachedDirs],\n { reject: false }\n );\n\n const files = stdout.split(\"\\n\").filter(Boolean);\n\n // Cache per directory\n for (const dir of uncachedDirs) {\n const dirFiles = new Set<string>();\n for (const file of files) {\n if (file.startsWith(dir + \"/\") || file.startsWith(dir + path.sep)) {\n dirFiles.add(file);\n cachedResults.add(file);\n }\n }\n directoryFileCache.set(dir, dirFiles);\n }\n\n // Also add root-level files if querying root\n for (const file of files) {\n if (!file.includes(\"/\") && !file.includes(path.sep)) {\n cachedResults.add(file);\n }\n }\n\n return cachedResults;\n } catch {\n // Fallback to full file list if targeted query fails\n return getAllFiles(exec);\n }\n}\n\n/**\n * Get all files in the project using git ls-files.\n * Returns a Set for O(1) lookups.\n * This is the fallback when targeted queries aren't possible.\n */\nasync function getAllFiles(exec: typeof execaDefault): Promise<Set<string>> {\n if (cachedFullFileList) return cachedFullFileList;\n\n try {\n const { stdout } = await exec(\n \"git\",\n [\"ls-files\", \"--cached\", \"--others\", \"--exclude-standard\"],\n { reject: false }\n );\n cachedFullFileList = new Set(stdout.split(\"\\n\").filter(Boolean));\n return cachedFullFileList;\n } catch {\n return new Set();\n }\n}\n\n// ============================================================================\n// Analysis Helpers\n// ============================================================================\n\n/**\n * Merge user config with defaults.\n */\nfunction mergeConfig(config?: TestParityConfig): Required<Omit<TestParityConfig, \"excludePatterns\">> & { excludePatterns: RegExp[] } {\n return {\n testPatterns: config?.testPatterns ?? DEFAULT_TEST_PATTERNS,\n excludePatterns: [...DEFAULT_EXCLUDED_PATTERNS, ...(config?.excludePatterns ?? [])],\n testDirectories: config?.testDirectories ?? DEFAULT_TEST_DIRECTORIES,\n sourceDirectories: config?.sourceDirectories ?? DEFAULT_SOURCE_DIRECTORIES,\n };\n}\n\n/**\n * Check if a file should be checked for test parity.\n */\nfunction shouldCheckParity(filePath: string, excludePatterns: RegExp[]): boolean {\n if (isTestFile(filePath)) return false;\n if (excludePatterns.some((p) => p.test(filePath))) return false;\n // Only check typescript/javascript source files\n return /\\.(ts|js|tsx|jsx|mts|mjs)$/.test(filePath);\n}\n\n/**\n * Compute confidence based on file characteristics.\n */\nfunction computeConfidence(filePath: string, diff?: { additions: number; deletions: number }): Confidence {\n // Lower confidence for utility/helper files\n if (/utils?|helpers?|lib|shared/i.test(filePath)) {\n return \"medium\";\n }\n\n // Lower confidence for small files (if we have diff info)\n if (diff && diff.additions + diff.deletions < 10) {\n return \"low\";\n }\n\n // Higher confidence for core business logic\n if (/services?|controllers?|handlers?|api|routes|commands?|analyzers?/i.test(filePath)) {\n return \"high\";\n }\n\n // Default to medium for most cases\n return \"medium\";\n}\n\n/**\n * Generate all potential test file locations for a source file.\n */\nfunction generateTestLocations(\n sourcePath: string,\n testPatterns: string[],\n testDirectories: string[],\n sourceDirectories: string[]\n): string[] {\n const locations: string[] = [];\n const ext = path.extname(sourcePath);\n const baseName = path.basename(sourcePath, ext);\n const dirName = path.dirname(sourcePath);\n\n // 1. Colocation: src/foo.ts -> src/foo.test.ts\n for (const testExt of testPatterns) {\n locations.push(path.join(dirName, `${baseName}${testExt}`));\n }\n\n // 2. Test directory mappings\n let relativePath = sourcePath;\n for (const srcDir of sourceDirectories) {\n if (sourcePath.startsWith(`${srcDir}/`)) {\n relativePath = sourcePath.slice(srcDir.length + 1);\n break;\n }\n }\n\n for (const testDir of testDirectories) {\n for (const testExt of testPatterns) {\n // Mirror: src/utils/math.ts -> tests/utils/math.test.ts\n locations.push(path.join(testDir, path.dirname(relativePath), `${baseName}${testExt}`));\n\n // Flat: src/utils/math.ts -> tests/math.test.ts\n locations.push(path.join(testDir, `${baseName}${testExt}`));\n\n // Mirror with source dir: src/utils/math.ts -> tests/src/utils/math.test.ts\n locations.push(path.join(testDir, dirName, `${baseName}${testExt}`));\n }\n }\n\n // 3. Hyphenated patterns: various naming conventions\n const pathParts = relativePath.split(path.sep);\n if (pathParts.length > 1) {\n const parentDir = pathParts[pathParts.length - 2];\n // Pattern A: parent-basename (e.g., src/commands/facts/builder.ts -> tests/facts-builder.test.ts)\n const hyphenatedA = `${parentDir}-${baseName}`;\n // Pattern B: basename-parent (e.g., src/render/markdown.ts -> tests/markdown-render.test.ts)\n const hyphenatedB = `${baseName}-${parentDir}`;\n \n for (const testDir of testDirectories) {\n for (const testExt of testPatterns) {\n locations.push(path.join(testDir, `${hyphenatedA}${testExt}`));\n locations.push(path.join(testDir, `${hyphenatedB}${testExt}`));\n }\n }\n }\n\n // Deduplicate and normalize\n return [...new Set(locations.map((loc) => path.normalize(loc)))];\n}\n\n/**\n * Find an existing test file for a source file.\n */\nasync function findTestFile(\n sourcePath: string,\n testPatterns: string[],\n testDirectories: string[],\n sourceDirectories: string[],\n allFiles: Set<string>\n): Promise<string | null> {\n const locations = generateTestLocations(sourcePath, testPatterns, testDirectories, sourceDirectories);\n\n for (const location of locations) {\n if (allFiles.has(location)) {\n return location;\n }\n }\n\n return null;\n}\n\n/**\n * Check if a test file for the source is being added in the current changeset.\n */\nfunction hasNewTestInChangeset(sourcePath: string, changeSet: ChangeSet): boolean {\n const baseName = path.basename(sourcePath, path.extname(sourcePath));\n\n return changeSet.files.some(\n (f) => isTestFile(f.path) && f.path.includes(baseName) && f.status !== \"deleted\"\n );\n}\n\n// ============================================================================\n// Analyzer Factory\n// ============================================================================\n\n/**\n * Create a test parity analyzer with optional configuration.\n */\nexport function createTestParityAnalyzer(\n config?: TestParityConfig,\n options?: { exec?: typeof execaDefault }\n): Analyzer {\n const mergedConfig = mergeConfig(config);\n const exec = options?.exec ?? execaDefault;\n\n return {\n name: \"test-parity\",\n\n async analyze(changeSet: ChangeSet): Promise<Finding[]> {\n const findings: TestParityViolationFinding[] = [];\n\n // Collect directories we need to check\n const dirsToCheck = new Set<string>();\n for (const file of changeSet.files) {\n if (file.status === \"deleted\") continue;\n if (!shouldCheckParity(file.path, mergedConfig.excludePatterns)) continue;\n\n // Add source directory\n const dirName = path.dirname(file.path);\n if (dirName && dirName !== \".\") {\n dirsToCheck.add(dirName.split(path.sep)[0]); // Top-level dir\n }\n }\n\n // Add test directories to check\n for (const testDir of mergedConfig.testDirectories) {\n dirsToCheck.add(testDir);\n }\n\n // Get files from relevant directories only (optimized)\n const allFiles = await getFilesInDirectories([...dirsToCheck], exec);\n\n // Also ensure we have changeset files in our set (they may not be committed yet)\n for (const file of changeSet.files) {\n if (file.status !== \"deleted\") {\n allFiles.add(file.path);\n }\n }\n\n // Analyze each file\n for (const file of changeSet.files) {\n if (file.status === \"deleted\") continue;\n if (!shouldCheckParity(file.path, mergedConfig.excludePatterns)) continue;\n\n // Check for existing test file\n const testFile = await findTestFile(\n file.path,\n mergedConfig.testPatterns,\n mergedConfig.testDirectories,\n mergedConfig.sourceDirectories,\n allFiles\n );\n\n if (testFile) {\n // Test exists, no violation\n continue;\n }\n\n // Check if a new test is being added in the changeset\n if (hasNewTestInChangeset(file.path, changeSet)) {\n continue;\n }\n\n // Get diff info for confidence scoring\n const fileDiff = changeSet.diffs.find((d) => d.path === file.path);\n const diffInfo = fileDiff\n ? {\n additions: fileDiff.hunks.reduce((sum, h) => sum + h.additions.length, 0),\n deletions: fileDiff.hunks.reduce((sum, h) => sum + h.deletions.length, 0),\n }\n : undefined;\n\n const confidence = computeConfidence(file.path, diffInfo);\n const expectedLocations = generateTestLocations(\n file.path,\n mergedConfig.testPatterns,\n mergedConfig.testDirectories,\n mergedConfig.sourceDirectories\n ).slice(0, 5); // Limit to top 5 for readability\n\n const finding: TestParityViolationFinding = {\n type: \"test-parity-violation\",\n kind: \"test-parity-violation\",\n category: \"tests\",\n confidence,\n evidence: [\n createEvidence(file.path, `Source file modified without corresponding test: ${file.path}`),\n ],\n sourceFile: file.path,\n expectedTestLocations: expectedLocations,\n };\n\n findings.push(finding);\n }\n\n return findings;\n },\n };\n}\n\n/**\n * Default test parity analyzer instance (with default config).\n * Note: This analyzer is NOT included in any profile by default.\n * It must be explicitly enabled via CLI flags.\n */\nexport const testParityAnalyzer: Analyzer = createTestParityAnalyzer();\n",
25
- "/**\n * Impact Analyzer.\n * Finds files that import the modified files (blast radius).\n */\n\nimport path from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport { execa as execaDefault } from \"execa\";\nimport { createEvidence } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n ImpactAnalysisFinding,\n} from \"../core/types.js\";\n\n// Files to exclude from impact scanning (both as source and target)\nconst EXCLUDE_PATTERNS = [\n /node_modules/,\n /\\.d\\.ts$/,\n /^dist\\//,\n /^build\\//,\n /^\\.git\\//,\n];\n\n// File extensions that support import analysis (code files only)\n// Excludes docs, config, and other non-importable files\nconst ANALYZABLE_EXTENSIONS = new Set([\n \".js\",\n \".jsx\",\n \".ts\",\n \".tsx\",\n \".mjs\",\n \".cjs\",\n \".mts\",\n \".cts\",\n \".vue\",\n \".svelte\",\n]);\n\n// Pattern to match code files (for filtering dependents)\n// Only these files can have actual imports, excludes docs/config/lockfiles\nconst CODE_FILE_PATTERN = /\\.(js|jsx|ts|tsx|mjs|cjs|mts|cts|vue|svelte)$/i;\n\n/**\n * Batch search for dependents using git grep.\n */\nasync function findDependentsBatch(\n targets: Array<{ path: string; baseName: string }>,\n cwd: string = process.cwd(),\n exec: typeof execaDefault = execaDefault\n): Promise<Map<string, string[]>> {\n const results = new Map<string, string[]>();\n targets.forEach((t) => results.set(t.path, []));\n\n if (targets.length === 0) return results;\n\n // Group paths by basename to avoid duplicate searches\n const baseNameToPaths = new Map<string, string[]>();\n for (const t of targets) {\n if (!baseNameToPaths.has(t.baseName)) {\n baseNameToPaths.set(t.baseName, []);\n }\n baseNameToPaths.get(t.baseName)!.push(t.path);\n }\n\n const uniqueBaseNames = Array.from(baseNameToPaths.keys());\n\n // Chunking to avoid ARG_MAX issues\n const CHUNK_SIZE = 50;\n for (let i = 0; i < uniqueBaseNames.length; i += CHUNK_SIZE) {\n const chunk = uniqueBaseNames.slice(i, i + CHUNK_SIZE);\n\n // git grep -I -F --null -e name1 -e name2 ...\n // -I: ignore binary files\n // -F: fixed strings\n // --null: output \\0 after filename\n const args = [\"grep\", \"-I\", \"-F\", \"--null\"];\n for (const name of chunk) {\n args.push(\"-e\");\n args.push(name);\n }\n\n try {\n const { stdout } = await exec(\"git\", args, {\n cwd,\n maxBuffer: 1024 * 1024 * 20, // Increase buffer for large outputs\n reject: false // git grep returns 1 if no matches found\n });\n\n if (!stdout) continue;\n\n const lines = stdout.split(\"\\n\");\n for (const line of lines) {\n if (!line) continue;\n\n // Parse: filename\\0content\n const nullIndex = line.indexOf(\"\\0\");\n if (nullIndex === -1) continue;\n\n const file = line.slice(0, nullIndex);\n const content = line.slice(nullIndex + 1);\n\n // Skip excluded files\n if (EXCLUDE_PATTERNS.some(p => p.test(file))) continue;\n \n // Skip non-code files (docs, config, lockfiles, etc.)\n // These may contain filename text but aren't actual imports\n if (!CODE_FILE_PATTERN.test(file)) continue;\n\n // Check which basename(s) matched in this line\n for (const baseName of chunk) {\n if (content.includes(baseName)) {\n const sourcePaths = baseNameToPaths.get(baseName) || [];\n for (const sourcePath of sourcePaths) {\n // Avoid self-reference\n if (sourcePath !== file) {\n const deps = results.get(sourcePath)!;\n if (!deps.includes(file)) {\n deps.push(file);\n }\n }\n }\n }\n }\n }\n } catch (e) {\n // Should ignore errors\n }\n }\n\n return results;\n}\n\n/**\n * Analyze a dependent file to extract detailed usage information.\n */\nasync function analyzeDependency(\n dependentPath: string,\n sourcePath: string,\n cwd: string = process.cwd(),\n readFile: typeof fs.readFile = fs.readFile\n): Promise<{ importedSymbols: string[]; usageContext: string } | null> {\n try {\n const content = await readFile(path.join(cwd, dependentPath), \"utf-8\");\n const sourceBaseName = path.basename(sourcePath, path.extname(sourcePath));\n const lines = content.split(\"\\n\");\n\n const importedSymbols: string[] = [];\n let usageContext = \"\";\n\n // Regex to find import statement\n // Matches: import { A, B } from './source' or import X from './source'\n // This is heuristic and won't cover 100% of cases (e.g. multiline imports might need smarter parsing)\n // But we iterate lines to find the one containing the source name.\n\n for (const line of lines) {\n if (line.includes(sourceBaseName) && (line.trim().startsWith(\"import\") || line.trim().startsWith(\"export\"))) {\n usageContext = usageContext ? `${usageContext}\\n${line.trim()}` : line.trim();\n\n // Try to extract symbols\n // Case 1: Named imports: import { A, B } ...\n const namedMatch = line.match(/\\{([^}]+)\\}/);\n if (namedMatch) {\n const symbols = namedMatch[1].split(\",\").map(s => {\n const part = s.trim().split(\" as \")[0].trim(); // Handle 'as' aliases\n return part.replace(/^type\\s+/, \"\"); // Handle 'type' keyword\n });\n importedSymbols.push(...symbols);\n }\n\n // Case 2: Default or namespace import: import X ... / import * as X ...\n // Simplistic check: if no curly braces and follows 'import'\n if (!namedMatch && line.trim().startsWith(\"import\")) {\n const parts = line.split(\"from\");\n if (parts.length > 1) {\n const preFrom = parts[0].replace(\"import\", \"\").trim();\n if (preFrom) {\n // Handle namespace imports: import * as Utils from \"./utils\"\n const namespaceMatch = preFrom.match(/\\*\\s+as\\s+([A-Za-z0-9_$]+)/);\n if (namespaceMatch) {\n importedSymbols.push(namespaceMatch[1].trim());\n } else if (!preFrom.includes(\"{\") && !preFrom.includes(\"*\")) {\n // Handle default imports: import X from \"./x\"\n importedSymbols.push(preFrom.split(\" as \")[0].trim());\n }\n }\n } else {\n // Note: lines like `import \"./utils\";` or `import \"./styles.css\";` are side-effect-only imports.\n // In these cases (and if we otherwise fail to parse), we intentionally leave `importedSymbols` empty\n // to distinguish \"no named symbols, just side effects\" from the presence of explicit imported identifiers.\n }\n }\n\n // Removed break to capture multiple imports\n }\n }\n\n // Note: We intentionally don't fall back to any matching line.\n // If no import/export statement was found, usageContext stays empty.\n // This avoids showing garbage like random doc text or config values.\n\n return {\n importedSymbols,\n usageContext,\n };\n\n } catch (error) {\n // If file read fails (e.g. deleted), return null\n return null;\n }\n}\n\nexport function createImpactAnalyzer(options?: {\n cwd?: string;\n exec?: typeof execaDefault;\n readFile?: typeof fs.readFile;\n}): Analyzer {\n const cwd = options?.cwd ?? process.cwd();\n const exec = options?.exec ?? execaDefault;\n const readFile = options?.readFile ?? fs.readFile;\n\n return {\n name: \"impact\",\n\n async analyze(changeSet: ChangeSet): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n // Filter relevant source files - only code files that can be imported\n const sourceFiles = changeSet.files.filter(f => {\n // Only modified or renamed files\n if (f.status !== \"modified\" && f.status !== \"renamed\") return false;\n // Skip excluded paths\n if (EXCLUDE_PATTERNS.some(p => p.test(f.path))) return false;\n // Only analyze files with importable extensions (skip docs, config, etc.)\n const ext = path.extname(f.path).toLowerCase();\n return ANALYZABLE_EXTENSIONS.has(ext);\n });\n\n if (sourceFiles.length === 0) return [];\n\n // Prepare targets for batch search\n const targets = sourceFiles.map(source => {\n const ext = path.extname(source.path);\n const baseName = path.basename(source.path, ext);\n return { path: source.path, baseName };\n });\n\n // Run batch search\n const dependentsMap = await findDependentsBatch(targets, cwd, exec);\n\n for (const source of sourceFiles) {\n const dependents = dependentsMap.get(source.path) || [];\n\n if (dependents.length > 0) {\n // Detailed analysis for each dependent\n const impactedFilesInfo: Array<{ file: string; details: any }> = [];\n\n for (const dep of dependents) {\n // We analyze only the first few dependents deeply to avoid perf hit on massive impact\n // Or maybe we analyze all? Let's analyze all for now, assuming typical impact < 100 files.\n // If massive, we might want to limit.\n if (impactedFilesInfo.length < 20) {\n const details = await analyzeDependency(dep, source.path, cwd, readFile);\n if (details) {\n impactedFilesInfo.push({ file: dep, details });\n } else {\n impactedFilesInfo.push({ file: dep, details: { importedSymbols: [], usageContext: \"\" } });\n }\n } else {\n impactedFilesInfo.push({ file: dep, details: { importedSymbols: [], usageContext: \"\" } });\n }\n }\n\n // Determine blast radius label for more informative evidence\n const blastLabel = dependents.length > 10 ? \"High\" : dependents.length > 3 ? \"Medium\" : \"Low\";\n \n const evidence = [\n createEvidence(source.path, `${blastLabel} blast radius: ${dependents.length} file(s) depend on this module`),\n ...impactedFilesInfo.slice(0, 5).map(info => {\n // More descriptive evidence showing what symbols are imported\n const text = info.details.importedSymbols?.length > 0\n ? `Imports: ${info.details.importedSymbols.slice(0, 3).join(\", \")}${info.details.importedSymbols.length > 3 ? ` (+${info.details.importedSymbols.length - 3} more)` : \"\"}`\n : `Imports module`;\n return createEvidence(info.file, text);\n })\n ];\n\n // Collect all symbols for the finding summary\n const allSymbols = new Set<string>();\n impactedFilesInfo.forEach(i => i.details.importedSymbols?.forEach((s: string) => allSymbols.add(s)));\n\n findings.push({\n type: \"impact-analysis\",\n kind: \"impact-analysis\",\n category: \"impact\",\n confidence: \"medium\",\n evidence: evidence,\n sourceFile: source.path,\n affectedFiles: dependents,\n importedSymbols: Array.from(allSymbols),\n usageContext: impactedFilesInfo[0]?.details.usageContext, // Example context from first file\n blastRadius: dependents.length > 10 ? \"high\" : dependents.length > 3 ? \"medium\" : \"low\",\n tags: [\"impact\", \"dependency\"]\n } as ImpactAnalysisFinding);\n }\n }\n\n return findings;\n },\n };\n}\n\nexport const impactAnalyzer: Analyzer = createImpactAnalyzer();\n",
26
- "/**\n * Large diff (churn) analyzer.\n */\n\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n LargeDiffFinding,\n} from \"../core/types.js\";\n\n/**\n * Analyze large diffs to detect high churn.\n */\nexport const analyzeLargeDiff: Analyzer = {\n name: \"large-diff\",\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: LargeDiffFinding[] = [];\n\n const filesChanged = changeSet.files.length;\n let linesChanged = 0;\n\n for (const diff of changeSet.diffs) {\n for (const hunk of diff.hunks) {\n linesChanged += hunk.additions.length + hunk.deletions.length;\n }\n }\n\n // Trigger if more than 30 files or 1000 lines changed\n if (filesChanged > 30 || linesChanged > 1000) {\n findings.push({\n type: \"large-diff\",\n kind: \"large-diff\",\n category: \"unknown\", // No specific category for churn/quality metrics\n confidence: \"high\",\n evidence: [],\n filesChanged,\n linesChanged,\n });\n }\n\n return findings;\n },\n};\n",
27
- "/**\n * Lockfile analyzer - detects lockfile/manifest mismatches.\n */\n\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n LockfileFinding,\n} from \"../core/types.js\";\n\n/**\n * Check if a file is package.json.\n */\nfunction isPackageJson(path: string): boolean {\n return path === \"package.json\";\n}\n\n/**\n * Check if a file is a lockfile.\n */\nfunction isLockfile(path: string): boolean {\n return (\n path === \"package-lock.json\" ||\n path === \"yarn.lock\" ||\n path === \"pnpm-lock.yaml\" ||\n path === \"bun.lockb\" ||\n path === \"bun.lock\"\n );\n}\n\n/**\n * Analyze lockfile changes.\n */\nexport const analyzeLockfiles: Analyzer = {\n name: \"lockfiles\",\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: LockfileFinding[] = [];\n\n const manifestChanged = changeSet.files.some(f => isPackageJson(f.path));\n const lockfileChanged = changeSet.files.some(f => isLockfile(f.path));\n\n // Flag if lockfile changed without manifest or vice versa\n if ((manifestChanged && !lockfileChanged) || (!manifestChanged && lockfileChanged)) {\n findings.push({\n type: \"lockfile-mismatch\",\n kind: \"lockfile-mismatch\",\n category: \"dependencies\",\n confidence: \"high\",\n evidence: [],\n manifestChanged,\n lockfileChanged,\n });\n }\n\n return findings;\n },\n};\n",
28
- "/**\n * Test gap analyzer - detects when prod code changes without test changes.\n */\n\nimport { createEvidence } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n TestGapFinding,\n} from \"../core/types.js\";\n\n/**\n * Check if a file is a test file.\n */\nfunction isTestFile(path: string): boolean {\n return (\n path.includes(\"/tests/\") ||\n path.includes(\"/__tests__/\") ||\n path.includes(\".test.\") ||\n path.includes(\".spec.\") ||\n path.startsWith(\"tests/\")\n );\n}\n\n/**\n * Check if a file is a documentation file.\n */\nfunction isDocFile(path: string): boolean {\n return path.endsWith(\".md\") || path.startsWith(\"docs/\");\n}\n\n/**\n * Check if a file is a config/meta file.\n */\nfunction isConfigFile(path: string): boolean {\n const filename = path.split(\"/\").pop() || \"\";\n return (\n // Package manager files\n filename === \"package.json\" ||\n filename === \"package-lock.json\" ||\n filename === \"yarn.lock\" ||\n filename === \"pnpm-lock.yaml\" ||\n filename === \"bun.lockb\" ||\n // Config files in root\n filename.endsWith(\".config.js\") ||\n filename.endsWith(\".config.ts\") ||\n filename.endsWith(\".config.mjs\") ||\n filename.endsWith(\".config.cjs\") ||\n // TOML configs\n filename.endsWith(\".toml\") ||\n // Dotfiles in root (but not directories like .github)\n (path.split(\"/\").length === 1 && filename.startsWith(\".\"))\n );\n}\n\n/**\n * Analyze test coverage gaps.\n */\nexport const analyzeTestGaps: Analyzer = {\n name: \"test-gaps\",\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: TestGapFinding[] = [];\n\n let prodFilesChanged = 0;\n let testFilesChanged = 0;\n const prodFiles: string[] = [];\n\n for (const file of changeSet.files) {\n // Skip docs and config\n if (isDocFile(file.path) || isConfigFile(file.path)) {\n continue;\n }\n\n if (isTestFile(file.path)) {\n testFilesChanged++;\n } else {\n prodFilesChanged++;\n prodFiles.push(file.path);\n }\n }\n\n // Flag if production code changed significantly without tests\n if (prodFilesChanged >= 3 && testFilesChanged === 0) {\n // Create evidence showing the prod files that changed without tests\n // Use first file as the \"main\" evidence with the summary, rest as supporting\n const evidence = prodFiles.slice(0, 5).map((file, index) =>\n createEvidence(\n file,\n index === 0\n ? `${prodFilesChanged} production file(s) changed with no test updates`\n : \"No corresponding test changes\"\n )\n );\n\n findings.push({\n type: \"test-gap\",\n kind: \"test-gap\",\n category: \"quality\",\n confidence: \"medium\",\n evidence,\n prodFilesChanged,\n testFilesChanged,\n });\n }\n\n return findings;\n },\n};\n",
29
- "/**\n * SQL risk analyzer - detects risky SQL patterns in migrations.\n */\n\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n SQLRiskFinding,\n} from \"../core/types.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\n\n/**\n * Check if a file is a migration or SQL file.\n */\nfunction isMigrationFile(path: string): boolean {\n return (\n path.includes(\"/migrations/\") ||\n path.includes(\"/migrate/\") ||\n path.endsWith(\".sql\")\n );\n}\n\n/**\n * Analyze SQL files for risky patterns.\n */\nexport const analyzeSQLRisks: Analyzer = {\n name: \"sql-risks\",\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: SQLRiskFinding[] = [];\n\n for (const diff of changeSet.diffs) {\n if (!isMigrationFile(diff.path)) continue;\n\n for (const hunk of diff.hunks) {\n const addedLines = hunk.additions.join(\"\\n\");\n\n // Check for destructive SQL\n const destructivePatterns = /\\b(DROP\\s+TABLE|DROP\\s+COLUMN|TRUNCATE)\\b/gi;\n if (destructivePatterns.test(addedLines)) {\n const excerpt = extractRepresentativeExcerpt(hunk.additions, 200);\n findings.push({\n type: \"sql-risk\",\n kind: \"sql-risk\",\n category: \"database\",\n confidence: \"high\",\n evidence: [\n createEvidence(diff.path, excerpt, { hunk }),\n ],\n file: diff.path,\n riskType: \"destructive\",\n details: \"Contains DROP TABLE/COLUMN or TRUNCATE\",\n });\n continue; // One finding per hunk\n }\n\n // Check for risky schema changes\n const riskySchemaPatterns = /ALTER\\s+TABLE[^;]+\\b(ALTER\\s+COLUMN|TYPE)\\b/gi;\n if (riskySchemaPatterns.test(addedLines)) {\n const excerpt = extractRepresentativeExcerpt(hunk.additions, 200);\n findings.push({\n type: \"sql-risk\",\n kind: \"sql-risk\",\n category: \"database\",\n confidence: \"high\",\n evidence: [\n createEvidence(diff.path, excerpt, { hunk }),\n ],\n file: diff.path,\n riskType: \"schema_change\",\n details: \"Contains ALTER COLUMN or TYPE change\",\n });\n continue;\n }\n\n // Check for unscoped data modification\n const unscopedPatterns = /(UPDATE|DELETE)\\s+(?![^;\\n]*\\bWHERE\\b)/gi;\n if (unscopedPatterns.test(addedLines)) {\n const excerpt = extractRepresentativeExcerpt(hunk.additions, 200);\n findings.push({\n type: \"sql-risk\",\n kind: \"sql-risk\",\n category: \"database\",\n confidence: \"medium\",\n evidence: [\n createEvidence(diff.path, excerpt, { hunk }),\n ],\n file: diff.path,\n riskType: \"unscoped_modification\",\n details: \"Contains UPDATE/DELETE without WHERE clause\",\n });\n }\n }\n }\n\n return findings;\n },\n};\n",
30
- "/**\n * CI workflow analyzer - detects risky CI/CD patterns.\n */\n\nimport type {\n Analyzer,\n ChangeSet,\n CIWorkflowFinding,\n Finding,\n} from \"../core/types.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\n\n/**\n * Check if a file is a CI workflow file.\n */\nfunction isCIFile(path: string): boolean {\n return (\n (path.includes(\".github/workflows/\") && (path.endsWith(\".yml\") || path.endsWith(\".yaml\"))) ||\n path === \".gitlab-ci.yml\" ||\n path === \"Jenkinsfile\" ||\n path === \"azure-pipelines.yml\"\n );\n}\n\n/**\n * Analyze CI workflows for risky patterns.\n */\nexport const analyzeCIWorkflows: Analyzer = {\n name: \"ci-workflows\",\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: CIWorkflowFinding[] = [];\n const seenFiles = new Set<string>();\n\n for (const diff of changeSet.diffs) {\n if (!isCIFile(diff.path)) continue;\n\n let hasPermissions = false;\n let hasPullRequestTarget = false;\n let hasRemoteScript = false;\n\n for (const hunk of diff.hunks) {\n const addedLines = hunk.additions.join(\"\\n\");\n\n // Check for broadened permissions (supports inline and multi-line YAML)\n const writePermissions = /permissions:[\\s\\S]{0,500}?\\b(contents|id-token|actions|packages|deployments|security-events)\\b\\s*:\\s*write/gi;\n if (!hasPermissions && writePermissions.test(addedLines)) {\n hasPermissions = true;\n const excerpt = extractRepresentativeExcerpt(hunk.additions, 200);\n findings.push({\n type: \"ci-workflow\",\n kind: \"ci-workflow\",\n category: \"ci\",\n confidence: \"high\",\n evidence: [\n createEvidence(diff.path, excerpt, { hunk }),\n ],\n file: diff.path,\n riskType: \"permissions_broadened\",\n details: \"Workflow has broadened permissions (write access)\",\n });\n }\n\n // Check for pull_request_target\n const prTargetPattern = /pull_request_target/i;\n if (!hasPullRequestTarget && prTargetPattern.test(addedLines)) {\n hasPullRequestTarget = true;\n const excerpt = extractRepresentativeExcerpt(hunk.additions, 200);\n findings.push({\n type: \"ci-workflow\",\n kind: \"ci-workflow\",\n category: \"ci\",\n confidence: \"high\",\n evidence: [\n createEvidence(diff.path, excerpt, { hunk }),\n ],\n file: diff.path,\n riskType: \"pull_request_target\",\n details: \"Workflow uses pull_request_target event (can expose secrets)\",\n });\n }\n\n // Check for remote script download\n const downloadPattern = /(curl|wget)\\s+[^\\s]+\\s*\\|\\s*(sh|bash)/gi;\n if (!hasRemoteScript && downloadPattern.test(addedLines)) {\n hasRemoteScript = true;\n const excerpt = extractRepresentativeExcerpt(hunk.additions, 200);\n findings.push({\n type: \"ci-workflow\",\n kind: \"ci-workflow\",\n category: \"ci\",\n confidence: \"high\",\n evidence: [\n createEvidence(diff.path, excerpt, { hunk }),\n ],\n file: diff.path,\n riskType: \"remote_script_download\",\n details: \"Workflow downloads and pipes to shell (supply chain risk)\",\n });\n }\n }\n\n // General pipeline change (one per file)\n if (!seenFiles.has(diff.path) && diff.hunks.length > 0) {\n seenFiles.add(diff.path);\n const excerpt = extractRepresentativeExcerpt(diff.hunks[0].additions, 150);\n findings.push({\n type: \"ci-workflow\",\n kind: \"ci-workflow\",\n category: \"ci\",\n confidence: \"medium\",\n evidence: [\n createEvidence(diff.path, excerpt),\n ],\n file: diff.path,\n riskType: \"pipeline_changed\",\n details: \"CI/CD pipeline configuration modified\",\n });\n }\n }\n\n return findings;\n },\n};\n",
31
- "/**\n * Infrastructure analyzer - detects infrastructure changes.\n */\n\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n InfraChangeFinding,\n} from \"../core/types.js\";\n\n/**\n * Analyze infrastructure file changes.\n */\nexport const analyzeInfra: Analyzer = {\n name: \"infra\",\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: InfraChangeFinding[] = [];\n\n // Group files by type\n const dockerfiles: string[] = [];\n const terraformFiles: string[] = [];\n const k8sFiles: string[] = [];\n\n for (const file of changeSet.files) {\n if (file.path.toLowerCase().includes(\"dockerfile\")) {\n dockerfiles.push(file.path);\n } else if (file.path.endsWith(\".tf\") || file.path.endsWith(\".tfvars\")) {\n terraformFiles.push(file.path);\n } else if (\n file.path.includes(\"kubernetes/\") ||\n file.path.includes(\"k8s/\") ||\n (file.path.endsWith(\".yaml\") && (\n file.path.includes(\"deployment\") ||\n file.path.includes(\"service\") ||\n file.path.includes(\"ingress\")\n ))\n ) {\n k8sFiles.push(file.path);\n }\n }\n\n if (dockerfiles.length > 0) {\n findings.push({\n type: \"infra-change\",\n kind: \"infra-change\",\n category: \"infra\",\n confidence: \"high\",\n evidence: [],\n infraType: \"dockerfile\",\n files: dockerfiles,\n });\n }\n\n if (terraformFiles.length > 0) {\n findings.push({\n type: \"infra-change\",\n kind: \"infra-change\",\n category: \"infra\",\n confidence: \"high\",\n evidence: [],\n infraType: \"terraform\",\n files: terraformFiles,\n });\n }\n\n if (k8sFiles.length > 0) {\n findings.push({\n type: \"infra-change\",\n kind: \"infra-change\",\n category: \"infra\",\n confidence: \"high\",\n evidence: [],\n infraType: \"k8s\",\n files: k8sFiles,\n });\n }\n\n return findings;\n },\n};\n",
32
- "/**\n * API contract analyzer - detects API contract changes.\n */\n\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n APIContractChangeFinding,\n} from \"../core/types.js\";\n\n/**\n * Check if a file is an API contract file.\n */\nfunction isAPIContractFile(path: string): boolean {\n return (\n path.includes(\"openapi\") ||\n path.includes(\"swagger\") ||\n path.endsWith(\".proto\") ||\n (path.includes(\"/api/\") && (path.endsWith(\".yaml\") || path.endsWith(\".yml\") || path.endsWith(\".json\")))\n );\n}\n\n/**\n * Analyze API contract changes.\n */\nexport const analyzeAPIContracts: Analyzer = {\n name: \"api-contracts\",\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: APIContractChangeFinding[] = [];\n\n const contractFiles = changeSet.files\n .filter(f => isAPIContractFile(f.path))\n .map(f => f.path);\n\n if (contractFiles.length > 0) {\n findings.push({\n type: \"api-contract-change\",\n kind: \"api-contract-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [],\n files: contractFiles,\n });\n }\n\n return findings;\n },\n};\n",
33
- "/**\n * Stencil analyzer - detects changes in StencilJS components.\n * Uses AST parsing to extract component metadata, props, events, methods, and slots.\n */\n\nimport { parse } from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\nimport * as t from \"@babel/types\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n StencilComponentChangeFinding,\n StencilPropChangeFinding,\n StencilEventChangeFinding,\n StencilMethodChangeFinding,\n StencilSlotChangeFinding,\n} from \"../core/types.js\";\nimport { createEvidence } from \"../core/evidence.js\";\nimport { batchGetFileContent as defaultBatchGetFileContent } from \"../git/batch.js\";\n\n// Allow injection for testing\nexport const dependencies = {\n batchGetFileContent: defaultBatchGetFileContent,\n};\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface StencilProp {\n name: string;\n typeText?: string;\n attribute?: string;\n reflect?: boolean;\n mutable?: boolean;\n line: number;\n}\n\ninterface StencilEvent {\n name: string; // Public event name (from option or member name)\n memberName: string;\n bubbles?: boolean;\n composed?: boolean;\n cancelable?: boolean;\n line: number;\n}\n\ninterface StencilMethod {\n name: string;\n signature?: string;\n line: number;\n}\n\ninterface StencilComponent {\n tag: string;\n shadow: boolean;\n file: string;\n line: number;\n props: Map<string, StencilProp>;\n events: Map<string, StencilEvent>;\n methods: Map<string, StencilMethod>;\n slots: Set<string>; // Only names for simple diffing\n}\n\n// ============================================================================\n// Extraction Logic\n// ============================================================================\n\nfunction isCandidateFile(path: string): boolean {\n return path.endsWith(\".tsx\") || path.endsWith(\".ts\");\n}\n\n/**\n * Format slot evidence string based on slot name type.\n */\nfunction formatSlotEvidence(slotName: string): string {\n if (slotName === \"default\") {\n return \"<slot />\";\n } else if (slotName === \"boolean\") {\n return \"<slot name />\";\n } else if (slotName === \"dynamic\") {\n return \"<slot name={...} />\";\n } else {\n return `<slot name=\"${slotName}\" />`;\n }\n}\n\n/**\n * Extract Stencil component information from file content.\n */\nexport function extractStencilComponents(\n content: string,\n filePath: string\n): StencilComponent[] {\n const components: StencilComponent[] = [];\n\n try {\n const ast = parse(content, {\n sourceType: \"module\",\n plugins: [\"typescript\", \"jsx\", \"decorators-legacy\"],\n });\n\n traverse(ast, {\n ClassDeclaration(path) {\n // Check for @Component decorator\n const decorators = path.node.decorators || [];\n const componentDecorator = decorators.find(\n (d) =>\n t.isCallExpression(d.expression) &&\n t.isIdentifier(d.expression.callee) &&\n d.expression.callee.name === \"Component\"\n );\n\n if (!componentDecorator) return;\n\n // Extract component metadata\n let tag = \"\";\n let shadow = false; // Default to false if not specified (though Stencil often recommends true)\n\n // Use default line 1 if loc is missing (rare)\n const componentLine = path.node.loc?.start.line ?? 1;\n\n if (t.isCallExpression(componentDecorator.expression)) {\n const arg = componentDecorator.expression.arguments[0];\n if (t.isObjectExpression(arg)) {\n for (const prop of arg.properties) {\n if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) {\n if (prop.key.name === \"tag\") {\n if (t.isStringLiteral(prop.value)) {\n tag = prop.value.value;\n }\n } else if (prop.key.name === \"shadow\") {\n if (t.isBooleanLiteral(prop.value)) {\n shadow = prop.value.value;\n }\n }\n }\n }\n }\n }\n\n if (!tag) return; // Tag is required\n\n const props = new Map<string, StencilProp>();\n const events = new Map<string, StencilEvent>();\n const methods = new Map<string, StencilMethod>();\n const slots = new Set<string>();\n\n // Traverse class body for members\n for (const bodyNode of path.node.body.body) {\n // Props\n if (t.isClassProperty(bodyNode) || t.isClassMethod(bodyNode)) {\n const memberDecorators = bodyNode.decorators || [];\n\n // @Prop\n const propDec = memberDecorators.find(\n (d) =>\n (t.isCallExpression(d.expression) &&\n t.isIdentifier(d.expression.callee) &&\n d.expression.callee.name === \"Prop\") ||\n (t.isIdentifier(d.expression) && d.expression.name === \"Prop\")\n );\n\n if (propDec && t.isIdentifier(bodyNode.key)) {\n const name = bodyNode.key.name;\n const line = bodyNode.loc?.start.line ?? 1;\n\n let attribute: string | undefined;\n let reflect = false;\n let mutable = false;\n let typeText: string | undefined; // We can't easily get full type text from AST without printing, so skipping for now or simple extraction\n\n if (t.isClassProperty(bodyNode) && bodyNode.typeAnnotation && t.isTSTypeAnnotation(bodyNode.typeAnnotation)) {\n // Best effort type extraction - skipping complex types for now\n // In a real implementation we might print the type node\n }\n\n if (t.isCallExpression(propDec.expression)) {\n const arg = propDec.expression.arguments[0];\n if (t.isObjectExpression(arg)) {\n for (const p of arg.properties) {\n if (t.isObjectProperty(p) && t.isIdentifier(p.key)) {\n if (p.key.name === \"attribute\" && t.isStringLiteral(p.value)) attribute = p.value.value;\n if (p.key.name === \"reflect\" && t.isBooleanLiteral(p.value)) reflect = p.value.value;\n if (p.key.name === \"mutable\" && t.isBooleanLiteral(p.value)) mutable = p.value.value;\n }\n }\n }\n }\n\n props.set(name, { name, attribute, reflect, mutable, typeText, line });\n }\n\n // @Event\n const eventDec = memberDecorators.find(\n (d) =>\n (t.isCallExpression(d.expression) &&\n t.isIdentifier(d.expression.callee) &&\n d.expression.callee.name === \"Event\") ||\n (t.isIdentifier(d.expression) && d.expression.name === \"Event\")\n );\n\n if (eventDec && t.isIdentifier(bodyNode.key)) {\n const memberName = bodyNode.key.name;\n let eventName = memberName;\n const line = bodyNode.loc?.start.line ?? 1;\n\n let bubbles = true; // Default true\n let composed = true; // Default true\n let cancelable = true; // Default true\n\n if (t.isCallExpression(eventDec.expression)) {\n const arg = eventDec.expression.arguments[0];\n if (t.isObjectExpression(arg)) {\n for (const p of arg.properties) {\n if (t.isObjectProperty(p) && t.isIdentifier(p.key)) {\n if (p.key.name === \"eventName\" && t.isStringLiteral(p.value)) eventName = p.value.value;\n if (p.key.name === \"bubbles\" && t.isBooleanLiteral(p.value)) bubbles = p.value.value;\n if (p.key.name === \"composed\" && t.isBooleanLiteral(p.value)) composed = p.value.value;\n if (p.key.name === \"cancelable\" && t.isBooleanLiteral(p.value)) cancelable = p.value.value;\n }\n }\n }\n }\n\n events.set(eventName, { name: eventName, memberName, bubbles, composed, cancelable, line });\n }\n\n // @Method\n const methodDec = memberDecorators.find(\n (d) =>\n (t.isCallExpression(d.expression) &&\n t.isIdentifier(d.expression.callee) &&\n d.expression.callee.name === \"Method\") ||\n (t.isIdentifier(d.expression) && d.expression.name === \"Method\")\n );\n\n if (methodDec && t.isIdentifier(bodyNode.key)) {\n const name = bodyNode.key.name;\n const line = bodyNode.loc?.start.line ?? 1;\n // Extract signature if needed, for now just name\n methods.set(name, { name, line });\n }\n }\n\n // render() for slots\n if (t.isClassMethod(bodyNode) && t.isIdentifier(bodyNode.key) && bodyNode.key.name === \"render\") {\n // Traverse render method body for JSX slots\n traverse(bodyNode, {\n JSXElement(innerPath) {\n const opening = innerPath.node.openingElement;\n if (t.isJSXIdentifier(opening.name) && opening.name.name === \"slot\") {\n let slotName = \"default\";\n for (const attr of opening.attributes) {\n if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name === \"name\") {\n if (t.isStringLiteral(attr.value)) {\n slotName = attr.value.value;\n } else if (attr.value === null) {\n // Boolean \"name\" attribute: <slot name />\n slotName = \"boolean\";\n } else {\n // Dynamic or non-literal slot name, e.g. <slot name={expr} />\n slotName = \"dynamic\";\n }\n }\n }\n slots.add(slotName);\n }\n },\n // Also handle self-closing <slot /> (JSXElement handles both usually if parsed correctly, but just in case)\n }, path.scope, path);\n }\n }\n\n components.push({\n tag,\n shadow,\n file: filePath,\n line: componentLine,\n props,\n events,\n methods,\n slots,\n });\n },\n });\n } catch (error) {\n // Parsing error, skip\n }\n\n return components;\n}\n\n// ============================================================================\n// Analyzer\n// ============================================================================\n\nexport const stencilAnalyzer: Analyzer = {\n name: \"stencil\",\n\n async analyze(changeSet: ChangeSet): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n // Select candidate files\n const candidateFiles = changeSet.files.filter((file) =>\n isCandidateFile(file.path)\n );\n\n if (candidateFiles.length === 0) return [];\n\n // Batch fetch content\n const batchRequest: Array<{ ref: string; path: string }> = [];\n for (const file of candidateFiles) {\n batchRequest.push({ ref: changeSet.base, path: file.path });\n batchRequest.push({ ref: changeSet.head, path: file.path });\n }\n\n const contentMap = await dependencies.batchGetFileContent(batchRequest);\n\n for (const file of candidateFiles) {\n const baseKey = `${changeSet.base}:${file.path}`;\n const headKey = `${changeSet.head}:${file.path}`;\n\n const baseContent = contentMap.get(baseKey);\n const headContent = contentMap.get(headKey);\n\n // Skip if neither has content (shouldn't happen for candidate files)\n if (!baseContent && !headContent) continue;\n\n const baseComponents = baseContent\n ? extractStencilComponents(baseContent, file.path)\n : [];\n const headComponents = headContent\n ? extractStencilComponents(headContent, file.path)\n : [];\n\n // Map by tag\n const baseMap = new Map(baseComponents.map((c) => [c.tag, c]));\n const headMap = new Map(headComponents.map((c) => [c.tag, c]));\n\n const allTags = new Set([...baseMap.keys(), ...headMap.keys()]);\n\n for (const tag of allTags) {\n const baseComp = baseMap.get(tag);\n const headComp = headMap.get(tag);\n\n if (baseComp && !headComp) {\n // Component removed\n findings.push({\n type: \"stencil-component-change\",\n kind: \"stencil-component-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Component({ tag: \"${tag}\" })`, { line: baseComp.line })],\n tag,\n change: \"removed\",\n file: file.path,\n } as StencilComponentChangeFinding);\n } else if (!baseComp && headComp) {\n // Component added\n findings.push({\n type: \"stencil-component-change\",\n kind: \"stencil-component-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Component({ tag: \"${tag}\" })`, { line: headComp.line })],\n tag,\n change: \"added\",\n file: file.path,\n } as StencilComponentChangeFinding);\n } else if (baseComp && headComp) {\n // Component modified - check details\n\n // Shadow DOM changed\n if (baseComp.shadow !== headComp.shadow) {\n findings.push({\n type: \"stencil-component-change\",\n kind: \"stencil-component-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Component({ tag: \"${tag}\", shadow: ${headComp.shadow} })`, { line: headComp.line })],\n tag,\n change: \"shadow-changed\",\n file: file.path,\n fromShadow: baseComp.shadow,\n toShadow: headComp.shadow,\n } as StencilComponentChangeFinding);\n }\n\n // Props\n const allProps = new Set([...baseComp.props.keys(), ...headComp.props.keys()]);\n for (const propName of allProps) {\n const baseProp = baseComp.props.get(propName);\n const headProp = headComp.props.get(propName);\n\n if (baseProp && !headProp) {\n findings.push({\n type: \"stencil-prop-change\",\n kind: \"stencil-prop-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Prop() ${propName}`, { line: baseProp.line })],\n tag,\n propName,\n change: \"removed\",\n file: file.path,\n } as StencilPropChangeFinding);\n } else if (!baseProp && headProp) {\n findings.push({\n type: \"stencil-prop-change\",\n kind: \"stencil-prop-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Prop() ${propName}`, { line: headProp.line })],\n tag,\n propName,\n change: \"added\",\n file: file.path,\n details: {\n attribute: headProp.attribute,\n reflect: headProp.reflect,\n mutable: headProp.mutable,\n }\n } as StencilPropChangeFinding);\n } else if (baseProp && headProp) {\n // Check for changes\n if (\n baseProp.attribute !== headProp.attribute ||\n baseProp.reflect !== headProp.reflect ||\n baseProp.mutable !== headProp.mutable\n ) {\n findings.push({\n type: \"stencil-prop-change\",\n kind: \"stencil-prop-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Prop() ${propName}`, { line: headProp.line })],\n tag,\n propName,\n change: \"changed\",\n file: file.path,\n details: {\n attribute: headProp.attribute,\n reflect: headProp.reflect,\n mutable: headProp.mutable,\n }\n } as StencilPropChangeFinding);\n }\n }\n }\n\n // Events\n const allEvents = new Set([...baseComp.events.keys(), ...headComp.events.keys()]);\n for (const eventName of allEvents) {\n const baseEvent = baseComp.events.get(eventName);\n const headEvent = headComp.events.get(eventName);\n\n if (baseEvent && !headEvent) {\n findings.push({\n type: \"stencil-event-change\",\n kind: \"stencil-event-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Event() ${baseEvent.memberName}`, { line: baseEvent.line })],\n tag,\n eventName,\n change: \"removed\",\n file: file.path,\n } as StencilEventChangeFinding);\n } else if (!baseEvent && headEvent) {\n findings.push({\n type: \"stencil-event-change\",\n kind: \"stencil-event-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Event() ${headEvent.memberName}`, { line: headEvent.line })],\n tag,\n eventName,\n change: \"added\",\n file: file.path,\n details: {\n bubbles: headEvent.bubbles,\n composed: headEvent.composed,\n cancelable: headEvent.cancelable\n }\n } as StencilEventChangeFinding);\n } else if (baseEvent && headEvent) {\n // Check for option changes\n if (\n baseEvent.bubbles !== headEvent.bubbles ||\n baseEvent.composed !== headEvent.composed ||\n baseEvent.cancelable !== headEvent.cancelable\n ) {\n findings.push({\n type: \"stencil-event-change\",\n kind: \"stencil-event-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Event() ${headEvent.memberName}`, { line: headEvent.line })],\n tag,\n eventName,\n change: \"changed\",\n file: file.path,\n details: {\n bubbles: headEvent.bubbles,\n composed: headEvent.composed,\n cancelable: headEvent.cancelable\n }\n } as StencilEventChangeFinding);\n }\n }\n }\n\n // Methods\n const allMethods = new Set([...baseComp.methods.keys(), ...headComp.methods.keys()]);\n for (const methodName of allMethods) {\n const baseMethod = baseComp.methods.get(methodName);\n const headMethod = headComp.methods.get(methodName);\n\n if (baseMethod && !headMethod) {\n findings.push({\n type: \"stencil-method-change\",\n kind: \"stencil-method-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Method() ${methodName}`, { line: baseMethod.line })],\n tag,\n methodName,\n change: \"removed\",\n file: file.path,\n } as StencilMethodChangeFinding);\n } else if (!baseMethod && headMethod) {\n findings.push({\n type: \"stencil-method-change\",\n kind: \"stencil-method-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, `@Method() ${methodName}`, { line: headMethod.line })],\n tag,\n methodName,\n change: \"added\",\n file: file.path,\n } as StencilMethodChangeFinding);\n }\n // Signature change check omitted for now (needs more complex AST analysis)\n }\n\n // Slots\n const allSlots = new Set([...baseComp.slots, ...headComp.slots]);\n for (const slotName of allSlots) {\n const baseHas = baseComp.slots.has(slotName);\n const headHas = headComp.slots.has(slotName);\n\n if (baseHas && !headHas) {\n findings.push({\n type: \"stencil-slot-change\",\n kind: \"stencil-slot-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, formatSlotEvidence(slotName), { line: baseComp.line })], // Approximate line\n tag,\n slotName,\n change: \"removed\",\n file: file.path,\n } as StencilSlotChangeFinding);\n } else if (!baseHas && headHas) {\n findings.push({\n type: \"stencil-slot-change\",\n kind: \"stencil-slot-change\",\n category: \"api\",\n confidence: \"high\",\n evidence: [createEvidence(file.path, formatSlotEvidence(slotName), { line: headComp.line })],\n tag,\n slotName,\n change: \"added\",\n file: file.path,\n } as StencilSlotChangeFinding);\n }\n }\n }\n }\n }\n\n return findings;\n },\n};\n",
34
- "/**\n * Next.js App Router route detector - detects changes under app/ directory.\n *\n * Supports Next.js 13+ App Router conventions:\n * - page.tsx/ts/jsx/js - Page components\n * - layout.tsx/ts - Layout components\n * - loading.tsx/ts - Loading UI\n * - error.tsx/ts - Error boundaries\n * - not-found.tsx/ts - 404 pages\n * - route.ts/tsx - API route handlers\n */\n\nimport { getAdditions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n FileDiff,\n FileStatus,\n Finding,\n RouteChangeFinding,\n RouteType,\n SecurityFileFinding,\n} from \"../core/types.js\";\n\n// Route file patterns (App Router)\nconst ROUTE_FILE_PATTERNS: Record<string, RouteType> = {\n \"page.tsx\": \"page\",\n \"page.ts\": \"page\",\n \"page.jsx\": \"page\",\n \"page.js\": \"page\",\n \"layout.tsx\": \"layout\",\n \"layout.ts\": \"layout\",\n \"layout.jsx\": \"layout\",\n \"layout.js\": \"layout\",\n \"loading.tsx\": \"page\",\n \"loading.ts\": \"page\",\n \"loading.jsx\": \"page\",\n \"loading.js\": \"page\",\n \"error.tsx\": \"error\",\n \"error.ts\": \"error\",\n \"error.jsx\": \"error\",\n \"error.js\": \"error\",\n \"not-found.tsx\": \"error\",\n \"not-found.ts\": \"error\",\n \"not-found.jsx\": \"error\",\n \"not-found.js\": \"error\",\n \"route.ts\": \"endpoint\",\n \"route.tsx\": \"endpoint\",\n \"route.js\": \"endpoint\",\n \"route.jsx\": \"endpoint\",\n};\n\n// Middleware file patterns\nconst MIDDLEWARE_FILES = [\n \"middleware.ts\",\n \"middleware.js\",\n \"middleware.tsx\",\n \"middleware.jsx\",\n \"src/middleware.ts\",\n \"src/middleware.js\",\n \"src/middleware.tsx\",\n \"src/middleware.jsx\",\n];\n\n// Next.js config file patterns\nconst CONFIG_FILES = [\n \"next.config.js\",\n \"next.config.mjs\",\n \"next.config.ts\",\n];\n\n// HTTP method detection pattern for route handlers\nconst METHOD_PATTERN = /export\\s+(?:async\\s+)?function\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\s*\\(/g;\n\n/**\n * Check if a path is a Next.js App Router route file.\n */\nexport function isNextRouteFile(path: string): boolean {\n // Must be under app/ directory (or src/app/)\n if (!path.startsWith(\"app/\") && !path.startsWith(\"src/app/\")) {\n return false;\n }\n return hasRouteFilePattern(path);\n}\n\n/**\n * Check if path ends with a route file pattern.\n */\nfunction hasRouteFilePattern(path: string): boolean {\n const fileName = path.split(\"/\").pop() ?? \"\";\n return Object.keys(ROUTE_FILE_PATTERNS).includes(fileName);\n}\n\n/**\n * Get the route type from a file path.\n */\nexport function getRouteType(path: string): RouteType {\n const fileName = path.split(\"/\").pop() ?? \"\";\n return ROUTE_FILE_PATTERNS[fileName] ?? \"unknown\";\n}\n\n/**\n * Convert a file path to a Next.js route ID.\n *\n * Rules:\n * - Strip `app/` or `src/app/` prefix\n * - Remove route groups `(name)` from URL\n * - Keep param notation: [slug], [[...catchAll]]\n * - Remove file name (the route is the directory)\n */\nexport function pathToRouteId(path: string): string {\n // Remove app/ or src/app/ prefix\n let routeId = path\n .replace(/^src\\/app/, \"\")\n .replace(/^app/, \"\");\n\n // Remove the file name\n const parts = routeId.split(\"/\");\n parts.pop(); // Remove file name\n\n routeId = parts.join(\"/\");\n\n // Remove route groups: (name)\n routeId = routeId.replace(/\\/\\([^)]+\\)/g, \"\");\n\n // If empty, it's the root route\n if (routeId === \"\" || routeId === \"/\") {\n return \"/\";\n }\n\n // Ensure leading slash\n if (!routeId.startsWith(\"/\")) {\n routeId = \"/\" + routeId;\n }\n\n // Remove trailing slash (except for root)\n if (routeId.length > 1 && routeId.endsWith(\"/\")) {\n routeId = routeId.slice(0, -1);\n }\n\n return routeId;\n}\n\n/**\n * Detect HTTP methods from route handler file content.\n */\nexport function detectMethods(diff: FileDiff): string[] {\n const methods = new Set<string>();\n const content = getAdditions(diff).join(\"\\n\");\n\n let match;\n const pattern = new RegExp(METHOD_PATTERN.source, \"g\");\n while ((match = pattern.exec(content)) !== null) {\n methods.add(match[1]);\n }\n\n return Array.from(methods).sort();\n}\n\n/**\n * Check if a path is a Next.js middleware file.\n */\nexport function isMiddlewareFile(path: string): boolean {\n return MIDDLEWARE_FILES.includes(path);\n}\n\n/**\n * Check if a path is a Next.js config file.\n */\nexport function isNextConfigFile(path: string): boolean {\n return CONFIG_FILES.includes(path);\n}\n\nexport const nextRoutesAnalyzer: Analyzer = {\n name: \"next-routes\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n const routeFiles = new Map<string, { diff?: FileDiff; status: FileStatus }>();\n\n // Collect route files from file changes\n for (const file of changeSet.files) {\n if (isNextRouteFile(file.path)) {\n routeFiles.set(file.path, { status: file.status });\n }\n\n // Check for middleware changes\n if (isMiddlewareFile(file.path)) {\n const diff = changeSet.diffs.find(d => d.path === file.path);\n const evidence = [];\n if (diff && diff.hunks.length > 0) {\n const additions = getAdditions(diff);\n if (additions.length > 0) {\n const excerpt = extractRepresentativeExcerpt(additions);\n if (excerpt) {\n evidence.push(createEvidence(file.path, excerpt));\n }\n }\n }\n\n const middlewareFinding: SecurityFileFinding = {\n type: \"security-file\",\n kind: \"security-file\",\n category: \"routes\",\n confidence: \"high\",\n evidence,\n files: [file.path],\n reasons: [\"middleware\"],\n };\n findings.push(middlewareFinding);\n }\n }\n\n // Add diff data for route files\n for (const diff of changeSet.diffs) {\n if (isNextRouteFile(diff.path)) {\n const existing = routeFiles.get(diff.path);\n if (existing) {\n existing.diff = diff;\n } else {\n routeFiles.set(diff.path, { diff, status: diff.status });\n }\n }\n }\n\n // Generate route findings\n for (const [path, { diff, status }] of routeFiles) {\n const routeId = pathToRouteId(path);\n const routeType = getRouteType(path);\n\n // Extract evidence\n const evidence = [];\n if (diff && diff.hunks.length > 0) {\n const additions = getAdditions(diff);\n if (additions.length > 0) {\n const excerpt = extractRepresentativeExcerpt(additions);\n if (excerpt) {\n evidence.push(createEvidence(path, excerpt));\n }\n }\n }\n\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"high\",\n evidence,\n routeId,\n file: path,\n change: status,\n routeType,\n };\n\n // Detect methods for API route handlers\n if (routeType === \"endpoint\" && diff) {\n const methods = detectMethods(diff);\n if (methods.length > 0) {\n finding.methods = methods;\n // Add method export as evidence if available\n const methodsExcerpt = methods.map(m => `export function ${m}`).join(\", \");\n if (!evidence.length) {\n evidence.push(createEvidence(path, methodsExcerpt));\n }\n }\n }\n\n findings.push(finding);\n }\n\n return findings;\n },\n};\n",
35
- "/**\n * GraphQL schema change detector.\n *\n * Detects changes to GraphQL schema files (.graphql, .gql) and identifies\n * potentially breaking changes such as removed types, fields, or arguments.\n */\n\nimport { getAdditions, getDeletions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n GraphQLChangeFinding,\n Confidence,\n} from \"../core/types.js\";\n\n// GraphQL schema file patterns\nconst GRAPHQL_PATTERNS = [\n /\\.graphql$/,\n /\\.gql$/,\n /schema\\.graphqls$/,\n /schema\\.sdl$/,\n];\n\n/**\n * Check if a file is a GraphQL schema file.\n */\nexport function isGraphQLSchema(path: string): boolean {\n return GRAPHQL_PATTERNS.some((pattern) => pattern.test(path));\n}\n\n/**\n * Analyze deletions for breaking changes.\n */\nfunction analyzeBreakingChanges(deletions: string[]): string[] {\n const breakingChanges: string[] = [];\n const deletedContent = deletions.join(\"\\n\");\n\n // Check for removed types\n const typeMatches = deletedContent.match(/type\\s+(\\w+)\\s*[{@]/g);\n if (typeMatches) {\n for (const match of typeMatches) {\n const typeName = match.match(/type\\s+(\\w+)/)?.[1];\n if (typeName) {\n breakingChanges.push(`Removed type: ${typeName}`);\n }\n }\n }\n\n // Check for removed enums\n const enumMatches = deletedContent.match(/enum\\s+(\\w+)\\s*{/g);\n if (enumMatches) {\n for (const match of enumMatches) {\n const enumName = match.match(/enum\\s+(\\w+)/)?.[1];\n if (enumName) {\n breakingChanges.push(`Removed enum: ${enumName}`);\n }\n }\n }\n\n // Check for removed interfaces\n const interfaceMatches = deletedContent.match(/interface\\s+(\\w+)\\s*[{@]/g);\n if (interfaceMatches) {\n for (const match of interfaceMatches) {\n const interfaceName = match.match(/interface\\s+(\\w+)/)?.[1];\n if (interfaceName) {\n breakingChanges.push(`Removed interface: ${interfaceName}`);\n }\n }\n }\n\n // Check for removed input types\n const inputMatches = deletedContent.match(/input\\s+(\\w+)\\s*{/g);\n if (inputMatches) {\n for (const match of inputMatches) {\n const inputName = match.match(/input\\s+(\\w+)/)?.[1];\n if (inputName) {\n breakingChanges.push(`Removed input type: ${inputName}`);\n }\n }\n }\n\n return breakingChanges;\n}\n\n/**\n * Analyze additions for new schema elements.\n */\nfunction analyzeAdditions(additions: string[]): string[] {\n const addedElements: string[] = [];\n const addedContent = additions.join(\"\\n\");\n\n // Check for added types\n const typeMatches = addedContent.match(/type\\s+(\\w+)\\s*[{@]/g);\n if (typeMatches) {\n for (const match of typeMatches) {\n const typeName = match.match(/type\\s+(\\w+)/)?.[1];\n if (typeName && ![\"Query\", \"Mutation\", \"Subscription\"].includes(typeName)) {\n addedElements.push(`Added type: ${typeName}`);\n }\n }\n }\n\n // Check for added enums\n const enumMatches = addedContent.match(/enum\\s+(\\w+)\\s*{/g);\n if (enumMatches) {\n for (const match of enumMatches) {\n const enumName = match.match(/enum\\s+(\\w+)/)?.[1];\n if (enumName) {\n addedElements.push(`Added enum: ${enumName}`);\n }\n }\n }\n\n return addedElements;\n}\n\nexport const graphqlAnalyzer: Analyzer = {\n name: \"graphql\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n\n for (const diff of changeSet.diffs) {\n if (!isGraphQLSchema(diff.path)) {\n continue;\n }\n\n const additions = getAdditions(diff);\n const deletions = getDeletions(diff);\n\n const breakingChanges = analyzeBreakingChanges(deletions);\n const addedElements = analyzeAdditions(additions);\n\n // Determine if this is a breaking change\n const isBreaking = breakingChanges.length > 0;\n const hasAdditions = addedElements.length > 0;\n const hasDeletions = deletions.length > 0;\n\n // Create evidence\n const excerpt = isBreaking\n ? extractRepresentativeExcerpt(deletions)\n : extractRepresentativeExcerpt(additions);\n\n let confidence: Confidence = \"medium\";\n if (isBreaking) {\n confidence = \"high\";\n } else if (hasAdditions && !hasDeletions) {\n confidence = \"low\";\n }\n\n const finding: GraphQLChangeFinding = {\n type: \"graphql-change\",\n kind: \"graphql-change\",\n category: \"api\",\n confidence,\n evidence: [createEvidence(diff.path, excerpt)],\n file: diff.path,\n status: diff.status,\n isBreaking,\n breakingChanges: breakingChanges.slice(0, 5),\n addedElements: addedElements.slice(0, 5),\n };\n\n findings.push(finding);\n }\n\n return findings;\n },\n};\n",
36
- "/**\n * TypeScript configuration change detector.\n *\n * Detects changes to tsconfig.json files and identifies potentially\n * build-breaking or behavior-changing modifications.\n */\n\nimport { getAdditions, getDeletions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n TypeScriptConfigFinding,\n Confidence,\n} from \"../core/types.js\";\n\n// TypeScript config file patterns\nconst TSCONFIG_PATTERNS = [\n /^tsconfig\\.json$/,\n /^tsconfig\\.\\w+\\.json$/,\n /\\/tsconfig\\.json$/,\n /\\/tsconfig\\.\\w+\\.json$/,\n];\n\n// Critical compiler options that can break builds or change behavior\nconst CRITICAL_OPTIONS = new Set([\n \"strict\",\n \"strictNullChecks\",\n \"strictFunctionTypes\",\n \"strictBindCallApply\",\n \"strictPropertyInitialization\",\n \"noImplicitAny\",\n \"noImplicitThis\",\n \"noImplicitReturns\",\n \"noUncheckedIndexedAccess\",\n \"target\",\n \"module\",\n \"moduleResolution\",\n \"lib\",\n \"jsx\",\n \"esModuleInterop\",\n \"allowSyntheticDefaultImports\",\n \"skipLibCheck\",\n \"isolatedModules\",\n \"verbatimModuleSyntax\",\n \"baseUrl\",\n \"paths\",\n \"outDir\",\n \"rootDir\",\n \"declaration\",\n \"declarationMap\",\n \"sourceMap\",\n \"composite\",\n \"incremental\",\n \"emitDecoratorMetadata\",\n \"experimentalDecorators\",\n]);\n\n// Options that affect type checking strictness\nconst STRICTNESS_OPTIONS = new Set([\n \"strict\",\n \"strictNullChecks\",\n \"strictFunctionTypes\",\n \"strictBindCallApply\",\n \"strictPropertyInitialization\",\n \"noImplicitAny\",\n \"noImplicitThis\",\n \"noImplicitReturns\",\n \"noUncheckedIndexedAccess\",\n \"noUnusedLocals\",\n \"noUnusedParameters\",\n \"exactOptionalPropertyTypes\",\n]);\n\n/**\n * Check if a file is a TypeScript config file.\n */\nexport function isTsConfig(path: string): boolean {\n return TSCONFIG_PATTERNS.some((pattern) => pattern.test(path));\n}\n\n/**\n * Extract changed options from diff content.\n */\nfunction extractChangedOptions(\n additions: string[],\n deletions: string[]\n): { added: string[]; removed: string[]; modified: string[] } {\n const added: string[] = [];\n const removed: string[] = [];\n const modified: string[] = [];\n\n // Regex to match JSON property assignments\n const optionPattern = /\"(\\w+)\":\\s*/;\n\n const addedOptions = new Set<string>();\n const removedOptions = new Set<string>();\n\n for (const line of additions) {\n const match = line.match(optionPattern);\n if (match) {\n addedOptions.add(match[1]);\n }\n }\n\n for (const line of deletions) {\n const match = line.match(optionPattern);\n if (match) {\n removedOptions.add(match[1]);\n }\n }\n\n // Categorize: added, removed, or modified\n for (const opt of addedOptions) {\n if (removedOptions.has(opt)) {\n modified.push(opt);\n } else {\n added.push(opt);\n }\n }\n\n for (const opt of removedOptions) {\n if (!addedOptions.has(opt)) {\n removed.push(opt);\n }\n }\n\n return { added, removed, modified };\n}\n\n/**\n * Determine if changes are breaking.\n */\nfunction isBreakingChange(\n added: string[],\n removed: string[],\n modified: string[]\n): boolean {\n // Removing strictness options can silently break type safety\n // Adding strictness options can cause build failures\n for (const opt of [...added, ...removed, ...modified]) {\n if (CRITICAL_OPTIONS.has(opt)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Identify strictness-related changes.\n */\nfunction getStrictnessChanges(\n added: string[],\n removed: string[],\n modified: string[]\n): string[] {\n const changes: string[] = [];\n const allChanges = [...added, ...removed, ...modified];\n\n for (const opt of allChanges) {\n if (STRICTNESS_OPTIONS.has(opt)) {\n if (added.includes(opt)) {\n changes.push(`Added ${opt}`);\n } else if (removed.includes(opt)) {\n changes.push(`Removed ${opt}`);\n } else {\n changes.push(`Modified ${opt}`);\n }\n }\n }\n\n return changes;\n}\n\nexport const typescriptConfigAnalyzer: Analyzer = {\n name: \"typescript-config\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n\n for (const diff of changeSet.diffs) {\n if (!isTsConfig(diff.path)) {\n continue;\n }\n\n const additions = getAdditions(diff);\n const deletions = getDeletions(diff);\n\n const { added, removed, modified } = extractChangedOptions(\n additions,\n deletions\n );\n\n // Skip if no meaningful changes detected\n if (added.length === 0 && removed.length === 0 && modified.length === 0) {\n // Still report the file changed if there were additions/deletions\n if (additions.length > 0 || deletions.length > 0) {\n const finding: TypeScriptConfigFinding = {\n type: \"typescript-config\",\n kind: \"typescript-config\",\n category: \"config_env\",\n confidence: \"low\",\n evidence: [\n createEvidence(\n diff.path,\n extractRepresentativeExcerpt(additions.length > 0 ? additions : deletions)\n ),\n ],\n file: diff.path,\n status: diff.status,\n isBreaking: false,\n changedOptions: {\n added: [],\n removed: [],\n modified: [],\n },\n strictnessChanges: [],\n };\n findings.push(finding);\n }\n continue;\n }\n\n const isBreaking = isBreakingChange(added, removed, modified);\n const strictnessChanges = getStrictnessChanges(added, removed, modified);\n\n const confidence: Confidence = isBreaking ? \"high\" : \"medium\";\n\n const excerpt = extractRepresentativeExcerpt(\n additions.length > 0 ? additions : deletions\n );\n\n const finding: TypeScriptConfigFinding = {\n type: \"typescript-config\",\n kind: \"typescript-config\",\n category: \"config_env\",\n confidence,\n evidence: [createEvidence(diff.path, excerpt)],\n file: diff.path,\n status: diff.status,\n isBreaking,\n changedOptions: {\n added,\n removed,\n modified,\n },\n strictnessChanges,\n };\n\n findings.push(finding);\n }\n\n return findings;\n },\n};\n",
37
- "/**\n * Tailwind CSS configuration change detector.\n *\n * Detects changes to Tailwind CSS configuration files and identifies\n * potentially breaking changes to themes, plugins, or content paths.\n */\n\nimport { getAdditions, getDeletions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n TailwindConfigFinding,\n Confidence,\n} from \"../core/types.js\";\n\n// Tailwind config file patterns\nconst TAILWIND_PATTERNS = [\n /^tailwind\\.config\\.(js|cjs|mjs|ts)$/,\n /\\/tailwind\\.config\\.(js|cjs|mjs|ts)$/,\n];\n\n// PostCSS config (often related to Tailwind)\nconst POSTCSS_PATTERNS = [\n /^postcss\\.config\\.(js|cjs|mjs)$/,\n /\\/postcss\\.config\\.(js|cjs|mjs)$/,\n];\n\n// Critical configuration sections\nconst CRITICAL_SECTIONS = [\n \"theme\",\n \"content\",\n \"plugins\",\n \"presets\",\n \"prefix\",\n \"important\",\n \"darkMode\",\n \"safelist\",\n];\n\n// Theme subsections that affect styling\nconst THEME_SECTIONS = [\n \"colors\",\n \"spacing\",\n \"screens\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"extend\",\n \"borderRadius\",\n \"boxShadow\",\n \"animation\",\n \"keyframes\",\n];\n\n/**\n * Check if a file is a Tailwind config file.\n */\nexport function isTailwindConfig(path: string): boolean {\n return TAILWIND_PATTERNS.some((pattern) => pattern.test(path));\n}\n\n/**\n * Check if a file is a PostCSS config file.\n */\nexport function isPostCSSConfig(path: string): boolean {\n return POSTCSS_PATTERNS.some((pattern) => pattern.test(path));\n}\n\n/**\n * Extract affected sections from diff content.\n */\nfunction extractAffectedSections(content: string[]): string[] {\n const sections = new Set<string>();\n const fullContent = content.join(\"\\n\");\n\n // Check for critical section changes\n for (const section of CRITICAL_SECTIONS) {\n const pattern = new RegExp(`\\\\b${section}\\\\s*[:{]`, \"i\");\n if (pattern.test(fullContent)) {\n sections.add(section);\n }\n }\n\n // Check for theme subsection changes\n for (const section of THEME_SECTIONS) {\n const pattern = new RegExp(`\\\\b${section}\\\\s*[:{]`, \"i\");\n if (pattern.test(fullContent)) {\n sections.add(`theme.${section}`);\n }\n }\n\n return Array.from(sections);\n}\n\n/**\n * Check for potentially breaking changes.\n */\nfunction detectBreakingChanges(\n additions: string[],\n deletions: string[]\n): { isBreaking: boolean; reasons: string[] } {\n const reasons: string[] = [];\n const addedContent = additions.join(\"\\n\");\n const deletedContent = deletions.join(\"\\n\");\n\n // Content paths changed (can break purging)\n if (/\\bcontent\\s*[:{]/.test(deletedContent) || /\\bcontent\\s*[:{]/.test(addedContent)) {\n if (deletions.length > 0) {\n reasons.push(\"Content paths modified (may affect CSS purging)\");\n }\n }\n\n // Prefix changed (breaks all existing class usage)\n if (/\\bprefix\\s*[:{]/.test(deletedContent) && /\\bprefix\\s*[:{]/.test(addedContent)) {\n reasons.push(\"Class prefix changed (requires updating all class names)\");\n }\n\n // Theme colors removed\n if (/colors\\s*[:{]/.test(deletedContent)) {\n reasons.push(\"Theme colors modified (may break existing color classes)\");\n }\n\n // Screen breakpoints changed\n if (/screens\\s*[:{]/.test(deletedContent)) {\n reasons.push(\"Screen breakpoints modified (may affect responsive design)\");\n }\n\n // Plugins removed\n if (/plugins\\s*[:{]/.test(deletedContent) && deletions.some((l) => l.includes(\"require(\"))) {\n reasons.push(\"Plugins removed (may remove utility classes)\");\n }\n\n // Dark mode strategy changed\n if (/darkMode\\s*[:{]/.test(deletedContent) || /darkMode\\s*[:{]/.test(addedContent)) {\n reasons.push(\"Dark mode configuration changed\");\n }\n\n return {\n isBreaking: reasons.length > 0,\n reasons,\n };\n}\n\nexport const tailwindAnalyzer: Analyzer = {\n name: \"tailwind\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n\n for (const diff of changeSet.diffs) {\n const isTailwind = isTailwindConfig(diff.path);\n const isPostCSS = isPostCSSConfig(diff.path);\n\n if (!isTailwind && !isPostCSS) {\n continue;\n }\n\n const additions = getAdditions(diff);\n const deletions = getDeletions(diff);\n\n const affectedSections = extractAffectedSections([...additions, ...deletions]);\n const { isBreaking, reasons } = detectBreakingChanges(additions, deletions);\n\n const confidence: Confidence = isBreaking ? \"high\" : affectedSections.length > 0 ? \"medium\" : \"low\";\n\n const excerpt = extractRepresentativeExcerpt(\n additions.length > 0 ? additions : deletions\n );\n\n const finding: TailwindConfigFinding = {\n type: \"tailwind-config\",\n kind: \"tailwind-config\",\n category: \"config_env\",\n confidence,\n evidence: [createEvidence(diff.path, excerpt)],\n file: diff.path,\n status: diff.status,\n configType: isTailwind ? \"tailwind\" : \"postcss\",\n isBreaking,\n affectedSections,\n breakingReasons: reasons,\n };\n\n findings.push(finding);\n }\n\n return findings;\n },\n};\n",
38
- "/**\n * Monorepo configuration change detector.\n *\n * Detects changes to monorepo configuration files (Turborepo, pnpm workspaces,\n * Lerna, Nx, Yarn workspaces) and identifies potentially impactful modifications.\n */\n\nimport { getAdditions, getDeletions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n MonorepoConfigFinding,\n MonorepoTool,\n Confidence,\n} from \"../core/types.js\";\n\n// Monorepo config patterns by tool\nconst CONFIG_PATTERNS: Record<MonorepoTool, RegExp[]> = {\n turborepo: [/^turbo\\.json$/],\n pnpm: [/^pnpm-workspace\\.yaml$/, /^pnpm-workspace\\.yml$/],\n lerna: [/^lerna\\.json$/],\n nx: [/^nx\\.json$/, /^project\\.json$/],\n yarn: [/^\\.yarnrc\\.yml$/, /^\\.yarnrc$/],\n npm: [/^package\\.json$/], // For workspaces field only\n changesets: [/^\\.changeset\\/config\\.json$/],\n};\n\n// Critical configuration fields by tool\nconst CRITICAL_FIELDS: Record<MonorepoTool, string[]> = {\n turborepo: [\"pipeline\", \"globalDependencies\", \"globalEnv\", \"tasks\"],\n pnpm: [\"packages\"],\n lerna: [\"packages\", \"version\", \"npmClient\", \"useWorkspaces\"],\n nx: [\"targetDefaults\", \"namedInputs\", \"plugins\", \"defaultProject\"],\n yarn: [\"nodeLinker\", \"enableGlobalCache\", \"nmMode\"],\n npm: [\"workspaces\"],\n changesets: [\"baseBranch\", \"access\", \"changelog\"],\n};\n\n/**\n * Detect which monorepo tool a file belongs to.\n */\nexport function detectMonorepoTool(path: string): MonorepoTool | null {\n for (const [tool, patterns] of Object.entries(CONFIG_PATTERNS)) {\n if (patterns.some((pattern) => pattern.test(path))) {\n // Special case: package.json only counts if it has workspaces\n if (tool === \"npm\" && !path.endsWith(\"package.json\")) {\n continue;\n }\n return tool as MonorepoTool;\n }\n }\n return null;\n}\n\n/**\n * Check if package.json has workspace changes.\n */\nfunction hasWorkspaceChanges(additions: string[], deletions: string[]): boolean {\n const allContent = [...additions, ...deletions].join(\"\\n\");\n return /[\"']workspaces[\"']/.test(allContent);\n}\n\n/**\n * Extract affected fields from diff content.\n */\nfunction extractAffectedFields(content: string[], tool: MonorepoTool): string[] {\n const criticalFields = CRITICAL_FIELDS[tool] || [];\n const affected: string[] = [];\n const fullContent = content.join(\"\\n\");\n\n for (const field of criticalFields) {\n const pattern = new RegExp(`[\"']?${field}[\"']?\\\\s*[:{[]`, \"i\");\n if (pattern.test(fullContent)) {\n affected.push(field);\n }\n }\n\n return affected;\n}\n\n/**\n * Detect potentially impactful changes.\n */\nfunction detectImpactfulChanges(\n tool: MonorepoTool,\n additions: string[],\n deletions: string[]\n): string[] {\n const impacts: string[] = [];\n const addedContent = additions.join(\"\\n\");\n const deletedContent = deletions.join(\"\\n\");\n\n switch (tool) {\n case \"turborepo\":\n if (/pipeline|tasks/.test(deletedContent)) {\n impacts.push(\"Build pipeline configuration changed\");\n }\n if (/cache\\s*[:=]\\s*false/.test(addedContent)) {\n impacts.push(\"Caching disabled for tasks\");\n }\n if (/globalDependencies/.test(addedContent) || /globalDependencies/.test(deletedContent)) {\n impacts.push(\"Global dependencies changed (affects cache invalidation)\");\n }\n break;\n\n case \"pnpm\":\n if (/packages/.test(deletedContent)) {\n impacts.push(\"Workspace packages configuration changed\");\n }\n break;\n\n case \"lerna\":\n if (/version/.test(addedContent) && /independent/.test(addedContent)) {\n impacts.push(\"Switching to independent versioning\");\n }\n if (/npmClient/.test(addedContent) || /npmClient/.test(deletedContent)) {\n impacts.push(\"npm client configuration changed\");\n }\n break;\n\n case \"nx\":\n if (/targetDefaults/.test(deletedContent)) {\n impacts.push(\"Default target configuration changed\");\n }\n if (/plugins/.test(addedContent) || /plugins/.test(deletedContent)) {\n impacts.push(\"Nx plugins configuration changed\");\n }\n break;\n\n case \"yarn\":\n if (/nodeLinker/.test(addedContent) || /nodeLinker/.test(deletedContent)) {\n impacts.push(\"Node linker strategy changed (affects dependency resolution)\");\n }\n break;\n\n case \"npm\":\n if (/workspaces/.test(deletedContent)) {\n impacts.push(\"Workspace packages configuration changed\");\n }\n break;\n\n case \"changesets\":\n if (/baseBranch/.test(addedContent) || /baseBranch/.test(deletedContent)) {\n impacts.push(\"Base branch for changesets modified\");\n }\n if (/access/.test(addedContent)) {\n impacts.push(\"Package publish access level changed\");\n }\n break;\n }\n\n return impacts;\n}\n\nexport const monorepoAnalyzer: Analyzer = {\n name: \"monorepo\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n\n for (const diff of changeSet.diffs) {\n const tool = detectMonorepoTool(diff.path);\n\n if (!tool) {\n continue;\n }\n\n const additions = getAdditions(diff);\n const deletions = getDeletions(diff);\n\n // For package.json, only report if workspaces field is affected\n if (tool === \"npm\" && !hasWorkspaceChanges(additions, deletions)) {\n continue;\n }\n\n const affectedFields = extractAffectedFields([...additions, ...deletions], tool);\n const impacts = detectImpactfulChanges(tool, additions, deletions);\n\n // Skip if no meaningful changes detected\n if (affectedFields.length === 0 && impacts.length === 0) {\n continue;\n }\n\n const isBreaking = impacts.length > 0;\n const confidence: Confidence = isBreaking ? \"high\" : \"medium\";\n\n const excerpt = extractRepresentativeExcerpt(\n additions.length > 0 ? additions : deletions\n );\n\n const finding: MonorepoConfigFinding = {\n type: \"monorepo-config\",\n kind: \"monorepo-config\",\n category: \"config_env\",\n confidence,\n evidence: [createEvidence(diff.path, excerpt)],\n file: diff.path,\n status: diff.status,\n tool,\n affectedFields,\n impacts,\n };\n\n findings.push(finding);\n }\n\n return findings;\n },\n};\n",
39
- "/**\n * Package exports change detector.\n *\n * Detects changes to package.json exports field which is critical for\n * library consumers. Changes to exports can be breaking changes.\n */\n\nimport { createEvidence } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Finding,\n PackageExportsFinding,\n Confidence,\n} from \"../core/types.js\";\n\ntype ExportsField = string | Record<string, unknown> | null;\n\n/**\n * Flatten exports field into a list of export paths.\n */\nfunction flattenExports(\n exports: ExportsField,\n prefix: string = \"\"\n): string[] {\n if (!exports) {\n return [];\n }\n\n if (typeof exports === \"string\") {\n return [prefix || \".\"];\n }\n\n if (typeof exports === \"object\") {\n const paths: string[] = [];\n\n for (const [key, value] of Object.entries(exports)) {\n // Conditional exports (e.g., \"import\", \"require\", \"types\")\n if (key.startsWith(\".\")) {\n paths.push(...flattenExports(value as ExportsField, key));\n } else {\n // This is a condition, not a subpath\n if (typeof value === \"string\" || typeof value === \"object\") {\n paths.push(...flattenExports(value as ExportsField, prefix));\n }\n }\n }\n\n // Remove duplicates\n return [...new Set(paths)];\n }\n\n return [];\n}\n\n/**\n * Compare exports between base and head package.json.\n */\nfunction compareExports(\n baseExports: ExportsField,\n headExports: ExportsField\n): {\n added: string[];\n removed: string[];\n hasExportsField: { base: boolean; head: boolean };\n} {\n const basePaths = flattenExports(baseExports);\n const headPaths = flattenExports(headExports);\n\n const baseSet = new Set(basePaths);\n const headSet = new Set(headPaths);\n\n const added = headPaths.filter((p) => !baseSet.has(p));\n const removed = basePaths.filter((p) => !headSet.has(p));\n\n return {\n added,\n removed,\n hasExportsField: {\n base: baseExports !== undefined && baseExports !== null,\n head: headExports !== undefined && headExports !== null,\n },\n };\n}\n\n/**\n * Check for main/module/types field changes (legacy entry points).\n */\nfunction compareLegacyFields(\n base: Record<string, unknown> | undefined,\n head: Record<string, unknown> | undefined\n): { field: string; from?: string; to?: string }[] {\n const fields = [\"main\", \"module\", \"types\", \"typings\", \"browser\"];\n const changes: { field: string; from?: string; to?: string }[] = [];\n\n for (const field of fields) {\n const baseValue = base?.[field] as string | undefined;\n const headValue = head?.[field] as string | undefined;\n\n if (baseValue !== headValue) {\n changes.push({\n field,\n from: baseValue,\n to: headValue,\n });\n }\n }\n\n return changes;\n}\n\n/**\n * Check for bin field changes.\n */\nfunction compareBinField(\n base: Record<string, unknown> | undefined,\n head: Record<string, unknown> | undefined\n): { added: string[]; removed: string[] } {\n const baseBin = base?.bin;\n const headBin = head?.bin;\n\n const getNames = (bin: unknown): string[] => {\n if (typeof bin === \"string\") {\n return [\"(default)\"];\n }\n if (typeof bin === \"object\" && bin !== null) {\n return Object.keys(bin);\n }\n return [];\n };\n\n const baseNames = new Set(getNames(baseBin));\n const headNames = new Set(getNames(headBin));\n\n return {\n added: [...headNames].filter((n) => !baseNames.has(n)),\n removed: [...baseNames].filter((n) => !headNames.has(n)),\n };\n}\n\nexport const packageExportsAnalyzer: Analyzer = {\n name: \"package-exports\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n\n const base = changeSet.basePackageJson;\n const head = changeSet.headPackageJson;\n\n // Skip if neither version has a package.json\n if (!base && !head) {\n return findings;\n }\n\n // Compare exports field\n const baseExports = base?.exports as ExportsField | undefined;\n const headExports = head?.exports as ExportsField | undefined;\n\n const exportsComparison = compareExports(\n baseExports ?? null,\n headExports ?? null\n );\n\n // Compare legacy entry point fields\n const legacyChanges = compareLegacyFields(base, head);\n\n // Compare bin field\n const binChanges = compareBinField(base, head);\n\n // Determine if there are breaking changes\n const hasRemovedExports = exportsComparison.removed.length > 0;\n const hasRemovedBins = binChanges.removed.length > 0;\n const hasRemovedLegacy = legacyChanges.some(\n (c) => c.from !== undefined && c.to === undefined\n );\n const isBreaking = hasRemovedExports || hasRemovedBins || hasRemovedLegacy;\n\n // Skip if no changes to exports/entry points\n const hasExportsChanges =\n exportsComparison.added.length > 0 ||\n exportsComparison.removed.length > 0;\n const hasLegacyChanges = legacyChanges.length > 0;\n const hasBinChanges =\n binChanges.added.length > 0 || binChanges.removed.length > 0;\n\n if (!hasExportsChanges && !hasLegacyChanges && !hasBinChanges) {\n return findings;\n }\n\n // Determine confidence\n let confidence: Confidence = \"medium\";\n if (isBreaking) {\n confidence = \"high\";\n } else if (\n exportsComparison.added.length > 0 ||\n binChanges.added.length > 0\n ) {\n confidence = \"low\";\n }\n\n // Create excerpt summarizing changes\n const excerptParts: string[] = [];\n if (exportsComparison.removed.length > 0) {\n excerptParts.push(\n `Removed exports: ${exportsComparison.removed.slice(0, 3).join(\", \")}`\n );\n }\n if (exportsComparison.added.length > 0) {\n excerptParts.push(\n `Added exports: ${exportsComparison.added.slice(0, 3).join(\", \")}`\n );\n }\n if (legacyChanges.length > 0) {\n excerptParts.push(\n `Changed fields: ${legacyChanges.map((c) => c.field).join(\", \")}`\n );\n }\n if (binChanges.removed.length > 0) {\n excerptParts.push(`Removed bins: ${binChanges.removed.join(\", \")}`);\n }\n if (binChanges.added.length > 0) {\n excerptParts.push(`Added bins: ${binChanges.added.join(\", \")}`);\n }\n\n const finding: PackageExportsFinding = {\n type: \"package-exports\",\n kind: \"package-exports\",\n category: \"api\",\n confidence,\n evidence: [createEvidence(\"package.json\", excerptParts.join(\"; \"))],\n isBreaking,\n addedExports: exportsComparison.added,\n removedExports: exportsComparison.removed,\n legacyFieldChanges: legacyChanges,\n binChanges: {\n added: binChanges.added,\n removed: binChanges.removed,\n },\n };\n\n findings.push(finding);\n\n return findings;\n },\n};\n",
40
- "/**\n * Vue.js and Nuxt route change detector.\n *\n * Detects changes to Vue Router and Nuxt file-based routes.\n */\n\nimport { getAdditions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Evidence,\n Finding,\n RouteChangeFinding,\n RouteType,\n} from \"../core/types.js\";\n\n// Nuxt 3 pages directory pattern\nconst NUXT_PAGES_PATTERN = /^(pages|src\\/pages)\\/(.+)\\.(vue|ts|tsx|js|jsx)$/;\n\n// Nuxt 3 server routes pattern\nconst NUXT_SERVER_PATTERN = /^server\\/(api|routes|middleware)\\/(.+)\\.(ts|js)$/;\n\n// Nuxt layouts pattern\nconst NUXT_LAYOUTS_PATTERN = /^(layouts|src\\/layouts)\\/(.+)\\.vue$/;\n\n// Vue Router config patterns\nconst VUE_ROUTER_PATTERNS = [\n /router\\.(ts|js)$/,\n /routes\\.(ts|js)$/,\n /router\\/index\\.(ts|js)$/,\n];\n\n/**\n * Check if file is a Nuxt page route.\n */\nexport function isNuxtPage(path: string): boolean {\n return NUXT_PAGES_PATTERN.test(path);\n}\n\n/**\n * Check if file is a Nuxt server route.\n */\nexport function isNuxtServerRoute(path: string): boolean {\n return NUXT_SERVER_PATTERN.test(path);\n}\n\n/**\n * Check if file is a Nuxt layout.\n */\nexport function isNuxtLayout(path: string): boolean {\n return NUXT_LAYOUTS_PATTERN.test(path);\n}\n\n/**\n * Check if file is Vue Router configuration.\n */\nexport function isVueRouterConfig(path: string): boolean {\n return VUE_ROUTER_PATTERNS.some((pattern) => pattern.test(path));\n}\n\n/**\n * Convert Nuxt file path to route path.\n * Examples:\n * - pages/index.vue -> /\n * - pages/about.vue -> /about\n * - pages/users/[id].vue -> /users/:id\n * - pages/[...slug].vue -> /:slug*\n */\nexport function nuxtFileToRoute(filePath: string): string {\n const match = filePath.match(NUXT_PAGES_PATTERN);\n if (!match) return filePath;\n\n let routePath = match[2];\n\n // Remove file extension part if it's like .get, .post, etc.\n routePath = routePath.replace(/\\.(get|post|put|delete|patch)$/i, \"\");\n\n // Convert to route path\n routePath = routePath\n // index -> /\n .replace(/\\/index$/, \"\")\n .replace(/^index$/, \"\")\n // [...slug] -> :slug*\n .replace(/\\[\\.\\.\\.(\\w+)\\]/g, \":$1*\")\n // [id] -> :id\n .replace(/\\[(\\w+)\\]/g, \":$1\");\n\n return \"/\" + routePath;\n}\n\n/**\n * Detect HTTP method from Nuxt server route filename.\n */\nfunction detectNuxtServerMethod(filePath: string): string[] {\n const methods: string[] = [];\n\n // Method can be in filename: route.get.ts, route.post.ts\n const methodMatch = filePath.match(/\\.(\\w+)\\.(ts|js)$/);\n if (methodMatch) {\n const method = methodMatch[1].toUpperCase();\n if ([\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"HEAD\", \"OPTIONS\"].includes(method)) {\n methods.push(method);\n }\n }\n\n // Default to all methods if no specific method detected\n if (methods.length === 0) {\n methods.push(\"*\");\n }\n\n return methods;\n}\n\n/**\n * Determine route type from file path.\n */\nfunction getRouteType(filePath: string): RouteType {\n if (isNuxtServerRoute(filePath)) {\n return \"endpoint\";\n }\n if (isNuxtLayout(filePath)) {\n return \"layout\";\n }\n if (\n filePath.includes(\"error.vue\") ||\n filePath.includes(\"404.vue\") ||\n filePath.includes(\"500.vue\")\n ) {\n return \"error\";\n }\n return \"page\";\n}\n\nexport const vueRoutesAnalyzer: Analyzer = {\n name: \"vue-routes\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n\n for (const file of changeSet.files) {\n const isPage = isNuxtPage(file.path);\n const isServer = isNuxtServerRoute(file.path);\n const isLayout = isNuxtLayout(file.path);\n const isRouterConfig = isVueRouterConfig(file.path);\n\n if (!isPage && !isServer && !isLayout && !isRouterConfig) {\n continue;\n }\n\n // For router config files, just report the change\n if (isRouterConfig) {\n const diff = changeSet.diffs.find((d) => d.path === file.path);\n const additions = diff ? getAdditions(diff) : [];\n const excerpt = extractRepresentativeExcerpt(additions);\n\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"medium\",\n evidence: [createEvidence(file.path, excerpt || \"Vue Router config changed\")],\n routeId: \"vue-router-config\",\n file: file.path,\n change: file.status,\n routeType: \"unknown\",\n };\n findings.push(finding);\n continue;\n }\n\n // Get route details\n const routeId = isPage ? nuxtFileToRoute(file.path) : file.path;\n const routeType = getRouteType(file.path);\n const methods = isServer ? detectNuxtServerMethod(file.path) : undefined;\n\n // Get evidence from diff\n const diff = changeSet.diffs.find((d) => d.path === file.path);\n const additions = diff ? getAdditions(diff) : [];\n const excerpt = extractRepresentativeExcerpt(additions);\n\n const evidence: Evidence[] = [];\n if (excerpt) {\n evidence.push(createEvidence(file.path, excerpt));\n }\n\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"high\",\n evidence,\n routeId,\n file: file.path,\n change: file.status,\n routeType,\n methods,\n };\n\n findings.push(finding);\n }\n\n return findings;\n },\n};\n",
41
- "/**\n * Astro route and page change detector.\n *\n * Detects changes to Astro pages, API routes, and layouts.\n */\n\nimport { getAdditions } from \"../git/parser.js\";\nimport { createEvidence, extractRepresentativeExcerpt } from \"../core/evidence.js\";\nimport type {\n Analyzer,\n ChangeSet,\n Evidence,\n Finding,\n RouteChangeFinding,\n RouteType,\n} from \"../core/types.js\";\n\n// Astro pages directory pattern\nconst ASTRO_PAGES_PATTERN = /^src\\/pages\\/(.+)\\.(astro|md|mdx|html|ts|js)$/;\n\n// Astro layouts pattern\nconst ASTRO_LAYOUTS_PATTERN = /^src\\/layouts\\/(.+)\\.astro$/;\n\n// Astro content collections pattern\nconst ASTRO_CONTENT_PATTERN = /^src\\/content\\/(.+)\\.(md|mdx|json|yaml|yml)$/;\n\n// Astro config pattern\nconst ASTRO_CONFIG_PATTERN = /^astro\\.config\\.(mjs|ts|js)$/;\n\n/**\n * Check if file is an Astro page.\n */\nexport function isAstroPage(path: string): boolean {\n return ASTRO_PAGES_PATTERN.test(path);\n}\n\n/**\n * Check if file is an Astro API endpoint.\n */\nexport function isAstroEndpoint(path: string): boolean {\n return ASTRO_PAGES_PATTERN.test(path) && /\\.(ts|js)$/.test(path);\n}\n\n/**\n * Check if file is an Astro layout.\n */\nexport function isAstroLayout(path: string): boolean {\n return ASTRO_LAYOUTS_PATTERN.test(path);\n}\n\n/**\n * Check if file is Astro content.\n */\nexport function isAstroContent(path: string): boolean {\n return ASTRO_CONTENT_PATTERN.test(path);\n}\n\n/**\n * Check if file is Astro config.\n */\nexport function isAstroConfig(path: string): boolean {\n return ASTRO_CONFIG_PATTERN.test(path);\n}\n\n/**\n * Convert Astro file path to route path.\n * Examples:\n * - src/pages/index.astro -> /\n * - src/pages/about.astro -> /about\n * - src/pages/blog/[slug].astro -> /blog/:slug\n * - src/pages/[...slug].astro -> /:slug*\n */\nexport function astroFileToRoute(filePath: string): string {\n const match = filePath.match(ASTRO_PAGES_PATTERN);\n if (!match) return filePath;\n\n let routePath = match[1];\n\n // Remove file extension\n routePath = routePath.replace(/\\.(astro|md|mdx|html|ts|js)$/, \"\");\n\n // Convert to route path\n routePath = routePath\n // index -> /\n .replace(/\\/index$/, \"\")\n .replace(/^index$/, \"\")\n // [...slug] -> :slug*\n .replace(/\\[\\.\\.\\.(\\w+)\\]/g, \":$1*\")\n // [id] -> :id\n .replace(/\\[(\\w+)\\]/g, \":$1\");\n\n return \"/\" + routePath;\n}\n\n/**\n * Detect HTTP methods from Astro endpoint content.\n */\nfunction detectAstroEndpointMethods(additions: string[]): string[] {\n const methods: string[] = [];\n const content = additions.join(\"\\n\");\n\n // Astro exports functions for each HTTP method\n const methodPatterns = [\n { pattern: /export\\s+(const|function|async function)\\s+GET\\b/, method: \"GET\" },\n { pattern: /export\\s+(const|function|async function)\\s+POST\\b/, method: \"POST\" },\n { pattern: /export\\s+(const|function|async function)\\s+PUT\\b/, method: \"PUT\" },\n { pattern: /export\\s+(const|function|async function)\\s+DELETE\\b/, method: \"DELETE\" },\n { pattern: /export\\s+(const|function|async function)\\s+PATCH\\b/, method: \"PATCH\" },\n { pattern: /export\\s+(const|function|async function)\\s+ALL\\b/, method: \"*\" },\n ];\n\n for (const { pattern, method } of methodPatterns) {\n if (pattern.test(content)) {\n methods.push(method);\n }\n }\n\n return methods;\n}\n\n/**\n * Determine route type from file path and content.\n */\nfunction getRouteType(filePath: string): RouteType {\n if (isAstroLayout(filePath)) {\n return \"layout\";\n }\n if (isAstroEndpoint(filePath)) {\n return \"endpoint\";\n }\n if (filePath.includes(\"404.\") || filePath.includes(\"500.\")) {\n return \"error\";\n }\n return \"page\";\n}\n\nexport const astroRoutesAnalyzer: Analyzer = {\n name: \"astro-routes\",\n\n analyze(changeSet: ChangeSet): Finding[] {\n const findings: Finding[] = [];\n\n for (const file of changeSet.files) {\n const isPage = isAstroPage(file.path);\n const isLayout = isAstroLayout(file.path);\n const isContent = isAstroContent(file.path);\n const isConfig = isAstroConfig(file.path);\n\n if (!isPage && !isLayout && !isContent && !isConfig) {\n continue;\n }\n\n // Get evidence from diff\n const diff = changeSet.diffs.find((d) => d.path === file.path);\n const additions = diff ? getAdditions(diff) : [];\n const excerpt = extractRepresentativeExcerpt(additions);\n\n // For config files, just report the change\n if (isConfig) {\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"medium\",\n evidence: [createEvidence(file.path, excerpt || \"Astro config changed\")],\n routeId: \"astro-config\",\n file: file.path,\n change: file.status,\n routeType: \"unknown\",\n };\n findings.push(finding);\n continue;\n }\n\n // For content files, report as content change\n if (isContent) {\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"high\",\n evidence: excerpt ? [createEvidence(file.path, excerpt)] : [],\n routeId: file.path.replace(/^src\\/content\\//, \"/content/\"),\n file: file.path,\n change: file.status,\n routeType: \"page\",\n tags: [\"content-collection\"],\n };\n findings.push(finding);\n continue;\n }\n\n // Get route details for pages and layouts\n const routeId = isPage ? astroFileToRoute(file.path) : file.path;\n const routeType = getRouteType(file.path);\n const endpointMethods = isAstroEndpoint(file.path)\n ? detectAstroEndpointMethods(additions)\n : [];\n const methods = endpointMethods.length > 0 ? endpointMethods : undefined;\n\n const evidence: Evidence[] = [];\n if (excerpt) {\n evidence.push(createEvidence(file.path, excerpt));\n }\n\n const finding: RouteChangeFinding = {\n type: \"route-change\",\n kind: \"route-change\",\n category: \"routes\",\n confidence: \"high\",\n evidence,\n routeId,\n file: file.path,\n change: file.status,\n routeType,\n methods,\n };\n\n findings.push(finding);\n }\n\n return findings;\n },\n};\n",
42
- "/**\n * Analyzer module exports.\n */\n\nexport * from \"./file-summary.js\";\nexport * from \"./file-category.js\";\nexport * from \"./route-detector.js\";\nexport * from \"./supabase.js\";\nexport * from \"./env-var.js\";\nexport * from \"./cloudflare.js\";\nexport * from \"./vitest.js\";\nexport * from \"./dependencies.js\";\nexport * from \"./security-files.js\";\nexport { reactRouterRoutesAnalyzer } from \"./reactRouterRoutes.js\";\nexport * from \"./test-parity.js\";\nexport * from \"./impact.js\";\nexport * from \"./large-diff.js\";\nexport * from \"./lockfiles.js\";\nexport * from \"./test-gaps.js\";\nexport * from \"./sql-risks.js\";\nexport * from \"./ci-workflows.js\";\nexport * from \"./infra.js\";\nexport * from \"./api-contracts.js\";\nexport { stencilAnalyzer } from \"./stencil.js\";\nexport { nextRoutesAnalyzer } from \"./next-routes.js\";\nexport { graphqlAnalyzer } from \"./graphql.js\";\nexport { typescriptConfigAnalyzer } from \"./typescript-config.js\";\nexport { tailwindAnalyzer } from \"./tailwind.js\";\nexport { monorepoAnalyzer } from \"./monorepo.js\";\nexport { packageExportsAnalyzer } from \"./package-exports.js\";\nexport { vueRoutesAnalyzer } from \"./vue-routes.js\";\nexport { astroRoutesAnalyzer } from \"./astro-routes.js\";\n\n",
43
- "/**\n * Default profile - generic analyzers for any project.\n */\n\nimport type { Profile } from \"../core/types.js\";\nimport {\n cloudflareAnalyzer,\n dependencyAnalyzer,\n envVarAnalyzer,\n fileCategoryAnalyzer,\n fileSummaryAnalyzer,\n securityFilesAnalyzer,\n vitestAnalyzer,\n impactAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n graphqlAnalyzer,\n} from \"../analyzers/index.js\";\n\n/**\n * Default profile with generic analyzers (no SvelteKit-specific ones).\n */\nexport const defaultProfile: Profile = {\n name: \"auto\", // Will be resolved to actual profile name\n analyzers: [\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n envVarAnalyzer,\n cloudflareAnalyzer,\n vitestAnalyzer,\n dependencyAnalyzer,\n securityFilesAnalyzer,\n impactAnalyzer,\n graphqlAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n ],\n};\n",
44
- "/**\n * SvelteKit profile - composes analyzers for SvelteKit projects.\n */\n\nimport type { Profile } from \"../core/types.js\";\nimport {\n cloudflareAnalyzer,\n dependencyAnalyzer,\n envVarAnalyzer,\n fileCategoryAnalyzer,\n fileSummaryAnalyzer,\n routeDetectorAnalyzer,\n securityFilesAnalyzer,\n supabaseAnalyzer,\n vitestAnalyzer,\n impactAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n} from \"../analyzers/index.js\";\nimport { tailwindAnalyzer } from \"../analyzers/tailwind.js\";\n\n/**\n * SvelteKit profile with all relevant analyzers.\n */\nexport const sveltekitProfile: Profile = {\n name: \"sveltekit\",\n analyzers: [\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n routeDetectorAnalyzer,\n supabaseAnalyzer,\n envVarAnalyzer,\n cloudflareAnalyzer,\n vitestAnalyzer,\n dependencyAnalyzer,\n securityFilesAnalyzer,\n impactAnalyzer,\n tailwindAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n ],\n};\n",
45
- "/**\n * React profile - composes analyzers for React projects.\n */\n\nimport type { Profile } from \"../core/types.js\";\nimport {\n cloudflareAnalyzer,\n dependencyAnalyzer,\n envVarAnalyzer,\n fileCategoryAnalyzer,\n fileSummaryAnalyzer,\n reactRouterRoutesAnalyzer,\n securityFilesAnalyzer,\n vitestAnalyzer,\n impactAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n} from \"../analyzers/index.js\";\nimport { tailwindAnalyzer } from \"../analyzers/tailwind.js\";\nimport { typescriptConfigAnalyzer } from \"../analyzers/typescript-config.js\";\n\n/**\n * React profile with all relevant analyzers.\n */\nexport const reactProfile: Profile = {\n name: \"react\",\n analyzers: [\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n reactRouterRoutesAnalyzer,\n envVarAnalyzer,\n cloudflareAnalyzer,\n vitestAnalyzer,\n dependencyAnalyzer,\n securityFilesAnalyzer,\n impactAnalyzer,\n tailwindAnalyzer,\n typescriptConfigAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n ],\n};\n",
46
- "/**\n * Stencil profile definition.\n */\n\nimport type { Profile } from \"../core/types.js\";\nimport {\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n dependencyAnalyzer,\n impactAnalyzer,\n stencilAnalyzer,\n envVarAnalyzer,\n cloudflareAnalyzer,\n vitestAnalyzer,\n securityFilesAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n} from \"../analyzers/index.js\";\nimport { typescriptConfigAnalyzer } from \"../analyzers/typescript-config.js\";\n\nexport const stencilProfile: Profile = {\n name: \"stencil\",\n analyzers: [\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n stencilAnalyzer,\n envVarAnalyzer,\n cloudflareAnalyzer,\n vitestAnalyzer,\n dependencyAnalyzer,\n securityFilesAnalyzer,\n impactAnalyzer,\n typescriptConfigAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n ],\n};\n",
47
- "/**\n * Next.js profile - composes analyzers for Next.js App Router projects.\n */\n\nimport type { Profile } from \"../core/types.js\";\nimport {\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n cloudflareAnalyzer,\n dependencyAnalyzer,\n envVarAnalyzer,\n fileCategoryAnalyzer,\n fileSummaryAnalyzer,\n securityFilesAnalyzer,\n vitestAnalyzer,\n impactAnalyzer,\n} from \"../analyzers/index.js\";\nimport { nextRoutesAnalyzer } from \"../analyzers/next-routes.js\";\nimport { tailwindAnalyzer } from \"../analyzers/tailwind.js\";\n\n/**\n * Next.js profile with all relevant analyzers for App Router projects.\n */\nexport const nextProfile: Profile = {\n name: \"next\",\n analyzers: [\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n nextRoutesAnalyzer,\n envVarAnalyzer,\n cloudflareAnalyzer,\n vitestAnalyzer,\n dependencyAnalyzer,\n securityFilesAnalyzer,\n impactAnalyzer,\n tailwindAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n ],\n};\n",
48
- "/**\n * Vue.js / Nuxt profile - analyzers for Vue and Nuxt projects.\n */\n\nimport type { Profile } from \"../core/types.js\";\nimport {\n cloudflareAnalyzer,\n dependencyAnalyzer,\n envVarAnalyzer,\n fileCategoryAnalyzer,\n fileSummaryAnalyzer,\n securityFilesAnalyzer,\n vitestAnalyzer,\n impactAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n} from \"../analyzers/index.js\";\nimport { vueRoutesAnalyzer } from \"../analyzers/vue-routes.js\";\nimport { tailwindAnalyzer } from \"../analyzers/tailwind.js\";\nimport { typescriptConfigAnalyzer } from \"../analyzers/typescript-config.js\";\n\n/**\n * Vue/Nuxt profile with Vue-specific analyzers.\n */\nexport const vueProfile: Profile = {\n name: \"vue\",\n analyzers: [\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n vueRoutesAnalyzer,\n envVarAnalyzer,\n cloudflareAnalyzer,\n vitestAnalyzer,\n dependencyAnalyzer,\n securityFilesAnalyzer,\n impactAnalyzer,\n tailwindAnalyzer,\n typescriptConfigAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n ],\n};\n",
49
- "/**\n * Astro profile - analyzers for Astro projects.\n */\n\nimport type { Profile } from \"../core/types.js\";\nimport {\n cloudflareAnalyzer,\n dependencyAnalyzer,\n envVarAnalyzer,\n fileCategoryAnalyzer,\n fileSummaryAnalyzer,\n securityFilesAnalyzer,\n vitestAnalyzer,\n impactAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n} from \"../analyzers/index.js\";\nimport { astroRoutesAnalyzer } from \"../analyzers/astro-routes.js\";\nimport { tailwindAnalyzer } from \"../analyzers/tailwind.js\";\nimport { typescriptConfigAnalyzer } from \"../analyzers/typescript-config.js\";\n\n/**\n * Astro profile with Astro-specific analyzers.\n */\nexport const astroProfile: Profile = {\n name: \"astro\",\n analyzers: [\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n astroRoutesAnalyzer,\n envVarAnalyzer,\n cloudflareAnalyzer,\n vitestAnalyzer,\n dependencyAnalyzer,\n securityFilesAnalyzer,\n impactAnalyzer,\n tailwindAnalyzer,\n typescriptConfigAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeSQLRisks,\n analyzeCIWorkflows,\n analyzeInfra,\n analyzeAPIContracts,\n ],\n};\n",
50
- "/**\n * Library profile - analyzers for npm package/library development.\n *\n * This profile focuses on API surface changes, breaking changes detection,\n * and package metadata that matters for library consumers.\n */\n\nimport type { Profile } from \"../core/types.js\";\nimport {\n dependencyAnalyzer,\n fileCategoryAnalyzer,\n fileSummaryAnalyzer,\n vitestAnalyzer,\n impactAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeCIWorkflows,\n analyzeAPIContracts,\n} from \"../analyzers/index.js\";\nimport { packageExportsAnalyzer } from \"../analyzers/package-exports.js\";\nimport { typescriptConfigAnalyzer } from \"../analyzers/typescript-config.js\";\nimport { monorepoAnalyzer } from \"../analyzers/monorepo.js\";\n\n/**\n * Library/Package profile with analyzers focused on API surface and breaking changes.\n */\nexport const libraryProfile: Profile = {\n name: \"library\",\n analyzers: [\n fileSummaryAnalyzer,\n fileCategoryAnalyzer,\n packageExportsAnalyzer,\n typescriptConfigAnalyzer,\n dependencyAnalyzer,\n vitestAnalyzer,\n impactAnalyzer,\n monorepoAnalyzer,\n analyzeLargeDiff,\n analyzeLockfiles,\n analyzeTestGaps,\n analyzeCIWorkflows,\n analyzeAPIContracts,\n ],\n};\n",
51
- "/**\n * Profile detection and management.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ChangeSet, Profile, ProfileName } from \"../core/types.js\";\nimport { defaultProfile } from \"./default.js\";\nimport { sveltekitProfile } from \"./sveltekit.js\";\nimport { reactProfile } from \"./react.js\";\nimport { stencilProfile } from \"./stencil.js\";\nimport { nextProfile } from \"./next.js\";\nimport { vueProfile } from \"./vue.js\";\nimport { astroProfile } from \"./astro.js\";\nimport { libraryProfile } from \"./library.js\";\n\n/**\n * Result of profile detection with reasons.\n */\nexport interface ProfileDetectionResult {\n profile: ProfileName;\n confidence: \"high\" | \"medium\" | \"low\";\n reasons: string[];\n}\n\n/**\n * Check if a project is a SvelteKit project.\n */\nexport function isSvelteKitProject(cwd: string = process.cwd()): boolean {\n // Check for src/routes directory\n if (existsSync(join(cwd, \"src\", \"routes\"))) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Check if package.json contains @sveltejs/kit.\n */\nexport function hasSvelteKitDependency(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n const deps = packageJson.dependencies as Record<string, string> | undefined;\n const devDeps = packageJson.devDependencies as\n | Record<string, string>\n | undefined;\n\n return Boolean(\n deps?.[\"@sveltejs/kit\"] || devDeps?.[\"@sveltejs/kit\"]\n );\n}\n\n/**\n * Check if package.json contains React dependencies.\n */\nexport function hasReactDependency(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n const deps = packageJson.dependencies as Record<string, string> | undefined;\n const devDeps = packageJson.devDependencies as\n | Record<string, string>\n | undefined;\n\n return Boolean(\n (deps?.[\"react\"] && deps?.[\"react-dom\"]) ||\n (devDeps?.[\"react\"] && devDeps?.[\"react-dom\"])\n );\n}\n\n/**\n * Check if package.json contains React Router dependencies.\n */\nexport function hasReactRouterDependency(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n const deps = packageJson.dependencies as Record<string, string> | undefined;\n const devDeps = packageJson.devDependencies as\n | Record<string, string>\n | undefined;\n\n return Boolean(\n deps?.[\"react-router\"] ||\n deps?.[\"react-router-dom\"] ||\n devDeps?.[\"react-router\"] ||\n devDeps?.[\"react-router-dom\"]\n );\n}\n\n/**\n * Check if package.json contains Next.js dependency.\n */\nexport function hasNextDependency(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n const deps = packageJson.dependencies as Record<string, string> | undefined;\n const devDeps = packageJson.devDependencies as\n | Record<string, string>\n | undefined;\n\n return Boolean(deps?.[\"next\"] || devDeps?.[\"next\"]);\n}\n\n/**\n * Check if package.json contains Stencil dependency.\n */\nexport function hasStencilDependency(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n const deps = packageJson.dependencies as Record<string, string> | undefined;\n const devDeps = packageJson.devDependencies as\n | Record<string, string>\n | undefined;\n\n return Boolean(deps?.[\"@stencil/core\"] || devDeps?.[\"@stencil/core\"]);\n}\n\n/**\n * Check if Stencil config exists.\n */\nexport function hasStencilConfig(cwd: string = process.cwd()): boolean {\n return existsSync(join(cwd, \"stencil.config.ts\")) || existsSync(join(cwd, \"stencil.config.js\"));\n}\n\n/**\n * Check if a project has Next.js App Router directory.\n */\nexport function isNextAppDir(cwd: string = process.cwd()): boolean {\n // Check for app/ directory (Next.js 13+ App Router)\n if (existsSync(join(cwd, \"app\"))) {\n return true;\n }\n // Check for src/app/ directory\n if (existsSync(join(cwd, \"src\", \"app\"))) {\n return true;\n }\n return false;\n}\n\n/**\n * Check if package.json contains Vue.js dependencies.\n */\nexport function hasVueDependency(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n const deps = packageJson.dependencies as Record<string, string> | undefined;\n const devDeps = packageJson.devDependencies as\n | Record<string, string>\n | undefined;\n\n return Boolean(deps?.[\"vue\"] || devDeps?.[\"vue\"]);\n}\n\n/**\n * Check if package.json contains Nuxt dependency.\n */\nexport function hasNuxtDependency(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n const deps = packageJson.dependencies as Record<string, string> | undefined;\n const devDeps = packageJson.devDependencies as\n | Record<string, string>\n | undefined;\n\n return Boolean(deps?.[\"nuxt\"] || devDeps?.[\"nuxt\"]);\n}\n\n/**\n * Check if project has Nuxt pages directory.\n */\nexport function isNuxtProject(cwd: string = process.cwd()): boolean {\n return existsSync(join(cwd, \"pages\")) || existsSync(join(cwd, \"src\", \"pages\"));\n}\n\n/**\n * Check if package.json contains Astro dependency.\n */\nexport function hasAstroDependency(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n const deps = packageJson.dependencies as Record<string, string> | undefined;\n const devDeps = packageJson.devDependencies as\n | Record<string, string>\n | undefined;\n\n return Boolean(deps?.[\"astro\"] || devDeps?.[\"astro\"]);\n}\n\n/**\n * Check if project has Astro config.\n */\nexport function hasAstroConfig(cwd: string = process.cwd()): boolean {\n return (\n existsSync(join(cwd, \"astro.config.mjs\")) ||\n existsSync(join(cwd, \"astro.config.ts\")) ||\n existsSync(join(cwd, \"astro.config.js\"))\n );\n}\n\n/**\n * Check if project is a library/package (has exports or publishConfig).\n */\nexport function isLibraryProject(\n packageJson: Record<string, unknown> | undefined\n): boolean {\n if (!packageJson) return false;\n\n // Has exports field (modern package entry points)\n if (packageJson.exports) return true;\n\n // Has publishConfig (intended for publishing)\n if (packageJson.publishConfig) return true;\n\n // Has private: false (explicitly public)\n if (packageJson.private === false) return true;\n\n // Has bin field (CLI tool)\n if (packageJson.bin) return true;\n\n return false;\n}\n\n/**\n * Detect the appropriate profile for a project with reasons.\n */\nexport function detectProfileWithReasons(\n changeSet: ChangeSet,\n cwd: string = process.cwd()\n): ProfileDetectionResult {\n const reasons: string[] = [];\n\n // Check for SvelteKit\n const hasSvelteRoutes = isSvelteKitProject(cwd);\n const hasSvelteDep = hasSvelteKitDependency(changeSet.headPackageJson);\n\n if (hasSvelteRoutes || hasSvelteDep) {\n if (hasSvelteRoutes) {\n reasons.push(\"Found src/routes/ directory (SvelteKit file-based routing)\");\n }\n if (hasSvelteDep) {\n reasons.push(\"Found @sveltejs/kit in package.json dependencies\");\n }\n return {\n profile: \"sveltekit\",\n confidence: hasSvelteRoutes && hasSvelteDep ? \"high\" : \"high\",\n reasons,\n };\n }\n\n // Check for Stencil\n const hasStencilDep = hasStencilDependency(changeSet.headPackageJson);\n const hasStencilConf = hasStencilConfig(cwd);\n\n if (hasStencilDep || hasStencilConf) {\n if (hasStencilDep) {\n reasons.push(\"Found @stencil/core in package.json dependencies\");\n }\n if (hasStencilConf) {\n reasons.push(\"Found stencil.config.ts or stencil.config.js\");\n }\n return {\n profile: \"stencil\",\n confidence: hasStencilDep && hasStencilConf ? \"high\" : \"high\",\n reasons,\n };\n }\n\n // Check for Next.js with App Router\n const hasNext = hasNextDependency(changeSet.headPackageJson);\n const hasAppDir = isNextAppDir(cwd);\n\n if (hasNext && hasAppDir) {\n reasons.push(\"Found next in package.json dependencies\");\n reasons.push(\"Found app/ directory (Next.js App Router)\");\n return {\n profile: \"next\",\n confidence: \"high\",\n reasons,\n };\n }\n\n if (hasNext) {\n reasons.push(\"Found next in package.json dependencies\");\n return {\n profile: \"next\",\n confidence: \"medium\",\n reasons,\n };\n }\n\n // Check for React with React Router (only if not Next.js)\n const hasReact = hasReactDependency(changeSet.headPackageJson);\n const hasRouter = hasReactRouterDependency(changeSet.headPackageJson);\n\n if (hasReact && hasRouter) {\n reasons.push(\"Found react and react-dom in package.json dependencies\");\n reasons.push(\"Found react-router or react-router-dom in package.json dependencies\");\n return {\n profile: \"react\",\n confidence: \"high\",\n reasons,\n };\n }\n\n // Check for Vue/Nuxt\n const hasVue = hasVueDependency(changeSet.headPackageJson);\n const hasNuxt = hasNuxtDependency(changeSet.headPackageJson);\n const isNuxt = isNuxtProject(cwd);\n\n if (hasNuxt || (hasVue && isNuxt)) {\n if (hasNuxt) {\n reasons.push(\"Found nuxt in package.json dependencies\");\n }\n if (hasVue) {\n reasons.push(\"Found vue in package.json dependencies\");\n }\n if (isNuxt) {\n reasons.push(\"Found pages/ directory (Nuxt file-based routing)\");\n }\n return {\n profile: \"vue\",\n confidence: \"high\",\n reasons,\n };\n }\n\n if (hasVue) {\n reasons.push(\"Found vue in package.json dependencies\");\n return {\n profile: \"vue\",\n confidence: \"medium\",\n reasons,\n };\n }\n\n // Check for Astro\n const hasAstro = hasAstroDependency(changeSet.headPackageJson);\n const hasAstroConf = hasAstroConfig(cwd);\n\n if (hasAstro || hasAstroConf) {\n if (hasAstro) {\n reasons.push(\"Found astro in package.json dependencies\");\n }\n if (hasAstroConf) {\n reasons.push(\"Found astro.config.{mjs,ts,js}\");\n }\n return {\n profile: \"astro\",\n confidence: hasAstro && hasAstroConf ? \"high\" : \"medium\",\n reasons,\n };\n }\n\n // Check for Library project (should be last before default)\n const isLibrary = isLibraryProject(changeSet.headPackageJson);\n\n if (isLibrary) {\n if (changeSet.headPackageJson?.exports) {\n reasons.push(\"Found exports field in package.json\");\n }\n if (changeSet.headPackageJson?.publishConfig) {\n reasons.push(\"Found publishConfig in package.json\");\n }\n if (changeSet.headPackageJson?.bin) {\n reasons.push(\"Found bin field in package.json (CLI tool)\");\n }\n if (changeSet.headPackageJson?.private === false) {\n reasons.push(\"Package marked as public (private: false)\");\n }\n return {\n profile: \"library\",\n confidence: \"medium\",\n reasons,\n };\n }\n\n // Default profile\n reasons.push(\"No framework-specific markers detected, using default analyzers\");\n return {\n profile: \"auto\",\n confidence: \"medium\",\n reasons,\n };\n}\n\n/**\n * Detect the appropriate profile for a project.\n * @deprecated Use detectProfileWithReasons for more detailed information.\n */\nexport function detectProfile(\n changeSet: ChangeSet,\n cwd: string = process.cwd()\n): ProfileName {\n return detectProfileWithReasons(changeSet, cwd).profile;\n}\n\n/**\n * Get profile by name.\n */\nexport function getProfile(name: ProfileName): Profile {\n switch (name) {\n case \"sveltekit\":\n return sveltekitProfile;\n case \"react\":\n return reactProfile;\n case \"stencil\":\n return stencilProfile;\n case \"next\":\n return nextProfile;\n case \"vue\":\n return vueProfile;\n case \"astro\":\n return astroProfile;\n case \"library\":\n return libraryProfile;\n case \"auto\":\n return defaultProfile;\n default:\n return defaultProfile;\n }\n}\n\n/**\n * Resolve profile name (handle 'auto').\n */\nexport function resolveProfileName(\n name: ProfileName,\n changeSet: ChangeSet,\n cwd: string = process.cwd()\n): ProfileName {\n if (name === \"auto\") {\n return detectProfile(changeSet, cwd);\n }\n return name;\n}\n\nexport { defaultProfile, sveltekitProfile, reactProfile, stencilProfile, nextProfile, vueProfile, astroProfile, libraryProfile };\n\n",
52
- "/**\n * Risk score computation.\n */\n\nimport type {\n ConventionViolationFinding,\n FileCategory,\n FileCategoryFinding,\n FileSummaryFinding,\n Finding,\n LargeDiffFinding,\n RiskLevel,\n RiskScore,\n RiskFactor,\n} from \"../core/types.js\";\n\n/**\n * Check if changes are only in low-risk categories.\n */\nfunction checkLowRiskOnlyChanges(\n findings: Finding[]\n): { isLowRisk: boolean; category: string | null } {\n const categoryFinding = findings.find(\n (f) => f.type === \"file-category\"\n ) as FileCategoryFinding | undefined;\n\n if (!categoryFinding) {\n return { isLowRisk: false, category: null };\n }\n\n const { categories } = categoryFinding;\n const highRiskCategories: FileCategory[] = [\n \"product\",\n \"infra\",\n \"ci\",\n \"dependencies\",\n ];\n\n // Check if any high-risk category has files\n const hasHighRiskChanges = highRiskCategories.some(\n (cat) => categories[cat].length > 0\n );\n\n if (hasHighRiskChanges) {\n return { isLowRisk: false, category: null };\n }\n\n // Determine which low-risk category dominates\n if (categories.docs.length > 0 && categories.tests.length === 0) {\n return { isLowRisk: true, category: \"docs\" };\n }\n if (categories.tests.length > 0 && categories.docs.length === 0) {\n return { isLowRisk: true, category: \"tests\" };\n }\n if (\n categories.config.length > 0 &&\n categories.docs.length === 0 &&\n categories.tests.length === 0\n ) {\n return { isLowRisk: true, category: \"config\" };\n }\n if (\n categories.docs.length > 0 ||\n categories.tests.length > 0 ||\n categories.config.length > 0\n ) {\n return { isLowRisk: true, category: \"docs/tests/config\" };\n }\n\n return { isLowRisk: false, category: null };\n}\n\n/**\n * Compute aggregate risk score from findings.\n */\nexport function computeRiskScore(findings: Finding[]): RiskScore {\n let score = 0;\n const evidenceBullets: string[] = [];\n const factors: RiskFactor[] = [];\n\n // Check for low-risk only changes first\n const { isLowRisk, category } = checkLowRiskOnlyChanges(findings);\n if (isLowRisk && category) {\n const reductions: Record<string, number> = {\n docs: -15,\n tests: -10,\n config: -5,\n \"docs/tests/config\": -10,\n };\n const weight = reductions[category] ?? 0;\n score += weight;\n evidenceBullets.push(\n `✅ Changes are only in ${category} (lower risk)`\n );\n factors.push({\n kind: \"low-risk-category\",\n weight,\n explanation: `Changes are only in ${category} (lower risk)`,\n evidence: [],\n });\n }\n\n for (const finding of findings) {\n switch (finding.type) {\n case \"risk-flag\":\n {\n const weight = finding.risk === \"high\" \n ? 40 \n : finding.risk === \"medium\" \n ? 20 \n : 5;\n score += weight;\n const emoji = finding.risk === \"high\" \n ? \"⚠️\" \n : finding.risk === \"medium\" \n ? \"⚡\" \n : \"ℹ️\";\n evidenceBullets.push(`${emoji} ${finding.evidenceText}`);\n factors.push({\n kind: `risk-${finding.risk}`,\n weight,\n explanation: finding.evidenceText,\n evidence: finding.evidence,\n });\n }\n break;\n\n case \"db-migration\":\n {\n const weight = finding.risk === \"high\" \n ? 30 \n : finding.risk === \"medium\" \n ? 15 \n : 0;\n if (weight > 0) {\n score += weight;\n const explanation = finding.risk === \"high\"\n ? `High-risk database migration: ${finding.reasons.join(\", \")}`\n : `Database migration detected: ${finding.files.join(\", \")}`;\n evidenceBullets.push(\n finding.risk === \"high\" ? `⚠️ ${explanation}` : `⚡ ${explanation}`\n );\n factors.push({\n kind: \"db-migration\",\n weight,\n explanation,\n evidence: finding.evidence,\n });\n }\n }\n break;\n\n case \"route-change\":\n if (finding.change === \"added\") {\n score += 5;\n factors.push({\n kind: \"route-added\",\n weight: 5,\n explanation: `Route added: ${finding.routeId}`,\n evidence: finding.evidence,\n });\n } else if (finding.change === \"deleted\") {\n score += 10;\n evidenceBullets.push(`ℹ️ Route deleted: ${finding.routeId}`);\n factors.push({\n kind: \"route-deleted\",\n weight: 10,\n explanation: `Route deleted: ${finding.routeId}`,\n evidence: finding.evidence,\n });\n }\n break;\n\n case \"dependency-change\":\n {\n let weight = 0;\n if (finding.impact === \"major\") {\n weight = 15;\n } else if (finding.impact === \"minor\") {\n weight = 5;\n }\n // Risky packages get additional points (already flagged via risk-flag)\n if (finding.riskCategory && finding.impact === \"new\") {\n weight += 10;\n }\n if (weight > 0) {\n score += weight;\n factors.push({\n kind: `dependency-${finding.impact}`,\n weight,\n explanation: `${finding.name}: ${finding.from ?? \"new\"} → ${finding.to ?? \"removed\"}`,\n evidence: finding.evidence,\n });\n }\n }\n break;\n\n case \"env-var\":\n if (finding.change === \"added\") {\n score += 5;\n evidenceBullets.push(`ℹ️ New env var: ${finding.name}`);\n factors.push({\n kind: \"env-var-added\",\n weight: 5,\n explanation: `New env var: ${finding.name}`,\n evidence: finding.evidence,\n });\n }\n break;\n\n case \"security-file\":\n // Additional points for security files (already adds risk-flag)\n score += 15;\n factors.push({\n kind: \"security-file\",\n weight: 15,\n explanation: `Security-sensitive files changed: ${finding.files.length} file(s)`,\n evidence: finding.evidence,\n });\n break;\n\n case \"convention-violation\":\n {\n const violationFinding = finding as ConventionViolationFinding;\n const fileCount = violationFinding.files.length;\n // Only add risk if significant number of files lack tests\n if (fileCount > 5) {\n const weight = 10;\n score += weight;\n evidenceBullets.push(`⚡ ${fileCount} source files lack test coverage`);\n factors.push({\n kind: \"test-coverage-gap\",\n weight,\n explanation: `${fileCount} source files lack test coverage`,\n evidence: violationFinding.evidence.slice(0, 3),\n });\n }\n }\n break;\n\n case \"large-diff\":\n {\n const largeDiffFinding = finding as LargeDiffFinding;\n const weight = largeDiffFinding.linesChanged > 1000 \n ? 15 \n : largeDiffFinding.linesChanged > 500 \n ? 10 \n : 5;\n score += weight;\n evidenceBullets.push(\n `ℹ️ Large diff: ${largeDiffFinding.filesChanged} files, ${largeDiffFinding.linesChanged} lines`\n );\n factors.push({\n kind: \"large-diff\",\n weight,\n explanation: `Large diff: ${largeDiffFinding.filesChanged} files, ${largeDiffFinding.linesChanged} lines`,\n evidence: largeDiffFinding.evidence,\n });\n }\n break;\n }\n }\n\n // Check for core module changes (types.ts, index.ts in core directories)\n const coreFilePatterns = [/\\/types\\.ts$/, /\\/core\\/.*\\.ts$/, /\\/index\\.ts$/];\n const fileSummary = findings.find(f => f.type === \"file-summary\") as FileSummaryFinding | undefined;\n if (fileSummary) {\n const coreFilesModified = fileSummary.modified.filter(file => \n coreFilePatterns.some(p => p.test(file))\n );\n if (coreFilesModified.length > 0) {\n const weight = 10;\n score += weight;\n evidenceBullets.push(`⚡ Core module files modified: ${coreFilesModified.join(\", \")}`);\n factors.push({\n kind: \"core-module-change\",\n weight,\n explanation: `Core module files modified (types.ts, index.ts): ${coreFilesModified.length} file(s)`,\n evidence: [],\n });\n }\n }\n\n // Ensure score stays within bounds\n score = Math.max(0, Math.min(score, 100));\n\n // Determine level\n let level: RiskLevel;\n if (score >= 50) {\n level = \"high\";\n } else if (score >= 20) {\n level = \"medium\";\n } else {\n level = \"low\";\n }\n\n return { score, level, factors, evidenceBullets };\n}\n",
53
- "/**\n * Category aggregation for findings.\n */\n\nimport type {\n Category,\n CategoryAggregate,\n Evidence,\n Finding,\n RiskFactor,\n} from \"../../core/types.js\";\n\n/**\n * Map risk factor kind to category.\n */\nfunction riskFactorKindToCategory(kind: string): Category {\n // Database-related\n if (kind.includes(\"db-migration\") || kind.includes(\"database\") || kind.includes(\"sql\")) {\n return \"database\";\n }\n // Dependency-related\n if (kind.includes(\"dependency\") || kind.includes(\"deps\")) {\n return \"dependencies\";\n }\n // Route-related\n if (kind.includes(\"route\")) {\n return \"routes\";\n }\n // Config/env-related\n if (kind.includes(\"env-var\") || kind.includes(\"config\")) {\n return \"config_env\";\n }\n // Security/infrastructure\n if (kind.includes(\"security\") || kind.includes(\"infra\") || kind.includes(\"docker\") || kind.includes(\"k8s\") || kind.includes(\"terraform\")) {\n return \"infra\";\n }\n // Cloudflare\n if (kind.includes(\"cloudflare\") || kind.includes(\"wrangler\") || kind.includes(\"workers\")) {\n return \"cloudflare\";\n }\n // CI/CD\n if (kind.includes(\"ci\") || kind.includes(\"workflow\") || kind.includes(\"pipeline\")) {\n return \"ci\";\n }\n // Test-related (actual test file changes)\n if (kind.includes(\"test\") && !kind.includes(\"test-gap\") && !kind.includes(\"test-coverage\")) {\n return \"tests\";\n }\n // Quality-related (test gaps, coverage issues)\n if (kind.includes(\"test-gap\") || kind.includes(\"test-coverage\") || kind.includes(\"quality\")) {\n return \"quality\";\n }\n // API-related\n if (kind.includes(\"api\") || kind.includes(\"contract\")) {\n return \"api\";\n }\n // Impact/core module changes - these affect the system broadly\n // Large diffs also affect reviewability and risk, so map to impact\n if (kind.includes(\"core-module\") || kind.includes(\"impact\") || kind.includes(\"blast-radius\") || kind.includes(\"large-diff\") || kind.includes(\"churn\")) {\n return \"impact\";\n }\n // Documentation\n if (kind.includes(\"doc\")) {\n return \"docs\";\n }\n return \"unknown\";\n}\n\n/**\n * Score evidence by information density.\n * Higher scores = more informative/actionable evidence.\n */\nfunction scoreEvidence(evidence: Evidence): number {\n const excerpt = evidence.excerpt.toLowerCase();\n let score = 0;\n \n // Prefer evidence with numbers (quantified impact)\n if (/\\d+/.test(excerpt)) score += 10;\n \n // Prefer evidence mentioning blast radius, impact, risk\n if (excerpt.includes(\"blast radius\")) score += 15;\n if (excerpt.includes(\"high\")) score += 5;\n if (excerpt.includes(\"critical\")) score += 8;\n if (excerpt.includes(\"breaking\")) score += 8;\n \n // Prefer evidence with specific action words\n if (excerpt.includes(\"added\") || excerpt.includes(\"removed\") || excerpt.includes(\"modified\")) score += 3;\n \n // Penalize generic/low-info evidence\n if (excerpt === \"imports module\") score -= 10;\n if (excerpt.startsWith(\"depends on\")) score -= 5;\n \n return score;\n}\n\n/**\n * Aggregate findings and risk factors by category.\n */\nexport function aggregateCategories(\n findings: Finding[],\n riskFactors: RiskFactor[]\n): CategoryAggregate[] {\n // Initialize category aggregates\n const categoryMap = new Map<Category, {\n count: number;\n riskWeight: number;\n evidence: Evidence[];\n }>();\n\n // Process findings (excluding meta-findings that don't belong to a specific domain)\n for (const finding of findings) {\n if (finding.kind === \"file-summary\" || finding.kind === \"file-category\") {\n continue; // Skip meta-findings\n }\n\n const category = finding.category;\n\n if (!categoryMap.has(category)) {\n categoryMap.set(category, {\n count: 0,\n riskWeight: 0,\n evidence: [],\n });\n }\n\n const agg = categoryMap.get(category)!;\n agg.count += 1;\n\n // Collect all evidence first, we'll select best ones later\n agg.evidence.push(...finding.evidence);\n }\n\n // Process risk factors to accumulate weights\n for (const factor of riskFactors) {\n // Determine category from factor kind or evidence\n let category: Category = \"unknown\";\n\n // First, check if there's a matching finding with this evidence\n for (const finding of findings) {\n if (finding.evidence.length > 0 && factor.evidence.length > 0) {\n // Check if evidence files match\n const findingFiles = new Set(finding.evidence.map(e => e.file));\n const factorFiles = new Set(factor.evidence.map(e => e.file));\n const hasOverlap = Array.from(findingFiles)\n .some(f => factorFiles.has(f));\n if (hasOverlap) {\n category = finding.category;\n break;\n }\n }\n }\n\n // Fallback to kind-based mapping\n if (category === \"unknown\") {\n category = riskFactorKindToCategory(factor.kind);\n }\n\n if (!categoryMap.has(category)) {\n categoryMap.set(category, {\n count: 0,\n riskWeight: 0,\n evidence: [],\n });\n }\n\n const agg = categoryMap.get(category)!;\n agg.riskWeight += factor.weight;\n\n // Collect all evidence from risk factors too\n agg.evidence.push(...factor.evidence);\n }\n\n // Convert to array and select top 3 evidence by information score\n // Filter out categories with no findings (count: 0) to avoid noise like \"unknown: 0\"\n const categories: CategoryAggregate[] = Array.from(\n categoryMap.entries()\n )\n .filter(([_id, data]) => data.count > 0)\n .map(([id, data]) => {\n // Sort evidence by score (descending), then by file path (ascending) for determinism\n const sortedEvidence = [...data.evidence].sort((a, b) => {\n const scoreA = scoreEvidence(a);\n const scoreB = scoreEvidence(b);\n if (scoreB !== scoreA) return scoreB - scoreA; // Higher score first\n return a.file.localeCompare(b.file); // Alphabetical for ties\n });\n \n // Dedupe by file to avoid repetition\n const seen = new Set<string>();\n const deduped: Evidence[] = [];\n for (const ev of sortedEvidence) {\n if (!seen.has(ev.file)) {\n seen.add(ev.file);\n deduped.push(ev);\n }\n if (deduped.length >= 3) break;\n }\n \n return {\n id,\n count: data.count,\n riskWeight: data.riskWeight,\n topEvidence: deduped,\n };\n });\n\n // Sort: riskWeight desc, count desc, id asc\n categories.sort((a, b) => {\n if (b.riskWeight !== a.riskWeight) {\n return b.riskWeight - a.riskWeight;\n }\n if (b.count !== a.count) {\n return b.count - a.count;\n }\n return a.id.localeCompare(b.id);\n });\n\n return categories;\n}\n\n/**\n * Build summary.byArea from categories.\n */\nexport function buildSummaryByArea(\n categories: CategoryAggregate[]\n): Record<string, number> {\n const byArea: Record<string, number> = {};\n for (const cat of categories) {\n byArea[cat.id] = cat.count;\n }\n return byArea;\n}\n",
54
- "/**\n * Action derivation from findings and risk.\n *\n * Actions provide context about what needs attention and why,\n * without prescribing specific commands. AI agents have more\n * context about the project's setup (package manager, CI system,\n * deployment target) to determine the appropriate commands.\n */\n\nimport type {\n Action,\n DbMigrationFinding,\n DependencyChangeFinding,\n EnvVarFinding,\n Finding,\n ProfileName,\n TestChangeFinding,\n} from \"../../core/types.js\";\n\n/**\n * Derive actionable recommendations from findings and risk.\n *\n * Each action provides:\n * - `id`: Unique identifier\n * - `category`: Grouping category\n * - `blocking`: Whether this blocks PR merge\n * - `reason`: What needs attention and why\n * - `triggers`: Context about what triggered this action\n */\nexport function deriveActions(\n findings: Finding[],\n profile: ProfileName\n): Action[] {\n const actions: Action[] = [];\n\n // SvelteKit type checking - only suggest when profile is explicitly SvelteKit\n // (not \"auto\" which means no framework was detected)\n if (profile === \"sveltekit\") {\n const hasRouteChanges = findings.some(f => f.type === \"route-change\");\n if (hasRouteChanges || findings.length > 0) {\n const triggers: string[] = [];\n if (hasRouteChanges) {\n triggers.push(\"Route files changed\");\n }\n if (findings.length > 0 && !hasRouteChanges) {\n triggers.push(\"Source files changed\");\n }\n\n actions.push({\n id: \"sveltekit-check\",\n category: \"types\",\n blocking: true,\n reason: \"Run SvelteKit type checker to verify no type errors were introduced\",\n triggers,\n });\n }\n }\n\n // Test execution\n const testFindings = findings.filter(\n (f): f is TestChangeFinding => f.type === \"test-change\"\n );\n const hasTestChanges = testFindings.length > 0;\n if (hasTestChanges || findings.length > 0) {\n const triggers: string[] = [];\n if (hasTestChanges) {\n // Count actual test files, not just findings\n const testFileCount = testFindings.reduce((sum, f) => sum + f.files.length, 0);\n triggers.push(`${testFileCount} test file(s) changed`);\n }\n if (findings.length > 0 && !hasTestChanges) {\n triggers.push(\"Source files changed without corresponding test changes\");\n }\n\n actions.push({\n id: \"run-tests\",\n category: \"tests\",\n blocking: true,\n reason: \"Run test suite to verify functionality and catch regressions\",\n triggers,\n });\n }\n\n // Database migrations\n const dbMigrations = findings.filter(\n (f): f is DbMigrationFinding => f.type === \"db-migration\"\n );\n if (dbMigrations.length > 0) {\n const hasDangerousSQL = dbMigrations.some(m => m.risk === \"high\");\n const migrationFiles = dbMigrations.flatMap(m => m.files);\n const reasons = [...new Set(dbMigrations.flatMap(m => m.reasons))];\n\n const triggers: string[] = [\n `${migrationFiles.length} migration file(s) changed`,\n ...reasons,\n ];\n\n if (hasDangerousSQL) {\n triggers.push(\"DANGEROUS SQL DETECTED (DROP, TRUNCATE, or destructive operations)\");\n }\n\n actions.push({\n id: \"apply-migrations\",\n category: \"database\",\n blocking: hasDangerousSQL,\n reason: hasDangerousSQL\n ? \"Apply database migrations in a safe environment and verify data integrity before production\"\n : \"Apply and test database migrations in development environment\",\n triggers,\n });\n\n if (hasDangerousSQL) {\n actions.push({\n id: \"backup-db\",\n category: \"database\",\n blocking: true,\n reason: \"Create database backup before applying destructive migrations\",\n triggers: [\"High-risk SQL operations detected in migrations\"],\n });\n }\n }\n\n // Cloudflare changes\n const cloudflareChanges = findings.filter(\n f => f.type === \"cloudflare-change\"\n );\n if (cloudflareChanges.length > 0) {\n const areas = [...new Set(cloudflareChanges.map(f => f.area))];\n const files = cloudflareChanges.flatMap(f => f.files);\n\n actions.push({\n id: \"verify-cloudflare-config\",\n category: \"cloudflare\",\n blocking: false,\n reason: \"Verify Cloudflare configuration and bindings match across environments\",\n triggers: [\n `Cloudflare ${areas.join(\", \")} configuration changed`,\n `Files: ${files.join(\", \")}`,\n ],\n });\n }\n\n // Environment variables\n const envVarChanges = findings.filter(\n (f): f is EnvVarFinding => f.type === \"env-var\"\n );\n if (envVarChanges.length > 0) {\n const varNames = envVarChanges.map(f => f.name);\n const addedVars = envVarChanges.filter(f => f.change === \"added\");\n\n const triggers: string[] = [];\n if (addedVars.length > 0) {\n triggers.push(`New environment variable(s): ${addedVars.map(f => f.name).join(\", \")}`);\n }\n if (envVarChanges.length > addedVars.length) {\n triggers.push(`Modified environment variable(s): ${varNames.filter(n => !addedVars.some(a => a.name === n)).join(\", \")}`);\n }\n\n actions.push({\n id: \"update-env-docs\",\n category: \"environment\",\n blocking: false,\n reason: \"Update .env.example and documentation with new or changed environment variables\",\n triggers,\n });\n }\n\n // Dependency changes with high risk\n const majorDependencyChanges = findings.filter(\n (f): f is DependencyChangeFinding =>\n f.type === \"dependency-change\" && f.impact === \"major\"\n );\n if (majorDependencyChanges.length > 0) {\n const deps = majorDependencyChanges.map(f => {\n const from = f.from || \"new\";\n const to = f.to || \"removed\";\n return `${f.name} (${from} → ${to})`;\n });\n\n actions.push({\n id: \"review-dependencies\",\n category: \"dependencies\",\n blocking: false,\n reason: \"Review major dependency changes for breaking changes and update migration guides if needed\",\n triggers: [\n `Major version changes: ${deps.join(\", \")}`,\n \"Check CHANGELOG and migration guides for breaking changes\",\n ],\n });\n }\n\n // Sort actions deterministically (blocking first, then by id)\n actions.sort((a, b) => {\n if (a.blocking !== b.blocking) {\n return a.blocking ? -1 : 1;\n }\n return a.id.localeCompare(b.id);\n });\n\n return actions;\n}\n",
55
- "/**\n * Highlights builder - generates prioritized summary bullets from findings.\n *\n * Highlights are ordered by impact (highest first):\n * - Blast radius (high > medium)\n * - Breaking changes (config/API surface)\n * - Risk/security warnings (high-risk flags, destructive SQL, DB migrations, CI security, security files)\n * - Lockfile mismatches\n * - General changes (infra, deps, routes, API contracts)\n * - API surface changes (Stencil, monorepo, env vars)\n * - Test coverage (test changes, gaps)\n * - Informational/fallback\n */\n\nimport type { Finding, LockfileFinding } from \"../../core/types.js\";\n\n// ============================================================================\n// Priority Constants (higher = more important, appears first)\n// ============================================================================\n\n/** Priority levels for highlight ordering */\nexport const HIGHLIGHT_PRIORITY = {\n // Highest: Blast radius / impact analysis\n HIGH_BLAST_RADIUS: 100,\n MEDIUM_BLAST_RADIUS: 95,\n\n // Breaking changes in config/API surface\n BREAKING_CONFIG: 90, // TS, Tailwind, GraphQL, Package exports (breaking variants)\n\n // Risk/security warnings\n HIGH_RISK_FLAGS: 85,\n DESTRUCTIVE_SQL: 85,\n HIGH_RISK_DB_MIGRATION: 85,\n CI_SECURITY: 85,\n SECURITY_FILES: 85,\n\n // Dependency warnings\n LOCKFILE_MISMATCH: 80,\n\n // General changes\n INFRA_CHANGES: 70,\n MAJOR_DEPS: 70,\n ROUTE_CHANGES: 70,\n API_CONTRACTS: 70,\n CLOUDFLARE: 70,\n\n // API surface / config (non-breaking)\n STENCIL_API: 60,\n MONOREPO_CONFIG: 60,\n ENV_VARS: 60,\n NEW_DEPS: 60,\n NON_BREAKING_CONFIG: 60, // TS, Tailwind, GraphQL, Package exports (non-breaking)\n\n // Database (non-high-risk)\n DB_MIGRATION: 55,\n CI_WORKFLOW: 55,\n\n // Test coverage\n TEST_CHANGES: 50,\n TEST_GAPS: 50,\n CONVENTION_VIOLATIONS: 50,\n\n // Fallback / informational\n FALLBACK: 10,\n} as const;\n\n// ============================================================================\n// Internal Types\n// ============================================================================\n\ninterface PrioritizedHighlight {\n text: string;\n priority: number;\n /** Insertion order for stable sorting within same priority */\n order: number;\n}\n\n// ============================================================================\n// Highlight Builder\n// ============================================================================\n\n/**\n * Build highlights from findings with priority-based ordering.\n * Returns an array of human-readable summary bullets, ordered by impact.\n *\n * @param findings - Array of findings to generate highlights from\n * @returns Array of highlight strings, ordered by priority (highest first)\n */\nexport function buildHighlights(findings: Finding[]): string[] {\n const items: PrioritizedHighlight[] = [];\n let order = 0;\n\n const add = (text: string, priority: number) => {\n items.push({ text, priority, order: order++ });\n };\n\n // -------------------------------------------------------------------------\n // Impact analysis (blast radius) - HIGHEST PRIORITY\n // -------------------------------------------------------------------------\n const impactFindings = findings.filter(f => f.type === \"impact-analysis\");\n const highImpact = impactFindings.filter(i => i.blastRadius === \"high\");\n const mediumImpact = impactFindings.filter(i => i.blastRadius === \"medium\");\n\n if (highImpact.length > 0) {\n add(\n `${highImpact.length} file(s) with high blast radius`,\n HIGHLIGHT_PRIORITY.HIGH_BLAST_RADIUS\n );\n }\n if (mediumImpact.length > 0) {\n add(\n `${mediumImpact.length} file(s) with medium blast radius`,\n HIGHLIGHT_PRIORITY.MEDIUM_BLAST_RADIUS\n );\n }\n\n // -------------------------------------------------------------------------\n // Breaking config/API changes\n // -------------------------------------------------------------------------\n\n // TypeScript config changes\n const tsConfigChanges = findings.filter(f => f.type === \"typescript-config\");\n if (tsConfigChanges.length > 0) {\n const breaking = tsConfigChanges.some(c => c.isBreaking);\n add(\n breaking ? \"TypeScript config changed (breaking)\" : \"TypeScript config modified\",\n breaking ? HIGHLIGHT_PRIORITY.BREAKING_CONFIG : HIGHLIGHT_PRIORITY.NON_BREAKING_CONFIG\n );\n }\n\n // Tailwind config changes\n const tailwindChanges = findings.filter(f => f.type === \"tailwind-config\");\n if (tailwindChanges.length > 0) {\n const breaking = tailwindChanges.some(c => c.isBreaking);\n add(\n breaking ? \"Tailwind config changed (breaking)\" : \"Tailwind config modified\",\n breaking ? HIGHLIGHT_PRIORITY.BREAKING_CONFIG : HIGHLIGHT_PRIORITY.NON_BREAKING_CONFIG\n );\n }\n\n // GraphQL schema changes\n const graphqlChanges = findings.filter(f => f.type === \"graphql-change\");\n if (graphqlChanges.length > 0) {\n const breaking = graphqlChanges.some(g => g.isBreaking);\n add(\n breaking ? \"GraphQL schema changed (breaking)\" : \"GraphQL schema modified\",\n breaking ? HIGHLIGHT_PRIORITY.BREAKING_CONFIG : HIGHLIGHT_PRIORITY.NON_BREAKING_CONFIG\n );\n }\n\n // Package exports changes\n const packageExports = findings.filter(f => f.type === \"package-exports\");\n if (packageExports.length > 0) {\n const breaking = packageExports.some(p => p.isBreaking);\n if (breaking) {\n add(\"Package exports changed (breaking)\", HIGHLIGHT_PRIORITY.BREAKING_CONFIG);\n } else {\n const binChanges = packageExports.filter(p =>\n p.binChanges && (p.binChanges.added.length > 0 || p.binChanges.removed.length > 0)\n );\n if (binChanges.length > 0) {\n add(\"Package bin/exports modified\", HIGHLIGHT_PRIORITY.NON_BREAKING_CONFIG);\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Risk/security warnings\n // -------------------------------------------------------------------------\n\n // High-risk flags\n const riskFlags = findings.filter(f => f.type === \"risk-flag\");\n const highRiskFlags = riskFlags.filter(r => r.risk === \"high\");\n if (highRiskFlags.length > 0) {\n add(\n `${highRiskFlags.length} high-risk condition(s) detected`,\n HIGHLIGHT_PRIORITY.HIGH_RISK_FLAGS\n );\n }\n\n // Destructive SQL\n const sqlRisks = findings.filter(f => f.type === \"sql-risk\");\n const destructiveSql = sqlRisks.filter(s => s.riskType === \"destructive\");\n if (destructiveSql.length > 0) {\n add(\n `Destructive SQL detected in ${destructiveSql.length} file(s)`,\n HIGHLIGHT_PRIORITY.DESTRUCTIVE_SQL\n );\n }\n\n // Database migrations (high risk variant gets higher priority)\n const dbMigrations = findings.filter(f => f.type === \"db-migration\");\n if (dbMigrations.length > 0) {\n const highRisk = dbMigrations.some(m => m.risk === \"high\");\n add(\n highRisk ? \"Database migrations (HIGH RISK)\" : \"Database migrations\",\n highRisk ? HIGHLIGHT_PRIORITY.HIGH_RISK_DB_MIGRATION : HIGHLIGHT_PRIORITY.DB_MIGRATION\n );\n }\n\n // CI/CD workflows (security issues get higher priority)\n const ciWorkflows = findings.filter(f => f.type === \"ci-workflow\");\n if (ciWorkflows.length > 0) {\n const securityIssues = ciWorkflows.filter(c =>\n c.riskType === \"permissions_broadened\" || c.riskType === \"pull_request_target\"\n );\n if (securityIssues.length > 0) {\n add(\"CI workflow security changes detected\", HIGHLIGHT_PRIORITY.CI_SECURITY);\n } else {\n add(`${ciWorkflows.length} CI workflow(s) modified`, HIGHLIGHT_PRIORITY.CI_WORKFLOW);\n }\n }\n\n // Security-sensitive files\n const securityFiles = findings.filter(f => f.type === \"security-file\");\n if (securityFiles.length > 0) {\n add(\"Security-sensitive files changed\", HIGHLIGHT_PRIORITY.SECURITY_FILES);\n }\n\n // -------------------------------------------------------------------------\n // Lockfile mismatch (dependency warning)\n // -------------------------------------------------------------------------\n const lockfileMismatch = findings.find(f => f.type === \"lockfile-mismatch\") as LockfileFinding | undefined;\n if (lockfileMismatch) {\n if (lockfileMismatch.manifestChanged && !lockfileMismatch.lockfileChanged) {\n add(\n \"Lockfile mismatch: package.json changed but lockfile not updated\",\n HIGHLIGHT_PRIORITY.LOCKFILE_MISMATCH\n );\n } else if (!lockfileMismatch.manifestChanged && lockfileMismatch.lockfileChanged) {\n add(\n \"Lockfile mismatch: lockfile changed but package.json not updated\",\n HIGHLIGHT_PRIORITY.LOCKFILE_MISMATCH\n );\n }\n }\n\n // -------------------------------------------------------------------------\n // General changes (infra, deps, routes, API contracts, cloudflare)\n // -------------------------------------------------------------------------\n\n // Infrastructure changes\n const infraChanges = findings.filter(f => f.type === \"infra-change\");\n if (infraChanges.length > 0) {\n const types = [...new Set(infraChanges.map(i => i.infraType))];\n add(`Infrastructure changes: ${types.join(\", \")}`, HIGHLIGHT_PRIORITY.INFRA_CHANGES);\n }\n\n // Major dependency changes\n const depChanges = findings.filter(f => f.type === \"dependency-change\");\n const majorChanges = depChanges.filter(d => d.impact === \"major\");\n if (majorChanges.length > 0) {\n add(`${majorChanges.length} major dependency update(s)`, HIGHLIGHT_PRIORITY.MAJOR_DEPS);\n }\n\n // Route changes\n const routeChanges = findings.filter(f => f.type === \"route-change\");\n if (routeChanges.length > 0) {\n add(`${routeChanges.length} route(s) changed`, HIGHLIGHT_PRIORITY.ROUTE_CHANGES);\n }\n\n // API contract changes\n const apiChanges = findings.filter(f => f.type === \"api-contract-change\");\n if (apiChanges.length > 0) {\n add(`${apiChanges.length} API contract(s) modified`, HIGHLIGHT_PRIORITY.API_CONTRACTS);\n }\n\n // Cloudflare changes\n const cfChanges = findings.filter(f => f.type === \"cloudflare-change\");\n if (cfChanges.length > 0) {\n const areas = [...new Set(cfChanges.map(c => c.area))];\n add(`Cloudflare ${areas.join(\"/\")} configuration changed`, HIGHLIGHT_PRIORITY.CLOUDFLARE);\n }\n\n // -------------------------------------------------------------------------\n // API surface / config (non-breaking) / env vars\n // -------------------------------------------------------------------------\n\n // Stencil component changes (group all Stencil findings)\n const stencilFindings = findings.filter(f =>\n f.type === \"stencil-component-change\" ||\n f.type === \"stencil-prop-change\" ||\n f.type === \"stencil-event-change\" ||\n f.type === \"stencil-method-change\" ||\n f.type === \"stencil-slot-change\"\n );\n if (stencilFindings.length > 0) {\n const components = new Set(stencilFindings.map(s => s.tag));\n add(`${components.size} Stencil component(s) with API changes`, HIGHLIGHT_PRIORITY.STENCIL_API);\n }\n\n // Monorepo config changes\n const monorepoChanges = findings.filter(f => f.type === \"monorepo-config\");\n if (monorepoChanges.length > 0) {\n const tools = [...new Set(monorepoChanges.map(m => m.tool))];\n add(`Monorepo config changed: ${tools.join(\", \")}`, HIGHLIGHT_PRIORITY.MONOREPO_CONFIG);\n }\n\n // Environment variables\n const envVars = findings.filter(f => f.type === \"env-var\");\n if (envVars.length > 0) {\n const added = envVars.filter(e => e.change === \"added\");\n add(\n added.length > 0\n ? `${added.length} new environment variable(s)`\n : `${envVars.length} environment variable(s) touched`,\n HIGHLIGHT_PRIORITY.ENV_VARS\n );\n }\n\n // New dependencies\n const newDeps = depChanges.filter(d => d.impact === \"new\");\n if (newDeps.length > 0) {\n add(`${newDeps.length} new dependency(ies) added`, HIGHLIGHT_PRIORITY.NEW_DEPS);\n }\n\n // -------------------------------------------------------------------------\n // Test coverage\n // -------------------------------------------------------------------------\n\n // Test changes\n const testChanges = findings.filter(f => f.type === \"test-change\");\n if (testChanges.length > 0) {\n const files = testChanges.flatMap(t => t.files);\n add(`${files.length} test file(s) modified`, HIGHLIGHT_PRIORITY.TEST_CHANGES);\n }\n\n // Convention violations (test gaps)\n const violations = findings.filter(f => f.type === \"convention-violation\");\n if (violations.length > 0) {\n const totalFiles = violations.reduce((sum, v) => sum + v.files.length, 0);\n add(\n `${totalFiles} source file(s) missing corresponding tests`,\n HIGHLIGHT_PRIORITY.CONVENTION_VIOLATIONS\n );\n }\n\n // Test gaps (explicit)\n const testGaps = findings.filter(f => f.type === \"test-gap\");\n if (testGaps.length > 0) {\n const totalUntested = testGaps.reduce((sum, t) => sum + t.prodFilesChanged, 0);\n add(`${totalUntested} modified file(s) lack test coverage`, HIGHLIGHT_PRIORITY.TEST_GAPS);\n }\n\n // -------------------------------------------------------------------------\n // Fallback: if we have findings but no highlights, show a generic summary\n // -------------------------------------------------------------------------\n if (items.length === 0 && findings.length > 0) {\n // Check for file summary findings to get file counts\n const fileSummary = findings.find(f => f.type === \"file-summary\");\n if (fileSummary) {\n const total =\n fileSummary.added.length +\n fileSummary.modified.length +\n fileSummary.deleted.length +\n fileSummary.renamed.length;\n if (total > 0) {\n add(`${total} ${fileSummary.category} file(s) changed`, HIGHLIGHT_PRIORITY.FALLBACK);\n }\n }\n\n // If still empty and we have impact findings, mention them\n if (items.length === 0 && impactFindings.length > 0) {\n const totalAffected = impactFindings.reduce((sum, f) => sum + f.affectedFiles.length, 0);\n add(\n `${impactFindings.length} file(s) analyzed, ${totalAffected} dependent file(s)`,\n HIGHLIGHT_PRIORITY.FALLBACK\n );\n }\n\n // Last resort: mention the number of findings\n if (items.length === 0) {\n add(`${findings.length} finding(s) detected`, HIGHLIGHT_PRIORITY.FALLBACK);\n }\n }\n\n // -------------------------------------------------------------------------\n // Sort by priority (descending), then by insertion order (ascending) for stability\n // -------------------------------------------------------------------------\n items.sort((a, b) => {\n if (b.priority !== a.priority) {\n return b.priority - a.priority;\n }\n return a.order - b.order;\n });\n\n return items.map(item => item.text);\n}\n",
56
- "/**\n * Sorting utilities for deterministic output ordering.\n */\n\nimport type { Finding, RiskFlag, Evidence, RiskFlagEvidence } from \"./types.js\";\n\n/**\n * Normalize path for consistent sorting across platforms.\n * Converts backslashes to forward slashes and normalizes case.\n */\nexport function normalizePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").toLowerCase();\n}\n\n/**\n * Compare two paths lexicographically.\n */\nexport function comparePaths(a: string, b: string): number {\n const normA = normalizePath(a);\n const normB = normalizePath(b);\n return normA.localeCompare(normB);\n}\n\n/**\n * Sort risk flags deterministically.\n * Order: category asc, effectiveScore desc, ruleKey asc, flagId asc\n */\nexport function sortRiskFlags(flags: RiskFlag[]): RiskFlag[] {\n return [...flags].sort((a, b) => {\n // Category ascending\n const catCompare = a.category.localeCompare(b.category);\n if (catCompare !== 0) return catCompare;\n\n // Effective score descending\n const scoreCompare = b.effectiveScore - a.effectiveScore;\n if (scoreCompare !== 0) return scoreCompare;\n\n // Rule key ascending\n const ruleCompare = a.ruleKey.localeCompare(b.ruleKey);\n if (ruleCompare !== 0) return ruleCompare;\n\n // Flag instance ID ascending\n return a.flagId.localeCompare(b.flagId);\n });\n}\n\n/**\n * Sort findings deterministically.\n * Order: type asc, file asc (if available), location asc\n */\nexport function sortFindings(findings: Finding[]): Finding[] {\n return [...findings].sort((a, b) => {\n // Type ascending\n const typeCompare = a.type.localeCompare(b.type);\n if (typeCompare !== 0) return typeCompare;\n\n // Get first file from evidence (if available)\n const getFirstFile = (f: Finding): string => {\n if (f.evidence && f.evidence.length > 0) {\n return f.evidence[0]!.file;\n }\n return \"\";\n };\n\n const fileA = getFirstFile(a);\n const fileB = getFirstFile(b);\n \n if (fileA && fileB) {\n const fileCompare = comparePaths(fileA, fileB);\n if (fileCompare !== 0) return fileCompare;\n }\n\n // Get first line number from evidence (if available)\n const getFirstLine = (f: Finding): number => {\n if (f.evidence && f.evidence.length > 0) {\n const ev = f.evidence[0]!;\n if (ev.line !== undefined) return ev.line;\n if (ev.hunk?.newStart !== undefined) return ev.hunk.newStart;\n }\n return 0;\n };\n\n const lineA = getFirstLine(a);\n const lineB = getFirstLine(b);\n \n return lineA - lineB;\n });\n}\n\n/**\n * Sort evidence deterministically.\n * Order: file asc, preserve line order within each file\n */\nexport function sortEvidence(evidence: Evidence[]): Evidence[] {\n return [...evidence].sort((a, b) => {\n // File ascending\n const fileCompare = comparePaths(a.file, b.file);\n if (fileCompare !== 0) return fileCompare;\n\n // Line number ascending (if available)\n const lineA = a.line ?? (a.hunk?.newStart ?? 0);\n const lineB = b.line ?? (b.hunk?.newStart ?? 0);\n \n return lineA - lineB;\n });\n}\n\n/**\n * Sort risk flag evidence deterministically.\n * Order: file asc, preserve line order within each file\n */\nexport function sortRiskFlagEvidence(evidence: RiskFlagEvidence[]): RiskFlagEvidence[] {\n return [...evidence].sort((a, b) => {\n // File ascending\n const fileCompare = comparePaths(a.file, b.file);\n if (fileCompare !== 0) return fileCompare;\n\n // Hunk order (if available) - extract line numbers from hunk string\n if (a.hunk && b.hunk) {\n const extractLineNum = (hunk: string): number => {\n const match = hunk.match(/\\+(\\d+)/);\n return match ? parseInt(match[1], 10) : 0;\n };\n return extractLineNum(a.hunk) - extractLineNum(b.hunk);\n }\n \n return 0;\n });\n}\n\n/**\n * Sort file paths deterministically.\n */\nexport function sortFilePaths(paths: string[]): string[] {\n return [...paths].sort(comparePaths);\n}\n\n/**\n * Create a sorted object from key-value pairs.\n * Ensures object keys are in a stable order.\n */\nexport function createSortedObject<T>(\n entries: Array<[string, T]>\n): Record<string, T> {\n const sorted = [...entries].sort((a, b) => a[0].localeCompare(b[0]));\n const result: Record<string, T> = {};\n for (const [key, value] of sorted) {\n result[key] = value;\n }\n return result;\n}\n",
57
- "/**\n * Stable ID generation for findings and risk flags.\n *\n * IDs are deterministic and based on canonical fingerprints of the underlying data.\n * This enables stable references across multiple analysis runs.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { Finding } from \"./types.js\";\n\n/**\n * Normalize a file path to POSIX format for deterministic hashing.\n * Converts backslashes to forward slashes.\n * Note: This is intentionally NOT exported to avoid conflict with sorting.ts's normalizePath.\n */\nfunction normalizePathForHash(path: string): string {\n return path.replace(/\\\\/g, \"/\");\n}\n\n/**\n * Create a stable hash from a string using SHA-256.\n * Returns the first 12 characters of the hex digest.\n */\nexport function stableHash(input: string): string {\n const hash = createHash(\"sha256\").update(input).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\n/**\n * Sort an array deterministically for hashing.\n * Creates a copy to avoid mutating the original.\n */\nfunction sortForHash<T>(arr: T[]): T[] {\n return [...arr].sort();\n}\n\n/**\n * Build a stable finding ID based on the finding's canonical identity.\n *\n * The fingerprint includes:\n * - Finding type\n * - Stable identifying attributes (e.g., env var name, package name, route ID)\n * - Sorted file paths (normalized to POSIX)\n *\n * Format: \"finding.<type>#<hash>\"\n */\nexport function buildFindingId(finding: Finding): string {\n let fingerprint: string;\n\n switch (finding.type) {\n case \"env-var\": {\n // Fingerprint: type + varName + sorted(files)\n const files = sortForHash(finding.evidenceFiles.map(normalizePathForHash));\n fingerprint = `env-var:${finding.name}:${files.join(\",\")}`;\n break;\n }\n\n case \"dependency-change\": {\n // Fingerprint: type + package + from + to + section\n fingerprint = `dependency-change:${finding.name}:${finding.from || \"null\"}:${finding.to || \"null\"}:${finding.section}`;\n break;\n }\n\n case \"route-change\": {\n // Fingerprint: type + routeId + change + routeType\n const routeId = normalizePathForHash(finding.routeId);\n fingerprint = `route-change:${routeId}:${finding.change}:${finding.routeType}`;\n break;\n }\n\n case \"db-migration\": {\n // Fingerprint: type + tool + sorted(files)\n const files = sortForHash(finding.files.map(normalizePathForHash));\n fingerprint = `db-migration:${finding.tool}:${files.join(\",\")}`;\n break;\n }\n\n case \"cloudflare-change\": {\n // Fingerprint: type + area + sorted(files)\n const files = sortForHash(finding.files.map(normalizePathForHash));\n fingerprint = `cloudflare-change:${finding.area}:${files.join(\",\")}`;\n break;\n }\n\n case \"test-change\": {\n // Fingerprint: type + framework + sorted(files)\n const files = sortForHash(finding.files.map(normalizePathForHash));\n fingerprint = `test-change:${finding.framework}:${files.join(\",\")}`;\n break;\n }\n\n case \"security-file\": {\n // Fingerprint: type + sorted(files) + sorted(reasons)\n const files = sortForHash(finding.files.map(normalizePathForHash));\n const reasons = sortForHash(finding.reasons);\n fingerprint = `security-file:${files.join(\",\")}:${reasons.join(\",\")}`;\n break;\n }\n\n case \"file-category\": {\n // Fingerprint: type + sorted category entries\n const entries = Object.entries(finding.categories)\n .map(([cat, files]) => `${cat}:${sortForHash(files.map(normalizePathForHash)).join(\",\")}`)\n .sort();\n fingerprint = `file-category:${entries.join(\"|\")}`;\n break;\n }\n\n case \"file-summary\": {\n // Fingerprint: type + category + sorted file lists\n const added = sortForHash(finding.added.map(normalizePathForHash)).join(\",\");\n const modified = sortForHash(finding.modified.map(normalizePathForHash)).join(\",\");\n const deleted = sortForHash(finding.deleted.map(normalizePathForHash)).join(\",\");\n const renamed = sortForHash(\n finding.renamed.map(r => `${normalizePathForHash(r.from)}->${normalizePathForHash(r.to)}`)\n ).join(\",\");\n fingerprint = `file-summary:${finding.category}:a=${added}:m=${modified}:d=${deleted}:r=${renamed}`;\n break;\n }\n\n case \"convention-violation\": {\n // Fingerprint: type + message + sorted(files)\n const files = sortForHash(finding.files.map(normalizePathForHash));\n fingerprint = `convention-violation:${finding.message}:${files.join(\",\")}`;\n break;\n }\n\n case \"test-parity-violation\": {\n // Fingerprint: type + sourceFile + sorted(expectedTestLocations)\n const sourceFile = normalizePathForHash(finding.sourceFile);\n const expectedLocs = sortForHash(finding.expectedTestLocations.map(normalizePathForHash));\n fingerprint = `test-parity-violation:${sourceFile}:${expectedLocs.join(\",\")}`;\n break;\n }\n\n case \"impact-analysis\": {\n // Fingerprint: type + sourceFile + sorted(affectedFiles)\n const sourceFile = normalizePathForHash(finding.sourceFile);\n const affected = sortForHash(finding.affectedFiles.map(normalizePathForHash));\n fingerprint = `impact-analysis:${sourceFile}:${affected.join(\",\")}`;\n break;\n }\n\n case \"ci-workflow\": {\n // Fingerprint: type + file + riskType\n const file = normalizePathForHash(finding.file);\n fingerprint = `ci-workflow:${file}:${finding.riskType}`;\n break;\n }\n\n case \"sql-risk\": {\n // Fingerprint: type + file + riskType\n const file = normalizePathForHash(finding.file);\n fingerprint = `sql-risk:${file}:${finding.riskType}`;\n break;\n }\n\n case \"infra-change\": {\n // Fingerprint: type + infraType + sorted(files)\n const files = sortForHash(finding.files.map(normalizePathForHash));\n fingerprint = `infra-change:${finding.infraType}:${files.join(\",\")}`;\n break;\n }\n\n case \"api-contract-change\": {\n // Fingerprint: type + sorted(files)\n const files = sortForHash(finding.files.map(normalizePathForHash));\n fingerprint = `api-contract-change:${files.join(\",\")}`;\n break;\n }\n\n case \"large-diff\": {\n // Fingerprint: type + filesChanged + linesChanged\n fingerprint = `large-diff:${finding.filesChanged}:${finding.linesChanged}`;\n break;\n }\n\n case \"lockfile-mismatch\": {\n // Fingerprint: type + manifestChanged + lockfileChanged\n fingerprint = `lockfile-mismatch:${finding.manifestChanged}:${finding.lockfileChanged}`;\n break;\n }\n\n case \"test-gap\": {\n // Fingerprint: type + prodFilesChanged + testFilesChanged\n fingerprint = `test-gap:${finding.prodFilesChanged}:${finding.testFilesChanged}`;\n break;\n }\n\n case \"stencil-component-change\": {\n // Fingerprint: type + tag + change + file\n const file = normalizePathForHash(finding.file);\n fingerprint = `stencil-component-change:${finding.tag}:${finding.change}:${file}:${finding.fromTag || \"\"}:${finding.toTag || \"\"}`;\n break;\n }\n\n case \"stencil-prop-change\": {\n // Fingerprint: type + tag + propName + change + file\n const file = normalizePathForHash(finding.file);\n fingerprint = `stencil-prop-change:${finding.tag}:${finding.propName}:${finding.change}:${file}`;\n break;\n }\n\n case \"stencil-event-change\": {\n // Fingerprint: type + tag + eventName + change + file\n const file = normalizePathForHash(finding.file);\n fingerprint = `stencil-event-change:${finding.tag}:${finding.eventName}:${finding.change}:${file}`;\n break;\n }\n\n case \"stencil-method-change\": {\n // Fingerprint: type + tag + methodName + change + file\n const file = normalizePathForHash(finding.file);\n fingerprint = `stencil-method-change:${finding.tag}:${finding.methodName}:${finding.change}:${file}`;\n break;\n }\n\n case \"stencil-slot-change\": {\n // Fingerprint: type + tag + slotName + change + file\n const file = normalizePathForHash(finding.file);\n fingerprint = `stencil-slot-change:${finding.tag}:${finding.slotName}:${finding.change}:${file}`;\n break;\n }\n\n case \"risk-flag\": {\n // Fingerprint: type + risk + evidenceText (legacy)\n // Note: risk-flag findings are being phased out in favor of derived flags\n fingerprint = `risk-flag:${finding.risk}:${finding.evidenceText}`;\n break;\n }\n\n case \"graphql-change\": {\n // Fingerprint: type + file + isBreaking + sorted(breakingChanges) + sorted(addedElements)\n const file = normalizePathForHash(finding.file);\n const breaking = sortForHash(finding.breakingChanges).join(\",\");\n const added = sortForHash(finding.addedElements).join(\",\");\n fingerprint = `graphql-change:${file}:${finding.isBreaking}:${breaking}:${added}`;\n break;\n }\n\n case \"typescript-config\": {\n // Fingerprint: type + file + isBreaking + sorted(changedOptions)\n const file = normalizePathForHash(finding.file);\n const added = sortForHash(finding.changedOptions.added).join(\",\");\n const removed = sortForHash(finding.changedOptions.removed).join(\",\");\n const modified = sortForHash(finding.changedOptions.modified).join(\",\");\n fingerprint = `typescript-config:${file}:${finding.isBreaking}:a=${added}:r=${removed}:m=${modified}`;\n break;\n }\n\n case \"tailwind-config\": {\n // Fingerprint: type + file + configType + isBreaking + sorted(affectedSections)\n const file = normalizePathForHash(finding.file);\n const sections = sortForHash(finding.affectedSections).join(\",\");\n fingerprint = `tailwind-config:${file}:${finding.configType}:${finding.isBreaking}:${sections}`;\n break;\n }\n\n case \"monorepo-config\": {\n // Fingerprint: type + file + tool + sorted(affectedFields)\n const file = normalizePathForHash(finding.file);\n const fields = sortForHash(finding.affectedFields).join(\",\");\n fingerprint = `monorepo-config:${file}:${finding.tool}:${fields}`;\n break;\n }\n\n case \"package-exports\": {\n // Fingerprint: type + isBreaking + sorted(addedExports) + sorted(removedExports)\n const added = sortForHash(finding.addedExports).join(\",\");\n const removed = sortForHash(finding.removedExports).join(\",\");\n fingerprint = `package-exports:${finding.isBreaking}:a=${added}:r=${removed}`;\n break;\n }\n\n default: {\n // TypeScript exhaustiveness check\n const _exhaustive: never = finding;\n throw new Error(`Unknown finding type: ${(_exhaustive as Finding).type}`);\n }\n }\n\n const hash = stableHash(fingerprint);\n return `finding.${finding.type}#${hash}`;\n}\n\n/**\n * Build a stable flag ID based on the rule key and related findings.\n *\n * Format: \"flag.<ruleKey>#<hash>\"\n *\n * The hash is computed from:\n * - ruleKey\n * - sorted relatedFindingIds\n */\nexport function buildFlagId(ruleKey: string, relatedFindingIds: string[]): string {\n const sortedIds = sortForHash(relatedFindingIds);\n const fingerprint = `${ruleKey}:${sortedIds.join(\",\")}`;\n const hash = stableHash(fingerprint);\n return `flag.${ruleKey}#${hash}`;\n}\n\n/**\n * Assign findingId to a finding (immutable - returns new finding).\n */\nexport function assignFindingId<T extends Finding>(finding: T): T & { findingId: string } {\n const findingId = buildFindingId(finding);\n return { ...finding, findingId };\n}\n",
58
- "/**\n * Facts output builder - assembles complete agent-grade facts.\n */\n\nimport type {\n ChangeSet,\n ChangesetInfo,\n ChangesetWarning,\n DiffMode,\n FactsOutput,\n FileCategory,\n FileCategoryFinding,\n FileSummaryFinding,\n Finding,\n Filters,\n GitInfo,\n LargeDiffFinding,\n LockfileFinding,\n ProfileInfo,\n ProfileName,\n RiskScore,\n SkippedFile,\n Stats,\n} from \"../../core/types.js\";\nimport { redactEvidence } from \"../../core/evidence.js\";\nimport { aggregateCategories, buildSummaryByArea } from \"./categories.js\";\nimport { deriveActions } from \"./actions.js\";\nimport { buildHighlights } from \"./highlights.js\";\nimport { DEFAULT_EXCLUDES } from \"../../core/filters.js\";\nimport { sortFindings as sortFindingsDeterministically, sortEvidence } from \"../../core/sorting.js\";\nimport { getRepoRoot, isWorkingDirDirty } from \"../../git/collector.js\";\nimport { assignFindingId } from \"../../core/ids.js\";\n\n/**\n * Build facts output options.\n */\nexport interface BuildFactsOptions {\n changeSet: ChangeSet;\n findings: Finding[];\n riskScore: RiskScore;\n requestedProfile: ProfileName;\n detectedProfile: ProfileName;\n profileConfidence: \"high\" | \"medium\" | \"low\";\n profileReasons: string[];\n filters?: {\n excludes?: string[];\n includes?: string[];\n redact?: boolean;\n maxFileBytes?: number;\n maxDiffBytes?: number;\n maxFindings?: number;\n };\n skippedFiles?: SkippedFile[];\n warnings?: string[];\n noTimestamp?: boolean;\n /** Pre-computed git repository root (avoids git call if provided) */\n repoRoot?: string;\n /** Pre-computed working directory dirty status (avoids git call if provided) */\n isDirty?: boolean;\n /** Original CLI mode used to generate this output */\n mode?: DiffMode;\n}\n\n/**\n * Calculate stats from change set.\n */\nfunction calculateStats(\n changeSet: ChangeSet,\n skippedFiles: SkippedFile[]\n): Stats {\n let insertions = 0;\n let deletions = 0;\n\n for (const diff of changeSet.diffs) {\n for (const hunk of diff.hunks) {\n insertions += hunk.additions.length;\n deletions += hunk.deletions.length;\n }\n }\n\n return {\n filesChanged: changeSet.files.length,\n insertions,\n deletions,\n skippedFilesCount: skippedFiles.length,\n };\n}\n\n/** Meta-finding types that should be extracted to changeset */\nconst META_FINDING_TYPES = new Set([\n \"file-summary\",\n \"file-category\",\n \"large-diff\",\n \"lockfile-mismatch\",\n]);\n\n/**\n * Check if a finding is a meta-finding (organizational, not domain-specific).\n */\nfunction isMetaFinding(finding: Finding): boolean {\n return META_FINDING_TYPES.has(finding.type);\n}\n\n/**\n * Build changeset info from meta-findings.\n */\nfunction buildChangesetInfo(findings: Finding[]): ChangesetInfo {\n // Find the meta-findings\n const fileSummary = findings.find(f => f.type === \"file-summary\") as FileSummaryFinding | undefined;\n const fileCategory = findings.find(f => f.type === \"file-category\") as FileCategoryFinding | undefined;\n const largeDiff = findings.find(f => f.type === \"large-diff\") as LargeDiffFinding | undefined;\n const lockfileMismatch = findings.find(f => f.type === \"lockfile-mismatch\") as LockfileFinding | undefined;\n\n // Build files structure\n const files = {\n added: fileSummary?.added ?? [],\n modified: fileSummary?.modified ?? [],\n deleted: fileSummary?.deleted ?? [],\n renamed: fileSummary?.renamed ?? [],\n };\n\n // Build byCategory - ensure all categories are present\n const defaultCategories: Record<FileCategory, string[]> = {\n product: [],\n tests: [],\n ci: [],\n infra: [],\n database: [],\n docs: [],\n dependencies: [],\n config: [],\n artifacts: [],\n other: [],\n };\n const byCategory = fileCategory?.categories ?? defaultCategories;\n\n // Build category summary\n const categorySummary = fileCategory?.summary ?? [];\n\n // Build warnings\n const warnings: ChangesetWarning[] = [];\n if (largeDiff) {\n warnings.push({\n type: \"large-diff\",\n filesChanged: largeDiff.filesChanged,\n linesChanged: largeDiff.linesChanged,\n });\n }\n if (lockfileMismatch) {\n warnings.push({\n type: \"lockfile-mismatch\",\n manifestChanged: lockfileMismatch.manifestChanged,\n lockfileChanged: lockfileMismatch.lockfileChanged,\n });\n }\n\n // Include change descriptions if available\n const changeDescriptions = fileSummary?.changeDescriptions;\n\n return {\n files,\n byCategory,\n categorySummary,\n changeDescriptions,\n warnings,\n };\n}\n\n/**\n * Build complete facts output.\n */\nexport async function buildFacts(\n options: BuildFactsOptions\n): Promise<FactsOutput> {\n const {\n changeSet,\n findings: rawFindings,\n riskScore,\n requestedProfile,\n detectedProfile,\n profileConfidence,\n profileReasons,\n filters: userFilters,\n skippedFiles: userSkippedFiles,\n warnings: userWarnings,\n noTimestamp,\n repoRoot: providedRepoRoot,\n isDirty: providedIsDirty,\n mode,\n } = options;\n\n // Sort findings deterministically first (without touching evidence yet)\n let findings = sortFindingsDeterministically(rawFindings);\n\n // Assign stable findingIds to all findings\n findings = findings.map(assignFindingId);\n\n // Apply max findings limit early to avoid processing evidence for discarded findings\n if (userFilters?.maxFindings && findings.length > userFilters.maxFindings) {\n findings = findings.slice(0, userFilters.maxFindings);\n }\n\n // Now process evidence only for the findings we're keeping\n if (userFilters?.redact) {\n findings = findings.map(finding => ({\n ...finding,\n evidence: sortEvidence(finding.evidence.map(redactEvidence)),\n }));\n } else {\n // Sort evidence even when not redacting\n findings = findings.map(finding => ({\n ...finding,\n evidence: sortEvidence(finding.evidence),\n }));\n }\n\n // Get git info - use provided values if available, otherwise fetch in parallel\n let repoRoot: string;\n let isDirty: boolean;\n\n if (providedRepoRoot !== undefined && providedIsDirty !== undefined) {\n // Both provided, use them directly\n repoRoot = providedRepoRoot;\n isDirty = providedIsDirty;\n } else if (providedRepoRoot !== undefined) {\n // Only repoRoot provided, fetch isDirty\n repoRoot = providedRepoRoot;\n isDirty = await isWorkingDirDirty();\n } else if (providedIsDirty !== undefined) {\n // Only isDirty provided, fetch repoRoot\n repoRoot = await getRepoRoot();\n isDirty = providedIsDirty;\n } else {\n // Neither provided, fetch both in parallel\n [repoRoot, isDirty] = await Promise.all([\n getRepoRoot(),\n isWorkingDirDirty(),\n ]);\n }\n\n const git: GitInfo = {\n base: changeSet.base,\n head: changeSet.head,\n range: `${changeSet.base}..${changeSet.head}`,\n repoRoot,\n isDirty,\n mode,\n };\n\n const profile: ProfileInfo = {\n requested: requestedProfile,\n detected: detectedProfile,\n confidence: profileConfidence,\n reasons: profileReasons,\n };\n\n const skippedFiles = userSkippedFiles ?? [];\n const stats = calculateStats(changeSet, skippedFiles);\n\n const filtersObj: Filters = {\n defaultExcludes: DEFAULT_EXCLUDES,\n excludes: userFilters?.excludes ?? [],\n includes: userFilters?.includes ?? [],\n redact: userFilters?.redact ?? false,\n maxFileBytes: userFilters?.maxFileBytes ?? 1048576, // 1MB default\n maxDiffBytes: userFilters?.maxDiffBytes ?? 5242880, // 5MB default\n maxFindings: userFilters?.maxFindings,\n };\n\n // Build changeset info from meta-findings (before filtering them out)\n const changeset = buildChangesetInfo(findings);\n\n // Filter out meta-findings - they're now in the changeset structure\n const domainFindings = findings.filter(f => !isMetaFinding(f));\n\n // Aggregate categories (uses domain findings only)\n const categories = aggregateCategories(domainFindings, riskScore.factors);\n const byArea = buildSummaryByArea(categories);\n const highlights = buildHighlights(domainFindings);\n\n const summary = {\n byArea,\n highlights,\n };\n\n // Derive actions (uses all findings for completeness)\n const actions = deriveActions(findings, detectedProfile);\n\n const warnings = userWarnings ?? [];\n\n return {\n schemaVersion: \"2.1\",\n generatedAt: noTimestamp ? undefined : new Date().toISOString(),\n git,\n profile,\n stats,\n filters: filtersObj,\n summary,\n categories,\n changeset,\n risk: riskScore,\n findings: domainFindings,\n actions,\n skippedFiles,\n warnings,\n };\n}\n",
59
- "/**\n * Delta computation utilities for --since comparison.\n * Provides ID-based diff logic for facts and risk-report outputs.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport type {\n FactsOutput,\n RiskReport,\n ScopeWarning,\n ScopeMetadata,\n} from \"./types.js\";\n\n/**\n * Load and parse a JSON file.\n */\nexport async function loadJson(path: string): Promise<any> {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content);\n}\n\n/**\n * Normalize an object for comparison by removing volatile fields.\n * - Removes generatedAt timestamps\n * - Ensures consistent ordering for arrays\n */\nexport function normalizeForComparison<T extends Record<string, any>>(obj: T): T {\n const normalized = { ...obj };\n\n // Remove volatile fields\n delete normalized.generatedAt;\n\n return normalized;\n}\n\n/**\n * Compare two normalized objects for deep equality.\n * Sorts object keys to avoid false positives from property order differences.\n */\nfunction deepEqual(a: any, b: any): boolean {\n // Sort keys recursively to ensure consistent ordering\n const sortKeys = (obj: any): any => {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n if (Array.isArray(obj)) {\n return obj.map(sortKeys);\n }\n const sorted: any = {};\n Object.keys(obj).sort().forEach(key => {\n sorted[key] = sortKeys(obj[key]);\n });\n return sorted;\n };\n\n return JSON.stringify(sortKeys(a)) === JSON.stringify(sortKeys(b));\n}\n\n/**\n * Build a map from ID to item for efficient lookup.\n */\nfunction buildIdMap<T extends { findingId?: string; flagId?: string }>(\n items: T[]\n): Map<string, T> {\n const map = new Map<string, T>();\n\n for (const item of items) {\n const id = item.findingId || item.flagId;\n if (id) {\n map.set(id, item);\n }\n }\n\n return map;\n}\n\n/**\n * Compute delta between two sets of items keyed by ID.\n */\nexport function diffById<T extends { findingId?: string; flagId?: string }>(params: {\n beforeItems: T[];\n afterItems: T[];\n}): {\n added: string[];\n removed: string[];\n changed: Array<{ id: string; before: T; after: T }>;\n} {\n const beforeMap = buildIdMap(params.beforeItems);\n const afterMap = buildIdMap(params.afterItems);\n\n const added: string[] = [];\n const removed: string[] = [];\n const changed: Array<{ id: string; before: T; after: T }> = [];\n\n // Find added and changed\n for (const [id, afterItem] of afterMap) {\n const beforeItem = beforeMap.get(id);\n\n if (!beforeItem) {\n added.push(id);\n } else {\n // Normalize both items for comparison\n const normalizedBefore = normalizeForComparison(beforeItem);\n const normalizedAfter = normalizeForComparison(afterItem);\n\n if (!deepEqual(normalizedBefore, normalizedAfter)) {\n changed.push({ id, before: beforeItem, after: afterItem });\n }\n }\n }\n\n // Find removed\n for (const id of beforeMap.keys()) {\n if (!afterMap.has(id)) {\n removed.push(id);\n }\n }\n\n // Sort for deterministic output\n added.sort();\n removed.sort();\n changed.sort((a, b) => a.id.localeCompare(b.id));\n\n return { added, removed, changed };\n}\n\n/**\n * Compare scope metadata and generate warnings for mismatches.\n */\nexport function compareScopeMetadata(\n before: ScopeMetadata,\n after: ScopeMetadata\n): ScopeWarning[] {\n const warnings: ScopeWarning[] = [];\n\n if (before.mode !== after.mode) {\n warnings.push({\n code: \"scope-mismatch\",\n message: `Previous run used mode=${before.mode}, current is mode=${after.mode}`,\n });\n }\n\n if (before.base !== after.base) {\n warnings.push({\n code: \"scope-mismatch\",\n message: `Previous run used base=${before.base}, current is base=${after.base}`,\n });\n }\n\n if (before.head !== after.head) {\n warnings.push({\n code: \"scope-mismatch\",\n message: `Previous run used head=${before.head}, current is head=${after.head}`,\n });\n }\n\n if (before.profile !== after.profile) {\n warnings.push({\n code: \"scope-mismatch\",\n message: `Previous run used profile=${before.profile}, current is profile=${after.profile}`,\n });\n }\n\n // Compare include/exclude arrays\n const beforeIncludes = JSON.stringify(before.include || []);\n const afterIncludes = JSON.stringify(after.include || []);\n if (beforeIncludes !== afterIncludes) {\n warnings.push({\n code: \"scope-mismatch\",\n message: `Include filters differ between runs`,\n });\n }\n\n const beforeExcludes = JSON.stringify(before.exclude || []);\n const afterExcludes = JSON.stringify(after.exclude || []);\n if (beforeExcludes !== afterExcludes) {\n warnings.push({\n code: \"scope-mismatch\",\n message: `Exclude filters differ between runs`,\n });\n }\n\n // Compare only (for risk-report)\n if (before.only !== undefined || after.only !== undefined) {\n const beforeOnly = JSON.stringify(before.only || null);\n const afterOnly = JSON.stringify(after.only || null);\n if (beforeOnly !== afterOnly) {\n warnings.push({\n code: \"scope-mismatch\",\n message: `Category filters differ between runs`,\n });\n }\n }\n\n return warnings;\n}\n\n/**\n * Extract scope metadata from FactsOutput for comparison.\n *\n * The mode field is read directly from the stored git.mode if available.\n * For backward compatibility with older outputs that don't have git.mode,\n * we fall back to heuristic inference based on base/head values.\n */\nexport function extractFactsScope(facts: FactsOutput): ScopeMetadata {\n // Use stored mode if available, otherwise fall back to heuristic\n let mode: string;\n if (facts.git.mode) {\n mode = facts.git.mode;\n } else {\n // Legacy fallback: infer mode from base/head values\n mode = facts.git.base ? \"branch\" : \"unstaged\";\n }\n\n return {\n mode,\n base: facts.git.base || null,\n head: facts.git.head || null,\n profile: facts.profile.detected,\n include: facts.filters.includes,\n exclude: facts.filters.excludes,\n };\n}\n\n/**\n * Extract scope metadata from RiskReport for comparison.\n *\n * The mode field is read directly from the stored range.mode if available.\n * For backward compatibility with older outputs that don't have range.mode,\n * we fall back to heuristic inference based on base/head values.\n *\n * Filters (only/exclude) are read from report.filters if available.\n */\nexport function extractRiskReportScope(report: RiskReport): ScopeMetadata {\n // Use stored mode if available, otherwise fall back to heuristic\n let mode: string;\n if (report.range.mode) {\n mode = report.range.mode;\n } else {\n // Legacy fallback: infer mode from base/head values\n mode = report.range.base ? \"branch\" : \"unstaged\";\n }\n\n return {\n mode,\n base: report.range.base || null,\n head: report.range.head || null,\n // Read filters from stored report if available\n only: report.filters?.only || null,\n exclude: report.filters?.exclude,\n };\n}\n",
60
- "/**\n * Delta computation for facts --since feature.\n */\n\nimport type {\n FactsOutput,\n FactsDelta,\n Finding,\n FindingChange,\n ScopeMetadata,\n} from \"../../core/types.js\";\nimport {\n loadJson,\n diffById,\n compareScopeMetadata,\n extractFactsScope,\n} from \"../../core/delta.js\";\nimport { BranchNarratorError } from \"../../core/errors.js\";\n\n/**\n * Options for computing facts delta.\n */\nexport interface ComputeFactsDeltaOptions {\n sincePath: string;\n currentFacts: FactsOutput;\n mode: string;\n base: string | null;\n head: string | null;\n profile: string;\n include: string[];\n exclude: string[];\n sinceStrict: boolean;\n}\n\n/**\n * Compute delta between current facts and a previous facts output.\n */\nexport async function computeFactsDelta(\n options: ComputeFactsDeltaOptions\n): Promise<FactsDelta> {\n const {\n sincePath,\n currentFacts,\n mode,\n base,\n head,\n profile,\n include,\n exclude,\n sinceStrict,\n } = options;\n\n // Load previous facts\n let previousFacts: FactsOutput;\n try {\n previousFacts = await loadJson(sincePath);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BranchNarratorError(\n `Failed to load previous facts from ${sincePath}: ${errorMessage}`,\n 1\n );\n }\n\n // Validate it looks like a FactsOutput\n if (!previousFacts.schemaVersion || !previousFacts.findings) {\n throw new BranchNarratorError(\n `File ${sincePath} does not appear to be a valid facts output`,\n 1\n );\n }\n\n // Build scope metadata for current run\n const currentScope: ScopeMetadata = {\n mode,\n base,\n head,\n profile,\n include,\n exclude,\n };\n\n // Extract scope from previous run\n const previousScope = extractFactsScope(previousFacts);\n\n // Compare scopes and generate warnings\n const warnings = compareScopeMetadata(previousScope, currentScope);\n\n // If strict mode and warnings exist, error out\n if (sinceStrict && warnings.length > 0) {\n throw new BranchNarratorError(\n `Scope mismatch detected (--since-strict): ${warnings.map(w => w.message).join(\"; \")}`,\n 1\n );\n }\n\n // Compute delta\n const { added, removed, changed } = diffById({\n beforeItems: previousFacts.findings,\n afterItems: currentFacts.findings,\n });\n\n // Build FindingChange objects\n const findingChanges: FindingChange[] = changed.map(c => ({\n findingId: c.id,\n before: c.before as Finding,\n after: c.after as Finding,\n }));\n\n // Build command metadata\n const commandArgs = [\"--mode\", mode];\n if (base) commandArgs.push(\"--base\", base);\n if (head) commandArgs.push(\"--head\", head);\n commandArgs.push(\"--since\", sincePath);\n if (sinceStrict) commandArgs.push(\"--since-strict\");\n\n return {\n schemaVersion: \"1.0\",\n generatedAt: new Date().toISOString(),\n command: {\n name: \"facts\",\n args: commandArgs,\n },\n since: {\n path: sincePath,\n schemaVersion: previousFacts.schemaVersion,\n },\n current: {\n schemaVersion: currentFacts.schemaVersion,\n },\n scope: currentScope,\n warnings,\n delta: {\n added,\n removed,\n changed: findingChanges,\n },\n summary: {\n addedCount: added.length,\n removedCount: removed.length,\n changedCount: findingChanges.length,\n },\n };\n}\n",
61
- "/**\n * Facts command - builds agent-grade facts output.\n */\n\nimport type { BuildFactsOptions } from \"./builder.js\";\nimport { buildFacts } from \"./builder.js\";\n\nexport { buildFacts, type BuildFactsOptions } from \"./builder.js\";\nexport { aggregateCategories, buildSummaryByArea } from \"./categories.js\";\nexport { deriveActions } from \"./actions.js\";\nexport { computeFactsDelta, type ComputeFactsDeltaOptions } from \"./delta.js\";\n\n/**\n * Execute the facts command.\n * This is the standard command handler that follows the execute* naming convention.\n */\nexport async function executeFacts(options: BuildFactsOptions) {\n return buildFacts(options);\n}\n",
62
- "/**\n * SARIF 2.1.0 renderer for branch-narrator facts output.\n *\n * This module converts findings from branch-narrator into SARIF format\n * for GitHub Code Scanning and other static analysis tool integrations.\n *\n * SARIF spec: https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html\n */\n\nimport type {\n ChangeSet,\n CIWorkflowFinding,\n DbMigrationFinding,\n DependencyChangeFinding,\n EnvVarFinding,\n FactsOutput,\n Finding,\n GraphQLChangeFinding,\n InfraChangeFinding,\n LargeDiffFinding,\n PackageExportsFinding,\n RouteChangeFinding,\n CloudflareChangeFinding,\n SecurityFileFinding,\n SQLRiskFinding,\n StencilComponentChangeFinding,\n StencilEventChangeFinding,\n StencilMethodChangeFinding,\n StencilPropChangeFinding,\n StencilSlotChangeFinding,\n TestGapFinding,\n TypeScriptConfigFinding,\n} from \"../core/types.js\";\nimport { getAdditionsWithLineNumbers } from \"../git/parser.js\";\nimport { getVersionSync } from \"../core/version.js\";\n\n// ============================================================================\n// SARIF 2.1.0 Types (subset needed for our use case)\n// ============================================================================\n\nexport interface SarifLog {\n version: \"2.1.0\";\n $schema: string;\n runs: SarifRun[];\n}\n\nexport interface SarifRun {\n tool: SarifTool;\n results: SarifResult[];\n originalUriBaseIds?: Record<string, SarifArtifactLocation>;\n}\n\nexport interface SarifTool {\n driver: SarifToolComponent;\n}\n\nexport interface SarifToolComponent {\n name: string;\n version?: string;\n informationUri?: string;\n rules?: SarifReportingDescriptor[];\n}\n\nexport interface SarifReportingDescriptor {\n id: string;\n name?: string;\n shortDescription?: SarifMultiformatMessageString;\n fullDescription?: SarifMultiformatMessageString;\n help?: SarifMultiformatMessageString;\n defaultConfiguration?: SarifReportingConfiguration;\n properties?: Record<string, unknown>;\n}\n\nexport interface SarifReportingConfiguration {\n level?: SarifLevel;\n}\n\nexport interface SarifMultiformatMessageString {\n text: string;\n markdown?: string;\n}\n\nexport type SarifLevel = \"none\" | \"note\" | \"warning\" | \"error\";\n\nexport interface SarifResult {\n ruleId: string;\n level?: SarifLevel;\n message: SarifMessage;\n locations?: SarifLocation[];\n partialFingerprints?: Record<string, string>;\n properties?: Record<string, unknown>;\n}\n\nexport interface SarifMessage {\n text: string;\n markdown?: string;\n}\n\nexport interface SarifLocation {\n physicalLocation?: SarifPhysicalLocation;\n}\n\nexport interface SarifPhysicalLocation {\n artifactLocation: SarifArtifactLocation;\n region?: SarifRegion;\n}\n\nexport interface SarifArtifactLocation {\n uri: string;\n uriBaseId?: string;\n}\n\nexport interface SarifRegion {\n startLine?: number;\n endLine?: number;\n startColumn?: number;\n endColumn?: number;\n}\n\n// ============================================================================\n// Rule Definitions\n// ============================================================================\n\nexport interface RuleMapping {\n id: string;\n name: string;\n shortDescription: string;\n fullDescription: string;\n defaultLevel: SarifLevel;\n category?: string;\n}\n\n/**\n * Stable rule set for SARIF output.\n * These IDs are stable and should not change across versions.\n */\nexport const SARIF_RULES: Record<string, RuleMapping> = {\n BNR001: {\n id: \"BNR001\",\n name: \"DangerousSqlInMigration\",\n shortDescription: \"Dangerous SQL detected in migration\",\n fullDescription:\n \"Database migration contains potentially destructive SQL operations (DROP, TRUNCATE, ALTER TYPE, etc.) that could cause data loss or service disruption.\",\n defaultLevel: \"error\",\n category: \"database\",\n },\n BNR002: {\n id: \"BNR002\",\n name: \"MigrationChanged\",\n shortDescription: \"Migration changed (non-destructive)\",\n fullDescription:\n \"Database migration file has been modified or added. Review schema changes for compatibility and rollback safety.\",\n defaultLevel: \"warning\",\n category: \"database\",\n },\n BNR003: {\n id: \"BNR003\",\n name: \"MajorDependencyBump\",\n shortDescription: \"Major bump in critical dependencies\",\n fullDescription:\n \"Major version bump detected in critical framework dependencies (e.g., @sveltejs/kit, svelte, vite, react, next). Major upgrades may introduce breaking changes.\",\n defaultLevel: \"warning\",\n category: \"dependencies\",\n },\n BNR004: {\n id: \"BNR004\",\n name: \"NewEnvVarReference\",\n shortDescription: \"New environment variable reference detected\",\n fullDescription:\n \"Code references a new environment variable. Ensure this variable is documented and configured in all deployment environments.\",\n defaultLevel: \"warning\",\n category: \"config_env\",\n },\n BNR005: {\n id: \"BNR005\",\n name: \"CloudflareConfigChanged\",\n shortDescription: \"Cloudflare configuration changed\",\n fullDescription:\n \"Cloudflare configuration files (wrangler.toml, Pages workflows) have been modified. Review deployment settings and worker configurations.\",\n defaultLevel: \"note\",\n category: \"infra\",\n },\n BNR006: {\n id: \"BNR006\",\n name: \"EndpointChanged\",\n shortDescription: \"API endpoint changed\",\n fullDescription:\n \"API endpoint file has been added, modified, or deleted. Verify API contract compatibility and update client code if needed.\",\n defaultLevel: \"note\",\n category: \"api\",\n },\n BNR007: {\n id: \"BNR007\",\n name: \"CIWorkflowPermissionsBroadened\",\n shortDescription: \"CI workflow permissions broadened\",\n fullDescription:\n \"GitHub Actions workflow has broadened permissions, which could allow unauthorized access to secrets or repository data. Review the permission changes carefully.\",\n defaultLevel: \"error\",\n category: \"security\",\n },\n BNR008: {\n id: \"BNR008\",\n name: \"CIWorkflowPullRequestTarget\",\n shortDescription: \"CI workflow uses pull_request_target\",\n fullDescription:\n \"GitHub Actions workflow uses pull_request_target trigger, which runs with write permissions on the base repository. This can be exploited if the workflow checks out or runs code from the PR.\",\n defaultLevel: \"error\",\n category: \"security\",\n },\n BNR009: {\n id: \"BNR009\",\n name: \"SecurityFileChanged\",\n shortDescription: \"Security-sensitive file changed\",\n fullDescription:\n \"A file related to authentication, authorization, or security configuration has been modified. Review these changes carefully for potential vulnerabilities.\",\n defaultLevel: \"warning\",\n category: \"security\",\n },\n BNR010: {\n id: \"BNR010\",\n name: \"GraphQLBreakingChange\",\n shortDescription: \"Breaking change in GraphQL schema\",\n fullDescription:\n \"GraphQL schema contains breaking changes such as removed types, fields, or arguments. This may break existing clients consuming the API.\",\n defaultLevel: \"error\",\n category: \"api\",\n },\n BNR011: {\n id: \"BNR011\",\n name: \"PackageExportsBreakingChange\",\n shortDescription: \"Breaking change in package exports\",\n fullDescription:\n \"Package exports have breaking changes such as removed exports or modified bin entries. This may break downstream consumers of this package.\",\n defaultLevel: \"error\",\n category: \"api\",\n },\n BNR012: {\n id: \"BNR012\",\n name: \"StencilAPIBreakingChange\",\n shortDescription: \"Breaking change in Stencil component API\",\n fullDescription:\n \"Stencil web component has breaking API changes such as removed props, events, methods, or slots. This may break consumers of the component library.\",\n defaultLevel: \"warning\",\n category: \"api\",\n },\n BNR013: {\n id: \"BNR013\",\n name: \"TypeScriptConfigBreaking\",\n shortDescription: \"Breaking TypeScript configuration change\",\n fullDescription:\n \"TypeScript configuration has breaking changes that may cause compilation errors in the codebase, such as stricter type checking options.\",\n defaultLevel: \"warning\",\n category: \"config_env\",\n },\n BNR014: {\n id: \"BNR014\",\n name: \"DestructiveSQL\",\n shortDescription: \"Destructive SQL operation detected\",\n fullDescription:\n \"SQL file contains destructive operations (DROP, TRUNCATE, DELETE without WHERE) that could cause data loss. Review carefully before execution.\",\n defaultLevel: \"error\",\n category: \"database\",\n },\n BNR015: {\n id: \"BNR015\",\n name: \"InfrastructureChanged\",\n shortDescription: \"Infrastructure configuration changed\",\n fullDescription:\n \"Infrastructure files (Dockerfile, Terraform, Kubernetes) have been modified. Review for security implications and deployment impact.\",\n defaultLevel: \"warning\",\n category: \"infra\",\n },\n BNR016: {\n id: \"BNR016\",\n name: \"TestGapDetected\",\n shortDescription: \"Test coverage gap detected\",\n fullDescription:\n \"Production code was modified but no corresponding test files were changed. Consider adding tests to cover the new or modified functionality.\",\n defaultLevel: \"note\",\n category: \"quality\",\n },\n BNR017: {\n id: \"BNR017\",\n name: \"LargeDiff\",\n shortDescription: \"Large diff detected\",\n fullDescription:\n \"This change has a large number of modified files or lines, which may indicate a refactoring or generated code. Consider breaking into smaller PRs for easier review.\",\n defaultLevel: \"note\",\n category: \"quality\",\n },\n};\n\n/**\n * Critical framework dependencies that trigger BNR003.\n */\nconst CRITICAL_DEPENDENCIES = [\n \"@sveltejs/kit\",\n \"svelte\",\n \"vite\",\n \"react\",\n \"react-dom\",\n \"next\",\n \"@stencil/core\",\n];\n\n\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Build a proper file URI from a directory path for SARIF originalUriBaseIds.\n * Handles both Windows and Unix paths correctly per RFC 3986.\n * Always includes trailing slash as this represents a base directory.\n */\nfunction buildFileUri(path: string): string {\n // Normalize backslashes to forward slashes for Windows\n const normalized = path.replace(/\\\\/g, \"/\");\n \n // RFC 3986: file URI scheme is file:/// followed by absolute path\n // Unix directory: /home/user → file:///home/user/\n // Windows directory: C:/path → file:///C:/path/\n \n // All file URIs have three slashes total (file:// + / + path)\n // Trailing slash indicates directory per SARIF spec\n return \"file:///\" + normalized + \"/\";\n}\n\n// ============================================================================\n// Renderer\n// ============================================================================\n\n/**\n * Render facts output as SARIF 2.1.0.\n */\nexport function renderSarif(facts: FactsOutput, changeSet: ChangeSet): SarifLog {\n const results = findingsToSarifResults(facts.findings, changeSet);\n\n // Collect unique rule IDs used in results\n const usedRuleIds = new Set(results.map((r) => r.ruleId));\n const rules = Array.from(usedRuleIds)\n .sort() // Stable ordering\n .map((ruleId) => {\n const rule = SARIF_RULES[ruleId];\n if (!rule) {\n throw new Error(`Unknown SARIF rule ID: ${ruleId}`);\n }\n return ruleToDescriptor(rule);\n });\n\n return {\n version: \"2.1.0\",\n $schema: \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n runs: [\n {\n tool: {\n driver: {\n name: \"branch-narrator\",\n version: getVersionSync(),\n informationUri: \"https://github.com/better-vibe/branch-narrator\",\n rules,\n },\n },\n results,\n originalUriBaseIds: {\n SRCROOT: {\n uri: buildFileUri(facts.git.repoRoot),\n },\n },\n },\n ],\n };\n}\n\n/**\n * Convert a rule mapping to a SARIF reporting descriptor.\n */\nfunction ruleToDescriptor(rule: RuleMapping): SarifReportingDescriptor {\n return {\n id: rule.id,\n name: rule.name,\n shortDescription: { text: rule.shortDescription },\n fullDescription: { text: rule.fullDescription },\n defaultConfiguration: {\n level: rule.defaultLevel,\n },\n properties: {\n category: rule.category,\n },\n };\n}\n\n/**\n * Convert findings to SARIF results with stable ordering.\n */\nfunction findingsToSarifResults(\n findings: Finding[],\n changeSet: ChangeSet\n): SarifResult[] {\n const results: SarifResult[] = [];\n\n // Sort findings by type then by findingId for deterministic ordering\n const sortedFindings = [...findings].sort((a, b) => {\n if (a.type !== b.type) {\n return a.type.localeCompare(b.type);\n }\n return (a.findingId || \"\").localeCompare(b.findingId || \"\");\n });\n\n for (const finding of sortedFindings) {\n const mapped = mapFindingToResult(finding, changeSet);\n if (mapped) {\n results.push(mapped);\n }\n }\n\n return results;\n}\n\n/**\n * Map a single finding to a SARIF result.\n * Returns null if the finding doesn't map to any SARIF rule.\n */\nfunction mapFindingToResult(\n finding: Finding,\n changeSet: ChangeSet\n): SarifResult | null {\n switch (finding.type) {\n case \"db-migration\":\n return mapDbMigrationFinding(finding as DbMigrationFinding);\n\n case \"dependency-change\":\n return mapDependencyChangeFinding(finding as DependencyChangeFinding);\n\n case \"env-var\":\n return mapEnvVarFinding(finding as EnvVarFinding, changeSet);\n\n case \"cloudflare-change\":\n return mapCloudflareChangeFinding(finding as CloudflareChangeFinding);\n\n case \"route-change\":\n return mapRouteChangeFinding(finding as RouteChangeFinding);\n\n case \"ci-workflow\":\n return mapCIWorkflowFinding(finding as CIWorkflowFinding);\n\n case \"security-file\":\n return mapSecurityFileFinding(finding as SecurityFileFinding);\n\n case \"graphql-change\":\n return mapGraphQLChangeFinding(finding as GraphQLChangeFinding);\n\n case \"package-exports\":\n return mapPackageExportsFinding(finding as PackageExportsFinding);\n\n case \"stencil-component-change\":\n return mapStencilComponentChangeFinding(\n finding as StencilComponentChangeFinding\n );\n\n case \"stencil-prop-change\":\n return mapStencilPropChangeFinding(finding as StencilPropChangeFinding);\n\n case \"stencil-event-change\":\n return mapStencilEventChangeFinding(finding as StencilEventChangeFinding);\n\n case \"stencil-method-change\":\n return mapStencilMethodChangeFinding(\n finding as StencilMethodChangeFinding\n );\n\n case \"stencil-slot-change\":\n return mapStencilSlotChangeFinding(finding as StencilSlotChangeFinding);\n\n case \"typescript-config\":\n return mapTypeScriptConfigFinding(finding as TypeScriptConfigFinding);\n\n case \"sql-risk\":\n return mapSQLRiskFinding(finding as SQLRiskFinding);\n\n case \"infra-change\":\n return mapInfraChangeFinding(finding as InfraChangeFinding);\n\n case \"test-gap\":\n return mapTestGapFinding(finding as TestGapFinding);\n\n case \"large-diff\":\n return mapLargeDiffFinding(finding as LargeDiffFinding);\n\n default:\n // Other finding types are not mapped to SARIF rules\n return null;\n }\n}\n\n/**\n * Map database migration finding to SARIF result.\n */\nfunction mapDbMigrationFinding(finding: DbMigrationFinding): SarifResult {\n const ruleId = finding.risk === \"high\" ? \"BNR001\" : \"BNR002\";\n const level = finding.risk === \"high\" ? \"error\" : \"warning\";\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n const reasons = finding.reasons.join(\", \");\n const message =\n finding.risk === \"high\"\n ? `Dangerous SQL migration detected: ${reasons}`\n : `Database migration changed: ${reasons}`;\n\n return {\n ruleId,\n level,\n message: { text: message },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n tool: finding.tool,\n files: finding.files,\n risk: finding.risk,\n },\n };\n}\n\n/**\n * Map dependency change finding to SARIF result.\n */\nfunction mapDependencyChangeFinding(\n finding: DependencyChangeFinding\n): SarifResult | null {\n // Only report major bumps in critical dependencies\n if (\n finding.impact !== \"major\" ||\n !CRITICAL_DEPENDENCIES.includes(finding.name)\n ) {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR003\",\n level: \"warning\",\n message: {\n text: `Major version bump: ${finding.name} ${finding.from || \"?\"} → ${finding.to || \"?\"}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n dependency: finding.name,\n from: finding.from,\n to: finding.to,\n section: finding.section,\n },\n };\n}\n\n/**\n * Map environment variable finding to SARIF result.\n */\nfunction mapEnvVarFinding(\n finding: EnvVarFinding,\n changeSet: ChangeSet\n): SarifResult {\n // Try to find line numbers for evidence\n const locations: SarifLocation[] = [];\n\n for (const ev of finding.evidence) {\n // Use ev.line if already set, otherwise try to compute from diff\n let lineNumber = ev.line;\n \n if (lineNumber == null && ev.excerpt) {\n const diff = changeSet.diffs.find((d) => d.path === ev.file);\n if (diff) {\n // Try to find the line number by searching for the excerpt in additions\n const additionsWithLines = getAdditionsWithLineNumbers(diff);\n const match = additionsWithLines.find((add) =>\n add.line.includes(ev.excerpt)\n );\n if (match) {\n lineNumber = match.lineNumber;\n }\n }\n }\n\n locations.push({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: lineNumber != null\n ? {\n startLine: lineNumber,\n }\n : undefined,\n },\n });\n }\n\n return {\n ruleId: \"BNR004\",\n level: \"warning\",\n message: {\n text: `New environment variable referenced: ${finding.name}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n envVar: finding.name,\n change: finding.change,\n evidenceFiles: finding.evidenceFiles,\n },\n };\n}\n\n/**\n * Map Cloudflare change finding to SARIF result.\n */\nfunction mapCloudflareChangeFinding(\n finding: CloudflareChangeFinding\n): SarifResult {\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR005\",\n level: \"note\",\n message: {\n text: `Cloudflare configuration changed in ${finding.files.join(\", \")}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n area: finding.area,\n files: finding.files,\n },\n };\n}\n\n/**\n * Map route change finding to SARIF result.\n */\nfunction mapRouteChangeFinding(finding: RouteChangeFinding): SarifResult {\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n const methods = finding.methods ? ` (${finding.methods.join(\", \")})` : \"\";\n const changeText =\n finding.change === \"added\"\n ? \"added\"\n : finding.change === \"deleted\"\n ? \"deleted\"\n : \"modified\";\n\n return {\n ruleId: \"BNR006\",\n level: \"note\",\n message: {\n text: `API endpoint ${changeText}: ${finding.routeId}${methods}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n routeId: finding.routeId,\n file: finding.file,\n change: finding.change,\n routeType: finding.routeType,\n methods: finding.methods,\n },\n };\n}\n\n/**\n * Map CI workflow finding to SARIF result.\n * Only maps high-risk workflow changes (permissions_broadened, pull_request_target).\n */\nfunction mapCIWorkflowFinding(finding: CIWorkflowFinding): SarifResult | null {\n // Only map security-critical risk types\n if (\n finding.riskType !== \"permissions_broadened\" &&\n finding.riskType !== \"pull_request_target\"\n ) {\n return null;\n }\n\n const ruleId =\n finding.riskType === \"permissions_broadened\" ? \"BNR007\" : \"BNR008\";\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n const message =\n finding.riskType === \"permissions_broadened\"\n ? `CI workflow permissions broadened in ${finding.file}: ${finding.details}`\n : `CI workflow uses pull_request_target in ${finding.file}: ${finding.details}`;\n\n return {\n ruleId,\n level: \"error\",\n message: { text: message },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n file: finding.file,\n riskType: finding.riskType,\n details: finding.details,\n },\n };\n}\n\n/**\n * Map security file finding to SARIF result.\n */\nfunction mapSecurityFileFinding(finding: SecurityFileFinding): SarifResult {\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR009\",\n level: \"warning\",\n message: {\n text: `Security-sensitive files changed: ${finding.files.join(\", \")}. Reasons: ${finding.reasons.join(\", \")}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n files: finding.files,\n reasons: finding.reasons,\n },\n };\n}\n\n/**\n * Map GraphQL change finding to SARIF result.\n * Only maps breaking changes.\n */\nfunction mapGraphQLChangeFinding(\n finding: GraphQLChangeFinding\n): SarifResult | null {\n if (!finding.isBreaking) {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR010\",\n level: \"error\",\n message: {\n text: `Breaking GraphQL schema changes in ${finding.file}: ${finding.breakingChanges.join(\", \")}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n file: finding.file,\n breakingChanges: finding.breakingChanges,\n addedElements: finding.addedElements,\n },\n };\n}\n\n/**\n * Map package exports finding to SARIF result.\n * Only maps breaking changes.\n */\nfunction mapPackageExportsFinding(\n finding: PackageExportsFinding\n): SarifResult | null {\n if (!finding.isBreaking) {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n const changes: string[] = [];\n if (finding.removedExports.length > 0) {\n changes.push(`removed exports: ${finding.removedExports.join(\", \")}`);\n }\n if (finding.binChanges.removed.length > 0) {\n changes.push(`removed bins: ${finding.binChanges.removed.join(\", \")}`);\n }\n\n return {\n ruleId: \"BNR011\",\n level: \"error\",\n message: {\n text: `Breaking package exports changes: ${changes.join(\"; \")}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n removedExports: finding.removedExports,\n addedExports: finding.addedExports,\n binChanges: finding.binChanges,\n },\n };\n}\n\n/**\n * Map Stencil component change finding to SARIF result.\n * Only maps breaking changes (removed components).\n */\nfunction mapStencilComponentChangeFinding(\n finding: StencilComponentChangeFinding\n): SarifResult | null {\n // Only \"removed\" is considered breaking for components\n if (finding.change !== \"removed\") {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR012\",\n level: \"warning\",\n message: {\n text: `Stencil component removed: <${finding.tag}>`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n tag: finding.tag,\n change: finding.change,\n file: finding.file,\n },\n };\n}\n\n/**\n * Map Stencil prop change finding to SARIF result.\n * Only maps breaking changes (removed props).\n */\nfunction mapStencilPropChangeFinding(\n finding: StencilPropChangeFinding\n): SarifResult | null {\n // Only \"removed\" is considered breaking for props\n if (finding.change !== \"removed\") {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR012\",\n level: \"warning\",\n message: {\n text: `Stencil prop removed: <${finding.tag}> @Prop() ${finding.propName}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n tag: finding.tag,\n propName: finding.propName,\n change: finding.change,\n file: finding.file,\n },\n };\n}\n\n/**\n * Map Stencil event change finding to SARIF result.\n * Only maps breaking changes (removed events).\n */\nfunction mapStencilEventChangeFinding(\n finding: StencilEventChangeFinding\n): SarifResult | null {\n // Only \"removed\" is considered breaking for events\n if (finding.change !== \"removed\") {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR012\",\n level: \"warning\",\n message: {\n text: `Stencil event removed: <${finding.tag}> @Event() ${finding.eventName}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n tag: finding.tag,\n eventName: finding.eventName,\n change: finding.change,\n file: finding.file,\n },\n };\n}\n\n/**\n * Map Stencil method change finding to SARIF result.\n * Only maps breaking changes (removed methods).\n */\nfunction mapStencilMethodChangeFinding(\n finding: StencilMethodChangeFinding\n): SarifResult | null {\n // Only \"removed\" is considered breaking for methods\n if (finding.change !== \"removed\") {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR012\",\n level: \"warning\",\n message: {\n text: `Stencil method removed: <${finding.tag}> @Method() ${finding.methodName}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n tag: finding.tag,\n methodName: finding.methodName,\n change: finding.change,\n file: finding.file,\n },\n };\n}\n\n/**\n * Map Stencil slot change finding to SARIF result.\n * Only maps breaking changes (removed slots).\n */\nfunction mapStencilSlotChangeFinding(\n finding: StencilSlotChangeFinding\n): SarifResult | null {\n // Only \"removed\" is considered breaking for slots\n if (finding.change !== \"removed\") {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n const slotDisplay =\n finding.slotName === \"default\" ? \"default slot\" : `slot \"${finding.slotName}\"`;\n\n return {\n ruleId: \"BNR012\",\n level: \"warning\",\n message: {\n text: `Stencil ${slotDisplay} removed from <${finding.tag}>`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n tag: finding.tag,\n slotName: finding.slotName,\n change: finding.change,\n file: finding.file,\n },\n };\n}\n\n/**\n * Map TypeScript config finding to SARIF result.\n * Only maps breaking changes.\n */\nfunction mapTypeScriptConfigFinding(\n finding: TypeScriptConfigFinding\n): SarifResult | null {\n if (!finding.isBreaking) {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n const changes: string[] = [];\n if (finding.strictnessChanges.length > 0) {\n changes.push(finding.strictnessChanges.join(\", \"));\n }\n if (finding.changedOptions.removed.length > 0) {\n changes.push(`removed: ${finding.changedOptions.removed.join(\", \")}`);\n }\n\n return {\n ruleId: \"BNR013\",\n level: \"warning\",\n message: {\n text: `Breaking TypeScript config changes in ${finding.file}: ${changes.join(\"; \")}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n file: finding.file,\n changedOptions: finding.changedOptions,\n strictnessChanges: finding.strictnessChanges,\n },\n };\n}\n\n/**\n * Map SQL risk finding to SARIF result.\n * Only maps destructive operations.\n */\nfunction mapSQLRiskFinding(finding: SQLRiskFinding): SarifResult | null {\n // Only map destructive SQL operations\n if (finding.riskType !== \"destructive\") {\n return null;\n }\n\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR014\",\n level: \"error\",\n message: {\n text: `Destructive SQL operation in ${finding.file}: ${finding.details}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n file: finding.file,\n riskType: finding.riskType,\n details: finding.details,\n },\n };\n}\n\n/**\n * Map infrastructure change finding to SARIF result.\n */\nfunction mapInfraChangeFinding(finding: InfraChangeFinding): SarifResult {\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n const infraTypeDisplay = {\n dockerfile: \"Dockerfile\",\n terraform: \"Terraform\",\n k8s: \"Kubernetes\",\n }[finding.infraType];\n\n return {\n ruleId: \"BNR015\",\n level: \"warning\",\n message: {\n text: `${infraTypeDisplay} configuration changed: ${finding.files.join(\", \")}`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n infraType: finding.infraType,\n files: finding.files,\n },\n };\n}\n\n/**\n * Map test gap finding to SARIF result.\n */\nfunction mapTestGapFinding(finding: TestGapFinding): SarifResult {\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR016\",\n level: \"note\",\n message: {\n text: `Test coverage gap: ${finding.prodFilesChanged} production files changed, ${finding.testFilesChanged} test files changed`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n prodFilesChanged: finding.prodFilesChanged,\n testFilesChanged: finding.testFilesChanged,\n },\n };\n}\n\n/**\n * Map large diff finding to SARIF result.\n */\nfunction mapLargeDiffFinding(finding: LargeDiffFinding): SarifResult {\n const locations = finding.evidence.map((ev) => ({\n physicalLocation: {\n artifactLocation: {\n uri: ev.file,\n uriBaseId: \"SRCROOT\",\n },\n region: ev.line\n ? {\n startLine: ev.line,\n }\n : undefined,\n },\n }));\n\n return {\n ruleId: \"BNR017\",\n level: \"note\",\n message: {\n text: `Large diff detected: ${finding.filesChanged} files changed, ${finding.linesChanged} lines modified`,\n },\n locations,\n partialFingerprints: {\n findingId: finding.findingId || \"\",\n },\n properties: {\n filesChanged: finding.filesChanged,\n linesChanged: finding.linesChanged,\n },\n };\n}\n",
63
- "/**\n * File exclusion patterns for risk-report.\n */\n\n/**\n * Default file patterns to exclude from evidence extraction.\n */\nexport const DEFAULT_EXCLUSIONS = [\n // Lockfiles\n \"pnpm-lock.yaml\",\n \"package-lock.json\",\n \"yarn.lock\",\n \"bun.lockb\",\n \n // Generated files\n \"**/*.d.ts\",\n \n // Logs\n \"**/*.log\",\n \n // Build artifacts\n \"dist/**\",\n \"build/**\",\n \"coverage/**\",\n \".turbo/**\",\n \".next/**\",\n \"out/**\",\n \".cache/**\",\n];\n\n/**\n * Check if a file should be skipped based on exclusion patterns.\n */\nexport function shouldSkipFile(path: string): { skip: boolean; reason?: string } {\n // Check lockfiles\n if (path === \"pnpm-lock.yaml\" || path === \"package-lock.json\" || \n path === \"yarn.lock\" || path === \"bun.lockb\") {\n return { skip: true, reason: \"lockfile\" };\n }\n\n // Check generated files\n if (path.endsWith(\".d.ts\")) {\n return { skip: true, reason: \"generated file\" };\n }\n\n // Check logs\n if (path.endsWith(\".log\")) {\n return { skip: true, reason: \"log file\" };\n }\n\n // Check build artifacts\n const buildPatterns = [\"dist/\", \"build/\", \"coverage/\", \".turbo/\", \".next/\", \"out/\", \".cache/\"];\n for (const pattern of buildPatterns) {\n if (path.includes(pattern)) {\n return { skip: true, reason: \"build artifact\" };\n }\n }\n\n return { skip: false };\n}\n",
64
- "/**\n * Evidence redaction utilities for sensitive data.\n */\n\n/**\n * Patterns for detecting secrets.\n */\nconst SECRET_KEY_PATTERNS = [\n /token/i,\n /secret/i,\n /password/i,\n /api[_-]?key/i,\n /private[_-]?key/i,\n /access[_-]?key/i,\n /auth[_-]?token/i,\n];\n\n// Pre-compiled regex patterns for secret keys\nconst COMPILED_SECRET_PATTERNS = SECRET_KEY_PATTERNS.map((pattern) => ({\n eqPattern: new RegExp(\n `(${pattern.source})\\\\s*=\\\\s*['\"]?([^'\"\\\\s}<]+)['\"]?`,\n \"gi\"\n ),\n colonPattern: new RegExp(\n `(${pattern.source})\\\\s*:\\\\s*['\"]?([^'\"\\\\s,}<]+)['\"]?`,\n \"gi\"\n ),\n}));\n\n/**\n * GitHub token patterns.\n */\nconst GITHUB_TOKEN_PATTERN = /(ghp_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9_]+)/g;\n\n/**\n * Long base64/hex-like strings (likely secrets).\n * Avoid matching short sequences that are part of identifiers.\n */\nconst LONG_SECRET_PATTERN = /\\b[a-zA-Z0-9+/=]{32,}\\b/g;\n\n/**\n * Redact secret values in a line of code.\n */\nexport function redactLine(line: string): string {\n let redacted = line;\n\n // Redact GitHub tokens FIRST (before other patterns)\n redacted = redacted.replace(GITHUB_TOKEN_PATTERN, \"<redacted-github-token>\");\n\n // Redact values after = or : for secret keys\n for (const { eqPattern, colonPattern } of COMPILED_SECRET_PATTERNS) {\n // Reset lastIndex for global patterns to ensure consistent matching\n eqPattern.lastIndex = 0;\n colonPattern.lastIndex = 0;\n\n redacted = redacted.replace(\n eqPattern,\n (_match, key) => `${key}=<redacted>`\n );\n redacted = redacted.replace(\n colonPattern,\n (_match, key) => `${key}: <redacted>`\n );\n }\n\n // Redact long base64/hex strings (but not if they look like hashes in code)\n // Only do this if not already redacted\n if (\n !redacted.includes(\"<redacted\") &&\n !redacted.includes(\"hash\") &&\n !redacted.includes(\"checksum\")\n ) {\n redacted = redacted.replace(LONG_SECRET_PATTERN, \"<redacted-value>\");\n }\n\n return redacted;\n}\n\n/**\n * Redact an array of evidence lines.\n */\nexport function redactLines(lines: string[]): string[] {\n return lines.map(redactLine);\n}\n",
65
- "/**\n * Risk scoring engine for risk-report command.\n */\n\nimport type {\n DiffMode,\n RiskCategory,\n RiskFlag,\n RiskReport,\n RiskReportLevel,\n ScoreBreakdown,\n} from \"../../core/types.js\";\nimport { sortRiskFlags } from \"../../core/sorting.js\";\n\n/**\n * Compute category scores from flags.\n */\nfunction computeCategoryScores(flags: RiskFlag[]): Record<RiskCategory, number> {\n // Create categories in alphabetical order for determinism\n const scores: Record<RiskCategory, number> = {\n api: 0,\n churn: 0,\n ci: 0,\n db: 0,\n deps: 0,\n infra: 0,\n security: 0,\n tests: 0,\n };\n\n for (const flag of flags) {\n scores[flag.category] += flag.effectiveScore;\n }\n\n // Cap each category at 100\n for (const category of Object.keys(scores) as RiskCategory[]) {\n scores[category] = Math.min(100, scores[category]);\n }\n\n return scores;\n}\n\n/**\n * Compute overall risk score from category scores.\n */\nfunction computeOverallScore(categoryScores: Record<RiskCategory, number>): number {\n const scores = Object.values(categoryScores);\n\n if (scores.length === 0) return 0;\n\n // Get max category score\n const maxCat = Math.max(...scores);\n\n // Get top 3 scores\n const sortedScores = [...scores].sort((a, b) => b - a);\n const top3 = sortedScores.slice(0, 3);\n\n // Pad with zeros if less than 3\n while (top3.length < 3) {\n top3.push(0);\n }\n\n const top3Avg = top3.reduce((sum, score) => sum + score, 0) / 3;\n\n // Formula: 0.6 * maxCat + 0.4 * top3Avg\n const overall = 0.6 * maxCat + 0.4 * top3Avg;\n\n return Math.round(Math.max(0, Math.min(100, overall)));\n}\n\n/**\n * Determine risk level from score.\n */\nfunction computeRiskLevel(score: number): RiskReportLevel {\n if (score >= 81) return \"critical\";\n if (score >= 61) return \"high\";\n if (score >= 41) return \"elevated\";\n if (score >= 21) return \"moderate\";\n return \"low\";\n}\n\n/**\n * Build score breakdown for --explain-score.\n */\nfunction buildScoreBreakdown(\n categoryScores: Record<RiskCategory, number>\n): ScoreBreakdown {\n const entries = Object.entries(categoryScores) as Array<[RiskCategory, number]>;\n const sorted = entries.sort((a, b) => b[1] - a[1]);\n\n const maxCategory = sorted.length > 0 ? sorted[0] : ([\"security\", 0] as [RiskCategory, number]);\n const topCategories = sorted.slice(0, 3).map(([category, score]) => ({ category, score }));\n\n const maxCat = maxCategory[1];\n const top3 = topCategories.map(t => t.score);\n while (top3.length < 3) top3.push(0);\n const top3Avg = top3.reduce((sum, s) => sum + s, 0) / 3;\n\n const formula = `riskScore = round(0.6 * ${maxCat} + 0.4 * ${top3Avg.toFixed(2)})`;\n\n return {\n maxCategory: { category: maxCategory[0], score: maxCat },\n topCategories,\n formula,\n };\n}\n\n/**\n * Filter flags by category.\n */\nexport function filterFlagsByCategory(\n flags: RiskFlag[],\n only?: string[],\n exclude?: string[]\n): RiskFlag[] {\n let filtered = flags;\n\n if (only && only.length > 0) {\n filtered = filtered.filter(f => only.includes(f.category));\n }\n\n if (exclude && exclude.length > 0) {\n filtered = filtered.filter(f => !exclude.includes(f.category));\n }\n\n return filtered;\n}\n\n/**\n * Compute risk report from flags.\n */\nexport function computeRiskReport(\n base: string,\n head: string,\n flags: RiskFlag[],\n skippedFiles: Array<{ file: string; reason: string }>,\n options?: {\n explainScore?: boolean;\n noTimestamp?: boolean;\n mode?: DiffMode;\n only?: string[];\n exclude?: string[];\n }\n): RiskReport {\n const categoryScores = computeCategoryScores(flags);\n const riskScore = computeOverallScore(categoryScores);\n const riskLevel = computeRiskLevel(riskScore);\n\n const report: RiskReport = {\n schemaVersion: \"2.0\",\n range: { base, head, mode: options?.mode },\n riskScore,\n riskLevel,\n categoryScores,\n flags: sortRiskFlags(flags),\n skippedFiles,\n };\n\n // Add timestamp unless --no-timestamp is specified\n if (!options?.noTimestamp) {\n report.generatedAt = new Date().toISOString();\n }\n\n if (options?.explainScore) {\n report.scoreBreakdown = buildScoreBreakdown(categoryScores);\n }\n\n // Store filters if provided\n if (options?.only || options?.exclude) {\n report.filters = {\n only: options.only,\n exclude: options.exclude,\n };\n }\n\n return report;\n}\n",
66
- "/**\n * Finding-to-flag conversion rules.\n * \n * This module contains rules that convert findings into risk flags.\n * Each rule examines findings and produces risk flags with:\n * - Stable flagId\n * - ruleKey\n * - relatedFindingIds (links back to findings)\n * - Score and confidence\n * - Evidence and suggested checks\n *\n * ## Canonical mapping (legacy detectors → analyzers/findings → rule keys)\n *\n * `risk-report` is derived from analyzer findings (single analysis pipeline).\n * The legacy detector system in `src/commands/risk/detectors/*` duplicated this\n * logic and used some inconsistent rule keys and thresholds.\n *\n * The rule keys in this module are the canonical identifiers:\n *\n * - Security / CI:\n * - `detectWorkflowPermissionsBroadened` → `CIWorkflowFinding(riskType=permissions_broadened)` → `security.workflow_permissions_broadened`\n * - `detectPullRequestTarget` → `CIWorkflowFinding(riskType=pull_request_target)` → `security.workflow_uses_pull_request_target`\n * - `detectRemoteScriptDownload` → `CIWorkflowFinding(riskType=remote_script_download)` → `security.workflow_downloads_remote_script`\n * - `detectCIPipelineChanged` → `CIWorkflowFinding(riskType=pipeline_changed)` → `ci.pipeline_changed`\n *\n * - Database:\n * - `detectDestructiveSQL` → `SQLRiskFinding(riskType=destructive)` → `db.destructive_sql`\n * - `detectRiskySchemaChange` → `SQLRiskFinding(riskType=schema_change)` → `db.schema_change_risky`\n * - `detectUnscopedDataModification` → `SQLRiskFinding(riskType=unscoped_modification)` → `db.unscoped_data_modification`\n * - `detectMigrationsChanged` → `DbMigrationFinding` → `db.migrations_changed`\n *\n * - Dependencies:\n * - `detectNewProdDependency` → `DependencyChangeFinding(impact=new, section=dependencies)` → `deps.new_prod_dependency`\n * - `detectMajorBump` (legacy id `deps.major_bump`) → `DependencyChangeFinding(impact=major)` → `deps.major_version_bump`\n * - `detectLockfileWithoutManifest` (legacy id `deps.lockfile_changed_without_manifest`) → `LockfileFinding` → `deps.lockfile_without_manifest`\n *\n * - Infrastructure:\n * - `detectDockerfileChanged` → `InfraChangeFinding(infraType=dockerfile)` → `infra.dockerfile_changed`\n * - `detectTerraformChanged` → `InfraChangeFinding(infraType=terraform)` → `infra.terraform_changed`\n * - `detectK8sManifestChanged` (legacy id `infra.k8s_manifest_changed`) → `InfraChangeFinding(infraType=k8s)` → `infra.k8s_changed`\n *\n * - API:\n * - `detectAPIContractChanged` → `APIContractChangeFinding` → `api.contract_changed`\n *\n * - Tests:\n * - `detectTestsChanged` → `TestChangeFinding` → `tests.changed`\n * - `detectPossibleTestGap` → `TestGapFinding` → `tests.possible_gap`\n *\n * - Churn:\n * - `detectLargeDiff` → `LargeDiffFinding` → `churn.large_diff`\n */\n\nimport type {\n Finding,\n RiskFlag,\n RiskFlagEvidence,\n CIWorkflowFinding,\n SQLRiskFinding,\n InfraChangeFinding,\n APIContractChangeFinding,\n LargeDiffFinding,\n LockfileFinding,\n TestGapFinding,\n DependencyChangeFinding,\n DbMigrationFinding,\n TestChangeFinding,\n TestParityViolationFinding,\n StencilComponentChangeFinding,\n StencilPropChangeFinding,\n StencilEventChangeFinding,\n StencilMethodChangeFinding,\n StencilSlotChangeFinding,\n} from \"../../core/types.js\";\nimport { buildFlagId } from \"../../core/ids.js\";\n\n/**\n * Convert evidence from findings to risk flag evidence format.\n */\nfunction convertEvidence(finding: Finding): RiskFlagEvidence[] {\n return finding.evidence.map(ev => ({\n file: ev.file,\n hunk: ev.hunk ? `@@ -${ev.hunk.oldStart},${ev.hunk.oldLines} +${ev.hunk.newStart},${ev.hunk.newLines} @@` : undefined,\n lines: ev.excerpt.split(\"\\n\").slice(0, 5),\n }));\n}\n\n/**\n * Convert CI workflow findings to flags.\n */\nfunction ciWorkflowToFlags(findings: Array<CIWorkflowFinding & { findingId: string }>): RiskFlag[] {\n const flags: RiskFlag[] = [];\n \n for (const finding of findings) {\n const relatedFindingIds = [finding.findingId];\n \n switch (finding.riskType) {\n case \"permissions_broadened\": {\n const ruleKey = \"security.workflow_permissions_broadened\";\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"security\",\n score: 35,\n confidence: 0.9,\n title: \"Workflow permissions broadened\",\n summary: `Workflow ${finding.file} has broadened permissions (write access)`,\n evidence: convertEvidence(finding),\n suggestedChecks: [\n \"Review if write permissions are necessary\",\n \"Ensure principle of least privilege\",\n \"Check if GITHUB_TOKEN usage is secure\",\n ],\n effectiveScore: Math.round(35 * 0.9),\n });\n break;\n }\n \n case \"pull_request_target\": {\n const ruleKey = \"security.workflow_uses_pull_request_target\";\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"security\",\n score: 40,\n confidence: 0.9,\n title: \"Workflow uses pull_request_target\",\n summary: `Workflow ${finding.file} uses pull_request_target event (can expose secrets)`,\n evidence: convertEvidence(finding),\n suggestedChecks: [\n \"Ensure no untrusted code is executed in this context\",\n \"Review if pull_request_target is necessary (vs pull_request)\",\n \"Verify secrets are not exposed to PR authors\",\n ],\n effectiveScore: Math.round(40 * 0.9),\n });\n break;\n }\n \n case \"remote_script_download\": {\n const ruleKey = \"security.workflow_downloads_remote_script\";\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"security\",\n score: 45,\n confidence: 0.85,\n title: \"Workflow downloads and executes remote scripts\",\n summary: `Workflow ${finding.file} downloads and pipes to shell (supply chain risk)`,\n evidence: convertEvidence(finding),\n suggestedChecks: [\n \"Pin script sources to specific commit SHAs\",\n \"Verify script integrity with checksums\",\n \"Consider vendoring the script instead\",\n ],\n effectiveScore: Math.round(45 * 0.85),\n });\n break;\n }\n \n case \"pipeline_changed\": {\n const ruleKey = \"ci.pipeline_changed\";\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"ci\",\n score: 10,\n confidence: 0.7,\n title: \"CI/CD pipeline configuration changed\",\n summary: `Pipeline ${finding.file} was modified`,\n evidence: convertEvidence(finding),\n suggestedChecks: [\n \"Review pipeline changes for security implications\",\n \"Test pipeline changes in a non-production environment\",\n ],\n effectiveScore: Math.round(10 * 0.7),\n });\n break;\n }\n }\n }\n \n return flags;\n}\n\n/**\n * Convert SQL risk findings to flags.\n */\nfunction sqlRiskToFlags(findings: Array<SQLRiskFinding & { findingId: string }>): RiskFlag[] {\n const flags: RiskFlag[] = [];\n \n for (const finding of findings) {\n const relatedFindingIds = [finding.findingId];\n \n switch (finding.riskType) {\n case \"destructive\": {\n const ruleKey = \"db.destructive_sql\";\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"db\",\n score: 45,\n confidence: 0.9,\n title: \"Destructive SQL detected\",\n summary: `Migration ${finding.file} contains DROP TABLE/COLUMN or TRUNCATE`,\n evidence: convertEvidence(finding),\n suggestedChecks: [\n \"Backup data before running migration\",\n \"Verify this is intentional data deletion\",\n \"Test migration rollback procedure\",\n \"Consider making column nullable instead of dropping\",\n ],\n effectiveScore: Math.round(45 * 0.9),\n });\n break;\n }\n \n case \"schema_change\": {\n const ruleKey = \"db.schema_change_risky\";\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"db\",\n score: 30,\n confidence: 0.85,\n title: \"Risky schema change detected\",\n summary: `Migration ${finding.file} contains ALTER COLUMN or TYPE change`,\n evidence: convertEvidence(finding),\n suggestedChecks: [\n \"Test schema changes on production-like data\",\n \"Check for data type compatibility\",\n \"Monitor migration execution time (may lock table)\",\n ],\n effectiveScore: Math.round(30 * 0.85),\n });\n break;\n }\n \n case \"unscoped_modification\": {\n const ruleKey = \"db.unscoped_data_modification\";\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"db\",\n score: 35,\n confidence: 0.75,\n title: \"Unscoped data modification detected\",\n summary: `Migration ${finding.file} contains UPDATE/DELETE without WHERE clause`,\n evidence: convertEvidence(finding),\n suggestedChecks: [\n \"Verify this affects all rows intentionally\",\n \"Add WHERE clause if only subset should be modified\",\n \"Test on staging data first\",\n ],\n effectiveScore: Math.round(35 * 0.75),\n });\n break;\n }\n }\n }\n \n return flags;\n}\n\n/**\n * Convert Stencil findings to flags.\n */\nfunction stencilToFlags(findings: Array<Finding & { findingId: string }>): RiskFlag[] {\n const flags: RiskFlag[] = [];\n\n const componentFindings = findings.filter(f => f.type === \"stencil-component-change\") as Array<StencilComponentChangeFinding & { findingId: string }>;\n const propFindings = findings.filter(f => f.type === \"stencil-prop-change\") as Array<StencilPropChangeFinding & { findingId: string }>;\n const eventFindings = findings.filter(f => f.type === \"stencil-event-change\") as Array<StencilEventChangeFinding & { findingId: string }>;\n const methodFindings = findings.filter(f => f.type === \"stencil-method-change\") as Array<StencilMethodChangeFinding & { findingId: string }>;\n const slotFindings = findings.filter(f => f.type === \"stencil-slot-change\") as Array<StencilSlotChangeFinding & { findingId: string }>;\n\n // High severity: Tag changed\n for (const f of componentFindings) {\n if (f.change === \"tag-changed\") {\n const ruleKey = \"stencil.tag_changed\";\n const relatedFindingIds = [f.findingId];\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 45,\n confidence: 0.95,\n title: \"Component tag changed\",\n summary: `Tag changed from \"${f.fromTag}\" to \"${f.toTag}\"`,\n evidence: convertEvidence(f),\n suggestedChecks: [\n \"Update all usages of this component\",\n \"This is a breaking change\",\n ],\n effectiveScore: Math.round(45 * 0.95),\n });\n }\n\n if (f.change === \"shadow-changed\") {\n const ruleKey = \"stencil.shadow_changed\";\n const relatedFindingIds = [f.findingId];\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 25,\n confidence: 0.9,\n title: \"Shadow DOM configuration changed\",\n summary: `Shadow DOM enabled changed from ${f.fromShadow} to ${f.toShadow}`,\n evidence: convertEvidence(f),\n suggestedChecks: [\n \"Check styles and global styling impact\",\n ],\n effectiveScore: Math.round(25 * 0.9),\n });\n }\n }\n\n // High severity: Prop removed or changed\n for (const f of propFindings) {\n if (f.change === \"removed\") {\n const ruleKey = \"stencil.prop_removed\";\n const relatedFindingIds = [f.findingId];\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 40,\n confidence: 0.95,\n title: \"Component prop removed\",\n summary: `Prop \"${f.propName}\" removed from <${f.tag}>`,\n evidence: convertEvidence(f),\n suggestedChecks: [\n \"This is a breaking change\",\n \"Check usages\",\n ],\n effectiveScore: Math.round(40 * 0.95),\n });\n } else if (f.change === \"changed\") {\n const ruleKey = \"stencil.prop_changed\";\n const relatedFindingIds = [f.findingId];\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 35,\n confidence: 0.9,\n title: \"Component prop modified\",\n summary: `Prop \"${f.propName}\" options changed`,\n evidence: convertEvidence(f),\n suggestedChecks: [\n \"Check for attribute/reflect/mutable changes\",\n ],\n effectiveScore: Math.round(35 * 0.9),\n });\n }\n }\n\n // High severity: Event removed or changed\n for (const f of eventFindings) {\n if (f.change === \"removed\") {\n const ruleKey = \"stencil.event_removed\";\n const relatedFindingIds = [f.findingId];\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 40,\n confidence: 0.95,\n title: \"Component event removed\",\n summary: `Event \"${f.eventName}\" removed from <${f.tag}>`,\n evidence: convertEvidence(f),\n suggestedChecks: [\n \"This is a breaking change\",\n \"Check event listeners\",\n ],\n effectiveScore: Math.round(40 * 0.95),\n });\n } else if (f.change === \"changed\") {\n const ruleKey = \"stencil.event_changed\";\n const relatedFindingIds = [f.findingId];\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 35,\n confidence: 0.9,\n title: \"Component event modified\",\n summary: `Event \"${f.eventName}\" options changed`,\n evidence: convertEvidence(f),\n suggestedChecks: [\n \"Check bubbles/composed/cancelable options\",\n ],\n effectiveScore: Math.round(35 * 0.9),\n });\n }\n }\n\n // High severity: Method removed or changed\n for (const f of methodFindings) {\n if (f.change === \"removed\") {\n const ruleKey = \"stencil.method_removed\";\n const relatedFindingIds = [f.findingId];\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 40,\n confidence: 0.95,\n title: \"Component method removed\",\n summary: `Method \"${f.methodName}\" removed from <${f.tag}>`,\n evidence: convertEvidence(f),\n suggestedChecks: [\n \"This is a breaking change\",\n \"Check usages\",\n ],\n effectiveScore: Math.round(40 * 0.95),\n });\n }\n // Changed not fully implemented yet in analyzer, but if it were:\n else if (f.change === \"changed\") {\n // ...\n }\n }\n\n // High severity: Slot removed\n for (const f of slotFindings) {\n if (f.change === \"removed\") {\n const ruleKey = \"stencil.slot_removed\";\n const relatedFindingIds = [f.findingId];\n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 35,\n confidence: 0.9,\n title: \"Component slot removed\",\n summary: `Slot \"${f.slotName}\" removed from <${f.tag}>`,\n evidence: convertEvidence(f),\n suggestedChecks: [\n \"Check content projection usages\",\n ],\n effectiveScore: Math.round(35 * 0.9),\n });\n }\n }\n\n return flags;\n}\n\n/**\n * Convert findings to risk flags using rules.\n */\nexport function findingsToFlags(findings: Array<Finding & { findingId: string }>): RiskFlag[] {\n const flags: RiskFlag[] = [];\n \n // Group findings by type\n const ciWorkflowFindings = findings.filter(f => f.type === \"ci-workflow\") as Array<CIWorkflowFinding & { findingId: string }>;\n const sqlRiskFindings = findings.filter(f => f.type === \"sql-risk\") as Array<SQLRiskFinding & { findingId: string }>;\n const infraFindings = findings.filter(f => f.type === \"infra-change\") as Array<InfraChangeFinding & { findingId: string }>;\n const apiContractFindings = findings.filter(f => f.type === \"api-contract-change\") as Array<APIContractChangeFinding & { findingId: string }>;\n const largeDiffFindings = findings.filter(f => f.type === \"large-diff\") as Array<LargeDiffFinding & { findingId: string }>;\n const lockfileFindings = findings.filter(f => f.type === \"lockfile-mismatch\") as Array<LockfileFinding & { findingId: string }>;\n const testGapFindings = findings.filter(f => f.type === \"test-gap\") as Array<TestGapFinding & { findingId: string }>;\n const depChanges = findings.filter(f => f.type === \"dependency-change\") as Array<DependencyChangeFinding & { findingId: string }>;\n const dbMigrations = findings.filter(f => f.type === \"db-migration\") as Array<DbMigrationFinding & { findingId: string }>;\n const testChanges = findings.filter(f => f.type === \"test-change\") as Array<TestChangeFinding & { findingId: string }>;\n \n // Apply conversion rules\n flags.push(...ciWorkflowToFlags(ciWorkflowFindings));\n flags.push(...sqlRiskToFlags(sqlRiskFindings));\n flags.push(...stencilToFlags(findings));\n \n // Infrastructure changes\n for (const finding of infraFindings) {\n const relatedFindingIds = [finding.findingId];\n const ruleKey = `infra.${finding.infraType}_changed`;\n const titles: Record<typeof finding.infraType, string> = {\n dockerfile: \"Dockerfile changed\",\n terraform: \"Terraform configuration changed\",\n k8s: \"Kubernetes manifest changed\",\n };\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"infra\",\n score: 20,\n confidence: 0.8,\n title: titles[finding.infraType],\n summary: `${finding.files.length} ${finding.infraType} ${finding.files.length === 1 ? \"file\" : \"files\"} changed`,\n evidence: finding.files.slice(0, 3).map(file => ({ file, lines: [`File changed`] })),\n suggestedChecks: [\n \"Review infrastructure changes carefully\",\n \"Test in staging environment\",\n \"Verify no unintended resource changes\",\n ],\n effectiveScore: Math.round(20 * 0.8),\n });\n }\n \n // API contract changes\n if (apiContractFindings.length > 0) {\n // Collect all findingIds from all API contract findings\n const relatedFindingIds = apiContractFindings.map(f => f.findingId);\n const ruleKey = \"api.contract_changed\";\n \n // Collect all changed files across all findings\n const allFiles = apiContractFindings.flatMap(f => f.files);\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"api\",\n score: 25,\n confidence: 0.85,\n title: \"API contract changed\",\n summary: `${allFiles.length} API ${allFiles.length === 1 ? \"file\" : \"files\"} changed`,\n evidence: allFiles.slice(0, 3).map(file => ({ file, lines: [`File changed`] })),\n suggestedChecks: [\n \"Verify backwards compatibility\",\n \"Update API documentation\",\n \"Notify API consumers of changes\",\n ],\n effectiveScore: Math.round(25 * 0.85),\n });\n }\n \n // Large diff\n if (largeDiffFindings.length > 0) {\n const finding = largeDiffFindings[0];\n const relatedFindingIds = [finding.findingId];\n const ruleKey = \"churn.large_diff\";\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"churn\",\n score: 15,\n confidence: 0.9,\n title: \"Large diff detected\",\n summary: `${finding.filesChanged} files changed, ${finding.linesChanged} lines modified`,\n evidence: [],\n suggestedChecks: [\n \"Consider breaking into smaller PRs\",\n \"Ensure adequate test coverage\",\n \"Review carefully for unintended changes\",\n ],\n effectiveScore: Math.round(15 * 0.9),\n });\n }\n \n // Lockfile mismatch\n for (const finding of lockfileFindings) {\n const relatedFindingIds = [finding.findingId];\n const ruleKey = \"deps.lockfile_without_manifest\";\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"deps\",\n score: 20,\n confidence: 0.9,\n title: \"Lockfile changed without manifest\",\n summary: finding.manifestChanged\n ? \"package.json changed without lockfile update\"\n : \"Lockfile changed without package.json update\",\n evidence: [],\n suggestedChecks: [\n \"Run package manager install to sync lockfile\",\n \"Verify dependencies are correctly resolved\",\n ],\n effectiveScore: Math.round(20 * 0.9),\n });\n }\n \n // Test gap\n for (const finding of testGapFindings) {\n const relatedFindingIds = [finding.findingId];\n const ruleKey = \"tests.possible_gap\";\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"tests\",\n score: 18,\n confidence: 0.7,\n title: \"Possible test coverage gap\",\n summary: `${finding.prodFilesChanged} production files changed with no test updates`,\n evidence: [],\n suggestedChecks: [\n \"Add tests for new functionality\",\n \"Update existing tests if behavior changed\",\n ],\n effectiveScore: Math.round(18 * 0.7),\n });\n }\n \n // New production dependencies\n const newProdDeps = depChanges.filter(d => d.section === \"dependencies\" && !d.from);\n if (newProdDeps.length > 0) {\n const relatedFindingIds = newProdDeps.map(f => f.findingId);\n const ruleKey = \"deps.new_prod_dependency\";\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"deps\",\n score: 15,\n confidence: 0.85,\n title: \"New production dependencies added\",\n summary: `${newProdDeps.length} new production ${newProdDeps.length === 1 ? \"dependency\" : \"dependencies\"} added`,\n evidence: newProdDeps.slice(0, 5).map(d => ({\n file: \"package.json\",\n lines: [`+ \"${d.name}\": \"${d.to}\"`],\n })),\n suggestedChecks: [\n \"Review new dependencies for security vulnerabilities\",\n \"Check license compatibility\",\n \"Verify dependencies are actively maintained\",\n ],\n tags: newProdDeps.map(d => d.name),\n effectiveScore: Math.round(15 * 0.85),\n });\n }\n \n // Major version bumps\n const majorBumps = depChanges.filter(d => d.impact === \"major\");\n if (majorBumps.length > 0) {\n const relatedFindingIds = majorBumps.map(f => f.findingId);\n const ruleKey = \"deps.major_version_bump\";\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"deps\",\n score: 25,\n confidence: 0.9,\n title: \"Major dependency version bump\",\n summary: `${majorBumps.length} ${majorBumps.length === 1 ? \"dependency\" : \"dependencies\"} with major version changes`,\n evidence: majorBumps.slice(0, 5).map(d => ({\n file: \"package.json\",\n lines: [`\"${d.name}\": \"${d.from}\" -> \"${d.to}\"`],\n })),\n suggestedChecks: [\n \"Review breaking changes in dependency changelogs\",\n \"Update code for API changes\",\n \"Run full test suite\",\n ],\n tags: majorBumps.map(d => d.name),\n effectiveScore: Math.round(25 * 0.9),\n });\n }\n \n // Database migrations\n if (dbMigrations.length > 0) {\n const relatedFindingIds = dbMigrations.map(f => f.findingId);\n const ruleKey = \"db.migrations_changed\";\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"db\",\n score: 12,\n confidence: 0.8,\n title: \"Database migrations changed\",\n summary: `${dbMigrations.length} migration/SQL ${dbMigrations.length === 1 ? \"file\" : \"files\"} changed`,\n evidence: dbMigrations.slice(0, 3).flatMap(m => m.files.map(file => ({\n file,\n lines: [\"Migration file changed\"],\n }))),\n suggestedChecks: [\n \"Test migrations on a staging database\",\n \"Ensure migrations are reversible\",\n \"Check for data loss or downtime impact\",\n ],\n effectiveScore: Math.round(12 * 0.8),\n });\n }\n \n // Test changes\n if (testChanges.length > 0) {\n const relatedFindingIds = testChanges.map(f => f.findingId);\n const ruleKey = \"tests.changed\";\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"tests\",\n score: 5,\n confidence: 0.8,\n title: \"Test files changed\",\n summary: `${testChanges.length} test ${testChanges.length === 1 ? \"file\" : \"files\"} modified`,\n evidence: testChanges.slice(0, 3).flatMap(t => t.files.map(file => ({\n file,\n lines: [\"Test file changed\"],\n }))),\n suggestedChecks: [\n \"Verify tests still pass\",\n \"Review test coverage changes\",\n ],\n effectiveScore: Math.round(5 * 0.8),\n });\n }\n \n // Test parity violations (opt-in analyzer)\n const testParityViolations = findings.filter(f => f.type === \"test-parity-violation\") as Array<TestParityViolationFinding & { findingId: string }>;\n if (testParityViolations.length > 0) {\n const relatedFindingIds = testParityViolations.map(f => f.findingId);\n const ruleKey = \"tests.missing_parity\";\n \n // Score based on confidence distribution\n const highConfidenceCount = testParityViolations.filter(v => v.confidence === \"high\").length;\n const mediumConfidenceCount = testParityViolations.filter(v => v.confidence === \"medium\").length;\n \n // Higher score if more high-confidence violations\n const baseScore = 12 + (highConfidenceCount * 2) + (mediumConfidenceCount * 1);\n const cappedScore = Math.min(baseScore, 25);\n \n // Confidence is higher if we have more high-confidence violations\n const avgConfidence = highConfidenceCount > mediumConfidenceCount ? 0.85 : 0.7;\n \n flags.push({\n ruleKey,\n flagId: buildFlagId(ruleKey, relatedFindingIds),\n relatedFindingIds,\n category: \"tests\",\n score: cappedScore,\n confidence: avgConfidence,\n title: \"Source files without test coverage\",\n summary: `${testParityViolations.length} source ${testParityViolations.length === 1 ? \"file\" : \"files\"} modified without corresponding tests`,\n evidence: testParityViolations.slice(0, 5).map(v => ({\n file: v.sourceFile,\n lines: [`No test file found (expected: ${v.expectedTestLocations[0] || \"unknown\"})`],\n })),\n suggestedChecks: [\n \"Add tests for new/changed code\",\n \"Verify existing tests cover the changes\",\n \"Consider if these files need unit tests\",\n ],\n effectiveScore: Math.round(cappedScore * avgConfidence),\n });\n }\n \n return flags;\n}\n",
67
- "/**\n * Risk report renderers (JSON, Markdown, Text).\n */\n\nimport type { RiskReport, RiskFlag } from \"../../core/types.js\";\n\n/**\n * Render risk report as JSON.\n */\nexport function renderRiskReportJSON(\n report: RiskReport,\n pretty: boolean = false\n): string {\n return pretty ? JSON.stringify(report, null, 2) : JSON.stringify(report);\n}\n\n/**\n * Render risk report as Markdown.\n */\nexport function renderRiskReportMarkdown(report: RiskReport): string {\n const lines: string[] = [];\n\n // Header\n lines.push(\"# Risk Report\");\n lines.push(\"\");\n lines.push(`**Range:** \\`${report.range.base}..${report.range.head}\\``);\n lines.push(\"\");\n\n // Overall score\n const emoji = getLevelEmoji(report.riskLevel);\n lines.push(`## Overall Risk: ${emoji} ${report.riskLevel.toUpperCase()}`);\n lines.push(\"\");\n lines.push(`**Score:** ${report.riskScore}/100`);\n lines.push(\"\");\n\n // Category scores\n lines.push(\"### Category Scores\");\n lines.push(\"\");\n const categories = Object.entries(report.categoryScores)\n .sort((a, b) => b[1] - a[1]);\n \n for (const [category, score] of categories) {\n if (score > 0) {\n const bar = \"█\".repeat(Math.floor(score / 10));\n lines.push(`- **${category}**: ${score}/100 ${bar}`);\n }\n }\n lines.push(\"\");\n\n // Flags\n if (report.flags.length > 0) {\n lines.push(\"## Risk Flags\");\n lines.push(\"\");\n\n const groupedFlags = groupFlagsByCategory(report.flags);\n for (const [category, flags] of Object.entries(groupedFlags)) {\n if (flags.length === 0) continue;\n\n lines.push(`### ${category.toUpperCase()}`);\n lines.push(\"\");\n\n for (const flag of flags) {\n lines.push(`#### ${flag.title}`);\n lines.push(\"\");\n lines.push(`**Rule:** \\`${flag.ruleKey}\\``);\n lines.push(`**Flag ID:** \\`${flag.flagId}\\``);\n lines.push(`**Score:** ${flag.effectiveScore}/100 (base: ${flag.score}, confidence: ${flag.confidence})`);\n lines.push(\"\");\n lines.push(flag.summary);\n lines.push(\"\");\n\n if (flag.evidence.length > 0) {\n lines.push(\"**Evidence:**\");\n lines.push(\"\");\n for (const ev of flag.evidence) {\n lines.push(`- **${ev.file}**`);\n if (ev.hunk) {\n lines.push(` \\`${ev.hunk}\\``);\n }\n if (ev.lines.length > 0) {\n lines.push(\" ```\");\n for (const line of ev.lines) {\n lines.push(` ${line}`);\n }\n lines.push(\" ```\");\n }\n }\n lines.push(\"\");\n }\n\n if (flag.suggestedChecks.length > 0) {\n lines.push(\"**Suggested Checks:**\");\n lines.push(\"\");\n for (const check of flag.suggestedChecks) {\n lines.push(`- ${check}`);\n }\n lines.push(\"\");\n }\n }\n }\n }\n\n // Score breakdown\n if (report.scoreBreakdown) {\n lines.push(\"## Score Breakdown\");\n lines.push(\"\");\n lines.push(`**Max Category:** ${report.scoreBreakdown.maxCategory.category} (${report.scoreBreakdown.maxCategory.score})`);\n lines.push(\"\");\n lines.push(\"**Top 3 Categories:**\");\n for (const cat of report.scoreBreakdown.topCategories) {\n lines.push(`- ${cat.category}: ${cat.score}`);\n }\n lines.push(\"\");\n lines.push(`**Formula:** \\`${report.scoreBreakdown.formula}\\``);\n lines.push(\"\");\n }\n\n // Skipped files\n if (report.skippedFiles.length > 0) {\n lines.push(\"## Skipped Files\");\n lines.push(\"\");\n lines.push(`${report.skippedFiles.length} files were skipped:`);\n lines.push(\"\");\n for (const skip of report.skippedFiles.slice(0, 20)) {\n lines.push(`- \\`${skip.file}\\` (${skip.reason})`);\n }\n if (report.skippedFiles.length > 20) {\n lines.push(`- ... and ${report.skippedFiles.length - 20} more`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render risk report as plain text.\n */\nexport function renderRiskReportText(report: RiskReport): string {\n const lines: string[] = [];\n\n // Header\n lines.push(\"RISK REPORT\");\n lines.push(\"=\".repeat(60));\n lines.push(\"\");\n lines.push(`Range: ${report.range.base}..${report.range.head}`);\n lines.push(\"\");\n\n // Overall score\n lines.push(`Overall Risk: ${report.riskLevel.toUpperCase()}`);\n lines.push(`Score: ${report.riskScore}/100`);\n lines.push(\"\");\n\n // Category scores\n lines.push(\"Category Scores:\");\n lines.push(\"-\".repeat(40));\n const categories = Object.entries(report.categoryScores)\n .sort((a, b) => b[1] - a[1]);\n \n for (const [category, score] of categories) {\n if (score > 0) {\n const bar = \"#\".repeat(Math.floor(score / 5));\n lines.push(` ${category.padEnd(12)} ${score.toString().padStart(3)}/100 ${bar}`);\n }\n }\n lines.push(\"\");\n\n // Flags\n if (report.flags.length > 0) {\n lines.push(\"Risk Flags:\");\n lines.push(\"-\".repeat(40));\n\n for (const flag of report.flags) {\n lines.push(\"\");\n lines.push(`[${flag.ruleKey}] ${flag.title}`);\n lines.push(` Score: ${flag.effectiveScore}/100`);\n lines.push(` ${flag.summary}`);\n \n if (flag.evidence.length > 0) {\n lines.push(` Evidence: ${flag.evidence.length} location(s)`);\n for (const ev of flag.evidence.slice(0, 2)) {\n lines.push(` - ${ev.file}`);\n }\n }\n }\n lines.push(\"\");\n }\n\n // Skipped files\n if (report.skippedFiles.length > 0) {\n lines.push(`Skipped Files: ${report.skippedFiles.length}`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Get emoji for risk level.\n */\nfunction getLevelEmoji(level: string): string {\n switch (level) {\n case \"critical\": return \"🔴\";\n case \"high\": return \"🟠\";\n case \"elevated\": return \"🟡\";\n case \"moderate\": return \"🔵\";\n case \"low\": return \"🟢\";\n default: return \"⚪\";\n }\n}\n\n/**\n * Group flags by category.\n */\nfunction groupFlagsByCategory(flags: RiskFlag[]): Record<string, RiskFlag[]> {\n const groups: Record<string, RiskFlag[]> = {};\n \n for (const flag of flags) {\n if (!groups[flag.category]) {\n groups[flag.category] = [];\n }\n groups[flag.category].push(flag);\n }\n\n return groups;\n}\n",
68
- "/**\n * Delta computation for risk-report --since feature.\n */\n\nimport type {\n RiskReport,\n RiskReportDelta,\n RiskFlag,\n FlagChange,\n ScopeMetadata,\n} from \"../../core/types.js\";\nimport {\n loadJson,\n diffById,\n compareScopeMetadata,\n extractRiskReportScope,\n} from \"../../core/delta.js\";\nimport { BranchNarratorError } from \"../../core/errors.js\";\n\n/**\n * Options for computing risk report delta.\n */\nexport interface ComputeRiskReportDeltaOptions {\n sincePath: string;\n currentReport: RiskReport;\n mode: string;\n base: string | null;\n head: string | null;\n only: string[] | null;\n exclude: string[] | null;\n sinceStrict: boolean;\n}\n\n/**\n * Compute delta between current risk report and a previous risk report.\n */\nexport async function computeRiskReportDelta(\n options: ComputeRiskReportDeltaOptions\n): Promise<RiskReportDelta> {\n const {\n sincePath,\n currentReport,\n mode,\n base,\n head,\n only,\n exclude,\n sinceStrict,\n } = options;\n\n // Load previous report\n let previousReport: RiskReport;\n try {\n previousReport = await loadJson(sincePath);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BranchNarratorError(\n `Failed to load previous risk report from ${sincePath}: ${errorMessage}`,\n 1\n );\n }\n\n // Validate it looks like a RiskReport\n if (!previousReport.schemaVersion || !previousReport.flags || previousReport.riskScore === undefined) {\n throw new BranchNarratorError(\n `File ${sincePath} does not appear to be a valid risk report output`,\n 1\n );\n }\n\n // Build scope metadata for current run\n const currentScope: ScopeMetadata = {\n mode,\n base,\n head,\n only,\n };\n\n // Extract scope from previous run\n const previousScope = extractRiskReportScope(previousReport);\n\n // Compare scopes and generate warnings\n const warnings = compareScopeMetadata(previousScope, currentScope);\n\n // If strict mode and warnings exist, error out\n if (sinceStrict && warnings.length > 0) {\n throw new BranchNarratorError(\n `Scope mismatch detected (--since-strict): ${warnings.map(w => w.message).join(\"; \")}`,\n 1\n );\n }\n\n // Compute delta for flags\n const { added, removed, changed } = diffById({\n beforeItems: previousReport.flags,\n afterItems: currentReport.flags,\n });\n\n // Build FlagChange objects\n const flagChanges: FlagChange[] = changed.map(c => ({\n flagId: c.id,\n before: c.before as RiskFlag,\n after: c.after as RiskFlag,\n }));\n\n // Compute risk score delta\n const riskScoreDelta = {\n from: previousReport.riskScore,\n to: currentReport.riskScore,\n delta: currentReport.riskScore - previousReport.riskScore,\n };\n\n // Build command metadata\n const commandArgs = [\"--mode\", mode];\n if (base) commandArgs.push(\"--base\", base);\n if (head) commandArgs.push(\"--head\", head);\n if (only) commandArgs.push(\"--only\", only.join(\",\"));\n if (exclude) commandArgs.push(\"--exclude\", exclude.join(\",\"));\n commandArgs.push(\"--since\", sincePath);\n if (sinceStrict) commandArgs.push(\"--since-strict\");\n\n return {\n schemaVersion: \"1.0\",\n generatedAt: new Date().toISOString(),\n command: {\n name: \"risk-report\",\n args: commandArgs,\n },\n since: {\n path: sincePath,\n schemaVersion: previousReport.schemaVersion,\n },\n current: {\n schemaVersion: currentReport.schemaVersion,\n },\n scope: currentScope,\n delta: {\n riskScore: riskScoreDelta,\n flags: {\n added,\n removed,\n changed: flagChanges,\n },\n },\n summary: {\n flagAddedCount: added.length,\n flagRemovedCount: removed.length,\n flagChangedCount: flagChanges.length,\n },\n };\n}\n",
69
- "/**\n * Risk report command.\n */\n\nimport type { ChangeSet, DiffMode, ProfileName, RiskFlag, RiskReport } from \"../../core/types.js\";\nimport { shouldSkipFile } from \"./exclusions.js\";\nimport { redactLines } from \"./redaction.js\";\nimport { computeRiskReport, filterFlagsByCategory } from \"./scoring.js\";\nimport { sortRiskFlagEvidence } from \"../../core/sorting.js\";\nimport { getProfile, resolveProfileName } from \"../../profiles/index.js\";\nimport { assignFindingId } from \"../../core/ids.js\";\nimport { findingsToFlags } from \"./findings-to-flags.js\";\nimport { runAnalyzersInParallel } from \"../../core/analyzer-runner.js\";\n\n/**\n * Options for generating risk report.\n */\nexport interface RiskReportOptions {\n only?: string[];\n exclude?: string[];\n maxEvidenceLines?: number;\n redact?: boolean;\n explainScore?: boolean;\n noTimestamp?: boolean;\n profile?: ProfileName;\n cwd?: string;\n /** Original CLI mode used to generate this output */\n mode?: DiffMode;\n /** Enable test parity checking (opt-in, may be slow on large repos) */\n testParity?: boolean;\n}\n\n/**\n * Generate risk report from change set.\n */\nexport async function generateRiskReport(\n changeSet: ChangeSet,\n options: RiskReportOptions = {}\n): Promise<RiskReport> {\n const {\n only,\n exclude,\n maxEvidenceLines = 5,\n redact = false,\n explainScore = false,\n noTimestamp = false,\n profile: requestedProfile = \"auto\",\n cwd = process.cwd(),\n mode,\n testParity = false,\n } = options;\n\n // Track skipped files\n const skippedFiles: Array<{ file: string; reason: string }> = [];\n\n // Check for skipped files in changeset\n for (const file of changeSet.files) {\n const skipCheck = shouldSkipFile(file.path);\n if (skipCheck.skip) {\n skippedFiles.push({\n file: file.path,\n reason: skipCheck.reason || \"excluded\",\n });\n }\n }\n\n // Run analysis pipeline to get findings\n const profileName = resolveProfileName(requestedProfile, changeSet, cwd);\n const profile = getProfile(profileName);\n\n // Run analyzers in parallel for better performance\n const rawFindings = await runAnalyzersInParallel(profile.analyzers, changeSet);\n\n // Run test parity analyzer if explicitly enabled (opt-in)\n if (testParity) {\n const { testParityAnalyzer } = await import(\"../../analyzers/test-parity.js\");\n const testParityFindings = await testParityAnalyzer.analyze(changeSet);\n rawFindings.push(...testParityFindings);\n }\n\n // Assign findingIds to all findings\n const findings = rawFindings.map(assignFindingId);\n\n // Convert findings to risk flags\n let allFlags: RiskFlag[] = findingsToFlags(findings);\n\n // Filter by category if requested\n allFlags = filterFlagsByCategory(allFlags, only, exclude);\n\n // Apply redaction and evidence line limits, and sort evidence\n if (redact || maxEvidenceLines !== 5) {\n allFlags = allFlags.map(flag => ({\n ...flag,\n evidence: sortRiskFlagEvidence(flag.evidence.map(ev => ({\n ...ev,\n lines: redact\n ? redactLines(ev.lines.slice(0, maxEvidenceLines))\n : ev.lines.slice(0, maxEvidenceLines),\n }))),\n }));\n } else {\n // Sort evidence even when not redacting or limiting lines\n allFlags = allFlags.map(flag => ({\n ...flag,\n evidence: sortRiskFlagEvidence(flag.evidence),\n }));\n }\n\n // Compute report\n return computeRiskReport(\n changeSet.base,\n changeSet.head,\n allFlags,\n skippedFiles,\n { explainScore, noTimestamp, mode, only, exclude }\n );\n}\n\n/**\n * Execute the risk-report command.\n * This is the standard command handler that follows the execute* naming convention.\n */\nexport async function executeRiskReport(\n changeSet: ChangeSet,\n options: RiskReportOptions = {}\n): Promise<RiskReport> {\n return await generateRiskReport(changeSet, options);\n}\n\nexport * from \"./exclusions.js\";\nexport * from \"./redaction.js\";\nexport * from \"./scoring.js\";\nexport * from \"./renderers.js\";\nexport * from \"./findings-to-flags.js\";\nexport { computeRiskReportDelta, type ComputeRiskReportDeltaOptions } from \"./delta.js\";\n",
70
- "/**\n * Zoom command - targeted drill-down for findings and flags.\n * \n * Provides minimal, deterministic, evidence-backed context for a single\n * finding or flag. Designed for interactive AI agent loops.\n */\n\nimport type {\n ChangeSet,\n DiffMode,\n Finding,\n ProfileName,\n ZoomOutput,\n ZoomFindingOutput,\n ZoomFlagOutput,\n ZoomEvidence,\n PatchContext,\n} from \"../../core/types.js\";\nimport { BranchNarratorError } from \"../../core/errors.js\";\nimport { getProfile, resolveProfileName } from \"../../profiles/index.js\";\nimport { runAnalyzersInParallel } from \"../../core/analyzer-runner.js\";\nimport { assignFindingId } from \"../../core/ids.js\";\nimport { generateRiskReport } from \"../risk/index.js\";\nimport { redactSecrets } from \"../../core/evidence.js\";\n\n/**\n * Options for the zoom command.\n */\nexport interface ZoomOptions {\n findingId?: string;\n flagId?: string;\n mode: DiffMode;\n base?: string;\n head?: string;\n profile: ProfileName;\n includePatch: boolean;\n unified: number;\n maxEvidenceLines: number;\n redact: boolean;\n noTimestamp: boolean;\n}\n\n/**\n * Execute the zoom command.\n */\nexport async function executeZoom(\n changeSet: ChangeSet,\n options: ZoomOptions\n): Promise<ZoomOutput> {\n // Validate that exactly one of findingId or flagId is provided\n if (options.findingId && options.flagId) {\n throw new BranchNarratorError(\n \"Cannot specify both --finding and --flag. Use only one.\",\n 1\n );\n }\n\n if (!options.findingId && !options.flagId) {\n throw new BranchNarratorError(\n \"Must specify either --finding <id> or --flag <id>\",\n 1\n );\n }\n\n // Route to appropriate handler\n if (options.findingId) {\n return executeZoomFinding(changeSet, options);\n } else {\n return executeZoomFlag(changeSet, options);\n }\n}\n\n/**\n * Zoom into a specific finding by ID.\n */\nasync function executeZoomFinding(\n changeSet: ChangeSet,\n options: ZoomOptions\n): Promise<ZoomFindingOutput> {\n const findingId = options.findingId!;\n\n // Run analysis to get all findings\n const profileName = resolveProfileName(options.profile, changeSet, process.cwd());\n const profile = getProfile(profileName);\n\n // Run analyzers in parallel for better performance\n const rawFindings = await runAnalyzersInParallel(profile.analyzers, changeSet);\n\n // Assign IDs to all findings\n const findings = rawFindings.map(assignFindingId);\n\n // Find the requested finding\n const finding = findings.find((f) => f.findingId === findingId);\n\n if (!finding) {\n throw new BranchNarratorError(\n `Finding not found: ${findingId}. Run 'facts' or 'risk-report' to see available findings.`,\n 1\n );\n }\n\n // Convert evidence to zoom format with optional redaction\n const evidence: ZoomEvidence[] = finding.evidence.slice(0, options.maxEvidenceLines).map((ev) => ({\n file: ev.file,\n excerpt: options.redact ? redactSecrets(ev.excerpt) : ev.excerpt,\n line: ev.line,\n hunk: ev.hunk,\n }));\n\n // Optionally fetch patch context\n let patchContext: PatchContext[] | undefined;\n if (options.includePatch) {\n patchContext = await fetchPatchContext(changeSet, finding, options.unified, options.redact);\n }\n\n const output: ZoomFindingOutput = {\n schemaVersion: \"1.0\",\n generatedAt: options.noTimestamp ? undefined : new Date().toISOString(),\n range: {\n base: changeSet.base,\n head: changeSet.head,\n },\n itemType: \"finding\",\n findingId,\n finding,\n evidence,\n patchContext,\n };\n\n return output;\n}\n\n/**\n * Zoom into a specific flag by ID.\n */\nasync function executeZoomFlag(\n changeSet: ChangeSet,\n options: ZoomOptions\n): Promise<ZoomFlagOutput> {\n const flagId = options.flagId!;\n\n // Run analysis once to get both findings and flags\n const profileName = resolveProfileName(options.profile, changeSet, process.cwd());\n const profile = getProfile(profileName);\n\n // Run analyzers in parallel for better performance\n const rawFindings = await runAnalyzersInParallel(profile.analyzers, changeSet);\n\n // Assign findingIds to all findings\n const allFindings = rawFindings.map(assignFindingId);\n\n // Generate risk report to get flags (passing findings avoids re-running analysis)\n const report = await generateRiskReport(changeSet, {\n profile: options.profile,\n redact: options.redact,\n maxEvidenceLines: options.maxEvidenceLines,\n noTimestamp: options.noTimestamp,\n });\n\n // Find the requested flag\n const flag = report.flags.find((f) => f.flagId === flagId);\n\n if (!flag) {\n throw new BranchNarratorError(\n `Flag not found: ${flagId}. Run 'risk-report' to see available flags.`,\n 1\n );\n }\n\n // Get related findings (using already computed findings)\n const relatedFindings = allFindings.filter((f) => flag.relatedFindingIds.includes(f.findingId));\n\n // Optionally fetch patch context from evidence files\n let patchContext: PatchContext[] | undefined;\n if (options.includePatch && flag.evidence.length > 0) {\n patchContext = await fetchPatchContextFromFiles(\n changeSet,\n flag.evidence.map((ev) => ev.file),\n options.unified,\n options.redact\n );\n }\n\n const output: ZoomFlagOutput = {\n schemaVersion: \"1.0\",\n generatedAt: options.noTimestamp ? undefined : new Date().toISOString(),\n range: {\n base: changeSet.base,\n head: changeSet.head,\n },\n itemType: \"flag\",\n flagId,\n flag,\n evidence: flag.evidence.slice(0, options.maxEvidenceLines),\n relatedFindings,\n patchContext,\n };\n\n return output;\n}\n\n/**\n * Fetch patch context for evidence files in a finding.\n */\nasync function fetchPatchContext(\n changeSet: ChangeSet,\n finding: Finding,\n unified: number,\n redact: boolean\n): Promise<PatchContext[]> {\n // Extract unique files from evidence\n const files = new Set<string>();\n for (const ev of finding.evidence) {\n files.add(ev.file);\n }\n\n return fetchPatchContextFromFiles(changeSet, Array.from(files), unified, redact);\n}\n\n/**\n * Fetch patch context for a list of files.\n * Note: unified parameter is reserved for future use when we might fetch\n * diffs with custom unified context. Currently uses hunks from changeSet.\n */\nasync function fetchPatchContextFromFiles(\n changeSet: ChangeSet,\n files: string[],\n _unified: number,\n redact: boolean\n): Promise<PatchContext[]> {\n const patchContext: PatchContext[] = [];\n\n for (const file of files) {\n // Find the file diff in the changeset\n const fileDiff = changeSet.diffs.find((d) => d.path === file);\n if (!fileDiff) {\n continue;\n }\n\n patchContext.push({\n file: fileDiff.path,\n status: fileDiff.status,\n hunks: fileDiff.hunks.map((hunk) => ({\n oldStart: hunk.oldStart,\n oldLines: hunk.oldLines,\n newStart: hunk.newStart,\n newLines: hunk.newLines,\n content: redact ? redactSecrets(hunk.content) : hunk.content,\n })),\n });\n }\n\n return patchContext;\n}\n",
71
- "/**\n * Renderers for zoom command output.\n */\n\nimport type { ZoomOutput, ZoomFindingOutput, ZoomFlagOutput } from \"../../core/types.js\";\n\n/**\n * Render zoom output as JSON.\n */\nexport function renderZoomJSON(output: ZoomOutput, pretty: boolean): string {\n return pretty ? JSON.stringify(output, null, 2) : JSON.stringify(output);\n}\n\n/**\n * Render zoom output as Markdown.\n */\nexport function renderZoomMarkdown(output: ZoomOutput): string {\n if (output.itemType === \"finding\") {\n return renderFindingMarkdown(output);\n } else {\n return renderFlagMarkdown(output);\n }\n}\n\n/**\n * Render finding output as Markdown.\n */\nfunction renderFindingMarkdown(output: ZoomFindingOutput): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`# Finding: ${output.findingId}`);\n lines.push(\"\");\n\n // Metadata\n lines.push(`**Type:** ${output.finding.type}`);\n lines.push(`**Category:** ${output.finding.category}`);\n lines.push(`**Confidence:** ${output.finding.confidence}`);\n lines.push(\"\");\n\n // Range\n lines.push(`**Range:** ${output.range.base}..${output.range.head}`);\n lines.push(\"\");\n\n // Finding details based on type\n lines.push(\"## Details\");\n lines.push(\"\");\n lines.push(\"```json\");\n lines.push(JSON.stringify(output.finding, null, 2));\n lines.push(\"```\");\n lines.push(\"\");\n\n // Evidence\n if (output.evidence.length > 0) {\n lines.push(\"## Evidence\");\n lines.push(\"\");\n\n for (const ev of output.evidence) {\n lines.push(`### ${ev.file}`);\n if (ev.line !== undefined) {\n lines.push(`Line ${ev.line}`);\n }\n if (ev.hunk) {\n lines.push(\n `Hunk: @@ -${ev.hunk.oldStart},${ev.hunk.oldLines} +${ev.hunk.newStart},${ev.hunk.newLines} @@`\n );\n }\n lines.push(\"\");\n lines.push(\"```\");\n lines.push(ev.excerpt);\n lines.push(\"```\");\n lines.push(\"\");\n }\n }\n\n // Patch context\n if (output.patchContext && output.patchContext.length > 0) {\n lines.push(\"## Patch Context\");\n lines.push(\"\");\n\n for (const patch of output.patchContext) {\n lines.push(`### ${patch.file} (${patch.status})`);\n lines.push(\"\");\n\n for (const hunk of patch.hunks) {\n lines.push(\"```diff\");\n lines.push(\n `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`\n );\n lines.push(hunk.content);\n lines.push(\"```\");\n lines.push(\"\");\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render flag output as Markdown.\n */\nfunction renderFlagMarkdown(output: ZoomFlagOutput): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`# Flag: ${output.flagId}`);\n lines.push(\"\");\n\n // Metadata\n lines.push(`**Rule:** ${output.flag.ruleKey}`);\n lines.push(`**Category:** ${output.flag.category}`);\n lines.push(`**Score:** ${output.flag.effectiveScore} (base: ${output.flag.score}, confidence: ${output.flag.confidence})`);\n lines.push(\"\");\n\n // Range\n lines.push(`**Range:** ${output.range.base}..${output.range.head}`);\n lines.push(\"\");\n\n // Flag details\n lines.push(\"## Details\");\n lines.push(\"\");\n lines.push(`**Title:** ${output.flag.title}`);\n lines.push(\"\");\n lines.push(`**Summary:** ${output.flag.summary}`);\n lines.push(\"\");\n\n // Suggested checks\n if (output.flag.suggestedChecks && output.flag.suggestedChecks.length > 0) {\n lines.push(\"### Suggested Checks\");\n lines.push(\"\");\n for (const check of output.flag.suggestedChecks) {\n lines.push(`- ${check}`);\n }\n lines.push(\"\");\n }\n\n // Evidence\n if (output.evidence.length > 0) {\n lines.push(\"## Evidence\");\n lines.push(\"\");\n\n for (const ev of output.evidence) {\n lines.push(`### ${ev.file}`);\n if (ev.hunk) {\n lines.push(`Hunk: ${ev.hunk}`);\n }\n lines.push(\"\");\n lines.push(\"```\");\n lines.push(ev.lines.join(\"\\n\"));\n lines.push(\"```\");\n lines.push(\"\");\n }\n }\n\n // Related findings\n if (output.relatedFindings && output.relatedFindings.length > 0) {\n lines.push(\"## Related Findings\");\n lines.push(\"\");\n\n for (const finding of output.relatedFindings) {\n lines.push(`- **${finding.findingId}** (${finding.type}, ${finding.category})`);\n }\n lines.push(\"\");\n }\n\n // Patch context\n if (output.patchContext && output.patchContext.length > 0) {\n lines.push(\"## Patch Context\");\n lines.push(\"\");\n\n for (const patch of output.patchContext) {\n lines.push(`### ${patch.file} (${patch.status})`);\n lines.push(\"\");\n\n for (const hunk of patch.hunks) {\n lines.push(\"```diff\");\n lines.push(\n `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`\n );\n lines.push(hunk.content);\n lines.push(\"```\");\n lines.push(\"\");\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render zoom output as plain text.\n */\nexport function renderZoomText(output: ZoomOutput): string {\n if (output.itemType === \"finding\") {\n return renderFindingText(output);\n } else {\n return renderFlagText(output);\n }\n}\n\n/**\n * Render finding output as plain text.\n */\nfunction renderFindingText(output: ZoomFindingOutput): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`Finding: ${output.findingId}`);\n lines.push(\"=\".repeat(60));\n lines.push(\"\");\n\n // Metadata\n lines.push(`Type: ${output.finding.type}`);\n lines.push(`Category: ${output.finding.category}`);\n lines.push(`Confidence: ${output.finding.confidence}`);\n lines.push(`Range: ${output.range.base}..${output.range.head}`);\n lines.push(\"\");\n\n // Evidence\n if (output.evidence.length > 0) {\n lines.push(\"Evidence:\");\n lines.push(\"-\".repeat(60));\n\n for (const ev of output.evidence) {\n lines.push(`File: ${ev.file}`);\n if (ev.line !== undefined) {\n lines.push(` Line: ${ev.line}`);\n }\n if (ev.hunk) {\n lines.push(\n ` Hunk: @@ -${ev.hunk.oldStart},${ev.hunk.oldLines} +${ev.hunk.newStart},${ev.hunk.newLines} @@`\n );\n }\n lines.push(\"\");\n lines.push(ev.excerpt);\n lines.push(\"\");\n }\n }\n\n // Patch context\n if (output.patchContext && output.patchContext.length > 0) {\n lines.push(\"Patch Context:\");\n lines.push(\"-\".repeat(60));\n\n for (const patch of output.patchContext) {\n lines.push(`File: ${patch.file} (${patch.status})`);\n lines.push(\"\");\n\n for (const hunk of patch.hunks) {\n lines.push(\n `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`\n );\n lines.push(hunk.content);\n lines.push(\"\");\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render flag output as plain text.\n */\nfunction renderFlagText(output: ZoomFlagOutput): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`Flag: ${output.flagId}`);\n lines.push(\"=\".repeat(60));\n lines.push(\"\");\n\n // Metadata\n lines.push(`Rule: ${output.flag.ruleKey}`);\n lines.push(`Category: ${output.flag.category}`);\n lines.push(`Score: ${output.flag.effectiveScore} (base: ${output.flag.score}, confidence: ${output.flag.confidence})`);\n lines.push(`Range: ${output.range.base}..${output.range.head}`);\n lines.push(\"\");\n\n // Details\n lines.push(`Title: ${output.flag.title}`);\n lines.push(`Summary: ${output.flag.summary}`);\n lines.push(\"\");\n\n // Suggested checks\n if (output.flag.suggestedChecks && output.flag.suggestedChecks.length > 0) {\n lines.push(\"Suggested Checks:\");\n for (const check of output.flag.suggestedChecks) {\n lines.push(` - ${check}`);\n }\n lines.push(\"\");\n }\n\n // Evidence\n if (output.evidence.length > 0) {\n lines.push(\"Evidence:\");\n lines.push(\"-\".repeat(60));\n\n for (const ev of output.evidence) {\n lines.push(`File: ${ev.file}`);\n if (ev.hunk) {\n lines.push(` Hunk: ${ev.hunk}`);\n }\n lines.push(\"\");\n lines.push(ev.lines.join(\"\\n\"));\n lines.push(\"\");\n }\n }\n\n // Related findings\n if (output.relatedFindings && output.relatedFindings.length > 0) {\n lines.push(\"Related Findings:\");\n lines.push(\"-\".repeat(60));\n\n for (const finding of output.relatedFindings) {\n lines.push(` - ${finding.findingId} (${finding.type}, ${finding.category})`);\n }\n lines.push(\"\");\n }\n\n // Patch context\n if (output.patchContext && output.patchContext.length > 0) {\n lines.push(\"Patch Context:\");\n lines.push(\"-\".repeat(60));\n\n for (const patch of output.patchContext) {\n lines.push(`File: ${patch.file} (${patch.status})`);\n lines.push(\"\");\n\n for (const hunk of patch.hunks) {\n lines.push(\n `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`\n );\n lines.push(hunk.content);\n lines.push(\"\");\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n",
72
- "/**\n * Shared content for branch-narrator integration.\n * This serves as the Single Source of Truth for tool usage instructions.\n */\n\nexport const BRANCH_NARRATOR_USAGE = `# branch-narrator CLI Reference\n\nUse \\`branch-narrator\\` to get deterministic, repo-grounded context about changes\nbetween git refs. It does not use an LLM and will not invent intent.\n\n## Quick Start\n\nRun \\`branch-narrator --help\\` for all options.\n\n## Commands\n\n### facts (Primary)\n\nGet structured JSON analysis of changes. This is the primary command for understanding what changed.\n\n**When to use:**\n- User asks for a PR description or summary of changes\n- You need structured data about routes, endpoints, dependencies, or config changes\n- You want to understand the scope of modifications\n\n**Example:**\n\\`\\`\\`bash\nbranch-narrator facts --mode branch --base main --head HEAD\n\\`\\`\\`\n\n**Output:** JSON with categorized findings including file summaries, route changes, dependency updates, environment variables, and more.\n\n---\n\n### risk-report\n\nGet a risk score (0-100) with evidence-backed security and stability flags.\n\n**When to use:**\n- User asks about security implications or risks\n- Before merging changes that touch sensitive areas (auth, DB, infra)\n- When reviewing PRs for potential issues\n\n**Example:**\n\\`\\`\\`bash\nbranch-narrator risk-report --mode branch --base main --head HEAD\n\\`\\`\\`\n\n**Output:** Risk score with categorized flags (high/medium/low) and evidence for each flag.\n\n---\n\n### zoom\n\nDrill into a specific finding or risk flag by its stable ID.\n\n**When to use:**\n- You need more details about a specific finding from \\`facts\\`\n- You want to understand a risk flag from \\`risk-report\\`\n- You need to cite specific evidence in a PR description\n\n**Examples:**\n\\`\\`\\`bash\n# Zoom into a finding\nbranch-narrator zoom --finding <id> --mode branch --base main\n\n# Zoom into a risk flag\nbranch-narrator zoom --flag <id> --mode branch --base main\n\\`\\`\\`\n\n**Output:** Detailed information about the specific finding or flag, including file paths and line-level context.\n\n---\n\n### dump-diff\n\nGet filtered diff output for line-level code review context.\n\n**When to use:**\n- You need raw diff content for precise code analysis\n- Writing detailed PR descriptions that cite specific lines\n- When \\`facts\\` doesn't provide enough detail\n\n**Example:**\n\\`\\`\\`bash\nbranch-narrator dump-diff --mode branch --base main --head HEAD --unified 3 --out .ai/diff.txt\n\\`\\`\\`\n\n**Output:** Unified diff written to the specified file, filtered to exclude noise (lockfiles, generated files).\n\n---\n\n### snap\n\nSave and restore workspace snapshots for safe experimentation.\n\n**When to use:**\n- Before making risky or experimental changes\n- When you want a restore point during complex refactoring\n- To compare workspace states\n\n**Examples:**\n\\`\\`\\`bash\n# Save current state\nbranch-narrator snap save \"before-refactor\"\n\n# List saved snapshots\nbranch-narrator snap list\n\n# Restore a snapshot\nbranch-narrator snap restore <id>\n\n# Show snapshot details\nbranch-narrator snap show <id>\n\n# Compare two snapshots\nbranch-narrator snap diff <idA> <idB>\n\\`\\`\\`\n\n---\n\n## Decision Tree\n\nUse this to decide which command to run:\n\n\\`\\`\\`\nUser asks to understand changes → run \\`facts\\`\nUser asks about risks/security → run \\`risk-report\\`\nNeed details on specific item → run \\`zoom --finding <id>\\` or \\`zoom --flag <id>\\`\nNeed raw diff for code review → run \\`dump-diff\\`\nBefore risky/experimental changes → run \\`snap save\\`\n\\`\\`\\`\n\n## Common Workflows\n\n### PR Description\n1. Run \\`facts --mode branch --base main --head HEAD\\`\n2. Run \\`dump-diff --mode branch --base main --head HEAD --out .ai/diff.txt\\`\n3. Use the structured facts and diff to write the PR description\n\n### Risk Review\n1. Run \\`risk-report --mode branch --base main --head HEAD\\`\n2. For high-severity flags, run \\`zoom --flag <id>\\` to get details\n3. Summarize risks with evidence citations\n\n### Code Review Context\n1. Run \\`facts\\` for overview\n2. Run \\`dump-diff\\` for specific file changes\n3. Use \\`zoom\\` for detailed investigation of specific findings\n\n## Default Behavior\n\n- **Mode:** Defaults to \\`unstaged\\` (local uncommitted changes) if no mode specified\n- **Base/Head:** For branch mode, defaults to \\`main\\` and \\`HEAD\\` if not specified\n- **For PR descriptions:** Always use \\`--mode branch\\`\n`;\n\nexport const PR_DESCRIPTION_TEMPLATE = `# PR Description (use branch-narrator)\n\nWhen the user asks to write a PR description, generate a Markdown PR body they\ncan copy-paste directly. Ground everything in the repo diff; do not invent\nintent or outcomes.\n\n## Required Steps\n\n1. Get structured facts:\n \\`branch-narrator facts --mode branch --base main --head HEAD\\`\n\n2. Dump a filtered diff:\n \\`branch-narrator dump-diff --mode branch --base main --head HEAD --unified 3 --out .ai/diff.txt\\`\n\n3. Read the JSON output and \\`.ai/diff.txt\\` for evidence\n\nIf the user provides different refs, use them instead of \\`main..HEAD\\`.\n\n## Writing Guidelines\n\n- Output ONLY the final PR Markdown (no preamble, no tool logs)\n- Use \\`facts\\` output to decide which sections are relevant\n- Use diff to cite specifics (files, endpoints, migrations)\n- Never claim \"why\" unless the user stated it\n- If intent is unclear, add an \"Open questions\" section\n\n## PR Structure\n\nInclude these sections based on what's relevant to the changes:\n\n### Summary\n2-6 bullets describing what changed (facts-based, no speculation).\nMention high-impact areas: routes, DB, env/config, dependencies, tests.\n\n### Product Impact\nUser-visible changes from a product perspective.\n\n### Testing\n- Automated: relevant test commands\n- Manual: checklist derived from routes/endpoints touched\n\n### Technical Notes\nKey implementation details for reviewers.\n\n### Deployment Notes\nEnv vars, migrations, infrastructure changes (if applicable).\n\n### Risks & Mitigations\nConcrete risks with evidence and verification steps.\n`;\n",
73
- "import { stat } from \"node:fs/promises\";\n\nexport async function isFile(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isFile();\n } catch {\n return false;\n }\n}\n\nexport async function isDirectory(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isDirectory();\n } catch {\n return false;\n }\n}\n",
74
- "import { join } from \"node:path\";\nimport { Provider } from \"../types.js\";\nimport { BRANCH_NARRATOR_USAGE } from \"../shared.js\";\nimport { isFile } from \"../fs.js\";\n\nconst CLAUDE_FILE = \"CLAUDE.md\";\n\nexport const claudeProvider: Provider = {\n name: \"claude\",\n description: \"Integrate with CLAUDE.md (Claude Code)\",\n detect: async (cwd: string) => isFile(join(cwd, CLAUDE_FILE)),\n generate: () => {\n const content = `\\n\\n## Branch Narrator Usage\\n\\n${BRANCH_NARRATOR_USAGE}`;\n return [\n {\n path: CLAUDE_FILE,\n content,\n },\n ];\n },\n};\n",
75
- "import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Provider } from \"../types.js\";\nimport { BRANCH_NARRATOR_USAGE, PR_DESCRIPTION_TEMPLATE } from \"../shared.js\";\nimport { isDirectory } from \"../fs.js\";\n\n/**\n * Detect whether to use .mdc or .md format based on existing rules.\n * If .mdc files exist in .cursor/rules/, use .mdc format with frontmatter.\n */\nasync function detectCursorFormat(cwd: string): Promise<\"mdc\" | \"md\"> {\n try {\n const rulesDir = join(cwd, \".cursor\", \"rules\");\n const files = await readdir(rulesDir);\n const hasMdcFiles = files.some((f) => f.endsWith(\".mdc\"));\n return hasMdcFiles ? \"mdc\" : \"md\";\n } catch {\n // Directory doesn't exist or can't be read - use default .md\n return \"md\";\n }\n}\n\n/**\n * Wrap content with .mdc frontmatter.\n */\nfunction wrapWithFrontmatter(content: string): string {\n return `---\nalwaysApply: true\n---\n\n${content}`;\n}\n\nexport const cursorProvider: Provider = {\n name: \"cursor\",\n description: \"Generate Cursor rules (.cursor/rules/*.md or *.mdc)\",\n detect: async (cwd: string) => isDirectory(join(cwd, \".cursor\", \"rules\")),\n generate: async (cwd: string) => {\n const format = await detectCursorFormat(cwd);\n const extension = format === \"mdc\" ? \".mdc\" : \".md\";\n\n const branchNarratorContent =\n format === \"mdc\"\n ? wrapWithFrontmatter(BRANCH_NARRATOR_USAGE)\n : BRANCH_NARRATOR_USAGE;\n\n const prDescriptionContent =\n format === \"mdc\"\n ? wrapWithFrontmatter(PR_DESCRIPTION_TEMPLATE)\n : PR_DESCRIPTION_TEMPLATE;\n\n return [\n {\n path: `.cursor/rules/branch-narrator${extension}`,\n content: branchNarratorContent,\n },\n {\n path: `.cursor/rules/pr-description${extension}`,\n content: prDescriptionContent,\n },\n ];\n },\n};\n",
76
- "import { join } from \"node:path\";\nimport { Provider } from \"../types.js\";\nimport { BRANCH_NARRATOR_USAGE } from \"../shared.js\";\nimport { isDirectory } from \"../fs.js\";\n\nexport const julesRulesProvider: Provider = {\n name: \"jules-rules\",\n description: \"Generate Jules rules in .jules/rules/branch-narrator.md\",\n detect: async (cwd: string) => isDirectory(join(cwd, \".jules\")),\n generate: () => [\n {\n path: \".jules/rules/branch-narrator.md\",\n content: BRANCH_NARRATOR_USAGE,\n },\n ],\n};\n",
77
- "\nimport { join } from \"node:path\";\nimport { Provider } from \"../types.js\";\nimport { BRANCH_NARRATOR_USAGE } from \"../shared.js\";\nimport { isFile } from \"../fs.js\";\n\nexport const julesProvider: Provider = {\n name: \"jules\",\n description: \"Integrate with AGENTS.md (Jules)\",\n detect: async (cwd: string) => isFile(join(cwd, \"AGENTS.md\")),\n generate: () => {\n // Wrap the usage instructions in a section suitable for AGENTS.md\n const content = `\\n\\n## Branch Narrator Usage\\n\\n${BRANCH_NARRATOR_USAGE}`;\n\n return [\n {\n path: \"AGENTS.md\",\n content: content,\n },\n ];\n },\n};\n",
78
- "import { join } from \"node:path\";\nimport { Provider } from \"../types.js\";\nimport { BRANCH_NARRATOR_USAGE } from \"../shared.js\";\nimport { isDirectory, isFile } from \"../fs.js\";\n\nconst OPENCODE_FILES = [\"OPENCODE.md\", \"opencode.md\"];\n\ninterface OpencodeTarget {\n path: string;\n useSection: boolean;\n}\n\nasync function resolveOpencodeTarget(cwd: string): Promise<OpencodeTarget> {\n for (const file of OPENCODE_FILES) {\n if (await isFile(join(cwd, file))) {\n return { path: file, useSection: true };\n }\n }\n\n if (await isDirectory(join(cwd, \".opencode\"))) {\n return { path: \".opencode/branch-narrator.md\", useSection: false };\n }\n\n return { path: \"OPENCODE.md\", useSection: true };\n}\n\nexport const opencodeProvider: Provider = {\n name: \"opencode\",\n description: \"Integrate with OPENCODE.md or .opencode/\",\n detect: async (cwd: string) => {\n for (const file of OPENCODE_FILES) {\n if (await isFile(join(cwd, file))) {\n return true;\n }\n }\n return isDirectory(join(cwd, \".opencode\"));\n },\n generate: async (cwd: string) => {\n const target = await resolveOpencodeTarget(cwd);\n const content = target.useSection\n ? `\\n\\n## Branch Narrator Usage\\n\\n${BRANCH_NARRATOR_USAGE}`\n : BRANCH_NARRATOR_USAGE;\n\n return [\n {\n path: target.path,\n content,\n },\n ];\n },\n};\n",
79
- "\nimport { cursorProvider } from \"../providers/cursor.js\";\n\n/**\n * Legacy support for direct import of generateCursorRules.\n * This ensures tests or other modules relying on this function don't break immediately.\n */\nexport async function generateCursorRules() {\n // Use empty string for cwd - this will default to .md format since no .mdc files exist\n const ops = await cursorProvider.generate(\"\");\n return ops;\n}\n",
80
- "/**\n * integrate command implementation.\n * Generates provider-specific rules (e.g., Cursor, Jules).\n */\n\nimport { mkdir, writeFile, access, readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { BranchNarratorError } from \"../core/errors.js\";\nimport type { IntegrateOptions, Provider, FileOperation } from \"./integrate/types.js\";\nimport { claudeProvider } from \"./integrate/providers/claude.js\";\nimport { cursorProvider } from \"./integrate/providers/cursor.js\";\nimport { julesRulesProvider } from \"./integrate/providers/jules-rules.js\";\nimport { julesProvider } from \"./integrate/providers/jules.js\";\nimport { opencodeProvider } from \"./integrate/providers/opencode.js\";\n\n// ============================================================================\n// Registry\n// ============================================================================\n\nconst providers: Record<string, Provider> = {\n cursor: cursorProvider,\n jules: julesProvider,\n claude: claudeProvider,\n \"jules-rules\": julesRulesProvider,\n opencode: opencodeProvider,\n};\n\nexport { generateCursorRules } from \"./integrate/commands/legacy_stub.js\"; // For backward compatibility if needed, or remove\n\nexport type { IntegrateOptions };\n\n// ============================================================================\n// File System Operations\n// ============================================================================\n\n/**\n * Check if a file exists.\n */\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Write rule files to disk using generic \"Append by Default\" strategy.\n */\nasync function writeRuleFiles(\n operations: FileOperation[],\n cwd: string,\n force: boolean\n): Promise<void> {\n for (const op of operations) {\n const fullPath = join(cwd, op.path);\n const exists = await fileExists(fullPath);\n\n await mkdir(dirname(fullPath), { recursive: true });\n\n if (exists && !force) {\n // Append strategy\n const existingContent = await readFile(fullPath, \"utf-8\");\n\n // Ensure newline separator if needed\n const separator = existingContent.endsWith(\"\\n\") ? \"\" : \"\\n\";\n const newContent = existingContent + separator + op.content;\n\n await writeFile(fullPath, newContent, \"utf-8\");\n console.log(` - ${op.path} (appended)`);\n } else {\n // Create or Overwrite (if force=true) strategy\n await writeFile(fullPath, op.content, \"utf-8\");\n const action = exists ? \"overwritten\" : \"created\";\n console.log(` - ${op.path} (${action})`);\n }\n }\n}\n\nasync function runIntegration(\n provider: Provider,\n options: IntegrateOptions,\n cwd: string\n): Promise<void> {\n const operations = await provider.generate(cwd);\n\n if (options.dryRun) {\n console.log(\"=\".repeat(80));\n console.log(`DRY RUN: Integration for ${provider.name}`);\n console.log(\"=\".repeat(80));\n console.log();\n\n for (const op of operations) {\n console.log(`File: ${op.path}`);\n console.log(\"-\".repeat(80));\n console.log(op.content);\n console.log(\"-\".repeat(80));\n console.log();\n }\n return;\n }\n\n console.log(`Integration for ${provider.name}:`);\n await writeRuleFiles(operations, cwd, options.force);\n}\n\nasync function detectTargets(cwd: string): Promise<string[]> {\n const detected: string[] = [];\n\n for (const [target, provider] of Object.entries(providers)) {\n if (!provider.detect) {\n continue;\n }\n\n try {\n if (await provider.detect(cwd)) {\n detected.push(target);\n }\n } catch {\n // Ignore detection failures and keep scanning.\n }\n }\n\n return detected;\n}\n\n// ============================================================================\n// Command Handler\n// ============================================================================\n\n/**\n * Execute the integrate command.\n */\nexport async function executeIntegrate(options: IntegrateOptions): Promise<void> {\n const cwd = options.cwd ?? process.cwd();\n const supportedTargets = Object.keys(providers);\n\n if (!options.target) {\n const detectedTargets = await detectTargets(cwd);\n\n if (detectedTargets.length === 0) {\n console.log(\"No supported agent guide files detected in this repo.\");\n console.log(\n `Run \"branch-narrator integrate <target>\" with one of: ${supportedTargets.join(\", \")}`\n );\n return;\n }\n\n console.log(`Auto-detected guides: ${detectedTargets.join(\", \")}`);\n\n for (const target of detectedTargets) {\n const provider = providers[target];\n await runIntegration(provider, options, cwd);\n }\n\n return;\n }\n\n const provider = providers[options.target];\n\n // Validate target\n if (!provider) {\n throw new BranchNarratorError(\n `Unknown integration target: ${options.target}\\n` +\n `Supported targets: ${supportedTargets.join(\", \")}`,\n 1\n );\n }\n\n await runIntegration(provider, options, cwd);\n}\n",
81
- "/**\n * Storage utilities for snapshot management.\n *\n * Handles reading/writing snapshot files, index management,\n * and directory structure operations.\n */\n\nimport { mkdir, readFile, writeFile, readdir, rm, stat } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport type {\n SnapshotJson,\n SnapshotIndex,\n SnapshotIndexEntry,\n SnapshotManifest,\n} from \"./types.js\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Base directory for branch-narrator data */\nexport const BRANCH_NARRATOR_DIR = \".branch-narrator\";\n\n/** Snapshots subdirectory */\nexport const SNAPSHOTS_DIR = \"snapshots\";\n\n/** Index file name */\nexport const INDEX_FILE = \"index.json\";\n\n/** Snapshot JSON file name */\nexport const SNAPSHOT_FILE = \"snapshot.json\";\n\n/** Staged patch file name */\nexport const STAGED_PATCH_FILE = \"staged.patch\";\n\n/** Unstaged patch file name */\nexport const UNSTAGED_PATCH_FILE = \"unstaged.patch\";\n\n/** Untracked files directory name */\nexport const UNTRACKED_DIR = \"untracked\";\n\n/** Manifest file name */\nexport const MANIFEST_FILE = \"manifest.json\";\n\n/** Blobs directory name */\nexport const BLOBS_DIR = \"blobs\";\n\n// ============================================================================\n// Path Helpers\n// ============================================================================\n\n/**\n * Get the snapshots base directory path.\n */\nexport function getSnapshotsDir(cwd: string = process.cwd()): string {\n return join(cwd, BRANCH_NARRATOR_DIR, SNAPSHOTS_DIR);\n}\n\n/**\n * Get the path to the snapshot index file.\n */\nexport function getIndexPath(cwd: string = process.cwd()): string {\n return join(getSnapshotsDir(cwd), INDEX_FILE);\n}\n\n/**\n * Get the path to a specific snapshot directory.\n */\nexport function getSnapshotDir(snapshotId: string, cwd: string = process.cwd()): string {\n return join(getSnapshotsDir(cwd), snapshotId);\n}\n\n/**\n * Get the path to a snapshot's JSON file.\n */\nexport function getSnapshotJsonPath(snapshotId: string, cwd: string = process.cwd()): string {\n return join(getSnapshotDir(snapshotId, cwd), SNAPSHOT_FILE);\n}\n\n/**\n * Get the path to a snapshot's staged patch file.\n */\nexport function getStagedPatchPath(snapshotId: string, cwd: string = process.cwd()): string {\n return join(getSnapshotDir(snapshotId, cwd), STAGED_PATCH_FILE);\n}\n\n/**\n * Get the path to a snapshot's unstaged patch file.\n */\nexport function getUnstagedPatchPath(snapshotId: string, cwd: string = process.cwd()): string {\n return join(getSnapshotDir(snapshotId, cwd), UNSTAGED_PATCH_FILE);\n}\n\n/**\n * Get the path to a snapshot's untracked files directory.\n */\nexport function getUntrackedDir(snapshotId: string, cwd: string = process.cwd()): string {\n return join(getSnapshotDir(snapshotId, cwd), UNTRACKED_DIR);\n}\n\n/**\n * Get the path to a snapshot's manifest file.\n */\nexport function getManifestPath(snapshotId: string, cwd: string = process.cwd()): string {\n return join(getUntrackedDir(snapshotId, cwd), MANIFEST_FILE);\n}\n\n/**\n * Get the path to a snapshot's blobs directory.\n */\nexport function getBlobsDir(snapshotId: string, cwd: string = process.cwd()): string {\n return join(getUntrackedDir(snapshotId, cwd), BLOBS_DIR);\n}\n\n/**\n * Get the path to a specific blob file.\n */\nexport function getBlobPath(snapshotId: string, blobSha256: string, cwd: string = process.cwd()): string {\n return join(getBlobsDir(snapshotId, cwd), blobSha256);\n}\n\n// ============================================================================\n// Hash Utilities\n// ============================================================================\n\n/**\n * Compute SHA256 hash of a buffer.\n */\nexport function computeSha256(data: Buffer | string): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\n/**\n * Compute snapshot ID from components.\n * Returns first 12 hex chars of SHA256 hash.\n */\nexport function computeSnapshotId(\n headSha: string,\n stagedPatchSha: string,\n unstagedPatchSha: string,\n manifestContent: string\n): string {\n const fingerprint = `${headSha}:${stagedPatchSha}:${unstagedPatchSha}:${manifestContent}`;\n const hash = createHash(\"sha256\").update(fingerprint).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\n// ============================================================================\n// Directory Management\n// ============================================================================\n\n/**\n * Ensure the snapshots directory exists.\n */\nexport async function ensureSnapshotsDir(cwd: string = process.cwd()): Promise<void> {\n await mkdir(getSnapshotsDir(cwd), { recursive: true });\n}\n\n/**\n * Ensure a snapshot directory and its subdirectories exist.\n */\nexport async function ensureSnapshotDirs(snapshotId: string, cwd: string = process.cwd()): Promise<void> {\n const snapshotDir = getSnapshotDir(snapshotId, cwd);\n await mkdir(snapshotDir, { recursive: true });\n await mkdir(getBlobsDir(snapshotId, cwd), { recursive: true });\n}\n\n/**\n * Check if a snapshot exists.\n */\nexport async function snapshotExists(snapshotId: string, cwd: string = process.cwd()): Promise<boolean> {\n try {\n const jsonPath = getSnapshotJsonPath(snapshotId, cwd);\n await stat(jsonPath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a snapshot directory.\n */\nexport async function deleteSnapshot(snapshotId: string, cwd: string = process.cwd()): Promise<void> {\n const snapshotDir = getSnapshotDir(snapshotId, cwd);\n await rm(snapshotDir, { recursive: true, force: true });\n}\n\n// ============================================================================\n// Index Operations\n// ============================================================================\n\n/**\n * Read the snapshot index.\n * Returns empty index if file doesn't exist.\n */\nexport async function readIndex(cwd: string = process.cwd()): Promise<SnapshotIndex> {\n try {\n const indexPath = getIndexPath(cwd);\n const content = await readFile(indexPath, \"utf-8\");\n return JSON.parse(content) as SnapshotIndex;\n } catch {\n return {\n schemaVersion: \"1.0\",\n snapshots: [],\n };\n }\n}\n\n/**\n * Write the snapshot index.\n */\nexport async function writeIndex(index: SnapshotIndex, cwd: string = process.cwd()): Promise<void> {\n await ensureSnapshotsDir(cwd);\n const indexPath = getIndexPath(cwd);\n await writeFile(indexPath, JSON.stringify(index, null, 2), \"utf-8\");\n}\n\n/**\n * Add an entry to the snapshot index.\n * Maintains sorted order by createdAt descending.\n */\nexport async function addIndexEntry(entry: SnapshotIndexEntry, cwd: string = process.cwd()): Promise<void> {\n const index = await readIndex(cwd);\n\n // Remove existing entry with same ID if present\n index.snapshots = index.snapshots.filter((s) => s.snapshotId !== entry.snapshotId);\n\n // Add new entry\n index.snapshots.push(entry);\n\n // Sort by createdAt descending (newest first)\n index.snapshots.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n\n await writeIndex(index, cwd);\n}\n\n/**\n * Remove an entry from the snapshot index.\n */\nexport async function removeIndexEntry(snapshotId: string, cwd: string = process.cwd()): Promise<void> {\n const index = await readIndex(cwd);\n index.snapshots = index.snapshots.filter((s) => s.snapshotId !== snapshotId);\n await writeIndex(index, cwd);\n}\n\n// ============================================================================\n// Snapshot JSON Operations\n// ============================================================================\n\n/**\n * Read a snapshot JSON file.\n */\nexport async function readSnapshotJson(snapshotId: string, cwd: string = process.cwd()): Promise<SnapshotJson> {\n const jsonPath = getSnapshotJsonPath(snapshotId, cwd);\n const content = await readFile(jsonPath, \"utf-8\");\n return JSON.parse(content) as SnapshotJson;\n}\n\n/**\n * Write a snapshot JSON file.\n */\nexport async function writeSnapshotJson(\n snapshotId: string,\n snapshot: SnapshotJson,\n cwd: string = process.cwd()\n): Promise<void> {\n await ensureSnapshotDirs(snapshotId, cwd);\n const jsonPath = getSnapshotJsonPath(snapshotId, cwd);\n await writeFile(jsonPath, JSON.stringify(snapshot, null, 2), \"utf-8\");\n}\n\n// ============================================================================\n// Patch File Operations\n// ============================================================================\n\n/**\n * Write a patch file.\n */\nexport async function writePatchFile(\n snapshotId: string,\n type: \"staged\" | \"unstaged\",\n content: Buffer,\n cwd: string = process.cwd()\n): Promise<{ path: string; sha256: string; bytes: number }> {\n await ensureSnapshotDirs(snapshotId, cwd);\n\n const filename = type === \"staged\" ? STAGED_PATCH_FILE : UNSTAGED_PATCH_FILE;\n const filePath = join(getSnapshotDir(snapshotId, cwd), filename);\n\n await writeFile(filePath, content);\n\n return {\n path: filename,\n sha256: computeSha256(content),\n bytes: content.length,\n };\n}\n\n/**\n * Read a patch file.\n */\nexport async function readPatchFile(\n snapshotId: string,\n type: \"staged\" | \"unstaged\",\n cwd: string = process.cwd()\n): Promise<Buffer> {\n const filePath = type === \"staged\"\n ? getStagedPatchPath(snapshotId, cwd)\n : getUnstagedPatchPath(snapshotId, cwd);\n return await readFile(filePath);\n}\n\n// ============================================================================\n// Manifest Operations\n// ============================================================================\n\n/**\n * Read a snapshot's manifest.\n */\nexport async function readManifest(snapshotId: string, cwd: string = process.cwd()): Promise<SnapshotManifest> {\n try {\n const manifestPath = getManifestPath(snapshotId, cwd);\n const content = await readFile(manifestPath, \"utf-8\");\n return JSON.parse(content) as SnapshotManifest;\n } catch {\n return { entries: [] };\n }\n}\n\n/**\n * Write a snapshot's manifest.\n */\nexport async function writeManifest(\n snapshotId: string,\n manifest: SnapshotManifest,\n cwd: string = process.cwd()\n): Promise<void> {\n await ensureSnapshotDirs(snapshotId, cwd);\n const manifestPath = getManifestPath(snapshotId, cwd);\n await mkdir(dirname(manifestPath), { recursive: true });\n await writeFile(manifestPath, JSON.stringify(manifest, null, 2), \"utf-8\");\n}\n\n// ============================================================================\n// Blob Operations\n// ============================================================================\n\n/**\n * Write a blob file.\n * Returns the SHA256 hash used as filename.\n */\nexport async function writeBlob(\n snapshotId: string,\n content: Buffer,\n cwd: string = process.cwd()\n): Promise<string> {\n await ensureSnapshotDirs(snapshotId, cwd);\n\n const sha256 = computeSha256(content);\n const blobPath = getBlobPath(snapshotId, sha256, cwd);\n\n await writeFile(blobPath, content);\n\n return sha256;\n}\n\n/**\n * Read a blob file.\n */\nexport async function readBlob(\n snapshotId: string,\n blobSha256: string,\n cwd: string = process.cwd()\n): Promise<Buffer> {\n const blobPath = getBlobPath(snapshotId, blobSha256, cwd);\n return await readFile(blobPath);\n}\n\n/**\n * Check if a blob exists.\n */\nexport async function blobExists(\n snapshotId: string,\n blobSha256: string,\n cwd: string = process.cwd()\n): Promise<boolean> {\n try {\n const blobPath = getBlobPath(snapshotId, blobSha256, cwd);\n await stat(blobPath);\n return true;\n } catch {\n return false;\n }\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * List all snapshot IDs.\n */\nexport async function listSnapshotIds(cwd: string = process.cwd()): Promise<string[]> {\n try {\n const snapshotsDir = getSnapshotsDir(cwd);\n const entries = await readdir(snapshotsDir, { withFileTypes: true });\n return entries\n .filter((entry) => entry.isDirectory() && entry.name !== BLOBS_DIR)\n .map((entry) => entry.name);\n } catch {\n return [];\n }\n}\n\n/**\n * Create an index entry from a snapshot.\n */\nexport function createIndexEntry(snapshot: SnapshotJson): SnapshotIndexEntry {\n return {\n snapshotId: snapshot.snapshotId,\n label: snapshot.label,\n createdAt: snapshot.createdAt,\n headSha: snapshot.git.headSha,\n branch: snapshot.git.branch,\n filesChanged: snapshot.analysis.facts.stats.filesChanged,\n riskScore: snapshot.analysis.riskReport.riskScore,\n flagCount: snapshot.analysis.riskReport.flags.length,\n findingCount: snapshot.analysis.facts.findings.length,\n };\n}\n\n/**\n * Generate a timestamp string for auto-generated labels.\n */\nexport function generateTimestamp(): string {\n return new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\n/**\n * Generate an auto-restore label.\n */\nexport function generateAutoRestoreLabel(): string {\n return `auto/pre-restore/${generateTimestamp()}`;\n}\n",
82
- "/**\n * Git operations for snapshot management.\n *\n * Provides functions for generating binary patches, managing untracked files,\n * applying patches, and resetting the working tree.\n */\n\nimport { execa } from \"execa\";\nimport { readFile, stat, chmod, unlink, readdir, rmdir } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { GitCommandError } from \"../../core/errors.js\";\n\n// ============================================================================\n// Git Info Operations\n// ============================================================================\n\n/**\n * Get the current HEAD SHA (full 40-character hash).\n */\nexport async function getHeadSha(cwd: string = process.cwd()): Promise<string> {\n try {\n const result = await execa(\"git\", [\"rev-parse\", \"HEAD\"], { cwd });\n return result.stdout.trim();\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\"git rev-parse HEAD\", String((error as { stderr: unknown }).stderr));\n }\n throw error;\n }\n}\n\n/**\n * Get the current branch name.\n * Returns empty string if in detached HEAD state.\n */\nexport async function getCurrentBranch(cwd: string = process.cwd()): Promise<string> {\n try {\n const result = await execa(\"git\", [\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], { cwd });\n const branch = result.stdout.trim();\n // In detached HEAD state, git returns \"HEAD\"\n return branch === \"HEAD\" ? \"\" : branch;\n } catch {\n return \"\";\n }\n}\n\n/**\n * Check if there are any staged changes.\n */\nexport async function hasStagedChanges(cwd: string = process.cwd()): Promise<boolean> {\n try {\n const result = await execa(\"git\", [\"diff\", \"--cached\", \"--quiet\"], { cwd, reject: false });\n return result.exitCode !== 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if there are any unstaged changes.\n */\nexport async function hasUnstagedChanges(cwd: string = process.cwd()): Promise<boolean> {\n try {\n const result = await execa(\"git\", [\"diff\", \"--quiet\"], { cwd, reject: false });\n return result.exitCode !== 0;\n } catch {\n return false;\n }\n}\n\n// ============================================================================\n// Binary Patch Operations\n// ============================================================================\n\n/**\n * Generate a binary patch for staged changes.\n * Returns empty buffer if no staged changes.\n */\nexport async function getStagedPatch(cwd: string = process.cwd()): Promise<Buffer> {\n try {\n const result = await execa(\"git\", [\"diff\", \"--binary\", \"--staged\"], {\n cwd,\n maxBuffer: 100 * 1024 * 1024, // 100MB max\n });\n return Buffer.from(result.stdout, \"utf-8\");\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\"git diff --binary --staged\", String((error as { stderr: unknown }).stderr));\n }\n throw error;\n }\n}\n\n/**\n * Generate a binary patch for unstaged changes.\n * Returns empty buffer if no unstaged changes.\n */\nexport async function getUnstagedPatch(cwd: string = process.cwd()): Promise<Buffer> {\n try {\n const result = await execa(\"git\", [\"diff\", \"--binary\"], {\n cwd,\n maxBuffer: 100 * 1024 * 1024, // 100MB max\n });\n return Buffer.from(result.stdout, \"utf-8\");\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\"git diff --binary\", String((error as { stderr: unknown }).stderr));\n }\n throw error;\n }\n}\n\n/**\n * Apply a patch file.\n * @param patchPath - Path to the patch file\n * @param options - Apply options\n * @param options.cached - Apply to index only (--cached)\n * @param options.check - Check if patch applies cleanly without applying\n */\nexport async function applyPatch(\n patchPath: string,\n options: { cached?: boolean; check?: boolean } = {},\n cwd: string = process.cwd()\n): Promise<void> {\n const args = [\"apply\"];\n\n if (options.cached) {\n args.push(\"--cached\");\n }\n\n if (options.check) {\n args.push(\"--check\");\n }\n\n args.push(patchPath);\n\n try {\n await execa(\"git\", args, { cwd });\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(`git ${args.join(\" \")}`, String((error as { stderr: unknown }).stderr));\n }\n throw error;\n }\n}\n\n/**\n * Apply a patch from buffer content.\n * Uses stdin to pass patch content.\n */\nexport async function applyPatchFromBuffer(\n patchContent: Buffer,\n options: { cached?: boolean; check?: boolean } = {},\n cwd: string = process.cwd()\n): Promise<void> {\n if (patchContent.length === 0) {\n // Empty patch, nothing to apply\n return;\n }\n\n const args = [\"apply\"];\n\n if (options.cached) {\n args.push(\"--cached\");\n }\n\n if (options.check) {\n args.push(\"--check\");\n }\n\n args.push(\"-\"); // Read from stdin\n\n try {\n await execa(\"git\", args, {\n cwd,\n input: patchContent,\n });\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(`git ${args.join(\" \")}`, String((error as { stderr: unknown }).stderr));\n }\n throw error;\n }\n}\n\n// ============================================================================\n// Untracked Files Operations\n// ============================================================================\n\n/**\n * Get list of untracked files (excluding ignored).\n * Uses null-separated output for binary-safe file names.\n */\nexport async function getUntrackedFiles(cwd: string = process.cwd()): Promise<string[]> {\n try {\n const result = await execa(\"git\", [\"ls-files\", \"--others\", \"--exclude-standard\", \"-z\"], { cwd });\n const output = result.stdout;\n if (!output) {\n return [];\n }\n // Split by null character, filter empty strings\n return output.split(\"\\0\").filter(Boolean);\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\n \"git ls-files --others --exclude-standard -z\",\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\n/**\n * Read file content from the working directory.\n */\nexport async function readWorkingFile(filePath: string, cwd: string = process.cwd()): Promise<Buffer> {\n const fullPath = join(cwd, filePath);\n return await readFile(fullPath);\n}\n\n/**\n * Get file mode (permissions).\n */\nexport async function getFileMode(filePath: string, cwd: string = process.cwd()): Promise<number> {\n const fullPath = join(cwd, filePath);\n const stats = await stat(fullPath);\n return stats.mode;\n}\n\n/**\n * Check if a file is executable.\n */\nexport async function isExecutable(filePath: string, cwd: string = process.cwd()): Promise<boolean> {\n try {\n const mode = await getFileMode(filePath, cwd);\n // Check if any execute bit is set\n return (mode & 0o111) !== 0;\n } catch {\n return false;\n }\n}\n\n// ============================================================================\n// Reset Operations\n// ============================================================================\n\n/**\n * Hard reset to HEAD.\n * This discards all staged and unstaged changes to tracked files.\n */\nexport async function resetHard(cwd: string = process.cwd()): Promise<void> {\n try {\n await execa(\"git\", [\"reset\", \"--hard\", \"HEAD\"], { cwd });\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\"git reset --hard HEAD\", String((error as { stderr: unknown }).stderr));\n }\n throw error;\n }\n}\n\n/**\n * Clean untracked files (but not ignored files).\n * This removes all untracked files from the working directory.\n * Excludes .branch-narrator directory to preserve snapshots.\n */\nexport async function cleanUntracked(cwd: string = process.cwd()): Promise<void> {\n try {\n // Use --exclude to preserve the .branch-narrator directory\n await execa(\"git\", [\"clean\", \"-fd\", \"--exclude=.branch-narrator\"], { cwd });\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\"git clean -fd --exclude=.branch-narrator\", String((error as { stderr: unknown }).stderr));\n }\n throw error;\n }\n}\n\n/**\n * Remove a specific untracked file.\n */\nexport async function removeUntrackedFile(filePath: string, cwd: string = process.cwd()): Promise<void> {\n const fullPath = join(cwd, filePath);\n try {\n await unlink(fullPath);\n\n // Try to remove empty parent directories\n let dir = dirname(fullPath);\n while (dir !== cwd && dir !== dirname(dir)) {\n try {\n const entries = await readdir(dir);\n if (entries.length === 0) {\n await rmdir(dir);\n dir = dirname(dir);\n } else {\n break;\n }\n } catch {\n break;\n }\n }\n } catch (error) {\n // Ignore if file doesn't exist\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n}\n\n// ============================================================================\n// File Restoration Operations\n// ============================================================================\n\n/**\n * Write a file to the working directory with specified mode.\n */\nexport async function writeWorkingFile(\n filePath: string,\n content: Buffer,\n mode: number,\n cwd: string = process.cwd()\n): Promise<void> {\n const { writeFile, mkdir } = await import(\"node:fs/promises\");\n const fullPath = join(cwd, filePath);\n\n // Ensure parent directory exists\n await mkdir(dirname(fullPath), { recursive: true });\n\n // Write file content\n await writeFile(fullPath, content);\n\n // Set file mode\n await chmod(fullPath, mode);\n}\n\n// ============================================================================\n// Verification Operations\n// ============================================================================\n\n/**\n * Verify that the current HEAD matches an expected SHA.\n */\nexport async function verifyHeadSha(expectedSha: string, cwd: string = process.cwd()): Promise<boolean> {\n const currentSha = await getHeadSha(cwd);\n return currentSha === expectedSha;\n}\n\n/**\n * Get the diff stat for staged changes.\n */\nexport async function getStagedStat(cwd: string = process.cwd()): Promise<string> {\n try {\n const result = await execa(\"git\", [\"diff\", \"--staged\", \"--stat\"], { cwd });\n return result.stdout;\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get the diff stat for unstaged changes.\n */\nexport async function getUnstagedStat(cwd: string = process.cwd()): Promise<string> {\n try {\n const result = await execa(\"git\", [\"diff\", \"--stat\"], { cwd });\n return result.stdout;\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get list of files changed in staged area.\n */\nexport async function getStagedFiles(cwd: string = process.cwd()): Promise<string[]> {\n try {\n const result = await execa(\"git\", [\"diff\", \"--cached\", \"--name-only\", \"-z\"], { cwd });\n if (!result.stdout) {\n return [];\n }\n return result.stdout.split(\"\\0\").filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Get list of files changed in working tree (unstaged).\n */\nexport async function getUnstagedFiles(cwd: string = process.cwd()): Promise<string[]> {\n try {\n const result = await execa(\"git\", [\"diff\", \"--name-only\", \"-z\"], { cwd });\n if (!result.stdout) {\n return [];\n }\n return result.stdout.split(\"\\0\").filter(Boolean);\n } catch {\n return [];\n }\n}\n",
83
- "/**\n * Snap save command implementation.\n *\n * Creates a new snapshot of the current workspace state including:\n * - Staged changes (binary patch)\n * - Unstaged changes (binary patch)\n * - Untracked files (as blobs)\n * - Embedded analysis (facts + risk-report)\n */\n\nimport { writeFile as fsWriteFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type {\n SnapshotJson,\n SnapshotManifest,\n SnapshotManifestEntry,\n SnapSaveOptions,\n SnapSaveResult,\n} from \"./types.js\";\nimport {\n computeSnapshotId,\n computeSha256,\n writePatchFile,\n writeManifest,\n writeBlob,\n writeSnapshotJson,\n addIndexEntry,\n createIndexEntry,\n generateTimestamp,\n UNTRACKED_DIR,\n MANIFEST_FILE,\n} from \"./storage.js\";\nimport {\n getHeadSha,\n getCurrentBranch,\n getStagedPatch,\n getUnstagedPatch,\n getUntrackedFiles,\n readWorkingFile,\n getFileMode,\n} from \"./git-ops.js\";\nimport { getVersion } from \"../../core/version.js\";\nimport { collectChangeSet } from \"../../git/collector.js\";\nimport { getProfile, detectProfileWithReasons } from \"../../profiles/index.js\";\nimport { computeRiskScore } from \"../../render/risk-score.js\";\nimport { buildFacts } from \"../facts/builder.js\";\nimport { generateRiskReport } from \"../risk/index.js\";\nimport type { ProfileName } from \"../../core/types.js\";\nimport { getRepoRoot, isWorkingDirDirty } from \"../../git/collector.js\";\nimport { runAnalyzersInParallel } from \"../../core/analyzer-runner.js\";\n\n/**\n * Execute the snap save command.\n *\n * Creates a snapshot capturing:\n * 1. Current HEAD SHA and branch\n * 2. Binary patches for staged and unstaged changes\n * 3. Untracked files as content-addressed blobs\n * 4. Embedded analysis using mode=all\n */\nexport async function executeSnapSave(options: SnapSaveOptions = {}): Promise<SnapSaveResult> {\n const cwd = options.cwd ?? process.cwd();\n const label = options.label ?? `snapshot-${generateTimestamp()}`;\n\n // 1. Get git info\n const [headSha, branch] = await Promise.all([\n getHeadSha(cwd),\n getCurrentBranch(cwd),\n ]);\n\n // 2. Generate binary patches\n const [stagedPatchContent, unstagedPatchContent] = await Promise.all([\n getStagedPatch(cwd),\n getUnstagedPatch(cwd),\n ]);\n\n // 3. Collect untracked files\n const untrackedFilePaths = await getUntrackedFiles(cwd);\n const manifest: SnapshotManifest = { entries: [] };\n const blobContents: Map<string, Buffer> = new Map();\n\n let totalUntrackedBytes = 0;\n for (const filePath of untrackedFilePaths) {\n try {\n const content = await readWorkingFile(filePath, cwd);\n const mode = await getFileMode(filePath, cwd);\n const blobSha256 = computeSha256(content);\n\n const entry: SnapshotManifestEntry = {\n path: filePath,\n blobSha256,\n mode,\n bytes: content.length,\n };\n\n manifest.entries.push(entry);\n blobContents.set(blobSha256, content);\n totalUntrackedBytes += content.length;\n } catch {\n // Skip files that can't be read (e.g., broken symlinks)\n continue;\n }\n }\n\n // Sort manifest entries by path for determinism\n manifest.entries.sort((a, b) => a.path.localeCompare(b.path));\n\n // 4. Compute snapshot ID\n const stagedPatchSha = computeSha256(stagedPatchContent);\n const unstagedPatchSha = computeSha256(unstagedPatchContent);\n const manifestContent = JSON.stringify(manifest);\n const snapshotId = computeSnapshotId(headSha, stagedPatchSha, unstagedPatchSha, manifestContent);\n\n // 5. Run analysis using mode=all\n const changeSet = await collectChangeSet({\n mode: \"all\",\n cwd,\n includeUntracked: true,\n });\n\n // Get git metadata for facts\n const [repoRoot, isDirty] = await Promise.all([\n getRepoRoot(cwd),\n isWorkingDirDirty(cwd),\n ]);\n\n // Resolve profile\n const requestedProfile: ProfileName = \"auto\";\n const detection = detectProfileWithReasons(changeSet, cwd);\n const detectedProfile = detection.profile;\n const profile = getProfile(detectedProfile);\n\n // Run analyzers in parallel for better performance\n const findings = await runAnalyzersInParallel(profile.analyzers, changeSet);\n\n // Compute risk score\n const riskScore = computeRiskScore(findings);\n\n // Build facts output (without timestamp for determinism)\n const facts = await buildFacts({\n changeSet,\n findings,\n riskScore,\n requestedProfile,\n detectedProfile,\n profileConfidence: detection.confidence,\n profileReasons: detection.reasons,\n filters: {\n excludes: [],\n includes: [],\n redact: false,\n maxFileBytes: 1048576,\n maxDiffBytes: 5242880,\n },\n skippedFiles: [],\n warnings: [],\n noTimestamp: true, // Omit for determinism\n repoRoot,\n isDirty,\n mode: \"all\",\n });\n\n // Build risk report (without timestamp for determinism)\n const riskReport = await generateRiskReport(changeSet, {\n noTimestamp: true,\n mode: \"all\",\n cwd,\n });\n\n // 6. Get tool version\n const version = await getVersion();\n\n // 7. Build snapshot JSON\n const createdAt = new Date().toISOString();\n const snapshot: SnapshotJson = {\n schemaVersion: \"1.0\",\n snapshotId,\n label,\n createdAt,\n tool: {\n name: \"branch-narrator\",\n version,\n },\n git: {\n headSha,\n branch,\n },\n workspace: {\n patches: {\n staged: {\n path: \"staged.patch\",\n sha256: stagedPatchSha,\n bytes: stagedPatchContent.length,\n },\n unstaged: {\n path: \"unstaged.patch\",\n sha256: unstagedPatchSha,\n bytes: unstagedPatchContent.length,\n },\n },\n untracked: {\n manifestPath: `${UNTRACKED_DIR}/${MANIFEST_FILE}`,\n fileCount: manifest.entries.length,\n totalBytes: totalUntrackedBytes,\n },\n },\n analysis: {\n facts,\n riskReport,\n },\n };\n\n // 8. Write all snapshot files\n // Write patches\n await writePatchFile(snapshotId, \"staged\", stagedPatchContent, cwd);\n await writePatchFile(snapshotId, \"unstaged\", unstagedPatchContent, cwd);\n\n // Write manifest\n await writeManifest(snapshotId, manifest, cwd);\n\n // Write blobs\n for (const [, content] of blobContents) {\n await writeBlob(snapshotId, content, cwd);\n }\n\n // Write snapshot.json\n await writeSnapshotJson(snapshotId, snapshot, cwd);\n\n // 9. Update index\n const indexEntry = createIndexEntry(snapshot);\n await addIndexEntry(indexEntry, cwd);\n\n // 10. Output result\n const result: SnapSaveResult = {\n snapshotId,\n label,\n snapshotPath: `.branch-narrator/snapshots/${snapshotId}`,\n };\n\n // Write to file if requested\n if (options.out) {\n await mkdir(dirname(options.out), { recursive: true });\n await fsWriteFile(options.out, snapshotId, \"utf-8\");\n }\n\n return result;\n}\n",
84
- "/**\n * Snap list command implementation.\n *\n * Lists all snapshots with summary information.\n */\n\nimport type { SnapListOptions, SnapshotIndex } from \"./types.js\";\nimport { readIndex } from \"./storage.js\";\n\n/**\n * Execute the snap list command.\n *\n * Returns the snapshot index with all entries sorted by createdAt descending.\n */\nexport async function executeSnapList(options: SnapListOptions = {}): Promise<SnapshotIndex> {\n const cwd = options.cwd ?? process.cwd();\n \n const index = await readIndex(cwd);\n \n // Ensure sorted by createdAt descending (newest first)\n index.snapshots.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n \n return index;\n}\n\n/**\n * Render snapshot list as JSON string.\n */\nexport function renderSnapListJSON(index: SnapshotIndex, pretty: boolean = false): string {\n return pretty\n ? JSON.stringify(index, null, 2)\n : JSON.stringify(index);\n}\n",
85
- "/**\n * Snap show command implementation.\n *\n * Shows the full details of a specific snapshot.\n */\n\nimport type { SnapShowOptions, SnapshotJson } from \"./types.js\";\nimport { readSnapshotJson, snapshotExists } from \"./storage.js\";\nimport { BranchNarratorError } from \"../../core/errors.js\";\n\n/**\n * Error thrown when snapshot is not found.\n */\nexport class SnapshotNotFoundError extends BranchNarratorError {\n constructor(snapshotId: string) {\n super(`Snapshot not found: ${snapshotId}`, 1);\n this.name = \"SnapshotNotFoundError\";\n }\n}\n\n/**\n * Execute the snap show command.\n *\n * Returns the full snapshot JSON for the given ID.\n */\nexport async function executeSnapShow(\n snapshotId: string,\n options: SnapShowOptions = {}\n): Promise<SnapshotJson> {\n const cwd = options.cwd ?? process.cwd();\n\n // Check if snapshot exists\n if (!(await snapshotExists(snapshotId, cwd))) {\n throw new SnapshotNotFoundError(snapshotId);\n }\n\n return await readSnapshotJson(snapshotId, cwd);\n}\n\n/**\n * Render snapshot as JSON string.\n */\nexport function renderSnapShowJSON(snapshot: SnapshotJson, pretty: boolean = false): string {\n return pretty\n ? JSON.stringify(snapshot, null, 2)\n : JSON.stringify(snapshot);\n}\n",
86
- "/**\n * Snap diff command implementation.\n *\n * Compares two snapshots and outputs a delta showing what changed.\n */\n\nimport type {\n SnapDiffOptions,\n SnapshotDelta,\n SnapshotJson,\n FindingChange,\n FlagChange,\n} from \"./types.js\";\nimport { readSnapshotJson, readManifest, snapshotExists } from \"./storage.js\";\nimport { SnapshotNotFoundError } from \"./show.js\";\nimport type { Finding, RiskFlag } from \"../../core/types.js\";\n\n/**\n * Execute the snap diff command.\n *\n * Compares two snapshots and returns a delta with:\n * - Risk score change\n * - Findings added/removed/changed\n * - Flags added/removed/changed\n * - Files added/removed/modified\n */\nexport async function executeSnapDiff(\n fromId: string,\n toId: string,\n options: SnapDiffOptions = {}\n): Promise<SnapshotDelta> {\n const cwd = options.cwd ?? process.cwd();\n\n // Validate both snapshots exist\n if (!(await snapshotExists(fromId, cwd))) {\n throw new SnapshotNotFoundError(fromId);\n }\n if (!(await snapshotExists(toId, cwd))) {\n throw new SnapshotNotFoundError(toId);\n }\n\n // Load both snapshots\n const [fromSnapshot, toSnapshot] = await Promise.all([\n readSnapshotJson(fromId, cwd),\n readSnapshotJson(toId, cwd),\n ]);\n\n // Load manifests for file comparison\n const [fromManifest, toManifest] = await Promise.all([\n readManifest(fromId, cwd),\n readManifest(toId, cwd),\n ]);\n\n // Compute findings delta\n const findingsDelta = computeFindingsDelta(\n fromSnapshot.analysis.facts.findings,\n toSnapshot.analysis.facts.findings\n );\n\n // Compute flags delta\n const flagsDelta = computeFlagsDelta(\n fromSnapshot.analysis.riskReport.flags,\n toSnapshot.analysis.riskReport.flags\n );\n\n // Compute files delta\n const filesDelta = computeFilesDelta(fromSnapshot, toSnapshot, fromManifest.entries, toManifest.entries);\n\n // Build delta object\n const delta: SnapshotDelta = {\n schemaVersion: \"1.0\",\n from: fromId,\n to: toId,\n delta: {\n riskScore: {\n from: fromSnapshot.analysis.riskReport.riskScore,\n to: toSnapshot.analysis.riskReport.riskScore,\n delta: toSnapshot.analysis.riskReport.riskScore - fromSnapshot.analysis.riskReport.riskScore,\n },\n findings: findingsDelta,\n flags: flagsDelta,\n files: filesDelta,\n },\n summary: {\n findingsAdded: findingsDelta.added.length,\n findingsRemoved: findingsDelta.removed.length,\n findingsChanged: findingsDelta.changed.length,\n flagsAdded: flagsDelta.added.length,\n flagsRemoved: flagsDelta.removed.length,\n flagsChanged: flagsDelta.changed.length,\n filesAdded: filesDelta.added.length,\n filesRemoved: filesDelta.removed.length,\n filesModified: filesDelta.modified.length,\n },\n };\n\n return delta;\n}\n\n/**\n * Compute delta between two sets of findings.\n */\nfunction computeFindingsDelta(\n fromFindings: Finding[],\n toFindings: Finding[]\n): { added: string[]; removed: string[]; changed: FindingChange[] } {\n const fromMap = new Map<string, Finding>();\n const toMap = new Map<string, Finding>();\n\n // Build maps keyed by findingId\n for (const finding of fromFindings) {\n if (finding.findingId) {\n fromMap.set(finding.findingId, finding);\n }\n }\n for (const finding of toFindings) {\n if (finding.findingId) {\n toMap.set(finding.findingId, finding);\n }\n }\n\n const added: string[] = [];\n const removed: string[] = [];\n const changed: FindingChange[] = [];\n\n // Find removed (in from but not in to)\n for (const id of fromMap.keys()) {\n if (!toMap.has(id)) {\n removed.push(id);\n }\n }\n\n // Find added and changed\n for (const [id, toFinding] of toMap) {\n const fromFinding = fromMap.get(id);\n if (!fromFinding) {\n added.push(id);\n } else {\n // Check if finding changed (deep comparison)\n if (!deepEqual(fromFinding, toFinding)) {\n changed.push({\n findingId: id,\n before: fromFinding,\n after: toFinding,\n });\n }\n }\n }\n\n // Sort all arrays for determinism\n added.sort();\n removed.sort();\n changed.sort((a, b) => a.findingId.localeCompare(b.findingId));\n\n return { added, removed, changed };\n}\n\n/**\n * Compute delta between two sets of flags.\n */\nfunction computeFlagsDelta(\n fromFlags: RiskFlag[],\n toFlags: RiskFlag[]\n): { added: string[]; removed: string[]; changed: FlagChange[] } {\n const fromMap = new Map<string, RiskFlag>();\n const toMap = new Map<string, RiskFlag>();\n\n // Build maps keyed by flagId\n for (const flag of fromFlags) {\n if (flag.flagId) {\n fromMap.set(flag.flagId, flag);\n }\n }\n for (const flag of toFlags) {\n if (flag.flagId) {\n toMap.set(flag.flagId, flag);\n }\n }\n\n const added: string[] = [];\n const removed: string[] = [];\n const changed: FlagChange[] = [];\n\n // Find removed (in from but not in to)\n for (const id of fromMap.keys()) {\n if (!toMap.has(id)) {\n removed.push(id);\n }\n }\n\n // Find added and changed\n for (const [id, toFlag] of toMap) {\n const fromFlag = fromMap.get(id);\n if (!fromFlag) {\n added.push(id);\n } else {\n // Check if flag changed (deep comparison)\n if (!deepEqual(fromFlag, toFlag)) {\n changed.push({\n flagId: id,\n before: fromFlag,\n after: toFlag,\n });\n }\n }\n }\n\n // Sort all arrays for determinism\n added.sort();\n removed.sort();\n changed.sort((a, b) => a.flagId.localeCompare(b.flagId));\n\n return { added, removed, changed };\n}\n\n/**\n * Compute delta between files in two snapshots.\n */\nfunction computeFilesDelta(\n fromSnapshot: SnapshotJson,\n toSnapshot: SnapshotJson,\n fromManifestEntries: Array<{ path: string; blobSha256: string }>,\n toManifestEntries: Array<{ path: string; blobSha256: string }>\n): { added: string[]; removed: string[]; modified: string[] } {\n // Collect all files from both snapshots\n const fromFiles = new Set<string>();\n const toFiles = new Set<string>();\n const fromHashes = new Map<string, string>();\n const toHashes = new Map<string, string>();\n\n // Add files from facts.changeset.files\n const fromChangeset = fromSnapshot.analysis.facts.changeset;\n const toChangeset = toSnapshot.analysis.facts.changeset;\n\n for (const file of fromChangeset.files.added) {\n fromFiles.add(file);\n fromHashes.set(file, \"added\");\n }\n for (const file of fromChangeset.files.modified) {\n fromFiles.add(file);\n fromHashes.set(file, \"modified\");\n }\n for (const file of fromChangeset.files.deleted) {\n fromFiles.add(file);\n fromHashes.set(file, \"deleted\");\n }\n for (const { from, to } of fromChangeset.files.renamed) {\n fromFiles.add(from);\n fromFiles.add(to);\n fromHashes.set(from, `renamed:${to}`);\n }\n\n for (const file of toChangeset.files.added) {\n toFiles.add(file);\n toHashes.set(file, \"added\");\n }\n for (const file of toChangeset.files.modified) {\n toFiles.add(file);\n toHashes.set(file, \"modified\");\n }\n for (const file of toChangeset.files.deleted) {\n toFiles.add(file);\n toHashes.set(file, \"deleted\");\n }\n for (const { from, to } of toChangeset.files.renamed) {\n toFiles.add(from);\n toFiles.add(to);\n toHashes.set(from, `renamed:${to}`);\n }\n\n // Add untracked files from manifests\n for (const entry of fromManifestEntries) {\n fromFiles.add(entry.path);\n fromHashes.set(entry.path, entry.blobSha256);\n }\n for (const entry of toManifestEntries) {\n toFiles.add(entry.path);\n toHashes.set(entry.path, entry.blobSha256);\n }\n\n const added: string[] = [];\n const removed: string[] = [];\n const modified: string[] = [];\n\n // Find removed (in from but not in to)\n for (const file of fromFiles) {\n if (!toFiles.has(file)) {\n removed.push(file);\n }\n }\n\n // Find added and modified\n for (const file of toFiles) {\n if (!fromFiles.has(file)) {\n added.push(file);\n } else {\n // Check if file changed\n const fromHash = fromHashes.get(file);\n const toHash = toHashes.get(file);\n if (fromHash !== toHash) {\n modified.push(file);\n }\n }\n }\n\n // Sort all arrays for determinism\n added.sort();\n removed.sort();\n modified.sort();\n\n return { added, removed, modified };\n}\n\n/**\n * Deep equality comparison for objects.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null) return false;\n if (typeof a !== \"object\" || typeof b !== \"object\") return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n if (Array.isArray(a) || Array.isArray(b)) return false;\n\n const aKeys = Object.keys(a as object).sort();\n const bKeys = Object.keys(b as object).sort();\n\n if (aKeys.length !== bKeys.length) return false;\n if (!aKeys.every((key, i) => key === bKeys[i])) return false;\n\n for (const key of aKeys) {\n if (!deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Render snapshot delta as JSON string.\n */\nexport function renderSnapDiffJSON(delta: SnapshotDelta, pretty: boolean = false): string {\n return pretty\n ? JSON.stringify(delta, null, 2)\n : JSON.stringify(delta);\n}\n",
87
- "/**\n * Snap restore command implementation.\n *\n * Restores the workspace to match a snapshot exactly.\n * Always creates an automatic pre-restore backup snapshot first.\n */\n\nimport type { SnapRestoreOptions, SnapRestoreResult } from \"./types.js\";\nimport {\n readSnapshotJson,\n readManifest,\n readPatchFile,\n readBlob,\n snapshotExists,\n generateAutoRestoreLabel,\n computeSha256,\n} from \"./storage.js\";\nimport {\n getHeadSha,\n resetHard,\n cleanUntracked,\n applyPatchFromBuffer,\n writeWorkingFile,\n getStagedPatch,\n getUnstagedPatch,\n} from \"./git-ops.js\";\nimport { executeSnapSave } from \"./save.js\";\nimport { SnapshotNotFoundError } from \"./show.js\";\nimport { BranchNarratorError } from \"../../core/errors.js\";\n\n/**\n * Error thrown when HEAD SHA doesn't match snapshot.\n */\nexport class HeadMismatchError extends BranchNarratorError {\n constructor(expected: string, actual: string) {\n super(\n `HEAD mismatch: snapshot was created at ${expected.slice(0, 8)} but current HEAD is ${actual.slice(0, 8)}. ` +\n `Snapshots can only be restored when HEAD matches the original commit.`,\n 1\n );\n this.name = \"HeadMismatchError\";\n }\n}\n\n/**\n * Error thrown when patch application fails.\n */\nexport class PatchApplicationError extends BranchNarratorError {\n constructor(patchType: \"staged\" | \"unstaged\", message: string) {\n super(`Failed to apply ${patchType} patch: ${message}`, 1);\n this.name = \"PatchApplicationError\";\n }\n}\n\n/**\n * Error thrown when restore verification fails.\n */\nexport class RestoreVerificationError extends BranchNarratorError {\n constructor(message: string) {\n super(`Restore verification failed: ${message}`, 1);\n this.name = \"RestoreVerificationError\";\n }\n}\n\n/**\n * Execute the snap restore command.\n *\n * Restores the workspace to match a snapshot:\n * 1. Verify HEAD SHA matches\n * 2. Create auto pre-restore backup\n * 3. Reset tracked files to HEAD\n * 4. Clean untracked files\n * 5. Apply staged patch\n * 6. Apply unstaged patch\n * 7. Restore untracked files from blobs\n * 8. Verify restore succeeded\n */\nexport async function executeSnapRestore(\n snapshotId: string,\n options: SnapRestoreOptions = {}\n): Promise<SnapRestoreResult> {\n const cwd = options.cwd ?? process.cwd();\n\n // 1. Validate snapshot exists\n if (!(await snapshotExists(snapshotId, cwd))) {\n throw new SnapshotNotFoundError(snapshotId);\n }\n\n // Load snapshot\n const snapshot = await readSnapshotJson(snapshotId, cwd);\n\n // 2. Verify HEAD SHA matches\n const currentHead = await getHeadSha(cwd);\n if (currentHead !== snapshot.git.headSha) {\n throw new HeadMismatchError(snapshot.git.headSha, currentHead);\n }\n\n // 3. Create automatic pre-restore backup snapshot\n const backupLabel = generateAutoRestoreLabel();\n const backupResult = await executeSnapSave({\n label: backupLabel,\n cwd,\n });\n\n // 4. Reset tracked files to HEAD\n await resetHard(cwd);\n\n // 5. Clean untracked files\n await cleanUntracked(cwd);\n\n // 6. Load and apply staged patch\n const stagedPatch = await readPatchFile(snapshotId, \"staged\", cwd);\n if (stagedPatch.length > 0) {\n try {\n // Apply to index (--cached)\n await applyPatchFromBuffer(stagedPatch, { cached: true }, cwd);\n // Apply to working tree\n await applyPatchFromBuffer(stagedPatch, {}, cwd);\n } catch (error) {\n throw new PatchApplicationError(\n \"staged\",\n error instanceof Error ? error.message : String(error)\n );\n }\n }\n\n // 7. Load and apply unstaged patch\n const unstagedPatch = await readPatchFile(snapshotId, \"unstaged\", cwd);\n if (unstagedPatch.length > 0) {\n try {\n // Apply to working tree only\n await applyPatchFromBuffer(unstagedPatch, {}, cwd);\n } catch (error) {\n throw new PatchApplicationError(\n \"unstaged\",\n error instanceof Error ? error.message : String(error)\n );\n }\n }\n\n // 8. Restore untracked files from blobs\n const manifest = await readManifest(snapshotId, cwd);\n for (const entry of manifest.entries) {\n const content = await readBlob(snapshotId, entry.blobSha256, cwd);\n await writeWorkingFile(entry.path, content, entry.mode, cwd);\n }\n\n // 9. Verify restore by comparing patch hashes\n const verified = await verifyRestore(snapshot, cwd);\n\n return {\n snapshotId,\n backupSnapshotId: backupResult.snapshotId,\n success: true,\n verified,\n };\n}\n\n/**\n * Verify that the restore succeeded by comparing patch hashes.\n */\nasync function verifyRestore(\n snapshot: { workspace: { patches: { staged: { sha256: string }; unstaged: { sha256: string } } } },\n cwd: string\n): Promise<boolean> {\n try {\n // Get current patches\n const [currentStagedPatch, currentUnstagedPatch] = await Promise.all([\n getStagedPatch(cwd),\n getUnstagedPatch(cwd),\n ]);\n\n // Compare hashes\n const currentStagedSha = computeSha256(currentStagedPatch);\n const currentUnstagedSha = computeSha256(currentUnstagedPatch);\n\n const stagedMatch = currentStagedSha === snapshot.workspace.patches.staged.sha256;\n const unstagedMatch = currentUnstagedSha === snapshot.workspace.patches.unstaged.sha256;\n\n return stagedMatch && unstagedMatch;\n } catch {\n return false;\n }\n}\n",
88
- "/**\n * Snap command module - local workspace snapshots.\n *\n * Provides commands for creating, listing, comparing, and restoring\n * snapshots of uncommitted work.\n */\n\n// Export all types\nexport * from \"./types.js\";\n\n// Export storage utilities\nexport {\n getSnapshotsDir,\n getSnapshotDir,\n snapshotExists,\n readIndex,\n readSnapshotJson,\n computeSnapshotId,\n} from \"./storage.js\";\n\n// Export git operations\nexport {\n getHeadSha,\n getCurrentBranch,\n getStagedPatch,\n getUnstagedPatch,\n getUntrackedFiles,\n} from \"./git-ops.js\";\n\n// Export command implementations\nexport { executeSnapSave } from \"./save.js\";\nexport { executeSnapList, renderSnapListJSON } from \"./list.js\";\nexport { executeSnapShow, renderSnapShowJSON, SnapshotNotFoundError } from \"./show.js\";\nexport { executeSnapDiff, renderSnapDiffJSON } from \"./diff.js\";\nexport { executeSnapRestore, HeadMismatchError, PatchApplicationError, RestoreVerificationError } from \"./restore.js\";\n",
89
- "#!/usr/bin/env node\n/**\n * branch-narrator CLI entry point.\n */\n\nimport { Command } from \"commander\";\nimport { createInterface } from \"readline\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { BranchNarratorError } from \"./core/errors.js\";\nimport { getVersion } from \"./core/version.js\";\nimport type { DiffMode, Finding, ProfileName, RenderContext } from \"./core/types.js\";\nimport { runAnalyzersInParallel } from \"./core/analyzer-runner.js\";\nimport { executeDumpDiff } from \"./commands/dump-diff/index.js\";\nimport { collectChangeSet, getDefaultBranch } from \"./git/collector.js\";\nimport { getProfile, resolveProfileName, detectProfileWithReasons } from \"./profiles/index.js\";\nimport { renderMarkdown, renderTerminal } from \"./render/index.js\";\nimport { computeRiskScore } from \"./render/risk-score.js\";\nimport { configureLogger, error as logError, warn, info } from \"./core/logger.js\";\n\nconst program = new Command();\n\n// Load version from package.json\nconst version = await getVersion();\n\nprogram\n .name(\"branch-narrator\")\n .description(\n \"A local-first CLI that reads git diff and generates structured PR descriptions\"\n )\n .version(version)\n .option(\"--quiet\", \"Suppress all non-fatal diagnostic output (warnings, info)\")\n .option(\"--debug\", \"Show debug diagnostics on stderr\")\n .hook(\"preAction\", (thisCommand) => {\n // Configure logger from global options\n const opts = thisCommand.opts();\n configureLogger({\n quiet: opts.quiet,\n debug: opts.debug,\n });\n });\n\n/**\n * Prompt user for input.\n */\nasync function prompt(question: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Resolve base/head refs for branch mode.\n * Auto-detects base branch if not provided.\n */\nasync function resolveDiffOptions(options: {\n mode: DiffMode;\n base?: string;\n head?: string;\n}): Promise<{ base?: string; head?: string }> {\n if (options.mode === \"branch\") {\n let base = options.base;\n let head = options.head;\n\n if (!base) {\n base = await getDefaultBranch();\n }\n if (!head) {\n head = \"HEAD\";\n }\n return { base, head };\n }\n\n // Warn if base/head provided with non-branch mode\n const baseProvided = options.base !== undefined;\n const headProvided = options.head !== undefined;\n if (baseProvided || headProvided) {\n warn(\n `Warning: --base and --head are ignored when --mode is \"${options.mode}\"`\n );\n }\n\n return { base: undefined, head: undefined };\n}\n\n/**\n * Run analysis with mode-based options.\n */\nasync function runAnalysisWithMode(options: {\n mode: DiffMode;\n base?: string;\n head?: string;\n profile: ProfileName;\n showSpinner?: boolean;\n}): Promise<{ findings: Finding[]; resolvedProfile: ProfileName }> {\n const spinner = options.showSpinner\n ? ora({\n text: \"Collecting git changes...\",\n color: \"cyan\",\n }).start()\n : null;\n\n // Collect git data using mode-based options\n const changeSet = await collectChangeSet({\n mode: options.mode,\n base: options.base,\n head: options.head,\n includeUntracked: options.mode === \"all\" || options.mode === \"unstaged\",\n });\n\n if (spinner) {\n spinner.text = \"Resolving profile...\";\n }\n\n // Resolve profile\n const resolvedProfile = resolveProfileName(\n options.profile,\n changeSet,\n process.cwd()\n );\n const profile = getProfile(resolvedProfile);\n\n if (spinner) {\n spinner.text = `Running analyzers (${profile.analyzers.length})...`;\n }\n\n // Run analyzers in parallel for better performance\n const findings = await runAnalyzersInParallel(profile.analyzers, changeSet);\n\n if (spinner) {\n spinner.succeed(\n chalk.green(`Analysis complete (${findings.length} findings)`)\n );\n }\n\n return { findings, resolvedProfile };\n}\n\n// pretty command - colorized terminal output for humans\nprogram\n .command(\"pretty\")\n .description(\"Display a colorized summary of changes (for humans)\")\n .option(\n \"--mode <type>\",\n \"Diff mode: branch|unstaged|staged|all\",\n \"unstaged\"\n )\n .option(\"--base <ref>\", \"Base branch to compare against (branch mode; auto-detected if omitted)\")\n .option(\"--head <ref>\", \"Head branch (branch mode; defaults to HEAD)\")\n .option(\n \"--profile <name>\",\n \"Profile to use (auto|sveltekit|react|stencil|next)\",\n \"auto\"\n )\n .action(async (options) => {\n try {\n // Validate mode\n const mode = options.mode as DiffMode;\n if (![\"branch\", \"unstaged\", \"staged\", \"all\"].includes(mode)) {\n logError(`Invalid mode: ${options.mode}. Use branch, unstaged, staged, or all.`);\n process.exit(1);\n }\n\n const { base, head } = await resolveDiffOptions({\n mode,\n base: options.base,\n head: options.head,\n });\n\n const { findings, resolvedProfile } = await runAnalysisWithMode({\n mode,\n base,\n head,\n profile: options.profile as ProfileName,\n showSpinner: true,\n });\n\n const riskScore = computeRiskScore(findings);\n\n const renderContext: RenderContext = {\n findings,\n riskScore,\n profile: resolvedProfile,\n };\n\n console.log(renderTerminal(renderContext));\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\n// pr-body command - raw markdown for GitHub PRs\nprogram\n .command(\"pr-body\")\n .description(\"Generate a Markdown PR description\")\n .option(\n \"--mode <type>\",\n \"Diff mode: branch|unstaged|staged|all\",\n \"unstaged\"\n )\n .option(\"--base <ref>\", \"Base branch to compare against (branch mode; auto-detected if omitted)\")\n .option(\"--head <ref>\", \"Head branch (branch mode; defaults to HEAD)\")\n .option(\"-u, --uncommitted\", \"[DEPRECATED] Use --mode unstaged instead\", false)\n .option(\n \"--profile <name>\",\n \"Profile to use (auto|sveltekit|react|stencil|next)\",\n \"auto\"\n )\n .option(\"--interactive\", \"Prompt for additional context\", false)\n .action(async (options) => {\n try {\n // Handle deprecated --uncommitted flag\n let mode = options.mode as DiffMode;\n if (options.uncommitted) {\n warn(\"Warning: --uncommitted is deprecated. Use --mode unstaged instead.\");\n mode = \"unstaged\";\n }\n\n // Validate mode\n if (![\"branch\", \"unstaged\", \"staged\", \"all\"].includes(mode)) {\n logError(`Invalid mode: ${options.mode}. Use branch, unstaged, staged, or all.`);\n process.exit(1);\n }\n\n const { base, head } = await resolveDiffOptions({\n mode,\n base: options.base,\n head: options.head,\n });\n\n const { findings, resolvedProfile } = await runAnalysisWithMode({\n mode,\n base,\n head,\n profile: options.profile as ProfileName,\n showSpinner: false,\n });\n\n const riskScore = computeRiskScore(findings);\n\n let interactive: RenderContext[\"interactive\"];\n\n if (options.interactive) {\n const context = await prompt(\n \"Context/Why (1-3 sentences, press Enter to skip): \"\n );\n const testNotes = await prompt(\n \"Special manual test notes (press Enter to skip): \"\n );\n\n interactive = {\n context: context || undefined,\n testNotes: testNotes || undefined,\n };\n }\n\n const renderContext: RenderContext = {\n findings,\n riskScore,\n profile: resolvedProfile,\n interactive,\n };\n\n console.log(renderMarkdown(renderContext));\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\n// facts command - JSON output for machine consumption\nprogram\n .command(\"facts\")\n .description(\"Output structured JSON facts (agent-grade output)\")\n .option(\n \"--mode <type>\",\n \"Diff mode: branch|unstaged|staged|all\",\n \"unstaged\"\n )\n .option(\"--base <ref>\", \"Base git reference (branch mode only; auto-detected if omitted)\")\n .option(\"--head <ref>\", \"Head git reference (branch mode only; defaults to HEAD)\")\n .option(\n \"--profile <name>\",\n \"Profile to use (auto|sveltekit|react|stencil|next)\",\n \"auto\"\n )\n .option(\"--format <type>\", \"Output format: json|sarif\", \"json\")\n .option(\"--pretty\", \"Pretty-print JSON with 2-space indentation\", false)\n .option(\"--redact\", \"Redact obvious secret values in evidence excerpts\", false)\n .option(\n \"--exclude <glob>\",\n \"Additional exclusion glob (repeatable)\",\n collect,\n []\n )\n .option(\n \"--include <glob>\",\n \"Include only files matching glob (repeatable)\",\n collect,\n []\n )\n .option(\n \"--max-file-bytes <n>\",\n \"Maximum file size in bytes to analyze\",\n \"1048576\"\n )\n .option(\n \"--max-diff-bytes <n>\",\n \"Maximum diff size in bytes to analyze\",\n \"5242880\"\n )\n .option(\n \"--max-findings <n>\",\n \"Maximum number of findings to include\"\n )\n .option(\"--out <path>\", \"Write output to file instead of stdout\")\n .option(\"--no-timestamp\", \"Omit generatedAt for deterministic output\")\n .option(\"--since <path>\", \"Compare current output to a previous JSON file\")\n .option(\"--since-strict\", \"Exit with code 1 on scope/tool/schema mismatch\", false)\n .option(\"--test-parity\", \"Enable test parity checking (opt-in, may be slow on large repos)\", false)\n .action(async (options) => {\n try {\n // Import executeFacts dynamically to avoid circular dependencies\n const { executeFacts } = await import(\"./commands/facts/index.js\");\n const { getRepoRoot, isWorkingDirDirty } = await import(\"./git/collector.js\");\n const { computeFactsDelta } = await import(\"./commands/facts/delta.js\");\n\n // Validate mode\n const mode = options.mode as DiffMode;\n if (![\"branch\", \"unstaged\", \"staged\", \"all\"].includes(mode)) {\n logError(`Invalid mode: ${options.mode}. Use branch, unstaged, staged, or all.`);\n process.exit(1);\n }\n\n const { base, head } = await resolveDiffOptions({\n mode,\n base: options.base,\n head: options.head,\n });\n\n // Validate format\n if (options.format !== \"json\" && options.format !== \"sarif\") {\n logError(`Invalid format: ${options.format}. Use json or sarif.`);\n process.exit(1);\n }\n\n // Parse numeric options\n const maxFileBytes = parseInt(options.maxFileBytes, 10);\n const maxDiffBytes = parseInt(options.maxDiffBytes, 10);\n const maxFindings = options.maxFindings\n ? parseInt(options.maxFindings, 10)\n : undefined;\n\n // Collect git data using mode-based options\n const changeSet = await collectChangeSet({\n mode,\n base,\n head,\n includeUntracked: mode === \"all\" || mode === \"unstaged\",\n });\n\n // Compute git metadata once (parallel for efficiency)\n const [repoRoot, isDirty] = await Promise.all([\n getRepoRoot(),\n isWorkingDirDirty(),\n ]);\n\n // Resolve profile with detection reasons\n const requestedProfile = options.profile as ProfileName;\n let detectedProfile: ProfileName;\n let profileConfidence: \"high\" | \"medium\" | \"low\";\n let profileReasons: string[];\n\n if (requestedProfile === \"auto\") {\n const detection = detectProfileWithReasons(changeSet, process.cwd());\n detectedProfile = detection.profile;\n profileConfidence = detection.confidence;\n profileReasons = detection.reasons;\n } else {\n // User explicitly requested a profile\n detectedProfile = requestedProfile;\n profileConfidence = \"high\";\n profileReasons = [`Profile explicitly set to ${requestedProfile}`];\n }\n\n const profile = getProfile(detectedProfile);\n\n // Run analyzers in parallel for better performance\n const findings = await runAnalyzersInParallel(profile.analyzers, changeSet);\n\n // Run test parity analyzer if explicitly enabled (opt-in)\n if (options.testParity) {\n const { testParityAnalyzer } = await import(\"./analyzers/test-parity.js\");\n const testParityFindings = await testParityAnalyzer.analyze(changeSet);\n findings.push(...testParityFindings);\n }\n\n // Compute risk\n const riskScore = computeRiskScore(findings);\n\n // Build facts output\n const facts = await executeFacts({\n changeSet,\n findings,\n riskScore,\n requestedProfile,\n detectedProfile,\n profileConfidence,\n profileReasons,\n filters: {\n excludes: options.exclude,\n includes: options.include,\n redact: options.redact,\n maxFileBytes,\n maxDiffBytes,\n maxFindings,\n },\n skippedFiles: [],\n warnings: [],\n noTimestamp: options.timestamp === false,\n repoRoot,\n isDirty,\n mode,\n });\n\n // If --since is provided, compute delta instead\n let output: any;\n if (options.since) {\n const delta = await computeFactsDelta({\n sincePath: options.since,\n currentFacts: facts,\n mode,\n base: base || null,\n head: head || null,\n profile: detectedProfile,\n include: options.include,\n exclude: options.exclude,\n sinceStrict: options.sinceStrict,\n });\n output = delta;\n } else {\n output = facts;\n }\n\n // Validate format compatibility\n if (options.format === \"sarif\" && options.since) {\n throw new BranchNarratorError(\n \"The --since option cannot be used with --format sarif. Remove --since or choose a different output format.\",\n 1\n );\n }\n\n // Output JSON or SARIF\n let outputText: string;\n if (options.format === \"sarif\") {\n const { renderSarif } = await import(\"./render/sarif.js\");\n const sarif = renderSarif(output, changeSet);\n outputText = options.pretty\n ? JSON.stringify(sarif, null, 2)\n : JSON.stringify(sarif);\n } else {\n outputText = options.pretty\n ? JSON.stringify(output, null, 2)\n : JSON.stringify(output);\n }\n\n // Write to file or stdout\n if (options.out) {\n const { writeFile, mkdir } = await import(\"node:fs/promises\");\n const { dirname } = await import(\"node:path\");\n await mkdir(dirname(options.out), { recursive: true });\n await writeFile(options.out, outputText, \"utf-8\");\n info(`Facts written to ${options.out}`);\n } else {\n console.log(outputText);\n }\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\n// Helper to collect repeatable options into an array\nfunction collect(value: string, previous: string[]): string[] {\n return previous.concat([value]);\n}\n\n// dump-diff command - prompt-ready git diff for AI agents\nprogram\n .command(\"dump-diff\")\n .description(\"Output prompt-ready git diff with smart exclusions (for AI agents)\")\n .option(\n \"--mode <type>\",\n \"Diff mode: branch|unstaged|staged|all\",\n \"unstaged\"\n )\n .option(\"--base <ref>\", \"Base git reference (branch mode only; auto-detected if omitted)\")\n .option(\"--head <ref>\", \"Head git reference (branch mode only; defaults to HEAD)\")\n .option(\"--no-untracked\", \"Exclude untracked files (non-branch modes)\")\n .option(\"--out <path>\", \"Write output to file (creates directories as needed)\")\n .option(\n \"--format <type>\",\n \"Output format: text|md|json\",\n \"text\"\n )\n .option(\"--unified <n>\", \"Lines of unified context (git diff -U)\", \"0\")\n .option(\n \"--include <glob>\",\n \"Include only files matching glob (repeatable)\",\n collect,\n []\n )\n .option(\n \"--exclude <glob>\",\n \"Additional exclusion glob (repeatable)\",\n collect,\n []\n )\n .option(\"--max-chars <n>\", \"Chunk output if it exceeds this size\")\n .option(\n \"--chunk-dir <path>\",\n \"Directory for chunk files\",\n \".ai/diff-chunks\"\n )\n .option(\"--name <prefix>\", \"Chunk file name prefix\", \"diff\")\n .option(\"--dry-run\", \"Preview what would be included/excluded\", false)\n .option(\"--name-only\", \"Output only file list (no diffs)\", false)\n .option(\"--stat\", \"Output file statistics (additions/deletions)\", false)\n .option(\"--patch-for <path>\", \"Output diff for a specific file only\")\n .option(\"--pretty\", \"Pretty-print JSON with 2-space indentation\", false)\n .option(\"--no-timestamp\", \"Omit generatedAt for deterministic output\", false)\n .action(async (options) => {\n try {\n // Validate mode\n const mode = options.mode as \"branch\" | \"unstaged\" | \"staged\" | \"all\";\n if (![\"branch\", \"unstaged\", \"staged\", \"all\"].includes(mode)) {\n logError(`Invalid mode: ${options.mode}. Use branch, unstaged, staged, or all.`);\n process.exit(1);\n }\n\n const { base, head } = await resolveDiffOptions({\n mode,\n base: options.base,\n head: options.head,\n });\n\n const format = options.format as \"text\" | \"md\" | \"json\";\n if (![\"text\", \"md\", \"json\"].includes(format)) {\n logError(`Invalid format: ${options.format}. Use text, md, or json.`);\n process.exit(1);\n }\n\n const unified = parseInt(options.unified, 10);\n if (isNaN(unified) || unified < 0) {\n logError(`Invalid unified context: ${options.unified}. Must be a non-negative integer.`);\n process.exit(1);\n }\n\n const maxChars = options.maxChars\n ? parseInt(options.maxChars, 10)\n : undefined;\n if (maxChars !== undefined && (isNaN(maxChars) || maxChars <= 0)) {\n logError(`Invalid max-chars: ${options.maxChars}. Must be a positive integer.`);\n process.exit(1);\n }\n\n // Validate mutual exclusivity of --name-only, --stat, and --patch-for\n const nameOnly = options.nameOnly === true;\n const stat = options.stat === true;\n const patchFor = options.patchFor !== undefined;\n\n const exclusiveCount = [nameOnly, stat, patchFor].filter(Boolean).length;\n if (exclusiveCount > 1) {\n logError(\n \"Options --name-only, --stat, and --patch-for are mutually exclusive. \" +\n \"Use only one at a time.\"\n );\n process.exit(1);\n }\n\n await executeDumpDiff({\n mode,\n base,\n head,\n out: options.out,\n format,\n unified,\n include: options.include,\n exclude: options.exclude,\n maxChars,\n chunkDir: options.chunkDir,\n name: options.name,\n dryRun: options.dryRun,\n includeUntracked: options.untracked !== false, // default true, --no-untracked sets to false\n nameOnly,\n stat,\n patchFor: options.patchFor,\n pretty: options.pretty,\n noTimestamp: options.timestamp === false,\n });\n\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\n// risk-report command - general-purpose risk analysis\nprogram\n .command(\"risk-report\")\n .description(\"Analyze git diff and emit risk score (0-100) with evidence-backed flags\")\n .option(\n \"--mode <type>\",\n \"Diff mode: branch|unstaged|staged|all\",\n \"unstaged\"\n )\n .option(\"--base <ref>\", \"Base git reference (branch mode only; auto-detected if omitted)\")\n .option(\"--head <ref>\", \"Head git reference (branch mode only; defaults to HEAD)\")\n .option(\"--format <type>\", \"Output format: json|md|text\", \"json\")\n .option(\"--out <path>\", \"Write output to file instead of stdout\")\n .option(\"--fail-on-score <n>\", \"Exit with code 2 if risk score >= threshold\")\n .option(\"--only <categories>\", \"Only include these categories (comma-separated)\")\n .option(\"--exclude <categories>\", \"Exclude these categories (comma-separated)\")\n .option(\"--max-evidence-lines <n>\", \"Max evidence lines per flag\", \"5\")\n .option(\"--redact\", \"Redact secret values in evidence\", false)\n .option(\"--explain-score\", \"Include score breakdown in output\", false)\n .option(\"--pretty\", \"Pretty-print JSON with 2-space indentation\", false)\n .option(\"--no-timestamp\", \"Omit generatedAt for deterministic output\", false)\n .option(\"--since <path>\", \"Compare current output to a previous JSON file\")\n .option(\"--since-strict\", \"Exit with code 1 on scope/tool/schema mismatch\", false)\n .option(\"--test-parity\", \"Enable test parity checking (opt-in, may be slow on large repos)\", false)\n .action(async (options) => {\n try {\n // Import risk report command dynamically\n const { executeRiskReport, renderRiskReportJSON, renderRiskReportMarkdown, renderRiskReportText } = await import(\"./commands/risk/index.js\");\n const { computeRiskReportDelta } = await import(\"./commands/risk/delta.js\");\n\n // Validate mode\n const mode = options.mode as DiffMode;\n if (![\"branch\", \"unstaged\", \"staged\", \"all\"].includes(mode)) {\n logError(`Invalid mode: ${options.mode}. Use branch, unstaged, staged, or all.`);\n process.exit(1);\n }\n\n const { base, head } = await resolveDiffOptions({\n mode,\n base: options.base,\n head: options.head,\n });\n\n // Validate format\n const format = options.format as \"json\" | \"md\" | \"text\";\n if (![\"json\", \"md\", \"text\"].includes(format)) {\n logError(`Invalid format: ${options.format}. Use json, md, or text.`);\n process.exit(1);\n }\n\n // Parse options\n const maxEvidenceLines = parseInt(options.maxEvidenceLines, 10);\n if (isNaN(maxEvidenceLines) || maxEvidenceLines < 1) {\n logError(`Invalid max-evidence-lines: ${options.maxEvidenceLines}. Must be a positive integer.`);\n process.exit(1);\n }\n\n const failOnScore = options.failOnScore\n ? parseInt(options.failOnScore, 10)\n : undefined;\n if (failOnScore !== undefined && (isNaN(failOnScore) || failOnScore < 0 || failOnScore > 100)) {\n logError(`Invalid fail-on-score: ${options.failOnScore}. Must be 0-100.`);\n process.exit(1);\n }\n\n const only = options.only\n ? options.only.split(\",\").map((s: string) => s.trim())\n : undefined;\n const exclude = options.exclude\n ? options.exclude.split(\",\").map((s: string) => s.trim())\n : undefined;\n\n // Collect git data using mode-based options\n const changeSet = await collectChangeSet({\n mode,\n base,\n head,\n includeUntracked: mode === \"all\" || mode === \"unstaged\",\n });\n\n // Execute risk report command\n const report = await executeRiskReport(changeSet, {\n only,\n exclude,\n maxEvidenceLines,\n redact: options.redact,\n explainScore: options.explainScore,\n noTimestamp: options.timestamp === false,\n mode,\n testParity: options.testParity,\n });\n\n // If --since is provided, compute delta and force JSON format\n let output: string;\n if (options.since) {\n // Validate format - --since only supports JSON for v1\n if (format !== \"json\") {\n logError(`--since requires --format json (other formats not supported in v1)`);\n process.exit(1);\n }\n\n const delta = await computeRiskReportDelta({\n sincePath: options.since,\n currentReport: report,\n mode,\n base: base || null,\n head: head || null,\n only: only || null,\n exclude: exclude || null,\n sinceStrict: options.sinceStrict,\n });\n\n output = options.pretty\n ? JSON.stringify(delta, null, 2)\n : JSON.stringify(delta);\n } else {\n // Normal rendering without delta\n switch (format) {\n case \"json\":\n output = renderRiskReportJSON(report, options.pretty);\n break;\n case \"md\":\n output = renderRiskReportMarkdown(report);\n break;\n case \"text\":\n output = renderRiskReportText(report);\n break;\n }\n }\n\n // Write to file or stdout\n if (options.out) {\n const { writeFile, mkdir } = await import(\"node:fs/promises\");\n const { dirname } = await import(\"node:path\");\n await mkdir(dirname(options.out), { recursive: true });\n await writeFile(options.out, output, \"utf-8\");\n info(`Risk report written to ${options.out}`);\n } else {\n console.log(output);\n }\n\n // Check fail-on-score threshold (use current score regardless of delta mode)\n if (failOnScore !== undefined && report.riskScore >= failOnScore) {\n logError(`Risk score ${report.riskScore} >= threshold ${failOnScore}`);\n process.exitCode = 2;\n return;\n }\n\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\n// zoom command - targeted drill-down for findings and flags\nprogram\n .command(\"zoom\")\n .description(\"Zoom into a specific finding or flag for detailed context\")\n .option(\"--finding <id>\", \"Finding ID to zoom into\")\n .option(\"--flag <id>\", \"Flag ID to zoom into\")\n .option(\n \"--mode <type>\",\n \"Diff mode: branch|unstaged|staged|all\",\n \"unstaged\"\n )\n .option(\"--base <ref>\", \"Base git reference (branch mode only; auto-detected if omitted)\")\n .option(\"--head <ref>\", \"Head git reference (branch mode only; defaults to HEAD)\")\n .option(\n \"--profile <name>\",\n \"Profile to use (auto|sveltekit|react|stencil|next)\",\n \"auto\"\n )\n .option(\"--format <type>\", \"Output format: json|md|text\", \"md\")\n .option(\"--unified <n>\", \"Lines of unified context for patch hunks\", \"3\")\n .option(\"--no-patch\", \"Do not include patch context, only evidence\")\n .option(\"--max-evidence-lines <n>\", \"Max evidence excerpt lines to show\", \"8\")\n .option(\"--redact\", \"Redact obvious secret values in evidence excerpts\", false)\n .option(\"--out <path>\", \"Write output to file instead of stdout\")\n .option(\"--pretty\", \"Pretty-print JSON with 2-space indentation\", false)\n .option(\"--no-timestamp\", \"Omit generatedAt for deterministic output\")\n .action(async (options) => {\n try {\n // Import zoom command dynamically\n const { executeZoom } = await import(\"./commands/zoom/index.js\");\n const { renderZoomJSON, renderZoomMarkdown, renderZoomText } = await import(\"./commands/zoom/renderers.js\");\n\n // Validate mode\n const mode = options.mode as DiffMode;\n if (![\"branch\", \"unstaged\", \"staged\", \"all\"].includes(mode)) {\n logError(`Invalid mode: ${options.mode}. Use branch, unstaged, staged, or all.`);\n process.exit(1);\n }\n\n const { base, head } = await resolveDiffOptions({\n mode,\n base: options.base,\n head: options.head,\n });\n\n // Validate format\n const format = options.format as \"json\" | \"md\" | \"text\";\n if (![\"json\", \"md\", \"text\"].includes(format)) {\n logError(`Invalid format: ${options.format}. Use json, md, or text.`);\n process.exit(1);\n }\n\n // Parse unified context\n const unified = parseInt(options.unified, 10);\n if (isNaN(unified) || unified < 0) {\n logError(`Invalid unified context: ${options.unified}. Must be a non-negative integer.`);\n process.exit(1);\n }\n\n // Parse max evidence lines\n const maxEvidenceLines = parseInt(options.maxEvidenceLines, 10);\n if (isNaN(maxEvidenceLines) || maxEvidenceLines < 1) {\n logError(`Invalid max-evidence-lines: ${options.maxEvidenceLines}. Must be a positive integer.`);\n process.exit(1);\n }\n\n // Collect git data using mode-based options\n const changeSet = await collectChangeSet({\n mode,\n base,\n head,\n includeUntracked: mode === \"all\" || mode === \"unstaged\",\n });\n\n // Execute zoom command\n const zoomOutput = await executeZoom(changeSet, {\n findingId: options.finding,\n flagId: options.flag,\n mode,\n base,\n head,\n profile: options.profile as ProfileName,\n includePatch: options.patch !== false,\n unified,\n maxEvidenceLines,\n redact: options.redact,\n noTimestamp: options.timestamp === false,\n });\n\n // Render output\n let output: string;\n switch (format) {\n case \"json\":\n output = renderZoomJSON(zoomOutput, options.pretty);\n break;\n case \"md\":\n output = renderZoomMarkdown(zoomOutput);\n break;\n case \"text\":\n output = renderZoomText(zoomOutput);\n break;\n }\n\n // Write to file or stdout\n if (options.out) {\n const { writeFile, mkdir } = await import(\"node:fs/promises\");\n const { dirname } = await import(\"node:path\");\n await mkdir(dirname(options.out), { recursive: true });\n await writeFile(options.out, output, \"utf-8\");\n info(`Zoom output written to ${options.out}`);\n } else {\n console.log(output);\n }\n\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\n// integrate command - generate provider rules (Cursor, Jules, etc.)\nprogram\n .command(\"integrate [target]\")\n .description(\"Generate provider-specific rules (auto-detects when omitted)\")\n .option(\"--dry-run\", \"Preview what would be written without creating files\", false)\n .option(\"--force\", \"Overwrite existing files\", false)\n .action(async (target, options) => {\n try {\n const { executeIntegrate } = await import(\"./commands/integrate.js\");\n\n await executeIntegrate({\n target: target,\n dryRun: options.dryRun,\n force: options.force,\n });\n\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\n// snap command - local workspace snapshots for agent iteration\nconst snap = program\n .command(\"snap\")\n .description(\"Manage local workspace snapshots for agent iteration\");\n\nsnap\n .command(\"save [label]\")\n .description(\"Create a new snapshot of current workspace state\")\n .option(\"--out <path>\", \"Write snapshotId to file instead of stdout\")\n .action(async (label: string | undefined, options: { out?: string }) => {\n try {\n const { executeSnapSave } = await import(\"./commands/snap/index.js\");\n const result = await executeSnapSave({\n label,\n out: options.out,\n });\n\n // Print snapshotId to stdout (unless --out is used)\n if (!options.out) {\n console.log(result.snapshotId);\n } else {\n info(`Snapshot ${result.snapshotId} saved to ${options.out}`);\n }\n\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\nsnap\n .command(\"list\")\n .description(\"List all snapshots\")\n .option(\"--pretty\", \"Pretty-print JSON with 2-space indentation\", false)\n .action(async (options: { pretty: boolean }) => {\n try {\n const { executeSnapList, renderSnapListJSON } = await import(\"./commands/snap/index.js\");\n const index = await executeSnapList();\n console.log(renderSnapListJSON(index, options.pretty));\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\nsnap\n .command(\"show <snapshotId>\")\n .description(\"Show snapshot details\")\n .option(\"--pretty\", \"Pretty-print JSON with 2-space indentation\", false)\n .action(async (snapshotId: string, options: { pretty: boolean }) => {\n try {\n const { executeSnapShow, renderSnapShowJSON } = await import(\"./commands/snap/index.js\");\n const snapshot = await executeSnapShow(snapshotId);\n console.log(renderSnapShowJSON(snapshot, options.pretty));\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\nsnap\n .command(\"diff <idA> <idB>\")\n .description(\"Compare two snapshots\")\n .option(\"--pretty\", \"Pretty-print JSON with 2-space indentation\", false)\n .action(async (idA: string, idB: string, options: { pretty: boolean }) => {\n try {\n const { executeSnapDiff, renderSnapDiffJSON } = await import(\"./commands/snap/index.js\");\n const delta = await executeSnapDiff(idA, idB);\n console.log(renderSnapDiffJSON(delta, options.pretty));\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\nsnap\n .command(\"restore <snapshotId>\")\n .description(\"Restore workspace to snapshot state (creates automatic backup first)\")\n .action(async (snapshotId: string) => {\n try {\n const { executeSnapRestore } = await import(\"./commands/snap/index.js\");\n const result = await executeSnapRestore(snapshotId);\n\n info(`Restored to snapshot ${result.snapshotId}`);\n info(`Pre-restore backup: ${result.backupSnapshotId}`);\n\n if (result.verified) {\n info(\"Verification: passed\");\n } else {\n warn(\"Verification: patch hashes differ (this may be expected for empty patches)\");\n }\n\n return;\n } catch (error) {\n handleError(error);\n }\n });\n\n/**\n * Handle errors and exit with appropriate code.\n */\nfunction handleError(error: unknown): never {\n if (error instanceof BranchNarratorError) {\n logError(`Error: ${error.message}`);\n process.exit(error.exitCode);\n }\n\n if (error instanceof Error) {\n logError(`Unexpected error: ${error.message}`);\n if (process.env.DEBUG) {\n logError(error.stack || \"\");\n }\n } else {\n logError(\"An unexpected error occurred\");\n }\n\n process.exit(1);\n}\n\nawait program.parseAsync();\n",
90
- "/**\n * dump-diff command implementation.\n */\n\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { BranchNarratorError } from \"../../core/errors.js\";\nimport { warn, info } from \"../../core/logger.js\";\nimport {\n buildDumpDiffJsonV2,\n calculateTotalChars,\n chunkByBudget,\n DEFAULT_EXCLUDES,\n filterPaths,\n limitConcurrency,\n parseDiffIntoHunks,\n renderDumpDiffJson,\n renderMarkdown,\n renderText,\n splitFullDiff,\n type DiffFile,\n type DiffFileEntry,\n type DiffMode,\n type FileEntry,\n type SkippedEntry,\n type SkippedFile,\n} from \"./core.js\";\nimport {\n getFileDiff,\n getFullDiff,\n getNameStatusList,\n getNumStats,\n getUntrackedFileDiff,\n getUntrackedFiles,\n isBinaryFile,\n isUntrackedBinaryFile,\n} from \"./git.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DumpDiffOptions {\n mode: DiffMode;\n base?: string;\n head?: string;\n out?: string;\n format: \"text\" | \"md\" | \"json\";\n unified: number;\n include: string[];\n exclude: string[];\n maxChars?: number;\n chunkDir: string;\n name: string;\n dryRun: boolean;\n includeUntracked: boolean;\n cwd?: string;\n nameOnly?: boolean;\n stat?: boolean;\n patchFor?: string;\n pretty?: boolean;\n noTimestamp?: boolean;\n}\n\nexport interface DryRunResult {\n included: FileEntry[];\n skipped: SkippedEntry[];\n estimatedChars: number;\n wouldChunk: boolean;\n chunkCount?: number;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Maximum number of concurrent operations for untracked file processing.\n * This prevents spawning hundreds of concurrent git processes when dealing\n * with many untracked files (binary checks and diff generation).\n */\nconst UNTRACKED_CONCURRENCY_LIMIT = 8;\n\n// ============================================================================\n// Command Handler\n// ============================================================================\n\n/**\n * Execute the dump-diff command.\n */\nexport async function executeDumpDiff(options: DumpDiffOptions): Promise<void> {\n const cwd = options.cwd ?? process.cwd();\n\n // Warn if base/head provided with non-branch mode\n if (options.mode !== \"branch\") {\n const baseProvided = options.base !== \"main\";\n const headProvided = options.head !== \"HEAD\";\n if (baseProvided || headProvided) {\n warn(\n `Warning: --base and --head are ignored when --mode is \"${options.mode}\"`\n );\n }\n }\n\n // Route to specialized handlers for new modes\n if (options.patchFor) {\n await handlePatchFor(options, cwd);\n return;\n }\n\n if (options.nameOnly) {\n await handleNameOnly(options, cwd);\n return;\n }\n\n if (options.stat) {\n await handleStat(options, cwd);\n return;\n }\n\n // Default: full diff mode (original behavior)\n await handleFullDiff(options, cwd);\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Handle full diff mode (default behavior).\n */\nasync function handleFullDiff(options: DumpDiffOptions, cwd: string): Promise<void> {\n // Get file list from git\n const allFiles = await getNameStatusList({\n mode: options.mode,\n base: options.base,\n head: options.head,\n cwd,\n });\n\n // Get untracked files if requested\n let untrackedFiles: FileEntry[] = [];\n if (options.includeUntracked && options.mode !== \"branch\") {\n const untrackedPaths = await getUntrackedFiles(cwd);\n untrackedFiles = untrackedPaths.map((path) => ({\n path,\n status: \"A\" as const,\n untracked: true,\n }));\n }\n\n const combinedFiles = [...allFiles, ...untrackedFiles];\n\n if (combinedFiles.length === 0) {\n // In JSON mode, output valid JSON instead of plain text\n if (options.format === \"json\") {\n const output = buildDumpDiffJsonV2(\n {\n mode: options.mode,\n base: options.base,\n head: options.head,\n unified: options.unified,\n include: options.include,\n exclude: options.exclude,\n includeUntracked: options.includeUntracked,\n nameOnly: false,\n stat: false,\n patchFor: null,\n noTimestamp: options.noTimestamp ?? false,\n },\n [],\n [],\n 0\n );\n const json = renderDumpDiffJson(output, options.pretty);\n if (options.out) {\n await writeOutput(options.out, json);\n info(`Wrote JSON output to ${options.out}`);\n } else {\n console.log(json);\n }\n return;\n }\n\n // For non-JSON formats, output plain text\n console.log(\"No changes found.\");\n return;\n }\n\n // Filter files\n const { included, skipped } = filterPaths({\n files: combinedFiles,\n includeGlobs: options.include,\n excludeGlobs: options.exclude,\n defaultExcludes: DEFAULT_EXCLUDES,\n });\n\n // Detect binary files and move them to skipped\n const textFiles: FileEntry[] = [];\n const binarySkipped: SkippedEntry[] = [];\n\n // Batch binary detection for tracked files using numstat\n const trackedFiles = included.filter((f) => !f.untracked);\n const untrackedFilesFiltered = included.filter((f) => f.untracked);\n\n let statsMap: Map<string, import(\"./git.js\").FileStats> = new Map();\n if (trackedFiles.length > 0) {\n statsMap = await getNumStats({\n mode: options.mode,\n base: options.base,\n head: options.head,\n cwd,\n });\n }\n\n // Check tracked files against numstat results\n for (const file of trackedFiles) {\n const stats = statsMap.get(file.path);\n if (stats?.binary) {\n binarySkipped.push({ path: file.path, reason: \"binary\" });\n } else {\n textFiles.push(file);\n }\n }\n\n // Check untracked files individually with concurrency limit\n if (untrackedFilesFiltered.length > 0) {\n const untrackedBinaryChecks = untrackedFilesFiltered.map((file) => async () => {\n const isBinary = await isUntrackedBinaryFile(file.path, cwd);\n return { file, isBinary };\n });\n\n const untrackedResults = await limitConcurrency(untrackedBinaryChecks, UNTRACKED_CONCURRENCY_LIMIT);\n for (const { file, isBinary } of untrackedResults) {\n if (isBinary) {\n binarySkipped.push({ path: file.path, reason: \"binary\" });\n } else {\n textFiles.push(file);\n }\n }\n }\n\n const allSkipped = [...skipped, ...binarySkipped];\n\n // Dry run - just show what would happen\n if (options.dryRun) {\n await handleDryRun(options, textFiles, allSkipped, cwd);\n return;\n }\n\n // Fetch diffs for included files\n const rawEntries = await fetchDiffs(options, textFiles, cwd);\n\n // Move empty diffs to skipped (these are likely directories or other edge cases)\n const entries: DiffFileEntry[] = [];\n const emptyDiffSkipped: SkippedEntry[] = [];\n\n for (const entry of rawEntries) {\n if (entry.diff.trim() === \"\") {\n emptyDiffSkipped.push({ path: entry.path, reason: \"diff-empty\" });\n } else {\n entries.push(entry);\n }\n }\n\n const finalSkipped = [...allSkipped, ...emptyDiffSkipped];\n\n // Handle output based on format\n if (options.format === \"json\") {\n const totalChars = calculateTotalChars(entries);\n\n // Check if chunking would be needed\n if (options.maxChars !== undefined && totalChars > options.maxChars) {\n throw new BranchNarratorError(\n `JSON output (${totalChars.toLocaleString()} chars) exceeds --max-chars ` +\n `(${options.maxChars.toLocaleString()}). JSON format does not support chunking. ` +\n `Use --format text or --format md for chunked output, or increase --max-chars.`,\n 1\n );\n }\n\n // Convert DiffFileEntry[] to DiffFile[] with patch.text\n const files: DiffFile[] = entries.map((entry) => ({\n path: entry.path,\n oldPath: entry.oldPath,\n status: entry.status,\n untracked: entry.untracked,\n patch: { text: entry.diff },\n }));\n\n // Convert SkippedEntry[] to SkippedFile[]\n const skippedFiles: SkippedFile[] = finalSkipped.map((s) => ({\n path: s.path,\n status: s.status,\n reason: s.reason,\n note: s.note,\n }));\n\n const output = buildDumpDiffJsonV2(\n {\n mode: options.mode,\n base: options.base,\n head: options.head,\n unified: options.unified,\n include: options.include,\n exclude: options.exclude,\n includeUntracked: options.includeUntracked,\n nameOnly: false,\n stat: false,\n patchFor: null,\n noTimestamp: options.noTimestamp ?? false,\n },\n files,\n skippedFiles,\n combinedFiles.length\n );\n\n const json = renderDumpDiffJson(output, options.pretty);\n if (options.out) {\n await writeOutput(options.out, json);\n info(`Wrote JSON output to ${options.out}`);\n } else {\n console.log(json);\n }\n } else {\n await handleTextOrMdOutput(options, entries, finalSkipped, combinedFiles.length, cwd);\n }\n}\n\n/**\n * Handle --name-only mode (just list files).\n */\nasync function handleNameOnly(options: DumpDiffOptions, cwd: string): Promise<void> {\n // Get file list from git\n const allFiles = await getNameStatusList({\n mode: options.mode,\n base: options.base,\n head: options.head,\n cwd,\n });\n\n // Get untracked files if requested\n let untrackedFiles: FileEntry[] = [];\n if (options.includeUntracked && options.mode !== \"branch\") {\n const untrackedPaths = await getUntrackedFiles(cwd);\n untrackedFiles = untrackedPaths.map((path) => ({\n path,\n status: \"A\" as const,\n untracked: true,\n }));\n }\n\n const combinedFiles = [...allFiles, ...untrackedFiles];\n\n // Filter files\n const { included, skipped } = filterPaths({\n files: combinedFiles,\n includeGlobs: options.include,\n excludeGlobs: options.exclude,\n defaultExcludes: DEFAULT_EXCLUDES,\n });\n\n // Detect binary files and add to skipped\n // Batch binary detection for tracked files using numstat\n const trackedFiles = included.filter((f) => !f.untracked);\n const untrackedFilesFiltered = included.filter((f) => f.untracked);\n\n let statsMap: Map<string, import(\"./git.js\").FileStats> = new Map();\n if (trackedFiles.length > 0) {\n statsMap = await getNumStats({\n mode: options.mode,\n base: options.base,\n head: options.head,\n cwd,\n });\n }\n\n // Check tracked files against numstat results\n for (const file of trackedFiles) {\n const stats = statsMap.get(file.path);\n if (stats?.binary) {\n skipped.push({\n path: file.path,\n status: file.status,\n reason: \"binary\",\n });\n }\n }\n\n // Check untracked files individually with concurrency limit\n if (untrackedFilesFiltered.length > 0) {\n const untrackedBinaryChecks = untrackedFilesFiltered.map((file) => async () => {\n const isBinary = await isUntrackedBinaryFile(file.path, cwd);\n return { file, isBinary };\n });\n\n const untrackedResults = await limitConcurrency(untrackedBinaryChecks, UNTRACKED_CONCURRENCY_LIMIT);\n for (const { file, isBinary } of untrackedResults) {\n if (isBinary) {\n skipped.push({\n path: file.path,\n status: file.status,\n reason: \"binary\",\n });\n }\n }\n }\n\n // Filter out binary files from included list\n const nonBinaryFiles = included.filter((f) => {\n return !skipped.some((s) => s.path === f.path && s.reason === \"binary\");\n });\n\n // Sort for deterministic output\n const sortedIncluded = nonBinaryFiles.sort((a, b) => a.path.localeCompare(b.path));\n const sortedSkipped = skipped.sort((a, b) => a.path.localeCompare(b.path));\n\n // Output based on format\n if (options.format === \"json\") {\n // Convert FileEntry[] to DiffFile[] (no patch for name-only)\n const files: DiffFile[] = sortedIncluded.map((f) => ({\n path: f.path,\n oldPath: f.oldPath,\n status: f.status,\n untracked: f.untracked,\n }));\n\n // Convert SkippedEntry[] to SkippedFile[]\n const skippedFiles: SkippedFile[] = sortedSkipped.map((s) => ({\n path: s.path,\n status: s.status,\n reason: s.reason,\n note: s.note,\n }));\n\n const output = buildDumpDiffJsonV2(\n {\n mode: options.mode,\n base: options.base,\n head: options.head,\n unified: options.unified,\n include: options.include,\n exclude: options.exclude,\n includeUntracked: options.includeUntracked,\n nameOnly: true,\n stat: false,\n patchFor: null,\n noTimestamp: options.noTimestamp ?? false,\n },\n files,\n skippedFiles,\n combinedFiles.length\n );\n\n const json = renderDumpDiffJson(output, options.pretty);\n if (options.out) {\n await writeOutput(options.out, json);\n info(`Wrote JSON output to ${options.out}`);\n } else {\n console.log(json);\n }\n } else if (options.format === \"md\") {\n const lines: string[] = [];\n lines.push(\"# Changed Files\\n\");\n for (const file of sortedIncluded) {\n lines.push(`- \\`${file.path}\\``);\n }\n const output = lines.join(\"\\n\");\n if (options.out) {\n await writeOutput(options.out, output);\n info(`Wrote markdown output to ${options.out}`);\n } else {\n console.log(output);\n }\n } else {\n // text format\n const lines = sortedIncluded.map((f) => f.path);\n const output = lines.join(\"\\n\");\n if (options.out) {\n await writeOutput(options.out, output);\n info(`Wrote text output to ${options.out}`);\n } else {\n console.log(output);\n }\n }\n}\n\n/**\n * Handle --stat mode (file statistics).\n */\nasync function handleStat(options: DumpDiffOptions, cwd: string): Promise<void> {\n // Get file list from git\n const allFiles = await getNameStatusList({\n mode: options.mode,\n base: options.base,\n head: options.head,\n cwd,\n });\n\n // Get untracked files if requested\n let untrackedFiles: FileEntry[] = [];\n if (options.includeUntracked && options.mode !== \"branch\") {\n const untrackedPaths = await getUntrackedFiles(cwd);\n untrackedFiles = untrackedPaths.map((path) => ({\n path,\n status: \"A\" as const,\n untracked: true,\n }));\n }\n\n const combinedFiles = [...allFiles, ...untrackedFiles];\n\n // Get stats from git\n const statsMap = await getNumStats({\n mode: options.mode,\n base: options.base,\n head: options.head,\n cwd,\n });\n\n // Filter files\n const { included, skipped } = filterPaths({\n files: combinedFiles,\n includeGlobs: options.include,\n excludeGlobs: options.exclude,\n defaultExcludes: DEFAULT_EXCLUDES,\n });\n\n // Add binary files to skipped\n for (const file of included) {\n const stats = statsMap.get(file.path);\n if (stats?.binary) {\n skipped.push({\n path: file.path,\n status: file.status,\n reason: \"binary\",\n });\n }\n }\n\n // Build file list with stats (excluding binaries)\n const filesWithStats = included\n .filter((f) => {\n const stats = statsMap.get(f.path);\n return !stats?.binary;\n })\n .map((f) => {\n const stats = statsMap.get(f.path);\n return {\n path: f.path,\n oldPath: f.oldPath,\n status: f.status,\n stats: stats\n ? { added: stats.added, removed: stats.removed }\n : { added: 0, removed: 0 },\n };\n });\n\n // Sort for deterministic output\n const sortedFiles = filesWithStats.sort((a, b) => a.path.localeCompare(b.path));\n const sortedSkipped = skipped.sort((a, b) => a.path.localeCompare(b.path));\n\n // Output based on format\n if (options.format === \"json\") {\n // Convert to DiffFile[] with stats\n const files: DiffFile[] = sortedFiles.map((f) => ({\n path: f.path,\n oldPath: f.oldPath,\n status: f.status,\n stats: f.stats,\n }));\n\n // Convert SkippedEntry[] to SkippedFile[]\n const skippedFilesOutput: SkippedFile[] = sortedSkipped.map((s) => ({\n path: s.path,\n status: s.status,\n reason: s.reason,\n note: s.note,\n }));\n\n const output = buildDumpDiffJsonV2(\n {\n mode: options.mode,\n base: options.base,\n head: options.head,\n unified: options.unified,\n include: options.include,\n exclude: options.exclude,\n includeUntracked: options.includeUntracked,\n nameOnly: false,\n stat: true,\n patchFor: null,\n noTimestamp: options.noTimestamp ?? false,\n },\n files,\n skippedFilesOutput,\n combinedFiles.length\n );\n\n const json = renderDumpDiffJson(output, options.pretty);\n if (options.out) {\n await writeOutput(options.out, json);\n info(`Wrote JSON output to ${options.out}`);\n } else {\n console.log(json);\n }\n } else if (options.format === \"md\") {\n const lines: string[] = [];\n lines.push(\"# File Statistics\\n\");\n lines.push(\"| File | Added | Removed |\");\n lines.push(\"| ---- | -----:| -------:|\");\n for (const file of sortedFiles) {\n lines.push(\n `| \\`${file.path}\\` | ${file.stats.added} | ${file.stats.removed} |`\n );\n }\n const output = lines.join(\"\\n\");\n if (options.out) {\n await writeOutput(options.out, output);\n info(`Wrote markdown output to ${options.out}`);\n } else {\n console.log(output);\n }\n } else {\n // text format (numstat-like: added<TAB>removed<TAB>path)\n const lines = sortedFiles.map(\n (f) => `${f.stats.added}\\t${f.stats.removed}\\t${f.path}`\n );\n const output = lines.join(\"\\n\");\n if (options.out) {\n await writeOutput(options.out, output);\n info(`Wrote text output to ${options.out}`);\n } else {\n console.log(output);\n }\n }\n}\n\n/**\n * Handle --patch-for mode (single file diff).\n */\nasync function handlePatchFor(options: DumpDiffOptions, cwd: string): Promise<void> {\n if (!options.patchFor) {\n throw new BranchNarratorError(\"--patch-for requires a file path\", 1);\n }\n\n const requestedPath = options.patchFor;\n\n // Get file list from git\n const allFiles = await getNameStatusList({\n mode: options.mode,\n base: options.base,\n head: options.head,\n cwd,\n });\n\n // Get untracked files if requested\n let untrackedFiles: FileEntry[] = [];\n if (options.includeUntracked && options.mode !== \"branch\") {\n const untrackedPaths = await getUntrackedFiles(cwd);\n untrackedFiles = untrackedPaths.map((path) => ({\n path,\n status: \"A\" as const,\n untracked: true,\n }));\n }\n\n const combinedFiles = [...allFiles, ...untrackedFiles];\n\n // Find the file (support both old and new paths for renames)\n let targetFile = combinedFiles.find(\n (f) => f.path === requestedPath || f.oldPath === requestedPath\n );\n\n if (!targetFile) {\n throw new BranchNarratorError(\n `File not found in changes: ${requestedPath}. ` +\n `Run 'branch-narrator dump-diff --name-only' to see changed files.`,\n 1\n );\n }\n\n // Check if file is excluded\n const { included, skipped } = filterPaths({\n files: [targetFile],\n includeGlobs: options.include,\n excludeGlobs: options.exclude,\n defaultExcludes: DEFAULT_EXCLUDES,\n });\n\n if (included.length === 0) {\n const skipReason = skipped[0]?.reason || \"excluded\";\n throw new BranchNarratorError(\n `File is excluded: ${requestedPath} (reason: ${skipReason}). ` +\n `Use --include \"${requestedPath}\" to include it.`,\n 1\n );\n }\n\n // Check if binary\n let isBinary: boolean;\n if (targetFile.untracked) {\n isBinary = await isUntrackedBinaryFile(targetFile.path, cwd);\n } else {\n isBinary = await isBinaryFile({\n mode: options.mode,\n base: options.base,\n head: options.head,\n path: targetFile.path,\n cwd,\n });\n }\n\n if (isBinary) {\n // Still report in JSON format\n if (options.format === \"json\") {\n const skippedFiles: SkippedFile[] = [\n {\n path: targetFile.path,\n status: targetFile.status,\n reason: \"binary\",\n },\n ];\n\n const output = buildDumpDiffJsonV2(\n {\n mode: options.mode,\n base: options.base,\n head: options.head,\n unified: options.unified,\n include: options.include,\n exclude: options.exclude,\n includeUntracked: options.includeUntracked,\n nameOnly: false,\n stat: false,\n patchFor: requestedPath,\n noTimestamp: options.noTimestamp ?? false,\n },\n [],\n skippedFiles,\n 1\n );\n\n const json = renderDumpDiffJson(output, options.pretty);\n if (options.out) {\n await writeOutput(options.out, json);\n info(`Wrote JSON output to ${options.out}`);\n } else {\n console.log(json);\n }\n } else {\n throw new BranchNarratorError(\n `File is binary: ${requestedPath}`,\n 1\n );\n }\n return;\n }\n\n // Get diff for the file\n let diff: string;\n if (targetFile.untracked) {\n diff = await getUntrackedFileDiff(targetFile.path, options.unified, cwd);\n } else {\n diff = await getFileDiff({\n mode: options.mode,\n base: options.base,\n head: options.head,\n path: targetFile.path,\n oldPath: targetFile.oldPath,\n unified: options.unified,\n cwd,\n });\n }\n\n // Get stats if in JSON format\n let stats: { added: number; removed: number } | undefined;\n if (options.format === \"json\") {\n const statsMap = await getNumStats({\n mode: options.mode,\n base: options.base,\n head: options.head,\n cwd,\n });\n const fileStats = statsMap.get(targetFile.path);\n if (fileStats && !fileStats.binary) {\n stats = { added: fileStats.added, removed: fileStats.removed };\n }\n }\n\n // Output based on format\n if (options.format === \"json\") {\n const hunks = parseDiffIntoHunks(diff);\n\n // Build file with both patch.text and patch.hunks for --patch-for\n const files: DiffFile[] = [\n {\n path: targetFile.path,\n oldPath: targetFile.oldPath,\n status: targetFile.status,\n untracked: targetFile.untracked,\n stats,\n patch: { text: diff, hunks },\n },\n ];\n\n const output = buildDumpDiffJsonV2(\n {\n mode: options.mode,\n base: options.base,\n head: options.head,\n unified: options.unified,\n include: options.include,\n exclude: options.exclude,\n includeUntracked: options.includeUntracked,\n nameOnly: false,\n stat: false,\n patchFor: requestedPath,\n noTimestamp: options.noTimestamp ?? false,\n },\n files,\n [],\n 1\n );\n\n const json = renderDumpDiffJson(output, options.pretty);\n if (options.out) {\n await writeOutput(options.out, json);\n info(`Wrote JSON output to ${options.out}`);\n } else {\n console.log(json);\n }\n } else if (options.format === \"md\") {\n const lines: string[] = [];\n lines.push(`# Diff for \\`${targetFile.path}\\`\\n`);\n lines.push(\"```diff\");\n lines.push(diff);\n lines.push(\"```\");\n const output = lines.join(\"\\n\");\n if (options.out) {\n await writeOutput(options.out, output);\n info(`Wrote markdown output to ${options.out}`);\n } else {\n console.log(output);\n }\n } else {\n // text format\n if (options.out) {\n await writeOutput(options.out, diff);\n info(`Wrote text output to ${options.out}`);\n } else {\n console.log(diff);\n }\n }\n}\n\n// ============================================================================\n// Diff Fetching Helpers\n// ============================================================================\n\n/**\n * Fetch diffs for all included files.\n * Uses a single git diff call for tracked files and limits concurrency for untracked files.\n */\nasync function fetchDiffs(\n options: DumpDiffOptions,\n files: FileEntry[],\n cwd: string\n): Promise<DiffFileEntry[]> {\n const entries: DiffFileEntry[] = [];\n\n // Separate tracked and untracked files\n const trackedFiles = files.filter((f) => !f.untracked);\n const untrackedFiles = files.filter((f) => f.untracked);\n\n // Fetch all tracked files in one git diff call\n if (trackedFiles.length > 0) {\n const trackedPaths = trackedFiles.map((f) => f.path);\n \n try {\n const fullDiff = await getFullDiff({\n mode: options.mode,\n base: options.base,\n head: options.head,\n paths: trackedPaths,\n unified: options.unified,\n cwd,\n });\n\n // Split the full diff into per-file entries\n const splitEntries = splitFullDiff(fullDiff);\n\n // Create a map for quick lookup\n const splitMap = new Map<string, string>();\n for (const entry of splitEntries) {\n splitMap.set(entry.path, entry.diffText);\n // Also map by oldPath for renames\n if (entry.oldPath) {\n splitMap.set(entry.oldPath, entry.diffText);\n }\n }\n\n // Match split diffs to original files\n for (const file of trackedFiles) {\n let diff = splitMap.get(file.path);\n \n // Fallback: try per-file diff if not found in split result\n if (!diff || diff.trim() === \"\") {\n diff = await getFileDiff({\n mode: options.mode,\n base: options.base,\n head: options.head,\n path: file.path,\n oldPath: file.oldPath,\n unified: options.unified,\n cwd,\n });\n }\n\n entries.push({\n path: file.path,\n oldPath: file.oldPath,\n status: file.status,\n diff: diff || \"\",\n untracked: false,\n });\n }\n } catch (error) {\n // Fallback to per-file diffs if full diff fails\n warn(`Batch diff failed, falling back to per-file diffs: ${error instanceof Error ? error.message : String(error)}`);\n \n for (const file of trackedFiles) {\n const diff = await getFileDiff({\n mode: options.mode,\n base: options.base,\n head: options.head,\n path: file.path,\n oldPath: file.oldPath,\n unified: options.unified,\n cwd,\n });\n\n entries.push({\n path: file.path,\n oldPath: file.oldPath,\n status: file.status,\n diff,\n untracked: false,\n });\n }\n }\n }\n\n // Fetch untracked files with concurrency limit\n if (untrackedFiles.length > 0) {\n const untrackedTasks = untrackedFiles.map((file) => async () => {\n const diff = await getUntrackedFileDiff(file.path, options.unified, cwd);\n return {\n path: file.path,\n oldPath: file.oldPath,\n status: file.status,\n diff,\n untracked: true,\n };\n });\n\n const untrackedEntries = await limitConcurrency(untrackedTasks, UNTRACKED_CONCURRENCY_LIMIT);\n entries.push(...untrackedEntries);\n }\n\n return entries;\n}\n\n/**\n * Handle dry run output.\n */\nasync function handleDryRun(\n options: DumpDiffOptions,\n included: FileEntry[],\n skipped: SkippedEntry[],\n cwd: string\n): Promise<void> {\n // Estimate sizes by fetching diffs\n let estimatedChars = 0;\n\n if (included.length > 0) {\n // For tracked files, get the full diff which is faster than per-file\n const trackedPaths = included.filter((f) => !f.untracked).map((f) => f.path);\n if (trackedPaths.length > 0) {\n const fullDiff = await getFullDiff({\n mode: options.mode,\n base: options.base,\n head: options.head,\n paths: trackedPaths,\n unified: options.unified,\n cwd,\n });\n estimatedChars += fullDiff.length;\n }\n\n // For untracked files, estimate based on file count (rough estimate)\n const untrackedCount = included.filter((f) => f.untracked).length;\n if (untrackedCount > 0) {\n // Rough estimate: ~500 chars per untracked file on average\n estimatedChars += untrackedCount * 500;\n }\n }\n\n const wouldChunk =\n options.maxChars !== undefined && estimatedChars > options.maxChars;\n\n console.log(\"=== Dry Run ===\\n\");\n console.log(`Mode: ${options.mode}`);\n if (options.mode === \"branch\") {\n console.log(`Base: ${options.base}`);\n console.log(`Head: ${options.head}`);\n }\n console.log(`Format: ${options.format}`);\n console.log(`Unified context: ${options.unified} lines`);\n console.log(`Include untracked: ${options.includeUntracked}`);\n console.log(\"\");\n\n console.log(`Files included (${included.length}):`);\n for (const file of included) {\n const status = getStatusEmoji(file.status);\n const untrackedLabel = file.untracked ? \" [untracked]\" : \"\";\n console.log(` ${status} ${file.path}${untrackedLabel}`);\n }\n console.log(\"\");\n\n console.log(`Files skipped (${skipped.length}):`);\n for (const file of skipped) {\n console.log(` - ${file.path} (${file.reason})`);\n }\n console.log(\"\");\n\n console.log(`Estimated output size: ${estimatedChars.toLocaleString()} chars`);\n\n if (options.maxChars !== undefined) {\n console.log(`Max chars: ${options.maxChars.toLocaleString()}`);\n console.log(`Would chunk: ${wouldChunk ? \"yes\" : \"no\"}`);\n\n if (wouldChunk) {\n const estimatedChunks = Math.ceil(estimatedChars / options.maxChars);\n console.log(`Estimated chunks: ~${estimatedChunks}`);\n }\n }\n\n if (options.out) {\n console.log(`\\nOutput would be written to: ${options.out}`);\n } else if (wouldChunk) {\n console.log(`\\nChunks would be written to: ${options.chunkDir}/`);\n }\n}\n\n/**\n * Handle text or markdown format output.\n */\nasync function handleTextOrMdOutput(\n options: DumpDiffOptions,\n entries: DiffFileEntry[],\n _skipped: SkippedEntry[],\n _totalFiles: number,\n _cwd: string\n): Promise<void> {\n const renderOpts = {\n mode: options.mode,\n base: options.mode === \"branch\" ? options.base : null,\n head: options.mode === \"branch\" ? options.head : null,\n unified: options.unified,\n excludePatterns: [...DEFAULT_EXCLUDES, ...options.exclude],\n };\n\n const totalChars = calculateTotalChars(entries);\n const needsChunking =\n options.maxChars !== undefined && totalChars > options.maxChars;\n\n if (needsChunking) {\n // Chunk the output\n const chunks = chunkByBudget(entries, options.maxChars!);\n const ext = options.format === \"md\" ? \"md\" : \"txt\";\n\n // Create chunk directory\n await mkdir(options.chunkDir, { recursive: true });\n\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i]!;\n const chunkNum = String(i + 1).padStart(3, \"0\");\n const filename = `${options.name}-${chunkNum}.${ext}`;\n const filepath = join(options.chunkDir, filename);\n\n let content: string;\n if (options.format === \"md\") {\n // For chunked markdown, update the header to indicate chunk number\n const chunkRenderOpts = {\n ...renderOpts,\n // Append chunk info if branch mode\n base:\n options.mode === \"branch\"\n ? `${options.base} (chunk ${i + 1}/${chunks.length})`\n : null,\n };\n content = renderMarkdown(chunk, chunkRenderOpts);\n } else {\n content = renderText(chunk);\n }\n\n await writeFile(filepath, content, \"utf-8\");\n info(`Wrote chunk ${i + 1}/${chunks.length} to ${filepath}`);\n }\n\n info(\n `\\nTotal: ${chunks.length} chunks, ${entries.length} files, ${totalChars.toLocaleString()} chars`\n );\n } else {\n // Single output\n let content: string;\n if (options.format === \"md\") {\n content = renderMarkdown(entries, renderOpts);\n } else {\n content = renderText(entries);\n }\n\n if (options.out) {\n await writeOutput(options.out, content);\n info(`Wrote ${options.format} output to ${options.out}`);\n } else {\n console.log(content);\n }\n }\n}\n\n/**\n * Write output to file, creating directories as needed.\n */\nasync function writeOutput(filepath: string, content: string): Promise<void> {\n const dir = dirname(filepath);\n await mkdir(dir, { recursive: true });\n await writeFile(filepath, content, \"utf-8\");\n}\n\n/**\n * Get emoji for file status.\n */\nfunction getStatusEmoji(status: string): string {\n switch (status) {\n case \"A\":\n return \"+\";\n case \"M\":\n return \"~\";\n case \"D\":\n return \"-\";\n case \"R\":\n return \"→\";\n default:\n return \"?\";\n }\n}\n\n// Re-export types and utilities for testing\nexport {\n buildDumpDiffJsonV2,\n buildNameStatusArgs,\n buildPerFileDiffArgs,\n buildUntrackedDiffArgs,\n calculateTotalChars,\n chunkByBudget,\n DEFAULT_EXCLUDES,\n filterPaths,\n parseHunkHeader,\n parseDiffIntoHunks,\n parseLsFilesOutput,\n renderDumpDiffJson,\n renderMarkdown,\n renderText,\n} from \"./core.js\";\nexport { parseNameStatus, parseNumStats } from \"./git.js\";\nexport type {\n DiffFile,\n DiffFileEntry,\n DiffFilePatch,\n DiffHunk,\n DiffLine,\n DiffMode,\n DumpDiffJsonV2,\n FileEntry,\n FilterResult,\n SkippedEntry,\n SkippedFile,\n} from \"./core.js\";\nexport type { FileStats } from \"./git.js\";\n",
91
- "/**\n * Global logger module for CLI diagnostics and warnings.\n * \n * Ensures clean stdout/stderr separation:\n * - All diagnostic output goes to stderr\n * - Honors --quiet and --debug flags\n * - No output pollution in JSON mode\n */\n\n/**\n * Logger state.\n */\ninterface LoggerState {\n quiet: boolean;\n debug: boolean;\n}\n\nconst state: LoggerState = {\n quiet: false,\n debug: false,\n};\n\n/**\n * Configure logger with global flags.\n */\nexport function configureLogger(options: { quiet?: boolean; debug?: boolean }): void {\n // --quiet overrides --debug\n if (options.quiet) {\n state.quiet = true;\n state.debug = false;\n } else {\n state.quiet = false;\n state.debug = options.debug ?? false;\n }\n}\n\n/**\n * Get current logger configuration.\n */\nexport function getLoggerState(): Readonly<LoggerState> {\n return { ...state };\n}\n\n/**\n * Reset logger to default state (for testing).\n */\nexport function resetLogger(): void {\n state.quiet = false;\n state.debug = false;\n}\n\n/**\n * Log a warning message to stderr.\n * Suppressed by --quiet.\n */\nexport function warn(message: string): void {\n if (!state.quiet) {\n console.error(message);\n }\n}\n\n/**\n * Log an info message to stderr.\n * Suppressed by --quiet.\n */\nexport function info(message: string): void {\n if (!state.quiet) {\n console.error(message);\n }\n}\n\n/**\n * Log a debug message to stderr.\n * Only shown when --debug is enabled.\n * Suppressed by --quiet.\n */\nexport function debug(message: string): void {\n if (!state.quiet && state.debug) {\n console.error(`[DEBUG] ${message}`);\n }\n}\n\n/**\n * Log an error message to stderr.\n * Never suppressed (even with --quiet).\n */\nexport function error(message: string): void {\n console.error(message);\n}\n",
92
- "/**\n * Core pure functions and types for dump-diff command.\n */\n\nimport picomatch from \"picomatch\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type DiffStatus = \"A\" | \"M\" | \"D\" | \"R\" | \"C\" | \"T\" | \"U\" | \"?\" | \"unknown\";\n\nexport type DiffMode = \"branch\" | \"unstaged\" | \"staged\" | \"all\";\n\nexport interface FileEntry {\n path: string;\n oldPath?: string;\n status: DiffStatus;\n untracked?: boolean;\n}\n\nexport interface DiffFileEntry extends FileEntry {\n diff: string;\n}\n\nexport type SkipReason =\n | \"excluded-by-default\"\n | \"excluded-by-user\"\n | \"excluded-by-glob\"\n | \"binary\"\n | \"too-large\"\n | \"unsupported\"\n | \"not-found\"\n | \"not-included\"\n | \"diff-empty\"\n | \"patch-for-mismatch\";\n\nexport interface SkippedEntry {\n path: string;\n status?: DiffStatus;\n reason: SkipReason;\n note?: string;\n}\n\n// ============================================================================\n// JSON Schema v2.0 Types (unified agent-grade output)\n// ============================================================================\n\nexport interface DiffLine {\n kind: \"add\" | \"del\" | \"context\";\n text: string;\n}\n\nexport interface DiffHunk {\n header: string; // \"@@ -1,0 +1,10 @@\"\n oldStart?: number;\n oldLines?: number;\n newStart?: number;\n newLines?: number;\n lines: DiffLine[];\n}\n\nexport interface DiffFilePatch {\n text: string;\n hunks?: DiffHunk[];\n}\n\nexport interface DiffFile {\n path: string;\n oldPath?: string;\n status: DiffStatus;\n untracked?: boolean;\n binary?: boolean;\n stats?: { added: number; removed: number };\n patch?: DiffFilePatch;\n}\n\nexport interface SkippedFile {\n path: string;\n status?: DiffStatus;\n reason: SkipReason;\n note?: string;\n}\n\nexport interface DumpDiffJsonV2 {\n schemaVersion: \"2.0\";\n generatedAt?: string; // ISO timestamp, omitted when --no-timestamp\n command: { name: \"dump-diff\"; args: string[] };\n git: {\n mode: DiffMode;\n base: string | null;\n head: string | null;\n isDirty: boolean;\n };\n options: {\n unified: number;\n include: string[];\n exclude: string[];\n includeUntracked: boolean;\n nameOnly: boolean;\n stat: boolean;\n patchFor: string | null;\n };\n files: DiffFile[];\n skippedFiles: SkippedFile[];\n summary: {\n changedFileCount: number;\n includedFileCount: number;\n skippedFileCount: number;\n };\n}\n\nexport interface FilterResult {\n included: FileEntry[];\n skipped: SkippedEntry[];\n}\n\nexport interface FilterOptions {\n files: FileEntry[];\n includeGlobs: string[];\n excludeGlobs: string[];\n defaultExcludes: string[];\n}\n\nexport interface RenderOptions {\n mode: DiffMode;\n base: string | null | undefined;\n head: string | null | undefined;\n unified: number;\n excludePatterns: string[];\n}\n\n// ============================================================================\n// Default Exclusions\n// ============================================================================\n\nexport const DEFAULT_EXCLUDES = [\n // Lockfiles\n \"**/pnpm-lock.yaml\",\n \"**/package-lock.json\",\n \"**/yarn.lock\",\n \"**/bun.lock\",\n \"**/bun.lockb\",\n // Type declarations\n \"**/*.d.ts\",\n // Logs\n \"**/*.log\",\n \"**/*.logs\",\n // Build/cache directories\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.svelte-kit/**\",\n \"**/.next/**\",\n \"**/.turbo/**\",\n \"**/coverage/**\",\n \"**/.cache/**\",\n // Minified files\n \"**/*.min.*\",\n // Sourcemaps\n \"**/*.map\",\n];\n\n// ============================================================================\n// Git Argument Builders (Pure Functions)\n// ============================================================================\n\nexport interface NameStatusArgsOptions {\n mode: DiffMode;\n base?: string;\n head?: string;\n}\n\n/**\n * Build git diff --name-status arguments for a given mode.\n */\nexport function buildNameStatusArgs(opts: NameStatusArgsOptions): string[] {\n const args = [\"diff\", \"--name-status\", \"--find-renames\"];\n\n switch (opts.mode) {\n case \"branch\":\n args.push(`${opts.base}..${opts.head}`);\n break;\n case \"unstaged\":\n // Working tree vs index (no additional args)\n break;\n case \"staged\":\n args.push(\"--staged\");\n break;\n case \"all\":\n args.push(\"HEAD\");\n break;\n }\n\n return args;\n}\n\nexport interface PerFileDiffArgsOptions {\n mode: DiffMode;\n base?: string;\n head?: string;\n unified: number;\n path: string;\n oldPath?: string;\n}\n\n/**\n * Build git diff arguments for a single file in a given mode.\n */\nexport function buildPerFileDiffArgs(opts: PerFileDiffArgsOptions): string[] {\n const args = [\"diff\", `--unified=${opts.unified}`, \"--find-renames\"];\n\n switch (opts.mode) {\n case \"branch\":\n args.push(`${opts.base}..${opts.head}`);\n break;\n case \"unstaged\":\n // Working tree vs index (no additional args)\n break;\n case \"staged\":\n args.push(\"--staged\");\n break;\n case \"all\":\n args.push(\"HEAD\");\n break;\n }\n\n args.push(\"--\");\n\n // For renames, include both old and new paths\n if (opts.oldPath) {\n args.push(opts.oldPath);\n }\n args.push(opts.path);\n\n return args;\n}\n\n/**\n * Build git diff --no-index arguments for untracked files.\n */\nexport function buildUntrackedDiffArgs(\n path: string,\n unified: number\n): string[] {\n return [\"diff\", \"--no-index\", `--unified=${unified}`, \"--\", \"/dev/null\", path];\n}\n\n/**\n * Parse git ls-files -z output into file paths.\n * Output is null-terminated list of file paths.\n */\nexport function parseLsFilesOutput(output: string): string[] {\n if (!output) {\n return [];\n }\n\n // -z uses NUL as separator\n return output.split(\"\\0\").filter(Boolean);\n}\n\n// ============================================================================\n// Path Filtering\n// ============================================================================\n\n/**\n * Create a matcher function from glob patterns.\n */\nfunction createMatcher(patterns: string[]): (path: string) => boolean {\n if (patterns.length === 0) {\n return () => false;\n }\n const matchers = patterns.map((p) => picomatch(p, { dot: true }));\n return (path: string) => matchers.some((m) => m(path));\n}\n\n/**\n * Filter file paths based on include/exclude globs.\n *\n * Precedence:\n * 1. If include globs are provided, file must match at least one\n * 2. Exclude globs always exclude (even if included)\n * 3. Default excludes apply unless file matches an include glob\n */\nexport function filterPaths(options: FilterOptions): FilterResult {\n const { files, includeGlobs, excludeGlobs, defaultExcludes } = options;\n\n const matchInclude = createMatcher(includeGlobs);\n const matchExclude = createMatcher(excludeGlobs);\n const matchDefaultExclude = createMatcher(defaultExcludes);\n\n const hasIncludeGlobs = includeGlobs.length > 0;\n\n const included: FileEntry[] = [];\n const skipped: SkippedEntry[] = [];\n\n for (const file of files) {\n const path = file.path;\n\n // Check explicit excludes first (highest priority)\n if (matchExclude(path)) {\n skipped.push({ path, reason: \"excluded-by-glob\" });\n continue;\n }\n\n // If include globs are set, file must match one\n if (hasIncludeGlobs) {\n if (!matchInclude(path)) {\n skipped.push({ path, reason: \"not-included\" });\n continue;\n }\n // If explicitly included, skip default exclude check\n included.push(file);\n continue;\n }\n\n // No include globs - apply default excludes\n if (matchDefaultExclude(path)) {\n skipped.push({ path, reason: \"excluded-by-default\" });\n continue;\n }\n\n included.push(file);\n }\n\n // Sort included files by path for deterministic output\n included.sort((a, b) => a.path.localeCompare(b.path));\n\n return { included, skipped };\n}\n\n// ============================================================================\n// Chunking\n// ============================================================================\n\n/**\n * Split diff entries into chunks that fit within a character budget.\n * Splits at file boundaries only.\n */\nexport function chunkByBudget(\n items: DiffFileEntry[],\n maxChars: number\n): DiffFileEntry[][] {\n if (items.length === 0) {\n return [];\n }\n\n const chunks: DiffFileEntry[][] = [];\n let currentChunk: DiffFileEntry[] = [];\n let currentSize = 0;\n\n for (const item of items) {\n const itemSize = item.diff.length;\n\n // If single item exceeds budget, put it in its own chunk\n if (itemSize > maxChars) {\n if (currentChunk.length > 0) {\n chunks.push(currentChunk);\n currentChunk = [];\n currentSize = 0;\n }\n chunks.push([item]);\n continue;\n }\n\n // If adding this item would exceed budget, start new chunk\n if (currentSize + itemSize > maxChars && currentChunk.length > 0) {\n chunks.push(currentChunk);\n currentChunk = [];\n currentSize = 0;\n }\n\n currentChunk.push(item);\n currentSize += itemSize;\n }\n\n // Don't forget the last chunk\n if (currentChunk.length > 0) {\n chunks.push(currentChunk);\n }\n\n return chunks;\n}\n\n// ============================================================================\n// Renderers\n// ============================================================================\n\n/**\n * Render entries as plain unified diff text.\n */\nexport function renderText(entries: DiffFileEntry[]): string {\n return entries.map((e) => e.diff).join(\"\\n\");\n}\n\n/**\n * Get header title based on mode.\n */\nfunction getModeHeader(options: RenderOptions): string {\n switch (options.mode) {\n case \"branch\":\n return `Git Diff: ${options.base}..${options.head}`;\n case \"unstaged\":\n return \"Git Diff: Unstaged Changes (working tree vs index)\";\n case \"staged\":\n return \"Git Diff: Staged Changes (index vs HEAD)\";\n case \"all\":\n return \"Git Diff: All Changes (working tree vs HEAD)\";\n }\n}\n\n/**\n * Render entries as markdown with fenced code block.\n */\nexport function renderMarkdown(\n entries: DiffFileEntry[],\n options: RenderOptions\n): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${getModeHeader(options)}`);\n lines.push(\"\");\n lines.push(`**Mode:** ${options.mode}`);\n lines.push(`**Unified context:** ${options.unified} lines`);\n\n if (options.excludePatterns.length > 0) {\n lines.push(`**Excluded patterns:** ${options.excludePatterns.join(\", \")}`);\n }\n\n lines.push(`**Files included:** ${entries.length}`);\n lines.push(\"\");\n\n // File list\n lines.push(\"## Files\");\n lines.push(\"\");\n for (const entry of entries) {\n const statusLabel = getStatusLabel(entry.status);\n const untrackedLabel = entry.untracked ? \" [untracked]\" : \"\";\n lines.push(`- \\`${entry.path}\\` (${statusLabel}${untrackedLabel})`);\n }\n lines.push(\"\");\n\n // Diff content\n lines.push(\"## Diff\");\n lines.push(\"\");\n lines.push(\"```diff\");\n lines.push(entries.map((e) => e.diff).join(\"\\n\"));\n lines.push(\"```\");\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Get human-readable label for status.\n */\nfunction getStatusLabel(status: DiffStatus): string {\n switch (status) {\n case \"A\":\n return \"added\";\n case \"M\":\n return \"modified\";\n case \"D\":\n return \"deleted\";\n case \"R\":\n return \"renamed\";\n case \"C\":\n return \"copied\";\n case \"T\":\n return \"type-changed\";\n case \"U\":\n return \"unmerged\";\n case \"?\":\n return \"untracked\";\n case \"unknown\":\n return \"unknown\";\n default:\n return \"unknown\";\n }\n}\n\n// ============================================================================\n// Stats\n// ============================================================================\n\n/**\n * Calculate total character count of all diffs.\n */\nexport function calculateTotalChars(entries: DiffFileEntry[]): number {\n return entries.reduce((sum, e) => sum + e.diff.length, 0);\n}\n\n// ============================================================================\n// Diff Parsing (for structured JSON output)\n// ============================================================================\n\n/**\n * Parse a hunk header line like \"@@ -1,4 +2,6 @@\" into structured data.\n */\nexport function parseHunkHeader(header: string): {\n oldStart: number;\n oldLines: number;\n newStart: number;\n newLines: number;\n} | null {\n // Match: @@ -oldStart[,oldLines] +newStart[,newLines] @@\n const match = header.match(/@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/);\n if (!match) {\n return null;\n }\n\n return {\n oldStart: parseInt(match[1]!, 10),\n oldLines: match[2] ? parseInt(match[2], 10) : 1,\n newStart: parseInt(match[3]!, 10),\n newLines: match[4] ? parseInt(match[4], 10) : 1,\n };\n}\n\n/**\n * Parse a unified diff string into structured hunks.\n * This handles the diff content for a single file.\n */\nexport function parseDiffIntoHunks(diff: string): DiffHunk[] {\n if (!diff.trim()) {\n return [];\n }\n\n const lines = diff.split(\"\\n\");\n const hunks: DiffHunk[] = [];\n let currentHunk: DiffHunk | null = null;\n\n for (const line of lines) {\n // Check if this is a hunk header\n if (line.startsWith(\"@@\")) {\n // Save previous hunk if exists\n if (currentHunk) {\n hunks.push(currentHunk);\n }\n\n // Parse header\n const parsed = parseHunkHeader(line);\n currentHunk = {\n header: line,\n oldStart: parsed?.oldStart,\n oldLines: parsed?.oldLines,\n newStart: parsed?.newStart,\n newLines: parsed?.newLines,\n lines: [],\n };\n } else if (currentHunk) {\n // Skip special git diff lines (e.g., \"\\")\n if (line.startsWith(\"\\\\\")) {\n continue;\n }\n\n // Add line to current hunk\n let kind: \"add\" | \"del\" | \"context\";\n if (line.startsWith(\"+\")) {\n kind = \"add\";\n } else if (line.startsWith(\"-\")) {\n kind = \"del\";\n } else {\n kind = \"context\";\n }\n\n currentHunk.lines.push({ kind, text: line });\n }\n // Ignore lines before first hunk (file headers, etc.)\n }\n\n // Don't forget the last hunk\n if (currentHunk) {\n hunks.push(currentHunk);\n }\n\n return hunks;\n}\n\n// ============================================================================\n// JSON Builder (v2.0 unified schema)\n// ============================================================================\n\nexport interface BuildDumpDiffJsonV2Options {\n mode: DiffMode;\n base?: string;\n head?: string;\n unified: number;\n include: string[];\n exclude: string[];\n includeUntracked: boolean;\n nameOnly: boolean;\n stat: boolean;\n patchFor: string | null;\n noTimestamp: boolean;\n}\n\n/**\n * Build the command args array for JSON output metadata.\n */\nfunction buildCommandArgs(options: BuildDumpDiffJsonV2Options): string[] {\n const args: string[] = [];\n\n args.push(\"--mode\", options.mode);\n\n if (options.mode === \"branch\") {\n if (options.base) {\n args.push(\"--base\", options.base);\n }\n if (options.head) {\n args.push(\"--head\", options.head);\n }\n }\n\n args.push(\"--format\", \"json\");\n\n if (options.unified !== 0) {\n args.push(\"--unified\", String(options.unified));\n }\n\n for (const glob of options.include) {\n args.push(\"--include\", glob);\n }\n\n for (const glob of options.exclude) {\n args.push(\"--exclude\", glob);\n }\n\n if (!options.includeUntracked) {\n args.push(\"--no-untracked\");\n }\n\n if (options.nameOnly) {\n args.push(\"--name-only\");\n }\n\n if (options.stat) {\n args.push(\"--stat\");\n }\n\n if (options.patchFor) {\n args.push(\"--patch-for\", options.patchFor);\n }\n\n return args;\n}\n\n/**\n * Build unified v2.0 JSON output for dump-diff command.\n */\nexport function buildDumpDiffJsonV2(\n options: BuildDumpDiffJsonV2Options,\n files: DiffFile[],\n skippedFiles: SkippedFile[],\n changedFileCount: number\n): DumpDiffJsonV2 {\n const output: DumpDiffJsonV2 = {\n schemaVersion: \"2.0\",\n generatedAt: options.noTimestamp ? undefined : new Date().toISOString(),\n command: {\n name: \"dump-diff\",\n args: buildCommandArgs(options),\n },\n git: {\n mode: options.mode,\n base: options.mode === \"branch\" ? (options.base ?? null) : null,\n head: options.mode === \"branch\" ? (options.head ?? null) : null,\n isDirty: options.mode !== \"branch\",\n },\n options: {\n unified: options.unified,\n include: options.include,\n exclude: options.exclude,\n includeUntracked: options.includeUntracked,\n nameOnly: options.nameOnly,\n stat: options.stat,\n patchFor: options.patchFor,\n },\n files,\n skippedFiles,\n summary: {\n changedFileCount,\n includedFileCount: files.length,\n skippedFileCount: skippedFiles.length,\n },\n };\n\n // Remove undefined generatedAt for cleaner output\n if (output.generatedAt === undefined) {\n delete output.generatedAt;\n }\n\n return output;\n}\n\n/**\n * Render DumpDiffJsonV2 as JSON string.\n */\nexport function renderDumpDiffJson(output: DumpDiffJsonV2, pretty: boolean = false): string {\n return pretty ? JSON.stringify(output, null, 2) : JSON.stringify(output);\n}\n\n// ============================================================================\n// Diff Splitting Utility\n// ============================================================================\n\nexport interface SplitDiffEntry {\n path: string;\n oldPath?: string;\n diffText: string;\n}\n\n/**\n * Split a full unified diff into per-file chunks.\n * \n * Parses unified diff output from git and splits it into individual file patches.\n * Handles rename headers and correctly identifies file boundaries using \"diff --git\" markers.\n * \n * @param fullDiff - The complete unified diff output from git diff\n * @returns Array of per-file diff entries with path and diff text\n */\nexport function splitFullDiff(fullDiff: string): SplitDiffEntry[] {\n if (!fullDiff.trim()) {\n return [];\n }\n\n const entries: SplitDiffEntry[] = [];\n const lines = fullDiff.split(\"\\n\");\n \n let currentPath: string | null = null;\n let currentOldPath: string | undefined;\n let currentLines: string[] = [];\n\n const flushCurrent = () => {\n if (currentPath && currentLines.length > 0) {\n entries.push({\n path: currentPath,\n oldPath: currentOldPath,\n diffText: currentLines.join(\"\\n\"),\n });\n }\n currentPath = null;\n currentOldPath = undefined;\n currentLines = [];\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n \n // Check for new file boundary: \"diff --git a/... b/...\"\n if (line.startsWith(\"diff --git \")) {\n // Save previous file if exists\n flushCurrent();\n\n // Parse file paths from \"diff --git a/old b/new\"\n // Use greedy matching to handle paths containing \" b/\"\n const match = line.match(/^diff --git a\\/(.+) b\\/(.+)$/);\n if (match) {\n const newPath = match[2]!;\n currentPath = newPath;\n \n // Check subsequent lines for rename markers to detect oldPath\n // Look ahead for \"rename from\" line\n let j = i + 1;\n while (j < lines.length && !lines[j]!.startsWith(\"diff --git \")) {\n const nextLine = lines[j]!;\n if (nextLine.startsWith(\"rename from \")) {\n currentOldPath = nextLine.substring(\"rename from \".length);\n break;\n }\n // Stop looking once we hit the hunk headers\n if (nextLine.startsWith(\"@@\")) {\n break;\n }\n j++;\n }\n }\n currentLines.push(line);\n } else if (currentPath) {\n // Add line to current file's diff\n currentLines.push(line);\n }\n // Ignore lines before first \"diff --git\" marker\n }\n\n // Don't forget the last file\n flushCurrent();\n\n return entries;\n}\n\n// ============================================================================\n// Concurrency Limiting Utility\n// ============================================================================\n\n/**\n * Simple concurrency limiter for parallel async operations.\n * Limits the number of concurrent promises running at once.\n * \n * @param tasks - Array of task functions that return promises\n * @param limit - Maximum number of concurrent tasks (default: 4)\n * @returns Promise that resolves to array of results in original order\n */\nexport async function limitConcurrency<T>(\n tasks: (() => Promise<T>)[],\n limit: number = 4\n): Promise<T[]> {\n if (tasks.length === 0) {\n return [];\n }\n\n const results: T[] = new Array(tasks.length);\n let currentIndex = 0;\n let activeCount = 0;\n\n return new Promise((resolve, reject) => {\n const startNext = () => {\n // Check if all tasks are done\n if (currentIndex >= tasks.length && activeCount === 0) {\n resolve(results);\n return;\n }\n\n // Start new tasks up to the limit\n while (activeCount < limit && currentIndex < tasks.length) {\n const index = currentIndex++;\n const task = tasks[index]!;\n \n activeCount++;\n task()\n .then((result) => {\n results[index] = result;\n activeCount--;\n startNext();\n })\n .catch(reject);\n }\n };\n\n startNext();\n });\n}\n\n",
93
- "/**\n * Git utilities for dump-diff command.\n */\n\nimport { execa } from \"execa\";\nimport {\n GitCommandError,\n InvalidRefError,\n NotAGitRepoError,\n} from \"../../core/errors.js\";\nimport {\n buildNameStatusArgs,\n buildPerFileDiffArgs,\n buildUntrackedDiffArgs,\n parseLsFilesOutput,\n type DiffMode,\n type DiffStatus,\n type FileEntry,\n} from \"./core.js\";\n\n/**\n * Check if the current directory is inside a git repository.\n */\nexport async function isGitRepo(cwd: string = process.cwd()): Promise<boolean> {\n try {\n const result = await execa(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n cwd,\n reject: false,\n });\n return result.exitCode === 0 && result.stdout.trim() === \"true\";\n } catch {\n return false;\n }\n}\n\n/**\n * Validate that a git reference exists.\n */\nexport async function refExists(\n ref: string,\n cwd: string = process.cwd()\n): Promise<boolean> {\n try {\n const result = await execa(\"git\", [\"rev-parse\", \"--verify\", ref], {\n cwd,\n reject: false,\n });\n return result.exitCode === 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse git diff --name-status output into structured file entries.\n */\nexport function parseNameStatus(output: string): FileEntry[] {\n if (!output.trim()) {\n return [];\n }\n\n const entries: FileEntry[] = [];\n const lines = output.trim().split(\"\\n\");\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n // Format: STATUS\\tPATH or STATUS\\tOLD_PATH\\tNEW_PATH (for renames)\n const parts = line.split(\"\\t\");\n const statusChar = parts[0]?.charAt(0) as DiffStatus;\n\n if (statusChar === \"R\" && parts.length >= 3) {\n // Rename: R100\\told_path\\tnew_path\n entries.push({\n path: parts[2]!,\n oldPath: parts[1],\n status: \"R\",\n });\n } else if (parts.length >= 2) {\n entries.push({\n path: parts[1]!,\n status: statusChar,\n });\n }\n }\n\n return entries;\n}\n\nexport interface GetNameStatusListOptions {\n mode: DiffMode;\n base?: string;\n head?: string;\n cwd?: string;\n}\n\n/**\n * Get file list with status from git diff.\n */\nexport async function getNameStatusList(\n options: GetNameStatusListOptions\n): Promise<FileEntry[]> {\n const cwd = options.cwd ?? process.cwd();\n\n // Validate git repo\n if (!(await isGitRepo(cwd))) {\n throw new NotAGitRepoError(cwd);\n }\n\n // Validate refs only for branch mode\n if (options.mode === \"branch\") {\n if (!options.base || !(await refExists(options.base, cwd))) {\n throw new InvalidRefError(options.base ?? \"undefined\");\n }\n if (!options.head || !(await refExists(options.head, cwd))) {\n throw new InvalidRefError(options.head ?? \"undefined\");\n }\n }\n\n const args = buildNameStatusArgs({\n mode: options.mode,\n base: options.base,\n head: options.head,\n });\n\n try {\n const result = await execa(\"git\", args, { cwd });\n return parseNameStatus(result.stdout);\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\n `git ${args.join(\" \")}`,\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\nexport interface GetFileDiffOptions {\n mode: DiffMode;\n base?: string;\n head?: string;\n path: string;\n oldPath?: string;\n unified?: number;\n cwd?: string;\n}\n\n/**\n * Get unified diff for a single file.\n */\nexport async function getFileDiff(options: GetFileDiffOptions): Promise<string> {\n const cwd = options.cwd ?? process.cwd();\n const unified = options.unified ?? 0;\n\n const args = buildPerFileDiffArgs({\n mode: options.mode,\n base: options.base,\n head: options.head,\n unified,\n path: options.path,\n oldPath: options.oldPath,\n });\n\n try {\n const result = await execa(\"git\", args, { cwd });\n return result.stdout;\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\n `git ${args.join(\" \")}`,\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\nexport interface IsBinaryFileOptions {\n mode: DiffMode;\n base?: string;\n head?: string;\n path: string;\n cwd?: string;\n}\n\n/**\n * Check if a file is binary using git diff --numstat.\n * Binary files show \"-\" for additions/deletions.\n */\nexport async function isBinaryFile(options: IsBinaryFileOptions): Promise<boolean> {\n const cwd = options.cwd ?? process.cwd();\n\n // Build args similar to name-status but with --numstat\n const args = [\"diff\", \"--numstat\", \"--find-renames\"];\n\n switch (options.mode) {\n case \"branch\":\n args.push(`${options.base}..${options.head}`);\n break;\n case \"unstaged\":\n break;\n case \"staged\":\n args.push(\"--staged\");\n break;\n case \"all\":\n args.push(\"HEAD\");\n break;\n }\n\n args.push(\"--\", options.path);\n\n try {\n const result = await execa(\"git\", args, { cwd, reject: false });\n\n // Binary files show: -\\t-\\tfilename\n const line = result.stdout.trim();\n if (!line) return false;\n\n const parts = line.split(\"\\t\");\n return parts[0] === \"-\" && parts[1] === \"-\";\n } catch {\n return false;\n }\n}\n\n/**\n * Get list of untracked files (files only, not directories).\n * Uses git ls-files which only returns file paths, avoiding the\n * directory issue with git status --porcelain.\n */\nexport async function getUntrackedFiles(\n cwd: string = process.cwd()\n): Promise<string[]> {\n try {\n const result = await execa(\n \"git\",\n [\"ls-files\", \"--others\", \"--exclude-standard\", \"-z\"],\n { cwd }\n );\n return parseLsFilesOutput(result.stdout);\n } catch {\n return [];\n }\n}\n\n/**\n * Get diff for an untracked file using --no-index.\n */\nexport async function getUntrackedFileDiff(\n path: string,\n unified: number = 0,\n cwd: string = process.cwd()\n): Promise<string> {\n const args = buildUntrackedDiffArgs(path, unified);\n\n try {\n // git diff --no-index returns exit code 1 when there are differences\n const result = await execa(\"git\", args, { cwd, reject: false });\n return result.stdout;\n } catch {\n return \"\";\n }\n}\n\n/**\n * Check if an untracked file is binary.\n * We check by trying to get the diff - if it contains \"Binary files\" it's binary.\n */\nexport async function isUntrackedBinaryFile(\n path: string,\n cwd: string = process.cwd()\n): Promise<boolean> {\n try {\n const result = await execa(\n \"git\",\n [\"diff\", \"--no-index\", \"--\", \"/dev/null\", path],\n { cwd, reject: false }\n );\n return result.stdout.includes(\"Binary files\");\n } catch {\n return false;\n }\n}\n\nexport interface GetFullDiffOptions {\n mode: DiffMode;\n base?: string;\n head?: string;\n paths: string[];\n unified?: number;\n cwd?: string;\n}\n\n/**\n * Get the full unified diff for all files (used for text output).\n */\nexport async function getFullDiff(options: GetFullDiffOptions): Promise<string> {\n const cwd = options.cwd ?? process.cwd();\n const unified = options.unified ?? 0;\n\n if (options.paths.length === 0) {\n return \"\";\n }\n\n const args = [\"diff\", `--unified=${unified}`, \"--find-renames\"];\n\n switch (options.mode) {\n case \"branch\":\n args.push(`${options.base}..${options.head}`);\n break;\n case \"unstaged\":\n break;\n case \"staged\":\n args.push(\"--staged\");\n break;\n case \"all\":\n args.push(\"HEAD\");\n break;\n }\n\n args.push(\"--\", ...options.paths);\n\n try {\n const result = await execa(\"git\", args, { cwd });\n return result.stdout;\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\n `git ${args.join(\" \")}`,\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\n// ============================================================================\n// Stats (numstat for accurate additions/deletions)\n// ============================================================================\n\nexport interface FileStats {\n path: string;\n oldPath?: string;\n added: number;\n removed: number;\n binary: boolean;\n}\n\nexport interface GetNumStatsOptions {\n mode: DiffMode;\n base?: string;\n head?: string;\n cwd?: string;\n}\n\n/**\n * Get file statistics (additions/deletions) using git diff --numstat.\n * Returns a map of path -> stats for efficient lookup.\n */\nexport async function getNumStats(\n options: GetNumStatsOptions\n): Promise<Map<string, FileStats>> {\n const cwd = options.cwd ?? process.cwd();\n\n const args = [\"diff\", \"--numstat\", \"--find-renames\"];\n\n switch (options.mode) {\n case \"branch\":\n args.push(`${options.base}..${options.head}`);\n break;\n case \"unstaged\":\n break;\n case \"staged\":\n args.push(\"--staged\");\n break;\n case \"all\":\n args.push(\"HEAD\");\n break;\n }\n\n try {\n const result = await execa(\"git\", args, { cwd });\n return parseNumStats(result.stdout);\n } catch (error) {\n if (error instanceof Error && \"stderr\" in error) {\n throw new GitCommandError(\n `git ${args.join(\" \")}`,\n String((error as { stderr: unknown }).stderr)\n );\n }\n throw error;\n }\n}\n\n/**\n * Parse git diff --numstat output into a map.\n * Format: <added>\\t<removed>\\t<path>\n * For renames: <added>\\t<removed>\\t<oldPath>\\t<newPath>\n * For binary files: -\\t-\\t<path>\n */\nexport function parseNumStats(output: string): Map<string, FileStats> {\n const statsMap = new Map<string, FileStats>();\n\n if (!output.trim()) {\n return statsMap;\n }\n\n const lines = output.trim().split(\"\\n\");\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n const parts = line.split(\"\\t\");\n if (parts.length < 3) continue;\n\n const addedStr = parts[0]!;\n const removedStr = parts[1]!;\n\n // Check for binary file (marked with -)\n const isBinary = addedStr === \"-\" && removedStr === \"-\";\n\n // Check for rename (4 parts)\n const isRename = parts.length >= 4;\n\n let path: string;\n let oldPath: string | undefined;\n\n if (isRename) {\n oldPath = parts[2];\n path = parts[3]!;\n } else {\n path = parts[2]!;\n }\n\n const stats: FileStats = {\n path,\n oldPath,\n added: isBinary ? 0 : parseInt(addedStr, 10),\n removed: isBinary ? 0 : parseInt(removedStr, 10),\n binary: isBinary,\n };\n\n statsMap.set(path, stats);\n }\n\n return statsMap;\n}\n",
94
- "/**\n * Markdown PR body renderer.\n */\n\nimport type {\n APIContractChangeFinding,\n CIWorkflowFinding,\n CloudflareChangeFinding,\n ConventionViolationFinding,\n DbMigrationFinding,\n DependencyChangeFinding,\n EnvVarFinding,\n FileCategoryFinding,\n FileSummaryFinding,\n Finding,\n GraphQLChangeFinding,\n ImpactAnalysisFinding,\n InfraChangeFinding,\n LargeDiffFinding,\n LockfileFinding,\n MonorepoConfigFinding,\n PackageExportsFinding,\n RenderContext,\n RouteChangeFinding,\n SecurityFileFinding,\n SQLRiskFinding,\n StencilComponentChangeFinding,\n StencilEventChangeFinding,\n StencilMethodChangeFinding,\n StencilPropChangeFinding,\n StencilSlotChangeFinding,\n TailwindConfigFinding,\n TestChangeFinding,\n TestGapFinding,\n TestParityViolationFinding,\n TypeScriptConfigFinding,\n} from \"../core/types.js\";\nimport { routeIdToUrlPath } from \"../analyzers/route-detector.js\";\nimport { getCategoryLabel } from \"../analyzers/file-category.js\";\n\n/**\n * Group findings by type.\n */\nfunction groupFindings(findings: Finding[]): Map<string, Finding[]> {\n const groups = new Map<string, Finding[]>();\n for (const finding of findings) {\n if (!groups.has(finding.type)) {\n groups.set(finding.type, []);\n }\n groups.get(finding.type)!.push(finding);\n }\n return groups;\n}\n\n/**\n * Render the Context section (interactive mode only).\n */\nfunction renderContext(context: RenderContext): string {\n if (!context.interactive?.context) {\n return \"\";\n }\n return `## Context\\n\\n${context.interactive.context}\\n\\n`;\n}\n\n/**\n * Render the Summary section.\n */\nfunction renderSummary(groups: Map<string, Finding[]>): string {\n const bullets: string[] = [];\n\n const fileSummary = groups.get(\"file-summary\")?.[0] as\n | FileSummaryFinding\n | undefined;\n if (fileSummary) {\n const total =\n fileSummary.added.length +\n fileSummary.modified.length +\n fileSummary.deleted.length +\n fileSummary.renamed.length;\n bullets.push(`${total} file(s) changed`);\n\n if (fileSummary.added.length > 0) {\n bullets.push(`${fileSummary.added.length} file(s) added`);\n }\n if (fileSummary.deleted.length > 0) {\n bullets.push(`${fileSummary.deleted.length} file(s) deleted`);\n }\n }\n\n const routeChanges = groups.get(\"route-change\") as\n | RouteChangeFinding[]\n | undefined;\n if (routeChanges && routeChanges.length > 0) {\n const newRoutes = routeChanges.filter((r) => r.change === \"added\");\n if (newRoutes.length > 0) {\n bullets.push(`${newRoutes.length} new route(s)`);\n }\n }\n\n const migrations = groups.get(\"db-migration\") as\n | DbMigrationFinding[]\n | undefined;\n if (migrations && migrations.length > 0) {\n bullets.push(`Database migrations detected`);\n }\n\n const deps = groups.get(\"dependency-change\") as\n | DependencyChangeFinding[]\n | undefined;\n if (deps && deps.length > 0) {\n const majorBumps = deps.filter((d) => d.impact === \"major\");\n if (majorBumps.length > 0) {\n bullets.push(`${majorBumps.length} major dependency update(s)`);\n }\n }\n\n const securityFiles = groups.get(\"security-file\") as\n | SecurityFileFinding[]\n | undefined;\n if (securityFiles && securityFiles.length > 0) {\n const totalFiles = securityFiles.reduce(\n (acc, sf) => acc + sf.files.length,\n 0\n );\n bullets.push(`${totalFiles} security-sensitive file(s) changed`);\n }\n\n // GraphQL breaking changes\n const graphqlChanges = groups.get(\"graphql-change\") as\n | GraphQLChangeFinding[]\n | undefined;\n if (graphqlChanges && graphqlChanges.length > 0) {\n const breakingCount = graphqlChanges.filter((g) => g.isBreaking).length;\n if (breakingCount > 0) {\n bullets.push(`${breakingCount} GraphQL breaking change(s)`);\n }\n }\n\n // CI workflow risks\n const ciWorkflows = groups.get(\"ci-workflow\") as\n | CIWorkflowFinding[]\n | undefined;\n if (ciWorkflows && ciWorkflows.length > 0) {\n bullets.push(`${ciWorkflows.length} CI workflow change(s) detected`);\n }\n\n // Stencil component changes\n const stencilComponents = groups.get(\"stencil-component-change\") as\n | StencilComponentChangeFinding[]\n | undefined;\n if (stencilComponents && stencilComponents.length > 0) {\n bullets.push(`${stencilComponents.length} component API change(s)`);\n }\n\n // Package exports breaking changes\n const packageExports = groups.get(\"package-exports\") as\n | PackageExportsFinding[]\n | undefined;\n if (packageExports && packageExports.length > 0) {\n const breakingExports = packageExports.filter((p) => p.isBreaking);\n if (breakingExports.length > 0) {\n bullets.push(`Package API breaking changes detected`);\n }\n }\n\n if (bullets.length === 0) {\n bullets.push(\"Minor changes detected\");\n }\n\n // Limit to 6 bullets\n const limitedBullets = bullets.slice(0, 6);\n\n return (\n `## Summary\\n\\n` +\n limitedBullets.map((b) => `- ${b}`).join(\"\\n\") +\n \"\\n\\n\"\n );\n}\n\n/**\n * Render What Changed section (grouped by category).\n */\nfunction renderWhatChanged(\n categoryFinding: FileCategoryFinding | undefined,\n fileSummary: FileSummaryFinding | undefined\n): string {\n if (!categoryFinding || !fileSummary) {\n return \"\";\n }\n\n const { categories, summary } = categoryFinding;\n\n // Skip if no meaningful categorization\n if (summary.length <= 1) {\n return \"\";\n }\n\n let output = \"## What Changed\\n\\n\";\n\n // Order categories by count (descending)\n const orderedCategories = summary\n .filter((s) => s.count > 0)\n .sort((a, b) => b.count - a.count);\n\n for (const { category, count } of orderedCategories) {\n const label = getCategoryLabel(category);\n const files = categories[category];\n\n output += `### ${label} (${count})\\n\\n`;\n\n // Show up to 10 files per category\n const displayFiles = files.slice(0, 10);\n for (const file of displayFiles) {\n // Determine if added, modified, or deleted\n let status = \"\";\n if (fileSummary.added.includes(file)) {\n status = \" *(new)*\";\n } else if (fileSummary.deleted.includes(file)) {\n status = \" *(deleted)*\";\n }\n output += `- \\`${file}\\`${status}\\n`;\n }\n\n if (files.length > 10) {\n output += `- *...and ${files.length - 10} more*\\n`;\n }\n\n output += \"\\n\";\n }\n\n return output;\n}\n\n/**\n * Render Routes / API section.\n */\nfunction renderRoutes(routes: RouteChangeFinding[]): string {\n if (routes.length === 0) {\n return \"\";\n }\n\n let output = \"## Routes / API\\n\\n\";\n output += \"| Route | Type | Change | Methods |\\n\";\n output += \"|-------|------|--------|--------|\\n\";\n\n for (const route of routes) {\n const urlPath = routeIdToUrlPath(route.routeId);\n const methods = route.methods?.join(\", \") || \"-\";\n output += `| \\`${urlPath}\\` | ${route.routeType} | ${route.change} | ${methods} |\\n`;\n }\n\n return output + \"\\n\";\n}\n\n/**\n * Render API Contract changes.\n */\nfunction renderAPIContracts(contracts: APIContractChangeFinding[]): string {\n if (contracts.length === 0) {\n return \"\";\n }\n\n let output = \"## API Contracts\\n\\n\";\n output += \"The following API specification files have changed:\\n\\n\";\n\n for (const contract of contracts) {\n for (const file of contract.files) {\n output += `- \\`${file}\\`\\n`;\n }\n }\n output += \"\\n\";\n\n return output;\n}\n\n/**\n * Render Database (Supabase) section.\n */\nfunction renderDatabase(migrations: DbMigrationFinding[]): string {\n if (migrations.length === 0) {\n return \"\";\n }\n\n let output = \"## Database (Supabase)\\n\\n\";\n\n for (const migration of migrations) {\n const riskEmoji =\n migration.risk === \"high\"\n ? \"🔴\"\n : migration.risk === \"medium\"\n ? \"🟡\"\n : \"🟢\";\n output += `**Risk Level:** ${riskEmoji} ${migration.risk.toUpperCase()}\\n\\n`;\n output += \"**Files:**\\n\";\n for (const file of migration.files) {\n output += `- \\`${file}\\`\\n`;\n }\n output += \"\\n\";\n\n if (migration.reasons.length > 0) {\n output += \"**Detected patterns:**\\n\";\n for (const reason of migration.reasons) {\n output += `- ${reason}\\n`;\n }\n output += \"\\n\";\n }\n }\n\n return output;\n}\n\n/**\n * Render Config / Env section.\n */\nfunction renderEnvVars(envVars: EnvVarFinding[]): string {\n if (envVars.length === 0) {\n return \"\";\n }\n\n let output = \"## Config / Env\\n\\n\";\n output += \"| Variable | Status | Evidence |\\n\";\n output += \"|----------|--------|----------|\\n\";\n\n for (const envVar of envVars) {\n const files = envVar.evidenceFiles.slice(0, 2).join(\", \");\n output += `| \\`${envVar.name}\\` | ${envVar.change} | ${files} |\\n`;\n }\n\n return output + \"\\n\";\n}\n\n/**\n * Render Cloudflare section.\n */\nfunction renderCloudflare(changes: CloudflareChangeFinding[]): string {\n if (changes.length === 0) {\n return \"\";\n }\n\n let output = \"## Cloudflare\\n\\n\";\n\n for (const change of changes) {\n output += `**Area:** ${change.area}\\n`;\n output += \"**Files:**\\n\";\n for (const file of change.files) {\n output += `- \\`${file}\\`\\n`;\n }\n output += \"\\n\";\n }\n\n return output;\n}\n\n/**\n * Render Dependencies section.\n */\nfunction renderDependencies(deps: DependencyChangeFinding[]): string {\n if (deps.length === 0) {\n return \"\";\n }\n\n const prodDeps = deps.filter((d) => d.section === \"dependencies\");\n const devDeps = deps.filter((d) => d.section === \"devDependencies\");\n\n let output = \"## Dependencies\\n\\n\";\n\n if (prodDeps.length > 0) {\n output += \"### Production\\n\\n\";\n output += \"| Package | From | To | Impact |\\n\";\n output += \"|---------|------|-----|--------|\\n\";\n for (const dep of prodDeps) {\n output += `| \\`${dep.name}\\` | ${dep.from ?? \"-\"} | ${dep.to ?? \"-\"} | ${dep.impact ?? \"-\"} |\\n`;\n }\n output += \"\\n\";\n }\n\n if (devDeps.length > 0) {\n output += \"### Dev Dependencies\\n\\n\";\n output += \"| Package | From | To | Impact |\\n\";\n output += \"|---------|------|-----|--------|\\n\";\n for (const dep of devDeps) {\n output += `| \\`${dep.name}\\` | ${dep.from ?? \"-\"} | ${dep.to ?? \"-\"} | ${dep.impact ?? \"-\"} |\\n`;\n }\n output += \"\\n\";\n }\n\n return output;\n}\n\n/**\n * Render GraphQL Schema section.\n */\nfunction renderGraphQL(changes: GraphQLChangeFinding[]): string {\n if (changes.length === 0) {\n return \"\";\n }\n\n let output = \"## GraphQL Schema\\n\\n\";\n\n // Check for breaking changes\n const breakingChanges = changes.filter((c) => c.isBreaking);\n if (breakingChanges.length > 0) {\n output += \"### 🔴 Breaking Changes\\n\\n\";\n for (const change of breakingChanges) {\n output += `**File:** \\`${change.file}\\`\\n`;\n if (change.breakingChanges.length > 0) {\n for (const bc of change.breakingChanges) {\n output += `- ${bc}\\n`;\n }\n }\n output += \"\\n\";\n }\n }\n\n // Show added elements\n const withAdditions = changes.filter((c) => c.addedElements.length > 0);\n if (withAdditions.length > 0) {\n output += \"### Added Elements\\n\\n\";\n for (const change of withAdditions) {\n output += `**File:** \\`${change.file}\\`\\n`;\n for (const elem of change.addedElements.slice(0, 10)) {\n output += `- ${elem}\\n`;\n }\n if (change.addedElements.length > 10) {\n output += `- ...and ${change.addedElements.length - 10} more\\n`;\n }\n output += \"\\n\";\n }\n }\n\n // Summary table for all changes\n output += \"### All Schema Changes\\n\\n\";\n output += \"| File | Status | Breaking |\\n\";\n output += \"|------|--------|----------|\\n\";\n for (const change of changes) {\n const breakingEmoji = change.isBreaking ? \"🔴 Yes\" : \"🟢 No\";\n output += `| \\`${change.file}\\` | ${change.status} | ${breakingEmoji} |\\n`;\n }\n output += \"\\n\";\n\n return output;\n}\n\n/**\n * Render TypeScript Config section.\n */\nfunction renderTypeScriptConfig(configs: TypeScriptConfigFinding[]): string {\n if (configs.length === 0) {\n return \"\";\n }\n\n let output = \"### TypeScript Configuration\\n\\n\";\n\n for (const config of configs) {\n const breakingEmoji = config.isBreaking ? \"🔴\" : \"🟢\";\n output += `**File:** \\`${config.file}\\` ${breakingEmoji}\\n\\n`;\n\n // Strictness changes\n if (config.strictnessChanges.length > 0) {\n output += \"**Strictness Changes:**\\n\";\n for (const change of config.strictnessChanges) {\n output += `- ${change}\\n`;\n }\n output += \"\\n\";\n }\n\n // Changed options\n const { added, removed, modified } = config.changedOptions;\n if (added.length > 0) {\n output += `**Added:** ${added.map((o) => `\\`${o}\\``).join(\", \")}\\n`;\n }\n if (removed.length > 0) {\n output += `**Removed:** ${removed.map((o) => `\\`${o}\\``).join(\", \")}\\n`;\n }\n if (modified.length > 0) {\n output += `**Modified:** ${modified.map((o) => `\\`${o}\\``).join(\", \")}\\n`;\n }\n output += \"\\n\";\n }\n\n return output;\n}\n\n/**\n * Render Tailwind Config section.\n */\nfunction renderTailwindConfig(configs: TailwindConfigFinding[]): string {\n if (configs.length === 0) {\n return \"\";\n }\n\n let output = \"### Tailwind Configuration\\n\\n\";\n\n for (const config of configs) {\n const breakingEmoji = config.isBreaking ? \"🔴\" : \"🟢\";\n output += `**File:** \\`${config.file}\\` (${config.configType}) ${breakingEmoji}\\n\\n`;\n\n if (config.affectedSections.length > 0) {\n output += \"**Affected Sections:**\\n\";\n for (const section of config.affectedSections) {\n output += `- ${section}\\n`;\n }\n output += \"\\n\";\n }\n\n if (config.isBreaking && config.breakingReasons.length > 0) {\n output += \"**Breaking Changes:**\\n\";\n for (const reason of config.breakingReasons) {\n output += `- ${reason}\\n`;\n }\n output += \"\\n\";\n }\n }\n\n return output;\n}\n\n/**\n * Render Monorepo Config section.\n */\nfunction renderMonorepoConfig(configs: MonorepoConfigFinding[]): string {\n if (configs.length === 0) {\n return \"\";\n }\n\n let output = \"### Monorepo Configuration\\n\\n\";\n\n for (const config of configs) {\n output += `**Tool:** ${config.tool}\\n`;\n output += `**File:** \\`${config.file}\\`\\n\\n`;\n\n if (config.affectedFields.length > 0) {\n output += \"**Changed Fields:**\\n\";\n for (const field of config.affectedFields) {\n output += `- ${field}\\n`;\n }\n output += \"\\n\";\n }\n\n if (config.impacts.length > 0) {\n output += \"**Impacts:**\\n\";\n for (const impact of config.impacts) {\n output += `- ${impact}\\n`;\n }\n output += \"\\n\";\n }\n }\n\n return output;\n}\n\n/**\n * Render combined Configuration section.\n */\nfunction renderConfiguration(\n tsConfigs: TypeScriptConfigFinding[],\n tailwindConfigs: TailwindConfigFinding[],\n monorepoConfigs: MonorepoConfigFinding[]\n): string {\n const hasTsConfig = tsConfigs.length > 0;\n const hasTailwind = tailwindConfigs.length > 0;\n const hasMonorepo = monorepoConfigs.length > 0;\n\n if (!hasTsConfig && !hasTailwind && !hasMonorepo) {\n return \"\";\n }\n\n let output = \"## Configuration Changes\\n\\n\";\n\n if (hasTsConfig) {\n output += renderTypeScriptConfig(tsConfigs);\n }\n if (hasTailwind) {\n output += renderTailwindConfig(tailwindConfigs);\n }\n if (hasMonorepo) {\n output += renderMonorepoConfig(monorepoConfigs);\n }\n\n return output;\n}\n\n/**\n * Render Package Exports / API section.\n */\nfunction renderPackageExports(exports: PackageExportsFinding[]): string {\n if (exports.length === 0) {\n return \"\";\n }\n\n let output = \"## Package API\\n\\n\";\n\n for (const exp of exports) {\n const breakingEmoji = exp.isBreaking ? \"🔴 Breaking\" : \"🟢 Non-breaking\";\n output += `**Status:** ${breakingEmoji}\\n\\n`;\n\n // Removed exports (breaking)\n if (exp.removedExports.length > 0) {\n output += \"### Removed Exports\\n\\n\";\n for (const removed of exp.removedExports) {\n output += `- 🔴 \\`${removed}\\`\\n`;\n }\n output += \"\\n\";\n }\n\n // Added exports\n if (exp.addedExports.length > 0) {\n output += \"### Added Exports\\n\\n\";\n for (const added of exp.addedExports) {\n output += `- 🟢 \\`${added}\\`\\n`;\n }\n output += \"\\n\";\n }\n\n // Legacy field changes\n if (exp.legacyFieldChanges.length > 0) {\n output += \"### Entry Point Changes\\n\\n\";\n output += \"| Field | From | To |\\n\";\n output += \"|-------|------|----|\\n\";\n for (const change of exp.legacyFieldChanges) {\n output += `| \\`${change.field}\\` | ${change.from ?? \"-\"} | ${change.to ?? \"-\"} |\\n`;\n }\n output += \"\\n\";\n }\n\n // Bin changes\n if (exp.binChanges.added.length > 0 || exp.binChanges.removed.length > 0) {\n output += \"### Binary Commands\\n\\n\";\n if (exp.binChanges.added.length > 0) {\n output += `**Added:** ${exp.binChanges.added.map((b) => `\\`${b}\\``).join(\", \")}\\n`;\n }\n if (exp.binChanges.removed.length > 0) {\n output += `**Removed:** ${exp.binChanges.removed.map((b) => `\\`${b}\\``).join(\", \")}\\n`;\n }\n output += \"\\n\";\n }\n }\n\n return output;\n}\n\n/**\n * Render Stencil Component API changes.\n */\nfunction renderStencilChanges(groups: Map<string, Finding[]>): string {\n const componentChanges =\n (groups.get(\"stencil-component-change\") as StencilComponentChangeFinding[]) ?? [];\n const propChanges =\n (groups.get(\"stencil-prop-change\") as StencilPropChangeFinding[]) ?? [];\n const eventChanges =\n (groups.get(\"stencil-event-change\") as StencilEventChangeFinding[]) ?? [];\n const methodChanges =\n (groups.get(\"stencil-method-change\") as StencilMethodChangeFinding[]) ?? [];\n const slotChanges =\n (groups.get(\"stencil-slot-change\") as StencilSlotChangeFinding[]) ?? [];\n\n const hasChanges =\n componentChanges.length > 0 ||\n propChanges.length > 0 ||\n eventChanges.length > 0 ||\n methodChanges.length > 0 ||\n slotChanges.length > 0;\n\n if (!hasChanges) {\n return \"\";\n }\n\n let output = \"## Component API (Stencil)\\n\\n\";\n\n // Group all changes by component tag\n const byTag = new Map<string, {\n component?: StencilComponentChangeFinding;\n props: StencilPropChangeFinding[];\n events: StencilEventChangeFinding[];\n methods: StencilMethodChangeFinding[];\n slots: StencilSlotChangeFinding[];\n }>();\n\n // Initialize groups for all tags\n const initTag = (tag: string) => {\n if (!byTag.has(tag)) {\n byTag.set(tag, { props: [], events: [], methods: [], slots: [] });\n }\n };\n\n for (const c of componentChanges) {\n initTag(c.tag);\n byTag.get(c.tag)!.component = c;\n }\n for (const p of propChanges) {\n initTag(p.tag);\n byTag.get(p.tag)!.props.push(p);\n }\n for (const e of eventChanges) {\n initTag(e.tag);\n byTag.get(e.tag)!.events.push(e);\n }\n for (const m of methodChanges) {\n initTag(m.tag);\n byTag.get(m.tag)!.methods.push(m);\n }\n for (const s of slotChanges) {\n initTag(s.tag);\n byTag.get(s.tag)!.slots.push(s);\n }\n\n // Render each component\n for (const [tag, changes] of byTag) {\n output += `### \\`<${tag}>\\`\\n\\n`;\n\n // Component-level changes\n if (changes.component) {\n const c = changes.component;\n const changeEmoji = c.change === \"removed\" ? \"🔴\" : c.change === \"added\" ? \"🟢\" : \"🟡\";\n output += `**Component:** ${changeEmoji} ${c.change}`;\n if (c.change === \"tag-changed\") {\n output += ` (${c.fromTag} → ${c.toTag})`;\n }\n if (c.change === \"shadow-changed\") {\n output += ` (shadow: ${c.fromShadow} → ${c.toShadow})`;\n }\n output += `\\n`;\n output += `**File:** \\`${c.file}\\`\\n\\n`;\n }\n\n // Props\n if (changes.props.length > 0) {\n output += \"**Props:**\\n\";\n for (const p of changes.props) {\n const emoji = p.change === \"removed\" ? \"🔴\" : p.change === \"added\" ? \"🟢\" : \"🟡\";\n let detail = \"\";\n if (p.details?.typeText) {\n detail = `: ${p.details.typeText}`;\n }\n output += `- ${emoji} \\`${p.propName}\\`${detail} (${p.change})\\n`;\n }\n output += \"\\n\";\n }\n\n // Events\n if (changes.events.length > 0) {\n output += \"**Events:**\\n\";\n for (const e of changes.events) {\n const emoji = e.change === \"removed\" ? \"🔴\" : e.change === \"added\" ? \"🟢\" : \"🟡\";\n output += `- ${emoji} \\`${e.eventName}\\` (${e.change})\\n`;\n }\n output += \"\\n\";\n }\n\n // Methods\n if (changes.methods.length > 0) {\n output += \"**Methods:**\\n\";\n for (const m of changes.methods) {\n const emoji = m.change === \"removed\" ? \"🔴\" : m.change === \"added\" ? \"🟢\" : \"🟡\";\n const sig = m.signature ? `: ${m.signature}` : \"\";\n output += `- ${emoji} \\`${m.methodName}\\`${sig} (${m.change})\\n`;\n }\n output += \"\\n\";\n }\n\n // Slots\n if (changes.slots.length > 0) {\n output += \"**Slots:**\\n\";\n for (const s of changes.slots) {\n const emoji = s.change === \"removed\" ? \"🔴\" : \"🟢\";\n const slotName = s.slotName === \"default\" ? \"(default)\" : `\"${s.slotName}\"`;\n output += `- ${emoji} ${slotName} (${s.change})\\n`;\n }\n output += \"\\n\";\n }\n }\n\n return output;\n}\n\n/**\n * Render CI Workflow findings.\n */\nfunction renderCIWorkflow(findings: CIWorkflowFinding[]): string {\n if (findings.length === 0) {\n return \"\";\n }\n\n let output = \"### CI Workflows\\n\\n\";\n\n for (const finding of findings) {\n const riskEmoji =\n finding.riskType === \"permissions_broadened\" ||\n finding.riskType === \"pull_request_target\" ||\n finding.riskType === \"remote_script_download\"\n ? \"🔴\"\n : \"🟡\";\n\n const riskLabel = finding.riskType.replace(/_/g, \" \");\n output += `${riskEmoji} **${riskLabel}**\\n`;\n output += `- File: \\`${finding.file}\\`\\n`;\n output += `- ${finding.details}\\n\\n`;\n }\n\n return output;\n}\n\n/**\n * Render SQL Risk findings.\n */\nfunction renderSQLRisk(findings: SQLRiskFinding[]): string {\n if (findings.length === 0) {\n return \"\";\n }\n\n let output = \"## SQL Risk\\n\\n\";\n\n for (const finding of findings) {\n const riskEmoji =\n finding.riskType === \"destructive\"\n ? \"🔴\"\n : finding.riskType === \"unscoped_modification\"\n ? \"🔴\"\n : \"🟡\";\n\n const riskLabel = finding.riskType.replace(/_/g, \" \");\n output += `${riskEmoji} **${riskLabel}**\\n`;\n output += `- File: \\`${finding.file}\\`\\n`;\n output += `- ${finding.details}\\n\\n`;\n }\n\n return output;\n}\n\n/**\n * Render Infrastructure changes.\n */\nfunction renderInfraChanges(findings: InfraChangeFinding[]): string {\n if (findings.length === 0) {\n return \"\";\n }\n\n let output = \"### Infrastructure\\n\\n\";\n\n // Group by infra type\n const byType = new Map<string, InfraChangeFinding[]>();\n for (const finding of findings) {\n if (!byType.has(finding.infraType)) {\n byType.set(finding.infraType, []);\n }\n byType.get(finding.infraType)!.push(finding);\n }\n\n for (const [infraType, typeFindings] of byType) {\n const label =\n infraType === \"dockerfile\"\n ? \"Docker\"\n : infraType === \"terraform\"\n ? \"Terraform\"\n : infraType === \"k8s\"\n ? \"Kubernetes\"\n : infraType;\n\n output += `**${label}:**\\n`;\n const allFiles = typeFindings.flatMap((f) => f.files);\n for (const file of allFiles) {\n output += `- \\`${file}\\`\\n`;\n }\n output += \"\\n\";\n }\n\n return output;\n}\n\n/**\n * Render combined CI / Infrastructure section.\n */\nfunction renderCIInfrastructure(\n ciFindings: CIWorkflowFinding[],\n infraFindings: InfraChangeFinding[]\n): string {\n if (ciFindings.length === 0 && infraFindings.length === 0) {\n return \"\";\n }\n\n let output = \"## CI / Infrastructure\\n\\n\";\n output += renderCIWorkflow(ciFindings);\n output += renderInfraChanges(infraFindings);\n\n return output;\n}\n\n/**\n * Render Warnings section (large-diff, lockfile-mismatch, test-gap).\n */\nfunction renderWarnings(groups: Map<string, Finding[]>): string {\n const largeDiff =\n (groups.get(\"large-diff\") as LargeDiffFinding[]) ?? [];\n const lockfileMismatch =\n (groups.get(\"lockfile-mismatch\") as LockfileFinding[]) ?? [];\n const testGap =\n (groups.get(\"test-gap\") as TestGapFinding[]) ?? [];\n\n const hasWarnings =\n largeDiff.length > 0 || lockfileMismatch.length > 0 || testGap.length > 0;\n\n if (!hasWarnings) {\n return \"\";\n }\n\n let output = \"## ⚠️ Warnings\\n\\n\";\n\n // Large diff warning\n for (const ld of largeDiff) {\n output += `- **Large diff detected:** ${ld.filesChanged} files changed, ${ld.linesChanged} lines modified\\n`;\n }\n\n // Lockfile mismatch warning\n for (const lm of lockfileMismatch) {\n if (lm.manifestChanged && !lm.lockfileChanged) {\n output += `- **Lockfile mismatch:** package.json changed but lockfile not updated\\n`;\n } else if (!lm.manifestChanged && lm.lockfileChanged) {\n output += `- **Lockfile mismatch:** lockfile changed but package.json not updated\\n`;\n }\n }\n\n // Test gap warning\n for (const tg of testGap) {\n output += `- **Test coverage gap:** ${tg.prodFilesChanged} production files changed, only ${tg.testFilesChanged} test files changed\\n`;\n }\n\n output += \"\\n\";\n return output;\n}\n\n/**\n * Render Suggested test plan section.\n */\nfunction renderTestPlan(\n context: RenderContext,\n groups: Map<string, Finding[]>\n): string {\n const bullets: string[] = [];\n\n // Check if vitest tests exist\n const testChanges = groups.get(\"test-change\") as\n | TestChangeFinding[]\n | undefined;\n if (testChanges && testChanges.length > 0) {\n bullets.push(\"`bun test` - Run test suite\");\n }\n\n // SvelteKit check\n if (context.profile === \"sveltekit\") {\n bullets.push(\"`bun run check` - Run SvelteKit type check\");\n }\n\n // Route exercise suggestions\n const routes = groups.get(\"route-change\") as RouteChangeFinding[] | undefined;\n if (routes) {\n const endpoints = routes.filter((r) => r.routeType === \"endpoint\");\n for (const endpoint of endpoints.slice(0, 3)) {\n const urlPath = routeIdToUrlPath(endpoint.routeId);\n const methods = endpoint.methods?.join(\"/\") || \"GET\";\n bullets.push(`Test \\`${methods} ${urlPath}\\` endpoint`);\n }\n\n const pages = routes.filter(\n (r) => r.routeType === \"page\" && r.change !== \"deleted\"\n );\n for (const page of pages.slice(0, 3)) {\n const urlPath = routeIdToUrlPath(page.routeId);\n bullets.push(`Verify \\`${urlPath}\\` page renders correctly`);\n }\n }\n\n // Interactive test notes\n if (context.interactive?.testNotes) {\n bullets.push(context.interactive.testNotes);\n }\n\n if (bullets.length === 0) {\n bullets.push(\"No specific test suggestions\");\n }\n\n let output = \"## Suggested Test Plan\\n\\n\";\n output += bullets.map((b) => `- [ ] ${b}`).join(\"\\n\") + \"\\n\\n\";\n\n return output;\n}\n\n/**\n * Render Risks / Notes section.\n */\nfunction renderRisks(context: RenderContext): string {\n const { riskScore } = context;\n\n const levelEmoji =\n riskScore.level === \"high\"\n ? \"🔴\"\n : riskScore.level === \"medium\"\n ? \"🟡\"\n : \"🟢\";\n\n let output = \"## Risks / Notes\\n\\n\";\n output += `**Overall Risk:** ${levelEmoji} ${riskScore.level.toUpperCase()} (score: ${riskScore.score}/100)\\n\\n`;\n\n const bullets = riskScore.evidenceBullets ?? [];\n if (bullets.length > 0) {\n for (const bullet of bullets) {\n output += `- ${bullet}\\n`;\n }\n output += \"\\n\";\n }\n\n return output;\n}\n\n/**\n * Render findings into a Markdown PR body.\n */\nexport function renderMarkdown(context: RenderContext): string {\n const groups = groupFindings(context.findings);\n\n let output = \"\";\n\n // Context (interactive only)\n output += renderContext(context);\n\n // Summary\n output += renderSummary(groups);\n\n // What Changed (grouped by category)\n const categoryFinding = groups.get(\"file-category\")?.[0] as\n | FileCategoryFinding\n | undefined;\n const fileSummary = groups.get(\"file-summary\")?.[0] as\n | FileSummaryFinding\n | undefined;\n output += renderWhatChanged(categoryFinding, fileSummary);\n\n // Routes / API\n const routes = (groups.get(\"route-change\") as RouteChangeFinding[]) ?? [];\n output += renderRoutes(routes);\n\n // API Contracts\n const apiContracts =\n (groups.get(\"api-contract-change\") as APIContractChangeFinding[]) ?? [];\n output += renderAPIContracts(apiContracts);\n\n // GraphQL Schema\n const graphqlChanges =\n (groups.get(\"graphql-change\") as GraphQLChangeFinding[]) ?? [];\n output += renderGraphQL(graphqlChanges);\n\n // Database (Supabase)\n const migrations =\n (groups.get(\"db-migration\") as DbMigrationFinding[]) ?? [];\n output += renderDatabase(migrations);\n\n // SQL Risk\n const sqlRisks = (groups.get(\"sql-risk\") as SQLRiskFinding[]) ?? [];\n output += renderSQLRisk(sqlRisks);\n\n // Config / Env\n const envVars = (groups.get(\"env-var\") as EnvVarFinding[]) ?? [];\n output += renderEnvVars(envVars);\n\n // Configuration Changes (TypeScript, Tailwind, Monorepo)\n const tsConfigs =\n (groups.get(\"typescript-config\") as TypeScriptConfigFinding[]) ?? [];\n const tailwindConfigs =\n (groups.get(\"tailwind-config\") as TailwindConfigFinding[]) ?? [];\n const monorepoConfigs =\n (groups.get(\"monorepo-config\") as MonorepoConfigFinding[]) ?? [];\n output += renderConfiguration(tsConfigs, tailwindConfigs, monorepoConfigs);\n\n // Cloudflare\n const cloudflare =\n (groups.get(\"cloudflare-change\") as CloudflareChangeFinding[]) ?? [];\n output += renderCloudflare(cloudflare);\n\n // Dependencies\n const deps =\n (groups.get(\"dependency-change\") as DependencyChangeFinding[]) ?? [];\n output += renderDependencies(deps);\n\n // Package API (exports)\n const packageExports =\n (groups.get(\"package-exports\") as PackageExportsFinding[]) ?? [];\n output += renderPackageExports(packageExports);\n\n // Component API (Stencil)\n output += renderStencilChanges(groups);\n\n // CI / Infrastructure\n const ciWorkflows =\n (groups.get(\"ci-workflow\") as CIWorkflowFinding[]) ?? [];\n const infraChanges =\n (groups.get(\"infra-change\") as InfraChangeFinding[]) ?? [];\n output += renderCIInfrastructure(ciWorkflows, infraChanges);\n\n // Convention Violations\n const violations =\n (groups.get(\"convention-violation\") as ConventionViolationFinding[]) ?? [];\n if (violations.length > 0) {\n output += \"## ⚠️ Conventions\\n\\n\";\n for (const v of violations) {\n output += `- **${v.message}**\\n`;\n for (const file of v.files.slice(0, 5)) {\n output += ` - \\`${file}\\`\\n`;\n }\n if (v.files.length > 5) {\n output += ` - ...and ${v.files.length - 5} more\\n`;\n }\n }\n output += \"\\n\";\n }\n\n // Test Parity Violations\n const testParityViolations =\n (groups.get(\"test-parity-violation\") as TestParityViolationFinding[]) ?? [];\n if (testParityViolations.length > 0) {\n output += \"## 🧪 Test Coverage Gaps\\n\\n\";\n output += `Found ${testParityViolations.length} source file(s) without corresponding tests:\\n\\n`;\n for (const v of testParityViolations.slice(0, 10)) {\n const confidenceLabel = v.confidence === \"high\" ? \"🔴\" : v.confidence === \"medium\" ? \"🟡\" : \"⚪\";\n output += `- ${confidenceLabel} \\`${v.sourceFile}\\`\\n`;\n }\n if (testParityViolations.length > 10) {\n output += `- ...and ${testParityViolations.length - 10} more\\n`;\n }\n output += \"\\n\";\n }\n\n // Impact Analysis\n const impacts =\n (groups.get(\"impact-analysis\") as ImpactAnalysisFinding[]) ?? [];\n if (impacts.length > 0) {\n output += \"## 🧨 Impact Analysis\\n\\n\";\n for (const impact of impacts) {\n const radiusEmoji = impact.blastRadius === \"high\" ? \"🔴\" : impact.blastRadius === \"medium\" ? \"🟡\" : \"🟢\";\n output += `### \\`${impact.sourceFile}\\` ${radiusEmoji}\\n\\n`;\n output += `**Blast Radius:** ${impact.blastRadius.toUpperCase()} (${impact.affectedFiles.length} files)\\n\\n`;\n output += \"Affected files:\\n\";\n for (const f of impact.affectedFiles.slice(0, 5)) {\n output += `- \\`${f}\\`\\n`;\n }\n if (impact.affectedFiles.length > 5) {\n output += `- ...and ${impact.affectedFiles.length - 5} more\\n`;\n }\n output += \"\\n\";\n }\n }\n\n // Warnings (large-diff, lockfile-mismatch, test-gap)\n output += renderWarnings(groups);\n\n // Suggested test plan\n output += renderTestPlan(context, groups);\n\n // Risks / Notes\n output += renderRisks(context);\n\n return output.trim() + \"\\n\";\n}\n\n",
95
- "/**\n * JSON facts renderer.\n */\n\nimport type { Finding, RenderContext, RiskScore } from \"../core/types.js\";\n\nexport interface FactsOutput {\n profile: string;\n riskScore: RiskScore;\n findings: Finding[];\n}\n\n/**\n * Render findings as JSON output.\n */\nexport function renderJson(context: RenderContext): string {\n const output: FactsOutput = {\n profile: context.profile,\n riskScore: context.riskScore,\n findings: context.findings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n",
96
- "/**\n * Terminal renderer with colors, tables, and visual formatting.\n */\n\nimport chalk from \"chalk\";\nimport boxen from \"boxen\";\nimport Table from \"cli-table3\";\nimport type {\n CloudflareChangeFinding,\n DbMigrationFinding,\n DependencyChangeFinding,\n EnvVarFinding,\n FileCategoryFinding,\n FileSummaryFinding,\n Finding,\n RenderContext,\n RouteChangeFinding,\n SecurityFileFinding,\n TestChangeFinding,\n} from \"../core/types.js\";\nimport { routeIdToUrlPath } from \"../analyzers/route-detector.js\";\nimport { getCategoryLabel } from \"../analyzers/file-category.js\";\n\n/**\n * Color scheme for terminal output.\n */\nconst colors = {\n // Risk levels\n riskHigh: chalk.red.bold,\n riskMedium: chalk.yellow.bold,\n riskLow: chalk.green.bold,\n\n // File status\n fileAdded: chalk.green,\n fileDeleted: chalk.red,\n fileModified: chalk.cyan,\n fileRenamed: chalk.blue,\n\n // UI elements\n header: chalk.magenta.bold,\n subheader: chalk.cyan.bold,\n label: chalk.gray,\n value: chalk.white,\n muted: chalk.dim,\n accent: chalk.blue,\n warning: chalk.yellow,\n success: chalk.green,\n error: chalk.red,\n\n // Specific elements\n route: chalk.blue,\n packageName: chalk.cyan,\n version: chalk.yellow,\n envVar: chalk.magenta,\n};\n\n/**\n * Icons for visual enhancement.\n */\nconst icons = {\n file: \"📄\",\n folder: \"📁\",\n route: \"🛤️\",\n database: \"🗄️\",\n security: \"🔒\",\n dependency: \"📦\",\n test: \"🧪\",\n config: \"⚙️\",\n warning: \"⚠️\",\n check: \"✓\",\n cross: \"✗\",\n arrow: \"→\",\n bullet: \"•\",\n riskHigh: \"🔴\",\n riskMedium: \"🟡\",\n riskLow: \"🟢\",\n};\n\n/**\n * Group findings by type.\n */\nfunction groupFindings(findings: Finding[]): Map<string, Finding[]> {\n const groups = new Map<string, Finding[]>();\n for (const finding of findings) {\n if (!groups.has(finding.type)) {\n groups.set(finding.type, []);\n }\n groups.get(finding.type)!.push(finding);\n }\n return groups;\n}\n\n/**\n * Get risk badge with color and icon.\n */\nfunction getRiskBadge(level: \"low\" | \"medium\" | \"high\"): string {\n const colorFn =\n level === \"high\"\n ? colors.riskHigh\n : level === \"medium\"\n ? colors.riskMedium\n : colors.riskLow;\n\n const icon =\n level === \"high\"\n ? icons.riskHigh\n : level === \"medium\"\n ? icons.riskMedium\n : icons.riskLow;\n\n return `${icon} ${colorFn(level.toUpperCase())}`;\n}\n\n/**\n * Create a section header.\n */\nfunction sectionHeader(title: string, icon?: string): string {\n const prefix = icon ? `${icon} ` : \"\";\n return `\\n${colors.header(prefix + title)}\\n${\"─\".repeat(50)}\\n`;\n}\n\n/**\n * Render the Summary section in a box.\n */\nfunction renderSummary(\n groups: Map<string, Finding[]>,\n riskScore: RenderContext[\"riskScore\"]\n): string {\n const bullets: string[] = [];\n\n const fileSummary = groups.get(\"file-summary\")?.[0] as\n | FileSummaryFinding\n | undefined;\n if (fileSummary) {\n const total =\n fileSummary.added.length +\n fileSummary.modified.length +\n fileSummary.deleted.length +\n fileSummary.renamed.length;\n\n bullets.push(`${colors.value(String(total))} file(s) changed`);\n\n if (fileSummary.added.length > 0) {\n bullets.push(\n `${colors.fileAdded(`+${fileSummary.added.length}`)} file(s) added`\n );\n }\n if (fileSummary.deleted.length > 0) {\n bullets.push(\n `${colors.fileDeleted(`-${fileSummary.deleted.length}`)} file(s) deleted`\n );\n }\n if (fileSummary.modified.length > 0) {\n bullets.push(\n `${colors.fileModified(`~${fileSummary.modified.length}`)} file(s) modified`\n );\n }\n }\n\n const routeChanges = groups.get(\"route-change\") as\n | RouteChangeFinding[]\n | undefined;\n if (routeChanges && routeChanges.length > 0) {\n const newRoutes = routeChanges.filter((r) => r.change === \"added\");\n if (newRoutes.length > 0) {\n bullets.push(\n `${colors.success(String(newRoutes.length))} new route(s)`\n );\n }\n }\n\n const migrations = groups.get(\"db-migration\") as\n | DbMigrationFinding[]\n | undefined;\n if (migrations && migrations.length > 0) {\n bullets.push(`${icons.database} Database migrations detected`);\n }\n\n const deps = groups.get(\"dependency-change\") as\n | DependencyChangeFinding[]\n | undefined;\n if (deps && deps.length > 0) {\n const majorBumps = deps.filter((d) => d.impact === \"major\");\n if (majorBumps.length > 0) {\n bullets.push(\n `${colors.warning(String(majorBumps.length))} major dependency update(s)`\n );\n }\n }\n\n const securityFiles = groups.get(\"security-file\") as\n | SecurityFileFinding[]\n | undefined;\n if (securityFiles && securityFiles.length > 0) {\n const totalFiles = securityFiles.reduce(\n (acc, sf) => acc + sf.files.length,\n 0\n );\n bullets.push(\n `${icons.security} ${totalFiles} security-sensitive file(s)`\n );\n }\n\n if (bullets.length === 0) {\n bullets.push(\"Minor changes detected\");\n }\n\n // Risk line\n const riskLine = `\\n${colors.label(\"Risk:\")} ${getRiskBadge(riskScore.level)} ${colors.muted(`(score: ${riskScore.score}/100)`)}`;\n\n const content =\n bullets.map((b) => ` ${icons.bullet} ${b}`).join(\"\\n\") + riskLine;\n\n return boxen(content, {\n title: \"SUMMARY\",\n titleAlignment: \"left\",\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n borderColor: \"cyan\",\n borderStyle: \"round\",\n });\n}\n\n/**\n * Render What Changed section.\n */\nfunction renderWhatChanged(\n categoryFinding: FileCategoryFinding | undefined,\n fileSummary: FileSummaryFinding | undefined\n): string {\n if (!categoryFinding || !fileSummary) {\n return \"\";\n }\n\n const { categories, summary } = categoryFinding;\n\n if (summary.length <= 1) {\n return \"\";\n }\n\n let output = sectionHeader(\"WHAT CHANGED\", icons.file);\n\n const orderedCategories = summary\n .filter((s) => s.count > 0)\n .sort((a, b) => b.count - a.count);\n\n for (const { category, count } of orderedCategories) {\n const label = getCategoryLabel(category);\n output += `\\n${colors.subheader(label)} ${colors.muted(`(${count})`)}\\n`;\n\n const files = categories[category];\n const displayFiles = files.slice(0, 8);\n\n for (const file of displayFiles) {\n let statusIcon = \" \";\n let colorFn = colors.value;\n\n if (fileSummary.added.includes(file)) {\n statusIcon = colors.fileAdded(\"+ \");\n colorFn = colors.fileAdded;\n } else if (fileSummary.deleted.includes(file)) {\n statusIcon = colors.fileDeleted(\"- \");\n colorFn = colors.fileDeleted;\n } else if (fileSummary.modified.includes(file)) {\n statusIcon = colors.fileModified(\"~ \");\n colorFn = colors.fileModified;\n }\n\n output += ` ${statusIcon}${colorFn(file)}\\n`;\n }\n\n if (files.length > 8) {\n output += ` ${colors.muted(`...and ${files.length - 8} more`)}\\n`;\n }\n }\n\n return output;\n}\n\n/**\n * Render Routes / API table.\n */\nfunction renderRoutes(routes: RouteChangeFinding[]): string {\n if (routes.length === 0) {\n return \"\";\n }\n\n let output = sectionHeader(\"ROUTES / API\", icons.route);\n\n const table = new Table({\n head: [\n colors.label(\"Route\"),\n colors.label(\"Type\"),\n colors.label(\"Change\"),\n colors.label(\"Methods\"),\n ],\n style: {\n head: [],\n border: [\"dim\"],\n },\n chars: {\n top: \"─\",\n \"top-mid\": \"┬\",\n \"top-left\": \"┌\",\n \"top-right\": \"┐\",\n bottom: \"─\",\n \"bottom-mid\": \"┴\",\n \"bottom-left\": \"└\",\n \"bottom-right\": \"┘\",\n left: \"│\",\n \"left-mid\": \"├\",\n mid: \"─\",\n \"mid-mid\": \"┼\",\n right: \"│\",\n \"right-mid\": \"┤\",\n middle: \"│\",\n },\n });\n\n for (const route of routes) {\n const urlPath = routeIdToUrlPath(route.routeId);\n const methods = route.methods?.join(\", \") || \"-\";\n\n const changeColor =\n route.change === \"added\"\n ? colors.fileAdded\n : route.change === \"deleted\"\n ? colors.fileDeleted\n : colors.fileModified;\n\n table.push([\n colors.route(urlPath),\n route.routeType,\n changeColor(route.change),\n methods,\n ]);\n }\n\n output += table.toString() + \"\\n\";\n return output;\n}\n\n/**\n * Render Database (Supabase) section.\n */\nfunction renderDatabase(migrations: DbMigrationFinding[]): string {\n if (migrations.length === 0) {\n return \"\";\n }\n\n let output = sectionHeader(\"DATABASE (SUPABASE)\", icons.database);\n\n for (const migration of migrations) {\n output += `${colors.label(\"Risk Level:\")} ${getRiskBadge(migration.risk)}\\n\\n`;\n\n output += `${colors.label(\"Files:\")}\\n`;\n for (const file of migration.files) {\n output += ` ${icons.bullet} ${colors.value(file)}\\n`;\n }\n\n if (migration.reasons.length > 0) {\n output += `\\n${colors.label(\"Detected patterns:\")}\\n`;\n for (const reason of migration.reasons) {\n output += ` ${icons.warning} ${colors.warning(reason)}\\n`;\n }\n }\n output += \"\\n\";\n }\n\n return output;\n}\n\n/**\n * Render Config / Env table.\n */\nfunction renderEnvVars(envVars: EnvVarFinding[]): string {\n if (envVars.length === 0) {\n return \"\";\n }\n\n let output = sectionHeader(\"CONFIG / ENV\", icons.config);\n\n const table = new Table({\n head: [\n colors.label(\"Variable\"),\n colors.label(\"Status\"),\n colors.label(\"Evidence\"),\n ],\n style: {\n head: [],\n border: [\"dim\"],\n },\n chars: {\n top: \"─\",\n \"top-mid\": \"┬\",\n \"top-left\": \"┌\",\n \"top-right\": \"┐\",\n bottom: \"─\",\n \"bottom-mid\": \"┴\",\n \"bottom-left\": \"└\",\n \"bottom-right\": \"┘\",\n left: \"│\",\n \"left-mid\": \"├\",\n mid: \"─\",\n \"mid-mid\": \"┼\",\n right: \"│\",\n \"right-mid\": \"┤\",\n middle: \"│\",\n },\n });\n\n for (const envVar of envVars) {\n const files = envVar.evidenceFiles.slice(0, 2).join(\", \");\n const changeColor =\n envVar.change === \"added\" ? colors.fileAdded : colors.fileModified;\n\n table.push([\n colors.envVar(envVar.name),\n changeColor(envVar.change),\n colors.muted(files),\n ]);\n }\n\n output += table.toString() + \"\\n\";\n return output;\n}\n\n/**\n * Render Cloudflare section.\n */\nfunction renderCloudflare(changes: CloudflareChangeFinding[]): string {\n if (changes.length === 0) {\n return \"\";\n }\n\n let output = sectionHeader(\"CLOUDFLARE\", \"☁️\");\n\n for (const change of changes) {\n output += `${colors.label(\"Area:\")} ${colors.value(change.area)}\\n`;\n output += `${colors.label(\"Files:\")}\\n`;\n for (const file of change.files) {\n output += ` ${icons.bullet} ${colors.value(file)}\\n`;\n }\n output += \"\\n\";\n }\n\n return output;\n}\n\n/**\n * Render Dependencies section.\n */\nfunction renderDependencies(deps: DependencyChangeFinding[]): string {\n if (deps.length === 0) {\n return \"\";\n }\n\n const prodDeps = deps.filter((d) => d.section === \"dependencies\");\n const devDeps = deps.filter((d) => d.section === \"devDependencies\");\n\n let output = sectionHeader(\"DEPENDENCIES\", icons.dependency);\n\n const renderDepTable = (\n depList: DependencyChangeFinding[],\n title: string\n ): string => {\n if (depList.length === 0) return \"\";\n\n let result = `${colors.subheader(title)}\\n`;\n\n const table = new Table({\n head: [\n colors.label(\"Package\"),\n colors.label(\"From\"),\n colors.label(\"To\"),\n colors.label(\"Impact\"),\n ],\n style: {\n head: [],\n border: [\"dim\"],\n },\n chars: {\n top: \"─\",\n \"top-mid\": \"┬\",\n \"top-left\": \"┌\",\n \"top-right\": \"┐\",\n bottom: \"─\",\n \"bottom-mid\": \"┴\",\n \"bottom-left\": \"└\",\n \"bottom-right\": \"┘\",\n left: \"│\",\n \"left-mid\": \"├\",\n mid: \"─\",\n \"mid-mid\": \"┼\",\n right: \"│\",\n \"right-mid\": \"┤\",\n middle: \"│\",\n },\n });\n\n for (const dep of depList) {\n const impactColor =\n dep.impact === \"major\"\n ? colors.error\n : dep.impact === \"minor\"\n ? colors.warning\n : colors.muted;\n\n table.push([\n colors.packageName(dep.name),\n colors.muted(dep.from ?? \"-\"),\n colors.version(dep.to ?? \"-\"),\n impactColor(dep.impact ?? \"-\"),\n ]);\n }\n\n result += table.toString() + \"\\n\";\n return result;\n };\n\n if (prodDeps.length > 0) {\n output += renderDepTable(prodDeps, \"Production\");\n }\n if (devDeps.length > 0) {\n output += renderDepTable(devDeps, \"Dev Dependencies\");\n }\n\n return output;\n}\n\n/**\n * Render Suggested test plan section.\n */\nfunction renderTestPlan(\n context: RenderContext,\n groups: Map<string, Finding[]>\n): string {\n const bullets: string[] = [];\n\n const testChanges = groups.get(\"test-change\") as\n | TestChangeFinding[]\n | undefined;\n if (testChanges && testChanges.length > 0) {\n bullets.push(`${colors.accent(\"bun test\")} - Run test suite`);\n }\n\n if (context.profile === \"sveltekit\") {\n bullets.push(`${colors.accent(\"bun run check\")} - Run SvelteKit type check`);\n }\n\n const routes = groups.get(\"route-change\") as RouteChangeFinding[] | undefined;\n if (routes) {\n const endpoints = routes.filter((r) => r.routeType === \"endpoint\");\n for (const endpoint of endpoints.slice(0, 3)) {\n const urlPath = routeIdToUrlPath(endpoint.routeId);\n const methods = endpoint.methods?.join(\"/\") || \"GET\";\n bullets.push(`Test ${colors.route(`${methods} ${urlPath}`)} endpoint`);\n }\n\n const pages = routes.filter(\n (r) => r.routeType === \"page\" && r.change !== \"deleted\"\n );\n for (const page of pages.slice(0, 3)) {\n const urlPath = routeIdToUrlPath(page.routeId);\n bullets.push(`Verify ${colors.route(urlPath)} page renders correctly`);\n }\n }\n\n if (context.interactive?.testNotes) {\n bullets.push(context.interactive.testNotes);\n }\n\n if (bullets.length === 0) {\n bullets.push(\"No specific test suggestions\");\n }\n\n let output = sectionHeader(\"SUGGESTED TEST PLAN\", icons.test);\n for (const bullet of bullets) {\n output += ` ${colors.muted(\"[ ]\")} ${bullet}\\n`;\n }\n\n return output;\n}\n\n/**\n * Render Risks / Notes section.\n */\nfunction renderRisks(context: RenderContext): string {\n const { riskScore } = context;\n\n let output = sectionHeader(\"RISKS / NOTES\", icons.warning);\n\n output += `${colors.label(\"Overall Risk:\")} ${getRiskBadge(riskScore.level)} ${colors.muted(`(score: ${riskScore.score}/100)`)}\\n\\n`;\n\n const bullets = riskScore.evidenceBullets ?? [];\n if (bullets.length > 0) {\n for (const bullet of bullets) {\n output += ` ${icons.bullet} ${bullet}\\n`;\n }\n }\n\n return output;\n}\n\n/**\n * Render the Context section (interactive mode only).\n */\nfunction renderContext(context: RenderContext): string {\n if (!context.interactive?.context) {\n return \"\";\n }\n\n return boxen(context.interactive.context, {\n title: \"CONTEXT\",\n titleAlignment: \"left\",\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n borderColor: \"blue\",\n borderStyle: \"round\",\n }) + \"\\n\";\n}\n\n/**\n * Render findings into a colorized terminal output.\n */\nexport function renderTerminal(context: RenderContext): string {\n const groups = groupFindings(context.findings);\n\n let output = \"\\n\";\n\n // Context (interactive only)\n output += renderContext(context);\n\n // Summary box\n output += renderSummary(groups, context.riskScore);\n output += \"\\n\";\n\n // What Changed (grouped by category)\n const categoryFinding = groups.get(\"file-category\")?.[0] as\n | FileCategoryFinding\n | undefined;\n const fileSummary = groups.get(\"file-summary\")?.[0] as\n | FileSummaryFinding\n | undefined;\n output += renderWhatChanged(categoryFinding, fileSummary);\n\n // Routes / API\n const routes = (groups.get(\"route-change\") as RouteChangeFinding[]) ?? [];\n output += renderRoutes(routes);\n\n // Database (Supabase)\n const migrations =\n (groups.get(\"db-migration\") as DbMigrationFinding[]) ?? [];\n output += renderDatabase(migrations);\n\n // Config / Env\n const envVars = (groups.get(\"env-var\") as EnvVarFinding[]) ?? [];\n output += renderEnvVars(envVars);\n\n // Cloudflare\n const cloudflare =\n (groups.get(\"cloudflare-change\") as CloudflareChangeFinding[]) ?? [];\n output += renderCloudflare(cloudflare);\n\n // Dependencies\n const deps =\n (groups.get(\"dependency-change\") as DependencyChangeFinding[]) ?? [];\n output += renderDependencies(deps);\n\n // Suggested test plan\n output += renderTestPlan(context, groups);\n\n // Risks / Notes\n output += renderRisks(context);\n\n return output;\n}\n\n"
97
- ],
98
- "mappings": "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",
99
- "debugId": "4965579577980DC164756E2164756E21",
100
- "names": []
101
- }