@vibedrift/cli 0.5.1 → 0.5.3
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/index.js +46 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/codedna/function-extractor.ts","../src/core/version.ts","../src/codedna/semantic-fingerprint.ts","../src/codedna/operation-sequence.ts","../src/codedna/pattern-classifier.ts","../src/codedna/taint-analysis.ts","../src/codedna/deviation-heuristics.ts","../src/codedna/index.ts","../src/ml-client/sampler.ts","../src/ml-client/client.ts","../src/ml-client/confidence.ts","../src/ml-client/project-name.ts","../src/ml-client/index.ts","../src/scoring/dedup.ts","../src/ml-client/summarize.ts","../src/ml-client/log-scan.ts","../src/ml-client/sanitize-result.ts","../src/output/csv.ts","../src/output/docx.ts","../src/cli/index.ts","../src/cli/commands/scan.ts","../src/core/discovery.ts","../src/core/language.ts","../src/utils/gitignore.ts","../src/utils/ast.ts","../src/analyzers/index.ts","../src/analyzers/naming.ts","../src/analyzers/imports.ts","../src/analyzers/error-handling.ts","../src/utils/text.ts","../src/analyzers/dependencies.ts","../src/analyzers/duplicates.ts","../src/analyzers/todo-density.ts","../src/analyzers/config-drift.ts","../src/analyzers/security.ts","../src/analyzers/complexity.ts","../src/analyzers/intent-clarity.ts","../src/analyzers/dead-code.ts","../src/analyzers/language-specific.ts","../src/drift/index.ts","../src/drift/types.ts","../src/drift/architectural-contradiction.ts","../src/drift/convention-oscillation.ts","../src/drift/security-consistency.ts","../src/drift/semantic-duplication.ts","../src/drift/phantom-scaffolding.ts","../src/scoring/engine.ts","../src/scoring/categories.ts","../src/output/tease.ts","../src/output/terminal.ts","../src/output/format.ts","../src/output/html.ts","../src/core/history.ts","../src/core/file-filter.ts","../src/auth/resolver.ts","../src/auth/config.ts","../src/auth/api.ts","../src/cli/commands/update.ts","../src/cli/commands/login.ts","../src/auth/browser.ts","../src/cli/commands/logout.ts","../src/cli/commands/status.ts","../src/cli/commands/usage.ts","../src/cli/commands/upgrade.ts","../src/cli/commands/billing.ts","../src/cli/commands/doctor.ts","../src/cli/commands/feedback.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Cross-language function extraction for the Code DNA pipeline.\n *\n * Parses function declarations from JS/TS, Go, Python, and Rust sources\n * using regex patterns, then tokenizes their bodies for downstream\n * fingerprinting and operation-sequence analysis.\n */\n\nimport type { SourceFile, SupportedLanguage } from \"../core/types.js\";\nimport type { ExtractedFunction, FunctionRef } from \"./types.js\";\n\n// Domain category detection based on function name and body content\nexport function detectDomainCategory(name: string, body: string): string {\n const lowerName = name.toLowerCase();\n const lowerBody = body.toLowerCase();\n\n if (/(?:format|display|render|stringify|tostring|totext)/i.test(lowerName)) return \"formatting\";\n if (/(?:date|time|timestamp|moment|duration)/i.test(lowerName + lowerBody)) return \"date_manipulation\";\n if (/(?:currency|price|money|dollar|cent|amount)/i.test(lowerName + lowerBody)) return \"currency_handling\";\n if (/(?:valid|check|verify|assert|ensure|sanitize)/i.test(lowerName)) return \"validation\";\n if (/(?:parse|deserialize|unmarshal|decode)/i.test(lowerName)) return \"parsing\";\n if (/(?:serialize|marshal|encode|stringify)/i.test(lowerName)) return \"serialization\";\n if (/(?:fetch|get|load|read|find|query|list|search)/i.test(lowerName)) return \"data_retrieval\";\n if (/(?:create|insert|add|save|store|write|put|post)/i.test(lowerName)) return \"data_mutation\";\n if (/(?:update|patch|modify|edit|set)/i.test(lowerName)) return \"data_update\";\n if (/(?:delete|remove|destroy|drop|revoke)/i.test(lowerName)) return \"data_deletion\";\n if (/(?:transform|convert|map|reduce|filter)/i.test(lowerName)) return \"data_transformation\";\n if (/(?:handle|process|dispatch|route)/i.test(lowerName)) return \"request_handling\";\n if (/(?:auth|login|logout|token|session|permission|role)/i.test(lowerName + lowerBody)) return \"authentication\";\n if (/(?:log|debug|trace|info|warn|error)/i.test(lowerName) && lowerName.length < 15) return \"logging\";\n if (/(?:config|setting|option|preference|env)/i.test(lowerName)) return \"configuration\";\n if (/(?:send|notify|email|sms|push|broadcast)/i.test(lowerName)) return \"notification\";\n\n return \"general\";\n}\n\n// Tokenize body for comparison (strip comments, normalize strings)\nexport function tokenizeBody(body: string): string[] {\n let cleaned = body.replace(/\\/\\/.*$/gm, \"\").replace(/#.*$/gm, \"\");\n cleaned = cleaned.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n cleaned = cleaned.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"\"');\n cleaned = cleaned.replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"''\");\n cleaned = cleaned.replace(/`(?:[^`\\\\]|\\\\.)*`/g, \"``\");\n return cleaned.match(/[a-zA-Z_]\\w*|[0-9]+|[{}()\\[\\];,.:=<>!+\\-*/%&|^~?]/g) ?? [];\n}\n\n// djb2-style hash — fast, deterministic, and sufficient for grouping\n// duplicate candidates (collisions are validated by full token comparison later)\nexport function simpleHash(tokens: string[]): number {\n let h = 0;\n for (const t of tokens) {\n for (let i = 0; i < t.length; i++) {\n h = ((h << 5) - h + t.charCodeAt(i)) | 0;\n }\n }\n return h;\n}\n\nfunction extractBody(content: string, startAfterBrace: number, language: string): string {\n if (language === \"python\") {\n const rest = content.slice(startAfterBrace);\n const lines = rest.split(\"\\n\");\n const bodyLines: string[] = [];\n let baseIndent = -1;\n for (const line of lines) {\n if (line.trim() === \"\") { bodyLines.push(line); continue; }\n const indent = line.search(/\\S/);\n if (baseIndent === -1) baseIndent = indent;\n if (indent >= baseIndent) bodyLines.push(line);\n else break;\n }\n return bodyLines.join(\"\\n\");\n }\n\n let depth = 1;\n let i = startAfterBrace;\n while (i < content.length && depth > 0) {\n if (content[i] === \"{\") depth++;\n else if (content[i] === \"}\") depth--;\n i++;\n }\n return content.slice(startAfterBrace, i);\n}\n\nfunction getLanguagePatterns(language: SupportedLanguage): RegExp[] {\n const patterns: RegExp[] = [];\n if (language === \"go\") {\n patterns.push(/func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)\\s*\\(([^)]*)\\)\\s*(?:[^{]*)?\\{/g);\n } else if (language === \"javascript\" || language === \"typescript\") {\n patterns.push(/(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*(?::\\s*[^{]*)?\\{/g);\n patterns.push(/(?:export\\s+)?const\\s+(\\w+)\\s*=\\s*(?:async\\s+)?\\(([^)]*)\\)\\s*(?::\\s*[^=]*)?\\s*=>\\s*\\{/g);\n } else if (language === \"python\") {\n patterns.push(/def\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*(?:->[^:]*)?:/g);\n } else if (language === \"rust\") {\n patterns.push(/(?:pub\\s+)?(?:async\\s+)?fn\\s+(\\w+)\\s*(?:<[^>]*>)?\\s*\\(([^)]*)\\)\\s*(?:->[^{]*)?\\{/g);\n }\n return patterns;\n}\n\n// Extract all functions from a single source file\nexport function extractFunctionsFromFile(file: SourceFile): ExtractedFunction[] {\n const functions: ExtractedFunction[] = [];\n if (!file.language) return functions;\n\n const patterns = getLanguagePatterns(file.language);\n\n for (const pattern of patterns) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const name = match[1];\n const paramsStr = match[2];\n const startIndex = match.index + match[0].length;\n const line = file.content.slice(0, match.index).split(\"\\n\").length;\n\n const body = extractBody(file.content, startIndex, file.language);\n if (body.length < 10) continue;\n\n const params = paramsStr.trim() ? paramsStr.split(\",\").map((p) => p.trim()) : [];\n const declarationCode = (file.content.split(\"\\n\")[line - 1] ?? \"\").trim();\n const tokens = tokenizeBody(body);\n if (tokens.length < 5) continue;\n\n functions.push({\n name,\n file: file.path,\n relativePath: file.relativePath,\n line,\n language: file.language,\n params,\n paramCount: params.length,\n rawBody: body,\n declarationCode,\n domainCategory: detectDomainCategory(name, body),\n bodyTokens: tokens,\n bodyTokenCount: tokens.length,\n bodyHash: simpleHash(tokens),\n });\n }\n }\n\n return functions;\n}\n\n// Extract all functions from the entire analysis context\nexport function extractAllFunctions(files: SourceFile[]): ExtractedFunction[] {\n const allFunctions: ExtractedFunction[] = [];\n for (const file of files) {\n allFunctions.push(...extractFunctionsFromFile(file));\n }\n return allFunctions;\n}\n\n/** Convert an ExtractedFunction to a FunctionRef. Shared by fingerprint + opseq. */\nexport function toFunctionRef(fn: ExtractedFunction): FunctionRef {\n return { file: fn.file, relativePath: fn.relativePath, name: fn.name, line: fn.line };\n}\n","import { readFileSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\n\nlet cached: string | null = null;\n\n/**\n * Returns the current VibeDrift version, read from package.json at runtime.\n * Works both in the bundled dist/ output and when running from source.\n */\nexport function getVersion(): string {\n if (cached) return cached;\n\n try {\n const here = dirname(fileURLToPath(import.meta.url));\n // dist/index.js → ../package.json\n // src/core/version.ts (dev) → ../../package.json\n const candidates = [\n join(here, \"..\", \"package.json\"),\n join(here, \"..\", \"..\", \"package.json\"),\n join(here, \"..\", \"..\", \"..\", \"package.json\"),\n ];\n\n for (const path of candidates) {\n try {\n const content = readFileSync(path, \"utf-8\");\n const pkg = JSON.parse(content) as { name?: string; version?: string };\n if (pkg.name === \"@vibedrift/cli\" && pkg.version) {\n cached = pkg.version;\n return cached;\n }\n } catch {\n // Try next candidate\n }\n }\n } catch {\n // Fall through\n }\n\n cached = \"0.0.0\";\n return cached;\n}\n","import { createHash } from \"node:crypto\";\nimport type { ExtractedFunction, SemanticFingerprint, SemanticDuplicateGroup, FunctionRef } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\nimport { toFunctionRef } from \"./function-extractor.js\";\n\n// Normalize a function body for fingerprinting:\n// - Strip comments\n// - Replace string literals with STR, numbers with NUM\n// - Replace local variable names with positional placeholders\n// - Normalize whitespace\nfunction normalizeBody(body: string, language: string): string {\n let normalized = body;\n\n // Strip comments\n normalized = normalized.replace(/\\/\\/.*$/gm, \"\");\n normalized = normalized.replace(/#.*$/gm, \"\");\n normalized = normalized.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n\n // Replace string literals with STR\n normalized = normalized.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, \"STR\");\n normalized = normalized.replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"STR\");\n normalized = normalized.replace(/`(?:[^`\\\\]|\\\\.)*`/g, \"STR\");\n\n // Replace number literals with NUM\n normalized = normalized.replace(/\\b\\d+\\.?\\d*\\b/g, \"NUM\");\n\n // Extract local variable names and replace with positional placeholders\n const varNames = new Map<string, string>();\n let varCounter = 0;\n\n // Collect variable declarations\n // Go: var/const + := assignments\n // JS/TS: const/let/var declarations\n // Python: simple assignments\n // Rust: let/let mut\n const declPatterns = [\n /\\b(?:var|let|const)\\s+(\\w+)/g, // JS/TS/Go/Rust\n /(\\w+)\\s*:=/g, // Go short declarations\n /(\\w+)\\s*,\\s*(\\w+)\\s*:=/g, // Go multi-assign\n /^(\\w+)\\s*=/gm, // Python top-level assignment\n ];\n\n for (const pattern of declPatterns) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(normalized)) !== null) {\n for (let i = 1; i < match.length; i++) {\n const name = match[i];\n if (name && !varNames.has(name) && name.length > 1 && !/^(STR|NUM|nil|null|undefined|true|false|err|error|ctx|context)$/i.test(name)) {\n varNames.set(name, `_v${varCounter++}`);\n }\n }\n }\n }\n\n // Also collect function parameter names as variables\n // These should have been captured from the params but we can detect them in the body too\n\n // Replace variable names with placeholders (longest first to avoid partial replacements)\n const sortedVars = [...varNames.entries()].sort((a, b) => b[0].length - a[0].length);\n for (const [name, placeholder] of sortedVars) {\n // Only replace whole-word occurrences\n normalized = normalized.replace(new RegExp(`\\\\b${escapeRegex(name)}\\\\b`, \"g\"), placeholder);\n }\n\n // Normalize whitespace\n normalized = normalized.replace(/\\s+/g, \" \").trim();\n\n return normalized;\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n// Simple SHA-256-like hash using FNV-1a (fast, good distribution, no crypto dependency)\nfunction fnv1aHash(str: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n // Return as hex string, combine two passes for more bits\n const h1 = (hash >>> 0).toString(16).padStart(8, \"0\");\n let hash2 = 0x1a47e90b;\n for (let i = str.length - 1; i >= 0; i--) {\n hash2 ^= str.charCodeAt(i);\n hash2 = Math.imul(hash2, 0x01000193);\n }\n const h2 = (hash2 >>> 0).toString(16).padStart(8, \"0\");\n return h1 + h2;\n}\n\nexport function computeSemanticFingerprints(functions: ExtractedFunction[]): SemanticFingerprint[] {\n return functions.map((fn) => ({\n functionRef: toFunctionRef(fn),\n normalizedHash: fnv1aHash(normalizeBody(fn.rawBody, fn.language)),\n }));\n}\n\nexport function findDuplicateGroups(\n fingerprints: SemanticFingerprint[],\n functions: ExtractedFunction[],\n): SemanticDuplicateGroup[] {\n // Build lookup: \"name:file\" → ExtractedFunction for SHA-256 verification\n const fnLookup = new Map<string, ExtractedFunction>();\n for (const fn of functions) {\n fnLookup.set(`${fn.name}:${fn.file}`, fn);\n }\n\n // Group by FNV-1a hash (fast, but can collide)\n const byHash = new Map<string, SemanticFingerprint[]>();\n for (const fp of fingerprints) {\n if (!byHash.has(fp.normalizedHash)) byHash.set(fp.normalizedHash, []);\n byHash.get(fp.normalizedHash)!.push(fp);\n }\n\n const groups: SemanticDuplicateGroup[] = [];\n let groupCounter = 0;\n\n for (const [hash, fps] of byHash) {\n if (fps.length < 2) continue;\n\n // Verify with SHA-256 of normalized body to eliminate FNV-1a collisions\n const bySha = new Map<string, SemanticFingerprint[]>();\n for (const fp of fps) {\n const key = `${fp.functionRef.name}:${fp.functionRef.file}`;\n const fn = fnLookup.get(key);\n if (!fn) continue;\n\n const sha = createHash(\"sha256\")\n .update(normalizeBody(fn.rawBody, fn.language))\n .digest(\"hex\");\n\n if (!bySha.has(sha)) bySha.set(sha, []);\n bySha.get(sha)!.push(fp);\n }\n\n // Only emit sub-groups where ≥2 functions share the same SHA-256\n for (const [, shaGroup] of bySha) {\n if (shaGroup.length < 2) continue;\n\n const uniqueFiles = new Set(shaGroup.map((fp) => fp.functionRef.file));\n if (uniqueFiles.size < 2) continue;\n\n groups.push({\n groupId: `fingerprint-${groupCounter++}`,\n hash,\n functions: shaGroup.map((fp) => fp.functionRef),\n });\n }\n }\n\n return groups;\n}\n\nexport function fingerprintFindings(groups: SemanticDuplicateGroup[]): Finding[] {\n return groups.map((group) => {\n const names = group.functions.map((f) => `${f.name}()`).join(\", \");\n const files = group.functions.map((f) => f.relativePath);\n\n return {\n analyzerId: \"codedna-fingerprint\",\n severity: \"error\" as const,\n confidence: 1.0,\n message: `Exact semantic duplicate: ${names} have identical normalized bodies across ${files.length} files`,\n locations: group.functions.map((f) => ({\n file: f.relativePath,\n line: f.line,\n snippet: f.name + \"()\",\n })),\n tags: [\"codedna\", \"duplicate\", \"fingerprint\"],\n };\n });\n}\n","import type { ExtractedFunction, Operation, OperationSequence, SequenceSimilarity, FunctionRef } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\nimport { toFunctionRef } from \"./function-extractor.js\";\n\n// Classify each line/statement of a function body into an abstract operation type\nfunction classifyLine(line: string, language: string): Operation | null {\n const trimmed = line.trim();\n if (!trimmed || trimmed === \"{\" || trimmed === \"}\" || trimmed === \")\") return null;\n\n // INPUT — reading parameters, request body, context\n if (/(?:req\\.params|req\\.query|req\\.body|c\\.Param|c\\.QueryParam|c\\.Bind|c\\.FormValue|request\\.args|request\\.form|request\\.json|request\\.GET|request\\.POST|r\\.URL\\.Query|web::Path|web::Query|web::Json)/i.test(trimmed)) {\n return \"INPUT\";\n }\n\n // VALIDATE — schema validation, type checking, bounds\n if (/(?:validate|schema\\.parse|\\.validate\\(|zod\\.|joi\\.|assert|ensure|check.*(?:nil|null|empty|valid)|guard|sanitize)/i.test(trimmed)) {\n return \"VALIDATE\";\n }\n\n // RETURN_ERR — error returns (check before BRANCH since if err != nil { return ... } is common)\n if (/(?:return\\s+(?:nil|null|None),?\\s*(?:err|fmt\\.Errorf|errors\\.)|throw\\s+new|raise\\s+|return\\s+(?:err|error)|res\\.status\\(\\d{3,}\\)|c\\.JSON\\(\\d{3,}|http\\.Error)/i.test(trimmed)) {\n return \"RETURN_ERR\";\n }\n\n // RETURN_OK — success returns\n if (/(?:return\\s+c\\.JSON\\(2|return\\s+res\\.(?:json|send|status\\(2)|return\\s+(?:Ok|Some|jsonify)|c\\.JSON\\(http\\.Status(?:OK|Created))/i.test(trimmed)) {\n return \"RETURN_OK\";\n }\n\n // QUERY — database read operations\n if (/(?:SELECT\\s|\\.find\\(|\\.findOne\\(|\\.findAll\\(|\\.get\\(|repo\\.(?:Get|Find|List|Load)|db\\.Query(?:Row)?\\(|\\.query\\(|cursor\\.execute.*SELECT|\\.Where\\(.*\\.First\\(|\\.Where\\(.*\\.Find\\()/i.test(trimmed)) {\n return \"QUERY\";\n }\n\n // MUTATE — database write operations\n if (/(?:INSERT\\s|UPDATE\\s|DELETE\\s|\\.save\\(|\\.create\\(|\\.insert\\(|repo\\.(?:Create|Save|Store|Insert)|db\\.Exec\\(|cursor\\.execute.*(?:INSERT|UPDATE|DELETE)|\\.Remove\\(|\\.Delete\\(|\\.destroy\\()/i.test(trimmed)) {\n return \"MUTATE\";\n }\n\n // API_CALL — outbound HTTP/gRPC\n if (/(?:fetch\\(|axios\\.|http\\.(?:Get|Post|Put|Delete)\\(|\\.request\\(|requests\\.(?:get|post|put|delete)|grpc\\.|client\\.\\w+\\()/i.test(trimmed)) {\n return \"API_CALL\";\n }\n\n // RESOURCE — open/close/defer\n if (/(?:defer\\s|\\.Close\\(|\\.close\\(|fs\\.open|os\\.Open|with\\s+open|try.*finally|\\.release\\(|\\.dispose\\(|\\.end\\()/i.test(trimmed)) {\n return \"RESOURCE\";\n }\n\n // LOG — logging\n if (/(?:console\\.(?:log|warn|error|info|debug)|log\\.(?:Info|Warn|Error|Debug|Printf|Println)|logger\\.|logging\\.|slog\\.)/i.test(trimmed)) {\n return \"LOG\";\n }\n\n // LOOP — iteration\n if (/(?:^for\\s|^for\\(|\\.forEach\\(|\\.map\\(|\\.filter\\(|while\\s|while\\(|\\.each\\(|range\\s)/i.test(trimmed)) {\n return \"LOOP\";\n }\n\n // BRANCH �� conditional logic\n if (/(?:^if\\s|^if\\(|^else\\s|^else\\{|switch\\s|switch\\(|case\\s|match\\s|\\?\\s)/i.test(trimmed)) {\n return \"BRANCH\";\n }\n\n // TRANSFORM — data manipulation\n if (/(?:\\.map\\(|\\.filter\\(|\\.reduce\\(|\\.sort\\(|\\.slice\\(|\\.splice\\(|JSON\\.(?:parse|stringify)|json\\.(?:Marshal|Unmarshal)|strings\\.|strconv\\.|fmt\\.Sprintf|\\.trim\\(|\\.split\\(|\\.join\\()/i.test(trimmed)) {\n return \"TRANSFORM\";\n }\n\n return null;\n}\n\nexport function extractOperationSequences(functions: ExtractedFunction[]): OperationSequence[] {\n return functions.map((fn) => {\n const lines = fn.rawBody.split(\"\\n\");\n const sequence: Operation[] = [];\n\n for (const line of lines) {\n const op = classifyLine(line, fn.language);\n if (op) {\n if (sequence.length === 0 || sequence[sequence.length - 1] !== op) {\n sequence.push(op);\n }\n }\n }\n\n return { functionRef: toFunctionRef(fn), sequence };\n });\n}\n\n// Longest Common Subsequence length\nfunction lcsLength(a: Operation[], b: Operation[]): number {\n const m = a.length;\n const n = b.length;\n if (m === 0 || n === 0) return 0;\n\n // Space-optimized: only need previous row\n let prev = new Array(n + 1).fill(0);\n let curr = new Array(n + 1).fill(0);\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n curr[j] = prev[j - 1] + 1;\n } else {\n curr[j] = Math.max(prev[j], curr[j - 1]);\n }\n }\n [prev, curr] = [curr, prev];\n curr.fill(0);\n }\n\n return prev[n];\n}\n\nexport function findSequenceSimilarities(\n sequences: OperationSequence[],\n functions: ExtractedFunction[],\n): SequenceSimilarity[] {\n const similarities: SequenceSimilarity[] = [];\n\n // Build a map of domain categories for filtering\n const domainMap = new Map<string, string>();\n for (const fn of functions) {\n const key = `${fn.file}::${fn.name}::${fn.line}`;\n domainMap.set(key, fn.domainCategory);\n }\n\n // Only compare cross-file pairs in the same domain category\n for (let i = 0; i < sequences.length; i++) {\n const seqA = sequences[i];\n if (seqA.sequence.length < 3) continue; // Too short to be meaningful\n\n const keyA = `${seqA.functionRef.file}::${seqA.functionRef.name}::${seqA.functionRef.line}`;\n const domainA = domainMap.get(keyA);\n\n for (let j = i + 1; j < sequences.length; j++) {\n const seqB = sequences[j];\n if (seqB.sequence.length < 3) continue;\n\n // Must be in different files\n if (seqA.functionRef.file === seqB.functionRef.file) continue;\n\n // Must be in same domain category (skip \"general\" and \"request_handling\")\n const keyB = `${seqB.functionRef.file}::${seqB.functionRef.name}::${seqB.functionRef.line}`;\n const domainB = domainMap.get(keyB);\n if (!domainA || !domainB || domainA !== domainB) continue;\n if (domainA === \"general\" || domainA === \"request_handling\") continue;\n\n const lcs = lcsLength(seqA.sequence, seqB.sequence);\n const maxLen = Math.max(seqA.sequence.length, seqB.sequence.length);\n const similarity = maxLen > 0 ? lcs / maxLen : 0;\n\n if (similarity >= 0.80) {\n similarities.push({\n functionA: seqA.functionRef,\n functionB: seqB.functionRef,\n similarity,\n lcsLength: lcs,\n maxLength: maxLen,\n });\n }\n }\n }\n\n return similarities;\n}\n\nexport function sequenceFindings(similarities: SequenceSimilarity[]): Finding[] {\n return similarities.map((sim) => ({\n analyzerId: \"codedna-opseq\",\n severity: \"warning\" as const,\n confidence: Math.min(sim.similarity, 0.95),\n message: `Near-duplicate operation sequence: ${sim.functionA.name}() and ${sim.functionB.name}() share ${Math.round(sim.similarity * 100)}% of their operation flow`,\n locations: [\n { file: sim.functionA.relativePath, line: sim.functionA.line, snippet: sim.functionA.name + \"()\" },\n { file: sim.functionB.relativePath, line: sim.functionB.line, snippet: sim.functionB.name + \"()\" },\n ],\n tags: [\"codedna\", \"duplicate\", \"opseq\"],\n }));\n}\n","import type { SourceFile } from \"../core/types.js\";\nimport type { ArchPattern, PatternDistribution, PatternSignal } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\n\ninterface SignalDef {\n pattern: ArchPattern;\n regex: RegExp;\n label: string;\n}\n\n// Signals that indicate each architectural pattern\nconst SIGNAL_DEFS: SignalDef[] = [\n // Repository pattern\n { pattern: \"repository\", regex: /(?:repository|repo|store)\\.\\w+\\(/i, label: \"calls repo/store method\" },\n { pattern: \"repository\", regex: /import.*(?:repositories|repos|store)\\b/i, label: \"imports from repository layer\" },\n { pattern: \"repository\", regex: /this\\.repo(?:sitory)?\\.|h\\.repo\\.|s\\.store\\.|\\.repository\\./i, label: \"accesses injected repository\" },\n\n // Raw SQL\n { pattern: \"raw_sql\", regex: /(?:SELECT|INSERT\\s+INTO|UPDATE\\s+\\w+\\s+SET|DELETE\\s+FROM)\\s/i, label: \"SQL statement literal\" },\n { pattern: \"raw_sql\", regex: /db\\.Query(?:Row)?\\s*\\(/i, label: \"direct db.Query call\" },\n { pattern: \"raw_sql\", regex: /db\\.Exec\\s*\\(/i, label: \"direct db.Exec call\" },\n { pattern: \"raw_sql\", regex: /cursor\\.execute\\s*\\(/i, label: \"cursor.execute call\" },\n { pattern: \"raw_sql\", regex: /\\.query\\s*\\(\\s*[`'\"]/i, label: \"inline SQL query string\" },\n\n // ORM\n { pattern: \"orm\", regex: /(?:gorm|prisma|sequelize|typeorm|sqlalchemy|django\\.db|ent\\.)\\.?/i, label: \"ORM import/usage\" },\n { pattern: \"orm\", regex: /\\.Find\\(\\s*&|\\.Create\\(\\s*&|\\.Save\\(\\s*&|\\.Where\\(/i, label: \"ORM method call (Go)\" },\n { pattern: \"orm\", regex: /\\.findOne\\(|\\.findAll\\(|\\.create\\(.*{|\\.update\\(.*{|\\.destroy\\(/i, label: \"ORM method call (JS)\" },\n { pattern: \"orm\", regex: /objects\\.(?:filter|get|create|all)\\(/i, label: \"Django ORM call\" },\n\n // Direct DB\n { pattern: \"direct_db\", regex: /sql\\.Open\\(|pgx\\.Connect|mysql\\.Open|mongo\\.Connect/i, label: \"direct DB connection\" },\n { pattern: \"direct_db\", regex: /new\\s+(?:Pool|Client)\\(/i, label: \"direct DB pool/client\" },\n\n // HTTP client\n { pattern: \"http_client\", regex: /http\\.(?:Get|Post|Put|Delete)\\(/i, label: \"HTTP client call\" },\n { pattern: \"http_client\", regex: /fetch\\(|axios\\.|requests\\.(?:get|post)/i, label: \"HTTP fetch/axios/requests\" },\n];\n\n// Files that are likely \"handler\" or \"service\" files (where pattern drift matters)\nfunction isHandlerOrServiceFile(path: string): boolean {\n return /(?:handler|controller|service|route|endpoint|api|resource)/i.test(path);\n}\n\nfunction classifyFile(file: SourceFile): PatternDistribution | null {\n if (!file.language) return null;\n if (!isHandlerOrServiceFile(file.relativePath)) return null;\n\n const lines = file.content.split(\"\\n\");\n const signals: PatternSignal[] = [];\n const counts: Partial<Record<ArchPattern, number>> = {};\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n for (const def of SIGNAL_DEFS) {\n if (def.regex.test(line)) {\n signals.push({ pattern: def.pattern, signal: def.label, line: i + 1 });\n counts[def.pattern] = (counts[def.pattern] ?? 0) + 1;\n }\n }\n }\n\n // No signals found → not classifiable\n const totalSignals = Object.values(counts).reduce((sum, c) => sum + c, 0);\n if (totalSignals === 0) return null;\n\n // Normalize to probability distribution\n const patterns: Partial<Record<ArchPattern, number>> = {};\n for (const [pattern, count] of Object.entries(counts)) {\n patterns[pattern as ArchPattern] = Math.round((count / totalSignals) * 100) / 100;\n }\n\n // Find dominant pattern\n let dominantPattern: ArchPattern = \"none\";\n let maxProb = 0;\n for (const [pattern, prob] of Object.entries(patterns)) {\n if (prob > maxProb) {\n maxProb = prob;\n dominantPattern = pattern as ArchPattern;\n }\n }\n\n // Detect internal inconsistency: no single pattern > 60%\n const isInternallyInconsistent = maxProb < 0.6 && Object.keys(patterns).length > 1;\n\n return {\n file: file.path,\n relativePath: file.relativePath,\n patterns,\n dominantPattern,\n confidence: maxProb,\n signals,\n isInternallyInconsistent,\n };\n}\n\nexport function classifyPatterns(files: SourceFile[]): PatternDistribution[] {\n const distributions: PatternDistribution[] = [];\n for (const file of files) {\n const dist = classifyFile(file);\n if (dist) distributions.push(dist);\n }\n return distributions;\n}\n\nexport function patternFindings(distributions: PatternDistribution[]): Finding[] {\n const findings: Finding[] = [];\n\n if (distributions.length < 2) return findings;\n\n // Find project-wide dominant pattern\n const patternCounts = new Map<ArchPattern, number>();\n for (const dist of distributions) {\n patternCounts.set(dist.dominantPattern, (patternCounts.get(dist.dominantPattern) ?? 0) + 1);\n }\n\n let projectDominant: ArchPattern = \"none\";\n let maxCount = 0;\n for (const [pattern, count] of patternCounts) {\n if (count > maxCount) {\n maxCount = count;\n projectDominant = pattern;\n }\n }\n\n // Flag files that deviate from the project-wide dominant pattern\n for (const dist of distributions) {\n if (dist.dominantPattern !== projectDominant && projectDominant !== \"none\") {\n findings.push({\n analyzerId: \"codedna-pattern\",\n severity: \"warning\",\n confidence: dist.confidence,\n message: `Pattern drift: ${dist.relativePath} uses ${dist.dominantPattern} while ${maxCount}/${distributions.length} files use ${projectDominant}`,\n locations: dist.signals.slice(0, 3).map((s) => ({\n file: dist.relativePath,\n line: s.line,\n snippet: s.signal,\n })),\n tags: [\"codedna\", \"pattern\", \"drift\"],\n });\n }\n\n // Flag internally inconsistent files\n if (dist.isInternallyInconsistent) {\n const patternList = Object.entries(dist.patterns)\n .map(([p, prob]) => `${p}: ${Math.round(prob * 100)}%`)\n .join(\", \");\n findings.push({\n analyzerId: \"codedna-pattern\",\n severity: \"info\",\n confidence: 0.6,\n message: `Mixed patterns in ${dist.relativePath}: ${patternList} — file mixes architectural approaches internally`,\n locations: [{ file: dist.relativePath }],\n tags: [\"codedna\", \"pattern\", \"mixed\"],\n });\n }\n }\n\n return findings;\n}\n","import type { SourceFile, SupportedLanguage } from \"../core/types.js\";\nimport type { TaintFlow, TaintSource, TaintSink } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\nimport type { ExtractedFunction } from \"./types.js\";\n\n// ──── Taint Sources (user input entry points) ────\n\ninterface SourcePattern {\n regex: RegExp;\n label: string;\n}\n\nconst TAINT_SOURCES: Record<string, SourcePattern[]> = {\n go: [\n { regex: /c\\.Param\\s*\\(/, label: \"URL parameter\" },\n { regex: /c\\.QueryParam\\s*\\(/, label: \"query parameter\" },\n { regex: /c\\.Bind\\s*\\(/, label: \"request body binding\" },\n { regex: /c\\.FormValue\\s*\\(/, label: \"form value\" },\n { regex: /r\\.URL\\.Query\\s*\\(\\)/, label: \"query string\" },\n { regex: /r\\.FormValue\\s*\\(/, label: \"form value\" },\n { regex: /json\\.NewDecoder\\s*\\(\\s*r\\.Body/, label: \"request body JSON\" },\n { regex: /mux\\.Vars\\s*\\(/, label: \"URL path variable\" },\n ],\n javascript: [\n { regex: /req\\.params\\.\\w+/, label: \"URL parameter\" },\n { regex: /req\\.query\\.\\w+/, label: \"query parameter\" },\n { regex: /req\\.body\\.\\w+/, label: \"request body\" },\n { regex: /c\\.req\\.param\\s*\\(/, label: \"Hono parameter\" },\n { regex: /event\\.(?:pathParameters|queryStringParameters)/, label: \"Lambda parameter\" },\n ],\n typescript: [\n { regex: /req\\.params\\.\\w+/, label: \"URL parameter\" },\n { regex: /req\\.query\\.\\w+/, label: \"query parameter\" },\n { regex: /req\\.body\\.\\w+/, label: \"request body\" },\n { regex: /c\\.req\\.param\\s*\\(/, label: \"Hono parameter\" },\n ],\n python: [\n { regex: /request\\.args\\.get\\s*\\(/, label: \"query parameter\" },\n { regex: /request\\.form\\.get\\s*\\(/, label: \"form value\" },\n { regex: /request\\.json/, label: \"request JSON body\" },\n { regex: /request\\.GET\\.get\\s*\\(/, label: \"GET parameter\" },\n { regex: /request\\.POST\\.get\\s*\\(/, label: \"POST parameter\" },\n { regex: /request\\.data/, label: \"request data\" },\n ],\n rust: [\n { regex: /web::Path/, label: \"URL path parameter\" },\n { regex: /web::Query/, label: \"query parameter\" },\n { regex: /web::Json/, label: \"request JSON body\" },\n ],\n};\n\n// ──── Dangerous Sinks ────\n\ninterface SinkPattern {\n regex: RegExp;\n label: string;\n severity: \"error\" | \"warning\";\n category: string;\n}\n\nconst TAINT_SINKS: SinkPattern[] = [\n // SQL injection\n { regex: /db\\.Query\\s*\\(/, label: \"SQL query\", severity: \"error\", category: \"sql_injection\" },\n { regex: /db\\.Exec\\s*\\(/, label: \"SQL exec\", severity: \"error\", category: \"sql_injection\" },\n { regex: /\\.query\\s*\\(\\s*[`'\"]/, label: \"SQL query string\", severity: \"error\", category: \"sql_injection\" },\n { regex: /cursor\\.execute\\s*\\(/, label: \"SQL execute\", severity: \"error\", category: \"sql_injection\" },\n { regex: /\\.raw\\s*\\(/, label: \"raw SQL query\", severity: \"error\", category: \"sql_injection\" },\n\n // Command injection\n { regex: /exec\\s*\\(/, label: \"command execution\", severity: \"error\", category: \"command_injection\" },\n { regex: /execSync\\s*\\(/, label: \"sync command execution\", severity: \"error\", category: \"command_injection\" },\n { regex: /child_process/, label: \"child process\", severity: \"error\", category: \"command_injection\" },\n { regex: /os\\.system\\s*\\(/, label: \"OS system call\", severity: \"error\", category: \"command_injection\" },\n { regex: /subprocess\\.(?:call|run|Popen)\\s*\\(/, label: \"subprocess call\", severity: \"error\", category: \"command_injection\" },\n\n // Path traversal\n { regex: /fs\\.readFile\\s*\\(/, label: \"file read\", severity: \"warning\", category: \"path_traversal\" },\n { regex: /fs\\.writeFile\\s*\\(/, label: \"file write\", severity: \"warning\", category: \"path_traversal\" },\n { regex: /os\\.Open\\s*\\(/, label: \"file open\", severity: \"warning\", category: \"path_traversal\" },\n { regex: /open\\s*\\(/, label: \"file open\", severity: \"warning\", category: \"path_traversal\" },\n\n // XSS\n { regex: /innerHTML\\s*=/, label: \"HTML injection\", severity: \"error\", category: \"xss\" },\n { regex: /dangerouslySetInnerHTML/, label: \"React HTML injection\", severity: \"error\", category: \"xss\" },\n { regex: /eval\\s*\\(/, label: \"code evaluation\", severity: \"error\", category: \"code_injection\" },\n { regex: /Function\\s*\\(/, label: \"dynamic function\", severity: \"error\", category: \"code_injection\" },\n\n // Outbound (lower severity)\n { regex: /fetch\\s*\\(/, label: \"outbound HTTP fetch\", severity: \"warning\", category: \"ssrf\" },\n { regex: /http\\.Get\\s*\\(/, label: \"outbound HTTP GET\", severity: \"warning\", category: \"ssrf\" },\n { regex: /axios\\.\\w+\\s*\\(/, label: \"outbound HTTP request\", severity: \"warning\", category: \"ssrf\" },\n];\n\n// ──── Sanitizers that remove taint ────\n\ninterface SanitizerPattern {\n regex: RegExp;\n label: string;\n removes: string | \"all\";\n}\n\nconst SANITIZERS: SanitizerPattern[] = [\n // Type coercion (removes SQL injection for numbers)\n { regex: /parseInt\\s*\\(/, label: \"parseInt\", removes: \"sql_injection\" },\n { regex: /parseFloat\\s*\\(/, label: \"parseFloat\", removes: \"sql_injection\" },\n { regex: /Number\\s*\\(/, label: \"Number()\", removes: \"sql_injection\" },\n { regex: /strconv\\.Atoi\\s*\\(/, label: \"strconv.Atoi\", removes: \"sql_injection\" },\n { regex: /strconv\\.Parse\\w+\\s*\\(/, label: \"strconv.Parse*\", removes: \"sql_injection\" },\n { regex: /int\\s*\\(/, label: \"int()\", removes: \"sql_injection\" },\n\n // Parameterized queries\n { regex: /\\$\\d+/, label: \"parameterized query ($N)\", removes: \"sql_injection\" },\n { regex: /\\?\\s*(?:,|\\)|\\])/, label: \"parameterized query (?)\", removes: \"sql_injection\" },\n\n // Schema validation (removes all taint)\n { regex: /schema\\.parse\\s*\\(/, label: \"schema.parse()\", removes: \"all\" },\n { regex: /\\.validate\\s*\\(/, label: \".validate()\", removes: \"all\" },\n { regex: /zod\\./i, label: \"Zod validation\", removes: \"all\" },\n { regex: /joi\\./i, label: \"Joi validation\", removes: \"all\" },\n\n // HTML escaping\n { regex: /escape\\s*\\(/, label: \"escape()\", removes: \"xss\" },\n { regex: /sanitize\\s*\\(/, label: \"sanitize()\", removes: \"xss\" },\n { regex: /DOMPurify/i, label: \"DOMPurify\", removes: \"xss\" },\n { regex: /html\\.EscapeString/i, label: \"html.EscapeString\", removes: \"xss\" },\n\n // Path sanitization\n { regex: /path\\.(?:join|resolve|normalize)\\s*\\(/, label: \"path.join/resolve\", removes: \"path_traversal\" },\n { regex: /filepath\\.(?:Clean|Abs)\\s*\\(/, label: \"filepath.Clean\", removes: \"path_traversal\" },\n];\n\n// ──── Taint Tracking Engine (per-function scope) ────\n\ninterface TaintedVar {\n name: string;\n source: TaintSource;\n sanitizedFor: Set<string>; // categories sanitized\n}\n\nfunction extractAssignedVariable(line: string): string | null {\n // Go/JS/TS: var/const/let name = ... or name :=\n const declMatch = line.match(/(?:var|const|let)\\s+(\\w+)\\s*[:=]/);\n if (declMatch) return declMatch[1];\n\n const shortDeclMatch = line.match(/(\\w+)\\s*:=/);\n if (shortDeclMatch) return shortDeclMatch[1];\n\n // Simple assignment: name = ...\n const assignMatch = line.match(/^(\\w+)\\s*=/);\n if (assignMatch) return assignMatch[1];\n\n // Python: name = ...\n const pyMatch = line.match(/^\\s*(\\w+)\\s*=/);\n if (pyMatch) return pyMatch[1];\n\n return null;\n}\n\nconst ALL_TAINT_CATEGORIES = new Set([\"sql_injection\", \"command_injection\", \"path_traversal\", \"xss\", \"ssrf\", \"code_injection\"]);\n\nfunction identifySources(\n trimmed: string,\n langSources: SourcePattern[],\n lineNumber: number,\n taintedVars: Map<string, TaintedVar>,\n): void {\n for (const src of langSources) {\n if (src.regex.test(trimmed)) {\n const varName = extractAssignedVariable(trimmed);\n if (varName) {\n taintedVars.set(varName, {\n name: varName,\n source: { type: src.label, variable: varName, line: lineNumber },\n sanitizedFor: new Set(),\n });\n }\n }\n }\n}\n\nfunction checkSanitizers(\n trimmed: string,\n taintedVars: Map<string, TaintedVar>,\n): void {\n for (const [varName, tainted] of taintedVars) {\n if (!trimmed.includes(varName)) continue;\n for (const san of SANITIZERS) {\n if (san.regex.test(trimmed)) {\n if (san.removes === \"all\") {\n tainted.sanitizedFor = new Set(ALL_TAINT_CATEGORIES);\n } else {\n tainted.sanitizedFor.add(san.removes);\n }\n }\n }\n }\n}\n\nfunction identifySinks(\n trimmed: string,\n fn: ExtractedFunction,\n lineNumber: number,\n taintedVars: Map<string, TaintedVar>,\n flows: TaintFlow[],\n): void {\n for (const sink of TAINT_SINKS) {\n if (!sink.regex.test(trimmed)) continue;\n\n for (const [varName, tainted] of taintedVars) {\n if (!trimmed.includes(varName)) continue;\n if (tainted.sanitizedFor.has(sink.category)) continue;\n\n // Check inline sanitization on the same line\n let inlineSanitized = false;\n for (const san of SANITIZERS) {\n if (san.regex.test(trimmed) && (san.removes === \"all\" || san.removes === sink.category)) {\n inlineSanitized = true;\n break;\n }\n }\n if (inlineSanitized) continue;\n\n flows.push({\n file: fn.file,\n relativePath: fn.relativePath,\n functionName: fn.name,\n source: tainted.source,\n sink: { type: sink.label, expression: trimmed.slice(0, 100), line: lineNumber, severity: sink.severity },\n sanitized: false,\n language: fn.language,\n });\n }\n }\n}\n\nfunction analyzeFunction(\n fn: ExtractedFunction,\n): TaintFlow[] {\n const flows: TaintFlow[] = [];\n const lines = fn.rawBody.split(\"\\n\");\n const taintedVars = new Map<string, TaintedVar>();\n const langSources = TAINT_SOURCES[fn.language] ?? [];\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n const lineNumber = fn.line + i;\n\n identifySources(trimmed, langSources, lineNumber, taintedVars);\n checkSanitizers(trimmed, taintedVars);\n identifySinks(trimmed, fn, lineNumber, taintedVars, flows);\n }\n\n return flows;\n}\n\nexport function analyzeTaintFlows(functions: ExtractedFunction[]): TaintFlow[] {\n const allFlows: TaintFlow[] = [];\n for (const fn of functions) {\n allFlows.push(...analyzeFunction(fn));\n }\n return allFlows;\n}\n\nexport function taintFindings(flows: TaintFlow[]): Finding[] {\n // Deduplicate by file+function+sink type\n const seen = new Set<string>();\n\n return flows\n .filter((flow) => {\n const key = `${flow.relativePath}:${flow.functionName}:${flow.sink.type}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .map((flow) => ({\n analyzerId: \"codedna-taint\",\n severity: flow.sink.severity,\n confidence: 0.75,\n message: `Unsanitized ${flow.source.type} reaches ${flow.sink.type} in ${flow.functionName}(): ${flow.source.variable} (line ${flow.source.line}) → ${flow.sink.type} (line ${flow.sink.line})`,\n locations: [\n { file: flow.relativePath, line: flow.source.line, snippet: `${flow.source.variable} = ${flow.source.type}` },\n { file: flow.relativePath, line: flow.sink.line, snippet: flow.sink.expression.slice(0, 80) },\n ],\n tags: [\"codedna\", \"taint\", \"security\"],\n }));\n}\n","import type { SourceFile } from \"../core/types.js\";\nimport type { PatternDistribution, DeviationJustification, JustificationSignal, ArchPattern } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\n\n// Special directories where deviations are more likely justified\nconst SPECIAL_DIRS = /(?:reporting|analytics|admin|migration|scripts|tools|benchmark|seed|fixtures|test)/i;\n\n// Complex SQL indicators (justify raw SQL over repository pattern)\nconst COMPLEX_SQL_INDICATORS = [\n /\\bGROUP\\s+BY\\b/i,\n /\\bHAVING\\b/i,\n /\\bWINDOW\\b/i,\n /\\bOVER\\s*\\(/i,\n /\\bWITH\\s+\\w+\\s+AS\\s*\\(/i, // CTEs\n /\\bUNION\\b/i,\n /\\bEXCEPT\\b/i,\n /\\bINTERSECT\\b/i,\n /JOIN.*JOIN.*JOIN/is, // 3+ JOINs\n /\\bLATERAL\\b/i,\n /\\bEXISTS\\s*\\(/i,\n];\n\n// Explanatory comment patterns near deviations\nconst COMMENT_EXPLAINS = /(?:performance|optimization|complex\\s+query|custom\\s+sql|raw\\s+sql|aggregate|report|analytics|workaround|intentional|reason|because|note:|todo:|hack:)/i;\n\nfunction countComplexSqlSignals(content: string): number {\n let count = 0;\n for (const pattern of COMPLEX_SQL_INDICATORS) {\n if (pattern.test(content)) count++;\n }\n return count;\n}\n\nfunction hasExplanatoryComment(content: string, lines: string[], deviationLine?: number): boolean {\n // Check comments near the deviation (within 5 lines above the SQL/pattern usage)\n if (deviationLine !== undefined) {\n const start = Math.max(0, deviationLine - 5);\n const end = Math.min(lines.length, deviationLine + 3);\n const nearby = lines.slice(start, end).join(\"\\n\");\n if (COMMENT_EXPLAINS.test(nearby)) return true;\n }\n\n // Also check file-level comments\n const firstLines = lines.slice(0, 10).join(\"\\n\");\n return COMMENT_EXPLAINS.test(firstLines);\n}\n\nfunction isInSpecialDirectory(path: string): boolean {\n return SPECIAL_DIRS.test(path);\n}\n\nfunction computeSignalScore(\n file: SourceFile,\n devDist: PatternDistribution,\n dominantFiles: PatternDistribution[],\n projectDominant: ArchPattern,\n): { signals: JustificationSignal[]; totalWeight: number } {\n const lines = file.content.split(\"\\n\");\n const signals: JustificationSignal[] = [];\n let totalWeight = 0;\n\n // Complex SQL present\n const sqlComplexity = countComplexSqlSignals(file.content);\n if (sqlComplexity > 0) {\n const weight = Math.min(sqlComplexity * 0.15, 0.3);\n signals.push({ type: \"complex_sql\", present: true, weight, evidence: `${sqlComplexity} complex SQL indicators` });\n totalWeight += weight;\n } else {\n signals.push({ type: \"complex_sql\", present: false, weight: 0 });\n }\n\n // Explanatory comment\n const firstSignalLine = devDist.signals[0]?.line;\n if (hasExplanatoryComment(file.content, lines, firstSignalLine)) {\n signals.push({ type: \"explanatory_comment\", present: true, weight: 0.2, evidence: \"comment explains deviation\" });\n totalWeight += 0.2;\n } else {\n signals.push({ type: \"no_comment\", present: true, weight: -0.1, evidence: \"no explanatory comment\" });\n totalWeight -= 0.1;\n }\n\n // Special directory\n if (isInSpecialDirectory(devDist.relativePath)) {\n signals.push({ type: \"special_directory\", present: true, weight: 0.2, evidence: devDist.relativePath });\n totalWeight += 0.2;\n }\n\n // Simple CRUD SQL (no complex indicators)\n if (devDist.dominantPattern === \"raw_sql\" && sqlComplexity === 0) {\n const hasCrudOnly = /(?:SELECT\\s+\\*|INSERT\\s+INTO|UPDATE\\s+\\w+\\s+SET|DELETE\\s+FROM)/i.test(file.content);\n if (hasCrudOnly) {\n signals.push({ type: \"simple_crud\", present: true, weight: -0.3, evidence: \"simple CRUD SQL without complex operations\" });\n totalWeight -= 0.3;\n }\n }\n\n // Same directory as dominant-pattern files\n const devDir = devDist.relativePath.includes(\"/\") ? devDist.relativePath.slice(0, devDist.relativePath.lastIndexOf(\"/\")) : \".\";\n const sameDir = dominantFiles.filter((d) => {\n const dir = d.relativePath.includes(\"/\") ? d.relativePath.slice(0, d.relativePath.lastIndexOf(\"/\")) : \".\";\n return dir === devDir;\n });\n if (sameDir.length > 0) {\n signals.push({ type: \"same_directory_as_dominant\", present: true, weight: -0.2, evidence: `${sameDir.length} files in same directory use ${projectDominant}` });\n totalWeight -= 0.2;\n }\n\n return { signals, totalWeight };\n}\n\nfunction classifyDeviation(totalWeight: number): { justificationScore: number; verdict: DeviationJustification[\"verdict\"] } {\n const rawScore = 0.5 + totalWeight;\n const justificationScore = Math.max(0, Math.min(1, rawScore));\n\n let verdict: DeviationJustification[\"verdict\"];\n if (justificationScore >= 0.6) verdict = \"likely_justified\";\n else if (justificationScore <= 0.3) verdict = \"likely_accidental\";\n else verdict = \"uncertain\";\n\n return { justificationScore, verdict };\n}\n\nexport function scoreDeviations(\n distributions: PatternDistribution[],\n files: SourceFile[],\n): DeviationJustification[] {\n if (distributions.length < 2) return [];\n\n // Find project-wide dominant pattern\n const patternCounts = new Map<ArchPattern, number>();\n for (const dist of distributions) {\n patternCounts.set(dist.dominantPattern, (patternCounts.get(dist.dominantPattern) ?? 0) + 1);\n }\n\n let projectDominant: ArchPattern = \"none\";\n let maxCount = 0;\n for (const [pattern, count] of patternCounts) {\n if (count > maxCount) {\n maxCount = count;\n projectDominant = pattern;\n }\n }\n\n if (projectDominant === \"none\") return [];\n\n const justifications: DeviationJustification[] = [];\n\n // Find files deviating from the dominant pattern\n const dominantFiles = distributions.filter((d) => d.dominantPattern === projectDominant);\n const deviatingFiles = distributions.filter((d) => d.dominantPattern !== projectDominant);\n\n for (const devDist of deviatingFiles) {\n const file = files.find((f) => f.path === devDist.file || f.relativePath === devDist.relativePath);\n if (!file) continue;\n\n const { signals, totalWeight } = computeSignalScore(file, devDist, dominantFiles, projectDominant);\n const { justificationScore, verdict } = classifyDeviation(totalWeight);\n\n justifications.push({\n file: devDist.file,\n relativePath: devDist.relativePath,\n deviatingPattern: devDist.dominantPattern,\n dominantPattern: projectDominant,\n justificationScore,\n signals,\n verdict,\n });\n }\n\n return justifications;\n}\n\nexport function deviationFindings(justifications: DeviationJustification[]): Finding[] {\n return justifications\n .filter((j) => j.verdict === \"likely_accidental\")\n .map((j) => {\n const signalSummary = j.signals\n .filter((s) => s.present && s.weight !== 0)\n .map((s) => s.evidence)\n .filter(Boolean)\n .join(\"; \");\n\n return {\n analyzerId: \"codedna-deviation\",\n severity: \"warning\" as const,\n confidence: Math.max(0.5, 1 - j.justificationScore),\n message: `Likely accidental deviation: ${j.relativePath} uses ${j.deviatingPattern} while project uses ${j.dominantPattern}. Signals: ${signalSummary}`,\n locations: [{ file: j.relativePath }],\n tags: [\"codedna\", \"deviation\", \"accidental\"],\n };\n });\n}\n","import type { AnalysisContext, Finding } from \"../core/types.js\";\nimport type { CodeDnaResult } from \"./types.js\";\nimport { extractAllFunctions } from \"./function-extractor.js\";\nimport { computeSemanticFingerprints, findDuplicateGroups, fingerprintFindings } from \"./semantic-fingerprint.js\";\nimport { extractOperationSequences, findSequenceSimilarities, sequenceFindings } from \"./operation-sequence.js\";\nimport { classifyPatterns, patternFindings } from \"./pattern-classifier.js\";\nimport { analyzeTaintFlows, taintFindings } from \"./taint-analysis.js\";\nimport { scoreDeviations, deviationFindings } from \"./deviation-heuristics.js\";\n\nexport function runCodeDnaAnalysis(ctx: AnalysisContext): CodeDnaResult {\n const timings = {\n extractionMs: 0,\n fingerprintMs: 0,\n sequenceMs: 0,\n patternMs: 0,\n taintMs: 0,\n deviationMs: 0,\n totalMs: 0,\n };\n\n const totalStart = Date.now();\n\n // 1. Extract all functions (shared across modules)\n let t = Date.now();\n const functions = extractAllFunctions(ctx.files);\n timings.extractionMs = Date.now() - t;\n\n // 2. Semantic fingerprinting (Module 1)\n t = Date.now();\n const fingerprints = computeSemanticFingerprints(functions);\n const duplicateGroups = findDuplicateGroups(fingerprints, functions);\n timings.fingerprintMs = Date.now() - t;\n\n // 3. Operation sequence analysis (Module 2)\n t = Date.now();\n const sequences = extractOperationSequences(functions);\n const sequenceSimilarities = findSequenceSimilarities(sequences, functions);\n timings.sequenceMs = Date.now() - t;\n\n // 4. Pattern classification (Module 3)\n t = Date.now();\n const patternDistributions = classifyPatterns(ctx.files);\n timings.patternMs = Date.now() - t;\n\n // 5. Taint analysis (Module 4)\n t = Date.now();\n const taintFlows = analyzeTaintFlows(functions);\n timings.taintMs = Date.now() - t;\n\n // 6. Deviation heuristics (Module 5) — uses pattern distributions\n t = Date.now();\n const deviationJustifications = scoreDeviations(patternDistributions, ctx.files);\n timings.deviationMs = Date.now() - t;\n\n // Aggregate all findings\n const findings: Finding[] = [\n ...fingerprintFindings(duplicateGroups),\n ...sequenceFindings(sequenceSimilarities),\n ...patternFindings(patternDistributions),\n ...taintFindings(taintFlows),\n ...deviationFindings(deviationJustifications),\n ];\n\n timings.totalMs = Date.now() - totalStart;\n\n return {\n functions,\n fingerprints,\n duplicateGroups,\n sequenceSimilarities,\n patternDistributions,\n taintFlows,\n deviationJustifications,\n findings,\n timings,\n };\n}\n","import type { AnalysisContext, Finding } from \"../core/types.js\";\nimport type { ExtractedFunction } from \"../codedna/types.js\";\nimport type { MlFunctionPayload } from \"./types.js\";\n\nconst MAX_FUNCTIONS = 30;\nconst MAX_LINES_PER_FUNCTION = 60;\n\nexport function sampleFunctionsForMl(\n functions: ExtractedFunction[],\n findings: Finding[],\n): MlFunctionPayload[] {\n // Score functions by importance\n const scored = functions.map((fn) => {\n let score = 0;\n\n // Entry point files are high priority\n if (/(?:main|index|app|server|lib|mod)\\./i.test(fn.file)) score += 10;\n\n // Files with existing findings\n const fnFindings = findings.filter((f) =>\n f.locations.some((l) => l.file === fn.relativePath),\n );\n score += fnFindings.length * 3;\n\n // Larger functions are more interesting\n const bodyLines = fn.rawBody.split(\"\\n\").length;\n score += Math.min(bodyLines / 20, 5);\n\n // Handler/service files\n if (/(?:handler|controller|service|route|endpoint)/i.test(fn.file)) score += 3;\n\n return { fn, score };\n });\n\n // Sort by score descending, take top N\n scored.sort((a, b) => b.score - a.score);\n const selected = scored.slice(0, MAX_FUNCTIONS);\n\n return selected.map(({ fn }) => {\n // Truncate body to max lines\n const bodyLines = fn.rawBody.split(\"\\n\");\n const truncatedBody =\n bodyLines.length > MAX_LINES_PER_FUNCTION\n ? bodyLines.slice(0, MAX_LINES_PER_FUNCTION).join(\"\\n\") + \"\\n// ... truncated\"\n : fn.rawBody;\n\n return {\n id: `${fn.relativePath}::${fn.name}`,\n name: fn.name,\n file: fn.relativePath,\n body: truncatedBody,\n line_start: fn.line,\n line_end: fn.line + bodyLines.length,\n language: fn.language,\n };\n });\n}\n","import type { MlAnalyzeRequest, MlAnalyzeResponse } from \"./types.js\";\n\nconst DEFAULT_API_URL = \"https://vibedrift-api.fly.dev\";\nconst TIMEOUT_MS = 90_000; // 90s to handle cold starts with model loading\n\n/**\n * Call the VibeDrift deep-analysis API.\n *\n * Authenticates with a Bearer token from the user's `vibedrift login`\n * session (stored at ~/.vibedrift/config.json or in VIBEDRIFT_TOKEN).\n */\nexport async function callMlApi(\n request: MlAnalyzeRequest,\n token?: string,\n apiUrl?: string,\n): Promise<MlAnalyzeResponse> {\n const url = `${apiUrl ?? DEFAULT_API_URL}/v1/analyze`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(request),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"\");\n throw new Error(`Deep-analysis API error ${response.status}: ${errorBody.slice(0, 200)}`);\n }\n\n return (await response.json()) as MlAnalyzeResponse;\n } finally {\n clearTimeout(timeout);\n }\n}\n","import type { Finding } from \"../core/types.js\";\nimport type {\n MlAnalyzeResponse,\n MlFindingForLlm,\n FilteredMlResults,\n} from \"./types.js\";\n\nconst HIGH_CONFIDENCE_THRESHOLD = 0.85;\nconst MEDIUM_CONFIDENCE_THRESHOLD = 0.50;\nconst MAX_LLM_CANDIDATES = 5;\n\nexport function filterByConfidence(response: MlAnalyzeResponse): FilteredMlResults {\n const highConfidence: Finding[] = [];\n const mediumConfidence: MlFindingForLlm[] = [];\n let droppedCount = 0;\n\n // ──── Process duplicates ────\n for (const dup of response.duplicates) {\n if (dup.confidence >= HIGH_CONFIDENCE_THRESHOLD) {\n highConfidence.push({\n analyzerId: \"ml-duplicate\",\n severity: \"error\",\n confidence: dup.confidence,\n message: `ML-detected semantic duplicate: ${dup.function_a} and ${dup.function_b} (${Math.round(dup.similarity * 100)}% similar)`,\n locations: [\n { file: dup.function_a.split(\"::\")[0] },\n { file: dup.function_b.split(\"::\")[0] },\n ],\n tags: [\"ml\", \"duplicate\"],\n });\n } else if (dup.confidence >= MEDIUM_CONFIDENCE_THRESHOLD) {\n mediumConfidence.push({\n type: \"duplicate\",\n confidence: dup.confidence,\n detail: dup,\n question: `Are ${dup.function_a} and ${dup.function_b} doing the same thing? Similarity: ${Math.round(dup.similarity * 100)}%`,\n });\n } else {\n droppedCount++;\n }\n }\n\n // ──── Process intent mismatches ────\n // Single-word function names (Accept, Quote, List, Verify) are inherently hard\n // to embed semantically — a single word can't convey enough meaning for reliable\n // name-body comparison. Only flag names with 2+ words where semantic distance is clear.\n const GENERIC_SINGLE_WORDS = new Set([\n \"handle\", \"process\", \"get\", \"set\", \"run\", \"do\", \"make\", \"create\",\n \"update\", \"delete\", \"find\", \"check\", \"init\", \"start\", \"stop\",\n \"accept\", \"quote\", \"ingest\", \"verify\", \"request\", \"list\", \"serve\",\n \"parse\", \"build\", \"load\", \"save\", \"send\", \"read\", \"write\", \"close\",\n \"open\", \"reset\", \"flush\", \"sync\", \"fetch\", \"push\", \"pull\", \"setup\",\n \"execute\", \"invoke\", \"dispatch\", \"resolve\", \"reject\", \"validate\",\n \"render\", \"mount\", \"unmount\", \"connect\", \"disconnect\",\n ]);\n\n // CRUD verbs followed by a domain noun are standard handler patterns — the name\n // perfectly describes the intent. Embedding models struggle because the body involves\n // many steps (parse request, validate, DB call, return response) beyond the literal verb.\n const CRUD_PREFIXES = /^(create|update|delete|remove|get|list|find|fetch|search|add|edit|patch|upsert|insert|save|read|load|count|check|validate|verify|accept|reject|approve|deny|submit|publish|archive|restore|activate|deactivate|enable|disable|cancel|revoke|grant|assign|unassign|invite|register|login|logout|signup|signin|signout|reset|confirm|generate|send|export|import|download|upload|sync|refresh|clone|copy|move|merge|split|batch|bulk|process|handle|serve|render|show|display|index|new|close|open|start|stop|pause|resume|retry|queue|schedule|trigger|execute|run|init|setup|configure|install|deploy|migrate|seed|clear|flush|purge|mark|flag|tag|rate|score|vote|like|follow|subscribe|unsubscribe|notify|broadcast|log|track|record|audit|monitor|watch|inspect|scan|analyze|parse|transform|convert|format|encode|decode|encrypt|decrypt|hash|sign|wrap|unwrap|serialize|deserialize|marshal|unmarshal|quote|ingest|request)[A-Z_]/i;\n\n for (const intent of response.intent_mismatches) {\n // Skip single-word names — they generate false positives\n const nameWords = intent.name.replace(/([a-z])([A-Z])/g, \"$1 $2\").split(/[\\s_]+/);\n if (nameWords.length <= 1 || GENERIC_SINGLE_WORDS.has(intent.name.toLowerCase())) {\n droppedCount++;\n continue;\n }\n\n // Skip CRUD verb + domain noun patterns — these names describe the intent correctly,\n // but embedding models can't match a verb-noun name to a complex handler body\n if (CRUD_PREFIXES.test(intent.name)) {\n droppedCount++;\n continue;\n }\n\n if (intent.confidence >= HIGH_CONFIDENCE_THRESHOLD) {\n highConfidence.push({\n analyzerId: \"ml-intent\",\n severity: \"warning\",\n confidence: intent.confidence,\n message: `Function name mismatch: ${intent.name}() — name doesn't match behavior (${Math.round(intent.similarity * 100)}% name-body alignment)`,\n locations: [{ file: intent.function_id.split(\"::\")[0] }],\n tags: [\"ml\", \"intent\"],\n });\n } else if (intent.confidence >= MEDIUM_CONFIDENCE_THRESHOLD) {\n mediumConfidence.push({\n type: \"intent_mismatch\",\n confidence: intent.confidence,\n detail: intent,\n question: `Does ${intent.name}() actually do what its name suggests? Name-body similarity is only ${Math.round(intent.similarity * 100)}%.`,\n });\n } else {\n droppedCount++;\n }\n }\n\n // ──── Process anomalies ────\n for (const anomaly of response.anomalies) {\n if (anomaly.confidence >= HIGH_CONFIDENCE_THRESHOLD) {\n highConfidence.push({\n analyzerId: \"ml-anomaly\",\n severity: \"info\",\n confidence: anomaly.confidence,\n message: `Pattern outlier: ${anomaly.function_id} doesn't cluster with its ${anomaly.cluster_size} peers (distance: ${anomaly.distance_from_cluster.toFixed(2)})`,\n locations: [{ file: anomaly.function_id.split(\"::\")[0] }],\n tags: [\"ml\", \"anomaly\"],\n });\n } else if (anomaly.confidence >= MEDIUM_CONFIDENCE_THRESHOLD) {\n mediumConfidence.push({\n type: \"anomaly\",\n confidence: anomaly.confidence,\n detail: anomaly,\n question: `Is ${anomaly.function_id} intentionally different from the ${anomaly.cluster_size} similar functions?`,\n });\n } else {\n droppedCount++;\n }\n }\n\n // Cap LLM candidates at MAX_LLM_CANDIDATES (highest confidence first)\n mediumConfidence.sort((a, b) => b.confidence - a.confidence);\n droppedCount += Math.max(0, mediumConfidence.length - MAX_LLM_CANDIDATES);\n\n return {\n highConfidence,\n mediumConfidence: mediumConfidence.slice(0, MAX_LLM_CANDIDATES),\n droppedCount,\n };\n}\n","import { basename, join } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\n\n/**\n * Project identity helpers.\n *\n * The dashboard groups scans by `project_hash` and displays them under a\n * human-readable `project_name`. Both values are computed CLI-side so the\n * server never sees absolute paths, only hashes.\n *\n * Autodetect order for `project_name`:\n * 1. --project-name <flag> (explicit override)\n * 2. package.json.name (Node/TS projects)\n * 3. Cargo.toml [package] name (Rust)\n * 4. go.mod module basename (Go)\n * 5. pyproject.toml [project] / [tool.poetry] name (Python)\n * 6. basename(rootDir) (fallback)\n *\n * `project_hash` is always SHA-256 of the absolute rootDir so the same\n * checkout always groups under the same project, even if the user\n * renames it. Collisions across machines are fine — the hash is scoped\n * to the user's scan history.\n */\n\nexport interface ProjectIdentity {\n name: string;\n hash: string;\n}\n\nexport async function detectProjectIdentity(\n rootDir: string,\n override?: string,\n): Promise<ProjectIdentity> {\n const hash = createHash(\"sha256\").update(rootDir).digest(\"hex\");\n\n // Explicit override wins\n if (override && override.trim()) {\n return { name: override.trim(), hash };\n }\n\n // package.json\n const fromPackageJson = await readJsonField(\n join(rootDir, \"package.json\"),\n \"name\",\n );\n if (fromPackageJson) return { name: fromPackageJson, hash };\n\n // Cargo.toml — grep for `name = \"xyz\"` in [package] section\n const fromCargo = await readTomlFieldInSection(\n join(rootDir, \"Cargo.toml\"),\n \"package\",\n \"name\",\n );\n if (fromCargo) return { name: fromCargo, hash };\n\n // go.mod — first \"module github.com/foo/bar\" line, take the last segment\n const fromGoMod = await readGoModule(join(rootDir, \"go.mod\"));\n if (fromGoMod) return { name: fromGoMod, hash };\n\n // pyproject.toml — [project] name or [tool.poetry] name\n const fromPyProject =\n (await readTomlFieldInSection(\n join(rootDir, \"pyproject.toml\"),\n \"project\",\n \"name\",\n )) ??\n (await readTomlFieldInSection(\n join(rootDir, \"pyproject.toml\"),\n \"tool.poetry\",\n \"name\",\n ));\n if (fromPyProject) return { name: fromPyProject, hash };\n\n // Final fallback: directory name\n return { name: basename(rootDir) || \"untitled\", hash };\n}\n\nasync function readJsonField(path: string, field: string): Promise<string | null> {\n try {\n const raw = await readFile(path, \"utf-8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n const value = parsed[field];\n if (typeof value === \"string\" && value.trim()) return value.trim();\n } catch {\n // File missing or malformed — treat as \"not found\"\n }\n return null;\n}\n\n/**\n * Minimal TOML reader — finds `[section]` then the first `key = \"value\"`\n * line within it. Good enough for Cargo.toml / pyproject.toml which\n * both follow a strict structure. Doesn't handle multi-line strings or\n * nested tables, which is fine for our use case.\n */\nasync function readTomlFieldInSection(\n path: string,\n section: string,\n key: string,\n): Promise<string | null> {\n try {\n const raw = await readFile(path, \"utf-8\");\n const lines = raw.split(\"\\n\");\n let inSection = false;\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"[\") && trimmed.endsWith(\"]\")) {\n inSection = trimmed === `[${section}]`;\n continue;\n }\n if (!inSection) continue;\n const match = trimmed.match(/^([\\w-]+)\\s*=\\s*\"([^\"]+)\"/);\n if (match && match[1] === key && match[2]) {\n return match[2];\n }\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nasync function readGoModule(path: string): Promise<string | null> {\n try {\n const raw = await readFile(path, \"utf-8\");\n const match = raw.match(/^\\s*module\\s+(\\S+)/m);\n if (match && match[1]) {\n // Take the last path segment so \"github.com/foo/bar\" → \"bar\"\n const segs = match[1].split(\"/\");\n const last = segs[segs.length - 1];\n if (last) return last;\n }\n } catch {\n // ignore\n }\n return null;\n}\n","import type { AnalysisContext, Finding, DriftFindingReport } from \"../core/types.js\";\nimport type { CodeDnaResult } from \"../codedna/types.js\";\nimport type { FilteredMlResults, MlDeviationPayload, MlLlmValidationPayload } from \"./types.js\";\nimport { sampleFunctionsForMl } from \"./sampler.js\";\nimport { callMlApi } from \"./client.js\";\nimport { filterByConfidence } from \"./confidence.js\";\n\nexport interface MlAnalysisOptions {\n /** Bearer token from `vibedrift login` (~/.vibedrift/config.json or VIBEDRIFT_TOKEN). */\n token?: string;\n /** Override the API base URL — staging/dev only. */\n apiUrl?: string;\n verbose?: boolean;\n driftFindings?: DriftFindingReport[];\n /** Optional human-readable project name override (--project-name flag). */\n projectName?: string;\n /** Composite score (0-100) from local scoring, sent for dashboard history. */\n scoreHint?: number;\n /** Letter grade from local scoring. */\n gradeHint?: string;\n}\n\n/**\n * Build deviation payloads from Code DNA and drift findings for the ML API's\n * deviation classifier. This enables the paid feature: ML-powered verdict\n * (justified vs accidental) that improves on the local heuristic.\n */\nfunction buildDeviationPayloads(\n codeDnaResult: CodeDnaResult | undefined,\n driftFindings: DriftFindingReport[],\n): MlDeviationPayload[] {\n const deviations: MlDeviationPayload[] = [];\n const seen = new Set<string>();\n\n // Code DNA deviations have the richest structural data\n if (codeDnaResult?.deviationJustifications) {\n for (const dj of codeDnaResult.deviationJustifications) {\n const key = `${dj.relativePath}::${dj.deviatingPattern}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const hasComment = dj.signals?.some((s) => s.type === \"explanatory_comment\" && s.present) ?? false;\n const sqlComplexity = dj.signals?.find((s) => s.type === \"complex_sql\")?.present ? 3 : 0;\n const funcComplexity = dj.signals?.reduce((sum, s) => sum + (s.present ? Math.abs(s.weight) : 0), 0) ?? 0;\n\n // Map the deviation pattern to the API's DEVIATION_TYPE_MAP categories:\n // data_access, error_handling, auth, naming, di, config\n // The API model was trained on these 6 types — sending \"architectural\"\n // (which is not in the map) causes it to default to 0.5 and lose signal.\n const patternToType: Record<string, string> = {\n repository: \"data_access\", raw_sql: \"data_access\", orm: \"data_access\",\n direct_db: \"data_access\", http_client: \"data_access\",\n wrap_with_context: \"error_handling\", raw_propagation: \"error_handling\",\n swallow: \"error_handling\", http_error_response: \"error_handling\",\n exception_throw: \"error_handling\", result_type: \"error_handling\",\n constructor_injection: \"di\", global_import: \"di\",\n service_locator: \"di\", no_di: \"di\",\n env_direct: \"config\", config_struct_di: \"config\",\n };\n const inferredType =\n patternToType[dj.deviatingPattern] ??\n patternToType[dj.dominantPattern] ??\n \"data_access\";\n\n deviations.push({\n file: dj.relativePath,\n deviation_type: inferredType,\n dominant_pattern: dj.dominantPattern,\n actual_pattern: dj.deviatingPattern,\n dominant_count: 0,\n total_files: 0,\n snippet: \"\",\n has_comment: hasComment,\n sql_complexity: sqlComplexity,\n function_complexity: Math.round(funcComplexity * 10),\n directory: dj.relativePath.split(\"/\").slice(0, -1).join(\"/\"),\n });\n }\n }\n\n // Drift findings provide dominant/total counts and code evidence\n for (const d of driftFindings) {\n if (d.driftCategory !== \"architectural_consistency\") continue;\n\n for (const df of d.deviatingFiles) {\n const key = `${df.path}::${df.detectedPattern}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n deviations.push({\n file: df.path,\n deviation_type: d.subCategory ?? \"data_access\",\n dominant_pattern: d.dominantPattern,\n actual_pattern: df.detectedPattern,\n dominant_count: d.dominantCount,\n total_files: d.totalRelevantFiles,\n snippet: df.evidence?.[0]?.code?.slice(0, 200) ?? \"\",\n has_comment: false,\n sql_complexity: 0,\n function_complexity: 0,\n directory: df.path.split(\"/\").slice(0, -1).join(\"/\"),\n });\n }\n }\n\n return deviations.slice(0, 20); // API limit\n}\n\n/**\n * Build LLM validation payloads from medium-confidence ML findings.\n * These get sent to the API for surgical Claude validation.\n */\nfunction buildLlmValidationPayloads(\n mediumConfidence: FilteredMlResults[\"mediumConfidence\"],\n): MlLlmValidationPayload[] {\n return mediumConfidence.map((mc) => ({\n finding: mc.question,\n confidence: mc.confidence,\n snippet_a: mc.snippetA ?? \"\",\n snippet_b: mc.snippetB ?? \"\",\n question: mc.question,\n }));\n}\n\nexport async function runMlAnalysis(\n ctx: AnalysisContext,\n codeDnaResult: CodeDnaResult | undefined,\n findings: Finding[],\n options: MlAnalysisOptions,\n): Promise<FilteredMlResults> {\n // Use Code DNA's extracted functions if available, otherwise we need to extract\n let functions = codeDnaResult?.functions ?? [];\n\n if (functions.length === 0) {\n // Fallback: extract functions\n const { extractAllFunctions } = await import(\"../codedna/function-extractor.js\");\n functions = extractAllFunctions(ctx.files);\n }\n\n if (functions.length === 0) {\n return { highConfidence: [], mediumConfidence: [], droppedCount: 0 };\n }\n\n // Sample top functions for the API\n const sampled = sampleFunctionsForMl(functions, findings);\n\n // Build deviation payloads from Code DNA + drift findings\n const deviations = buildDeviationPayloads(codeDnaResult, options.driftFindings ?? []);\n\n // Calculate payload size for transparency\n const payloadSize = JSON.stringify(sampled).length + JSON.stringify(deviations).length;\n\n if (options.verbose) {\n console.error(`[deep] Sending ${sampled.length} functions + ${deviations.length} deviations (${Math.round(payloadSize / 1024)}KB) to VibeDrift API...`);\n console.error(`[deep] No full files transmitted — only function snippets and structural metadata.`);\n }\n\n // Detect project identity (project_name + stable project_hash) so the\n // dashboard can group scans under a user-visible label. Autodetects from\n // package.json / Cargo.toml / go.mod / pyproject.toml, or uses the\n // --project-name override if one was passed.\n const { detectProjectIdentity } = await import(\"./project-name.js\");\n const projectIdentity = await detectProjectIdentity(\n ctx.rootDir,\n options.projectName,\n );\n\n // Build request\n const request = {\n language: ctx.dominantLanguage ?? \"unknown\",\n file_count: ctx.files.length,\n project_hash: projectIdentity.hash,\n project_name: projectIdentity.name,\n score_hint: options.scoreHint,\n grade_hint: options.gradeHint,\n // Tell the server NOT to persist a row from the analyze call —\n // the CLI logs the full scan summary via /v1/scans/log AFTER the\n // pipeline finishes, which has accurate metadata.\n defer_persist: true,\n functions: sampled,\n deviations,\n llm_validations: [] as MlLlmValidationPayload[],\n };\n\n // Call the API\n const response = await callMlApi(request, options.token, options.apiUrl);\n\n if (options.verbose) {\n console.error(\n `[deep] API returned: ${response.duplicates.length} duplicates, ` +\n `${response.intent_mismatches.length} intent mismatches, ` +\n `${response.anomalies.length} anomalies, ` +\n `${response.deviations?.length ?? 0} deviation verdicts — ${response.processing_time_ms}ms`,\n );\n }\n\n // Filter by confidence\n const filtered = filterByConfidence(response);\n\n // Surface the persisted scan id so the caller can upload the HTML report\n if (response.scan_id) {\n filtered.scanId = response.scan_id;\n }\n\n // If API returned ML deviation verdicts, override Code DNA's local heuristic verdicts\n if (response.deviations?.length > 0 && codeDnaResult?.deviationJustifications) {\n for (const mlDev of response.deviations) {\n const local = codeDnaResult.deviationJustifications.find(\n (dj: any) => dj.relativePath === mlDev.file || dj.file === mlDev.file,\n );\n if (local && mlDev.confidence > 0.6) {\n // ML classifier overrides local heuristic\n (local as any).verdict = mlDev.verdict === \"justified\" ? \"likely_justified\"\n : mlDev.verdict === \"accidental\" ? \"likely_accidental\" : local.verdict;\n }\n }\n }\n\n return filtered;\n}\n","import type { Finding } from \"../core/types.js\";\n\n// Analyzer IDs that detect duplicates, in priority order (highest first)\nconst DUPLICATE_ANALYZER_IDS = [\"ml-duplicate\", \"codedna-fingerprint\", \"codedna-opseq\", \"duplicates\"];\nconst DUPLICATE_IDS_SET = new Set(DUPLICATE_ANALYZER_IDS);\n\n/**\n * Deduplicate findings across the three duplicate detection layers.\n *\n * The same function pair can be reported by static analysis, Code DNA, and ML embeddings.\n * We keep only the highest-priority detection per file pair:\n * ML-confirmed > Code DNA fingerprint > Code DNA opseq > Static\n *\n * Non-duplicate findings pass through unchanged.\n */\nexport function deduplicateFindingsAcrossLayers(findings: Finding[]): Finding[] {\n const nonDuplicate: Finding[] = [];\n const duplicateFindings: Finding[] = [];\n\n for (const f of findings) {\n if (DUPLICATE_IDS_SET.has(f.analyzerId)) {\n duplicateFindings.push(f);\n } else {\n nonDuplicate.push(f);\n }\n }\n\n if (duplicateFindings.length === 0) return findings;\n\n // Group duplicate findings by the set of files they involve\n const byFilePair = new Map<string, Finding[]>();\n\n for (const f of duplicateFindings) {\n const key = makeFilePairKey(f);\n if (!byFilePair.has(key)) byFilePair.set(key, []);\n byFilePair.get(key)!.push(f);\n }\n\n // For each file pair group, keep only the highest-priority finding\n const dedupedDuplicates: Finding[] = [];\n\n for (const [, group] of byFilePair) {\n if (group.length === 1) {\n dedupedDuplicates.push(group[0]);\n continue;\n }\n\n // Sort by priority (ML > Code DNA fingerprint > Code DNA opseq > Static)\n group.sort((a, b) => {\n const pa = DUPLICATE_ANALYZER_IDS.indexOf(a.analyzerId);\n const pb = DUPLICATE_ANALYZER_IDS.indexOf(b.analyzerId);\n return pa - pb; // lower index = higher priority\n });\n\n const best = group[0];\n const sources = [...new Set(group.map((f) => f.analyzerId))];\n\n // Annotate the winning finding with detection source info\n if (sources.length > 1) {\n const sourceLabels = sources.map((s) =>\n s === \"ml-duplicate\" ? \"ML embeddings\"\n : s === \"codedna-fingerprint\" ? \"Code DNA fingerprint\"\n : s === \"codedna-opseq\" ? \"Code DNA sequence\"\n : \"static analysis\"\n );\n best.message += ` [confirmed by ${sourceLabels.join(\", \")}]`;\n }\n\n dedupedDuplicates.push(best);\n }\n\n return [...nonDuplicate, ...dedupedDuplicates];\n}\n\n/**\n * Create a normalized key for a finding based on its involved files.\n * For single-file findings, uses the file + analyzer as key.\n * For multi-file findings (duplicates), sorts file paths for consistency.\n */\nfunction makeFilePairKey(f: Finding): string {\n // Use ALL unique files (sorted + deduped) so 3+-file clusters merge\n // correctly when reported by different layers. The old approach used\n // only the first two files, which meant {A,B,C} and {A,C} could\n // produce different keys and inflate the duplicate count.\n const files = [...new Set(\n f.locations.map((l) => l.file).filter(Boolean),\n )].sort();\n\n if (files.length >= 2) {\n return `dup::${files.join(\"::\")}`;\n }\n\n // Single-file duplicate findings (e.g., static \"X pairs of duplicates in this file\")\n return `dup::${files[0] ?? \"unknown\"}::${f.analyzerId}`;\n}\n","import type { ScanResult } from \"../core/types.js\";\n\nconst TIMEOUT_MS = 30_000;\n\ninterface SummaryResponse {\n summary: string;\n highlights: string[];\n processingTimeMs: number;\n}\n\nexport async function fetchAiSummary(\n result: ScanResult,\n apiUrl: string,\n token?: string,\n): Promise<{ summary: string; highlights: string[] } | null> {\n const dna = result.codeDnaResult;\n const mlFindings = result.findings.filter((f) => f.tags?.includes(\"ml\"));\n\n const body = {\n project: result.context.rootDir.split(\"/\").pop() ?? \"project\",\n score: result.compositeScore,\n maxScore: result.maxCompositeScore,\n grade: getGrade(result.compositeScore, result.maxCompositeScore),\n fileCount: result.context.files.length,\n totalLines: result.context.totalLines,\n languages: [...result.context.languageBreakdown.entries()]\n .map(([l, s]) => `${l}: ${s.files} files`)\n .join(\", \"),\n driftFindings: (result.driftFindings ?? []).map((d) => ({\n severity: d.severity,\n finding: d.finding,\n category: d.driftCategory,\n consistency: d.consistencyScore,\n dominant: d.dominantPattern,\n deviatingFiles: d.deviatingFiles.map((f) => f.path).join(\", \"),\n })),\n codeDnaSummary: dna ? {\n functions: dna.functions?.length ?? 0,\n fingerprints: dna.duplicateGroups?.length ?? 0,\n sequences: dna.sequenceSimilarities?.length ?? 0,\n taintFlows: dna.taintFlows?.length ?? 0,\n deviations: dna.deviationJustifications?.length ?? 0,\n } : null,\n mlSummary: mlFindings.length > 0 ? {\n duplicates: mlFindings.filter((f) => f.analyzerId === \"ml-duplicate\").length,\n intentMismatches: mlFindings.filter((f) => f.analyzerId === \"ml-intent\").length,\n anomalies: mlFindings.filter((f) => f.analyzerId === \"ml-anomaly\").length,\n } : null,\n topIssues: (result.driftFindings ?? [])\n .sort((a, b) => {\n const sev = { error: 3, warning: 2, info: 1 };\n return (sev[b.severity as keyof typeof sev] ?? 0) - (sev[a.severity as keyof typeof sev] ?? 0);\n })\n .slice(0, 5)\n .map((d) => d.recommendation),\n };\n\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);\n\n try {\n const response = await fetch(`${apiUrl}/v1/summarize`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as SummaryResponse;\n return { summary: data.summary, highlights: data.highlights };\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction getGrade(score: number, max: number): string {\n const pct = max > 0 ? (score / max) * 100 : 0;\n if (pct >= 90) return \"A\";\n if (pct >= 75) return \"B\";\n if (pct >= 50) return \"C\";\n if (pct >= 25) return \"D\";\n return \"F\";\n}\n","/**\n * Log a completed scan to the dashboard via /v1/scans/log.\n *\n * Called by the CLI for EVERY scan, free or deep, after the local\n * pipeline + scoring + HTML rendering has finished. This is the single\n * source of truth for what shows up in the user's dashboard — the\n * values sent here are what the user sees in the dashboard's metadata\n * strip and timeline.\n *\n * Silent on failure (network down, server 500, etc.) — the scan\n * already succeeded locally so a failed log shouldn't surface an error.\n */\n\nconst DEFAULT_API_URL = \"https://vibedrift-api.fly.dev\";\nconst TIMEOUT_MS = 20_000;\nconst MAX_HTML_BYTES = 1_500_000;\n\nexport interface ScanLogPayload {\n project_hash?: string;\n project_name?: string;\n language: string;\n file_count: number;\n function_count: number;\n finding_count: number;\n score?: number | null;\n grade?: string | null;\n duplicates_found: number;\n intent_mismatches: number;\n anomalies_found: number;\n is_deep: boolean;\n processing_time_ms: number;\n /** Full self-contained HTML report. Truncated server-side if too large. */\n report_html?: string;\n /**\n * Sanitized full ScanResult — the canonical source of truth for the\n * dashboard. Both the metadata strip and the embedded HTML report\n * are derived from this object, so they're guaranteed consistent.\n * Absolute paths are stripped before sending.\n */\n result_json?: Record<string, unknown>;\n}\n\nexport interface ScanLogResult {\n ok: boolean;\n scanId?: string;\n projectId?: string;\n bytesStored?: number;\n error?: string;\n}\n\nexport async function logScan(opts: {\n payload: ScanLogPayload;\n token: string;\n apiUrl?: string;\n verbose?: boolean;\n}): Promise<ScanLogResult> {\n const { payload, token, apiUrl, verbose } = opts;\n const base = apiUrl ?? DEFAULT_API_URL;\n\n // Trim HTML if it exceeds the cap so we still log the metadata\n const trimmed = { ...payload };\n if (trimmed.report_html) {\n const size = Buffer.byteLength(trimmed.report_html, \"utf-8\");\n if (size > MAX_HTML_BYTES) {\n if (verbose) {\n console.error(\n `[scan-log] HTML too large (${Math.round(size / 1024)}KB), dropping the blob`,\n );\n }\n delete trimmed.report_html;\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);\n\n try {\n const res = await fetch(`${base}/v1/scans/log`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(trimmed),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n if (verbose) {\n console.error(`[scan-log] HTTP ${res.status}: ${text.slice(0, 200)}`);\n }\n return { ok: false, error: `HTTP ${res.status}` };\n }\n\n const data = (await res.json().catch(() => ({}))) as {\n scan_id?: string;\n project_id?: string;\n bytes_stored?: number;\n };\n\n if (verbose) {\n console.error(\n `[scan-log] Logged scan ${data.scan_id?.slice(0, 8) ?? \"?\"} ` +\n `(project ${data.project_id?.slice(0, 8) ?? \"?\"}, ` +\n `${data.bytes_stored ?? 0} HTML bytes)`,\n );\n }\n\n return {\n ok: true,\n scanId: data.scan_id,\n projectId: data.project_id,\n bytesStored: data.bytes_stored,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (verbose) console.error(`[scan-log] Failed: ${msg}`);\n return { ok: false, error: msg };\n } finally {\n clearTimeout(timer);\n }\n}\n","import type { ScanResult } from \"../core/types.js\";\n\n/**\n * Convert a ScanResult into a JSON-safe object suitable for upload to the\n * dashboard. The on-the-wire shape becomes the single source of truth: both\n * the dashboard metadata strip AND the embedded HTML report are derived\n * from this object, so they're guaranteed consistent.\n *\n * What we strip:\n * - `context.rootDir` (absolute path on the user's machine — privacy)\n * - Any absolute path that starts with `rootDir` is rewritten relative\n *\n * What we keep:\n * - All findings (metadata only — no file contents)\n * - All drift findings + per-category scores\n * - codeDnaResult summary (function names, hashes, deviation verdicts)\n * - Composite scores, grade, language breakdown\n * - Per-file scores (with relative paths)\n *\n * What we drop entirely (large + not needed for the dashboard):\n * - Raw file contents from `context.files`\n * - tree-sitter AST nodes\n * - Map / Set instances (converted to plain object/array)\n */\ntype StripPathFn = (p: string | undefined | null) => string | null;\ntype SanitizeNodeFn = (node: unknown) => unknown;\n\nfunction createStripPath(rootDir: string): StripPathFn {\n return (p: string | undefined | null): string | null => {\n if (!p) return null;\n if (rootDir && p.startsWith(rootDir)) {\n const rel = p.slice(rootDir.length).replace(/^\\/+/, \"\");\n return rel || \".\";\n }\n return p;\n };\n}\n\nfunction createSanitizeNode(stripPath: StripPathFn): SanitizeNodeFn {\n const sanitizeNode = (node: unknown): unknown => {\n if (typeof node === \"string\") return stripPath(node) ?? node;\n if (Array.isArray(node)) return node.map(sanitizeNode);\n if (node instanceof Map) {\n return sanitizeMapNode(node, stripPath, sanitizeNode);\n }\n if (node instanceof Set) {\n return [...node].map(sanitizeNode);\n }\n if (node && typeof node === \"object\") {\n return sanitizeObjectNode(node as Record<string, unknown>, stripPath, sanitizeNode);\n }\n return node;\n };\n return sanitizeNode;\n}\n\nfunction sanitizeObjectNode(\n node: Record<string, unknown>,\n stripPath: StripPathFn,\n sanitizeNode: SanitizeNodeFn,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(node)) {\n if (k === \"rootDir\") continue;\n if (k === \"files\" && Array.isArray(v)) {\n out[k] = sanitizeFilesList(v as Array<Record<string, unknown>>, stripPath);\n continue;\n }\n if (k === \"ast\" || k === \"treeSitterNode\") continue;\n out[k] = sanitizeNode(v);\n }\n return out;\n}\n\nfunction sanitizeFilesList(\n files: Array<Record<string, unknown>>,\n stripPath: StripPathFn,\n): Array<Record<string, unknown>> {\n return files.map((f) => ({\n relativePath: stripPath(f.relativePath as string) ?? f.relativePath,\n lineCount: f.lineCount,\n language: f.language,\n }));\n}\n\nfunction sanitizeMapNode(\n node: Map<unknown, unknown>,\n stripPath: StripPathFn,\n sanitizeNode: SanitizeNodeFn,\n): Record<string, unknown> {\n const obj: Record<string, unknown> = {};\n for (const [k, v] of node.entries()) {\n const safeKey = typeof k === \"string\" ? stripPath(k) ?? k : String(k);\n obj[safeKey] = sanitizeNode(v);\n }\n return obj;\n}\n\nexport function sanitizeResultForUpload(result: ScanResult): Record<string, unknown> {\n const ctx = result.context;\n const rootDir = ctx?.rootDir ?? \"\";\n\n const stripPath = createStripPath(rootDir);\n const sanitizeNode = createSanitizeNode(stripPath);\n\n return {\n schema: \"vibedrift-scan-result/v1\",\n project: {},\n language: {\n dominant: ctx?.dominantLanguage ?? null,\n breakdown: sanitizeNode(ctx?.languageBreakdown),\n totalLines: ctx?.totalLines ?? 0,\n },\n fileCount: (ctx?.files ?? []).length,\n files: sanitizeNode(ctx?.files),\n score: {\n composite: result.compositeScore,\n max: result.maxCompositeScore,\n categories: sanitizeNode(result.scores),\n },\n findings: sanitizeNode(result.findings),\n driftFindings: sanitizeNode(result.driftFindings),\n driftScores: sanitizeNode(result.driftScores),\n codeDnaResult: sanitizeNode(result.codeDnaResult),\n perFileScores: sanitizeNode(result.perFileScores),\n teaseMessages: result.teaseMessages,\n aiSummary: result.aiSummary ?? null,\n scanTimeMs: result.scanTimeMs,\n };\n}\n","/**\n * CSV report renderer for VibeDrift scan results.\n *\n * Produces a multi-section CSV document covering summary stats, category scores,\n * drift findings, Code DNA results (duplicates, taint flows, pattern distributions),\n * per-file scores, and deep insights. Designed for spreadsheet import and CI\n * artifact archiving.\n */\n\nimport type { ScanResult } from \"../core/types.js\";\n\nfunction csvEscape(val: string): string {\n if (val.includes(\",\") || val.includes('\"') || val.includes(\"\\n\")) {\n return '\"' + val.replace(/\"/g, '\"\"') + '\"';\n }\n return val;\n}\n\nfunction row(...cells: (string | number)[]): string {\n return cells.map((c) => csvEscape(String(c))).join(\",\");\n}\n\nfunction csvMetadata(result: ScanResult): string[] {\n return [\n \"VIBEDRIFT REPORT\",\n row(\"Project\", result.context.rootDir.split(\"/\").pop() ?? \"\"),\n row(\"Files Scanned\", result.context.files.length),\n row(\"Total Lines\", result.context.totalLines),\n row(\"Scan Time (ms)\", result.scanTimeMs),\n row(\"Composite Score\", result.compositeScore),\n row(\"Max Score\", result.maxCompositeScore),\n \"\",\n ];\n}\n\nfunction csvScoreCategories(result: ScanResult): string[] {\n const lines: string[] = [];\n lines.push(\"CATEGORY SCORES\");\n lines.push(row(\"Category\", \"Score\", \"Max Score\", \"Finding Count\"));\n for (const [key, val] of Object.entries(result.scores)) {\n lines.push(row(key, val.score, val.maxScore, val.findingCount));\n }\n lines.push(\"\");\n\n const ds = result.driftScores ?? {};\n if (Object.keys(ds).length > 0) {\n lines.push(\"DRIFT SCORES\");\n lines.push(row(\"Category\", \"Score\", \"Max Score\", \"Findings\", \"Grade\"));\n for (const [key, val] of Object.entries(ds)) {\n if (key === \"composite\" || key === \"grade\") continue;\n const v = val as any;\n if (v?.score !== undefined) {\n lines.push(row(key, v.score, v.maxScore, v.findings ?? 0));\n }\n }\n lines.push(\"\");\n }\n return lines;\n}\n\nfunction csvDriftFindings(result: ScanResult): string[] {\n if ((result.driftFindings ?? []).length === 0) return [];\n const lines: string[] = [];\n lines.push(\"DRIFT FINDINGS\");\n lines.push(row(\"Severity\", \"Category\", \"Finding\", \"Dominant Pattern\", \"Dominant Count\", \"Total Files\", \"Consistency %\", \"Deviating Files\", \"Recommendation\"));\n for (const d of result.driftFindings) {\n const devFiles = d.deviatingFiles.map((f) => f.path).join(\"; \");\n lines.push(row(\n d.severity, d.driftCategory, d.finding,\n d.dominantPattern, d.dominantCount, d.totalRelevantFiles, d.consistencyScore,\n devFiles, d.recommendation,\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvDuplicateGroups(dna: any): string[] {\n if (!dna.duplicateGroups?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: SEMANTIC DUPLICATES\");\n lines.push(row(\"Group\", \"Functions\", \"Files\"));\n for (const g of dna.duplicateGroups) {\n const fns = g.functions.map((f: any) => f.name + \"()\").join(\"; \");\n const files = g.functions.map((f: any) => f.relativePath || f.file).join(\"; \");\n lines.push(row(g.groupId, fns, files));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvSequenceSimilarities(dna: any): string[] {\n if (!dna.sequenceSimilarities?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: OPERATION SEQUENCE MATCHES\");\n lines.push(row(\"Function A\", \"File A\", \"Function B\", \"File B\", \"Similarity %\"));\n for (const s of dna.sequenceSimilarities) {\n lines.push(row(\n s.functionA.name, s.functionA.relativePath || s.functionA.file,\n s.functionB.name, s.functionB.relativePath || s.functionB.file,\n Math.round(s.similarity * 100),\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvTaintFlows(dna: any): string[] {\n if (!dna.taintFlows?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: TAINT FLOWS\");\n lines.push(row(\"File\", \"Function\", \"Source Type\", \"Source Line\", \"Sink Type\", \"Sink Line\", \"Sanitized\"));\n for (const t of dna.taintFlows) {\n lines.push(row(\n t.relativePath || t.file, t.functionName,\n t.source.type, t.source.line, t.sink.type, t.sink.line,\n t.sanitized ? \"Yes\" : \"No\",\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvDeviations(dna: any): string[] {\n if (!dna.deviationJustifications?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: DEVIATION ANALYSIS\");\n lines.push(row(\"File\", \"Deviating Pattern\", \"Dominant Pattern\", \"Verdict\", \"Score\"));\n for (const dj of dna.deviationJustifications) {\n lines.push(row(\n dj.relativePath || dj.file, dj.deviatingPattern, dj.dominantPattern,\n dj.verdict, Math.round(dj.justificationScore * 100),\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvPatterns(dna: any): string[] {\n if (!dna.patternDistributions?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: PATTERN DISTRIBUTIONS\");\n lines.push(row(\"File\", \"Dominant Pattern\", \"Confidence\", \"Internally Inconsistent\"));\n for (const pd of dna.patternDistributions) {\n lines.push(row(\n pd.relativePath || pd.file, pd.dominantPattern,\n Math.round(pd.confidence * 100), pd.isInternallyInconsistent ? \"Yes\" : \"No\",\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvCodeDna(result: ScanResult): string[] {\n const dna = result.codeDnaResult;\n if (!dna) return [];\n return [\n ...csvDuplicateGroups(dna),\n ...csvSequenceSimilarities(dna),\n ...csvTaintFlows(dna),\n ...csvDeviations(dna),\n ...csvPatterns(dna),\n ];\n}\n\nfunction csvFindings(result: ScanResult): string[] {\n const lines: string[] = [];\n lines.push(\"ALL FINDINGS\");\n lines.push(row(\"Severity\", \"Analyzer\", \"Confidence %\", \"Message\", \"File\", \"Line\", \"Tags\"));\n for (const f of result.findings) {\n const loc = f.locations[0];\n lines.push(row(\n f.severity, f.analyzerId, Math.round(f.confidence * 100),\n f.message, loc?.file ?? \"\", loc?.line ?? \"\",\n (f.tags ?? []).join(\"; \"),\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvPerFileScores(result: ScanResult): string[] {\n const lines: string[] = [];\n lines.push(\"PER-FILE SCORES\");\n lines.push(row(\"File\", \"Score\", \"Finding Count\"));\n const fileSorted = [...result.perFileScores.entries()].sort((a, b) => a[1].score - b[1].score);\n for (const [path, data] of fileSorted) {\n lines.push(row(path, data.score, data.findings.length));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvAiSummary(result: ScanResult): string[] {\n if ((result.deepInsights ?? []).length === 0) return [];\n const lines: string[] = [];\n lines.push(\"DEEP ANALYSIS INSIGHTS\");\n lines.push(row(\"Category\", \"Severity\", \"Title\", \"Description\", \"Related Files\", \"Recommendation\"));\n for (const ins of result.deepInsights) {\n lines.push(row(\n ins.category, ins.severity, ins.title, ins.description,\n ins.relatedFiles.join(\"; \"), ins.recommendation ?? \"\",\n ));\n }\n return lines;\n}\n\nexport function renderCsvReport(result: ScanResult): string {\n return [\n ...csvMetadata(result),\n ...csvScoreCategories(result),\n ...csvDriftFindings(result),\n ...csvCodeDna(result),\n ...csvFindings(result),\n ...csvPerFileScores(result),\n ...csvAiSummary(result),\n ].join(\"\\n\");\n}\n","import { deflateRawSync } from \"zlib\";\nimport type { ScanResult } from \"../core/types.js\";\nimport { getVersion } from \"../core/version.js\";\n\n// ──── Minimal ZIP generator (OOXML requires ZIP container) ────\n\ninterface ZipEntry {\n name: string;\n data: Buffer;\n}\n\nfunction buildZip(entries: ZipEntry[]): Buffer {\n const centralDir: Buffer[] = [];\n const localFiles: Buffer[] = [];\n let offset = 0;\n\n for (const entry of entries) {\n const compressed = deflateRawSync(entry.data);\n const nameBytes = Buffer.from(entry.name, \"utf-8\");\n const crc = crc32(entry.data);\n\n // Local file header\n const local = Buffer.alloc(30 + nameBytes.length);\n local.writeUInt32LE(0x04034b50, 0); // signature\n local.writeUInt16LE(20, 4); // version needed\n local.writeUInt16LE(0, 6); // flags\n local.writeUInt16LE(8, 8); // compression: deflate\n local.writeUInt16LE(0, 10); // mod time\n local.writeUInt16LE(0, 12); // mod date\n local.writeUInt32LE(crc, 14); // crc32\n local.writeUInt32LE(compressed.length, 18); // compressed size\n local.writeUInt32LE(entry.data.length, 22); // uncompressed size\n local.writeUInt16LE(nameBytes.length, 26); // name length\n local.writeUInt16LE(0, 28); // extra length\n nameBytes.copy(local, 30);\n\n localFiles.push(local);\n localFiles.push(compressed);\n\n // Central directory header\n const central = Buffer.alloc(46 + nameBytes.length);\n central.writeUInt32LE(0x02014b50, 0); // signature\n central.writeUInt16LE(20, 4); // version made by\n central.writeUInt16LE(20, 6); // version needed\n central.writeUInt16LE(0, 8); // flags\n central.writeUInt16LE(8, 10); // compression\n central.writeUInt16LE(0, 12); // mod time\n central.writeUInt16LE(0, 14); // mod date\n central.writeUInt32LE(crc, 16); // crc32\n central.writeUInt32LE(compressed.length, 20);\n central.writeUInt32LE(entry.data.length, 24);\n central.writeUInt16LE(nameBytes.length, 28);\n central.writeUInt16LE(0, 30); // extra length\n central.writeUInt16LE(0, 32); // comment length\n central.writeUInt16LE(0, 34); // disk number\n central.writeUInt16LE(0, 36); // internal attrs\n central.writeUInt32LE(0, 38); // external attrs\n central.writeUInt32LE(offset, 42); // relative offset\n nameBytes.copy(central, 46);\n\n centralDir.push(central);\n offset += local.length + compressed.length;\n }\n\n const centralDirBuf = Buffer.concat(centralDir);\n const centralDirOffset = offset;\n\n // End of central directory\n const eocd = Buffer.alloc(22);\n eocd.writeUInt32LE(0x06054b50, 0); // signature\n eocd.writeUInt16LE(0, 4); // disk number\n eocd.writeUInt16LE(0, 6); // disk of central dir\n eocd.writeUInt16LE(entries.length, 8); // entries on disk\n eocd.writeUInt16LE(entries.length, 10); // total entries\n eocd.writeUInt32LE(centralDirBuf.length, 12); // central dir size\n eocd.writeUInt32LE(centralDirOffset, 16); // central dir offset\n eocd.writeUInt16LE(0, 20); // comment length\n\n return Buffer.concat([...localFiles, centralDirBuf, eocd]);\n}\n\nfunction crc32(buf: Buffer): number {\n let crc = 0xFFFFFFFF;\n for (let i = 0; i < buf.length; i++) {\n crc ^= buf[i];\n for (let j = 0; j < 8; j++) {\n crc = (crc >>> 1) ^ ((crc & 1) ? 0xEDB88320 : 0);\n }\n }\n return (crc ^ 0xFFFFFFFF) >>> 0;\n}\n\n// ──── OOXML Document Parts ────\n\nfunction contentTypes(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>\n <Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>\n</Types>`;\n}\n\nfunction rootRels(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/>\n</Relationships>`;\n}\n\nfunction docRels(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>`;\n}\n\nfunction styles(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:styles xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:style w:type=\"paragraph\" w:styleId=\"Title\"><w:name w:val=\"Title\"/><w:pPr><w:spacing w:after=\"200\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"52\"/><w:color w:val=\"00D4FF\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading1\"><w:name w:val=\"heading 1\"/><w:pPr><w:spacing w:before=\"400\" w:after=\"200\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"32\"/><w:color w:val=\"E2E8F0\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading2\"><w:name w:val=\"heading 2\"/><w:pPr><w:spacing w:before=\"300\" w:after=\"100\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"26\"/><w:color w:val=\"8B9DB8\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/><w:rPr><w:sz w:val=\"22\"/><w:rFonts w:ascii=\"Calibri\" w:hAnsi=\"Calibri\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Code\"><w:name w:val=\"Code\"/><w:pPr><w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"F5F5F5\"/><w:spacing w:before=\"60\" w:after=\"60\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Consolas\" w:hAnsi=\"Consolas\"/><w:sz w:val=\"18\"/></w:rPr></w:style>\n</w:styles>`;\n}\n\n// ──── XML Helpers ────\n\nconst W = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\";\n\nfunction xml(s: string): string {\n return s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nfunction para(text: string, style?: string, props?: string): string {\n const pPr = style ? `<w:pPr><w:pStyle w:val=\"${style}\"/>${props ?? \"\"}</w:pPr>` : (props ? `<w:pPr>${props}</w:pPr>` : \"\");\n return `<w:p>${pPr}<w:r><w:t xml:space=\"preserve\">${xml(text)}</w:t></w:r></w:p>`;\n}\n\nfunction boldPara(text: string, color?: string): string {\n const rPr = `<w:rPr><w:b/>${color ? `<w:color w:val=\"${color}\"/>` : \"\"}</w:rPr>`;\n return `<w:p><w:r>${rPr}<w:t xml:space=\"preserve\">${xml(text)}</w:t></w:r></w:p>`;\n}\n\nfunction colorRun(text: string, color: string, bold?: boolean): string {\n const rPr = `<w:rPr>${bold ? \"<w:b/>\" : \"\"}<w:color w:val=\"${color}\"/></w:rPr>`;\n return `<w:r>${rPr}<w:t xml:space=\"preserve\">${xml(text)}</w:t></w:r>`;\n}\n\nfunction multiRunPara(runs: string[]): string {\n return `<w:p>${runs.join(\"\")}</w:p>`;\n}\n\nfunction tableCellSimple(text: string, shade?: string, bold?: boolean): string {\n const shd = shade ? `<w:tcPr><w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${shade}\"/></w:tcPr>` : \"\";\n const rPr = bold ? \"<w:rPr><w:b/></w:rPr>\" : \"\";\n return `<w:tc>${shd}<w:p><w:r>${rPr}<w:t xml:space=\"preserve\">${xml(text)}</w:t></w:r></w:p></w:tc>`;\n}\n\nfunction tableRow(cells: string[]): string {\n return `<w:tr>${cells.join(\"\")}</w:tr>`;\n}\n\nfunction hr(): string {\n return `<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"1\" w:color=\"CCCCCC\"/></w:pBdr></w:pPr></w:p>`;\n}\n\n// ──── Document Body Builder (helpers) ────\n\nconst TABLE_BORDERS = `<w:tblBorders><w:top w:val=\"single\" w:sz=\"4\" w:color=\"CCCCCC\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:color=\"CCCCCC\"/><w:insideH w:val=\"single\" w:sz=\"4\" w:color=\"E0E0E0\"/><w:insideV w:val=\"single\" w:sz=\"4\" w:color=\"E0E0E0\"/></w:tblBorders>`;\n\nfunction wrapTable(rows: string): string {\n return `<w:tbl><w:tblPr>${TABLE_BORDERS}<w:tblW w:w=\"5000\" w:type=\"pct\"/></w:tblPr>${rows}</w:tbl>`;\n}\n\nfunction buildDocxTitlePage(result: ScanResult): string {\n const parts: string[] = [];\n const name = result.context.rootDir.split(\"/\").pop() ?? \"project\";\n const date = new Date().toLocaleDateString(\"en-US\", { month: \"long\", day: \"numeric\", year: \"numeric\" });\n\n parts.push(para(\"VIBEDRIFT REPORT\", \"Title\"));\n parts.push(para(`${name}`, \"Heading1\"));\n parts.push(para(`Generated: ${date} | Files: ${result.context.files.length} | Lines: ${result.context.totalLines.toLocaleString()} | Scan: ${(result.scanTimeMs / 1000).toFixed(1)}s`));\n const langs = [...result.context.languageBreakdown.entries()].map(([l, s]) => `${l}: ${s.files} files`).join(\", \");\n parts.push(para(`Languages: ${langs}`));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxScoreTable(result: ScanResult): string {\n const parts: string[] = [];\n const pct = result.maxCompositeScore > 0 ? (result.compositeScore / result.maxCompositeScore) * 100 : 0;\n const grade = pct >= 90 ? \"A\" : pct >= 75 ? \"B\" : pct >= 50 ? \"C\" : pct >= 25 ? \"D\" : \"F\";\n\n parts.push(para(\"1. SCORE SUMMARY\", \"Heading1\"));\n parts.push(boldPara(`Composite Score: ${result.compositeScore} / ${result.maxCompositeScore} (Grade ${grade})`));\n parts.push(para(\"\"));\n\n const ds = result.driftScores ?? {};\n const catRows = [\n [\"Architectural Consistency\", ds.architectural_consistency],\n [\"Security Posture\", ds.security_posture],\n [\"Semantic Duplication\", ds.semantic_duplication],\n [\"Convention Drift\", ds.naming_conventions],\n [\"Phantom Scaffolding\", ds.phantom_scaffolding],\n ];\n\n const headerRow = tableRow([\n tableCellSimple(\"Category\", \"D9E2F3\", true),\n tableCellSimple(\"Score\", \"D9E2F3\", true),\n tableCellSimple(\"Max\", \"D9E2F3\", true),\n tableCellSimple(\"Findings\", \"D9E2F3\", true),\n ]);\n const dataRows = catRows.map(([catName, catScore]) => {\n const cs = catScore as any;\n return tableRow([\n tableCellSimple(catName as string),\n tableCellSimple(String(cs?.score ?? 0)),\n tableCellSimple(String(cs?.maxScore ?? 0)),\n tableCellSimple(String(cs?.findings ?? 0)),\n ]);\n }).join(\"\");\n\n parts.push(wrapTable(headerRow + dataRows));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxIntentSection(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"2. CODEBASE INTENT\", \"Heading1\"));\n parts.push(para(\"The following patterns represent the dominant approach established by the majority of files in this codebase.\"));\n parts.push(para(\"\"));\n\n const intentSeen = new Set<string>();\n for (const d of (result.driftFindings ?? [])) {\n const key = d.driftCategory + \"::\" + d.dominantPattern;\n if (intentSeen.has(key)) continue;\n intentSeen.add(key);\n parts.push(boldPara(`${d.driftCategory.replace(/_/g, \" \").toUpperCase()}: ${d.dominantPattern}`));\n parts.push(para(` ${d.dominantCount} of ${d.totalRelevantFiles} files follow this pattern (${d.consistencyScore}% consistency)`));\n }\n if (intentSeen.size === 0) parts.push(para(\"No dominant patterns detected — codebase may be too small or highly consistent.\"));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxDriftSection(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"3. DRIFT FINDINGS\", \"Heading1\"));\n parts.push(para(`${(result.driftFindings ?? []).length} cross-file contradictions detected.`));\n parts.push(para(\"\"));\n\n for (const d of (result.driftFindings ?? [])) {\n const sevStr = d.severity === \"error\" ? \"CRITICAL\" : d.severity === \"warning\" ? \"WARNING\" : \"INFO\";\n parts.push(para(`[${sevStr}] ${d.finding}`, \"Heading2\"));\n parts.push(para(`Category: ${d.driftCategory.replace(/_/g, \" \")} | Consistency: ${d.consistencyScore}% | Confidence: ${Math.round(d.confidence * 100)}%`));\n parts.push(para(\"\"));\n\n parts.push(boldPara(\"INTENT (DOMINANT PATTERN)\", \"10B981\"));\n parts.push(para(`Pattern: ${d.dominantPattern} — used by ${d.dominantCount} of ${d.totalRelevantFiles} files`));\n parts.push(para(\"\"));\n\n parts.push(boldPara(\"DEVIATING FILES\", \"F97316\"));\n for (const df of d.deviatingFiles) {\n parts.push(para(` File: ${df.path}`));\n parts.push(para(` Pattern: ${df.detectedPattern}`));\n for (const ev of df.evidence.slice(0, 3)) {\n parts.push(para(` Line ${ev.line}: ${ev.code.slice(0, 100)}`, \"Code\"));\n }\n parts.push(para(\"\"));\n }\n\n parts.push(boldPara(\"Pattern Distribution:\"));\n parts.push(para(` ${d.dominantPattern}: ${d.dominantCount} files (${Math.round((d.dominantCount / d.totalRelevantFiles) * 100)}%)`));\n parts.push(para(` Deviating: ${d.totalRelevantFiles - d.dominantCount} files (${Math.round(((d.totalRelevantFiles - d.dominantCount) / d.totalRelevantFiles) * 100)}%)`));\n parts.push(para(\"\"));\n\n if (d.recommendation) {\n parts.push(boldPara(\"RECOMMENDATION:\", \"00D4FF\"));\n parts.push(para(` ${d.recommendation}`));\n }\n parts.push(hr());\n }\n return parts.join(\"\\n \");\n}\n\nfunction docxDnaDuplicates(dna: any): string[] {\n if (!dna.duplicateGroups?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Semantic Fingerprint Duplicates\", \"Heading2\"));\n for (const g of dna.duplicateGroups) {\n const fns = g.functions.map((f: any) => `${f.name}() in ${f.relativePath || f.file}`).join(\", \");\n parts.push(para(` Group: ${fns}`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction docxDnaSequences(dna: any): string[] {\n if (!dna.sequenceSimilarities?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Operation Sequence Matches\", \"Heading2\"));\n for (const s of dna.sequenceSimilarities) {\n parts.push(para(` ${Math.round(s.similarity * 100)}% match: ${s.functionA.name}() in ${s.functionA.relativePath || s.functionA.file} ↔ ${s.functionB.name}() in ${s.functionB.relativePath || s.functionB.file}`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction docxDnaTaintFlows(dna: any): string[] {\n if (!dna.taintFlows?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Taint Flows\", \"Heading2\"));\n for (const t of dna.taintFlows) {\n parts.push(para(` [${t.sink.severity.toUpperCase()}] ${t.functionName}() in ${t.relativePath || t.file}: ${t.source.type} (line ${t.source.line}) → ${t.sink.type} (line ${t.sink.line}) — ${t.sanitized ? \"SANITIZED\" : \"UNSANITIZED\"}`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction docxDnaDeviations(dna: any): string[] {\n if (!dna.deviationJustifications?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Deviation Justification Analysis\", \"Heading2\"));\n for (const dj of dna.deviationJustifications) {\n const verdict = dj.verdict === \"likely_justified\" ? \"JUSTIFIED\" : dj.verdict === \"likely_accidental\" ? \"ACCIDENTAL\" : \"UNCERTAIN\";\n parts.push(para(` [${verdict}] ${dj.relativePath || dj.file}: uses ${dj.deviatingPattern} vs project ${dj.dominantPattern} (score: ${Math.round(dj.justificationScore * 100)}%)`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction docxDnaPatterns(dna: any): string[] {\n if (!dna.patternDistributions?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Pattern Classification\", \"Heading2\"));\n for (const pd of dna.patternDistributions) {\n const mixed = pd.isInternallyInconsistent ? \" [MIXED]\" : \"\";\n parts.push(para(` ${pd.relativePath || pd.file}: ${pd.dominantPattern} (${Math.round(pd.confidence * 100)}% confidence)${mixed}`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction buildDocxCodeDnaSection(result: ScanResult): string {\n const dna = result.codeDnaResult;\n if (!dna) return \"\";\n\n const parts: string[] = [];\n parts.push(para(\"4. CODE DNA ANALYSIS\", \"Heading1\"));\n parts.push(para(`${dna.functions?.length ?? 0} functions analyzed in ${dna.timings?.totalMs ?? 0}ms. ${dna.findings?.length ?? 0} findings.`));\n parts.push(para(\"\"));\n\n parts.push(\n ...docxDnaDuplicates(dna),\n ...docxDnaSequences(dna),\n ...docxDnaTaintFlows(dna),\n ...docxDnaDeviations(dna),\n ...docxDnaPatterns(dna),\n );\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxPerFileTable(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"5. FILE RANKING\", \"Heading1\"));\n const fileSorted = [...result.perFileScores.entries()].sort((a, b) => a[1].score - b[1].score);\n parts.push(para(`${fileSorted.length} files scanned. Ranked worst to best.`));\n parts.push(para(\"\"));\n\n const fileHeaderRow = tableRow([\n tableCellSimple(\"File\", \"D9E2F3\", true),\n tableCellSimple(\"Score\", \"D9E2F3\", true),\n tableCellSimple(\"Drift\", \"D9E2F3\", true),\n tableCellSimple(\"Static\", \"D9E2F3\", true),\n ]);\n const fileDataRows = fileSorted.slice(0, 40).map(([path, data]) => {\n const driftCount = data.findings.filter((f) => f.tags?.includes(\"drift\") || f.tags?.includes(\"codedna\")).length;\n const staticCount = data.findings.length - driftCount;\n return tableRow([\n tableCellSimple(path),\n tableCellSimple(`${data.score}/100`),\n tableCellSimple(String(driftCount)),\n tableCellSimple(String(staticCount)),\n ]);\n }).join(\"\");\n\n parts.push(wrapTable(fileHeaderRow + fileDataRows));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxFindingsTable(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"6. STATIC ANALYSIS FINDINGS\", \"Heading1\"));\n const statics = result.findings.filter((f) => !f.tags?.includes(\"drift\") && !f.tags?.includes(\"codedna\"));\n parts.push(para(`${statics.length} findings from ${13} static analyzers.`));\n parts.push(para(\"\"));\n\n for (const f of statics.slice(0, 50)) {\n const loc = f.locations[0];\n const sevStr = f.severity === \"error\" ? \"ERROR\" : f.severity === \"warning\" ? \"WARNING\" : \"INFO\";\n parts.push(para(`[${sevStr}] [${f.analyzerId}] ${f.message}`));\n if (loc) parts.push(para(` File: ${loc.file}${loc.line ? `:${loc.line}` : \"\"} | Confidence: ${Math.round(f.confidence * 100)}%`));\n }\n if (statics.length > 50) parts.push(para(`... and ${statics.length - 50} more findings.`));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxDeepInsights(result: ScanResult): string {\n if ((result.deepInsights ?? []).length === 0) return \"\";\n\n const parts: string[] = [];\n parts.push(para(\"7. DEEP ANALYSIS INSIGHTS (AI-POWERED)\", \"Heading1\"));\n for (const ins of result.deepInsights) {\n const sevStr = ins.severity === \"error\" ? \"CRITICAL\" : ins.severity === \"warning\" ? \"WARNING\" : \"INFO\";\n parts.push(para(`[${sevStr}] ${ins.title}`, \"Heading2\"));\n parts.push(para(ins.description));\n if (ins.relatedFiles.length > 0) parts.push(para(` Files: ${ins.relatedFiles.join(\", \")}`));\n if (ins.recommendation) {\n parts.push(boldPara(\"Recommendation:\", \"00D4FF\"));\n parts.push(para(` ${ins.recommendation}`));\n }\n parts.push(para(\"\"));\n }\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxFooter(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"\"));\n parts.push(para(`Generated by VibeDrift v${getVersion()} | ${result.context.files.length} files | ${result.context.totalLines.toLocaleString()} lines | ${(result.scanTimeMs / 1000).toFixed(1)}s | No data sent externally`));\n parts.push(para(\"Re-scan: npx vibedrift .\"));\n return parts.join(\"\\n \");\n}\n\n// ──── Document Body Builder ────\n\nfunction buildDocumentXml(result: ScanResult): string {\n const sections = [\n buildDocxTitlePage(result),\n buildDocxScoreTable(result),\n buildDocxIntentSection(result),\n buildDocxDriftSection(result),\n buildDocxCodeDnaSection(result),\n buildDocxPerFileTable(result),\n buildDocxFindingsTable(result),\n buildDocxDeepInsights(result),\n buildDocxFooter(result),\n ].filter(Boolean);\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:document xmlns:w=\"${W}\">\n <w:body>\n ${sections.join(\"\\n \")}\n <w:sectPr>\n <w:pgSz w:w=\"12240\" w:h=\"15840\"/>\n <w:pgMar w:top=\"1440\" w:right=\"1440\" w:bottom=\"1440\" w:left=\"1440\"/>\n </w:sectPr>\n </w:body>\n</w:document>`;\n}\n\n// ──── Public API ────\n\nexport function renderDocxReport(result: ScanResult): Buffer {\n const entries: ZipEntry[] = [\n { name: \"[Content_Types].xml\", data: Buffer.from(contentTypes(), \"utf-8\") },\n { name: \"_rels/.rels\", data: Buffer.from(rootRels(), \"utf-8\") },\n { name: \"word/_rels/document.xml.rels\", data: Buffer.from(docRels(), \"utf-8\") },\n { name: \"word/styles.xml\", data: Buffer.from(styles(), \"utf-8\") },\n { name: \"word/document.xml\", data: Buffer.from(buildDocumentXml(result), \"utf-8\") },\n ];\n return buildZip(entries);\n}\n","/**\n * CLI entry point — wires Commander.js commands to their handlers.\n *\n * \"scan\" is the default command (runs when no subcommand is given). Account\n * commands (login, logout, status, usage, upgrade, billing) manage auth and\n * Stripe integration. Maintenance commands (update, doctor, feedback) handle\n * self-update, diagnostics, and user feedback.\n */\n\nimport { Command, Option } from \"commander\";\nimport { runScan } from \"./commands/scan.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { runLogin } from \"./commands/login.js\";\nimport { runLogout } from \"./commands/logout.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { runUsage } from \"./commands/usage.js\";\nimport { runUpgrade } from \"./commands/upgrade.js\";\nimport { runBilling } from \"./commands/billing.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { runFeedback } from \"./commands/feedback.js\";\nimport { getVersion } from \"../core/version.js\";\n\nconst VERSION = getVersion();\n\nfunction parseScoreThreshold(value: string): number {\n const n = parseFloat(value);\n if (Number.isNaN(n) || n < 0 || n > 100) {\n console.error(\n `Error: --fail-on-score must be a number between 0 and 100, got \"${value}\"`,\n );\n process.exit(1);\n }\n return n;\n}\n\nfunction collect(value: string, previous: string[]): string[] {\n return previous.concat([value]);\n}\n\nconst program = new Command();\n\nprogram\n .name(\"vibedrift\")\n .description(\n \"Detect drift, contradictions, and security gaps in AI-generated codebases.\",\n )\n .version(VERSION, \"-V, --version\", \"show the installed version\")\n .helpOption(\"-h, --help\", \"show this help\");\n\n// ──── Default subcommand: scan ────\nprogram\n .command(\"scan\", { isDefault: true })\n .description(\"Scan a project for vibe drift (default command)\")\n .argument(\"[path]\", \"path to project directory\", \".\")\n // Output\n .option(\n \"--format <type>\",\n \"output format: html, terminal, json, csv, docx\",\n \"html\",\n )\n .option(\"--output <path>\", \"write report to a file\")\n .option(\"--json\", \"shorthand for --format json\")\n .option(\n \"--fail-on-score <n>\",\n \"exit with code 1 if composite score is below this threshold\",\n parseScoreThreshold,\n )\n // Analysis toggles\n .option(\"--no-codedna\", \"skip Code DNA semantic analysis\")\n .option(\n \"--deep\",\n \"enable AI-powered deep analysis (requires `vibedrift login`)\",\n )\n .option(\n \"--project-name <name>\",\n \"override the auto-detected project name shown in the dashboard\",\n )\n // File filtering\n .option(\n \"--include <pattern>\",\n \"only scan files matching this glob (repeatable)\",\n collect,\n [],\n )\n .option(\n \"--exclude <pattern>\",\n \"exclude files matching this glob (repeatable)\",\n collect,\n [],\n )\n // Maintenance\n .option(\n \"--update\",\n \"update the VibeDrift CLI to the latest version (alias for `vibedrift update`)\",\n )\n .option(\n \"--feedback [message...]\",\n \"send feedback to the maintainer (alias for `vibedrift feedback`)\",\n )\n .option(\"--verbose\", \"show timing breakdown and analyzer details\")\n // Hidden / advanced\n .addOption(\n new Option(\"--api-url <url>\", \"override the VibeDrift API base URL\")\n .hideHelp(),\n )\n .action(async (path: string, options) => {\n if (options.update) {\n await runUpdate(VERSION);\n return;\n }\n if (options.feedback) {\n // --feedback can be a bare flag (`true`) or carry inline words\n // (`[\"the\", \"install\", \"is\", \"broken\"]`); normalize both into a string\n const inline = Array.isArray(options.feedback)\n ? options.feedback.join(\" \").trim()\n : \"\";\n await runFeedback({\n message: inline || undefined,\n apiUrl: options.apiUrl,\n });\n return;\n }\n\n await runScan(path, {\n json: options.json,\n format: options.json ? \"json\" : options.format,\n output: options.output,\n failOnScore: options.failOnScore,\n codedna: options.codedna,\n deep: options.deep,\n apiUrl: options.apiUrl,\n include: options.include,\n exclude: options.exclude,\n verbose: options.verbose,\n projectName: options.projectName,\n });\n });\n\n// ──── Account / auth subcommands ────\nprogram\n .command(\"login\")\n .description(\"Log in to your VibeDrift account\")\n .option(\"--no-browser\", \"don't open the browser automatically\")\n .addOption(\n new Option(\"--api-url <url>\", \"override the API base URL\")\n .hideHelp(),\n )\n .action(async (options) => {\n await runLogin({\n apiUrl: options.apiUrl,\n noBrowser: options.browser === false,\n });\n });\n\nprogram\n .command(\"logout\")\n .description(\"Log out and revoke the current token\")\n .action(async () => {\n await runLogout();\n });\n\nprogram\n .command(\"status\")\n .description(\"Show the current account, plan, and token\")\n .action(async () => {\n await runStatus();\n });\n\nprogram\n .command(\"usage\")\n .description(\"Show your current billing period's scan usage\")\n .action(async () => {\n await runUsage();\n });\n\nprogram\n .command(\"upgrade\")\n .description(\"Open the VibeDrift pricing page\")\n .action(async () => {\n await runUpgrade();\n });\n\nprogram\n .command(\"billing\")\n .description(\"Open the Stripe Customer Portal to manage your subscription\")\n .action(async () => {\n await runBilling();\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Diagnose CLI installation, auth, and API connectivity\")\n .action(async () => {\n await runDoctor();\n });\n\nprogram\n .command(\"update\")\n .description(\"Update the VibeDrift CLI to the latest version\")\n .action(async () => {\n await runUpdate(VERSION);\n });\n\nprogram\n .command(\"feedback\")\n .description(\"Send feedback, bug reports, or feature requests directly to the maintainer\")\n .argument(\n \"[message...]\",\n \"feedback text (omit to be prompted interactively)\",\n )\n .addOption(\n new Option(\"--api-url <url>\", \"override the API base URL\").hideHelp(),\n )\n .action(async (messageWords: string[], options) => {\n const message = (messageWords ?? []).join(\" \").trim() || undefined;\n await runFeedback({ message, apiUrl: options.apiUrl });\n });\n\nprogram.addHelpText(\n \"after\",\n `\nExamples:\n $ vibedrift scan the current directory\n $ vibedrift ./my-project scan a specific project\n $ vibedrift --format terminal print results to the terminal\n $ vibedrift --json > report.json pipe JSON output to a file\n $ vibedrift --fail-on-score 70 fail CI if score drops below 70\n $ vibedrift --include \"src/**\" only scan files under src/\n $ vibedrift --exclude \"**/*.spec.*\" skip test files\n $ vibedrift --deep run premium AI-powered deep analysis\n $ vibedrift login sign in to enable --deep\n $ vibedrift status check current auth state\n $ vibedrift usage view this month's scan usage\n $ vibedrift upgrade open the pricing page\n $ vibedrift billing manage your Stripe subscription\n $ vibedrift update update to the latest CLI version\n $ vibedrift feedback open an interactive feedback prompt\n $ vibedrift feedback \"the install is broken on Windows\"\n send inline feedback in one shot\n $ vibedrift --feedback \"...\" same as above, top-level shortcut\n\nEnvironment:\n VIBEDRIFT_TOKEN bearer token (overrides ~/.vibedrift/config.json)\n VIBEDRIFT_API_URL override the API base URL\n VIBEDRIFT_NO_BROWSER if \"1\", never auto-open the browser\n\nLearn more: https://vibedrift.ai`,\n);\n\n// Top-level catch ensures unhandled rejections from any command\n// produce a clean error message instead of a stack trace\nprogram.parseAsync().catch((err) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","import { resolve } from \"path\";\nimport { writeFile } from \"fs/promises\";\nimport { stat } from \"fs/promises\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { buildAnalysisContext } from \"../../core/discovery.js\";\nimport { parseFiles } from \"../../utils/ast.js\";\nimport { createAnalyzerRegistry } from \"../../analyzers/index.js\";\nimport { runDriftDetection } from \"../../drift/index.js\";\nimport { computeScores } from \"../../scoring/engine.js\";\nimport { generateTeaseMessages } from \"../../output/tease.js\";\nimport { renderTerminalOutput, renderJsonOutput } from \"../../output/terminal.js\";\nimport { renderHtmlReport } from \"../../output/html.js\";\nimport { saveScanResult, loadPreviousScores } from \"../../core/history.js\";\nimport { applyIncludeExclude } from \"../../core/file-filter.js\";\nimport { resolveToken, resolveApiUrl } from \"../../auth/resolver.js\";\nimport { fetchCredits } from \"../../auth/api.js\";\nimport type { Finding, ScanResult, ScanOptions, SourceFile } from \"../../core/types.js\";\n\n// ────────────────────────────────────────────────────────────────────\n// 1. resolveAuthAndBanner\n// ────────────────────────────────────────────────────────────────────\nasync function resolveAuthAndBanner(\n options: ScanOptions,\n): Promise<{ bearerToken: string | null; apiUrl: string | undefined }> {\n // ──── Resolve token *before* the scan starts ────\n // Required for --deep (the API call would 401 anyway), but ALSO attempted\n // for free scans so we can log them to the user's dashboard. Free scans\n // without a token still work — they just don't appear in the dashboard.\n let bearerToken: string | null = null;\n let apiUrl: string | undefined = options.apiUrl;\n if (options.deep) {\n const resolved = await resolveToken();\n if (!resolved) {\n console.error(\"\");\n console.error(chalk.red(\" ✗ Deep scans require a VibeDrift account.\"));\n console.error(\"\");\n console.error(chalk.bgYellow.black.bold(\" 🎁 But your first deep scan is FREE. \"));\n console.error(\"\");\n console.error(\" Run \" + chalk.bold(\"vibedrift login\") + \" to sign in and claim it.\");\n console.error(\" Or set \" + chalk.bold(\"VIBEDRIFT_TOKEN\") + \" in your environment for CI.\");\n console.error(\"\");\n process.exit(1);\n }\n bearerToken = resolved.token;\n apiUrl = await resolveApiUrl(options.apiUrl);\n } else {\n // Free scan: best-effort token resolution. If the user is logged in\n // we log the scan to their dashboard; if not, the local scan still\n // runs to completion.\n try {\n const resolved = await resolveToken();\n if (resolved) {\n bearerToken = resolved.token;\n apiUrl = await resolveApiUrl(options.apiUrl);\n }\n } catch {\n // ignore — free scans don't require auth\n }\n }\n\n // ──── Advertise the one-time welcome credit ────\n // Three cases:\n // 1. Logged in + has welcome credit unconsumed → \"🎁 1 free deep scan ready\"\n // 2. Logged in + already used / pro plan → no banner\n // 3. Not logged in → \"Sign up to get 1 free deep scan\"\n //\n // Visible for both `--format html` (default) and `--format terminal`,\n // suppressed for `--json` and explicit deep scans (the banner only\n // makes sense before a free scan, not during a deep one).\n if (!options.json && options.format !== \"json\" && !options.deep) {\n if (bearerToken) {\n try {\n const credits = await fetchCredits(bearerToken, { apiUrl });\n if (credits.has_free_deep_scan && !credits.unlimited) {\n console.log(\"\");\n console.log(chalk.bgYellow.black.bold(\" 🎁 1 FREE DEEP SCAN AVAILABLE \"));\n console.log(chalk.yellow(\" Run with \") + chalk.bold.cyan(\"--deep\") + chalk.yellow(\" to use Claude-powered analysis (no card required).\"));\n console.log(\"\");\n }\n } catch {\n // Older API build or transient error — skip the banner.\n }\n } else {\n console.log(\"\");\n console.log(chalk.dim(\" Tip: \") + chalk.yellow(\"sign up free to get 1 deep scan included\"));\n console.log(chalk.dim(\" Run \") + chalk.bold(\"vibedrift login\") + chalk.dim(\" to claim it (no card required).\"));\n console.log(\"\");\n }\n }\n\n return { bearerToken, apiUrl };\n}\n\n// ────────────────────────────────────────────────────────────────────\n// 2. runAnalysisPipeline\n// ────────────────────────────────────────────────────────────────────\nasync function discoverAndFilterFiles(\n rootDir: string,\n options: ScanOptions,\n spinner: ReturnType<typeof ora> | null,\n): Promise<{\n ctx: Awaited<ReturnType<typeof buildAnalysisContext>>[\"ctx\"];\n discoveryMs: number;\n}> {\n const isTerminal = options.format === \"terminal\" && !options.json;\n const t0 = Date.now();\n const { ctx, warnings } = await buildAnalysisContext(rootDir);\n\n // Apply --include / --exclude glob filters in-place on the context's files.\n const includes = options.include ?? [];\n const excludes = options.exclude ?? [];\n if (includes.length > 0 || excludes.length > 0) {\n const before = ctx.files.length;\n const filtered = applyIncludeExclude(ctx.files, includes, excludes);\n ctx.files = filtered;\n ctx.totalLines = filtered.reduce((sum: number, f: SourceFile) => sum + f.lineCount, 0);\n if (options.verbose) {\n console.error(chalk.dim(`[filter] ${before} → ${filtered.length} files after include/exclude`));\n }\n }\n\n const discoveryMs = Date.now() - t0;\n\n // Report discovery warnings\n if (isTerminal) {\n if (warnings.truncated) {\n console.warn(chalk.yellow(`\\nWarning: File limit reached (${warnings.truncatedAt}). Only partial coverage — results may be incomplete.`));\n }\n if (warnings.skippedDirs.length > 0) {\n console.warn(chalk.yellow(`Warning: ${warnings.skippedDirs.length} directories skipped (permission denied): ${warnings.skippedDirs.slice(0, 3).join(\", \")}${warnings.skippedDirs.length > 3 ? \"...\" : \"\"}`));\n }\n if (warnings.unreadableFiles.length > 0) {\n console.warn(chalk.yellow(`Warning: ${warnings.unreadableFiles.length} files unreadable: ${warnings.unreadableFiles.slice(0, 3).join(\", \")}${warnings.unreadableFiles.length > 3 ? \"...\" : \"\"}`));\n }\n }\n\n if (ctx.files.length === 0) {\n if (spinner) spinner.stop();\n console.log(\"No source files found to analyze.\");\n process.exit(0);\n }\n\n return { ctx, discoveryMs };\n}\n\nasync function runAnalysisPipeline(\n rootDir: string,\n options: ScanOptions,\n spinner: ReturnType<typeof ora> | null,\n): Promise<{\n ctx: Awaited<ReturnType<typeof buildAnalysisContext>>[\"ctx\"];\n allFindings: Finding[];\n driftResult: ReturnType<typeof runDriftDetection>;\n codeDnaResult: any;\n timings: Record<string, number>;\n}> {\n const isTerminal = options.format === \"terminal\" && !options.json;\n const timings: Record<string, number> = {};\n\n const { ctx, discoveryMs } = await discoverAndFilterFiles(rootDir, options, spinner);\n timings.discovery = discoveryMs;\n\n if (spinner) spinner.text = `Parsing ${ctx.files.length} files...`;\n\n // Parse ASTs\n const t1 = Date.now();\n await parseFiles(ctx.files);\n timings.parsing = Date.now() - t1;\n\n // Run analyzers\n const t2 = Date.now();\n const analyzers = createAnalyzerRegistry();\n if (spinner) spinner.text = `Running ${analyzers.length} analyzers...`;\n const allFindings: Finding[] = [];\n\n for (const analyzer of analyzers) {\n const findings = await analyzer.analyze(ctx);\n allFindings.push(...findings);\n }\n\n timings.analyzers = Date.now() - t2;\n\n // Run cross-file drift detection\n const t3 = Date.now();\n if (spinner) spinner.text = \"Detecting vibe drift...\";\n const driftResult = runDriftDetection(ctx);\n allFindings.push(...driftResult.findings);\n timings.drift = Date.now() - t3;\n\n // Run Code DNA analysis (Layer 1.7)\n let codeDnaResult: any = undefined;\n if (options.codedna !== false) {\n const t4 = Date.now();\n if (spinner) spinner.text = \"Running Code DNA analysis...\";\n const { runCodeDnaAnalysis } = await import(\"../../codedna/index.js\");\n codeDnaResult = runCodeDnaAnalysis(ctx);\n allFindings.push(...codeDnaResult.findings);\n timings.codedna = Date.now() - t4;\n if (isTerminal && options.verbose) {\n console.error(`[codedna] ${codeDnaResult.functions.length} functions analyzed in ${codeDnaResult.timings.totalMs}ms`);\n console.error(`[codedna] ${codeDnaResult.duplicateGroups.length} fingerprint duplicates, ${codeDnaResult.sequenceSimilarities.length} sequence matches, ${codeDnaResult.taintFlows.length} taint flows`);\n }\n }\n\n return { ctx, allFindings, driftResult, codeDnaResult, timings };\n}\n\n// ────────────────────────────────────────────────────────────────────\n// 3. runDeepAnalysis\n// ────────────────────────────────────────────────────────────────────\nasync function runDeepAnalysis(\n pipeline: {\n allFindings: Finding[];\n ctx: Awaited<ReturnType<typeof buildAnalysisContext>>[\"ctx\"];\n codeDnaResult: any;\n driftResult: ReturnType<typeof runDriftDetection>;\n },\n options: ScanOptions,\n bearerToken: string,\n apiUrl: string | undefined,\n spinner: ReturnType<typeof ora> | null,\n): Promise<{ timings: Record<string, number> }> {\n const { allFindings, ctx, codeDnaResult, driftResult } = pipeline;\n const timings: Record<string, number> = {};\n\n // Run AI deep analysis (Layer 2) — opt-in with --deep\n let mlMediumConfidence: any[] = [];\n const t5 = Date.now();\n if (spinner) spinner.text = \"Running AI deep analysis (may take ~30s on cold start)...\";\n try {\n const { runMlAnalysis } = await import(\"../../ml-client/index.js\");\n const mlResult = await runMlAnalysis(ctx, codeDnaResult, allFindings, {\n token: bearerToken,\n apiUrl,\n verbose: options.verbose,\n driftFindings: driftResult.driftFindings,\n projectName: options.projectName,\n });\n allFindings.push(...mlResult.highConfidence);\n mlMediumConfidence = mlResult.mediumConfidence;\n if (options.verbose) {\n console.error(`[deep] ${mlResult.highConfidence.length} high-confidence findings shipped, ${mlResult.mediumConfidence.length} sent to LLM, ${mlResult.droppedCount} dropped`);\n }\n } catch (err: any) {\n console.error(chalk.red(`[deep] AI analysis failed: ${err.message}`));\n console.error(chalk.dim(\" The local scan will continue. Run `vibedrift doctor` if this persists.\"));\n }\n timings.deep = Date.now() - t5;\n\n // Deduplicate findings across layers (AI > Code DNA > Static)\n const { deduplicateFindingsAcrossLayers } = await import(\"../../scoring/dedup.js\");\n const dedupedCount = allFindings.length;\n const dedupedFindings = deduplicateFindingsAcrossLayers(allFindings);\n if (options.verbose && dedupedFindings.length < dedupedCount) {\n console.error(`[dedup] Removed ${dedupedCount - dedupedFindings.length} cross-layer duplicate findings`);\n }\n // Replace allFindings with deduplicated version\n allFindings.length = 0;\n allFindings.push(...dedupedFindings);\n\n // suppress unused-var lint (mlMediumConfidence is reserved for future use)\n void mlMediumConfidence;\n\n return { timings };\n}\n\n// ────────────────────────────────────────────────────────────────────\n// 4. buildScanResult\n// ────────────────────────────────────────────────────────────────────\nasync function buildScanResult(\n pipeline: {\n ctx: Awaited<ReturnType<typeof buildAnalysisContext>>[\"ctx\"];\n allFindings: Finding[];\n driftResult: ReturnType<typeof runDriftDetection>;\n codeDnaResult: any;\n },\n options: ScanOptions,\n startTime: number,\n timings: Record<string, number>,\n bearerToken: string | null,\n apiUrl: string | undefined,\n spinner: ReturnType<typeof ora> | null,\n): Promise<ScanResult> {\n const { ctx, allFindings, driftResult, codeDnaResult } = pipeline;\n const rootDir = ctx.rootDir;\n\n // Load previous scores for delta\n const previousScores = await loadPreviousScores(rootDir);\n\n // Score\n if (spinner) spinner.text = \"Computing scores...\";\n const { scores, compositeScore, maxCompositeScore, perFileScores } = computeScores(\n allFindings,\n ctx.totalLines,\n ctx,\n previousScores ?? undefined,\n );\n\n // Deep insights are reserved for the premium AI tier (routed via VibeDrift API).\n // No direct Anthropic key path is exposed to end users.\n const deepInsights: ScanResult[\"deepInsights\"] = [];\n\n // Tease — show \"run --deep\" upsell only when user is *not* using deep mode.\n const teaseMessages = generateTeaseMessages(ctx, allFindings, options.deep === true);\n\n const scanTimeMs = Date.now() - startTime;\n if (spinner) spinner.stop();\n\n // Print timing breakdown so the user knows what's taking time\n const layer1Ms = (timings.discovery ?? 0) + (timings.parsing ?? 0) + (timings.analyzers ?? 0) + (timings.drift ?? 0);\n const parts = [`Layer 1: ${(layer1Ms / 1000).toFixed(1)}s`];\n if (timings.codedna) parts.push(`Code DNA: ${(timings.codedna / 1000).toFixed(1)}s`);\n if (timings.deep) parts.push(`AI: ${(timings.deep / 1000).toFixed(1)}s`);\n parts.push(`Total: ${(scanTimeMs / 1000).toFixed(1)}s`);\n console.error(chalk.dim(` ${parts.join(\" · \")}`));\n\n const result: ScanResult = {\n context: ctx,\n findings: allFindings,\n driftFindings: driftResult.driftFindings,\n driftScores: driftResult.driftScores,\n scores,\n compositeScore,\n maxCompositeScore,\n teaseMessages,\n deepInsights,\n scanTimeMs,\n perFileScores,\n codeDnaResult,\n };\n\n // AI Summary (when --deep is enabled, call the VibeDrift API for an executive summary)\n if (options.deep && bearerToken) {\n if (spinner) spinner.text = \"Generating AI summary...\";\n try {\n const { fetchAiSummary } = await import(\"../../ml-client/summarize.js\");\n const targetUrl = apiUrl ?? \"https://vibedrift-api.fly.dev\";\n if (options.verbose) console.error(`[summary] Calling ${targetUrl}/v1/summarize...`);\n const summary = await fetchAiSummary(result, targetUrl, bearerToken);\n if (summary) {\n result.aiSummary = summary;\n if (options.verbose) console.error(`[summary] AI summary generated (${summary.highlights.length} highlights)`);\n } else {\n if (options.verbose) console.error(`[summary] API returned null`);\n }\n } catch (err: any) {\n if (options.verbose) console.error(`[summary] Failed: ${err.message}`);\n }\n }\n\n return result;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// 5. logAndRender\n// ────────────────────────────────────────────────────────────────────\nasync function logAndRender(\n result: ScanResult,\n options: ScanOptions,\n bearerToken: string | null,\n apiUrl: string | undefined,\n rootDir: string,\n codeDnaResult: any,\n): Promise<void> {\n const { findings: allFindings, compositeScore, maxCompositeScore, scanTimeMs } = result;\n\n // ── Log the scan to the dashboard ──\n // The CLI's full ScanResult (sanitized) is the single source of truth.\n // Both the dashboard's metadata strip AND the embedded HTML report\n // are derived from this object, so they're guaranteed consistent.\n // Runs for both free and deep scans whenever the user is logged in.\n // Silent on failure — the scan already succeeded locally.\n if (bearerToken) {\n try {\n const { logScan } = await import(\"../../ml-client/log-scan.js\");\n const { detectProjectIdentity } = await import(\"../../ml-client/project-name.js\");\n const { sanitizeResultForUpload } = await import(\"../../ml-client/sanitize-result.js\");\n const projectIdentity = await detectProjectIdentity(\n rootDir,\n options.projectName,\n );\n\n // Tally per-detector ML counts (only present for deep scans).\n const mlDuplicates = allFindings.filter((f) => f.analyzerId === \"ml-duplicate\").length;\n const mlIntent = allFindings.filter((f) => f.analyzerId === \"ml-intent\").length;\n const mlAnomaly = allFindings.filter((f) => f.analyzerId === \"ml-anomaly\").length;\n\n // Render the HTML once and ship it. Failures here are fine — the\n // server stores metadata even if the HTML upload is dropped.\n let html: string | undefined;\n try {\n html = renderHtmlReport(result);\n } catch {\n html = undefined;\n }\n\n // Letter grade — MUST match the thresholds in src/output/html.ts\n // gradeFor() so the dashboard's metadata strip agrees with the\n // report it embeds. (A=90, B=75, C=50, D=25, F<25)\n const pct = maxCompositeScore > 0 ? (compositeScore / maxCompositeScore) * 100 : 0;\n const grade =\n pct >= 90 ? \"A\" : pct >= 75 ? \"B\" : pct >= 50 ? \"C\" : pct >= 25 ? \"D\" : \"F\";\n\n // Sanitize the full ScanResult so we can ship it as the canonical\n // metadata blob. Strips ctx.rootDir + any absolute paths.\n const sanitizedResult = sanitizeResultForUpload(result);\n // Stamp the project identity onto the envelope (the sanitizer\n // doesn't know it because it's computed by detectProjectIdentity).\n (sanitizedResult.project as Record<string, unknown>) = {\n name: projectIdentity.name,\n hash: projectIdentity.hash,\n };\n sanitizedResult.grade = grade;\n sanitizedResult.scanType = options.deep ? \"deep\" : \"free\";\n sanitizedResult.scannedAt = new Date().toISOString();\n\n await logScan({\n token: bearerToken,\n apiUrl,\n verbose: options.verbose,\n payload: {\n project_hash: projectIdentity.hash,\n project_name: projectIdentity.name,\n language: result.context.dominantLanguage ?? \"unknown\",\n file_count: result.context.files.length,\n function_count: codeDnaResult?.functions?.length ?? 0,\n finding_count: allFindings.length,\n score: compositeScore,\n grade,\n duplicates_found: mlDuplicates,\n intent_mismatches: mlIntent,\n anomalies_found: mlAnomaly,\n is_deep: !!options.deep,\n processing_time_ms: scanTimeMs,\n report_html: html,\n result_json: sanitizedResult,\n },\n });\n } catch (err: any) {\n if (options.verbose) {\n console.error(chalk.dim(`[scan-log] Failed: ${err.message}`));\n }\n }\n }\n\n // Output\n const format = options.format ?? (options.json ? \"json\" : \"html\");\n await renderToFormat(result, format, options);\n\n // Fail on score threshold\n if (options.failOnScore !== undefined && compositeScore < options.failOnScore) {\n process.exit(1);\n }\n}\n\nasync function renderToFormat(\n result: ScanResult,\n format: string,\n options: ScanOptions,\n): Promise<void> {\n if (format === \"html\") {\n const html = renderHtmlReport(result);\n const outputPath = options.output ?? \"vibedrift-report.html\";\n await writeFile(outputPath, html);\n // Serve on localhost\n const { createServer } = await import(\"http\");\n const server = createServer((req, res) => {\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(html);\n });\n const port = 4173 + Math.floor(Math.random() * 100);\n server.listen(port, () => {\n console.log(`\\n Report saved to ${outputPath}`);\n console.log(` View in browser: \\x1b[36mhttp://localhost:${port}\\x1b[0m\\n`);\n });\n // Keep alive for 10 minutes then auto-close\n setTimeout(() => { server.close(); process.exit(0); }, 600_000);\n // But don't block if user presses Ctrl+C\n process.on(\"SIGINT\", () => { server.close(); process.exit(0); });\n return; // Don't exit — server is running\n } else if (format === \"csv\") {\n const { renderCsvReport } = await import(\"../../output/csv.js\");\n const csv = renderCsvReport(result);\n const outputPath = options.output ?? \"vibedrift-report.csv\";\n await writeFile(outputPath, csv);\n console.log(`CSV report written to ${outputPath}`);\n } else if (format === \"docx\") {\n const { renderDocxReport } = await import(\"../../output/docx.js\");\n const docx = renderDocxReport(result);\n const outputPath = options.output ?? \"vibedrift-report.docx\";\n await writeFile(outputPath, docx);\n console.log(`DOCX report written to ${outputPath}`);\n } else if (format === \"json\") {\n const json = renderJsonOutput(result);\n if (options.output) {\n await writeFile(options.output, json);\n console.log(`JSON report written to ${options.output}`);\n } else {\n console.log(json);\n }\n } else {\n console.log(renderTerminalOutput(result));\n }\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Orchestrator\n// ────────────────────────────────────────────────────────────────────\nexport async function runScan(\n targetPath: string,\n options: ScanOptions,\n): Promise<void> {\n const rootDir = resolve(targetPath);\n\n try {\n const info = await stat(rootDir);\n if (!info.isDirectory()) {\n console.error(`Error: ${rootDir} is not a directory`);\n process.exit(1);\n }\n } catch {\n console.error(`Error: ${rootDir} does not exist`);\n process.exit(1);\n }\n\n const { bearerToken, apiUrl } = await resolveAuthAndBanner(options);\n\n const startTime = Date.now();\n const isTerminal = options.format === \"terminal\" && !options.json;\n const spinner = isTerminal ? ora(\"Discovering files...\").start() : null;\n\n const pipeline = await runAnalysisPipeline(rootDir, options, spinner);\n\n const deepTimings = options.deep && bearerToken\n ? await runDeepAnalysis(pipeline, options, bearerToken, apiUrl, spinner)\n : { timings: {} };\n\n const timings = { ...pipeline.timings, ...deepTimings.timings };\n\n const result = await buildScanResult(pipeline, options, startTime, timings, bearerToken, apiUrl, spinner);\n\n // Save history (per-project, in user home dir — not in the project itself)\n await saveScanResult(rootDir, result.scores, result.compositeScore);\n\n await logAndRender(result, options, bearerToken, apiUrl, rootDir, pipeline.codeDnaResult);\n}\n","/**\n * Project file discovery and manifest loading.\n *\n * Recursively walks the project directory, respects .gitignore rules, and\n * loads ecosystem manifests (package.json, go.mod, Cargo.toml, etc.) to\n * build the AnalysisContext that every analyzer receives.\n */\n\nimport { readdir, readFile, stat } from \"fs/promises\";\nimport { join, relative } from \"path\";\nimport type {\n SourceFile,\n PackageJson,\n GoMod,\n CargoToml,\n AnalysisContext,\n SupportedLanguage,\n} from \"./types.js\";\nimport { detectLanguage } from \"./language.js\";\nimport { loadGitignore } from \"../utils/gitignore.js\";\n\nconst SKIP_DIRS = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \".nuxt\",\n \"target\", \"vendor\", \"__pycache__\", \".venv\", \"venv\",\n \"coverage\", \".turbo\", \".cache\", \".idea\", \".vscode\",\n]);\n\nconst MAX_FILE_SIZE = 1024 * 1024;\nconst MAX_FILE_COUNT = 5000;\n\nexport interface DiscoveryWarnings {\n truncated: boolean;\n truncatedAt: number;\n skippedDirs: string[];\n unreadableFiles: string[];\n}\n\nexport async function discoverFiles(rootDir: string): Promise<{ files: SourceFile[]; warnings: DiscoveryWarnings }> {\n const ig = await loadGitignore(rootDir);\n const files: SourceFile[] = [];\n const warnings: DiscoveryWarnings = {\n truncated: false,\n truncatedAt: 0,\n skippedDirs: [],\n unreadableFiles: [],\n };\n\n async function walk(dir: string) {\n if (files.length >= MAX_FILE_COUNT) {\n warnings.truncated = true;\n warnings.truncatedAt = MAX_FILE_COUNT;\n return;\n }\n\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch (err: any) {\n // Permission denied, etc — skip this directory, don't crash\n warnings.skippedDirs.push(relative(rootDir, dir) || dir);\n return;\n }\n\n for (const entry of entries) {\n if (files.length >= MAX_FILE_COUNT) {\n warnings.truncated = true;\n warnings.truncatedAt = MAX_FILE_COUNT;\n break;\n }\n\n const fullPath = join(dir, entry.name);\n const relPath = relative(rootDir, fullPath);\n\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name) || entry.name.startsWith(\".\")) continue;\n if (ig.ignores(relPath + \"/\")) continue;\n await walk(fullPath);\n } else if (entry.isFile()) {\n if (ig.ignores(relPath)) continue;\n const language = detectLanguage(entry.name);\n if (!language) continue;\n\n try {\n const info = await stat(fullPath);\n if (info.size > MAX_FILE_SIZE) continue;\n\n const content = await readFile(fullPath, \"utf-8\");\n const lineCount = content.split(\"\\n\").length;\n files.push({ path: fullPath, relativePath: relPath, language, content, lineCount });\n } catch {\n // Unreadable file — permission denied, broken symlink, etc.\n warnings.unreadableFiles.push(relPath);\n }\n }\n }\n }\n\n await walk(rootDir);\n return { files, warnings };\n}\n\nexport async function loadPackageJson(rootDir: string): Promise<PackageJson | null> {\n try {\n const raw = await readFile(join(rootDir, \"package.json\"), \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\nexport async function loadGoMod(rootDir: string): Promise<GoMod | null> {\n try {\n const raw = await readFile(join(rootDir, \"go.mod\"), \"utf-8\");\n const lines = raw.split(\"\\n\");\n const result: GoMod = { module: \"\", require: [] };\n\n // State-machine parser: track whether we're inside a `require (` block\n let inRequire = false;\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"module \")) {\n result.module = trimmed.slice(7).trim();\n } else if (trimmed.startsWith(\"go \")) {\n result.goVersion = trimmed.slice(3).trim();\n } else if (trimmed === \"require (\") {\n inRequire = true;\n } else if (trimmed === \")\") {\n inRequire = false;\n } else if (inRequire && trimmed && !trimmed.startsWith(\"//\")) {\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n result.require.push({ path: parts[0], version: parts[1] });\n }\n } else if (trimmed.startsWith(\"require \") && !trimmed.includes(\"(\")) {\n const parts = trimmed.slice(8).trim().split(/\\s+/);\n if (parts.length >= 2) {\n result.require.push({ path: parts[0], version: parts[1] });\n }\n }\n }\n\n return result.module ? result : null;\n } catch {\n return null;\n }\n}\n\nexport async function loadCargoToml(rootDir: string): Promise<CargoToml | null> {\n try {\n const raw = await readFile(join(rootDir, \"Cargo.toml\"), \"utf-8\");\n const result: CargoToml = { dependencies: {} };\n\n let inDeps = false;\n let inPackage = false;\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"[package]\") { inPackage = true; inDeps = false; }\n else if (trimmed === \"[dependencies]\") { inDeps = true; inPackage = false; }\n else if (trimmed.startsWith(\"[\")) { inDeps = false; inPackage = false; }\n else if (inPackage && trimmed.startsWith(\"name\")) {\n const match = trimmed.match(/name\\s*=\\s*\"([^\"]+)\"/);\n if (match) result.name = match[1];\n } else if (inDeps && trimmed.includes(\"=\") && !trimmed.startsWith(\"#\")) {\n const eqIdx = trimmed.indexOf(\"=\");\n const depName = trimmed.slice(0, eqIdx).trim();\n const depVal = trimmed.slice(eqIdx + 1).trim().replace(/\"/g, \"\");\n result.dependencies[depName] = depVal;\n }\n }\n\n return Object.keys(result.dependencies).length > 0 || result.name ? result : null;\n } catch {\n return null;\n }\n}\n\nexport async function loadRequirementsTxt(rootDir: string): Promise<string[] | null> {\n for (const file of [\"requirements.txt\", \"requirements/base.txt\"]) {\n try {\n const raw = await readFile(join(rootDir, file), \"utf-8\");\n const deps: string[] = [];\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\") || trimmed.startsWith(\"-\")) continue;\n const name = trimmed.split(/[>=<!\\[\\s]/)[0];\n if (name) deps.push(name.toLowerCase());\n }\n return deps.length > 0 ? deps : null;\n } catch {\n continue;\n }\n }\n\n try {\n const raw = await readFile(join(rootDir, \"pyproject.toml\"), \"utf-8\");\n const deps: string[] = [];\n let inDeps = false;\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"dependencies = [\") inDeps = true;\n else if (inDeps && trimmed === \"]\") inDeps = false;\n else if (inDeps) {\n const match = trimmed.match(/^\"([^>=<!\\s\"]+)/);\n if (match) deps.push(match[1].toLowerCase());\n }\n }\n return deps.length > 0 ? deps : null;\n } catch {\n return null;\n }\n}\n\nexport async function loadEnvExample(rootDir: string): Promise<Map<string, string> | null> {\n try {\n const raw = await readFile(join(rootDir, \".env.example\"), \"utf-8\");\n const vars = new Map<string, string>();\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx > 0) {\n vars.set(trimmed.slice(0, eqIdx).trim(), trimmed.slice(eqIdx + 1).trim());\n }\n }\n return vars.size > 0 ? vars : null;\n } catch {\n return null;\n }\n}\n\nfunction computeLanguageBreakdown(\n files: SourceFile[],\n): { breakdown: Map<SupportedLanguage, { files: number; lines: number }>; dominant: SupportedLanguage | null } {\n const breakdown = new Map<SupportedLanguage, { files: number; lines: number }>();\n\n for (const file of files) {\n if (!file.language) continue;\n const existing = breakdown.get(file.language) ?? { files: 0, lines: 0 };\n existing.files++;\n existing.lines += file.lineCount;\n breakdown.set(file.language, existing);\n }\n\n let dominant: SupportedLanguage | null = null;\n let maxLines = 0;\n for (const [lang, stats] of breakdown) {\n if (stats.lines > maxLines) { maxLines = stats.lines; dominant = lang; }\n }\n\n return { breakdown, dominant };\n}\n\nexport async function buildAnalysisContext(rootDir: string): Promise<{ ctx: AnalysisContext; warnings: DiscoveryWarnings }> {\n // Load file tree and all manifest types in parallel to minimize I/O wait\n const [discovery, packageJson, goMod, cargoToml, requirementsTxt, envExample] = await Promise.all([\n discoverFiles(rootDir),\n loadPackageJson(rootDir),\n loadGoMod(rootDir),\n loadCargoToml(rootDir),\n loadRequirementsTxt(rootDir),\n loadEnvExample(rootDir),\n ]);\n\n const { files, warnings } = discovery;\n const totalLines = files.reduce((sum, f) => sum + f.lineCount, 0);\n const { breakdown, dominant } = computeLanguageBreakdown(files);\n\n const ctx: AnalysisContext = {\n rootDir,\n files,\n packageJson,\n goMod,\n cargoToml,\n requirementsTxt,\n envExample,\n totalLines,\n languageBreakdown: breakdown,\n dominantLanguage: dominant,\n };\n\n return { ctx, warnings };\n}\n","import type { SupportedLanguage } from \"./types.js\";\n\nconst EXTENSION_MAP: Record<string, SupportedLanguage> = {\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".ts\": \"typescript\",\n \".tsx\": \"typescript\",\n \".mts\": \"typescript\",\n \".cts\": \"typescript\",\n \".py\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n};\n\nexport function detectLanguage(filePath: string): SupportedLanguage | null {\n const ext = filePath.slice(filePath.lastIndexOf(\".\"));\n return EXTENSION_MAP[ext] ?? null;\n}\n\nexport function getLanguageDisplayName(lang: SupportedLanguage): string {\n const names: Record<SupportedLanguage, string> = {\n javascript: \"JS\",\n typescript: \"TS\",\n python: \"Python\",\n go: \"Go\",\n rust: \"Rust\",\n };\n return names[lang];\n}\n","import ignore, { type Ignore } from \"ignore\";\nimport { readFile } from \"fs/promises\";\nimport { join } from \"path\";\n\nexport async function loadGitignore(rootDir: string): Promise<Ignore> {\n const ig = ignore();\n\n for (const file of [\".gitignore\", \".vibedriftignore\"]) {\n try {\n const content = await readFile(join(rootDir, file), \"utf-8\");\n ig.add(content);\n } catch {\n // file doesn't exist, skip\n }\n }\n\n return ig;\n}\n","import { Parser, Language } from \"web-tree-sitter\";\nimport type { Tree } from \"web-tree-sitter\";\nimport type { SupportedLanguage, SourceFile } from \"../core/types.js\";\n\nlet initialized = false;\nconst languageCache = new Map<string, Language>();\n\nasync function ensureInit(): Promise<void> {\n if (initialized) return;\n await Parser.init();\n initialized = true;\n}\n\nasync function getLanguage(lang: SupportedLanguage): Promise<Language> {\n const grammarMap: Record<SupportedLanguage, string> = {\n javascript: \"javascript\",\n typescript: \"typescript\",\n python: \"python\",\n go: \"go\",\n rust: \"rust\",\n };\n\n const grammarName = grammarMap[lang];\n const cached = languageCache.get(grammarName);\n if (cached) return cached;\n\n const wasmModule = await import(\"tree-sitter-wasms\");\n const wasmPath =\n (wasmModule as Record<string, string>)[`tree_sitter_${grammarName}`] ??\n (wasmModule.default as Record<string, string>)?.[\n `tree_sitter_${grammarName}`\n ];\n\n if (!wasmPath) {\n throw new Error(`No WASM grammar found for language: ${lang}`);\n }\n\n const language = await Language.load(wasmPath);\n languageCache.set(grammarName, language);\n return language;\n}\n\nexport async function parseFile(file: SourceFile): Promise<Tree | null> {\n if (!file.language) return null;\n\n try {\n await ensureInit();\n const language = await getLanguage(file.language);\n const parser = new Parser();\n parser.setLanguage(language);\n const tree = parser.parse(file.content);\n return tree;\n } catch {\n return null;\n }\n}\n\nexport async function parseFiles(files: SourceFile[]): Promise<void> {\n for (const file of files) {\n if (file.language) {\n file.tree = (await parseFile(file)) ?? undefined;\n }\n }\n}\n","import type { Analyzer } from \"./base.js\";\nimport { namingAnalyzer } from \"./naming.js\";\nimport { importsAnalyzer } from \"./imports.js\";\nimport { errorHandlingAnalyzer } from \"./error-handling.js\";\nimport { dependenciesAnalyzer } from \"./dependencies.js\";\nimport { duplicatesAnalyzer } from \"./duplicates.js\";\nimport { todoDensityAnalyzer } from \"./todo-density.js\";\nimport { configDriftAnalyzer } from \"./config-drift.js\";\nimport { securityAnalyzer } from \"./security.js\";\nimport { complexityAnalyzer } from \"./complexity.js\";\nimport { intentClarityAnalyzer } from \"./intent-clarity.js\";\nimport { deadCodeAnalyzer } from \"./dead-code.js\";\nimport { languageSpecificAnalyzer } from \"./language-specific.js\";\n\nexport function createAnalyzerRegistry(): Analyzer[] {\n return [\n // Architectural Consistency\n namingAnalyzer,\n importsAnalyzer,\n errorHandlingAnalyzer,\n languageSpecificAnalyzer,\n // Redundancy\n duplicatesAnalyzer,\n todoDensityAnalyzer,\n deadCodeAnalyzer,\n // Dependency Health\n dependenciesAnalyzer,\n configDriftAnalyzer,\n // Security Posture\n securityAnalyzer,\n // Intent Clarity\n intentClarityAnalyzer,\n complexityAnalyzer,\n ];\n}\n","/**\n * Naming convention consistency analyzer.\n *\n * Detects the dominant casing convention (camelCase vs snake_case) across\n * all identifiers in the project, then flags files that deviate from it.\n * Works with AST when available, falls back to regex extraction otherwise.\n */\n\nimport type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding, SyntaxNode } from \"../core/types.js\";\n\ntype Convention = \"camelCase\" | \"snake_case\" | \"PascalCase\" | \"SCREAMING_SNAKE\";\n\nfunction detectConvention(name: string): Convention | null {\n if (/^[A-Z][A-Z0-9_]+$/.test(name)) return \"SCREAMING_SNAKE\";\n if (/^[A-Z][a-zA-Z0-9]*$/.test(name)) return \"PascalCase\";\n if (/^[a-z][a-zA-Z0-9]*$/.test(name)) return \"camelCase\";\n if (/^[a-z][a-z0-9_]*$/.test(name)) return \"snake_case\";\n return null;\n}\n\nfunction extractIdentifiers(node: SyntaxNode): string[] {\n const ids: string[] = [];\n const targetTypes = new Set([\n \"variable_declarator\", \"function_declaration\", \"method_definition\",\n \"lexical_declaration\", \"short_var_declaration\", \"function_item\",\n \"let_declaration\",\n ]);\n\n function walk(n: SyntaxNode) {\n if (targetTypes.has(n.type)) {\n const nameNode = n.childForFieldName(\"name\");\n if (nameNode) ids.push(nameNode.text);\n }\n for (let i = 0; i < n.childCount; i++) {\n walk(n.child(i)!);\n }\n }\n\n walk(node);\n return ids;\n}\n\n// Regex fallback for files without AST\nfunction extractIdentifiersRegex(content: string): string[] {\n const ids: string[] = [];\n const patterns = [\n /(?:const|let|var|function)\\s+(\\w+)/g,\n /def\\s+(\\w+)/g, // Python\n /func\\s+(\\w+)/g, // Go\n /fn\\s+(\\w+)/g, // Rust\n ];\n for (const p of patterns) {\n const regex = new RegExp(p.source, p.flags);\n let m;\n while ((m = regex.exec(content)) !== null) {\n ids.push(m[1]);\n }\n }\n return ids;\n}\n\nexport const namingAnalyzer: Analyzer = {\n id: \"naming\",\n name: \"Naming Conventions\",\n category: \"architecturalConsistency\",\n requiresAST: false, // works with regex fallback too\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const conventionCounts = new Map<Convention, string[]>();\n\n for (const file of ctx.files) {\n const ids = file.tree\n ? extractIdentifiers(file.tree.rootNode)\n : extractIdentifiersRegex(file.content);\n\n for (const id of ids) {\n if (id.length <= 1 || id.startsWith(\"_\")) continue;\n const conv = detectConvention(id);\n // Exclude SCREAMING_SNAKE (constants) and PascalCase (types/classes)\n // since those are cross-convention by design\n if (!conv || conv === \"SCREAMING_SNAKE\" || conv === \"PascalCase\") continue;\n if (!conventionCounts.has(conv)) conventionCounts.set(conv, []);\n conventionCounts.get(conv)!.push(file.relativePath);\n }\n }\n\n // Sort by frequency so the most-used convention is at index 0 (\"dominant\")\n const conventions = [...conventionCounts.entries()].sort(\n (a, b) => b[1].length - a[1].length,\n );\n\n // Only flag inconsistency when at least two conventions coexist\n if (conventions.length >= 2) {\n const dominant = conventions[0];\n for (const [conv, files] of conventions.slice(1)) {\n const uniqueFiles = [...new Set(files)];\n if (uniqueFiles.length >= 2) {\n findings.push({\n analyzerId: \"naming\",\n severity: \"warning\",\n confidence: 0.8,\n message: `${uniqueFiles.length} files use ${conv} while majority uses ${dominant[0]}`,\n locations: uniqueFiles.slice(0, 10).map((f) => ({ file: f })),\n tags: [\"naming\", \"inconsistency\"],\n });\n }\n }\n }\n\n return findings;\n },\n};\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\n\nconst ESM_PATTERN = /\\b(?:import\\s+|export\\s+(?:default\\s+)?(?:function|class|const|let|var|{))/;\nconst CJS_PATTERN = /\\b(?:require\\s*\\(|module\\.exports|exports\\.)/;\nconst CONFIG_FILE_PATTERN = /(?:\\.config\\.|\\.setup\\.|\\.rc\\.|jest\\.|babel\\.|webpack\\.|rollup\\.|vite\\.|next\\.config|tailwind\\.config|postcss\\.config|tsconfig|eslint\\.config|prettier\\.config|svelte\\.config|nuxt\\.config|astro\\.config|vitest\\.config|tsup\\.config|esbuild\\.config|turbo\\.json|\\.cjs$|\\.mjs$)/;\n\nexport const importsAnalyzer: Analyzer = {\n id: \"imports\",\n name: \"Import Patterns\",\n category: \"architecturalConsistency\",\n requiresAST: false,\n applicableLanguages: [\"javascript\", \"typescript\"],\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const jsFiles = ctx.files.filter(\n (f) => f.language === \"javascript\" || f.language === \"typescript\",\n );\n\n const esmFiles: string[] = [];\n const cjsFiles: string[] = [];\n\n // Skip test fixtures (intentionally mixed) and analyzer files\n // (which have CJS patterns as detection targets inside regex strings)\n const SKIP_PATH = /(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\\\]/i;\n\n for (const file of jsFiles) {\n if (CONFIG_FILE_PATTERN.test(file.relativePath)) continue;\n if (SKIP_PATH.test(file.relativePath)) continue;\n\n // Strip regex literals and string contents before checking for CJS\n // patterns. This prevents analyzer files that have /require\\s*\\(/\n // inside their pattern definitions from being flagged as CJS.\n const stripped = file.content\n .replace(/\\/[^/\\n]+\\/[gimsuvy]*/g, '\"\"') // regex literals → empty string\n .replace(/`[^`]*`/g, '\"\"'); // template literals → empty\n const hasESM = ESM_PATTERN.test(file.content);\n const hasCJS = CJS_PATTERN.test(stripped);\n\n if (hasESM && hasCJS) {\n findings.push({\n analyzerId: \"imports\",\n severity: \"warning\",\n confidence: 0.9,\n message: `Mixed ESM and CommonJS in ${file.relativePath}`,\n locations: [{ file: file.relativePath }],\n tags: [\"imports\", \"mixed\"],\n });\n }\n\n if (hasESM) esmFiles.push(file.relativePath);\n if (hasCJS) cjsFiles.push(file.relativePath);\n }\n\n if (esmFiles.length > 0 && cjsFiles.length > 0) {\n const minorityFiles = esmFiles.length >= cjsFiles.length ? cjsFiles : esmFiles;\n findings.push({\n analyzerId: \"imports\",\n severity: \"warning\",\n confidence: 0.85,\n message: `Mixed ESM/CommonJS across project: ${esmFiles.length} ESM files, ${cjsFiles.length} CJS files`,\n locations: minorityFiles.slice(0, 10).map((f) => ({ file: f })),\n tags: [\"imports\", \"project-inconsistency\"],\n });\n }\n\n return findings;\n },\n};\n","/**\n * Error handling quality analyzer for JavaScript/TypeScript.\n *\n * Detects two anti-patterns: (1) empty catch blocks that silently swallow\n * errors, and (2) async functions using `await` without any try/catch or\n * .catch() — a common source of unhandled promise rejections.\n */\n\nimport type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\nconst EMPTY_CATCH_PATTERN = /catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}/g;\nconst TRY_CATCH_PATTERN = /\\btry\\s*\\{/g;\nconst ASYNC_PATTERN = /\\basync\\s+(?:function|\\(|[a-zA-Z])/g;\n\nexport const errorHandlingAnalyzer: Analyzer = {\n id: \"error-handling\",\n name: \"Error Handling\",\n category: \"architecturalConsistency\",\n requiresAST: false,\n applicableLanguages: [\"javascript\", \"typescript\"],\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const jsFiles = ctx.files.filter(\n (f) => f.language === \"javascript\" || f.language === \"typescript\",\n );\n\n let totalEmptyCatches = 0;\n const emptyCatchLocations: { file: string; line: number; snippet?: string }[] = [];\n\n for (const file of jsFiles) {\n const emptyRegex = new RegExp(EMPTY_CATCH_PATTERN.source, \"g\");\n let match;\n while ((match = emptyRegex.exec(file.content)) !== null) {\n totalEmptyCatches++;\n const line = getLineNumber(file.content, match.index);\n emptyCatchLocations.push({\n file: file.relativePath,\n line,\n snippet: match[0],\n });\n }\n }\n\n if (totalEmptyCatches > 0) {\n findings.push({\n analyzerId: \"error-handling\",\n severity: totalEmptyCatches > 5 ? \"error\" : \"warning\",\n confidence: 0.95,\n message: `${totalEmptyCatches} empty catch blocks found`,\n locations: emptyCatchLocations.slice(0, 10),\n tags: [\"error-handling\", \"empty-catch\"],\n });\n }\n\n const ASYNC_FN_PATTERN =\n /async\\s+(?:function\\s+\\w+|\\(\\w*\\)|\\w+)\\s*\\([^)]*\\)\\s*(?::\\s*[^{]*)?\\s*\\{/g;\n const ERROR_HANDLING_PATTERNS = [\n /\\btry\\s*\\{/,\n /\\.catch\\s*\\(/,\n /\\bcatch\\s*\\(/,\n /\\b(?:Result|Either)\\s*[<(]/,\n ];\n\n // Aggregate unhandled async counts per directory to avoid flooding\n // the report with one finding per function\n const dirUnhandled = new Map<string, number>();\n\n for (const file of jsFiles) {\n const dir = file.relativePath.includes(\"/\")\n ? file.relativePath.slice(0, file.relativePath.lastIndexOf(\"/\"))\n : \".\";\n\n const asyncRegex = new RegExp(ASYNC_FN_PATTERN.source, \"g\");\n let fnMatch;\n while ((fnMatch = asyncRegex.exec(file.content)) !== null) {\n // Extract the function body via brace-depth counting so we can\n // check if error handling exists within this specific function scope\n const openBrace = file.content.indexOf(\"{\", fnMatch.index + fnMatch[0].length - 1);\n if (openBrace === -1) continue;\n let depth = 1;\n let pos = openBrace + 1;\n while (pos < file.content.length && depth > 0) {\n if (file.content[pos] === \"{\") depth++;\n else if (file.content[pos] === \"}\") depth--;\n pos++;\n }\n const body = file.content.slice(openBrace + 1, pos - 1);\n\n // Only flag if the body uses await but has no error handling\n if (!/\\bawait\\b/.test(body)) continue;\n const hasHandling = ERROR_HANDLING_PATTERNS.some((p) => p.test(body));\n if (!hasHandling) {\n dirUnhandled.set(dir, (dirUnhandled.get(dir) ?? 0) + 1);\n }\n }\n }\n\n for (const [dir, count] of dirUnhandled) {\n if (count > 3) {\n findings.push({\n analyzerId: \"error-handling\",\n severity: \"info\",\n confidence: 0.6,\n message: `${count} async functions without error handling in ${dir}/`,\n locations: [{ file: dir }],\n tags: [\"error-handling\", \"unhandled-async\"],\n });\n }\n }\n\n return findings;\n },\n};\n","export function getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split(\"\\n\").length;\n}\n\nexport function densityPer1K(count: number, totalLines: number): number {\n if (totalLines === 0) return 0;\n return Math.round((count / totalLines) * 1000 * 10) / 10;\n}\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\n\nconst NODE_BUILTINS = new Set([\n \"assert\", \"buffer\", \"child_process\", \"cluster\", \"console\", \"constants\",\n \"crypto\", \"dgram\", \"dns\", \"domain\", \"events\", \"fs\", \"http\", \"http2\",\n \"https\", \"module\", \"net\", \"os\", \"path\", \"perf_hooks\", \"process\",\n \"punycode\", \"querystring\", \"readline\", \"repl\", \"stream\", \"string_decoder\",\n \"sys\", \"timers\", \"tls\", \"tty\", \"url\", \"util\", \"v8\", \"vm\", \"wasi\",\n \"worker_threads\", \"zlib\",\n]);\n\nconst JS_IMPORT_PATTERNS = [\n /(?:import|from)\\s+['\"]([^./][^'\"]*)['\"]/g,\n /require\\(\\s*['\"]([^./][^'\"]*)['\"]\\s*\\)/g,\n // Dynamic imports: await import(\"pkg\") or import(\"pkg\")\n /import\\(\\s*['\"]([^./][^'\"]*)['\"]\\s*\\)/g,\n];\n\n// Test fixture directories — their imports are intentionally broken/nonexistent\nconst FIXTURE_PATH_PATTERN = /(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\\\]/i;\n\n// We extract Go imports by finding import blocks, not raw string matching\nfunction extractGoImports(content: string): string[] {\n const imports: string[] = [];\n\n // Single import: import \"path\"\n const singlePattern = /^import\\s+\"([^\"]+)\"/gm;\n let m;\n while ((m = singlePattern.exec(content)) !== null) {\n imports.push(m[1]);\n }\n\n // Block import: import ( ... )\n const blockPattern = /^import\\s*\\(([\\s\\S]*?)\\)/gm;\n while ((m = blockPattern.exec(content)) !== null) {\n const block = m[1];\n const linePattern = /^\\s*(?:\\w+\\s+)?\"([^\"]+)\"/gm;\n let lineMatch;\n while ((lineMatch = linePattern.exec(block)) !== null) {\n imports.push(lineMatch[1]);\n }\n }\n\n return imports;\n}\nconst PYTHON_IMPORT_PATTERN = /^(?:import|from)\\s+(\\w+)/gm;\nconst RUST_USE_PATTERN = /^use\\s+(\\w+)/gm;\n\nfunction extractJsPackageName(specifier: string): string {\n if (specifier.startsWith(\"@\")) {\n const parts = specifier.split(\"/\");\n return parts.slice(0, 2).join(\"/\");\n }\n return specifier.split(\"/\")[0];\n}\n\nconst DEV_TOOL_PATTERNS = [\n \"@types/\", \"eslint\", \"prettier\", \"tsup\", \"vitest\", \"typescript\",\n \"jest\", \"mocha\", \"webpack\", \"rollup\", \"vite\", \"babel\", \"postcss\",\n \"tailwindcss\", \"autoprefixer\", \"lint-staged\", \"husky\",\n];\n\nexport const dependenciesAnalyzer: Analyzer = {\n id: \"dependencies\",\n name: \"Dependency Health\",\n category: \"dependencyHealth\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n // JS/TS dependency analysis\n if (ctx.packageJson) {\n findings.push(...analyzeJsDeps(ctx));\n }\n\n // Go dependency analysis\n if (ctx.goMod) {\n findings.push(...analyzeGoDeps(ctx));\n }\n\n // Python dependency analysis\n if (ctx.requirementsTxt) {\n findings.push(...analyzePythonDeps(ctx));\n }\n\n // Rust dependency analysis\n if (ctx.cargoToml) {\n findings.push(...analyzeRustDeps(ctx));\n }\n\n return findings;\n },\n};\n\nfunction collectImportedPackages(\n files: { content: string; relativePath: string }[],\n): { imported: Set<string>; importLocations: Map<string, { file: string; line: number }[]> } {\n const imported = new Set<string>();\n const importLocations = new Map<string, { file: string; line: number }[]>();\n\n for (const file of files) {\n for (const pattern of JS_IMPORT_PATTERNS) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const pkg = extractJsPackageName(match[1]);\n if (NODE_BUILTINS.has(pkg) || pkg.startsWith(\"node:\") || pkg.startsWith(\"@/\") || pkg.startsWith(\"~\")) continue;\n imported.add(pkg);\n if (!importLocations.has(pkg)) importLocations.set(pkg, []);\n importLocations.get(pkg)!.push({\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n });\n }\n }\n }\n\n return { imported, importLocations };\n}\n\nfunction detectPhantomDeps(declared: Set<string>, imported: Set<string>, devToolPatterns: string[]): Finding[] {\n const phantom = [...declared].filter((d) => !imported.has(d));\n const realPhantom = phantom.filter(\n (p) => !devToolPatterns.some((pat) => p.includes(pat)),\n );\n\n if (realPhantom.length > 0) {\n return [{\n analyzerId: \"dependencies\",\n severity: realPhantom.length > 5 ? \"error\" : \"warning\",\n confidence: 0.75,\n message: `${realPhantom.length} phantom dependencies (declared but unused): ${realPhantom.slice(0, 5).join(\", \")}${realPhantom.length > 5 ? \"...\" : \"\"}`,\n locations: realPhantom.map((p) => ({ file: \"package.json\" })),\n tags: [\"deps\", \"phantom\", \"js\"],\n }];\n }\n\n return [];\n}\n\n// Filter out common bundler aliases, virtual modules, and workspace-internal packages\nconst ALIAS_PATTERNS = [\n /^#/, /^virtual:/, /^vite\\//, /^next\\//,\n /^\\$/, /^server-only$/, /^client-only$/,\n];\n\nfunction detectMissingDeps(\n declared: Set<string>,\n imported: Set<string>,\n isMonorepo: boolean,\n importLocations: Map<string, { file: string; line: number }[]>,\n): Finding[] {\n const missing = [...imported].filter((i) => {\n if (declared.has(i)) return false;\n if (ALIAS_PATTERNS.some((p) => p.test(i))) return false;\n return true;\n });\n\n // In monorepos/workspaces, missing deps are likely workspace packages — lower severity\n const missingConfidence = isMonorepo ? 0.4 : 0.75;\n const missingSeverity = isMonorepo ? \"warning\" as const : \"error\" as const;\n\n if (missing.length > 0) {\n return [{\n analyzerId: \"dependencies\",\n severity: missingSeverity,\n confidence: missingConfidence,\n message: `${missing.length} packages imported but not in package.json: ${missing.slice(0, 5).join(\", \")}${missing.length > 5 ? \"...\" : \"\"}${isMonorepo ? \" (may be workspace packages)\" : \"\"}`,\n locations: missing.slice(0, 5).flatMap((p) => importLocations.get(p) ?? []),\n tags: [\"deps\", \"missing\", \"js\"],\n }];\n }\n\n return [];\n}\n\nfunction analyzeJsDeps(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const pkg = ctx.packageJson!;\n\n // Include optionalDependencies and detect workspace packages\n const declared = new Set<string>([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ...Object.keys(pkg.peerDependencies ?? {}),\n ...Object.keys((pkg as any).optionalDependencies ?? {}),\n ]);\n\n // Detect monorepo workspace packages (workspace:* protocol, or packages\n // whose versions are \"workspace:*\", \"workspace:^\", \"workspace:~\", \"*\")\n const isMonorepo = [...Object.values(pkg.dependencies ?? {}),\n ...Object.values(pkg.devDependencies ?? {})].some(\n (v) => typeof v === \"string\" && (v.startsWith(\"workspace:\") || v === \"*\"),\n );\n // Also check for workspaces field\n const hasWorkspaces = !!(pkg as any).workspaces;\n\n const jsFiles = ctx.files.filter(\n (f) =>\n (f.language === \"javascript\" || f.language === \"typescript\") &&\n !FIXTURE_PATH_PATTERN.test(f.relativePath),\n );\n\n const { imported, importLocations } = collectImportedPackages(jsFiles);\n\n findings.push(...detectPhantomDeps(declared, imported, DEV_TOOL_PATTERNS));\n findings.push(...detectMissingDeps(declared, imported, isMonorepo || hasWorkspaces, importLocations));\n\n return findings;\n}\n\nfunction analyzeGoDeps(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const goMod = ctx.goMod!;\n const declaredPaths = new Set(goMod.require.map((r) => r.path));\n\n const importedPaths = new Set<string>();\n const goFiles = ctx.files.filter((f) => f.language === \"go\");\n\n for (const file of goFiles) {\n const goImports = extractGoImports(file.content);\n for (const importPath of goImports) {\n // Skip stdlib (no dots in first segment)\n if (!importPath.includes(\".\")) continue;\n // Skip URLs\n if (importPath.startsWith(\"http://\") || importPath.startsWith(\"https://\")) continue;\n // Skip internal module imports\n if (importPath.startsWith(goMod.module)) continue;\n // Extract module path (first 3 segments for github.com/x/y style)\n const segments = importPath.split(\"/\");\n const modPath = segments.length >= 3 ? segments.slice(0, 3).join(\"/\") : importPath;\n importedPaths.add(modPath);\n }\n }\n\n const phantom = [...declaredPaths].filter((d) => !importedPaths.has(d));\n if (phantom.length > 0) {\n findings.push({\n analyzerId: \"dependencies\",\n severity: \"warning\",\n confidence: 0.7,\n message: `${phantom.length} potentially unused Go modules: ${phantom.slice(0, 3).join(\", \")}${phantom.length > 3 ? \"...\" : \"\"}`,\n locations: [{ file: \"go.mod\" }],\n tags: [\"deps\", \"phantom\", \"go\"],\n });\n }\n\n const missing = [...importedPaths].filter((i) => !declaredPaths.has(i));\n if (missing.length > 0) {\n findings.push({\n analyzerId: \"dependencies\",\n severity: \"error\",\n confidence: 0.8,\n message: `${missing.length} Go imports not in go.mod: ${missing.slice(0, 3).join(\", \")}${missing.length > 3 ? \"...\" : \"\"}`,\n locations: [{ file: \"go.mod\" }],\n tags: [\"deps\", \"missing\", \"go\"],\n });\n }\n\n return findings;\n}\n\nfunction analyzePythonDeps(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const declared = new Set(ctx.requirementsTxt!);\n\n const imported = new Set<string>();\n const pyFiles = ctx.files.filter((f) => f.language === \"python\");\n\n const PYTHON_STDLIB = new Set([\n \"os\", \"sys\", \"re\", \"json\", \"math\", \"datetime\", \"collections\", \"itertools\",\n \"functools\", \"pathlib\", \"typing\", \"abc\", \"io\", \"time\", \"logging\", \"copy\",\n \"hashlib\", \"base64\", \"subprocess\", \"threading\", \"multiprocessing\", \"socket\",\n \"http\", \"urllib\", \"email\", \"html\", \"xml\", \"csv\", \"sqlite3\", \"unittest\",\n \"argparse\", \"configparser\", \"dataclasses\", \"enum\", \"contextlib\", \"inspect\",\n \"asyncio\", \"concurrent\", \"signal\", \"shutil\", \"glob\", \"tempfile\", \"pickle\",\n \"struct\", \"textwrap\", \"string\", \"operator\", \"warnings\",\n ]);\n\n for (const file of pyFiles) {\n const regex = new RegExp(PYTHON_IMPORT_PATTERN.source, PYTHON_IMPORT_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const mod = match[1].toLowerCase();\n if (PYTHON_STDLIB.has(mod)) continue;\n imported.add(mod);\n }\n }\n\n const phantom = [...declared].filter((d) => !imported.has(d));\n if (phantom.length > 2) {\n findings.push({\n analyzerId: \"dependencies\",\n severity: \"warning\",\n confidence: 0.65,\n message: `${phantom.length} potentially unused Python packages: ${phantom.slice(0, 5).join(\", \")}`,\n locations: [{ file: \"requirements.txt\" }],\n tags: [\"deps\", \"phantom\", \"python\"],\n });\n }\n\n return findings;\n}\n\nfunction analyzeRustDeps(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const declared = new Set(Object.keys(ctx.cargoToml!.dependencies));\n\n const imported = new Set<string>();\n const rsFiles = ctx.files.filter((f) => f.language === \"rust\");\n\n for (const file of rsFiles) {\n const regex = new RegExp(RUST_USE_PATTERN.source, RUST_USE_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const crateName = match[1];\n if ([\"std\", \"core\", \"alloc\", \"self\", \"super\", \"crate\"].includes(crateName)) continue;\n imported.add(crateName);\n }\n }\n\n const phantom = [...declared].filter(\n (d) => !imported.has(d) && !imported.has(d.replace(/-/g, \"_\")),\n );\n if (phantom.length > 0) {\n findings.push({\n analyzerId: \"dependencies\",\n severity: \"warning\",\n confidence: 0.7,\n message: `${phantom.length} potentially unused Rust crates: ${phantom.slice(0, 5).join(\", \")}`,\n locations: [{ file: \"Cargo.toml\" }],\n tags: [\"deps\", \"phantom\", \"rust\"],\n });\n }\n\n return findings;\n}\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\n\ninterface TokenSequence {\n file: string;\n line: number;\n funcName: string;\n tokens: string[];\n hash: number;\n}\n\n// Tokenize source: strip comments, whitespace, normalize identifiers\nfunction tokenize(source: string): string[] {\n // Remove single-line comments\n let cleaned = source.replace(/\\/\\/.*$/gm, \"\");\n cleaned = cleaned.replace(/#.*$/gm, \"\");\n // Remove multi-line comments\n cleaned = cleaned.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n // Remove string literals (replace with placeholder)\n cleaned = cleaned.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"STR\"');\n cleaned = cleaned.replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"'STR'\");\n cleaned = cleaned.replace(/`(?:[^`\\\\]|\\\\.)*`/g, \"`STR`\");\n\n // Split into tokens\n const tokens = cleaned.match(/[a-zA-Z_]\\w*|[0-9]+(?:\\.[0-9]+)?|[{}()\\[\\];,.:=<>!+\\-*/%&|^~?@#]/g);\n return tokens ?? [];\n}\n\n// Simple hash for fast comparison (FNV-1a inspired)\nfunction hashTokens(tokens: string[]): number {\n let hash = 2166136261;\n for (const t of tokens) {\n for (let i = 0; i < t.length; i++) {\n hash ^= t.charCodeAt(i);\n hash = (hash * 16777619) | 0;\n }\n hash ^= 31; // separator\n }\n return hash;\n}\n\n// Normalize tokens: replace specific identifiers with placeholders\nfunction normalizeTokens(tokens: string[]): string[] {\n const identifierMap = new Map<string, string>();\n let counter = 0;\n\n return tokens.map((t) => {\n // Keep keywords and operators\n if (isKeywordOrOperator(t)) return t;\n // Keep number literals\n if (/^[0-9]/.test(t)) return \"NUM\";\n // Keep string placeholders\n if (t === \"STR\") return \"STR\";\n\n // Normalize identifiers\n if (!identifierMap.has(t)) {\n identifierMap.set(t, `ID${counter++}`);\n }\n return identifierMap.get(t)!;\n });\n}\n\nconst KEYWORDS = new Set([\n \"function\", \"const\", \"let\", \"var\", \"if\", \"else\", \"for\", \"while\", \"do\",\n \"switch\", \"case\", \"break\", \"continue\", \"return\", \"throw\", \"try\", \"catch\",\n \"finally\", \"new\", \"delete\", \"typeof\", \"instanceof\", \"void\", \"in\", \"of\",\n \"class\", \"extends\", \"super\", \"import\", \"export\", \"default\", \"from\",\n \"async\", \"await\", \"yield\", \"static\", \"public\", \"private\", \"protected\",\n \"true\", \"false\", \"null\", \"undefined\", \"this\",\n // Go\n \"func\", \"type\", \"struct\", \"interface\", \"map\", \"chan\", \"go\", \"select\",\n \"defer\", \"range\", \"package\",\n // Python\n \"def\", \"class\", \"elif\", \"except\", \"lambda\", \"with\", \"as\", \"pass\",\n \"raise\", \"global\", \"nonlocal\", \"assert\", \"and\", \"or\", \"not\", \"is\",\n \"None\", \"True\", \"False\",\n // Rust\n \"fn\", \"let\", \"mut\", \"impl\", \"trait\", \"enum\", \"match\", \"pub\", \"mod\",\n \"use\", \"crate\", \"self\", \"where\", \"unsafe\", \"move\", \"ref\",\n]);\n\nfunction isKeywordOrOperator(t: string): boolean {\n if (KEYWORDS.has(t)) return true;\n return /^[{}()\\[\\];,.:=<>!+\\-*/%&|^~?@#]$/.test(t);\n}\n\n// Extract function bodies as token sequences\nfunction extractFunctionTokens(content: string, file: string): TokenSequence[] {\n const sequences: TokenSequence[] = [];\n const funcPatterns = [\n /(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\([^)]*\\)\\s*\\{/g,\n /(?:export\\s+)?const\\s+(\\w+)\\s*=\\s*(?:async\\s+)?\\([^)]*\\)\\s*=>\\s*\\{/g,\n /def\\s+(\\w+)\\s*\\([^)]*\\)\\s*:/g,\n /func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)\\s*\\([^)]*\\)\\s*(?:\\([^)]*\\)\\s*)?\\{/g,\n /(?:pub\\s+)?(?:async\\s+)?fn\\s+(\\w+)\\s*(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*(?:->[^{]*)?\\{/g,\n ];\n\n for (const pattern of funcPatterns) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(content)) !== null) {\n const funcName = match[1];\n const startIndex = match.index;\n const line = content.slice(0, startIndex).split(\"\\n\").length;\n\n // Find function body (brace matching or indent-based for Python)\n const body = extractBody(content, startIndex + match[0].length - 1);\n if (body.length < 20) continue; // too short to be meaningful\n\n const tokens = tokenize(body);\n if (tokens.length < 15) continue; // minimum token threshold\n\n const normalized = normalizeTokens(tokens);\n sequences.push({\n file,\n line,\n funcName,\n tokens: normalized,\n hash: hashTokens(normalized),\n });\n }\n }\n\n return sequences;\n}\n\nfunction extractBody(content: string, openBraceIndex: number): string {\n const ch = content[openBraceIndex];\n\n if (ch === \"{\") {\n // Brace-delimited\n let depth = 1;\n let i = openBraceIndex + 1;\n while (i < content.length && depth > 0) {\n if (content[i] === \"{\") depth++;\n else if (content[i] === \"}\") depth--;\n i++;\n }\n return content.slice(openBraceIndex, i);\n }\n\n if (ch === \":\") {\n // Python: indent-based, take until dedent\n const lines = content.slice(openBraceIndex + 1).split(\"\\n\");\n const bodyLines: string[] = [];\n let baseIndent = -1;\n\n for (const line of lines) {\n if (line.trim() === \"\") {\n bodyLines.push(line);\n continue;\n }\n const indent = line.search(/\\S/);\n if (baseIndent === -1) {\n baseIndent = indent;\n }\n if (indent >= baseIndent) {\n bodyLines.push(line);\n } else {\n break;\n }\n }\n return bodyLines.join(\"\\n\");\n }\n\n return \"\";\n}\n\n// Compare two token sequences for similarity using LCS ratio\nfunction tokenSimilarity(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n\n // Use rolling window comparison for efficiency on larger functions\n const minLen = Math.min(a.length, b.length);\n const maxLen = Math.max(a.length, b.length);\n\n // Quick reject: length ratio too different\n if (minLen / maxLen < 0.5) return 0;\n\n // LCS-based similarity (O(n*m) but bounded by function size)\n if (minLen > 500) {\n // For very long functions, use sampled comparison\n return sampledSimilarity(a, b);\n }\n\n const dp: number[][] = Array.from({ length: a.length + 1 }, () =>\n new Array(b.length + 1).fill(0),\n );\n\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n if (a[i - 1] === b[j - 1]) {\n dp[i][j] = dp[i - 1][j - 1] + 1;\n } else {\n dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);\n }\n }\n }\n\n const lcsLength = dp[a.length][b.length];\n return (2 * lcsLength) / (a.length + b.length);\n}\n\nfunction sampledSimilarity(a: string[], b: string[]): number {\n // Sample every Nth token and compare\n const sampleRate = Math.max(1, Math.floor(Math.min(a.length, b.length) / 100));\n const sampledA = a.filter((_, i) => i % sampleRate === 0);\n const sampledB = b.filter((_, i) => i % sampleRate === 0);\n\n let matches = 0;\n const bSet = new Set(sampledB);\n for (const t of sampledA) {\n if (bSet.has(t)) matches++;\n }\n\n return (2 * matches) / (sampledA.length + sampledB.length);\n}\n\nexport const duplicatesAnalyzer: Analyzer = {\n id: \"duplicates\",\n name: \"Code Duplication\",\n category: \"redundancy\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const allSequences: TokenSequence[] = [];\n\n for (const file of ctx.files) {\n if (!file.language) continue;\n const sequences = extractFunctionTokens(file.content, file.relativePath);\n allSequences.push(...sequences);\n }\n\n // Group by hash for fast comparison\n const hashGroups = new Map<number, TokenSequence[]>();\n for (const seq of allSequences) {\n if (!hashGroups.has(seq.hash)) hashGroups.set(seq.hash, []);\n hashGroups.get(seq.hash)!.push(seq);\n }\n\n // Check exact hash matches first\n const duplicatePairs: { a: TokenSequence; b: TokenSequence; similarity: number }[] = [];\n\n for (const [, group] of hashGroups) {\n if (group.length > 1) {\n for (let i = 0; i < group.length; i++) {\n for (let j = i + 1; j < group.length; j++) {\n if (group[i].file === group[j].file) continue;\n const sim = tokenSimilarity(group[i].tokens, group[j].tokens);\n if (sim >= 0.8) {\n duplicatePairs.push({ a: group[i], b: group[j], similarity: sim });\n }\n }\n }\n }\n }\n\n // Also compare across different hashes (slower, do pairwise for small sets)\n if (allSequences.length > 200) {\n findings.push({\n analyzerId: \"duplicates\",\n severity: \"info\",\n confidence: 0.3,\n message: `Cross-function duplicate detection limited to hash-based matching (${allSequences.length} functions exceeds the 200-function threshold for full comparison). Use --include to narrow scope for deeper analysis.`,\n locations: [],\n tags: [\"duplicates\", \"scalability\"],\n });\n }\n if (allSequences.length <= 200) {\n for (let i = 0; i < allSequences.length; i++) {\n for (let j = i + 1; j < allSequences.length; j++) {\n if (allSequences[i].file === allSequences[j].file) continue;\n if (allSequences[i].hash === allSequences[j].hash) continue; // already checked\n\n // Quick length filter\n const lenRatio = Math.min(allSequences[i].tokens.length, allSequences[j].tokens.length) /\n Math.max(allSequences[i].tokens.length, allSequences[j].tokens.length);\n if (lenRatio < 0.6) continue;\n\n const sim = tokenSimilarity(allSequences[i].tokens, allSequences[j].tokens);\n if (sim >= 0.7) {\n duplicatePairs.push({\n a: allSequences[i],\n b: allSequences[j],\n similarity: sim,\n });\n }\n }\n }\n }\n\n // Deduplicate pairs\n const seenPairs = new Set<string>();\n const uniquePairs = duplicatePairs.filter((p) => {\n const key = [p.a.file + \":\" + p.a.funcName, p.b.file + \":\" + p.b.funcName].sort().join(\"|\");\n if (seenPairs.has(key)) return false;\n seenPairs.add(key);\n return true;\n });\n\n if (uniquePairs.length > 0) {\n // Sort by similarity descending\n uniquePairs.sort((a, b) => b.similarity - a.similarity);\n\n findings.push({\n analyzerId: \"duplicates\",\n severity: uniquePairs.length > 5 ? \"error\" : \"warning\",\n confidence: 0.75,\n message: `${uniquePairs.length} pairs of duplicate/near-duplicate functions detected`,\n locations: uniquePairs.slice(0, 10).flatMap((p) => {\n const sim = Math.round(p.similarity * 100);\n // When names are identical, include file paths to disambiguate\n const aLabel = p.a.funcName === p.b.funcName\n ? `${p.a.file}:${p.a.funcName}()`\n : `${p.a.funcName}()`;\n const bLabel = p.b.funcName === p.a.funcName\n ? `${p.b.file}:${p.b.funcName}()`\n : `${p.b.funcName}()`;\n return [\n { file: p.a.file, line: p.a.line, snippet: `${aLabel} — ${sim}% similar to ${bLabel}` },\n { file: p.b.file, line: p.b.line, snippet: `${bLabel} — ${sim}% similar to ${aLabel}` },\n ];\n }),\n tags: [\"duplicates\", \"token-based\"],\n });\n }\n\n return findings;\n },\n};\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { densityPer1K, getLineNumber } from \"../utils/text.js\";\n\nconst TODO_PATTERN = /\\b(TODO|FIXME|HACK|XXX|TEMP)\\b/gi;\n\nexport const todoDensityAnalyzer: Analyzer = {\n id: \"todo-density\",\n name: \"TODO/FIXME Density\",\n category: \"redundancy\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n let totalCount = 0;\n const fileHits: { file: string; count: number; lines: number[] }[] = [];\n\n for (const file of ctx.files) {\n const matches = [...file.content.matchAll(TODO_PATTERN)];\n if (matches.length === 0) continue;\n totalCount += matches.length;\n const lines = matches.map((m) => getLineNumber(file.content, m.index!));\n fileHits.push({ file: file.relativePath, count: matches.length, lines });\n }\n\n if (totalCount === 0) return findings;\n\n const density = densityPer1K(totalCount, ctx.totalLines);\n\n if (density > 2) {\n findings.push({\n analyzerId: \"todo-density\",\n severity: density > 5 ? \"error\" : \"warning\",\n confidence: 1.0,\n message: `${totalCount} TODOs/FIXMEs across ${fileHits.length} files (density: ${density}/1K lines)`,\n locations: fileHits.map((h) => ({ file: h.file, line: h.lines[0] })),\n tags: [\"todo\", \"debt\"],\n });\n }\n\n for (const hit of fileHits) {\n if (hit.count >= 3) {\n findings.push({\n analyzerId: \"todo-density\",\n severity: \"info\",\n confidence: 1.0,\n message: `${hit.count} TODOs clustered in ${hit.file}`,\n locations: hit.lines.map((l) => ({ file: hit.file, line: l })),\n tags: [\"todo\", \"cluster\"],\n });\n }\n }\n\n return findings;\n },\n};\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\nconst ENV_PATTERNS = [\n /process\\.env\\.(\\w+)/g,\n /import\\.meta\\.env\\.(\\w+)/g,\n /os\\.environ(?:\\.get)?\\(\\s*['\"](\\w+)['\"]/g,\n /os\\.Getenv\\(\\s*\"(\\w+)\"\\s*\\)/g, // Go\n /env::var\\(\\s*\"(\\w+)\"\\s*\\)/g, // Rust\n];\n\nexport const configDriftAnalyzer: Analyzer = {\n id: \"config-drift\",\n name: \"Config Drift\",\n category: \"dependencyHealth\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const envUsages = new Map<string, { file: string; line: number }[]>();\n\n for (const file of ctx.files) {\n for (const pattern of ENV_PATTERNS) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const varName = match[1];\n if (!envUsages.has(varName)) envUsages.set(varName, []);\n envUsages.get(varName)!.push({\n file: file.relativePath,\n line: getLineNumber(file.content, match.index),\n });\n }\n }\n }\n\n if (envUsages.size === 0) return findings;\n\n if (ctx.envExample) {\n const undocumented: string[] = [];\n for (const [varName, locations] of envUsages) {\n if (!ctx.envExample.has(varName) && !varName.startsWith(\"NODE_\") && varName !== \"NODE_ENV\") {\n undocumented.push(varName);\n findings.push({\n analyzerId: \"config-drift\",\n severity: \"warning\",\n confidence: 0.85,\n message: `Env var ${varName} used in code but missing from .env.example`,\n locations,\n tags: [\"config\", \"env\"],\n });\n }\n }\n if (undocumented.length > 0) {\n findings.push({\n analyzerId: \"config-drift\",\n severity: \"warning\",\n confidence: 0.85,\n message: `${undocumented.length} env vars used in code but missing from .env.example`,\n locations: [],\n tags: [\"config\", \"summary\"],\n });\n }\n } else if (envUsages.size > 3) {\n findings.push({\n analyzerId: \"config-drift\",\n severity: \"info\",\n confidence: 0.7,\n message: `${envUsages.size} env vars used but no .env.example file found`,\n locations: [],\n tags: [\"config\", \"missing-example\"],\n });\n }\n\n return findings;\n },\n};\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding, FileLocation, SupportedLanguage } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\ninterface SecurityPattern {\n id: string;\n name: string;\n pattern: RegExp;\n severity: \"info\" | \"warning\" | \"error\";\n confidence: number;\n message: string;\n languages: SupportedLanguage[] | \"all\";\n tags: string[];\n // If provided, a second regex that must NOT match on the same line (reduces false positives)\n negativeFilter?: RegExp;\n // If provided, the pattern is only flagged when the surrounding ±5 lines\n // contain at least one match for this regex (security context proximity check)\n contextRequired?: RegExp;\n}\n\nconst SECURITY_PATTERNS: SecurityPattern[] = [\n // === Hardcoded Secrets ===\n {\n id: \"hardcoded-api-key\",\n name: \"Hardcoded API key\",\n pattern: /(?:api[_-]?key|apikey|api[_-]?secret)\\s*[:=]\\s*['\"][A-Za-z0-9_\\-]{16,}['\"]/gi,\n severity: \"error\",\n confidence: 0.85,\n message: \"Potential hardcoded API key\",\n languages: \"all\",\n tags: [\"security\", \"secrets\"],\n negativeFilter: /(?:example|placeholder|your[_-]|xxx|test|dummy|fake|sample)/i,\n },\n {\n id: \"hardcoded-password\",\n name: \"Hardcoded password\",\n pattern: /(?:password|passwd|pwd)\\s*[:=]\\s*['\"][^'\"]{4,}['\"]/gi,\n severity: \"error\",\n confidence: 0.75,\n message: \"Potential hardcoded password\",\n languages: \"all\",\n tags: [\"security\", \"secrets\"],\n negativeFilter: /(?:example|placeholder|your[_-]|xxx|test|dummy|fake|sample|\\$\\{|process\\.env|os\\.environ|os\\.Getenv)/i,\n },\n {\n id: \"hardcoded-token\",\n name: \"Hardcoded token\",\n pattern: /(?:token|bearer|jwt|auth[_-]?token|access[_-]?token|secret[_-]?key)\\s*[:=]\\s*['\"][A-Za-z0-9_.\\-]{20,}['\"]/gi,\n severity: \"error\",\n confidence: 0.8,\n message: \"Potential hardcoded authentication token\",\n languages: \"all\",\n tags: [\"security\", \"secrets\"],\n negativeFilter: /(?:example|placeholder|your[_-]|xxx|test|dummy|fake|sample)/i,\n },\n {\n id: \"private-key\",\n name: \"Private key in source\",\n pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/g,\n severity: \"error\",\n confidence: 0.98,\n message: \"Private key embedded in source code\",\n languages: \"all\",\n tags: [\"security\", \"secrets\", \"critical\"],\n },\n {\n id: \"aws-key\",\n name: \"AWS access key\",\n pattern: /(?:AKIA|ASIA)[A-Z0-9]{16}/g,\n severity: \"error\",\n confidence: 0.95,\n message: \"AWS access key ID detected\",\n languages: \"all\",\n tags: [\"security\", \"secrets\", \"aws\"],\n },\n\n // === Injection Vulnerabilities ===\n {\n id: \"sql-injection\",\n name: \"SQL injection risk\",\n pattern: /(?:query|exec|execute|raw)\\s*\\(\\s*[`'\"](?:SELECT|INSERT|UPDATE|DELETE|DROP)\\b[^`'\"]*\\$\\{/gi,\n severity: \"error\",\n confidence: 0.8,\n message: \"Potential SQL injection: string interpolation in query\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"injection\", \"sql\"],\n },\n {\n id: \"sql-concat\",\n name: \"SQL concatenation\",\n pattern: /(?:query|exec|execute)\\s*\\(\\s*['\"](?:SELECT|INSERT|UPDATE|DELETE)\\b[^'\"]*['\"]\\s*\\+/gi,\n severity: \"error\",\n confidence: 0.85,\n message: \"Potential SQL injection: string concatenation in query\",\n languages: [\"javascript\", \"typescript\", \"python\"],\n tags: [\"security\", \"injection\", \"sql\"],\n },\n {\n id: \"go-sql-fmt\",\n name: \"Go SQL fmt injection\",\n pattern: /(?:db\\.(?:Query|Exec|QueryRow))\\s*\\(\\s*fmt\\.Sprintf\\s*\\(/g,\n severity: \"error\",\n confidence: 0.9,\n message: \"SQL injection risk: fmt.Sprintf used in database query\",\n languages: [\"go\"],\n tags: [\"security\", \"injection\", \"sql\"],\n },\n {\n id: \"command-injection\",\n name: \"Command injection\",\n pattern: /(?:exec|execSync|spawn|execFile)\\s*\\([^)]*\\+/g,\n severity: \"error\",\n confidence: 0.75,\n message: \"Potential command injection: dynamic value in shell execution\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"injection\", \"command\"],\n },\n {\n id: \"python-shell-injection\",\n name: \"Python shell injection\",\n pattern: /subprocess\\.(?:call|run|Popen)\\s*\\([^)]*shell\\s*=\\s*True/g,\n severity: \"error\",\n confidence: 0.85,\n message: \"Shell injection risk: subprocess with shell=True\",\n languages: [\"python\"],\n tags: [\"security\", \"injection\", \"command\"],\n },\n\n // === Unsafe Functions ===\n {\n id: \"eval-usage\",\n name: \"eval() usage\",\n pattern: /\\beval\\s*\\(/g,\n severity: \"error\",\n confidence: 0.9,\n message: \"Use of eval() — potential code injection vector\",\n languages: [\"javascript\", \"typescript\", \"python\"],\n tags: [\"security\", \"unsafe-function\"],\n negativeFilter: /(?:eslint|no-eval|# noqa)/i,\n },\n {\n id: \"function-constructor\",\n name: \"Function constructor\",\n pattern: /new\\s+Function\\s*\\(/g,\n severity: \"error\",\n confidence: 0.9,\n message: \"Use of Function constructor — equivalent to eval()\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"unsafe-function\"],\n },\n {\n id: \"innerHTML-assignment\",\n name: \"innerHTML assignment\",\n pattern: /\\.innerHTML\\s*=/g,\n severity: \"warning\",\n confidence: 0.7,\n message: \"Direct innerHTML assignment — potential XSS vector\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"xss\"],\n },\n {\n id: \"dangerously-set-html\",\n name: \"dangerouslySetInnerHTML\",\n pattern: /dangerouslySetInnerHTML/g,\n severity: \"warning\",\n confidence: 0.8,\n message: \"dangerouslySetInnerHTML used — ensure input is sanitized\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"xss\", \"react\"],\n },\n\n // === Insecure Crypto ===\n {\n id: \"weak-hash-md5\",\n name: \"MD5 hash usage\",\n pattern: /(?:createHash|hashlib\\.md5|md5\\.New|Md5::new)\\s*\\(\\s*['\"]?md5['\"]?\\s*\\)/gi,\n severity: \"warning\",\n confidence: 0.85,\n message: \"MD5 is cryptographically broken — use SHA-256 or better\",\n languages: \"all\",\n tags: [\"security\", \"crypto\"],\n },\n {\n id: \"weak-hash-sha1\",\n name: \"SHA1 hash usage\",\n pattern: /(?:createHash|hashlib\\.sha1|sha1\\.New|Sha1::new)\\s*\\(\\s*['\"]?sha1['\"]?\\s*\\)/gi,\n severity: \"warning\",\n confidence: 0.8,\n message: \"SHA-1 is deprecated for security — use SHA-256 or better\",\n languages: \"all\",\n tags: [\"security\", \"crypto\"],\n },\n {\n id: \"math-random-crypto\",\n name: \"Math.random for security\",\n pattern: /Math\\.random\\s*\\(\\)/g,\n severity: \"warning\",\n confidence: 0.5,\n message: \"Math.random() is not cryptographically secure — use crypto.randomUUID()\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"crypto\"],\n negativeFilter: /(?:test|mock|seed|shuffle|animation|color|position|offset|delay|jitter)/i,\n // Only flag near security-relevant code — UI shuffles/animations are not a risk\n contextRequired: /(?:token|secret|password|key|nonce|salt|hash|crypto|auth|session|jwt|api.?key|credential)/i,\n },\n\n // === Path Traversal ===\n {\n id: \"path-traversal\",\n name: \"Path traversal risk\",\n pattern: /(?:readFile|readFileSync|createReadStream|open)\\s*\\([^)]*\\+/g,\n severity: \"warning\",\n confidence: 0.6,\n message: \"Potential path traversal: dynamic value in file operation\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"path-traversal\"],\n },\n\n // === SSRF ===\n {\n id: \"ssrf-risk\",\n name: \"SSRF risk\",\n pattern: /(?:fetch|axios\\.get|http\\.get|requests\\.get|httpClient)\\s*\\(\\s*(?:[`'\"].*\\$\\{|[^'\"]*\\+)/g,\n severity: \"info\",\n confidence: 0.4,\n message: \"URL constructed from variable — review if the source is user-controlled\",\n languages: \"all\",\n tags: [\"security\", \"ssrf\"],\n negativeFilter: /(?:API_URL|BASE_URL|apiUrl|baseUrl|base\\s*\\+|endpoint|config\\.|process\\.env)/i,\n },\n\n // === Python-specific ===\n {\n id: \"python-pickle\",\n name: \"Unsafe pickle.load\",\n pattern: /pickle\\.loads?\\s*\\(/g,\n severity: \"error\",\n confidence: 0.85,\n message: \"pickle.load can execute arbitrary code — use json or safer alternatives\",\n languages: [\"python\"],\n tags: [\"security\", \"deserialization\"],\n },\n {\n id: \"python-yaml-unsafe\",\n name: \"Unsafe YAML load\",\n pattern: /yaml\\.load\\s*\\([^)]*(?!\\bLoader\\b)/g,\n severity: \"error\",\n confidence: 0.8,\n message: \"yaml.load without SafeLoader can execute arbitrary code\",\n languages: [\"python\"],\n tags: [\"security\", \"deserialization\"],\n negativeFilter: /SafeLoader|FullLoader|BaseLoader/,\n },\n\n // === Go-specific ===\n {\n id: \"go-tls-skip-verify\",\n name: \"Go TLS skip verify\",\n pattern: /InsecureSkipVerify\\s*:\\s*true/g,\n severity: \"error\",\n confidence: 0.95,\n message: \"TLS certificate verification disabled\",\n languages: [\"go\"],\n tags: [\"security\", \"tls\"],\n },\n\n // === Rust-specific ===\n {\n id: \"rust-unsafe\",\n name: \"Rust unsafe blocks\",\n pattern: /\\bunsafe\\s*\\{/g,\n severity: \"warning\",\n confidence: 0.7,\n message: \"Unsafe block — ensure memory safety invariants are upheld\",\n languages: [\"rust\"],\n tags: [\"security\", \"memory-safety\"],\n },\n];\n\nexport const securityAnalyzer: Analyzer = {\n id: \"security\",\n name: \"Security Posture\",\n category: \"securityPosture\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const projectLanguages = [...ctx.languageBreakdown.keys()];\n\n // Skip matches inside pattern definitions (regex literals, analyzer\n // config objects). Prevents the security analyzer from flagging its\n // own detection pattern strings.\n const PATTERN_DEF = /(?:pattern\\s*:|regex\\s*:|RegExp\\s*\\(|name\\s*:|message\\s*:|id\\s*:|label\\s*:)/;\n\n for (const file of ctx.files) {\n // Skip test fixture files — they contain intentionally insecure code\n if (/(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\\\]/i.test(file.relativePath)) continue;\n\n for (const pattern of SECURITY_PATTERNS) {\n if (pattern.languages !== \"all\") {\n if (!file.language || !pattern.languages.includes(file.language)) continue;\n }\n\n const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const lineStart = file.content.lastIndexOf(\"\\n\", match.index) + 1;\n const lineEnd = file.content.indexOf(\"\\n\", match.index);\n const line = file.content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd);\n\n // Skip matches inside pattern/config definitions\n if (PATTERN_DEF.test(line)) continue;\n\n // Apply negative filter\n if (pattern.negativeFilter) {\n if (pattern.negativeFilter.test(line)) continue;\n }\n\n // Context proximity check: only flag if surrounding ±5 lines\n // contain security-relevant keywords\n if (pattern.contextRequired) {\n const lines = file.content.split(\"\\n\");\n const matchLine = file.content.slice(0, match.index).split(\"\\n\").length - 1;\n const start = Math.max(0, matchLine - 5);\n const end = Math.min(lines.length, matchLine + 6);\n const context = lines.slice(start, end).join(\"\\n\");\n if (!pattern.contextRequired.test(context)) continue;\n }\n\n const lineNum = getLineNumber(file.content, match.index);\n const snippet = line.trim();\n\n findings.push({\n analyzerId: \"security\",\n severity: pattern.severity,\n confidence: pattern.confidence,\n message: `${pattern.message} in ${file.relativePath}:${lineNum}`,\n locations: [{\n file: file.relativePath,\n line: lineNum,\n snippet: snippet.length > 120 ? snippet.slice(0, 120) + \"...\" : snippet,\n }],\n tags: pattern.tags,\n });\n }\n }\n }\n\n // Deduplicate similar findings in the same file\n return deduplicateFindings(findings);\n },\n};\n\nfunction deduplicateFindings(findings: Finding[]): Finding[] {\n const seen = new Map<string, Finding>();\n for (const f of findings) {\n const key = `${f.locations[0]?.file}:${f.locations[0]?.line}:${f.tags.join(\",\")}`;\n const existing = seen.get(key);\n if (!existing || f.confidence > existing.confidence) {\n seen.set(key, f);\n }\n }\n return [...seen.values()];\n}\n","/**\n * Cyclomatic complexity analyzer.\n *\n * Computes per-function cyclomatic complexity using AST decision-node counting\n * (when tree-sitter is available) or regex-based pattern matching as fallback.\n * Flags individual functions exceeding complexity 10/20 and warns if the\n * project-wide average exceeds 8.\n */\n\nimport type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding, SyntaxNode } from \"../core/types.js\";\n\n// Cyclomatic complexity: M = E - N + 2P\n// Simplified: start at 1, add 1 for each decision point\n\n// Decision-point node types per language\nconst DECISION_NODES: Record<string, Set<string>> = {\n javascript: new Set([\n \"if_statement\", \"else_clause\", \"for_statement\", \"for_in_statement\",\n \"while_statement\", \"do_statement\", \"switch_case\", \"catch_clause\",\n \"ternary_expression\", \"binary_expression\", // && and || counted below\n ]),\n typescript: new Set([\n \"if_statement\", \"else_clause\", \"for_statement\", \"for_in_statement\",\n \"while_statement\", \"do_statement\", \"switch_case\", \"catch_clause\",\n \"ternary_expression\", \"binary_expression\",\n ]),\n python: new Set([\n \"if_statement\", \"elif_clause\", \"for_statement\", \"while_statement\",\n \"except_clause\", \"conditional_expression\", \"boolean_operator\",\n \"list_comprehension\", \"dictionary_comprehension\", \"set_comprehension\",\n ]),\n go: new Set([\n \"if_statement\", \"for_statement\", \"expression_case\", \"type_case\",\n \"select_statement\", \"communication_case\",\n ]),\n rust: new Set([\n \"if_expression\", \"for_expression\", \"while_expression\", \"loop_expression\",\n \"match_arm\", \"if_let_expression\", \"while_let_expression\",\n ]),\n};\n\nconst LOGICAL_OPS = new Set([\"&&\", \"||\", \"and\", \"or\"]);\n\ninterface FunctionInfo {\n name: string;\n file: string;\n line: number;\n complexity: number;\n lineCount: number;\n}\n\nfunction computeComplexityAST(node: SyntaxNode, language: string): number {\n let complexity = 1; // base complexity\n const decisionNodes = DECISION_NODES[language] ?? DECISION_NODES[\"javascript\"];\n\n function walk(n: SyntaxNode) {\n if (decisionNodes.has(n.type)) {\n // binary_expression includes arithmetic — only && / || / and / or add branches\n if (n.type === \"binary_expression\" || n.type === \"boolean_operator\") {\n const op = n.childForFieldName(\"operator\");\n if (op && LOGICAL_OPS.has(op.text)) {\n complexity++;\n }\n } else {\n complexity++;\n }\n }\n for (let i = 0; i < n.childCount; i++) {\n walk(n.child(i)!);\n }\n }\n\n walk(node);\n return complexity;\n}\n\n// Strip comments so the regex fallback doesn't count && / || inside comments\nfunction stripComments(code: string): string {\n return code\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\") // multi-line /* ... */\n .replace(/\\/\\/.*$/gm, \"\") // single-line //\n .replace(/#.*$/gm, \"\"); // single-line # (Python)\n}\n\n// Regex fallback: count decision points in source text\nfunction computeComplexityRegex(content: string): number {\n const stripped = stripComments(content);\n let complexity = 1;\n const patterns = [\n /\\bif\\s*\\(/g, /\\belse\\s+if\\b/g, /\\belif\\b/g,\n /\\bfor\\s*\\(/g, /\\bfor\\s+\\w/g, // for-in, for range\n /\\bwhile\\s*\\(/g, /\\bwhile\\s+/g,\n /\\bcase\\s+/g,\n /\\bcatch\\s*\\(/g, /\\bexcept\\s/g,\n /\\?\\s*[^?:]+\\s*:/g, // ternary\n /\\s&&\\s/g, /\\s\\|\\|\\s/g,\n /\\band\\b/g, /\\bor\\b/g,\n ];\n\n for (const p of patterns) {\n const regex = new RegExp(p.source, p.flags);\n const matches = stripped.match(regex);\n if (matches) complexity += matches.length;\n }\n\n return complexity;\n}\n\nfunction extractFunctions(node: SyntaxNode, file: string, language: string): FunctionInfo[] {\n const functions: FunctionInfo[] = [];\n const functionTypes = new Set([\n \"function_declaration\", \"method_definition\", \"arrow_function\",\n \"function_definition\", \"method_declaration\", // Python, Go\n \"function_item\", \"impl_item\", // Rust\n ]);\n\n function walk(n: SyntaxNode) {\n if (functionTypes.has(n.type)) {\n const nameNode = n.childForFieldName(\"name\");\n const name = nameNode?.text ?? \"(anonymous)\";\n const startLine = n.startPosition.row + 1;\n const lineCount = n.endPosition.row - n.startPosition.row + 1;\n const complexity = computeComplexityAST(n, language);\n\n functions.push({ name, file, line: startLine, complexity, lineCount });\n }\n for (let i = 0; i < n.childCount; i++) {\n walk(n.child(i)!);\n }\n }\n\n walk(node);\n return functions;\n}\n\n// Regex-based function extraction fallback\nfunction extractFunctionsRegex(content: string, file: string): FunctionInfo[] {\n const functionPattern = /(?:(?:async\\s+)?function\\s+(\\w+)|(?:const|let|var)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?(?:\\([^)]*\\)|[a-zA-Z_]\\w*)\\s*=>|def\\s+(\\w+)|func\\s+(\\w+)|fn\\s+(\\w+))/g;\n\n // First pass: collect all function start positions\n const starts: { name: string; index: number; line: number }[] = [];\n let match;\n while ((match = functionPattern.exec(content)) !== null) {\n const name = match[1] || match[2] || match[3] || match[4] || match[5];\n const line = content.slice(0, match.index).split(\"\\n\").length;\n starts.push({ name, index: match.index, line });\n }\n\n // Second pass: slice between consecutive starts to approximate each body,\n // then run the regex complexity counter on each slice\n const functions: FunctionInfo[] = [];\n for (let i = 0; i < starts.length; i++) {\n const start = starts[i];\n const bodyEnd = i + 1 < starts.length ? starts[i + 1].index : content.length;\n const body = content.slice(start.index, bodyEnd);\n const complexity = computeComplexityRegex(body);\n const lineCount = body.split(\"\\n\").length;\n functions.push({ name: start.name, file, line: start.line, complexity, lineCount });\n }\n\n return functions;\n}\n\nexport const complexityAnalyzer: Analyzer = {\n id: \"complexity\",\n name: \"Code Complexity\",\n category: \"intentClarity\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const allFunctions: FunctionInfo[] = [];\n\n for (const file of ctx.files) {\n if (!file.language) continue;\n const fns = file.tree\n ? extractFunctions(file.tree.rootNode, file.relativePath, file.language)\n : extractFunctionsRegex(file.content, file.relativePath);\n allFunctions.push(...fns);\n }\n\n // Flag individual high-complexity functions\n const highComplexity = allFunctions.filter((f) => f.complexity > 10);\n const veryHighComplexity = allFunctions.filter((f) => f.complexity > 20);\n\n for (const fn of veryHighComplexity) {\n findings.push({\n analyzerId: \"complexity\",\n severity: \"error\",\n confidence: 0.9,\n message: `Function \"${fn.name}\" has cyclomatic complexity ${fn.complexity} (threshold: 20)`,\n locations: [{\n file: fn.file,\n line: fn.line,\n snippet: `${fn.name}() — ${fn.lineCount} lines, complexity ${fn.complexity}`,\n }],\n tags: [\"complexity\", \"critical\"],\n });\n }\n\n for (const fn of highComplexity.filter((f) => f.complexity <= 20)) {\n findings.push({\n analyzerId: \"complexity\",\n severity: \"warning\",\n confidence: 0.85,\n message: `Function \"${fn.name}\" has cyclomatic complexity ${fn.complexity} (threshold: 10)`,\n locations: [{\n file: fn.file,\n line: fn.line,\n snippet: `${fn.name}() — ${fn.lineCount} lines, complexity ${fn.complexity}`,\n }],\n tags: [\"complexity\", \"high\"],\n });\n }\n\n // Project-level complexity summary\n if (allFunctions.length > 0) {\n const avgComplexity = allFunctions.reduce((s, f) => s + f.complexity, 0) / allFunctions.length;\n if (avgComplexity > 8) {\n findings.push({\n analyzerId: \"complexity\",\n severity: \"warning\",\n confidence: 0.8,\n message: `High average complexity: ${avgComplexity.toFixed(1)} across ${allFunctions.length} functions`,\n locations: [],\n tags: [\"complexity\", \"average\"],\n });\n }\n }\n\n return findings;\n },\n};\n","/**\n * Intent clarity analyzer — measures how well code communicates its purpose.\n *\n * Runs four sub-checks: (1) commented-out code blocks that add noise,\n * (2) generic/unclear function names, (3) functions exceeding 50 lines that\n * likely do too much, and (4) low documentation density on large files and\n * undocumented public exports.\n */\n\nimport type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\n// Detect commented-out code blocks (not documentation comments)\nconst CODE_COMMENT_PATTERNS = [\n // JS/TS/Go/Rust: // or /* ... */ containing code-like syntax\n /\\/\\/\\s*(?:const|let|var|function|return|if|for|import|export|class)\\s/g,\n /\\/\\/\\s*\\w+\\s*[=(]/g,\n // Python: # followed by code-like syntax\n /#\\s*(?:def|class|import|return|if|for|while|try|except)\\s/g,\n /#\\s*\\w+\\s*[=(]/g,\n];\n\n// Multi-line commented-out code (3+ consecutive comment lines with code patterns)\nconst MULTI_LINE_COMMENT_CODE = /(?:^[ \\t]*\\/\\/.*(?:\\{|;|=|return|const|let|var|function)\\s*$\\n?){3,}/gm;\nconst MULTI_LINE_COMMENT_CODE_PY = /(?:^[ \\t]*#.*(?::|=|return|def|class|import)\\s*$\\n?){3,}/gm;\n\n// Generic / unclear naming patterns\nconst GENERIC_NAMES = new Set([\n \"data\", \"temp\", \"tmp\", \"val\", \"value\", \"item\", \"obj\", \"thing\",\n \"foo\", \"bar\", \"baz\", \"test\", \"handle\", \"process\", \"do\", \"run\",\n \"manager\", \"helper\", \"utils\", \"misc\",\n]);\n\nconst SHORT_NAME_MIN = 3;\n\nexport const intentClarityAnalyzer: Analyzer = {\n id: \"intent-clarity\",\n name: \"Intent Clarity\",\n category: \"intentClarity\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n findings.push(...detectCommentedOutCode(ctx));\n findings.push(...detectUnclearNaming(ctx));\n findings.push(...detectLongFunctions(ctx));\n findings.push(...detectLowDocumentation(ctx));\n\n return findings;\n },\n};\n\nfunction detectCommentedOutCode(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n let totalBlocks = 0;\n const blockLocations: { file: string; line: number; snippet: string }[] = [];\n\n for (const file of ctx.files) {\n // Multi-line commented code blocks\n const pattern = file.language === \"python\"\n ? MULTI_LINE_COMMENT_CODE_PY\n : MULTI_LINE_COMMENT_CODE;\n\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n totalBlocks++;\n const line = getLineNumber(file.content, match.index);\n const lines = match[0].trim().split(\"\\n\");\n blockLocations.push({\n file: file.relativePath,\n line,\n snippet: lines[0].trim().slice(0, 80) + (lines.length > 1 ? ` (+${lines.length - 1} lines)` : \"\"),\n });\n }\n }\n\n if (totalBlocks > 0) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: totalBlocks > 10 ? \"error\" : totalBlocks > 3 ? \"warning\" : \"info\",\n confidence: 0.7,\n message: `${totalBlocks} blocks of commented-out code found`,\n locations: blockLocations.slice(0, 15),\n tags: [\"intent\", \"commented-code\"],\n });\n }\n\n return findings;\n}\n\nfunction detectUnclearNaming(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const funcNamePatterns = [\n /(?:function|const|let|var)\\s+(\\w+)\\s*(?:=\\s*(?:async\\s+)?(?:\\(|function)|\\()/g,\n /def\\s+(\\w+)\\s*\\(/g,\n /func\\s+(\\w+)\\s*\\(/g,\n /fn\\s+(\\w+)\\s*[(<]/g,\n ];\n\n const genericFunctions: { name: string; file: string; line: number }[] = [];\n const shortFunctions: { name: string; file: string; line: number }[] = [];\n\n for (const file of ctx.files) {\n for (const pattern of funcNamePatterns) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const name = match[1];\n const line = getLineNumber(file.content, match.index);\n\n if (name.length < SHORT_NAME_MIN && ![\"go\", \"fn\", \"ok\", \"id\"].includes(name)) {\n shortFunctions.push({ name, file: file.relativePath, line });\n }\n\n const lowerName = name.toLowerCase();\n if (GENERIC_NAMES.has(lowerName)) {\n genericFunctions.push({ name, file: file.relativePath, line });\n }\n }\n }\n }\n\n if (genericFunctions.length > 3) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: \"warning\",\n confidence: 0.65,\n message: `${genericFunctions.length} functions with generic/unclear names (${[...new Set(genericFunctions.map((f) => f.name))].slice(0, 5).join(\", \")})`,\n locations: genericFunctions.slice(0, 10).map((f) => ({\n file: f.file,\n line: f.line,\n snippet: `function ${f.name}(...)`,\n })),\n tags: [\"intent\", \"naming\"],\n });\n }\n\n if (shortFunctions.length > 5) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: \"info\",\n confidence: 0.5,\n message: `${shortFunctions.length} functions with very short names (<${SHORT_NAME_MIN} chars)`,\n locations: shortFunctions.slice(0, 10).map((f) => ({\n file: f.file,\n line: f.line,\n })),\n tags: [\"intent\", \"naming\", \"short\"],\n });\n }\n\n return findings;\n}\n\nfunction detectLongFunctions(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n\n // Heuristic: detect functions longer than 50 lines\n // We look for function starts and measure to next function or end\n const functionStarts = [\n /^(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)/gm,\n /^def\\s+(\\w+)/gm,\n /^func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)/gm,\n /^(?:pub\\s+)?(?:async\\s+)?fn\\s+(\\w+)/gm,\n ];\n\n const longFunctions: { name: string; file: string; line: number; lines: number }[] = [];\n const LONG_THRESHOLD = 50;\n\n for (const file of ctx.files) {\n const lineOffsets: number[] = [];\n let offset = 0;\n for (const line of file.content.split(\"\\n\")) {\n lineOffsets.push(offset);\n offset += line.length + 1;\n }\n\n const starts: { name: string; offset: number; line: number }[] = [];\n\n for (const pattern of functionStarts) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n starts.push({\n name: match[1],\n offset: match.index,\n line: getLineNumber(file.content, match.index),\n });\n }\n }\n\n starts.sort((a, b) => a.offset - b.offset);\n\n // Approximate each function's length by measuring from its start to the\n // next function's start (or EOF). Imprecise but avoids needing an AST.\n for (let i = 0; i < starts.length; i++) {\n const start = starts[i];\n const endOffset = i + 1 < starts.length ? starts[i + 1].offset : file.content.length;\n const body = file.content.slice(start.offset, endOffset);\n const lineCount = body.split(\"\\n\").length;\n\n if (lineCount > LONG_THRESHOLD) {\n longFunctions.push({\n name: start.name,\n file: file.relativePath,\n line: start.line,\n lines: lineCount,\n });\n }\n }\n }\n\n if (longFunctions.length > 0) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: longFunctions.some((f) => f.lines > 100) ? \"error\" : \"warning\",\n confidence: 0.85,\n message: `${longFunctions.length} functions exceed ${LONG_THRESHOLD} lines`,\n locations: longFunctions.slice(0, 10).map((f) => ({\n file: f.file,\n line: f.line,\n snippet: `${f.name}() — ${f.lines} lines`,\n })),\n tags: [\"intent\", \"long-function\"],\n });\n }\n\n return findings;\n}\n\nfunction countFileCommentDensity(file: { content: string; lineCount: number }): {\n lines: number;\n commentLines: number;\n density: number;\n} {\n const lines = file.content.split(\"\\n\");\n let commentLines = 0;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (\n trimmed.startsWith(\"//\") || trimmed.startsWith(\"#\") ||\n trimmed.startsWith(\"/*\") || trimmed.startsWith(\"*\") ||\n trimmed.startsWith(\"///\") || trimmed.startsWith('\"\"\"')\n ) {\n commentLines++;\n }\n }\n\n return {\n lines: file.lineCount,\n commentLines,\n density: commentLines / file.lineCount,\n };\n}\n\nfunction findUndocumentedExports(\n files: { content: string; language: string | null; relativePath: string }[],\n): { file: string; name: string; line: number }[] {\n const undocumentedExports: { file: string; name: string; line: number }[] = [];\n\n for (const file of files) {\n if (!file.language) continue;\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let exportedName: string | null = null;\n\n if (file.language === \"go\") {\n const m = line.match(/^func\\s+(?:\\([^)]*\\)\\s+)?([A-Z]\\w+)\\s*\\(/);\n if (m) exportedName = m[1];\n } else if (file.language === \"python\") {\n const m = line.match(/^def\\s+(\\w+)\\s*\\(/);\n if (m && !m[1].startsWith(\"_\")) exportedName = m[1];\n } else if (file.language === \"rust\") {\n const m = line.match(/^pub\\s+(?:async\\s+)?fn\\s+(\\w+)/);\n if (m) exportedName = m[1];\n }\n\n if (!exportedName) continue;\n\n const prevLine = i > 0 ? lines[i - 1].trim() : \"\";\n const hasDoc = prevLine.startsWith(\"//\") || prevLine.startsWith(\"///\") ||\n prevLine.startsWith(\"/*\") || prevLine.startsWith('\"\"\"') ||\n prevLine.startsWith(\"#\");\n\n if (!hasDoc) {\n undocumentedExports.push({ file: file.relativePath, name: exportedName, line: i + 1 });\n }\n }\n }\n\n return undocumentedExports;\n}\n\nfunction detectLowDocumentation(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n\n const underdocumented: { file: string; lines: number; commentRatio: number }[] = [];\n\n for (const file of ctx.files) {\n if (file.lineCount < 100) continue;\n\n const { density } = countFileCommentDensity(file);\n\n // 5% is a pragmatic floor — below this, even experienced developers\n // struggle to understand intent without reading every line\n if (density < 0.05) {\n underdocumented.push({\n file: file.relativePath,\n lines: file.lineCount,\n commentRatio: Math.round(density * 100),\n });\n }\n }\n\n if (underdocumented.length > 2) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: underdocumented.length > 5 ? \"warning\" : \"info\",\n confidence: 0.6,\n message: `${underdocumented.length} files over 100 lines have <5% comment density — intent may be unclear to maintainers`,\n locations: underdocumented.slice(0, 10).map((f) => ({\n file: f.file,\n snippet: `${f.lines} lines, ${f.commentRatio}% comments`,\n })),\n tags: [\"intent\", \"documentation\"],\n });\n }\n\n const undocumentedExports = findUndocumentedExports(ctx.files);\n\n if (undocumentedExports.length > 10) {\n const ratio = ctx.files.length > 0\n ? Math.round((undocumentedExports.length / ctx.files.length) * 10) / 10\n : 0;\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: undocumentedExports.length > 30 ? \"warning\" : \"info\",\n confidence: 0.55,\n message: `${undocumentedExports.length} exported functions lack documentation (~${ratio} per file)`,\n locations: undocumentedExports.slice(0, 10).map((e) => ({\n file: e.file,\n line: e.line,\n snippet: `${e.name}() — no doc comment`,\n })),\n tags: [\"intent\", \"undocumented\"],\n });\n }\n\n return findings;\n}\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\n\n// Entry point filenames that should not be flagged\nconst ENTRY_POINTS = new Set([\n \"index\", \"main\", \"app\", \"server\", \"mod\", \"lib\", \"init\", \"__init__\",\n \"setup\", \"config\", \"routes\", \"handler\", \"handlers\",\n]);\n\ninterface ExportedSymbol {\n name: string;\n file: string;\n line: number;\n isDefault: boolean;\n}\n\ninterface ImportedSymbol {\n name: string;\n source: string; // the import path\n importingFile: string;\n}\n\nconst EXPORT_PATTERNS = [\n // JS/TS named exports\n /export\\s+(?:async\\s+)?(?:function|class|const|let|var|type|interface|enum)\\s+(\\w+)/g,\n // JS/TS export { name }\n /export\\s*\\{([^}]+)\\}/g,\n];\n\nconst DEFAULT_EXPORT_PATTERN = /export\\s+default\\s+(?:(?:async\\s+)?(?:function|class)\\s+(\\w+)|(\\w+))/g;\n\nconst IMPORT_PATTERNS_JS = [\n // import { name } from 'path'\n /import\\s*\\{([^}]+)\\}\\s*from\\s*['\"]([^'\"]+)['\"]/g,\n // import name from 'path'\n /import\\s+(\\w+)\\s+from\\s*['\"]([^'\"]+)['\"]/g,\n // import * as name from 'path'\n /import\\s*\\*\\s*as\\s+(\\w+)\\s+from\\s*['\"]([^'\"]+)['\"]/g,\n // const { name } = require('path')\n /(?:const|let|var)\\s*\\{([^}]+)\\}\\s*=\\s*require\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g,\n // const name = require('path')\n /(?:const|let|var)\\s+(\\w+)\\s*=\\s*require\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g,\n];\n\n// Go exports: capitalized functions/types\nconst GO_EXPORT_PATTERN = /^(?:func|type|var|const)\\s+([A-Z]\\w+)/gm;\nconst GO_USAGE_PATTERN = /\\b([A-Z]\\w+)\\b/g;\n\n// Python: functions at module level\nconst PYTHON_DEF_PATTERN = /^def\\s+(\\w+)/gm;\nconst PYTHON_IMPORT_PATTERN = /from\\s+\\.\\w*\\s+import\\s+(.+)/g;\n\nfunction isEntryPoint(filePath: string): boolean {\n const base = filePath.split(\"/\").pop()?.replace(/\\.[^.]+$/, \"\") ?? \"\";\n return ENTRY_POINTS.has(base);\n}\n\nexport const deadCodeAnalyzer: Analyzer = {\n id: \"dead-code\",\n name: \"Dead Code Detection\",\n category: \"redundancy\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n const jsFiles = ctx.files.filter(\n (f) => f.language === \"javascript\" || f.language === \"typescript\",\n );\n const goFiles = ctx.files.filter((f) => f.language === \"go\");\n const pyFiles = ctx.files.filter((f) => f.language === \"python\");\n\n if (jsFiles.length > 0) {\n findings.push(...analyzeJsDeadExports(jsFiles));\n }\n if (goFiles.length > 0) {\n findings.push(...analyzeGoDeadExports(goFiles));\n }\n if (pyFiles.length > 0) {\n findings.push(...analyzePythonDeadCode(pyFiles));\n }\n\n // Unreachable code after return/throw (all languages)\n findings.push(...detectUnreachableCode(ctx));\n\n return findings;\n },\n};\n\nfunction buildExportMap(files: any[]): ExportedSymbol[] {\n const exports: ExportedSymbol[] = [];\n for (const file of files) {\n if (isEntryPoint(file.relativePath)) continue;\n\n // Named exports\n for (const pattern of EXPORT_PATTERNS) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const captured = match[1];\n if (captured.includes(\",\")) {\n for (const name of captured.split(\",\")) {\n const trimmed = name.trim().split(/\\s+as\\s+/)[0].trim();\n if (trimmed) {\n exports.push({\n name: trimmed,\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n isDefault: false,\n });\n }\n }\n } else {\n exports.push({\n name: captured,\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n isDefault: false,\n });\n }\n }\n }\n\n // Default exports\n {\n const regex = new RegExp(DEFAULT_EXPORT_PATTERN.source, DEFAULT_EXPORT_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const name = match[1] || match[2];\n if (name) {\n exports.push({\n name,\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n isDefault: true,\n });\n }\n }\n }\n }\n\n return exports;\n}\n\nfunction buildImportSet(files: any[]): Set<string> {\n const importedNames = new Set<string>();\n for (const file of files) {\n for (const pattern of IMPORT_PATTERNS_JS) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const names = match[1];\n if (names.includes(\",\") || names.includes(\"{\")) {\n for (const n of names.split(\",\")) {\n const trimmed = n.trim().split(/\\s+as\\s+/)[0].trim().replace(/[{}]/g, \"\");\n if (trimmed) importedNames.add(trimmed);\n }\n } else {\n importedNames.add(names.trim());\n }\n }\n }\n }\n\n return importedNames;\n}\n\nfunction identifyDeadExports(\n exports: ExportedSymbol[],\n importedNames: Set<string>,\n allContent: string,\n): ExportedSymbol[] {\n // Track default import usage — files that import defaults reference the export indirectly\n // \"import Foo from './bar'\" means bar's default export is used\n // We track this by marking any file that HAS a default import as having its default used\n\n // Also check for usage via string matching (handles re-exports, dynamic usage)\n return exports.filter(\n (e) => !importedNames.has(e.name) && countOccurrences(allContent, e.name) <= 1,\n );\n}\n\nfunction analyzeJsDeadExports(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n const exports = buildExportMap(files);\n const importedNames = buildImportSet(files);\n const allContent = files.map((f: any) => f.content).join(\"\\n\");\n const deadExports = identifyDeadExports(exports, importedNames, allContent);\n\n if (deadExports.length > 3) {\n findings.push({\n analyzerId: \"dead-code\",\n severity: deadExports.length > 10 ? \"error\" : \"warning\",\n confidence: 0.6,\n message: `${deadExports.length} exported symbols appear unused: ${deadExports.slice(0, 5).map((e) => e.name).join(\", \")}${deadExports.length > 5 ? \"...\" : \"\"}`,\n locations: deadExports.slice(0, 15).map((e) => ({\n file: e.file,\n line: e.line,\n snippet: `export ${e.name}`,\n })),\n tags: [\"dead-code\", \"unused-export\"],\n });\n }\n\n return findings;\n}\n\nfunction analyzeGoDeadExports(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n // In Go, exported = capitalized. Collect all exports.\n const exports: { name: string; file: string; line: number }[] = [];\n for (const file of files) {\n if (isEntryPoint(file.relativePath)) continue;\n const regex = new RegExp(GO_EXPORT_PATTERN.source, GO_EXPORT_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n exports.push({\n name: match[1],\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n });\n }\n }\n\n // Count usage across all files\n const allContent = files.map((f: any) => f.content).join(\"\\n\");\n const deadExports = exports.filter(\n (e) => countOccurrences(allContent, e.name) <= 1,\n );\n\n if (deadExports.length > 3) {\n findings.push({\n analyzerId: \"dead-code\",\n severity: \"warning\",\n confidence: 0.55,\n message: `${deadExports.length} Go exported symbols appear unused: ${deadExports.slice(0, 5).map((e) => e.name).join(\", \")}${deadExports.length > 5 ? \"...\" : \"\"}`,\n locations: deadExports.slice(0, 10).map((e) => ({\n file: e.file,\n line: e.line,\n })),\n tags: [\"dead-code\", \"unused-export\", \"go\"],\n });\n }\n\n return findings;\n}\n\nfunction analyzePythonDeadCode(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n const defs: { name: string; file: string; line: number }[] = [];\n for (const file of files) {\n if (isEntryPoint(file.relativePath)) continue;\n const regex = new RegExp(PYTHON_DEF_PATTERN.source, PYTHON_DEF_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const name = match[1];\n if (name.startsWith(\"_\")) continue; // private\n defs.push({\n name,\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n });\n }\n }\n\n const allContent = files.map((f: any) => f.content).join(\"\\n\");\n const dead = defs.filter((d) => countOccurrences(allContent, d.name) <= 1);\n\n if (dead.length > 3) {\n findings.push({\n analyzerId: \"dead-code\",\n severity: \"warning\",\n confidence: 0.5,\n message: `${dead.length} Python functions appear unused: ${dead.slice(0, 5).map((d) => d.name).join(\", \")}${dead.length > 5 ? \"...\" : \"\"}`,\n locations: dead.slice(0, 10).map((d) => ({ file: d.file, line: d.line })),\n tags: [\"dead-code\", \"unused-def\", \"python\"],\n });\n }\n\n return findings;\n}\n\nfunction detectUnreachableCode(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const unreachableLocations: { file: string; line: number; snippet: string }[] = [];\n\n // Pattern: return/throw/break/continue followed by non-closing-brace code on next line\n const UNREACHABLE_PATTERN = /^(\\s*)(?:return\\b|throw\\b|break\\b|continue\\b).*;?\\s*$\\n(?!\\s*\\}|\\s*$|\\s*\\/\\/|\\s*case\\b|\\s*default\\b|\\s*else\\b|\\s*catch\\b|\\s*finally\\b)(\\s*)(\\S.+)$/gm;\n\n for (const file of ctx.files) {\n const regex = new RegExp(UNREACHABLE_PATTERN.source, UNREACHABLE_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const returnIndent = match[1].length;\n const nextIndent = match[2].length;\n // Only flag if next line has same or deeper indentation\n if (nextIndent >= returnIndent) {\n const line = file.content.slice(0, match.index).split(\"\\n\").length + 1;\n unreachableLocations.push({\n file: file.relativePath,\n line: line + 1,\n snippet: match[3].trim().slice(0, 60),\n });\n }\n }\n }\n\n if (unreachableLocations.length > 0) {\n findings.push({\n analyzerId: \"dead-code\",\n severity: \"warning\",\n confidence: 0.65,\n message: `${unreachableLocations.length} potentially unreachable code blocks after return/throw`,\n locations: unreachableLocations.slice(0, 10),\n tags: [\"dead-code\", \"unreachable\"],\n });\n }\n\n return findings;\n}\n\nfunction countOccurrences(text: string, word: string): number {\n const regex = new RegExp(`\\\\b${escapeRegex(word)}\\\\b`, \"g\");\n const matches = text.match(regex);\n return matches ? matches.length : 0;\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\nexport const languageSpecificAnalyzer: Analyzer = {\n id: \"language-specific\",\n name: \"Language-Specific Patterns\",\n category: \"architecturalConsistency\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n const goFiles = ctx.files.filter((f) => f.language === \"go\");\n const pyFiles = ctx.files.filter((f) => f.language === \"python\");\n const rsFiles = ctx.files.filter((f) => f.language === \"rust\");\n\n if (goFiles.length > 0) findings.push(...analyzeGo(goFiles));\n if (pyFiles.length > 0) findings.push(...analyzePython(pyFiles));\n if (rsFiles.length > 0) findings.push(...analyzeRust(rsFiles));\n\n return findings;\n },\n};\n\n// ===== Go Analysis =====\n\nfunction detectGoUncheckedErrors(\n files: any[],\n): { count: number; locations: { file: string; line: number; snippet: string }[] } {\n let count = 0;\n const locations: { file: string; line: number; snippet: string }[] = [];\n\n for (const file of files) {\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n\n // Unchecked error: line assigns to err (or _) but next non-blank line doesn't check it\n if (/\\berr\\s*[:=]/.test(trimmed) && !trimmed.startsWith(\"//\")) {\n // Look at the next non-empty, non-comment line\n let nextLine = \"\";\n for (let j = i + 1; j < Math.min(i + 4, lines.length); j++) {\n const next = lines[j].trim();\n if (next && !next.startsWith(\"//\")) {\n nextLine = next;\n break;\n }\n }\n if (nextLine && !nextLine.includes(\"err\") && !nextLine.startsWith(\"return\")) {\n count++;\n locations.push({\n file: file.relativePath,\n line: i + 1,\n snippet: trimmed.slice(0, 80),\n });\n }\n }\n }\n }\n\n return { count, locations };\n}\n\nfunction detectGoNakedGoroutines(\n files: any[],\n): { count: number; locations: { file: string; line: number }[] } {\n let count = 0;\n const locations: { file: string; line: number }[] = [];\n\n for (const file of files) {\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Goroutine: go func() without context.Context in nearby scope\n if (/^\\s*go\\s+func\\s*\\(/.test(line) || /^\\s*go\\s+\\w+\\s*\\(/.test(line)) {\n // Check if context is passed (heuristic: \"ctx\" in the go call or surrounding 3 lines)\n const nearby = lines.slice(Math.max(0, i - 2), i + 3).join(\" \");\n if (!/\\bctx\\b/.test(nearby) && !/context\\./.test(nearby)) {\n count++;\n locations.push({ file: file.relativePath, line: i + 1 });\n }\n }\n }\n }\n\n return { count, locations };\n}\n\nfunction detectGoUnsafeMutex(\n files: any[],\n): { count: number; locations: { file: string; line: number }[] } {\n let count = 0;\n const locations: { file: string; line: number }[] = [];\n\n for (const file of files) {\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n\n // Mutex: .Lock() without defer .Unlock() within next 3 lines\n if (/\\.Lock\\(\\)/.test(trimmed)) {\n const nextLines = lines.slice(i + 1, i + 4).join(\" \");\n if (!/defer\\s+.*\\.Unlock\\(\\)/.test(nextLines) && !/\\.Unlock\\(\\)/.test(trimmed)) {\n count++;\n locations.push({ file: file.relativePath, line: i + 1 });\n }\n }\n }\n }\n\n return { count, locations };\n}\n\nfunction analyzeGo(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n const uncheckedErrors = detectGoUncheckedErrors(files);\n const nakedGoroutines = detectGoNakedGoroutines(files);\n const unsafeMutex = detectGoUnsafeMutex(files);\n\n if (uncheckedErrors.count > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: uncheckedErrors.count > 10 ? \"error\" : \"warning\",\n confidence: 0.7,\n message: `${uncheckedErrors.count} potentially unchecked errors in Go code`,\n locations: uncheckedErrors.locations.slice(0, 10),\n tags: [\"go\", \"error-handling\", \"unchecked-error\"],\n });\n }\n\n if (nakedGoroutines.count > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: \"warning\",\n confidence: 0.6,\n message: `${nakedGoroutines.count} goroutines launched without context — potential leak risk`,\n locations: nakedGoroutines.locations.slice(0, 10),\n tags: [\"go\", \"goroutine\", \"leak\"],\n });\n }\n\n if (unsafeMutex.count > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: \"warning\",\n confidence: 0.75,\n message: `${unsafeMutex.count} mutex locks without defer Unlock — risk of deadlock`,\n locations: unsafeMutex.locations.slice(0, 10),\n tags: [\"go\", \"mutex\", \"concurrency\"],\n });\n }\n\n return findings;\n}\n\n// ===== Python Analysis =====\n\nfunction analyzePython(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n let bareExcepts = 0;\n const bareExceptLocations: { file: string; line: number }[] = [];\n\n let mutableDefaults = 0;\n const mutableDefaultLocations: { file: string; line: number; snippet: string }[] = [];\n\n for (const file of files) {\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n\n // Bare except (catches everything including SystemExit, KeyboardInterrupt)\n if (/^except\\s*:/.test(trimmed)) {\n bareExcepts++;\n bareExceptLocations.push({ file: file.relativePath, line: i + 1 });\n }\n\n // Mutable default arguments\n if (/^def\\s+\\w+\\s*\\(/.test(trimmed)) {\n // Check for mutable defaults: list=[], dict={}, set()\n if (/=\\s*\\[\\s*\\]|=\\s*\\{\\s*\\}|=\\s*set\\s*\\(\\s*\\)/.test(trimmed)) {\n mutableDefaults++;\n mutableDefaultLocations.push({\n file: file.relativePath,\n line: i + 1,\n snippet: trimmed.slice(0, 80),\n });\n }\n }\n }\n }\n\n if (bareExcepts > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: \"error\",\n confidence: 0.95,\n message: `${bareExcepts} bare except clauses — catches SystemExit and KeyboardInterrupt`,\n locations: bareExceptLocations.slice(0, 10),\n tags: [\"python\", \"error-handling\", \"bare-except\"],\n });\n }\n\n if (mutableDefaults > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: \"warning\",\n confidence: 0.9,\n message: `${mutableDefaults} functions with mutable default arguments`,\n locations: mutableDefaultLocations.slice(0, 10),\n tags: [\"python\", \"mutable-default\"],\n });\n }\n\n return findings;\n}\n\n// ===== Rust Analysis =====\n\nfunction analyzeRust(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n let unwrapCount = 0;\n const unwrapLocations: { file: string; line: number; snippet: string }[] = [];\n\n let unsafeCount = 0;\n const unsafeLocations: { file: string; line: number }[] = [];\n\n for (const file of files) {\n // Count .unwrap() calls\n const unwrapPattern = /\\.unwrap\\(\\)/g;\n let match;\n while ((match = unwrapPattern.exec(file.content)) !== null) {\n unwrapCount++;\n const line = getLineNumber(file.content, match.index);\n const lineStart = file.content.lastIndexOf(\"\\n\", match.index) + 1;\n const lineEnd = file.content.indexOf(\"\\n\", match.index);\n const snippet = file.content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd).trim();\n unwrapLocations.push({\n file: file.relativePath,\n line,\n snippet: snippet.slice(0, 80),\n });\n }\n\n // Count unsafe blocks\n const unsafePattern = /\\bunsafe\\s*\\{/g;\n while ((match = unsafePattern.exec(file.content)) !== null) {\n unsafeCount++;\n unsafeLocations.push({\n file: file.relativePath,\n line: getLineNumber(file.content, match.index),\n });\n }\n }\n\n if (unwrapCount > 2) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: unwrapCount > 20 ? \"error\" : \"warning\",\n confidence: 0.8,\n message: `${unwrapCount} .unwrap() calls — consider using ? operator or expect() with context`,\n locations: unwrapLocations.slice(0, 10),\n tags: [\"rust\", \"unwrap\", \"error-handling\"],\n });\n }\n\n if (unsafeCount > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: unsafeCount > 5 ? \"error\" : \"warning\",\n confidence: 0.85,\n message: `${unsafeCount} unsafe blocks in Rust code`,\n locations: unsafeLocations.slice(0, 10),\n tags: [\"rust\", \"unsafe\"],\n });\n }\n\n return findings;\n}\n","import type { AnalysisContext, Finding } from \"../core/types.js\";\nimport type { DriftContext, DriftFinding, DriftDetector, DriftCategory } from \"./types.js\";\nimport { DRIFT_WEIGHTS } from \"./types.js\";\nimport { architecturalContradiction } from \"./architectural-contradiction.js\";\nimport { conventionOscillation } from \"./convention-oscillation.js\";\nimport { securityConsistency } from \"./security-consistency.js\";\nimport { semanticDuplication } from \"./semantic-duplication.js\";\nimport { phantomScaffolding } from \"./phantom-scaffolding.js\";\n\nexport function createDriftDetectors(): DriftDetector[] {\n return [\n architecturalContradiction,\n conventionOscillation,\n securityConsistency,\n semanticDuplication,\n phantomScaffolding,\n ];\n}\n\nexport function buildDriftContext(ctx: AnalysisContext): DriftContext {\n return {\n files: ctx.files.map((f) => ({\n path: f.relativePath,\n language: f.language,\n content: f.content,\n lineCount: f.lineCount,\n })),\n totalLines: ctx.totalLines,\n dominantLanguage: ctx.dominantLanguage,\n };\n}\n\nexport interface DriftScores {\n architectural_consistency: { score: number; maxScore: number; findings: number };\n security_posture: { score: number; maxScore: number; findings: number };\n semantic_duplication: { score: number; maxScore: number; findings: number };\n naming_conventions: { score: number; maxScore: number; findings: number };\n phantom_scaffolding: { score: number; maxScore: number; findings: number };\n composite: number; // 0-100 weighted score\n grade: string; // A-F\n}\n\nexport function runDriftDetection(ctx: AnalysisContext): {\n findings: Finding[];\n driftFindings: DriftFinding[];\n driftScores: DriftScores;\n} {\n const driftCtx = buildDriftContext(ctx);\n const detectors = createDriftDetectors();\n const allDrift: DriftFinding[] = [];\n\n for (const detector of detectors) {\n const driftFindings = detector.detect(driftCtx);\n allDrift.push(...driftFindings);\n }\n\n // Compute drift-specific scores\n const driftScores = computeDriftScores(allDrift);\n\n // Convert to standard Finding format for the existing pipeline\n const findings = allDrift.map(driftFindingToFinding);\n\n return { findings, driftFindings: allDrift, driftScores };\n}\n\nfunction computeDriftScores(findings: DriftFinding[]): DriftScores {\n const categories: DriftCategory[] = [\n \"architectural_consistency\",\n \"security_posture\",\n \"semantic_duplication\",\n \"naming_conventions\",\n \"phantom_scaffolding\",\n ];\n\n const scores: Record<string, { score: number; maxScore: number; findings: number }> = {};\n\n for (const cat of categories) {\n const catFindings = findings.filter((f) => f.driftCategory === cat);\n const weight = DRIFT_WEIGHTS[cat];\n\n if (catFindings.length === 0) {\n scores[cat] = { score: weight, maxScore: weight, findings: 0 };\n continue;\n }\n\n // Use consistency scores from findings\n // Average consistency score of all findings in this category\n const avgConsistency = catFindings.reduce((sum, f) => sum + f.consistencyScore, 0) / catFindings.length;\n\n // Scale: consistency 100% = full score, consistency 50% = half score\n // But also penalize by severity: errors reduce score more\n let severityPenalty = 0;\n for (const f of catFindings) {\n if (f.severity === \"error\") severityPenalty += 3;\n else if (f.severity === \"warning\") severityPenalty += 1.5;\n else severityPenalty += 0.5;\n }\n\n // Base score from consistency, reduced by severity penalty\n const rawScore = (avgConsistency / 100) * weight;\n const penalty = Math.min(rawScore, severityPenalty * (weight / 20));\n const score = Math.max(0, Math.round((rawScore - penalty) * 10) / 10);\n\n scores[cat] = { score, maxScore: weight, findings: catFindings.length };\n }\n\n // Composite: sum of all category scores\n const composite = Math.round(\n Object.values(scores).reduce((sum, s) => sum + s.score, 0) * 10,\n ) / 10;\n\n // Grade\n let grade: string;\n // Must match the canonical thresholds used by html.ts, docx.ts, scan.ts,\n // and ml-client/summarize.ts: A≥90, B≥75, C≥50, D≥25, F<25.\n if (composite >= 90) grade = \"A\";\n else if (composite >= 75) grade = \"B\";\n else if (composite >= 50) grade = \"C\";\n else if (composite >= 25) grade = \"D\";\n else grade = \"F\";\n\n return {\n ...(scores as any),\n composite,\n grade,\n };\n}\n\nfunction driftFindingToFinding(d: DriftFinding): Finding {\n return {\n analyzerId: `drift-${d.detector}`,\n severity: d.severity,\n confidence: d.confidence,\n message: `DRIFT: ${d.finding}`,\n locations: d.deviatingFiles.slice(0, 15).map((df) => ({\n file: df.path,\n line: df.evidence[0]?.line,\n snippet: df.evidence[0]?.code ?? df.detectedPattern,\n })),\n tags: [\"drift\", d.driftCategory, \"cross-file\"],\n };\n}\n","import type { Finding } from \"../core/types.js\";\n\nexport interface DriftDetector {\n id: string;\n name: string;\n category: DriftCategory;\n detect(ctx: DriftContext): DriftFinding[];\n}\n\nexport type DriftCategory =\n | \"architectural_consistency\"\n | \"security_posture\"\n | \"semantic_duplication\"\n | \"naming_conventions\"\n | \"phantom_scaffolding\";\n\nexport const DRIFT_WEIGHTS: Record<DriftCategory, number> = {\n architectural_consistency: 25,\n security_posture: 25,\n semantic_duplication: 20,\n naming_conventions: 15,\n phantom_scaffolding: 15,\n};\n\nexport interface DriftContext {\n files: DriftFile[];\n totalLines: number;\n dominantLanguage: string | null;\n}\n\nexport interface DriftFile {\n path: string;\n language: string | null;\n content: string;\n lineCount: number;\n}\n\nexport interface Evidence {\n line: number;\n code: string;\n}\n\nexport interface DeviatingFile {\n path: string;\n detectedPattern: string;\n evidence: Evidence[];\n}\n\nexport interface DriftFinding {\n detector: string;\n subCategory?: string;\n driftCategory: DriftCategory;\n severity: \"info\" | \"warning\" | \"error\";\n confidence: number;\n finding: string;\n dominantPattern: string;\n dominantCount: number;\n totalRelevantFiles: number;\n consistencyScore: number; // 0-100: (dominant/total)*100\n deviatingFiles: DeviatingFile[];\n recommendation: string;\n}\n","import type { DriftDetector, DriftContext, DriftFinding, DriftFile, Evidence, DeviatingFile } from \"./types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\ntype DataAccessPattern = \"repository\" | \"raw_sql\" | \"orm\" | \"direct_db\" | \"http_client\" | \"in_memory\";\ntype ErrorHandlingPattern = \"wrap_with_context\" | \"raw_propagation\" | \"swallow\" | \"http_error_response\" | \"exception_throw\" | \"result_type\";\ntype ConfigPattern = \"env_direct\" | \"config_struct_di\" | \"hardcoded\" | \"mixed\";\ntype DIPattern = \"constructor_injection\" | \"global_import\" | \"service_locator\" | \"no_di\";\n\ninterface FileArchProfile {\n file: string;\n language: string;\n dataAccess: { pattern: DataAccessPattern; evidence: Evidence[] }[];\n errorHandling: { pattern: ErrorHandlingPattern; evidence: Evidence[] }[];\n config: { pattern: ConfigPattern; evidence: Evidence[] }[];\n di: { pattern: DIPattern; evidence: Evidence[] }[];\n}\n\n\nfunction getLineContent(content: string, lineNum: number): string {\n return (content.split(\"\\n\")[lineNum - 1] ?? \"\").trim();\n}\n\nfunction extractEvidence(content: string, pattern: RegExp, maxResults = 3): Evidence[] {\n const evidence: Evidence[] = [];\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(content)) !== null && evidence.length < maxResults) {\n const line = getLineNumber(content, match.index);\n evidence.push({ line, code: getLineContent(content, line) });\n }\n return evidence;\n}\n\nfunction isHandlerOrController(path: string): boolean {\n return /(?:handler|controller|route|endpoint|view|api|resource|page|action)/i.test(path)\n && !/(?:repository|repo|store|dal|model|query|migration|test|spec|mock)/i.test(path);\n}\n\n// --- Data Access Pattern Detection ---\n\nfunction detectDataAccess(file: DriftFile): { pattern: DataAccessPattern; evidence: Evidence[] }[] {\n const results: { pattern: DataAccessPattern; evidence: Evidence[] }[] = [];\n const c = file.content;\n\n // Repository pattern\n const repoEvidence = extractEvidence(c, /\\b(?:store|repo|repository)\\.\\w+\\s*\\(/g);\n if (repoEvidence.length > 0) results.push({ pattern: \"repository\", evidence: repoEvidence });\n\n // Raw SQL\n const sqlEvidence = extractEvidence(c, /(?:SELECT|INSERT|UPDATE|DELETE)\\s+(?:FROM|INTO|SET|\\*)\\b/gi);\n if (sqlEvidence.length > 0 && !isRepoFile(file.path)) {\n results.push({ pattern: \"raw_sql\", evidence: sqlEvidence });\n }\n\n // ORM\n const ormPatterns = /\\.(?:Where|Find|Create|Save|Delete|First|Preload|findOne|findMany|findAll|objects\\.filter)\\s*\\(/g;\n const ormEvidence = extractEvidence(c, ormPatterns);\n if (ormEvidence.length > 0) results.push({ pattern: \"orm\", evidence: ormEvidence });\n\n // Direct DB\n const dbEvidence = extractEvidence(c, /\\b(?:db|pool|client)\\.\\s*(?:Query|Exec|QueryRow|query|execute|raw)\\s*\\(/g);\n if (dbEvidence.length > 0 && !isRepoFile(file.path)) {\n results.push({ pattern: \"direct_db\", evidence: dbEvidence });\n }\n\n // HTTP client calls in business logic (not in dedicated service layer)\n const httpEvidence = extractEvidence(c, /\\b(?:fetch|axios|http\\.(?:Get|Post|Put)|requests\\.(?:get|post))\\s*\\(/g);\n if (httpEvidence.length > 0 && isHandlerOrController(file.path)) {\n results.push({ pattern: \"http_client\", evidence: httpEvidence });\n }\n\n return results;\n}\n\nfunction isRepoFile(path: string): boolean {\n return /(?:repository|repo|store|dal|model|query)/i.test(path);\n}\n\n// --- Error Handling Pattern Detection ---\n\nfunction detectErrorHandling(file: DriftFile): { pattern: ErrorHandlingPattern; evidence: Evidence[] }[] {\n const results: { pattern: ErrorHandlingPattern; evidence: Evidence[] }[] = [];\n const c = file.content;\n\n if (file.language === \"go\") {\n const wrapEvidence = extractEvidence(c, /fmt\\.Errorf\\([^)]*%w/g);\n if (wrapEvidence.length > 0) results.push({ pattern: \"wrap_with_context\", evidence: wrapEvidence });\n\n const rawEvidence = extractEvidence(c, /return\\s+(?:\\w+,\\s*)?err\\b/g);\n if (rawEvidence.length > 0) results.push({ pattern: \"raw_propagation\", evidence: rawEvidence });\n\n const swallowEvidence = extractEvidence(c, /\\b_\\s*=\\s*\\w+\\.\\w+\\(/g);\n if (swallowEvidence.length > 0) results.push({ pattern: \"swallow\", evidence: swallowEvidence });\n\n const httpErrEvidence = extractEvidence(c, /echo\\.NewHTTPError|http\\.Error|c\\.JSON\\(\\s*http\\.Status/g);\n if (httpErrEvidence.length > 0) results.push({ pattern: \"http_error_response\", evidence: httpErrEvidence });\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n const wrapEvidence = extractEvidence(c, /new\\s+(?:\\w+)?Error\\([^)]*\\+|throw\\s+new\\s+\\w*Error\\(/g);\n if (wrapEvidence.length > 0) results.push({ pattern: \"wrap_with_context\", evidence: wrapEvidence });\n\n const swallowEvidence = extractEvidence(c, /catch\\s*\\([^)]*\\)\\s*\\{\\s*(?:\\/\\/.*\\n\\s*)?(?:console\\.(?:log|warn)|logger\\.\\w+)[^}]*\\}/g);\n if (swallowEvidence.length > 0) results.push({ pattern: \"swallow\", evidence: swallowEvidence });\n\n const httpErrEvidence = extractEvidence(c, /res\\.status\\(\\d+\\)\\.json|\\.json\\(\\s*\\{[^}]*error/g);\n if (httpErrEvidence.length > 0) results.push({ pattern: \"http_error_response\", evidence: httpErrEvidence });\n\n const resultEvidence = extractEvidence(c, /Result<|Either<|\\.ok\\(|\\.err\\(/g);\n if (resultEvidence.length > 0) results.push({ pattern: \"result_type\", evidence: resultEvidence });\n } else if (file.language === \"python\") {\n const swallowEvidence = extractEvidence(c, /except[^:]*:\\s*\\n\\s*(?:pass|\\.\\.\\.)\\b/g);\n if (swallowEvidence.length > 0) results.push({ pattern: \"swallow\", evidence: swallowEvidence });\n\n const raiseEvidence = extractEvidence(c, /raise\\s+\\w+/g);\n if (raiseEvidence.length > 0) results.push({ pattern: \"exception_throw\", evidence: raiseEvidence });\n }\n\n return results;\n}\n\n// --- Config Pattern Detection ---\n\nfunction detectConfigPattern(file: DriftFile): { pattern: ConfigPattern; evidence: Evidence[] }[] {\n const results: { pattern: ConfigPattern; evidence: Evidence[] }[] = [];\n const c = file.content;\n\n const envEvidence = extractEvidence(c, /(?:process\\.env\\.\\w+|os\\.Getenv\\(|os\\.environ|import\\.meta\\.env\\.\\w+|env::var\\()/g);\n if (envEvidence.length > 0) results.push({ pattern: \"env_direct\", evidence: envEvidence });\n\n const configDI = extractEvidence(c, /\\b(?:cfg|config|settings)\\.\\w+/g);\n if (configDI.length > 0) results.push({ pattern: \"config_struct_di\", evidence: configDI });\n\n return results;\n}\n\n// --- DI Pattern Detection ---\n\nfunction detectDIPattern(file: DriftFile): { pattern: DIPattern; evidence: Evidence[] }[] {\n const results: { pattern: DIPattern; evidence: Evidence[] }[] = [];\n const c = file.content;\n\n if (file.language === \"go\") {\n const constructorEvidence = extractEvidence(c, /func\\s+New\\w+\\s*\\([^)]*\\)\\s*\\*/g);\n if (constructorEvidence.length > 0) results.push({ pattern: \"constructor_injection\", evidence: constructorEvidence });\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n const constructorEvidence = extractEvidence(c, /constructor\\s*\\([^)]*(?:private|readonly|public)\\s+\\w+/g);\n if (constructorEvidence.length > 0) results.push({ pattern: \"constructor_injection\", evidence: constructorEvidence });\n\n const factoryEvidence = extractEvidence(c, /(?:create|make|build)\\w+\\s*\\([^)]*(?:store|repo|service|client)/g);\n if (factoryEvidence.length > 0) results.push({ pattern: \"constructor_injection\", evidence: factoryEvidence });\n }\n\n return results;\n}\n\nfunction buildProfile(file: DriftFile): FileArchProfile | null {\n if (!file.language || !isHandlerOrController(file.path)) return null;\n\n const dataAccess = detectDataAccess(file);\n const errorHandling = detectErrorHandling(file);\n const config = detectConfigPattern(file);\n const di = detectDIPattern(file);\n\n // Only include files that have meaningful patterns\n if (dataAccess.length === 0 && errorHandling.length === 0) return null;\n\n return { file: file.path, language: file.language, dataAccess, errorHandling, config, di };\n}\n\nfunction detectFilePattern<T extends string>(\n patterns: { pattern: T; evidence: Evidence[] }[],\n): T | null {\n // Use the primary (most common) pattern per file\n const fileCounts = new Map<T, number>();\n for (const { pattern } of patterns) {\n fileCounts.set(pattern, (fileCounts.get(pattern) ?? 0) + 1);\n }\n let primaryPattern: T | null = null;\n let maxCount = 0;\n for (const [pat, count] of fileCounts) {\n if (count > maxCount) { maxCount = count; primaryPattern = pat; }\n }\n return primaryPattern;\n}\n\nfunction buildPatternDistribution<T extends string>(\n profiles: { file: string; patterns: { pattern: T; evidence: Evidence[] }[] }[],\n): Map<T, { count: number; files: string[] }> {\n const counts = new Map<T, { count: number; files: string[] }>();\n\n for (const p of profiles) {\n const primaryPattern = detectFilePattern(p.patterns);\n if (!primaryPattern) continue;\n\n if (!counts.has(primaryPattern)) counts.set(primaryPattern, { count: 0, files: [] });\n const entry = counts.get(primaryPattern)!;\n entry.count++;\n entry.files.push(p.file);\n }\n\n return counts;\n}\n\nfunction collectDeviatingFiles<T extends string>(\n counts: Map<T, { count: number; files: string[] }>,\n dominant: T,\n profiles: { file: string; patterns: { pattern: T; evidence: Evidence[] }[] }[],\n patternNames: Record<T, string>,\n): DeviatingFile[] {\n const deviating: DeviatingFile[] = [];\n for (const [pattern, data] of counts) {\n if (pattern === dominant) continue;\n for (const filePath of data.files) {\n const profile = profiles.find((p) => p.file === filePath);\n const evidence = profile?.patterns\n .filter((pp) => pp.pattern === pattern)\n .flatMap((pp) => pp.evidence) ?? [];\n deviating.push({\n path: filePath,\n detectedPattern: patternNames[pattern],\n evidence: evidence.slice(0, 3),\n });\n }\n }\n return deviating;\n}\n\nfunction findDominantPattern<T extends string>(\n counts: Map<T, { count: number; files: string[] }>,\n): { dominant: T; dominantCount: number } | null {\n let dominant: T | null = null;\n let dominantCount = 0;\n for (const [pattern, data] of counts) {\n if (data.count > dominantCount) { dominantCount = data.count; dominant = pattern; }\n }\n if (!dominant) return null;\n return { dominant, dominantCount };\n}\n\nfunction analyzePatternDistribution<T extends string>(\n profiles: { file: string; patterns: { pattern: T; evidence: Evidence[] }[] }[],\n patternNames: Record<T, string>,\n): DriftFinding | null {\n const counts = buildPatternDistribution(profiles);\n\n if (counts.size < 2) return null;\n\n const result = findDominantPattern(counts);\n if (!result) return null;\n\n const { dominant, dominantCount } = result;\n const totalFiles = profiles.length;\n const consistencyScore = Math.round((dominantCount / totalFiles) * 100);\n\n const deviating = collectDeviatingFiles(counts, dominant, profiles, patternNames);\n if (deviating.length === 0) return null;\n\n return {\n detector: \"architectural_consistency\",\n driftCategory: \"architectural_consistency\",\n severity: deviating.length >= 3 ? \"error\" : \"warning\",\n confidence: 0.85,\n finding: `${deviating.length} files use ${[...new Set(deviating.map((d) => d.detectedPattern))].join(\", \")} while ${dominantCount} use ${patternNames[dominant]}`,\n dominantPattern: patternNames[dominant],\n dominantCount,\n totalRelevantFiles: totalFiles,\n consistencyScore,\n deviatingFiles: deviating,\n recommendation: `${dominantCount} of ${totalFiles} files use ${patternNames[dominant]}. Migrate deviating files for consistency.`,\n };\n}\n\nconst DATA_ACCESS_NAMES: Record<DataAccessPattern, string> = {\n repository: \"repository pattern\",\n raw_sql: \"raw SQL queries\",\n orm: \"ORM methods\",\n direct_db: \"direct database calls\",\n http_client: \"inline HTTP client calls\",\n in_memory: \"in-memory data\",\n};\n\nconst ERROR_HANDLING_NAMES: Record<ErrorHandlingPattern, string> = {\n wrap_with_context: \"error wrapping with context\",\n raw_propagation: \"raw error propagation\",\n swallow: \"error swallowing\",\n http_error_response: \"direct HTTP error responses\",\n exception_throw: \"exception throwing\",\n result_type: \"Result/Either types\",\n};\n\nconst CONFIG_NAMES: Record<ConfigPattern, string> = {\n env_direct: \"direct env var access\",\n config_struct_di: \"config struct via DI\",\n hardcoded: \"hardcoded values\",\n mixed: \"mixed config approaches\",\n};\n\nconst DI_NAMES: Record<DIPattern, string> = {\n constructor_injection: \"constructor injection\",\n global_import: \"global singleton imports\",\n service_locator: \"service locator\",\n no_di: \"no dependency injection\",\n};\n\nexport const architecturalContradiction: DriftDetector = {\n id: \"architectural-contradiction\",\n name: \"Architectural Pattern Contradictions\",\n category: \"architectural_consistency\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n const findings: DriftFinding[] = [];\n const profiles: FileArchProfile[] = [];\n\n for (const file of ctx.files) {\n const p = buildProfile(file);\n if (p) profiles.push(p);\n }\n\n if (profiles.length < 2) return findings;\n\n // Analyze data access patterns\n const dataAccessProfiles = profiles\n .filter((p) => p.dataAccess.length > 0)\n .map((p) => ({ file: p.file, patterns: p.dataAccess }));\n const dataAccessFinding = analyzePatternDistribution(dataAccessProfiles, DATA_ACCESS_NAMES);\n if (dataAccessFinding) {\n dataAccessFinding.subCategory = \"data_access\";\n findings.push(dataAccessFinding);\n }\n\n // Analyze error handling patterns\n const errorProfiles = profiles\n .filter((p) => p.errorHandling.length > 0)\n .map((p) => ({ file: p.file, patterns: p.errorHandling }));\n const errorFinding = analyzePatternDistribution(errorProfiles, ERROR_HANDLING_NAMES);\n if (errorFinding) {\n errorFinding.subCategory = \"error_handling\";\n findings.push(errorFinding);\n }\n\n // Analyze config patterns (only in handler files, not config files)\n const configProfiles = profiles\n .filter((p) => p.config.length > 0)\n .map((p) => ({ file: p.file, patterns: p.config }));\n if (configProfiles.length >= 3) {\n const configFinding = analyzePatternDistribution(configProfiles, CONFIG_NAMES);\n if (configFinding) {\n configFinding.subCategory = \"configuration\";\n findings.push(configFinding);\n }\n }\n\n // Analyze DI patterns\n const diProfiles = profiles.map((p) => ({\n file: p.file,\n patterns: p.di.length > 0 ? p.di : [{ pattern: \"no_di\" as DIPattern, evidence: [] as Evidence[] }],\n }));\n if (diProfiles.length >= 3) {\n const diFinding = analyzePatternDistribution(diProfiles, DI_NAMES);\n if (diFinding) {\n diFinding.subCategory = \"dependency_injection\";\n findings.push(diFinding);\n }\n }\n\n return findings;\n },\n};\n","import type { DriftDetector, DriftContext, DriftFinding, DriftFile, DeviatingFile } from \"./types.js\";\n\ntype NamingConvention = \"camelCase\" | \"snake_case\" | \"PascalCase\" | \"SCREAMING_SNAKE\" | \"kebab-case\";\n\nfunction classifyName(name: string): NamingConvention | null {\n if (/^[A-Z][A-Z0-9_]+$/.test(name)) return \"SCREAMING_SNAKE\";\n if (/^[A-Z][a-zA-Z0-9]*$/.test(name)) return \"PascalCase\";\n if (/^[a-z][a-zA-Z0-9]*$/.test(name) && /[A-Z]/.test(name)) return \"camelCase\";\n if (/^[a-z][a-z0-9_]*$/.test(name) && name.includes(\"_\")) return \"snake_case\";\n if (/^[a-z][a-z0-9-]*$/.test(name) && name.includes(\"-\")) return \"kebab-case\";\n if (/^[a-z][a-z0-9]*$/.test(name)) return \"camelCase\"; // single-word lowercase = camelCase\n return null;\n}\n\n// Language-idiomatic exclusions: don't flag these as drift\n\nfunction isIdiomaticGo(name: string, convention: NamingConvention): boolean {\n if (convention === \"PascalCase\" && /^[A-Z]/.test(name)) return true;\n if (/^(?:HTTP|URL|ID|JSON|XML|SQL|API|DNS|TCP|UDP|IP|TLS|SSH|EOF)/.test(name)) return true;\n return false;\n}\n\nfunction isIdiomaticJsTs(name: string, convention: NamingConvention, symbolType: string): boolean {\n if (symbolType === \"class\" && convention === \"PascalCase\") return true;\n if (symbolType === \"function\" && convention === \"PascalCase\" && /^[A-Z]\\w*$/.test(name)) return true;\n return false;\n}\n\nfunction isIdiomaticPython(name: string, convention: NamingConvention, symbolType: string): boolean {\n if (symbolType === \"class\" && convention === \"PascalCase\") return true;\n if (name.startsWith(\"__\") && name.endsWith(\"__\")) return true;\n return false;\n}\n\nfunction isIdiomatic(name: string, convention: NamingConvention, symbolType: string, language: string): boolean {\n if (language === \"go\" && isIdiomaticGo(name, convention)) return true;\n if ((language === \"javascript\" || language === \"typescript\") && isIdiomaticJsTs(name, convention, symbolType)) return true;\n if (language === \"python\" && isIdiomaticPython(name, convention, symbolType)) return true;\n\n // Constants: SCREAMING_SNAKE is expected\n if (symbolType === \"constant\" && convention === \"SCREAMING_SNAKE\") return true;\n\n return false;\n}\n\ninterface SymbolInfo {\n name: string;\n convention: NamingConvention;\n symbolType: string;\n file: string;\n line: number;\n}\n\nfunction extractSymbols(file: DriftFile): SymbolInfo[] {\n const symbols: SymbolInfo[] = [];\n if (!file.language) return symbols;\n\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Functions\n const funcPatterns: { regex: RegExp; type: string }[] = [];\n if (file.language === \"go\") {\n funcPatterns.push({ regex: /func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)\\s*\\(/g, type: \"function\" });\n } else if (file.language === \"python\") {\n funcPatterns.push({ regex: /def\\s+(\\w+)\\s*\\(/g, type: \"function\" });\n funcPatterns.push({ regex: /class\\s+(\\w+)/g, type: \"class\" });\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n funcPatterns.push({ regex: /(?:async\\s+)?function\\s+(\\w+)/g, type: \"function\" });\n funcPatterns.push({ regex: /(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?(?:\\([^)]*\\)|[a-zA-Z_]\\w*)\\s*=>/g, type: \"function\" });\n funcPatterns.push({ regex: /class\\s+(\\w+)/g, type: \"class\" });\n funcPatterns.push({ regex: /interface\\s+(\\w+)/g, type: \"type\" });\n funcPatterns.push({ regex: /type\\s+(\\w+)/g, type: \"type\" });\n }\n\n for (const { regex, type } of funcPatterns) {\n const r = new RegExp(regex.source, regex.flags);\n let m;\n while ((m = r.exec(line)) !== null) {\n const name = m[1];\n if (name.length <= 1) continue;\n const conv = classifyName(name);\n if (!conv) continue;\n\n // Skip idiomatic patterns\n if (isIdiomatic(name, conv, type, file.language)) continue;\n\n symbols.push({ name, convention: conv, symbolType: type, file: file.path, line: i + 1 });\n }\n }\n }\n\n return symbols;\n}\n\nfunction classifyBaseName(filePath: string): { basename: string; convention: NamingConvention } | null {\n const basename = filePath.split(\"/\").pop()?.replace(/\\.[^.]+$/, \"\") ?? \"\";\n if (basename.length <= 1) return null;\n // Skip test files, config files\n if (/(?:test|spec|config|setup|__)/i.test(basename)) return null;\n\n const convention = classifyName(basename);\n if (!convention) return null;\n\n return { basename, convention };\n}\n\nfunction findDominantConvention(\n fileNameConventions: Map<NamingConvention, string[]>,\n): { dominant: NamingConvention; maxCount: number; totalFiles: number } | null {\n let dominant: NamingConvention | null = null;\n let maxCount = 0;\n let totalFiles = 0;\n for (const [conv, files] of fileNameConventions) {\n totalFiles += files.length;\n if (files.length > maxCount) { maxCount = files.length; dominant = conv; }\n }\n\n if (!dominant || maxCount === totalFiles) return null;\n\n return { dominant, maxCount, totalFiles };\n}\n\n// Also analyze file naming conventions\nfunction analyzeFileNaming(files: DriftFile[]): DriftFinding | null {\n const fileNameConventions = new Map<NamingConvention, string[]>();\n\n for (const file of files) {\n const classified = classifyBaseName(file.path);\n if (!classified) continue;\n\n if (!fileNameConventions.has(classified.convention)) fileNameConventions.set(classified.convention, []);\n fileNameConventions.get(classified.convention)!.push(file.path);\n }\n\n if (fileNameConventions.size < 2) return null;\n\n const result = findDominantConvention(fileNameConventions);\n if (!result) return null;\n\n const { dominant, maxCount, totalFiles } = result;\n\n const deviating: DeviatingFile[] = [];\n for (const [conv, filePaths] of fileNameConventions) {\n if (conv === dominant) continue;\n for (const fp of filePaths) {\n deviating.push({ path: fp, detectedPattern: conv, evidence: [] });\n }\n }\n\n if (deviating.length < 2) return null;\n\n return {\n detector: \"naming_conventions\",\n subCategory: \"file_names\",\n driftCategory: \"naming_conventions\",\n severity: \"warning\",\n confidence: 0.75,\n finding: `File naming convention oscillates: ${dominant} dominant (${maxCount}/${totalFiles}), ${deviating.length} files deviate`,\n dominantPattern: dominant,\n dominantCount: maxCount,\n totalRelevantFiles: totalFiles,\n consistencyScore: Math.round((maxCount / totalFiles) * 100),\n deviatingFiles: deviating.slice(0, 10),\n recommendation: `Standardize file names to ${dominant}. ${deviating.length} files use a different convention.`,\n };\n}\n\nfunction collectDeviantFiles(\n convCounts: Map<NamingConvention, SymbolInfo[]>,\n dominant: NamingConvention,\n): DeviatingFile[] {\n const fileDeviants = new Map<string, SymbolInfo[]>();\n for (const [conv, syms] of convCounts) {\n if (conv === dominant) continue;\n for (const s of syms) {\n if (!fileDeviants.has(s.file)) fileDeviants.set(s.file, []);\n fileDeviants.get(s.file)!.push(s);\n }\n }\n\n const deviatingFiles: DeviatingFile[] = [];\n for (const [filePath, syms] of fileDeviants) {\n const uniqueConventions = [...new Set(syms.map((s) => s.convention))];\n deviatingFiles.push({\n path: filePath,\n detectedPattern: uniqueConventions.join(\", \"),\n evidence: syms.slice(0, 3).map((s) => ({ line: s.line, code: s.name })),\n });\n }\n return deviatingFiles;\n}\n\nfunction buildConventionFinding(\n type: string,\n dominant: NamingConvention,\n maxCount: number,\n totalSymbols: number,\n deviatingFiles: DeviatingFile[],\n): DriftFinding {\n const deviantCount = totalSymbols - maxCount;\n const consistencyScore = Math.round((maxCount / totalSymbols) * 100);\n return {\n detector: \"naming_conventions\",\n subCategory: `${type}_names`,\n driftCategory: \"naming_conventions\",\n severity: deviatingFiles.length > 5 ? \"error\" : \"warning\",\n confidence: 0.8,\n finding: `${type} naming convention oscillates: ${maxCount} use ${dominant}, ${deviantCount} use other conventions — likely from different AI sessions`,\n dominantPattern: dominant,\n dominantCount: maxCount,\n totalRelevantFiles: totalSymbols,\n consistencyScore,\n deviatingFiles: deviatingFiles.slice(0, 10),\n recommendation: `${maxCount} of ${totalSymbols} ${type} names use ${dominant}. Standardize deviating names.`,\n };\n}\n\nfunction analyzeSymbolTypeConventions(\n type: string,\n typeSymbols: SymbolInfo[],\n): DriftFinding | null {\n if (typeSymbols.length < 3) return null;\n\n const convCounts = new Map<NamingConvention, SymbolInfo[]>();\n for (const s of typeSymbols) {\n if (!convCounts.has(s.convention)) convCounts.set(s.convention, []);\n convCounts.get(s.convention)!.push(s);\n }\n\n if (convCounts.size < 2) return null;\n\n let dominant: NamingConvention | null = null;\n let maxCount = 0;\n for (const [conv, syms] of convCounts) {\n if (syms.length > maxCount) { maxCount = syms.length; dominant = conv; }\n }\n\n if (!dominant) return null;\n\n const totalSymbols = typeSymbols.length;\n const deviantCount = totalSymbols - maxCount;\n if (deviantCount < 3 || deviantCount / totalSymbols < 0.1) return null;\n\n const deviatingFiles = collectDeviantFiles(convCounts, dominant);\n if (deviatingFiles.length < 2) return null;\n\n return buildConventionFinding(type, dominant, maxCount, totalSymbols, deviatingFiles);\n}\n\nexport const conventionOscillation: DriftDetector = {\n id: \"convention-oscillation\",\n name: \"Naming Convention Oscillation\",\n category: \"naming_conventions\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n const findings: DriftFinding[] = [];\n\n const allSymbols: SymbolInfo[] = [];\n for (const file of ctx.files) {\n allSymbols.push(...extractSymbols(file));\n }\n\n if (allSymbols.length < 5) return findings;\n\n const symbolTypes = [...new Set(allSymbols.map((s) => s.symbolType))];\n\n for (const type of symbolTypes) {\n const typeSymbols = allSymbols.filter((s) => s.symbolType === type);\n const finding = analyzeSymbolTypeConventions(type, typeSymbols);\n if (finding) findings.push(finding);\n }\n\n const fileNaming = analyzeFileNaming(ctx.files);\n if (fileNaming) findings.push(fileNaming);\n\n return findings;\n },\n};\n","/**\n * Route-level security posture drift detection.\n *\n * Extracts HTTP routes from Express, Echo, Gorilla, Flask, and FastAPI codebases,\n * then checks whether security properties (auth, validation, rate-limiting) are\n * applied consistently. Routes that lack a property the majority has are flagged\n * as accidental drift from the project's established security posture.\n */\n\nimport type { DriftDetector, DriftContext, DriftFinding, DriftFile, DeviatingFile } from \"./types.js\";\n\ninterface RouteInfo {\n method: string;\n path: string;\n file: string;\n line: number;\n hasAuth: boolean;\n hasValidation: boolean;\n hasRateLimit: boolean;\n hasErrorHandler: boolean;\n}\n\nfunction extractRoutes(files: DriftFile[]): RouteInfo[] {\n const routes: RouteInfo[] = [];\n\n for (const file of files) {\n if (!file.language) continue;\n if (file.language === \"go\") extractGoRoutes(file, routes);\n else if (file.language === \"javascript\" || file.language === \"typescript\") extractJsRoutes(file, routes);\n else if (file.language === \"python\") extractPythonRoutes(file, routes);\n }\n\n return routes;\n}\n\nfunction extractGoRoutes(file: DriftFile, routes: RouteInfo[]) {\n const lines = file.content.split(\"\\n\");\n const echoPattern = /\\.\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\s*\\(\\s*\"([^\"]+)\"/;\n const gorillaPattern = /HandleFunc\\s*\\(\\s*\"([^\"]+)\".*\\.Methods\\s*\\(\\s*\"(\\w+)\"/;\n const hasGroupAuth = /\\.Use\\s*\\(\\s*\\w*[Aa]uth/.test(file.content);\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let method = \"\", path = \"\";\n\n const echoMatch = line.match(echoPattern);\n if (echoMatch) { method = echoMatch[1]; path = echoMatch[2]; }\n const gorillaMatch = line.match(gorillaPattern);\n if (gorillaMatch) { path = gorillaMatch[1]; method = gorillaMatch[2]; }\n\n if (!method || !path) continue;\n\n const context = lines.slice(Math.max(0, i - 10), i + 10).join(\"\\n\");\n const handlerContent = findHandlerContent(file.content, path);\n\n routes.push({\n method, path, file: file.path, line: i + 1,\n hasAuth: hasGroupAuth || /[Aa]uth|[Tt]oken|require[A-Z]|middleware\\.\\w*[Aa]uth/.test(context),\n hasValidation: /[Bb]ind|[Vv]alidat|[Pp]arse/.test(handlerContent),\n hasRateLimit: /[Rr]ate[Ll]imit|[Tt]hrottle/.test(context + handlerContent),\n hasErrorHandler: /catch|err\\s*!=\\s*nil|try|except|\\.catch/.test(handlerContent),\n });\n }\n}\n\nfunction extractJsRoutes(file: DriftFile, routes: RouteInfo[]) {\n const lines = file.content.split(\"\\n\");\n const expressPattern = /\\.(?:get|post|put|patch|delete|all)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/;\n const hasGroupAuth = /\\.use\\s*\\(\\s*\\w*[Aa]uth/.test(file.content);\n\n for (let i = 0; i < lines.length; i++) {\n const match = lines[i].match(expressPattern);\n if (!match) continue;\n const path = match[1];\n const method = match[0].match(/\\.(get|post|put|patch|delete|all)/)?.[1]?.toUpperCase() ?? \"ANY\";\n const context = lines.slice(Math.max(0, i - 5), i + 20).join(\"\\n\");\n\n routes.push({\n method, path, file: file.path, line: i + 1,\n hasAuth: hasGroupAuth || /auth|[Tt]oken|passport|requireAuth|isAuthenticated/.test(context),\n hasValidation: /validate|joi|zod|yup|celebrate|body\\(|query\\(/.test(context),\n hasRateLimit: /rateLimit|throttle|limiter/.test(context),\n hasErrorHandler: /catch|try|\\.catch|next\\(err/.test(context),\n });\n }\n}\n\nfunction extractPythonRoutes(file: DriftFile, routes: RouteInfo[]) {\n const lines = file.content.split(\"\\n\");\n const routePattern = /@\\w+\\.(?:route|get|post|put|patch|delete)\\s*\\(\\s*['\"]([^'\"]+)['\"]/;\n\n for (let i = 0; i < lines.length; i++) {\n const match = lines[i].match(routePattern);\n if (!match) continue;\n const path = match[1];\n const method = lines[i].match(/\\.(get|post|put|patch|delete)/)?.[1]?.toUpperCase() ?? \"ANY\";\n const context = lines.slice(i, Math.min(lines.length, i + 30)).join(\"\\n\");\n const nextDef = lines.slice(i + 1, i + 5).find((l) => /def\\s+(\\w+)/.test(l.trim()));\n const handlerName = nextDef?.match(/def\\s+(\\w+)/)?.[1] ?? \"anonymous\";\n\n routes.push({\n method, path, file: file.path, line: i + 1,\n hasAuth: /login_required|auth|token|permission|jwt|@requires/.test(context),\n hasValidation: /pydantic|validate|Schema|Serializer/.test(context),\n hasRateLimit: /rate_limit|throttle|limiter/.test(context),\n hasErrorHandler: /try|except|raise/.test(context),\n });\n }\n}\n\n// Grab a ~2.5KB window around the route registration to catch the handler body,\n// since the handler is usually defined near (or inline with) the route path string\nfunction findHandlerContent(fullContent: string, routePath: string): string {\n const idx = fullContent.indexOf(routePath);\n if (idx === -1) return \"\";\n return fullContent.slice(Math.max(0, idx - 500), Math.min(fullContent.length, idx + 2000));\n}\n\nfunction analyzeSecurityProperty(\n routes: RouteInfo[],\n propertyName: string,\n getter: (r: RouteInfo) => boolean,\n excludePaths: RegExp,\n): DriftFinding | null {\n const applicableRoutes = routes.filter((r) => !excludePaths.test(r.path));\n if (applicableRoutes.length < 2) return null;\n\n const withProperty = applicableRoutes.filter(getter);\n const withoutProperty = applicableRoutes.filter((r) => !getter(r));\n const ratio = withProperty.length / applicableRoutes.length;\n\n // Only flag if strong majority (>75%) have it — 60% was too low and\n // flagged legitimate mixed public/private APIs as drift\n if (ratio <= 0.75 || withoutProperty.length === 0) return null;\n\n return {\n detector: \"security_posture\",\n subCategory: propertyName,\n driftCategory: \"security_posture\",\n severity: withoutProperty.length > 2 ? \"error\" : \"warning\",\n confidence: 0.75,\n finding: `${propertyName} missing on ${withoutProperty.length} of ${applicableRoutes.length} routes`,\n dominantPattern: `${propertyName} applied`,\n dominantCount: withProperty.length,\n totalRelevantFiles: applicableRoutes.length,\n consistencyScore: Math.round(ratio * 100),\n deviatingFiles: withoutProperty.map((r) => ({\n path: r.file,\n detectedPattern: `${r.method} ${r.path} — no ${propertyName}`,\n evidence: [{ line: r.line, code: `${r.method} ${r.path}` }],\n })),\n recommendation: `${withProperty.length} of ${applicableRoutes.length} routes have ${propertyName}. Review ${withoutProperty.length} unprotected routes — likely built in a session where ${propertyName} wasn't discussed.`,\n };\n}\n\nexport const securityConsistency: DriftDetector = {\n id: \"security-consistency\",\n name: \"Security Posture Consistency\",\n category: \"security_posture\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n const findings: DriftFinding[] = [];\n const routes = extractRoutes(ctx.files);\n\n if (routes.length < 2) return findings;\n\n const healthPaths = /^\\/(?:health|healthz|ready|metrics|ping)$/;\n\n const authFinding = analyzeSecurityProperty(routes, \"Auth middleware\", (r) => r.hasAuth, healthPaths);\n if (authFinding) findings.push(authFinding);\n\n // Input validation only matters for state-changing methods (POST/PUT/PATCH);\n // GETs legitimately skip validation in most APIs\n const mutationRoutes = routes.filter((r) => [\"POST\", \"PUT\", \"PATCH\"].includes(r.method));\n if (mutationRoutes.length >= 2) {\n const valFinding = analyzeSecurityProperty(mutationRoutes, \"Input validation\", (r) => r.hasValidation, healthPaths);\n if (valFinding) findings.push(valFinding);\n }\n\n const rateLimitFinding = analyzeSecurityProperty(routes, \"Rate limiting\", (r) => r.hasRateLimit, healthPaths);\n if (rateLimitFinding) findings.push(rateLimitFinding);\n\n return findings;\n },\n};\n","import type { DriftDetector, DriftContext, DriftFinding, DriftFile, Evidence, DeviatingFile } from \"./types.js\";\nimport { extractFunctionsFromFile } from \"../codedna/function-extractor.js\";\nimport type { ExtractedFunction } from \"../codedna/types.js\";\n\n// Adapter: convert ExtractedFunction → FunctionSignature for backward compat\ninterface FunctionSignature {\n name: string;\n file: string;\n line: number;\n paramCount: number;\n declarationCode: string;\n bodySnippet: string;\n domainCategory: string;\n bodyTokenCount: number;\n bodyHash: number;\n}\n\nfunction toFunctionSignature(ef: ExtractedFunction): FunctionSignature {\n return {\n name: ef.name,\n file: ef.file,\n line: ef.line,\n paramCount: ef.paramCount,\n declarationCode: ef.declarationCode,\n bodySnippet: ef.rawBody.slice(0, 200),\n domainCategory: ef.domainCategory,\n bodyTokenCount: ef.bodyTokenCount,\n bodyHash: ef.bodyHash,\n };\n}\n\nfunction extractFunctions(file: DriftFile): FunctionSignature[] {\n // DriftFile.path is actually relativePath; adapt for shared extractor\n const sourceFile = {\n path: file.path,\n relativePath: file.path,\n language: file.language as any,\n content: file.content,\n lineCount: file.lineCount,\n };\n const extracted = extractFunctionsFromFile(sourceFile);\n return extracted.map(toFunctionSignature);\n}\n\n// Names that are framework conventions / interface methods — NOT duplicates\nconst CONVENTION_NAMES = new Set([\n \"registerroutes\", \"register\", \"routes\", \"setup\", \"init\", \"initialize\",\n \"close\", \"shutdown\", \"start\", \"stop\", \"run\", \"main\", \"new\", \"string\",\n \"error\", \"serve\", \"listen\", \"handle\", \"middleware\", \"mount\",\n \"marshal\", \"unmarshal\", \"serialize\", \"deserialize\",\n \"validate\", \"reset\", \"clone\", \"equals\", \"hash\", \"compare\",\n]);\n\n// Detect interface+implementation pairs (same name, one in interface/abstract file)\nfunction isInterfaceImplPair(a: FunctionSignature, b: FunctionSignature): boolean {\n const aIsInterface = /(?:interface|store|contract|abstract|base|types)\\./i.test(a.file) || a.bodyTokenCount < 10;\n const bIsInterface = /(?:interface|store|contract|abstract|base|types)\\./i.test(b.file) || b.bodyTokenCount < 10;\n // One is interface, other is implementation\n return (aIsInterface && !bIsInterface) || (!aIsInterface && bIsInterface);\n}\n\n// Check if a function name is a framework/interface convention\nfunction isConventionalName(name: string): boolean {\n return CONVENTION_NAMES.has(name.toLowerCase());\n}\n\n// Check if two functions have structurally similar signatures\nfunction areStructurallySimilar(a: FunctionSignature, b: FunctionSignature): boolean {\n if (a.domainCategory !== b.domainCategory || a.domainCategory === \"general\") return false;\n if (a.file === b.file) return false;\n if (Math.abs(a.paramCount - b.paramCount) > 1) return false;\n const sizeRatio = Math.min(a.bodyTokenCount, b.bodyTokenCount) / Math.max(a.bodyTokenCount, b.bodyTokenCount);\n return sizeRatio >= 0.4;\n}\n\n// Check if two function names are similar enough to be duplicates\nfunction areNamesSimilar(nameA: string, nameB: string, hashA: number, hashB: number, tokenCountA: number): boolean {\n if (nameA === nameB) return true;\n if (nameA.length >= 6 && nameB.length >= 6 && levenshtein(nameA, nameB) <= 3) return true;\n if (hashA === hashB && tokenCountA > 20) return true;\n return false;\n}\n\n// Check if two functions are in a handler/repo layer pair (intentional architecture)\nfunction isLayerPair(a: FunctionSignature, b: FunctionSignature): boolean {\n const aIsRepo = /(?:repository|repo|store|postgres|mysql|mongo|dal)/i.test(a.file);\n const bIsRepo = /(?:repository|repo|store|postgres|mysql|mongo|dal)/i.test(b.file);\n const aIsHandler = /(?:handler|controller|route|endpoint|api)/i.test(a.file);\n const bIsHandler = /(?:handler|controller|route|endpoint|api)/i.test(b.file);\n\n if ((aIsHandler && bIsRepo) || (aIsRepo && bIsHandler)) return true;\n\n const nameA = a.name.toLowerCase();\n const nameB = b.name.toLowerCase();\n\n if (nameA === nameB && a.paramCount === b.paramCount) {\n if (aIsHandler && bIsHandler) return true;\n if (aIsRepo && bIsRepo) return true;\n }\n return false;\n}\n\n// Compare two function signatures for semantic similarity\nfunction areSemanticallySimlar(a: FunctionSignature, b: FunctionSignature): boolean {\n if (!areStructurallySimilar(a, b)) return false;\n\n const nameA = a.name.toLowerCase();\n const nameB = b.name.toLowerCase();\n\n if (isConventionalName(nameA) || isConventionalName(nameB)) return false;\n\n // Exclude common handler names that are EXPECTED to have same signature\n if (nameA === nameB && /(?:handler|controller|resource|api)/i.test(a.file) && /(?:handler|controller|resource|api)/i.test(b.file)) {\n if ([\"list\", \"get\", \"create\", \"update\", \"delete\", \"find\", \"search\"].includes(nameA)) return false;\n }\n\n if (nameA === nameB && isInterfaceImplPair(a, b)) return false;\n if (isLayerPair(a, b)) return false;\n\n return areNamesSimilar(nameA, nameB, a.bodyHash, b.bodyHash, a.bodyTokenCount);\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length, n = b.length;\n if (m === 0) return n;\n if (n === 0) return m;\n const dp: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\n// Detect inline code that duplicates an existing utility function\nfunction detectInlineDuplicates(\n utilFunctions: FunctionSignature[],\n allFiles: DriftFile[],\n): DriftFinding[] {\n const findings: DriftFinding[] = [];\n\n // Build a map of utility function \"operations\" by keywords\n for (const util of utilFunctions) {\n const keywords = extractOperationKeywords(util.bodySnippet);\n if (keywords.length < 2) continue;\n\n // Search other files for inline code with the same keywords\n for (const file of allFiles) {\n if (file.path === util.file) continue;\n if (!file.language) continue;\n\n // Check if this file does NOT import from the utility file\n const utilModule = util.file.replace(/\\.[^.]+$/, \"\");\n if (file.content.includes(utilModule)) continue; // Already imports it\n\n // Look for inline code with similar operations\n const inlineMatches = findInlineOperations(file.content, keywords);\n if (inlineMatches.length === 0) continue;\n\n for (const inlineMatch of inlineMatches) {\n findings.push({\n detector: \"semantic_duplication\",\n driftCategory: \"semantic_duplication\",\n severity: \"warning\",\n confidence: 0.65,\n finding: `Inline ${util.domainCategory} logic in ${file.path} duplicates ${util.name}() in ${util.file}`,\n dominantPattern: `Utility function ${util.name}()`,\n dominantCount: 1,\n totalRelevantFiles: 2,\n consistencyScore: 50,\n deviatingFiles: [{\n path: file.path,\n detectedPattern: `inline ${util.domainCategory} code`,\n evidence: [{ line: inlineMatch.line, code: inlineMatch.code }],\n }],\n recommendation: `Replace inline ${util.domainCategory} logic at ${file.path}:${inlineMatch.line} with a call to ${util.name}() from ${util.file}.`,\n });\n }\n }\n }\n\n return findings;\n}\n\nfunction extractOperationKeywords(body: string): string[] {\n const keywords: string[] = [];\n if (/toFixed|toLocaleString/i.test(body)) keywords.push(\"number_format\");\n if (/\\$|currency|usd|eur/i.test(body)) keywords.push(\"currency\");\n if (/toISOString|getFullYear|getMonth|moment/i.test(body)) keywords.push(\"date_format\");\n if (/toLowerCase|toUpperCase|trim|replace|split|join/i.test(body)) keywords.push(\"string_transform\");\n if (/parseInt|parseFloat|Number\\(/i.test(body)) keywords.push(\"number_parse\");\n if (/JSON\\.parse|JSON\\.stringify/i.test(body)) keywords.push(\"json_serialize\");\n if (/encodeURI|decodeURI|btoa|atob/i.test(body)) keywords.push(\"encoding\");\n return keywords;\n}\n\nfunction findInlineOperations(content: string, keywords: string[]): { line: number; code: string }[] {\n const results: { line: number; code: string }[] = [];\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let matchCount = 0;\n for (const kw of keywords) {\n if (kw === \"number_format\" && /toFixed|toLocaleString/i.test(line)) matchCount++;\n if (kw === \"currency\" && /\\$|currency/i.test(line) && /toFixed/i.test(line)) matchCount++;\n if (kw === \"date_format\" && /toISOString|getFullYear|format/i.test(line)) matchCount++;\n if (kw === \"string_transform\" && /replace|split|join/i.test(line)) matchCount++;\n }\n if (matchCount >= 2) {\n results.push({ line: i + 1, code: line.trim().slice(0, 100) });\n }\n }\n\n return results.slice(0, 3);\n}\n\nexport const semanticDuplication: DriftDetector = {\n id: \"semantic-duplication\",\n name: \"Semantic Duplication\",\n category: \"semantic_duplication\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n const findings: DriftFinding[] = [];\n\n // Extract all functions\n const allFunctions: FunctionSignature[] = [];\n for (const file of ctx.files) {\n allFunctions.push(...extractFunctions(file));\n }\n\n if (allFunctions.length < 3) return findings;\n\n // Group by domain category\n const byDomain = new Map<string, FunctionSignature[]>();\n for (const fn of allFunctions) {\n if (fn.domainCategory === \"general\" || fn.domainCategory === \"request_handling\") continue;\n if (!byDomain.has(fn.domainCategory)) byDomain.set(fn.domainCategory, []);\n byDomain.get(fn.domainCategory)!.push(fn);\n }\n\n // Within each domain, find semantic duplicates\n for (const [domain, functions] of byDomain) {\n if (functions.length < 2) continue;\n\n const pairs: { a: FunctionSignature; b: FunctionSignature }[] = [];\n for (let i = 0; i < functions.length; i++) {\n for (let j = i + 1; j < functions.length; j++) {\n if (areSemanticallySimlar(functions[i], functions[j])) {\n pairs.push({ a: functions[i], b: functions[j] });\n }\n }\n }\n\n // Deduplicate\n const seenKeys = new Set<string>();\n for (const pair of pairs) {\n const key = [pair.a.file + \":\" + pair.a.name, pair.b.file + \":\" + pair.b.name].sort().join(\"|\");\n if (seenKeys.has(key)) continue;\n seenKeys.add(key);\n\n findings.push({\n detector: \"semantic_duplication\",\n subCategory: domain,\n driftCategory: \"semantic_duplication\",\n severity: \"error\",\n confidence: 0.75,\n finding: `Duplicate ${domain.replace(/_/g, \" \")} logic: ${pair.a.name}() in ${pair.a.file} and ${pair.b.name}() in ${pair.b.file}`,\n dominantPattern: `${pair.a.name}()`,\n dominantCount: 1,\n totalRelevantFiles: 2,\n consistencyScore: 50,\n deviatingFiles: [\n {\n path: pair.a.file,\n detectedPattern: `${pair.a.name}(${pair.a.paramCount} params)`,\n evidence: [{ line: pair.a.line, code: pair.a.declarationCode || pair.a.name + \"()\" }],\n },\n {\n path: pair.b.file,\n detectedPattern: `${pair.b.name}(${pair.b.paramCount} params)`,\n evidence: [{ line: pair.b.line, code: pair.b.declarationCode || pair.b.name + \"()\" }],\n },\n ],\n recommendation: `Extract shared ${domain.replace(/_/g, \" \")} logic into a single utility function. Both ${pair.a.name}() and ${pair.b.name}() appear to do the same thing.`,\n });\n }\n }\n\n // Also check for inline code duplicating utility functions\n const utilFiles = ctx.files.filter((f) => /(?:util|helper|lib|common|shared)/i.test(f.path));\n const utilFunctions = allFunctions.filter((fn) => /(?:util|helper|lib|common|shared)/i.test(fn.file));\n if (utilFunctions.length > 0) {\n findings.push(...detectInlineDuplicates(utilFunctions, ctx.files));\n }\n\n return findings;\n },\n};\n","import type { DriftDetector, DriftContext, DriftFinding, DriftFile, Evidence, DeviatingFile } from \"./types.js\";\n\ninterface ExportedFunction {\n name: string;\n file: string;\n line: number;\n crudType: \"create\" | \"read\" | \"update\" | \"delete\" | \"list\" | \"other\";\n}\n\ninterface RouteRegistration {\n method: string;\n path: string;\n handlerName: string;\n file: string;\n line: number;\n}\n\n// Classify function by CRUD type based on name\nfunction classifyCRUD(name: string): ExportedFunction[\"crudType\"] {\n const lower = name.toLowerCase();\n if (/^(?:create|add|insert|new|post|register|store|save)/.test(lower)) return \"create\";\n if (/^(?:get|find|fetch|read|load|retrieve|show|detail)/.test(lower)) return \"read\";\n if (/^(?:list|search|browse|index|all|query|paginate)/.test(lower)) return \"list\";\n if (/^(?:update|edit|modify|patch|change|set|put)/.test(lower)) return \"update\";\n if (/^(?:delete|remove|destroy|revoke|drop|unregister|purge)/.test(lower)) return \"delete\";\n return \"other\";\n}\n\nfunction extractExportedFunctions(file: DriftFile): ExportedFunction[] {\n const functions: ExportedFunction[] = [];\n if (!file.language) return functions;\n\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let name: string | null = null;\n\n if (file.language === \"go\") {\n // Exported Go functions: func Name( or func (recv) Name(\n const m = line.match(/^func\\s+(?:\\([^)]*\\)\\s+)?([A-Z]\\w+)\\s*\\(/);\n if (m) name = m[1];\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n const m = line.match(/export\\s+(?:async\\s+)?(?:function|const|class)\\s+(\\w+)/);\n if (m) name = m[1];\n } else if (file.language === \"python\") {\n // Non-private functions at module level\n const m = line.match(/^def\\s+(\\w+)\\s*\\(/);\n if (m && !m[1].startsWith(\"_\")) name = m[1];\n } else if (file.language === \"rust\") {\n const m = line.match(/^pub\\s+(?:async\\s+)?fn\\s+(\\w+)/);\n if (m) name = m[1];\n }\n\n if (name) {\n functions.push({\n name,\n file: file.path,\n line: i + 1,\n crudType: classifyCRUD(name),\n });\n }\n }\n\n return functions;\n}\n\nfunction extractRouteRegistrations(file: DriftFile): RouteRegistration[] {\n const routes: RouteRegistration[] = [];\n if (!file.language) return routes;\n\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Go Echo: .GET(\"/path\", handler) or .POST(\"/path\", handler.Method)\n const echoMatch = line.match(/\\.\\s*(GET|POST|PUT|PATCH|DELETE)\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*(\\w+(?:\\.\\w+)?)/);\n if (echoMatch) {\n routes.push({ method: echoMatch[1], path: echoMatch[2], handlerName: echoMatch[3], file: file.path, line: i + 1 });\n continue;\n }\n\n // Go Gorilla mux: HandleFunc(\"/path\", handler).Methods(\"GET\")\n const gorillaMatch = line.match(/HandleFunc\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*(\\w+(?:\\.\\w+)?)\\)/);\n if (gorillaMatch) {\n const methodMatch = lines.slice(i, i + 2).join(\"\").match(/Methods\\s*\\(\\s*\"(\\w+)\"/);\n routes.push({ method: methodMatch?.[1] ?? \"ANY\", path: gorillaMatch[1], handlerName: gorillaMatch[2], file: file.path, line: i + 1 });\n continue;\n }\n\n // JS/TS Express: app.get('/path', handler) or router.post('/path', handler)\n const expressMatch = line.match(/\\.\\s*(get|post|put|patch|delete)\\s*\\(\\s*['\"]([^'\"]+)['\"](?:\\s*,\\s*(\\w+))?/);\n if (expressMatch) {\n routes.push({ method: expressMatch[1].toUpperCase(), path: expressMatch[2], handlerName: expressMatch[3] ?? \"anonymous\", file: file.path, line: i + 1 });\n continue;\n }\n\n // Python Flask/FastAPI: @app.get('/path') or @router.post('/path')\n const pyMatch = line.match(/@\\w+\\.\\s*(get|post|put|patch|delete)\\s*\\(\\s*['\"]([^'\"]+)['\"]/);\n if (pyMatch) {\n // Next def is the handler\n const nextDef = lines.slice(i + 1, i + 5).find((l) => /^(?:async\\s+)?def\\s+(\\w+)/.test(l.trim()));\n const handlerName = nextDef?.match(/def\\s+(\\w+)/)?.[1] ?? \"anonymous\";\n routes.push({ method: pyMatch[1].toUpperCase(), path: pyMatch[2], handlerName, file: file.path, line: i + 1 });\n }\n }\n\n return routes;\n}\n\nfunction buildUsageGraph(files: DriftFile[]): Map<string, Set<string>> {\n // Map: symbol name → set of files that reference it\n const usage = new Map<string, Set<string>>();\n\n const allContent = files.map((f) => ({ path: f.path, content: f.content }));\n\n for (const file of allContent) {\n // Find all identifiers used in this file\n const identifiers = file.content.match(/\\b[A-Z]\\w+\\b/g) ?? [];\n for (const id of identifiers) {\n if (!usage.has(id)) usage.set(id, new Set());\n usage.get(id)!.add(file.path);\n }\n }\n\n return usage;\n}\n\nfunction isReferencedExternally(\n name: string,\n usage: Map<string, Set<string>>,\n currentFile: string,\n allRoutes: RouteRegistration[],\n): boolean {\n const references = usage.get(name);\n // A function is \"used\" if referenced from a different file\n const usedExternally = references && [...references].some((f) => f !== currentFile);\n\n // Also check if it's in a route registration\n const isRouted = allRoutes.some((r) =>\n r.handlerName.includes(name) || r.handlerName.endsWith(\".\" + name),\n );\n\n return !!(usedExternally || isRouted);\n}\n\nfunction detectScaffoldingPattern(\n filePath: string,\n crudFunctions: ExportedFunction[],\n usage: Map<string, Set<string>>,\n allRoutes: RouteRegistration[],\n): DriftFinding | null {\n const usedFunctions: ExportedFunction[] = [];\n const unusedFunctions: ExportedFunction[] = [];\n\n for (const fn of crudFunctions) {\n if (isReferencedExternally(fn.name, usage, filePath, allRoutes)) {\n usedFunctions.push(fn);\n } else {\n unusedFunctions.push(fn);\n }\n }\n\n // Only flag if there's a GROUP of unused CRUD functions (not individual)\n if (unusedFunctions.length < 2 || usedFunctions.length < 1) return null;\n\n const usedTypes = usedFunctions.map((f) => f.crudType);\n const unusedTypes = unusedFunctions.map((f) => f.crudType);\n\n // Classic scaffolding: Read is used, Create/Update/Delete are not\n const isScaffoldingLike =\n usedTypes.some((t) => t === \"read\" || t === \"list\") &&\n unusedTypes.some((t) => t === \"create\" || t === \"update\" || t === \"delete\");\n\n return {\n detector: \"phantom_scaffolding\",\n driftCategory: \"phantom_scaffolding\",\n severity: isScaffoldingLike ? \"warning\" : \"info\",\n confidence: isScaffoldingLike ? 0.8 : 0.6,\n finding: `CRUD scaffolding detected in ${filePath} — ${usedFunctions.length} functions used, ${unusedFunctions.length} appear unused`,\n dominantPattern: \"used CRUD operations\",\n dominantCount: usedFunctions.length,\n totalRelevantFiles: usedFunctions.length + unusedFunctions.length,\n consistencyScore: Math.round((usedFunctions.length / (usedFunctions.length + unusedFunctions.length)) * 100),\n deviatingFiles: [{\n path: filePath,\n detectedPattern: `unused: ${unusedFunctions.map((f) => f.name).join(\", \")}`,\n evidence: unusedFunctions.slice(0, 5).map((f) => ({\n line: f.line,\n code: `${f.name} (${f.crudType}) — defined but not routed or imported`,\n })),\n }],\n recommendation: `${unusedFunctions.map((f) => f.name).join(\", \")} are defined in ${filePath.split(\"/\").pop()} but never registered in routes or called externally. This looks like AI-generated CRUD scaffolding — remove unused handlers or wire them to routes.`,\n };\n}\n\nfunction detectUnroutedHandlers(\n allExports: ExportedFunction[],\n allRoutes: RouteRegistration[],\n usage: Map<string, Set<string>>,\n): DriftFinding[] {\n const findings: DriftFinding[] = [];\n\n // Find handler files that have CRUD functions\n const handlerFiles = new Map<string, ExportedFunction[]>();\n for (const exp of allExports) {\n if (exp.crudType === \"other\") continue;\n if (!handlerFiles.has(exp.file)) handlerFiles.set(exp.file, []);\n handlerFiles.get(exp.file)!.push(exp);\n }\n\n // For each handler file with CRUD functions, check which are actually used\n for (const [filePath, functions] of handlerFiles) {\n const crudFunctions = functions.filter((f) => f.crudType !== \"other\");\n if (crudFunctions.length < 2) continue; // Need at least 2 CRUD operations to detect scaffolding\n\n const finding = detectScaffoldingPattern(filePath, crudFunctions, usage, allRoutes);\n if (finding) findings.push(finding);\n }\n\n return findings;\n}\n\nfunction extractTypeDefinitions(\n files: DriftFile[],\n): { name: string; file: string; line: number }[] {\n const typeDefinitions: { name: string; file: string; line: number }[] = [];\n\n // In Go, types used as method receivers are NOT unused — find them\n const goMethodReceivers = new Set<string>();\n for (const file of files) {\n if (file.language !== \"go\") continue;\n const receiverPattern = /func\\s+\\(\\s*\\w+\\s+\\*?(\\w+)\\s*\\)/g;\n let m;\n while ((m = receiverPattern.exec(file.content)) !== null) {\n goMethodReceivers.add(m[1]);\n }\n }\n\n for (const file of files) {\n if (!file.language) continue;\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let typeName: string | null = null;\n\n if (file.language === \"go\") {\n const m = line.match(/^type\\s+([A-Z]\\w+)\\s+struct\\b/);\n if (m) typeName = m[1];\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n const m = line.match(/export\\s+(?:interface|type|class)\\s+(\\w+)/);\n if (m) typeName = m[1];\n }\n\n if (!typeName) continue;\n if (file.language === \"go\" && goMethodReceivers.has(typeName)) continue;\n if (/(?:Request|Response|Params|Config|Options|Input|Output|Payload|Body|DTO)$/i.test(typeName)) continue;\n\n typeDefinitions.push({ name: typeName, file: file.path, line: i + 1 });\n }\n }\n\n return typeDefinitions;\n}\n\nfunction findUnusedTypes(\n typeDefinitions: { name: string; file: string; line: number }[],\n usage: Map<string, Set<string>>,\n): Map<string, { name: string; line: number }[]> {\n const unusedTypesByFile = new Map<string, { name: string; line: number }[]>();\n for (const td of typeDefinitions) {\n const refs = usage.get(td.name);\n const usedExternally = refs && [...refs].some((f) => f !== td.file);\n if (!usedExternally) {\n if (!unusedTypesByFile.has(td.file)) unusedTypesByFile.set(td.file, []);\n unusedTypesByFile.get(td.file)!.push(td);\n }\n }\n return unusedTypesByFile;\n}\n\nfunction detectUnusedTypeScaffolding(\n files: DriftFile[],\n usage: Map<string, Set<string>>,\n): DriftFinding[] {\n const findings: DriftFinding[] = [];\n const typeDefinitions = extractTypeDefinitions(files);\n const unusedTypesByFile = findUnusedTypes(typeDefinitions, usage);\n\n for (const [filePath, unusedTypes] of unusedTypesByFile) {\n if (unusedTypes.length < 3) continue;\n\n findings.push({\n detector: \"phantom_scaffolding\",\n subCategory: \"unused_types\",\n driftCategory: \"phantom_scaffolding\",\n severity: \"info\",\n confidence: 0.55,\n finding: `${unusedTypes.length} types/structs in ${filePath} appear unused outside their file`,\n dominantPattern: \"used types\",\n dominantCount: typeDefinitions.length - unusedTypes.length,\n totalRelevantFiles: typeDefinitions.length,\n consistencyScore: Math.round(((typeDefinitions.length - unusedTypes.length) / typeDefinitions.length) * 100),\n deviatingFiles: [{\n path: filePath,\n detectedPattern: `unused types: ${unusedTypes.map((t) => t.name).join(\", \")}`,\n evidence: unusedTypes.slice(0, 5).map((t) => ({\n line: t.line,\n code: `type ${t.name} — defined but never imported`,\n })),\n }],\n recommendation: `${unusedTypes.length} types in ${filePath.split(\"/\").pop()} are never used outside their file. They may be AI-generated scaffolding that was never needed.`,\n });\n }\n\n return findings;\n}\n\nexport const phantomScaffolding: DriftDetector = {\n id: \"phantom-scaffolding\",\n name: \"Phantom Scaffolding\",\n category: \"phantom_scaffolding\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n // Extract all exported functions and route registrations\n const allExports: ExportedFunction[] = [];\n const allRoutes: RouteRegistration[] = [];\n\n for (const file of ctx.files) {\n allExports.push(...extractExportedFunctions(file));\n allRoutes.push(...extractRouteRegistrations(file));\n }\n\n if (allExports.length < 3) return [];\n\n // Build usage graph\n const usage = buildUsageGraph(ctx.files);\n\n const findings: DriftFinding[] = [];\n\n // Detect unrouted handler functions\n findings.push(...detectUnroutedHandlers(allExports, allRoutes, usage));\n\n // Detect unused type/struct scaffolding\n findings.push(...detectUnusedTypeScaffolding(ctx.files, usage));\n\n return findings;\n },\n};\n","import type {\n Finding,\n CategoryScores,\n CategoryScore,\n SupportedLanguage,\n PerFileScore,\n AnalysisContext,\n} from \"../core/types.js\";\nimport {\n CATEGORY_CONFIG,\n ALL_CATEGORIES,\n isCategoryApplicable,\n getApplicableAnalyzerIds,\n type ScoringCategory,\n} from \"./categories.js\";\n\nconst SEVERITY_WEIGHTS = { error: 3, warning: 1.5, info: 0.5 };\n\nconst ENTRY_POINT_PATTERNS = [\n /index\\.[jt]sx?$/, /main\\.[jt]s$/, /app\\.[jt]sx?$/, /server\\.[jt]s$/,\n /main\\.go$/, /main\\.py$/, /lib\\.rs$/, /mod\\.rs$/,\n /\\.config\\.[jt]s$/, /\\.env/,\n];\n\nfunction isEntryPoint(filePath: string): boolean {\n return ENTRY_POINT_PATTERNS.some((p) => p.test(filePath));\n}\n\nfunction computeFileImportanceWeight(filePath: string): number {\n if (isEntryPoint(filePath)) return 1.5;\n return 1.0;\n}\n\nfunction computeCorrelationAmplifier(findings: Finding[]): Map<string, number> {\n const fileAnalyzers = new Map<string, Set<string>>();\n for (const f of findings) {\n for (const loc of f.locations) {\n if (!loc.file) continue;\n if (!fileAnalyzers.has(loc.file)) fileAnalyzers.set(loc.file, new Set());\n fileAnalyzers.get(loc.file)!.add(f.analyzerId);\n }\n }\n\n const amplifiers = new Map<string, number>();\n for (const [file, analyzers] of fileAnalyzers) {\n const count = analyzers.size;\n amplifiers.set(file, count >= 4 ? 1.5 : count >= 3 ? 1.3 : 1.0);\n }\n return amplifiers;\n}\n\n/**\n * Scoring philosophy: the score should HURT when there are real issues.\n *\n * Formula per category (0-20):\n * 1. Sum weighted severity of all findings (error=3, warning=1.5, info=0.5)\n * × confidence × file importance × correlation amplifier\n * 2. Apply mild project-size adjustment (sqrt scale, not linear divide)\n * 3. Map through exponential decay: score = maxScore × e^(-k × adjustedWeight)\n * where k is tuned so that ~10 weighted points = ~50% score\n *\n * This means:\n * - 0 findings → 20/20\n * - 2-3 warnings → ~17/20\n * - 5 warnings → ~14/20\n * - 10 warnings or 3 errors → ~10/20\n * - 20+ weighted points → <5/20\n */\nfunction computeCategoryScore(\n findings: Finding[],\n maxScore: number,\n totalLines: number,\n applicable: boolean,\n correlationAmplifiers: Map<string, number>,\n): CategoryScore {\n if (!applicable) {\n return { score: 0, maxScore, locked: false, findingCount: 0, applicable: false };\n }\n\n if (findings.length === 0) {\n return { score: maxScore, maxScore, locked: false, findingCount: 0, applicable: true };\n }\n\n // Sum weighted severity\n let rawWeight = 0;\n for (const f of findings) {\n const base = SEVERITY_WEIGHTS[f.severity];\n const confidence = f.confidence ?? 1.0;\n let fileWeight = 1.0;\n let corrWeight = 1.0;\n for (const loc of f.locations) {\n if (loc.file) {\n fileWeight = Math.max(fileWeight, computeFileImportanceWeight(loc.file));\n corrWeight = Math.max(corrWeight, correlationAmplifiers.get(loc.file) ?? 1.0);\n }\n }\n rawWeight += base * confidence * fileWeight * corrWeight;\n }\n\n // Mild project-size adjustment: larger projects tolerate slightly more issues.\n // Projects under 500 lines get no penalty — prevents tiny demos from scoring F.\n // Uses sqrt scale — a 10K line project gets ~3x tolerance vs 500 lines, not 100x\n const sizeFactor = totalLines > 500 ? Math.sqrt(totalLines / 1000) : 1.0;\n // Clamp to [0.5, 3.0] — never more than 3x tolerance\n const clampedSizeFactor = Math.max(0.5, Math.min(3.0, sizeFactor));\n const adjustedWeight = rawWeight / clampedSizeFactor;\n\n // Exponential decay: score = max × e^(-k × weight)\n // k = ln(2)/15 means 15 weighted points = 50% score (softer than the\n // original /10 — two error findings no longer tank a category)\n const k = Math.LN2 / 15;\n const factor = Math.exp(-k * adjustedWeight);\n const score = Math.round(maxScore * factor * 10) / 10;\n\n return {\n score: Math.max(0, Math.min(maxScore, score)),\n maxScore,\n locked: false,\n findingCount: findings.length,\n applicable: true,\n };\n}\n\nexport function computeScores(\n findings: Finding[],\n totalLines: number,\n ctx?: AnalysisContext,\n previousScores?: CategoryScores,\n): { scores: CategoryScores; compositeScore: number; maxCompositeScore: number; perFileScores: Map<string, PerFileScore> } {\n const projectLanguages: SupportedLanguage[] = ctx\n ? [...ctx.languageBreakdown.keys()]\n : [\"javascript\", \"typescript\"];\n\n const correlationAmplifiers = computeCorrelationAmplifier(findings);\n\n const findingsByCategory = new Map<ScoringCategory, Finding[]>();\n for (const cat of ALL_CATEGORIES) {\n const applicableIds = getApplicableAnalyzerIds(cat, projectLanguages);\n findingsByCategory.set(cat, findings.filter((f) => applicableIds.includes(f.analyzerId)));\n }\n\n const categoryScores: Record<string, CategoryScore> = {};\n\n for (const cat of ALL_CATEGORIES) {\n const config = CATEGORY_CONFIG[cat];\n const applicable = isCategoryApplicable(cat, projectLanguages);\n const catFindings = findingsByCategory.get(cat) ?? [];\n\n const score = computeCategoryScore(\n catFindings,\n config.maxScore,\n totalLines,\n applicable,\n correlationAmplifiers,\n );\n\n if (previousScores) {\n const prev = previousScores[cat];\n if (prev && prev.applicable) {\n score.delta = Math.round((score.score - prev.score) * 10) / 10;\n }\n }\n\n categoryScores[cat] = score;\n }\n\n const scores = categoryScores as unknown as CategoryScores;\n\n let compositeScore = 0;\n let maxCompositeScore = 0;\n for (const cat of ALL_CATEGORIES) {\n const s = scores[cat];\n if (s.applicable) {\n compositeScore += s.score;\n maxCompositeScore += s.maxScore;\n }\n }\n\n // Drag penalty: when critical categories score poorly, the composite score\n // shouldn't be rescued by perfect scores in less impactful categories.\n // Architecture and redundancy are load-bearing — if they're broken, the\n // overall health should reflect that urgency.\n const DRAG_CATEGORIES: ScoringCategory[] = [\"architecturalConsistency\", \"redundancy\"];\n const DRAG_THRESHOLD = 0.50; // below 50% health triggers drag\n const DRAG_MAX_PENALTY = 0.10; // up to 10% composite penalty per category (reduced from 15% to avoid double-punishment)\n\n for (const cat of DRAG_CATEGORIES) {\n const s = scores[cat];\n if (!s.applicable || s.maxScore === 0) continue;\n const healthPct = s.score / s.maxScore;\n if (healthPct < DRAG_THRESHOLD) {\n // Linear penalty: 0% health → full penalty, 50% health → 0 penalty\n const penaltyFraction = (DRAG_THRESHOLD - healthPct) / DRAG_THRESHOLD;\n const penalty = DRAG_MAX_PENALTY * penaltyFraction * maxCompositeScore;\n compositeScore -= penalty;\n }\n }\n\n compositeScore = Math.max(0, Math.round(compositeScore * 10) / 10);\n\n const perFileScores = computePerFileScores(findings, ctx);\n\n return { scores, compositeScore, maxCompositeScore, perFileScores };\n}\n\nfunction computePerFileScores(\n findings: Finding[],\n ctx?: AnalysisContext,\n): Map<string, PerFileScore> {\n const perFile = new Map<string, PerFileScore>();\n if (!ctx) return perFile;\n\n for (const file of ctx.files) {\n perFile.set(file.relativePath, {\n file: file.relativePath,\n findings: [],\n score: 100,\n maxScore: 100,\n });\n }\n\n for (const finding of findings) {\n // Deduplicate: add each finding to a file only once, even if it has\n // multiple locations pointing to the same file\n const seenFiles = new Set<string>();\n for (const loc of finding.locations) {\n if (!loc.file || seenFiles.has(loc.file)) continue;\n seenFiles.add(loc.file);\n const entry = perFile.get(loc.file);\n if (entry) entry.findings.push(finding);\n }\n }\n\n for (const [, entry] of perFile) {\n if (entry.findings.length === 0) continue;\n let penalty = 0;\n for (const f of entry.findings) {\n penalty += SEVERITY_WEIGHTS[f.severity] * (f.confidence ?? 1.0);\n }\n // Exponential decay per file too\n const k = Math.LN2 / 5; // 5 weighted points = 50 score\n entry.score = Math.max(0, Math.round(100 * Math.exp(-k * penalty)));\n }\n\n return perFile;\n}\n","import type { SupportedLanguage } from \"../core/types.js\";\n\nexport type ScoringCategory =\n | \"architecturalConsistency\"\n | \"redundancy\"\n | \"dependencyHealth\"\n | \"securityPosture\"\n | \"intentClarity\";\n\nexport interface AnalyzerMeta {\n id: string;\n applicableLanguages: SupportedLanguage[] | \"all\";\n}\n\nexport interface CategoryConfig {\n name: string;\n maxScore: number;\n analyzers: AnalyzerMeta[];\n}\n\nexport const CATEGORY_CONFIG: Record<ScoringCategory, CategoryConfig> = {\n architecturalConsistency: {\n name: \"Architectural Consistency\",\n maxScore: 20,\n analyzers: [\n { id: \"naming\", applicableLanguages: \"all\" },\n { id: \"imports\", applicableLanguages: [\"javascript\", \"typescript\"] },\n { id: \"error-handling\", applicableLanguages: [\"javascript\", \"typescript\"] },\n { id: \"language-specific\", applicableLanguages: \"all\" },\n // Drift detectors (cross-file)\n { id: \"drift-architectural_consistency\", applicableLanguages: \"all\" },\n { id: \"drift-convention-oscillation\", applicableLanguages: \"all\" },\n // Code DNA\n { id: \"codedna-pattern\", applicableLanguages: \"all\" },\n { id: \"codedna-deviation\", applicableLanguages: \"all\" },\n // ML\n { id: \"ml-anomaly\", applicableLanguages: \"all\" },\n ],\n },\n redundancy: {\n name: \"Redundancy\",\n maxScore: 20,\n analyzers: [\n { id: \"duplicates\", applicableLanguages: \"all\" },\n { id: \"todo-density\", applicableLanguages: \"all\" },\n { id: \"dead-code\", applicableLanguages: \"all\" },\n // Code DNA\n { id: \"codedna-fingerprint\", applicableLanguages: \"all\" },\n { id: \"codedna-opseq\", applicableLanguages: \"all\" },\n // ML\n { id: \"ml-duplicate\", applicableLanguages: \"all\" },\n ],\n },\n dependencyHealth: {\n name: \"Dependency Health\",\n maxScore: 20,\n analyzers: [\n { id: \"dependencies\", applicableLanguages: \"all\" },\n { id: \"config-drift\", applicableLanguages: \"all\" },\n ],\n },\n securityPosture: {\n name: \"Security Posture\",\n maxScore: 20,\n analyzers: [\n { id: \"security\", applicableLanguages: \"all\" },\n { id: \"drift-security_posture\", applicableLanguages: \"all\" },\n // Code DNA\n { id: \"codedna-taint\", applicableLanguages: \"all\" },\n ],\n },\n intentClarity: {\n name: \"Intent Clarity\",\n maxScore: 20,\n analyzers: [\n { id: \"intent-clarity\", applicableLanguages: \"all\" },\n { id: \"complexity\", applicableLanguages: \"all\" },\n // ML\n { id: \"ml-intent\", applicableLanguages: \"all\" },\n ],\n },\n};\n\nexport const ALL_CATEGORIES = Object.keys(CATEGORY_CONFIG) as ScoringCategory[];\n\nexport function getApplicableAnalyzerIds(\n category: ScoringCategory,\n projectLanguages: SupportedLanguage[],\n): string[] {\n return CATEGORY_CONFIG[category].analyzers\n .filter((a) => {\n if (a.applicableLanguages === \"all\") return true;\n return a.applicableLanguages.some((l) => projectLanguages.includes(l));\n })\n .map((a) => a.id);\n}\n\nexport function isCategoryApplicable(\n category: ScoringCategory,\n projectLanguages: SupportedLanguage[],\n): boolean {\n return getApplicableAnalyzerIds(category, projectLanguages).length > 0;\n}\n","import type { AnalysisContext, Finding } from \"../core/types.js\";\n\nexport function generateTeaseMessages(\n ctx: AnalysisContext,\n findings: Finding[],\n deepUsed: boolean,\n): string[] {\n if (deepUsed) return []; // No tease needed when deep AI analysis already ran\n\n const messages: string[] = [];\n\n const securityFindings = findings.filter((f) => f.analyzerId === \"security\");\n if (securityFindings.length > 0) {\n const errorCount = securityFindings.filter((f) => f.severity === \"error\").length;\n messages.push(\n `${securityFindings.length} security issues found${errorCount > 0 ? ` (${errorCount} critical)` : \"\"} — run \\`vibedrift --deep\\` for AI-powered context analysis`,\n );\n }\n\n const complexityFindings = findings.filter((f) => f.analyzerId === \"complexity\");\n if (complexityFindings.length > 0) {\n messages.push(\n `${complexityFindings.length} complexity concerns detected — run \\`vibedrift --deep\\` for AI-powered architectural recommendations`,\n );\n }\n\n const deadCodeFindings = findings.filter((f) => f.analyzerId === \"dead-code\");\n if (deadCodeFindings.length > 0) {\n messages.push(\n `Potential dead code detected — run \\`vibedrift --deep\\` for AI-powered semantic analysis`,\n );\n }\n\n if (ctx.files.length > 10 && messages.length === 0) {\n messages.push(\n `Run \\`vibedrift --deep\\` for AI-powered architectural pattern detection and intent analysis`,\n );\n }\n\n if (messages.length > 0) {\n messages.push(`Sign in first with \\`vibedrift login\\` — it's free.`);\n }\n\n return messages;\n}\n","/**\n * Terminal output renderer for VibeDrift scan reports.\n *\n * Formats the full scan result (findings, category scores, deep insights)\n * as a colorized, human-readable terminal report using chalk. Also provides\n * a structured JSON renderer for piping to files or CI systems.\n */\n\nimport chalk from \"chalk\";\nimport type { ScanResult, Finding } from \"../core/types.js\";\nimport { CATEGORY_CONFIG, ALL_CATEGORIES, type ScoringCategory } from \"../scoring/categories.js\";\nimport { scoreBar, padRight } from \"./format.js\";\nimport { getLanguageDisplayName } from \"../core/language.js\";\nimport type { SupportedLanguage } from \"../core/types.js\";\nimport { getVersion } from \"../core/version.js\";\n\nfunction severityIcon(severity: Finding[\"severity\"]): string {\n switch (severity) {\n case \"error\": return chalk.red(\"\\u2718\");\n case \"warning\": return chalk.yellow(\"\\u26A0\");\n case \"info\": return chalk.blue(\"\\u2139\");\n }\n}\n\nfunction scoreColorFn(score: number, max: number): typeof chalk {\n const ratio = score / max;\n if (ratio >= 0.8) return chalk.green;\n if (ratio >= 0.5) return chalk.yellow;\n return chalk.red;\n}\n\nfunction renderFindingsList(result: ScanResult): string[] {\n const lines: string[] = [];\n for (const cat of ALL_CATEGORIES) {\n const config = CATEGORY_CONFIG[cat];\n const s = result.scores[cat];\n\n if (!s.applicable) {\n lines.push(chalk.dim(`\\u2500\\u2500 ${config.name} (N/A) \\u2500\\u2500\\u2500`));\n lines.push(chalk.dim(\" Not applicable for this project's languages\"));\n lines.push(\"\");\n continue;\n }\n\n lines.push(chalk.bold(`\\u2500\\u2500 ${config.name} ${\"─\".repeat(Math.max(0, 48 - config.name.length))}`));\n\n const catAnalyzerIds = config.analyzers.map((a) => a.id);\n const catFindings = result.findings.filter((f) => catAnalyzerIds.includes(f.analyzerId));\n\n if (catFindings.length === 0) {\n lines.push(chalk.green(\" \\u2713 No issues found\"));\n } else {\n for (const finding of catFindings) {\n lines.push(` ${severityIcon(finding.severity)} ${finding.message}`);\n if (finding.locations.length > 0 && finding.locations.length <= 5) {\n for (const loc of finding.locations) {\n const lineStr = loc.line ? `:${loc.line}` : \"\";\n lines.push(chalk.dim(` ${loc.file}${lineStr}`));\n }\n } else if (finding.locations.length > 5) {\n for (const loc of finding.locations.slice(0, 3)) {\n const lineStr = loc.line ? `:${loc.line}` : \"\";\n lines.push(chalk.dim(` ${loc.file}${lineStr}`));\n }\n lines.push(chalk.dim(` ... and ${finding.locations.length - 3} more`));\n }\n }\n }\n lines.push(\"\");\n }\n return lines;\n}\n\nfunction renderCategoryBars(result: ScanResult): string[] {\n const lines: string[] = [];\n lines.push(chalk.bold(\"\\u2500\\u2500 Vibe Debt Score \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\"));\n\n for (const cat of ALL_CATEGORIES) {\n const config = CATEGORY_CONFIG[cat];\n const s = result.scores[cat];\n const label = padRight(config.name, 28);\n\n if (!s.applicable) {\n lines.push(chalk.dim(` ${label} N/A`));\n } else {\n const color = scoreColorFn(s.score, s.maxScore);\n const bar = color(scoreBar(s.score, s.maxScore));\n let deltaStr = \"\";\n if (s.delta !== undefined && s.delta !== 0) {\n const dColor = s.delta > 0 ? chalk.green : chalk.red;\n const arrow = s.delta > 0 ? \"\\u25B2\" : \"\\u25BC\";\n deltaStr = \" \" + dColor(`${arrow}${Math.abs(s.delta).toFixed(1)}`);\n }\n lines.push(` ${label} ${color(`${s.score.toFixed(0).padStart(2)}/${s.maxScore}`)} ${bar}${deltaStr}`);\n }\n }\n\n lines.push(` ${\"─\".repeat(34)}`);\n const totalColor = scoreColorFn(result.compositeScore, result.maxCompositeScore);\n lines.push(` ${padRight(\"Total Score:\", 28)} ${totalColor(`${result.compositeScore.toFixed(0)}/${result.maxCompositeScore}`)}`);\n lines.push(\"\");\n return lines;\n}\n\nfunction renderScoreSection(result: ScanResult): string[] {\n const lines: string[] = [];\n\n const banner = ` VibeDrift v${getVersion()} `;\n const border = \"\\u2500\".repeat(banner.length);\n lines.push(chalk.cyan(`\\u256D${border}\\u256E`));\n lines.push(chalk.cyan(`\\u2502${banner}\\u2502`));\n lines.push(chalk.cyan(`\\u2570${border}\\u256F`));\n lines.push(\"\");\n\n const langCounts = new Map<string, number>();\n for (const f of result.context.files) {\n if (f.language) {\n const label = getLanguageDisplayName(f.language as SupportedLanguage);\n langCounts.set(label, (langCounts.get(label) ?? 0) + 1);\n }\n }\n const langStr = [...langCounts.entries()].map(([l, c]) => `${l}: ${c}`).join(\", \");\n\n lines.push(chalk.dim(`Scanning: ${result.context.rootDir}`));\n lines.push(chalk.dim(`Files: ${result.context.files.length} (${langStr}) | Lines: ${result.context.totalLines.toLocaleString()} | Time: ${(result.scanTimeMs / 1000).toFixed(1)}s`));\n lines.push(\"\");\n return lines;\n}\n\nexport function renderTerminalOutput(result: ScanResult): string {\n const lines: string[] = [\n ...renderScoreSection(result),\n ...renderFindingsList(result),\n ...renderCategoryBars(result),\n ];\n\n // Deep insights\n if (result.deepInsights.length > 0) {\n lines.push(chalk.bold(\"\\u2500\\u2500 Deep Analysis (AI-Powered) \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\"));\n for (const insight of result.deepInsights.slice(0, 10)) {\n const icon = severityIcon(insight.severity);\n lines.push(` ${icon} [${insight.category}] ${insight.title}`);\n lines.push(chalk.dim(` ${insight.description.slice(0, 120)}${insight.description.length > 120 ? \"...\" : \"\"}`));\n if (insight.recommendation) {\n lines.push(chalk.green(` \\u2192 ${insight.recommendation.slice(0, 100)}`));\n }\n }\n lines.push(\"\");\n }\n\n // Tease\n if (result.teaseMessages.length > 0) {\n lines.push(chalk.bold(\"\\u2500\\u2500 Deep Analysis Preview \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\"));\n for (const msg of result.teaseMessages) {\n lines.push(chalk.dim(` \\u00B7 ${msg}`));\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function renderJsonOutput(result: ScanResult): string {\n return JSON.stringify(\n {\n version: getVersion(),\n project: result.context.rootDir,\n fileCount: result.context.files.length,\n totalLines: result.context.totalLines,\n dominantLanguage: result.context.dominantLanguage,\n scanTimeMs: result.scanTimeMs,\n scores: result.scores,\n compositeScore: result.compositeScore,\n maxCompositeScore: result.maxCompositeScore,\n findings: result.findings,\n deepInsights: result.deepInsights,\n perFileScores: Object.fromEntries(result.perFileScores),\n },\n null,\n 2,\n );\n}\n","export function scoreBar(score: number, max: number, width = 20): string {\n const filled = Math.round((score / max) * width);\n return \"\\u2588\".repeat(filled) + \"\\u2591\".repeat(width - filled);\n}\n\nexport function padRight(str: string, len: number): string {\n return str + \" \".repeat(Math.max(0, len - str.length));\n}\n","import type { ScanResult, Finding, DriftFindingReport } from \"../core/types.js\";\nimport { getVersion } from \"../core/version.js\";\n\nfunction esc(s: string): string {\n return s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\");\n}\n\nfunction gradeFor(score: number, max: number): { letter: string; color: string } {\n const pct = max > 0 ? (score / max) * 100 : 0;\n if (pct >= 90) return { letter: \"A\", color: \"var(--grade-a)\" };\n if (pct >= 75) return { letter: \"B\", color: \"var(--grade-b)\" };\n if (pct >= 50) return { letter: \"C\", color: \"var(--grade-c)\" };\n if (pct >= 25) return { letter: \"D\", color: \"var(--grade-d)\" };\n return { letter: \"F\", color: \"var(--grade-f)\" };\n}\n\nfunction sevColor(sev: string): string {\n if (sev === \"error\") return \"var(--drift-red)\";\n if (sev === \"warning\") return \"var(--drift-orange)\";\n return \"var(--info-blue)\";\n}\n\nfunction sevLabel(sev: string): string {\n if (sev === \"error\") return \"CRITICAL\";\n if (sev === \"warning\") return \"WARNING\";\n return \"INFO\";\n}\n\nfunction scoreColor(score: number): string {\n if (score <= 25) return \"var(--drift-red)\";\n if (score <= 50) return \"var(--drift-orange)\";\n if (score <= 75) return \"var(--drift-amber)\";\n if (score <= 90) return \"var(--grade-b)\";\n return \"var(--grade-a)\";\n}\n\nfunction shortPath(p: string): string {\n const parts = p.split(\"/\");\n return parts.length > 3 ? \".../\" + parts.slice(-2).join(\"/\") : p;\n}\n\n// ──── Extract intent patterns from drift findings ────\n\ninterface IntentPattern {\n category: string;\n label: string;\n dominantCount: number;\n totalRelevant: number;\n consistency: number;\n}\n\nfunction extractIntentPatterns(result: ScanResult): IntentPattern[] {\n const patterns: IntentPattern[] = [];\n const seen = new Set<string>();\n\n for (const d of (result.driftFindings ?? [])) {\n const key = d.driftCategory + \"::\" + (d.subCategory ?? \"\") + \"::\" + d.dominantPattern;\n if (seen.has(key)) continue;\n seen.add(key);\n\n // Use subCategory for architectural_consistency to get precise labels\n const subCatNames: Record<string, string> = {\n data_access: \"Data Access\",\n error_handling: \"Error Handling\",\n dependency_injection: \"Dependency Injection\",\n configuration: \"Configuration\",\n };\n\n const catNames: Record<string, string> = {\n architectural_consistency: \"Architecture\",\n security_posture: \"Security\",\n semantic_duplication: \"Duplication\",\n naming_conventions: \"Naming\",\n phantom_scaffolding: \"Scaffolding\",\n };\n\n // Prefer subCategory label for architectural findings, fallback to category\n const category = (d.driftCategory === \"architectural_consistency\" && d.subCategory)\n ? (subCatNames[d.subCategory] ?? catNames[d.driftCategory] ?? d.driftCategory)\n : (catNames[d.driftCategory] ?? d.driftCategory);\n\n // Skip \"no clear dominant\" cards — they add confusion, not clarity\n if (d.consistencyScore < 60) continue;\n\n patterns.push({\n category,\n label: d.dominantPattern,\n dominantCount: d.dominantCount,\n totalRelevant: d.totalRelevantFiles,\n consistency: d.consistencyScore,\n });\n }\n\n // Add Code DNA patterns\n const dna = result.codeDnaResult;\n if (dna?.patternDistributions?.length > 0) {\n const patternCounts = new Map<string, number>();\n for (const pd of dna.patternDistributions) {\n patternCounts.set(pd.dominantPattern, (patternCounts.get(pd.dominantPattern) ?? 0) + 1);\n }\n let dominant = \"\";\n let maxC = 0;\n for (const [p, c] of patternCounts) {\n if (c > maxC) { maxC = c; dominant = p; }\n }\n if (dominant && !seen.has(\"codedna::\" + dominant)) {\n patterns.push({\n category: \"Architecture\",\n label: dominant,\n dominantCount: maxC,\n totalRelevant: dna.patternDistributions.length,\n consistency: Math.round((maxC / dna.patternDistributions.length) * 100),\n });\n }\n }\n\n return patterns;\n}\n\n// ──── Build coherence data per file ────\n\ninterface FileCoherence {\n path: string;\n score: number;\n alignments: { category: string; matches: boolean; actual?: string }[];\n alignmentPct: number;\n driftCount: number;\n staticCount: number;\n}\n\nfunction buildDriftFileMap(result: ScanResult): Map<string, { category: string; pattern: string }[]> {\n const driftFiles = new Map<string, { category: string; pattern: string }[]>();\n for (const d of (result.driftFindings ?? [])) {\n for (const df of d.deviatingFiles) {\n if (!driftFiles.has(df.path)) driftFiles.set(df.path, []);\n const catKey = (d.driftCategory === \"architectural_consistency\" && d.subCategory)\n ? d.driftCategory + \"::\" + d.subCategory\n : d.driftCategory;\n driftFiles.get(df.path)!.push({ category: catKey, pattern: df.detectedPattern });\n }\n }\n return driftFiles;\n}\n\nfunction buildCategorySet(result: ScanResult): Map<string, string> {\n const subCatNames: Record<string, string> = {\n data_access: \"Data Access\",\n error_handling: \"Error Handling\",\n dependency_injection: \"Dep. Injection\",\n configuration: \"Configuration\",\n };\n const baseCatNames: Record<string, string> = {\n security_posture: \"Security\",\n naming_conventions: \"Naming\",\n phantom_scaffolding: \"Scaffolding\",\n };\n\n const catSet = new Map<string, string>();\n for (const d of (result.driftFindings ?? [])) {\n if (d.driftCategory === \"architectural_consistency\" && d.subCategory) {\n const label = subCatNames[d.subCategory] ?? d.subCategory;\n catSet.set(d.driftCategory + \"::\" + d.subCategory, label);\n } else if (baseCatNames[d.driftCategory]) {\n catSet.set(d.driftCategory, baseCatNames[d.driftCategory]);\n }\n }\n return catSet;\n}\n\nfunction buildCodeDnaPatternData(result: ScanResult): { projectDominantPattern: string; filePatternMap: Map<string, string> } {\n const filePatternMap = new Map<string, string>();\n let projectDominantPattern = \"\";\n const dna = result.codeDnaResult;\n\n if (dna?.patternDistributions?.length > 0) {\n const patternCounts = new Map<string, number>();\n for (const pd of dna.patternDistributions) {\n if (pd.dominantPattern !== \"none\") {\n patternCounts.set(pd.dominantPattern, (patternCounts.get(pd.dominantPattern) ?? 0) + 1);\n }\n filePatternMap.set(pd.relativePath, pd.dominantPattern);\n }\n let maxC = 0;\n for (const [p, c] of patternCounts) {\n if (c > maxC) { maxC = c; projectDominantPattern = p; }\n }\n }\n return { projectDominantPattern, filePatternMap };\n}\n\nfunction buildFileCoherence(result: ScanResult): FileCoherence[] {\n const entries = [...result.perFileScores.entries()];\n const driftFiles = buildDriftFileMap(result);\n const catSet = buildCategorySet(result);\n\n const { projectDominantPattern, filePatternMap } = buildCodeDnaPatternData(result);\n if (projectDominantPattern) {\n catSet.set(\"codedna_architecture\", \"Architecture\");\n }\n\n const categories = [...catSet.values()];\n const catKeys = [...catSet.keys()];\n\n return entries.map(([path, data]) => {\n const deviations = driftFiles.get(path) ?? [];\n const alignments = catKeys.map((key, i) => {\n if (key === \"codedna_architecture\") {\n // Check file's pattern against project dominant\n const filePattern = filePatternMap.get(path);\n if (!filePattern || filePattern === \"none\") {\n return { category: categories[i], matches: true }; // no pattern data = assume aligned\n }\n const matches = filePattern === projectDominantPattern;\n return { category: categories[i], matches, actual: matches ? undefined : filePattern };\n }\n const dev = deviations.find((d) => d.category === key);\n return { category: categories[i], matches: !dev, actual: dev?.pattern };\n });\n const matchCount = alignments.filter((a) => a.matches).length;\n const driftCount = data.findings.filter((f) => f.tags?.includes(\"drift\") || f.tags?.includes(\"codedna\")).length;\n const staticCount = data.findings.filter((f) => !f.tags?.includes(\"drift\") && !f.tags?.includes(\"codedna\")).length;\n\n return {\n path,\n score: data.score,\n alignments,\n alignmentPct: categories.length > 0 ? Math.round((matchCount / categories.length) * 100) : 100,\n driftCount,\n staticCount,\n };\n }).sort((a, b) => a.alignmentPct - b.alignmentPct || a.score - b.score);\n}\n\n// ──── Section Builders ────\n\nfunction buildHeader(result: ScanResult): string {\n const name = result.context.rootDir.split(\"/\").pop() ?? \"project\";\n const date = new Date().toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\", year: \"numeric\" });\n const time = (result.scanTimeMs / 1000).toFixed(1);\n const langs = [...result.context.languageBreakdown.entries()]\n .sort((a, b) => b[1].files - a[1].files)\n .map(([l, s]) => `${l.charAt(0).toUpperCase() + l.slice(1)} (${Math.round((s.files / result.context.files.length) * 100)}%)`)\n .join(\", \");\n\n return `<header id=\"report-header\" style=\"padding:32px 0 24px;border-bottom:1px solid var(--border)\">\n <div style=\"display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:8px\">\n <div>\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:4px\"><span style=\"display:inline-block;width:10px;height:10px;background:var(--brand-cyan)\"></span><span class=\"label\" style=\"margin-bottom:0;letter-spacing:2px\">VIBEDRIFT REPORT</span></div>\n <div class=\"heading\" style=\"font-size:24px;font-weight:700;color:var(--text-primary);text-transform:uppercase;letter-spacing:-0.5px\">${esc(name)}</div>\n </div>\n <div style=\"text-align:right;font-size:13px;color:var(--text-secondary)\">\n <div>${date} · ${time}s</div>\n <div>${result.context.files.length} files · ${result.context.totalLines.toLocaleString()} LOC</div>\n <div style=\"color:var(--text-tertiary)\">${langs}</div>\n </div>\n </div>\n</header>`;\n}\n\nfunction buildIntentDefinition(patterns: IntentPattern[]): string {\n if (patterns.length === 0) return \"\";\n\n const cards = patterns.map((p) => {\n return `<div style=\"background:var(--bg-surface);border-left:3px solid var(--intent-green);border-radius:0;padding:14px 16px;min-width:160px;flex:1\">\n <div class=\"label\" style=\"color:var(--text-tertiary)\">${esc(p.category)}</div>\n <div style=\"font-size:14px;font-weight:500;color:var(--text-primary);margin:4px 0\">${esc(p.label)}</div>\n <div class=\"mono\" style=\"font-size:12px;color:var(--intent-green)\">${p.dominantCount} of ${p.totalRelevant} files (${p.consistency}%)</div>\n </div>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">CODEBASE INTENT</div>\n <div style=\"display:flex;gap:12px;flex-wrap:wrap\">${cards}</div>\n</section>`;\n}\n\nfunction buildCoherenceMatrix(files: FileCoherence[]): string {\n if (files.length === 0) return \"\";\n\n const categories = files[0]?.alignments.map((a) => a.category) ?? [];\n if (categories.length === 0) return \"\";\n\n // Split into aligned (100%) and drifting\n const aligned = files.filter((f) => f.alignmentPct === 100);\n const drifting = files.filter((f) => f.alignmentPct < 100).sort((a, b) => a.alignmentPct - b.alignmentPct);\n\n const colHeaders = categories.map((c) =>\n `<th style=\"padding:6px 12px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;text-align:center;font-weight:600\">${esc(c)}</th>`\n ).join(\"\");\n\n function buildAlignmentCells(f: FileCoherence): { cells: string; deviations: string[] } {\n const deviations: string[] = [];\n const cells = f.alignments.map((a) => {\n if (a.matches) return `<td style=\"text-align:center;padding:6px 12px;color:var(--intent-green);font-size:14px\">●</td>`;\n const devColor = f.alignmentPct <= 25 ? \"var(--drift-red)\" : f.alignmentPct <= 50 ? \"var(--drift-orange)\" : \"var(--drift-amber)\";\n deviations.push(`${a.category}: ${a.actual ?? \"deviates\"}`);\n return `<td style=\"text-align:center;padding:6px 12px;color:${devColor};font-size:13px\" data-tooltip=\"${esc(a.actual ?? \"deviates\")}\">◆</td>`;\n }).join(\"\");\n return { cells, deviations };\n }\n\n function buildDeviationSummary(deviations: string[]): string {\n return deviations.length > 0\n ? `<td style=\"padding:6px 12px;font-size:11px;color:var(--text-secondary);max-width:250px\">${deviations.map((d) => esc(d)).join(\"; \")}</td>`\n : `<td style=\"padding:6px 12px;font-size:11px;color:var(--intent-green)\">Fully aligned</td>`;\n }\n\n function fileRow(f: FileCoherence, open?: boolean): string {\n const pctColor = f.alignmentPct >= 100 ? \"var(--intent-green)\" : f.alignmentPct >= 50 ? \"var(--drift-amber)\" : \"var(--drift-red)\";\n const bgTint = f.alignmentPct < 50 ? \"var(--tint-red)\" : f.alignmentPct < 100 ? \"var(--tint-amber)\" : \"transparent\";\n const { cells, deviations } = buildAlignmentCells(f);\n const summary = buildDeviationSummary(deviations);\n\n return `<tr style=\"background:${bgTint}\" id=\"file-${esc(f.path.replace(/[^a-zA-Z0-9]/g, \"-\"))}\">\n <td class=\"mono\" style=\"padding:6px 12px;font-size:12px;color:var(--text-secondary);white-space:nowrap;max-width:280px;overflow:hidden;text-overflow:ellipsis\" data-scroll-to=\"rank-${esc(f.path.replace(/[^a-zA-Z0-9]/g, \"-\"))}\">${esc(f.path)}</td>\n ${cells}\n <td class=\"mono\" style=\"padding:6px 12px;text-align:right;font-weight:600;color:${pctColor}\">${f.alignmentPct}%</td>\n ${summary}\n </tr>`;\n }\n\n const colCount = categories.length + 3; // file + categories + align + summary\n\n // Show first 3 aligned, then collapse rest\n const alignedRows = aligned.slice(0, 3).map((f) => fileRow(f)).join(\"\");\n const collapsedAligned = aligned.length > 3\n ? `<tr><td colspan=\"${colCount}\" style=\"padding:6px 12px;font-size:12px;color:var(--text-tertiary);cursor:pointer\" data-collapse=\"aligned-rest\">··· ${aligned.length - 3} more at 100% ···</td></tr>\n <tbody id=\"aligned-rest\" style=\"display:none\">${aligned.slice(3).map((f) => fileRow(f)).join(\"\")}</tbody>` : \"\";\n\n // Collapse files with identical single-issue deviations to reduce noise\n // e.g., \"8 files deviate on naming only (camelCase)\" as a collapsed row\n const singleIssueDrifting = new Map<string, FileCoherence[]>(); // deviation key → files\n const multiIssueDrifting: FileCoherence[] = [];\n\n for (const f of drifting) {\n const devs = f.alignments.filter((a) => !a.matches);\n if (devs.length === 1) {\n const key = `${devs[0].category}: ${devs[0].actual ?? \"deviates\"}`;\n if (!singleIssueDrifting.has(key)) singleIssueDrifting.set(key, []);\n singleIssueDrifting.get(key)!.push(f);\n } else {\n multiIssueDrifting.push(f);\n }\n }\n\n // Render multi-issue files individually (these are the interesting ones)\n let driftingRows = multiIssueDrifting.map((f) => fileRow(f)).join(\"\");\n\n // Render single-issue groups: if >=4 files share the same deviation, collapse them\n for (const [devKey, files2] of singleIssueDrifting) {\n if (files2.length >= 4) {\n // Show first file, then collapse the rest\n driftingRows += fileRow(files2[0]);\n const collapseId = `single-dev-${devKey.replace(/[^a-zA-Z0-9]/g, \"-\")}`;\n driftingRows += `<tr><td colspan=\"${colCount}\" style=\"padding:4px 12px;font-size:12px;color:var(--text-tertiary);cursor:pointer\" data-collapse=\"${collapseId}\">··· ${files2.length - 1} more files with same issue (${esc(devKey)}) ···</td></tr>`;\n driftingRows += `<tbody id=\"${collapseId}\" style=\"display:none\">${files2.slice(1).map((f) => fileRow(f)).join(\"\")}</tbody>`;\n } else {\n driftingRows += files2.map((f) => fileRow(f)).join(\"\");\n }\n }\n\n // Summary bar\n const total = files.length;\n const fullAlign = aligned.length;\n const partial = drifting.filter((f) => f.alignmentPct >= 50).length;\n const significant = drifting.filter((f) => f.alignmentPct > 0 && f.alignmentPct < 50).length;\n const critical = drifting.filter((f) => f.alignmentPct === 0).length;\n const coherencePct = total > 0 ? Math.round((fullAlign / total) * 100) : 100;\n\n const barSegments = [\n { pct: (fullAlign / total) * 100, color: \"var(--intent-green)\" },\n { pct: (partial / total) * 100, color: \"var(--drift-amber)\" },\n { pct: (significant / total) * 100, color: \"var(--drift-orange)\" },\n { pct: (critical / total) * 100, color: \"var(--drift-red)\" },\n ].filter((s) => s.pct > 0).map((s) =>\n `<div style=\"width:${s.pct}%;height:100%;background:${s.color}\"></div>`\n ).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">INTENT COHERENCE</div>\n <div style=\"display:flex;gap:20px;margin-bottom:16px;font-size:12px;color:var(--text-secondary);flex-wrap:wrap;align-items:center\">\n <span style=\"display:flex;align-items:center;gap:5px\"><span style=\"color:var(--intent-green);font-size:14px\">●</span> Follows dominant pattern</span>\n <span style=\"display:flex;align-items:center;gap:5px\"><span style=\"color:var(--drift-amber);font-size:13px\">◆</span> Deviates from intent</span>\n <span style=\"display:flex;align-items:center;gap:5px\"><span style=\"color:var(--drift-orange);font-size:13px\">◆</span> Multiple deviations</span>\n <span style=\"display:flex;align-items:center;gap:5px\"><span style=\"color:var(--drift-red);font-size:13px\">◆</span> Critical drift</span>\n </div>\n <div style=\"overflow-x:auto\">\n <table style=\"width:100%;border-collapse:collapse;font-size:13px\">\n <thead><tr style=\"border-bottom:1px solid var(--border)\">\n <th style=\"padding:6px 12px;text-align:left;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">File</th>\n ${colHeaders}\n <th style=\"padding:6px 12px;text-align:right;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Align</th>\n <th style=\"padding:6px 12px;text-align:left;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Issue</th>\n </tr></thead>\n <tbody>\n ${driftingRows}\n ${alignedRows}\n ${collapsedAligned}\n </tbody>\n </table>\n </div>\n <div style=\"margin-top:16px\">\n <div style=\"display:flex;height:6px;border-radius:0;overflow:hidden;gap:2px\">${barSegments}</div>\n <div style=\"display:flex;gap:16px;margin-top:6px;font-size:12px;color:var(--text-tertiary);flex-wrap:wrap\">\n <span style=\"color:var(--intent-green)\">${fullAlign} aligned</span>\n ${partial > 0 ? `<span style=\"color:var(--drift-amber)\">${partial} partial</span>` : \"\"}\n ${significant > 0 ? `<span style=\"color:var(--drift-orange)\">${significant} significant</span>` : \"\"}\n ${critical > 0 ? `<span style=\"color:var(--drift-red)\">${critical} critical</span>` : \"\"}\n <span style=\"margin-left:auto;font-weight:500;color:var(--text-secondary)\">${coherencePct}% intent coherence</span>\n </div>\n </div>\n</section>`;\n}\n\nfunction buildAiSummaryWidget(result: ScanResult): string {\n const ai = result.aiSummary;\n if (!ai) return \"\";\n\n const highlights = (ai.highlights ?? []).map((h) =>\n `<li style=\"margin:4px 0;font-size:13px;color:var(--text-primary)\">${esc(h)}</li>`\n ).join(\"\");\n\n return `<section class=\"section\" style=\"margin-bottom:32px\">\n <div style=\"background:rgba(255,208,0,0.03);border:1px solid var(--border);border-radius:0;padding:24px 28px;position:relative;overflow:hidden\">\n <div style=\"position:absolute;top:0;left:0;width:3px;height:100%;background:var(--border)\"></div>\n <div class=\"score-layout\" style=\"display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap\">\n <div style=\"flex:1;min-width:280px\">\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:10px\">\n <span style=\"font-size:16px\">🤖</span>\n <span class=\"label\" style=\"margin-bottom:0\">AI SUMMARY</span>\n </div>\n <p style=\"font-size:15px;color:var(--text-primary);line-height:1.7;margin:0\">${esc(ai.summary)}</p>\n </div>\n ${highlights ? `<div style=\"min-width:200px;max-width:300px;background:var(--bg-surface);border-radius:0;padding:14px 18px\">\n <div style=\"font-size:11px;font-weight:600;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:1px;margin-bottom:8px\">Key Takeaways</div>\n <ul style=\"list-style:none;padding:0;margin:0\">${highlights}</ul>\n </div>` : \"\"}\n </div>\n <div style=\"margin-top:10px;font-size:10px;color:var(--text-tertiary)\">Generated by Claude Haiku</div>\n </div>\n</section>`;\n}\n\nfunction getDriftCats(result: ScanResult) {\n const ds = result.driftScores ?? {};\n return [\n { name: \"Architectural Consistency\", shortName: \"Architecture\", score: ds.architectural_consistency?.score ?? 0, max: ds.architectural_consistency?.maxScore ?? 25, findings: ds.architectural_consistency?.findings ?? 0 },\n { name: \"Security Posture\", shortName: \"Security\", score: ds.security_posture?.score ?? 0, max: ds.security_posture?.maxScore ?? 25, findings: ds.security_posture?.findings ?? 0 },\n { name: \"Semantic Duplication\", shortName: \"Duplication\", score: ds.semantic_duplication?.score ?? 0, max: ds.semantic_duplication?.maxScore ?? 20, findings: ds.semantic_duplication?.findings ?? 0 },\n { name: \"Convention Drift\", shortName: \"Conventions\", score: ds.naming_conventions?.score ?? 0, max: ds.naming_conventions?.maxScore ?? 15, findings: ds.naming_conventions?.findings ?? 0 },\n { name: \"Phantom Scaffolding\", shortName: \"Scaffolding\", score: ds.phantom_scaffolding?.score ?? 0, max: ds.phantom_scaffolding?.maxScore ?? 15, findings: ds.phantom_scaffolding?.findings ?? 0 },\n ];\n}\n\nfunction buildScoreSection(result: ScanResult): string {\n const { compositeScore, maxCompositeScore } = result;\n const { letter, color } = gradeFor(compositeScore, maxCompositeScore);\n const cats = getDriftCats(result);\n\n const bars = cats.map((c) => {\n const pct = c.max > 0 ? (c.score / c.max) * 100 : 0;\n const { color: barColor } = gradeFor(c.score, c.max);\n return `<div style=\"display:flex;align-items:center;gap:10px;margin:6px 0\">\n <span style=\"font-size:13px;color:var(--text-primary);min-width:190px\">${esc(c.name)}</span>\n <div style=\"flex:1;height:6px;border-radius:0;background:var(--border)\"><div style=\"width:${pct}%;height:100%;border-radius:0;background:${barColor}\"></div></div>\n <span class=\"mono\" style=\"font-size:12px;font-weight:600;color:${barColor};min-width:50px;text-align:right\">${c.score}/${c.max}</span>\n </div>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">SCORE OVERVIEW</div>\n <div class=\"score-layout\" style=\"display:flex;gap:40px;align-items:flex-start;flex-wrap:wrap\">\n <div style=\"text-align:center;min-width:120px\">\n <div class=\"mono\" style=\"font-size:72px;font-weight:800;color:${color};line-height:1\">${compositeScore}</div>\n <div class=\"mono\" style=\"font-size:16px;color:var(--text-tertiary)\">/ ${maxCompositeScore}</div>\n <div style=\"margin-top:8px\"><span style=\"display:inline-block;padding:4px 14px;border-radius:0;font-size:14px;font-weight:600;background:${color}18;color:${color}\">Grade ${letter}</span></div>\n </div>\n <div style=\"flex:1;min-width:300px\">${bars}</div>\n </div>\n</section>`;\n}\n\nfunction buildRadarSection(result: ScanResult): string {\n const cats = getDriftCats(result);\n const n = cats.length;\n if (n === 0) return \"\";\n\n // Wider viewBox (520x440) so labels on left/right/bottom aren't clipped.\n // Center shifted right to 260 and down to 200 to balance label room.\n const cx = 260, cy = 200, r = 130, step = (2 * Math.PI) / n;\n let grid = \"\", dots = \"\", labels = \"\";\n const pts: string[] = [];\n\n // Concentric rings with percentage labels\n for (const ring of [0.25, 0.5, 0.75, 1.0]) {\n grid += `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${r * ring}\" fill=\"none\" stroke=\"#1E2A3A\" stroke-width=\"${ring === 1 ? \"1\" : \"0.5\"}\" stroke-dasharray=\"${ring < 1 ? \"3,3\" : \"none\"}\"/>`;\n if (ring < 1) {\n grid += `<text x=\"${cx + 4}\" y=\"${cy - r * ring + 4}\" fill=\"#3A4555\" font-size=\"9\" font-family=\"-apple-system,sans-serif\">${Math.round(ring * 100)}%</text>`;\n }\n }\n\n // Axis lines and data points\n for (let i = 0; i < n; i++) {\n const a = -Math.PI / 2 + i * step;\n const ex = cx + r * Math.cos(a), ey = cy + r * Math.sin(a);\n grid += `<line x1=\"${cx}\" y1=\"${cy}\" x2=\"${ex}\" y2=\"${ey}\" stroke=\"#1E2A3A\" stroke-width=\"0.5\"/>`;\n\n const ratio = cats[i].max > 0 ? cats[i].score / cats[i].max : 0;\n const px = cx + r * ratio * Math.cos(a), py = cy + r * ratio * Math.sin(a);\n pts.push(`${px},${py}`);\n dots += `<circle cx=\"${px}\" cy=\"${py}\" r=\"5\" fill=\"var(--text-secondary)\" stroke=\"var(--bg-page)\" stroke-width=\"2\"/>`;\n\n // Labels: full name + score\n const labelDist = r + 35;\n const lx = cx + labelDist * Math.cos(a), ly = cy + labelDist * Math.sin(a);\n const anchor = Math.abs(Math.cos(a)) < 0.3 ? \"middle\" : Math.cos(a) > 0 ? \"start\" : \"end\";\n const { color: catColor } = gradeFor(cats[i].score, cats[i].max);\n labels += `<text x=\"${lx}\" y=\"${ly - 7}\" fill=\"${catColor}\" font-size=\"12\" font-weight=\"600\" font-family=\"-apple-system,sans-serif\" text-anchor=\"${anchor}\" dominant-baseline=\"middle\">${esc(cats[i].shortName)}</text>`;\n labels += `<text x=\"${lx}\" y=\"${ly + 8}\" fill=\"#5A6A7E\" font-size=\"11\" font-weight=\"500\" font-family=\"'SF Mono',Consolas,monospace\" text-anchor=\"${anchor}\" dominant-baseline=\"middle\">${cats[i].score}/${cats[i].max} ${cats[i].findings > 0 ? \"(\" + cats[i].findings + \" issues)\" : \"\"}</text>`;\n }\n\n const radar = `<svg viewBox=\"0 0 520 440\" style=\"width:100%;max-width:560px;height:auto;margin:0 auto;display:block\">${grid}<polygon points=\"${pts.join(\" \")}\" fill=\"rgba(255,208,0,0.04)\" stroke=\"rgba(255,208,0,0.3)\" stroke-width=\"1.5\"/>${dots}${labels}</svg>`;\n\n // Find the weakest category for the description\n const weakest = [...cats].sort((a, b) => {\n const pctA = a.max > 0 ? a.score / a.max : 1;\n const pctB = b.max > 0 ? b.score / b.max : 1;\n return pctA - pctB;\n })[0];\n const weakPct = weakest.max > 0 ? Math.round((weakest.score / weakest.max) * 100) : 100;\n\n const strongest = [...cats].sort((a, b) => {\n const pctA = a.max > 0 ? a.score / a.max : 0;\n const pctB = b.max > 0 ? b.score / b.max : 0;\n return pctB - pctA;\n })[0];\n const strongPct = strongest.max > 0 ? Math.round((strongest.score / strongest.max) * 100) : 0;\n\n return `<section class=\"section\">\n <div class=\"label\">DRIFT FINGERPRINT</div>\n <p style=\"font-size:13px;color:var(--text-secondary);margin-bottom:20px;line-height:1.6\">\n This radar shows how well your codebase maintains consistency across 5 drift categories.\n The outer edge represents a perfect score in each category. Points closer to the center indicate more drift.\n A balanced shape means consistent quality; an uneven shape reveals where drift concentrates.\n </p>\n ${radar}\n <div style=\"display:flex;gap:20px;justify-content:center;margin-top:20px;flex-wrap:wrap\">\n <div style=\"background:var(--bg-surface);border-radius:0;padding:12px 18px;text-align:center;min-width:160px\">\n <div style=\"font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:1px;margin-bottom:4px\">Strongest</div>\n <div style=\"font-size:15px;font-weight:600;color:var(--intent-green)\">${esc(strongest.shortName)}</div>\n <div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\">${strongPct}% health</div>\n </div>\n <div style=\"background:var(--bg-surface);border-radius:0;padding:12px 18px;text-align:center;min-width:160px\">\n <div style=\"font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:1px;margin-bottom:4px\">Needs Attention</div>\n <div style=\"font-size:15px;font-weight:600;color:var(--drift-orange)\">${esc(weakest.shortName)}</div>\n <div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\">${weakPct}% health${weakest.findings > 0 ? \" · \" + weakest.findings + \" issues\" : \"\"}</div>\n </div>\n </div>\n</section>`;\n}\n\nfunction buildFixFirst(result: ScanResult): string {\n // Category importance: architectural issues always outrank convention issues\n // regardless of how many files are affected. Renaming files is cosmetic\n // compared to fixing raw SQL vs repository pattern inconsistencies.\n const catWeight: Record<string, number> = {\n architectural_consistency: 10,\n security_posture: 8,\n semantic_duplication: 6,\n phantom_scaffolding: 3,\n naming_conventions: 1,\n };\n\n const ranked = [...(result.driftFindings ?? [])].sort((a, b) => {\n const sev = { error: 3, warning: 2, info: 1 };\n const wA = (catWeight[a.driftCategory] ?? 1) * (sev[a.severity as keyof typeof sev] ?? 0);\n const wB = (catWeight[b.driftCategory] ?? 1) * (sev[b.severity as keyof typeof sev] ?? 0);\n if (wB !== wA) return wB - wA;\n // Tiebreak by file count\n return b.deviatingFiles.length - a.deviatingFiles.length;\n }).slice(0, 3);\n\n if (ranked.length === 0) return \"\";\n\n const cards = ranked.map((d, i) => {\n const severity = d.severity === \"error\" ? \"CRITICAL\" : d.severity === \"warning\" ? \"HIGH\" : \"MEDIUM\";\n const sColor = sevColor(d.severity);\n const files = d.deviatingFiles.map((f) => f.path).slice(0, 3);\n\n // Make recommendations specific with file names and code references\n let recText = d.recommendation ?? \"\";\n let exampleRef = \"\";\n if (d.deviatingFiles.length > 0) {\n const firstDev = d.deviatingFiles[0];\n const firstEvidence = firstDev.evidence?.[0];\n // Find files that follow the dominant pattern (for \"see example in...\" reference)\n const allFiles = [...(result.perFileScores?.keys() ?? [])];\n const deviatingPaths = new Set(d.deviatingFiles.map((f) => f.path));\n const dominantFiles = allFiles.filter((f) => !deviatingPaths.has(f));\n\n if (recText.includes(\"Migrate deviating files\") || recText.includes(\"Standardize deviating\")) {\n const fileNames = d.deviatingFiles.slice(0, 3).map((f) => f.path.split(\"/\").pop()).join(\", \");\n recText = `In ${fileNames}${d.deviatingFiles.length > 3 ? ` (+${d.deviatingFiles.length - 3} more)` : \"\"}: replace ${firstDev.detectedPattern} with the dominant ${d.dominantPattern} pattern (used by ${d.dominantCount}/${d.totalRelevantFiles} files).`;\n if (firstEvidence) {\n recText += ` See ${firstDev.path.split(\"/\").pop()}:${firstEvidence.line}.`;\n }\n }\n // Add example reference file that follows the dominant pattern\n if (dominantFiles.length > 0) {\n const example = dominantFiles.find((f) => f.includes(\"handler\") || f.includes(\"service\")) ?? dominantFiles[0];\n exampleRef = `Follow the pattern in ${example.split(\"/\").pop()}`;\n }\n }\n\n return `<div style=\"background:var(--bg-surface);border-radius:0;padding:20px 24px;margin-bottom:12px;border-left:3px solid ${sColor}\">\n <div style=\"display:flex;align-items:center;gap:10px;margin-bottom:10px\">\n <span class=\"mono\" style=\"font-size:28px;font-weight:800;color:var(--text-tertiary)\">${i + 1}</span>\n <span class=\"sev-badge\" style=\"background:${sColor}\">${severity}</span>\n </div>\n <p style=\"font-size:15px;font-weight:500;color:var(--text-primary);line-height:1.6;margin:0 0 8px\">${esc(recText)}</p>\n <p style=\"font-size:13px;color:var(--text-secondary);margin:0 0 8px\">Impact: Resolves ${d.deviatingFiles.length} deviating file${d.deviatingFiles.length > 1 ? \"s\" : \"\"} in ${d.driftCategory.replace(/_/g, \" \")}.${exampleRef ? \" \" + esc(exampleRef) + \".\" : \"\"}</p>\n <div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\">${files.map((f) => esc(f)).join(\" · \")}</div>\n </div>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">FIX FIRST</div>\n ${cards}\n</section>`;\n}\n\nfunction buildDeviatingBlocks(d: DriftFindingReport): string {\n const isConvention = d.driftCategory === \"naming_conventions\";\n const devByPattern = new Map<string, typeof d.deviatingFiles>();\n for (const df of d.deviatingFiles) {\n const key = df.detectedPattern;\n if (!devByPattern.has(key)) devByPattern.set(key, []);\n devByPattern.get(key)!.push(df);\n }\n\n if (isConvention && d.deviatingFiles.length > 4) {\n return [...devByPattern.entries()].map(([pattern, files]) => {\n const fileList = files.map((df) => esc(df.path)).join(\"</div><div style='padding:1px 0'>\");\n const collapseId = `conv-${pattern.replace(/[^a-zA-Z0-9]/g, \"-\")}-${Math.random().toString(36).slice(2, 6)}`;\n return `<div style=\"background:var(--tint-orange);border-left:3px solid var(--drift-orange);border-radius:0;padding:12px 16px;margin:8px 0\">\n <div class=\"label\" style=\"color:var(--drift-orange);margin-bottom:4px\">DRIFT — ${esc(pattern)} — ${files.length} files</div>\n <div style=\"cursor:pointer;font-size:12px;color:var(--text-secondary);margin-top:6px\" data-collapse=\"${collapseId}\">▶ Show ${files.length} files</div>\n <div id=\"${collapseId}\" style=\"display:none;padding:6px 0\" class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\"><div style=\"padding:1px 0\">${fileList}</div></div>\n </div>`;\n }).join(\"\");\n }\n\n return d.deviatingFiles.slice(0, 4).map((df) => {\n const evidence = df.evidence.slice(0, 3).map((e) =>\n `<div style=\"background:var(--bg-code);padding:6px 12px;border-radius:0;margin:4px 0;overflow-x:auto\" class=\"mono\"><span style=\"color:var(--text-tertiary);margin-right:12px;user-select:none\">${e.line}</span>${esc(e.code.slice(0, 120))}</div>`\n ).join(\"\");\n return `<div style=\"background:var(--tint-orange);border-left:3px solid var(--drift-orange);border-radius:0;padding:12px 16px;margin:8px 0\">\n <div class=\"label\" style=\"color:var(--drift-orange);margin-bottom:4px\">DRIFT — ${esc(df.detectedPattern)}</div>\n <div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary);margin-bottom:6px\">${esc(df.path)}</div>\n ${evidence}\n </div>`;\n }).join(\"\");\n}\n\nfunction buildDriftRecommendation(d: DriftFindingReport): string {\n let recText = d.recommendation ?? \"\";\n if (recText && d.deviatingFiles.length > 0) {\n const firstDev = d.deviatingFiles[0];\n const firstEvidence = firstDev.evidence?.[0];\n if (recText.includes(\"Migrate deviating files\") || recText.includes(\"Standardize deviating\")) {\n const fileList = d.deviatingFiles.slice(0, 3).map((f) => f.path.split(\"/\").pop()).join(\", \");\n recText = `In ${fileList}${d.deviatingFiles.length > 3 ? ` (+${d.deviatingFiles.length - 3} more)` : \"\"}: replace ${firstDev.detectedPattern} with the dominant ${d.dominantPattern} pattern (used by ${d.dominantCount}/${d.totalRelevantFiles} files).`;\n if (firstEvidence) {\n recText += ` Example: ${firstDev.path.split(\"/\").pop()}:${firstEvidence.line} currently uses ${firstDev.detectedPattern}.`;\n }\n }\n }\n return recText;\n}\n\nfunction buildDistributionBar(d: DriftFindingReport): string {\n const domPct = d.totalRelevantFiles > 0 ? Math.round((d.dominantCount / d.totalRelevantFiles) * 100) : 0;\n const devPct = 100 - domPct;\n return `<div style=\"margin:12px 0\">\n <div style=\"display:flex;height:6px;border-radius:0;overflow:hidden;gap:2px\">\n <div style=\"width:${domPct}%;background:var(--intent-green);border-radius:0\"></div>\n <div style=\"width:${devPct}%;background:var(--drift-orange);border-radius:0\"></div>\n </div>\n <div style=\"display:flex;gap:16px;margin-top:4px;font-size:11px;color:var(--text-tertiary)\">\n <span>${esc(d.dominantPattern)} (${d.dominantCount})</span>\n <span>Deviating (${d.totalRelevantFiles - d.dominantCount})</span>\n <span style=\"margin-left:auto\">${d.consistencyScore}% consistent</span>\n </div>\n </div>`;\n}\n\nfunction buildDriftFindings(result: ScanResult): string {\n const driftCats = [\"architectural_consistency\", \"security_posture\", \"semantic_duplication\", \"naming_conventions\", \"phantom_scaffolding\"];\n const catLabels: Record<string, string> = {\n architectural_consistency: \"Architectural contradictions\",\n security_posture: \"Security posture gaps\",\n semantic_duplication: \"Semantic duplication\",\n naming_conventions: \"Convention drift\",\n phantom_scaffolding: \"Phantom scaffolding\",\n };\n\n const groups = driftCats.map((cat) => ({\n cat,\n label: catLabels[cat] ?? cat,\n findings: (result.driftFindings ?? []).filter((f) => f.driftCategory === cat),\n })).filter((g) => g.findings.length > 0);\n\n if (groups.length === 0) return \"\";\n\n const totalFindings = groups.reduce((s, g) => s + g.findings.length, 0);\n\n const sections = groups.map((g, gi) => {\n const cards = g.findings.map((d) => {\n const domPctVal = d.totalRelevantFiles > 0 ? Math.round((d.dominantCount / d.totalRelevantFiles) * 100) : 0;\n const closeSplitNote = domPctVal < 70 && domPctVal >= 50\n ? ` <span style=\"font-size:11px;font-weight:400;color:var(--drift-amber)\">(close split at ${domPctVal}%)</span>`\n : \"\";\n const domBlock = `<div style=\"background:var(--tint-green);border-left:3px solid var(--intent-green);border-radius:0;padding:12px 16px;margin:8px 0\">\n <div class=\"label\" style=\"color:var(--intent-green);margin-bottom:6px\">INTENT (DOMINANT) — ${esc(d.dominantPattern)} — ${d.dominantCount} files${closeSplitNote}</div>\n </div>`;\n\n const devBlocks = buildDeviatingBlocks(d);\n const distBar = buildDistributionBar(d);\n const recText = buildDriftRecommendation(d);\n\n const closeSplitQualifier = domPctVal < 70 && domPctVal >= 50\n ? `<div style=\"margin-top:8px;padding:8px 14px;background:var(--tint-amber);border-left:3px solid var(--drift-amber);border-radius:0;font-size:13px;line-height:1.6;color:var(--text-secondary)\">\n <strong>${esc(d.dominantPattern)}</strong> is dominant at ${domPctVal}%, but the split is close.\n If your team prefers <strong>${esc(d.deviatingFiles[0]?.detectedPattern ?? \"the alternative\")}</strong>, adopt that instead.\n The important thing is consistency, not which pattern wins.\n </div>`\n : \"\";\n\n const rec = recText ? `<div style=\"margin-top:12px;padding:10px 16px;background:var(--tint-cyan);border-left:3px solid var(--border);border-radius:0;font-size:14px;line-height:1.6;color:var(--text-primary)\">\n <span style=\"color:var(--text-secondary);font-weight:700;margin-right:4px\">→</span> ${esc(recText)}\n </div>` : \"\";\n\n return `<div style=\"background:var(--bg-surface);border-radius:0;padding:20px 24px;margin-bottom:10px;border:1px solid var(--border)\">\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap\">\n <span class=\"sev-badge\" style=\"background:${sevColor(d.severity)}\">${sevLabel(d.severity)}</span>\n <span style=\"font-size:15px;font-weight:500;color:var(--text-primary);flex:1\">${esc(d.finding)}</span>\n <span class=\"mono\" style=\"font-size:12px;color:var(--text-tertiary)\">${d.dominantCount}/${d.totalRelevantFiles}</span>\n </div>\n ${domBlock}\n ${devBlocks}\n ${distBar}\n ${rec}\n ${closeSplitQualifier}\n </div>`;\n }).join(\"\");\n\n return `<details ${gi === 0 ? \"open\" : \"\"} style=\"margin-bottom:8px\">\n <summary style=\"cursor:pointer;padding:12px 18px;background:var(--bg-surface);border-radius:0;display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;color:var(--text-primary);list-style:none;border:1px solid var(--border)\">\n <span class=\"chevron\">▶</span>\n ${esc(g.label)}\n <span style=\"margin-left:auto;font-size:12px;color:var(--text-tertiary)\">${g.findings.length} finding${g.findings.length > 1 ? \"s\" : \"\"}</span>\n </summary>\n <div style=\"padding:8px 0\">${cards}</div>\n </details>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">DRIFT FINDINGS <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--text-tertiary);margin-left:8px\">${totalFindings} cross-file contradictions</span></div>\n ${sections}\n</section>`;\n}\n\nfunction buildSecurityMatrix(result: ScanResult): string {\n const secFindings = (result.driftFindings ?? []).filter((d) => d.driftCategory === \"security_posture\");\n if (secFindings.length === 0) return \"\";\n\n const rows = secFindings.flatMap((f) =>\n f.deviatingFiles.map((df) => `<tr style=\"background:var(--tint-red)\">\n <td class=\"mono\" style=\"padding:8px 12px;border-bottom:1px solid var(--border-subtle);font-size:12px;color:var(--text-primary)\">${esc(df.evidence[0]?.code ?? df.path)}</td>\n <td style=\"padding:8px 12px;border-bottom:1px solid var(--border-subtle);text-align:center;color:var(--drift-red);font-weight:700\">✗</td>\n <td class=\"mono\" style=\"padding:8px 12px;border-bottom:1px solid var(--border-subtle);font-size:12px;color:var(--text-tertiary)\">${esc(df.path)}</td>\n <td style=\"padding:8px 12px;border-bottom:1px solid var(--border-subtle);font-size:11px;color:var(--drift-red)\">DRIFT</td>\n </tr>`)\n );\n\n if (rows.length === 0) return \"\";\n\n return `<section class=\"section\">\n <div class=\"label\">SECURITY MATRIX</div>\n <div style=\"overflow-x:auto\">\n <table style=\"width:100%;border-collapse:collapse;font-size:13px\">\n <thead><tr style=\"border-bottom:1px solid var(--border)\">\n <th style=\"text-align:left;padding:8px 12px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Route / Endpoint</th>\n <th style=\"text-align:center;padding:8px 12px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Status</th>\n <th style=\"text-align:left;padding:8px 12px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">File</th>\n <th style=\"padding:8px 12px;font-size:11px;color:var(--text-tertiary);font-weight:600\"></th>\n </tr></thead>\n <tbody>${rows.join(\"\")}</tbody>\n </table>\n </div>\n</section>`;\n}\n\nfunction buildFileRanking(result: ScanResult): string {\n const entries = [...result.perFileScores.entries()];\n const withFindings = entries.filter(([, v]) => v.findings.length > 0).sort((a, b) => a[1].score - b[1].score);\n const clean = entries.filter(([, v]) => v.findings.length === 0);\n\n if (entries.length === 0) return \"\";\n\n const fileCards = withFindings.slice(0, 25).map(([file, data], i) => {\n const color = scoreColor(data.score);\n const { letter } = gradeFor(data.score, 100);\n const driftFindings = data.findings.filter((f) => f.tags?.includes(\"drift\") || f.tags?.includes(\"codedna\"));\n const staticFindings = data.findings.filter((f) => !f.tags?.includes(\"drift\") && !f.tags?.includes(\"codedna\"));\n\n // Deduplicate findings using semantic key — same issue from different analyzers should collapse\n const seenKeys = new Set<string>();\n function findingKey(f: Finding): string {\n // For duplicate-type findings, normalize by sorted file paths\n if ([\"duplicates\", \"codedna-fingerprint\", \"codedna-opseq\", \"ml-duplicate\"].includes(f.analyzerId)) {\n const files = f.locations.map((l) => l.file).filter(Boolean).sort().join(\"::\");\n return `dup::${files || f.message}`;\n }\n // For all others, use analyzer + message as key\n return `${f.analyzerId}::${f.message}`;\n }\n const dedupedDrift = driftFindings.filter((f) => { const k = findingKey(f); if (seenKeys.has(k)) return false; seenKeys.add(k); return true; });\n const dedupedStatic = staticFindings.filter((f) => { const k = findingKey(f); if (seenKeys.has(k)) return false; seenKeys.add(k); return true; });\n\n const findingList = [...dedupedDrift.slice(0, 4), ...dedupedStatic.slice(0, 4)].map((f) => {\n const isDrift = f.tags?.includes(\"drift\") || f.tags?.includes(\"codedna\");\n return `<div style=\"padding:3px 0;font-size:12px;color:var(--text-secondary);display:flex;align-items:baseline;gap:6px\">\n <span style=\"color:${isDrift ? \"var(--drift-orange)\" : \"var(--text-tertiary)\"};font-size:10px;font-weight:600;min-width:42px\">${isDrift ? \"◆ DRIFT\" : \"● STATIC\"}</span>\n <span>${esc(f.message.slice(0, 90))}${f.message.length > 90 ? \"...\" : \"\"}</span>\n </div>`;\n }).join(\"\");\n\n return `<details ${i === 0 ? \"open\" : \"\"} style=\"margin-bottom:4px\" id=\"rank-${esc(file.replace(/[^a-zA-Z0-9]/g, \"-\"))}\">\n <summary style=\"cursor:pointer;padding:10px 16px;background:var(--bg-surface);border-radius:0;display:flex;align-items:center;gap:10px;font-size:13px;border:1px solid var(--border);list-style:none\">\n <div style=\"width:4px;height:22px;border-radius:2px;background:${color}\"></div>\n <span class=\"mono\" style=\"color:var(--text-secondary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\">${esc(file)}</span>\n <span class=\"mono\" style=\"font-weight:600;color:${color}\">${data.score}/100</span>\n <span style=\"font-size:12px;font-weight:600;color:${color}\">${letter}</span>\n <span style=\"font-size:11px;color:var(--text-tertiary)\">${driftFindings.length} drift · ${staticFindings.length} static</span>\n </summary>\n <div style=\"padding:6px 16px 10px 32px\">${findingList}</div>\n </details>`;\n }).join(\"\");\n\n const cleanSection = clean.length > 0 ? `<details style=\"margin-top:8px\">\n <summary style=\"cursor:pointer;padding:8px 16px;font-size:12px;color:var(--text-tertiary);list-style:none\">── ${clean.length} files with no findings ──</summary>\n <div style=\"padding:4px 16px;font-size:12px;color:var(--text-tertiary)\" class=\"mono\">${clean.slice(0, 20).map(([f]) => `<div style=\"padding:1px 0\">${esc(f)} <span style=\"color:var(--intent-green)\">100/100 A ✓</span></div>`).join(\"\")}${clean.length > 20 ? `<div style=\"color:var(--text-tertiary)\">··· ${clean.length - 20} more</div>` : \"\"}</div>\n </details>` : \"\";\n\n return `<section class=\"section\">\n <div class=\"label\">FILE RANKING <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--text-tertiary);margin-left:8px\">${entries.length} files scanned</span></div>\n ${fileCards}\n ${cleanSection}\n</section>`;\n}\n\nfunction buildMlInsights(result: ScanResult): string {\n const mlFindings = result.findings.filter((f) => f.tags?.includes(\"ml\"));\n if (mlFindings.length === 0) return \"\";\n\n const byType: Record<string, typeof mlFindings> = {};\n for (const f of mlFindings) {\n const type = f.analyzerId === \"ml-duplicate\" ? \"Semantic Duplicates\"\n : f.analyzerId === \"ml-intent\" ? \"Intent Mismatches\"\n : f.analyzerId === \"ml-anomaly\" ? \"Pattern Anomalies\" : \"Other\";\n if (!byType[type]) byType[type] = [];\n byType[type].push(f);\n }\n\n const sections = Object.entries(byType).map(([type, findings]) => {\n const icon = type === \"Semantic Duplicates\" ? \"🔁\" : type === \"Intent Mismatches\" ? \"🎯\" : \"🔎\";\n const typeColor = type === \"Semantic Duplicates\" ? \"var(--drift-red)\" : type === \"Intent Mismatches\" ? \"var(--drift-orange)\" : \"var(--info-blue)\";\n\n const cards = findings.map((f) => {\n const sColor = sevColor(f.severity);\n const files = f.locations.map((l) => l.file).filter(Boolean);\n // Add actionable recommendations for anomalies\n let recommendation = \"\";\n if (f.analyzerId === \"ml-anomaly\" && files.length > 0) {\n const funcName = f.message.match(/Pattern outlier: (.+?) doesn/)?.[1]?.split(\"::\").pop() ?? \"\";\n const fileName = files[0]?.split(\"/\").pop() ?? \"\";\n if (funcName && fileName) {\n recommendation = `<div style=\"margin-top:6px;padding:6px 12px;background:var(--tint-cyan);border-left:2px solid var(--border);border-radius:0 4px 4px 0;font-size:12px;color:var(--text-secondary)\"><span style=\"color:var(--text-secondary);font-weight:700;margin-right:4px\">→</span> Consider extracting ${esc(funcName)} from ${esc(fileName)} into a shared utils package, or verify it belongs in this module.</div>`;\n }\n }\n return `<div style=\"background:var(--bg-surface);border-radius:0;padding:14px 18px;margin-bottom:8px;border-left:3px solid ${sColor}\">\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:6px\">\n <span class=\"sev-badge\" style=\"background:${sColor}\">${sevLabel(f.severity)}</span>\n <span style=\"font-size:14px;font-weight:500;color:var(--text-primary);flex:1\">${esc(f.message)}</span>\n <span class=\"mono\" style=\"font-size:11px;color:var(--text-tertiary)\">${Math.round(f.confidence * 100)}%</span>\n </div>\n ${files.length > 0 ? `<div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary);margin-top:4px\">${files.map((fp) => esc(fp)).join(\" · \")}</div>` : \"\"}\n ${recommendation}\n </div>`;\n }).join(\"\");\n\n return `<details open style=\"margin-bottom:10px\">\n <summary style=\"cursor:pointer;padding:10px 16px;background:var(--bg-surface);border-radius:0;display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:var(--text-primary);list-style:none;border:1px solid var(--border)\">\n <span class=\"chevron\">▶</span>\n <span>${icon}</span>\n <span style=\"color:${typeColor}\">${esc(type)}</span>\n <span style=\"margin-left:auto;font-size:12px;color:var(--text-tertiary)\">${findings.length} finding${findings.length > 1 ? \"s\" : \"\"}</span>\n </summary>\n <div style=\"padding:8px 0\">${cards}</div>\n </details>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">AI ANALYSIS <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--info-blue);margin-left:8px\">Deep Layer · Code Embeddings · ${mlFindings.length} findings</span></div>\n <p style=\"font-size:13px;color:var(--text-secondary);margin-bottom:16px;line-height:1.6\">\n These findings were detected by VibeDrift’s AI inference API. Only function snippets (not full files) were sent for analysis — snippets are processed in memory and not stored.\n Functions were embedded as 768-dimensional vectors and compared for semantic similarity, name-body alignment, and clustering anomalies.\n </p>\n ${sections}\n</section>`;\n}\n\nfunction buildStaticFindings(result: ScanResult): string {\n const statics = result.findings.filter((f) => !f.tags?.includes(\"drift\") && !f.tags?.includes(\"codedna\") && !f.tags?.includes(\"ml\"));\n if (statics.length === 0) return \"\";\n\n const sorted = [...statics].sort((a, b) => {\n const sev = { error: 0, warning: 1, info: 2 };\n return (sev[a.severity as keyof typeof sev] ?? 2) - (sev[b.severity as keyof typeof sev] ?? 2);\n });\n\n const rows = sorted.slice(0, 30).map((f) => {\n const sColor = f.severity === \"error\" ? \"var(--drift-orange)\" : f.severity === \"warning\" ? \"var(--drift-amber)\" : \"var(--info-blue)\";\n const loc = f.locations[0];\n return `<tr>\n <td style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle)\"><span class=\"sev-badge\" style=\"background:${sColor};font-size:10px\">${f.severity === \"error\" ? \"ERROR\" : f.severity === \"warning\" ? \"WARN\" : \"INFO\"}</span></td>\n <td style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle);font-size:12px;color:var(--text-tertiary)\">${esc(f.analyzerId)}</td>\n <td style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle);font-size:13px;color:var(--text-primary)\">${esc(f.message.slice(0, 80))}${f.message.length > 80 ? \"...\" : \"\"}</td>\n <td class=\"mono\" style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle);font-size:11px;color:var(--text-secondary);white-space:nowrap\">${loc ? esc(shortPath(loc.file)) + (loc.line ? \":\" + loc.line : \"\") : \"\"}</td>\n <td class=\"mono\" style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle);font-size:11px;color:var(--text-tertiary)\">${Math.round(f.confidence * 100)}%</td>\n </tr>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">STATIC ANALYSIS <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--text-tertiary);margin-left:8px\">${statics.length} findings</span></div>\n <div style=\"overflow-x:auto\">\n <table style=\"width:100%;border-collapse:collapse;font-size:13px\">\n <thead><tr style=\"border-bottom:1px solid var(--border)\">\n <th style=\"text-align:left;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\" data-sort>Sev</th>\n <th style=\"text-align:left;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\" data-sort>Analyzer</th>\n <th style=\"text-align:left;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Finding</th>\n <th style=\"text-align:left;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">File</th>\n <th style=\"text-align:right;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Conf</th>\n </tr></thead>\n <tbody>${rows}</tbody>\n </table>\n </div>\n ${statics.length > 30 ? `<div style=\"font-size:12px;color:var(--text-tertiary);margin-top:8px\">${statics.length - 30} more findings not shown</div>` : \"\"}\n</section>`;\n}\n\nfunction buildDeepInsights(result: ScanResult): string {\n const insights = result.deepInsights ?? [];\n if (insights.length === 0) return \"\";\n\n const cards = insights.map((ins) => {\n const sColor = sevColor(ins.severity);\n return `<div style=\"background:var(--bg-surface);border-left:3px solid var(--info-blue);border-radius:0;padding:16px 20px;margin-bottom:10px\">\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:6px\">\n <span class=\"sev-badge\" style=\"background:${sColor}\">${sevLabel(ins.severity)}</span>\n <span style=\"font-size:14px;font-weight:500;color:var(--text-primary)\">${esc(ins.title)}</span>\n </div>\n <p style=\"font-size:13px;color:var(--text-secondary);line-height:1.6;margin:0\">${esc(ins.description)}</p>\n ${ins.relatedFiles.length > 0 ? `<div class=\"mono\" style=\"font-size:11px;color:var(--text-tertiary);margin-top:6px\">${ins.relatedFiles.slice(0, 4).map((f) => esc(f)).join(\" · \")}</div>` : \"\"}\n ${ins.recommendation ? `<div style=\"margin-top:8px;padding:8px 14px;background:var(--tint-cyan);border-left:3px solid var(--border);border-radius:0;font-size:13px;color:var(--text-primary)\"><span style=\"color:var(--text-secondary);font-weight:700;margin-right:4px\">→</span> ${esc(ins.recommendation)}</div>` : \"\"}\n </div>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">DEEP ANALYSIS INSIGHTS <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--info-blue);margin-left:8px\">AI-powered · ${insights.length} insights</span></div>\n ${cards}\n</section>`;\n}\n\nfunction buildSequenceCards(similarities: any[]): string {\n const seqCards = similarities.slice(0, 6).map((sim: any) => {\n const pct = Math.round(sim.similarity * 100);\n const color = pct >= 90 ? \"var(--drift-red)\" : \"var(--drift-orange)\";\n const matchLabel = pct >= 100 ? \"Exact duplicate\" : pct >= 90 ? \"Near-exact match\" : \"Similar\";\n return `<div style=\"display:flex;align-items:center;gap:12px;padding:6px 0;border-bottom:1px solid var(--border-subtle)\">\n <span class=\"mono\" style=\"min-width:40px;font-weight:700;color:${color}\">${pct}%</span>\n <div style=\"flex:1\">\n <span style=\"font-size:11px;font-weight:600;color:${color};margin-right:6px\">${matchLabel}</span>\n <span class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\">${esc(sim.functionA.name)}()</span>\n <span style=\"font-size:11px;color:var(--text-tertiary)\"> in ${esc(shortPath(sim.functionA.relativePath || sim.functionA.file))}</span>\n <span style=\"color:var(--text-tertiary);margin:0 4px\">↔</span>\n <span class=\"mono\" style=\"font-size:12px;color:var(--drift-orange)\">${esc(sim.functionB.name)}()</span>\n <span style=\"font-size:11px;color:var(--text-tertiary)\"> in ${esc(shortPath(sim.functionB.relativePath || sim.functionB.file))}</span>\n </div>\n </div>`;\n }).join(\"\");\n return `<details style=\"margin-bottom:8px\"><summary style=\"cursor:pointer;font-size:13px;font-weight:500;color:var(--text-primary);list-style:none;padding:6px 0\"><span class=\"chevron\">▶</span> Operation sequence matches <span style=\"color:var(--text-tertiary);font-weight:400\">${similarities.length} pairs</span></summary><div style=\"padding:4px 0 4px 16px\">${seqCards}</div></details>`;\n}\n\nfunction buildDeviationCards(justifications: any[]): string {\n const devCards = justifications.map((dj: any) => {\n const vColor = dj.verdict === \"likely_justified\" ? \"var(--intent-green)\" : dj.verdict === \"likely_accidental\" ? \"var(--drift-red)\" : \"var(--drift-amber)\";\n const vLabel = dj.verdict === \"likely_justified\" ? \"JUSTIFIED\" : dj.verdict === \"likely_accidental\" ? \"ACCIDENTAL\" : \"UNCERTAIN\";\n return `<div style=\"display:flex;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid var(--border-subtle)\">\n <span class=\"sev-badge\" style=\"background:${vColor};min-width:80px;text-align:center\">${vLabel}</span>\n <span class=\"mono\" style=\"font-size:12px;color:var(--text-secondary);flex:1\">${esc(shortPath(dj.relativePath || dj.file))}</span>\n <span style=\"font-size:12px;color:var(--text-tertiary)\">${esc(dj.deviatingPattern)} vs ${esc(dj.dominantPattern)}</span>\n </div>`;\n }).join(\"\");\n return `<details style=\"margin-bottom:8px\"><summary style=\"cursor:pointer;font-size:13px;font-weight:500;color:var(--text-primary);list-style:none;padding:6px 0\"><span class=\"chevron\">▶</span> Deviation analysis <span style=\"color:var(--text-tertiary);font-weight:400\">${justifications.length}</span></summary><div style=\"padding:4px 0 4px 16px\">${devCards}</div></details>`;\n}\n\nfunction buildCodeDnaSummary(result: ScanResult): string {\n const dna = result.codeDnaResult;\n if (!dna) return \"\";\n\n const hasDupes = dna.duplicateGroups?.length > 0;\n const hasSeqs = dna.sequenceSimilarities?.length > 0;\n const hasTaint = dna.taintFlows?.length > 0;\n const hasDevs = dna.deviationJustifications?.length > 0;\n\n if (!hasDupes && !hasSeqs && !hasTaint && !hasDevs) return \"\";\n\n const parts: string[] = [];\n\n if (hasSeqs) {\n parts.push(buildSequenceCards(dna.sequenceSimilarities));\n }\n\n if (hasDevs) {\n parts.push(buildDeviationCards(dna.deviationJustifications));\n }\n\n if (parts.length === 0) return \"\";\n\n const totalFindings = dna.findings?.length ?? 0;\n const timeMs = dna.timings?.totalMs ?? 0;\n\n return `<section class=\"section\">\n <div class=\"label\">CODE DNA <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--intent-green);margin-left:8px\">Layer 1.7 · ${totalFindings} findings · ${dna.functions?.length ?? 0} functions · ${timeMs}ms</span></div>\n ${parts.join(\"\")}\n</section>`;\n}\n\nfunction buildFooter(result: ScanResult): string {\n const hasDeep = result.findings.some((f) => f.tags?.includes(\"ml\")) || !!result.aiSummary;\n const premiumUpsell = !hasDeep ? `<div style=\"margin-top:16px;padding:14px 18px;background:var(--bg-surface);border-radius:0;border-left:3px solid var(--border);text-align:left;font-size:13px;color:var(--text-secondary);max-width:520px;margin-left:auto;margin-right:auto\">\n Want AI-powered deep analysis? Sign in once with <code class=\"mono\" style=\"color:var(--text-primary);background:var(--bg-code);padding:2px 6px;border-radius:0\">vibedrift login</code> then run:<br>\n <code class=\"mono\" style=\"color:var(--text-primary);background:var(--bg-code);padding:2px 6px;border-radius:0;margin-top:4px;display:inline-block\">vibedrift . --deep</code>\n <span data-copy=\"vibedrift . --deep\" style=\"cursor:pointer;margin-left:6px;font-size:11px;color:var(--text-tertiary)\">[copy]</span>\n </div>` : \"\";\n\n return `<footer style=\"border-top:1px solid var(--border);padding-top:28px;margin-top:48px;text-align:center;color:var(--text-tertiary);font-size:13px\">\n <div style=\"display:flex;gap:8px;justify-content:center;margin-bottom:20px;flex-wrap:wrap\">\n <button onclick=\"exportCSV()\" class=\"export-btn\">Export CSV</button>\n <button onclick=\"exportDOCX()\" class=\"export-btn\">Export DOCX</button>\n <button onclick=\"window.print()\" class=\"export-btn\">Export PDF</button>\n </div>\n <p>Generated by <span style=\"color:var(--text-primary);font-weight:600\">VibeDrift v${getVersion()}</span></p>\n <p style=\"margin:4px 0\">${result.context.files.length} files · ${result.context.totalLines.toLocaleString()} lines · ${(result.scanTimeMs / 1000).toFixed(1)}s</p>\n <p style=\"margin:4px 0;font-size:12px\">${hasDeep\n ? \"Function snippets were sent to VibeDrift’s AI API for analysis. No full files transmitted. Snippets processed in memory and not stored.\"\n : \"No data sent externally.\"}</p>\n <p style=\"margin-top:10px\">Fix the top issues and re-scan: <code class=\"mono\" style=\"background:var(--bg-code);padding:2px 6px;border-radius:0;color:var(--text-primary)\">vibedrift .</code> <span data-copy=\"vibedrift .\" style=\"cursor:pointer;font-size:11px;color:var(--text-tertiary)\">[copy]</span></p>\n ${premiumUpsell}\n <div style=\"margin-top:16px;padding:12px 18px;background:var(--bg-surface);border-radius:0;display:inline-block;text-align:left\">\n <div style=\"font-size:11px;color:var(--text-tertiary);margin-bottom:6px\">Add to your README:</div>\n <code class=\"mono\" style=\"font-size:11px;color:var(--text-secondary)\">[}-${result.compositeScore >= 75 ? \"brightgreen\" : result.compositeScore >= 50 ? \"yellow\" : \"red\"})](https://vibedrift.ai)</code>\n <span data-copy=\"[}-${result.compositeScore >= 75 ? \"brightgreen\" : result.compositeScore >= 50 ? \"yellow\" : \"red\"})](https://vibedrift.ai)\" style=\"cursor:pointer;margin-left:8px;font-size:11px;color:var(--text-tertiary)\">[copy]</span>\n </div>\n <p style=\"margin-top:16px;font-size:11px;color:var(--border)\">vibedrift.ai · Built by the creator of <a href=\"https://thevibelang.org\" style=\"color:var(--text-tertiary);text-decoration:none\">VibeLang</a></p>\n</footer>`;\n}\n\n// ──── Embedded data for client-side exports ────\n\nfunction buildEmbeddedData(result: ScanResult): string {\n const dna = result.codeDnaResult;\n\n const data = {\n version: getVersion(),\n project: result.context.rootDir.split(\"/\").pop() ?? \"project\",\n score: result.compositeScore,\n maxScore: result.maxCompositeScore,\n fileCount: result.context.files.length,\n totalLines: result.context.totalLines,\n scanTimeMs: result.scanTimeMs,\n driftFindings: (result.driftFindings ?? []).map((d) => ({\n severity: d.severity,\n category: d.driftCategory,\n finding: d.finding,\n dominant: d.dominantPattern,\n consistency: d.consistencyScore,\n devFiles: d.deviatingFiles.map((f) => f.path).join(\"; \"),\n recommendation: d.recommendation,\n })),\n findings: result.findings.map((f) => ({\n severity: f.severity,\n analyzer: f.analyzerId,\n message: f.message,\n file: f.locations[0]?.file ?? \"\",\n line: f.locations[0]?.line ?? \"\",\n confidence: Math.round(f.confidence * 100),\n })),\n fileScores: [...result.perFileScores.entries()].sort((a, b) => a[1].score - b[1].score).map(([path, data]) => ({\n file: path,\n score: data.score,\n findings: data.findings.length,\n })),\n codeDna: dna ? {\n sequences: (dna.sequenceSimilarities ?? []).map((s: any) => ({\n a: s.functionA.name + \"() in \" + (s.functionA.relativePath || s.functionA.file),\n b: s.functionB.name + \"() in \" + (s.functionB.relativePath || s.functionB.file),\n pct: Math.round(s.similarity * 100),\n })),\n deviations: (dna.deviationJustifications ?? []).map((dj: any) => ({\n file: dj.relativePath || dj.file,\n verdict: dj.verdict,\n pattern: dj.deviatingPattern + \" vs \" + dj.dominantPattern,\n })),\n } : null,\n deepInsights: (result.deepInsights ?? []).map((ins) => ({\n severity: ins.severity,\n title: ins.title,\n description: ins.description,\n recommendation: ins.recommendation ?? \"\",\n })),\n };\n\n return JSON.stringify(data);\n}\n\n// ──── Main Report ────\n\nexport function renderHtmlReport(result: ScanResult): string {\n const projectName = result.context.rootDir.split(\"/\").pop() ?? \"project\";\n const { compositeScore, maxCompositeScore } = result;\n const { letter, color: gradeColor } = gradeFor(compositeScore, maxCompositeScore);\n const intentPatterns = extractIntentPatterns(result);\n const fileCoherence = buildFileCoherence(result);\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>VibeDrift Report — ${esc(projectName)}</title>\n<style>\n:root {\n --bg-page: #121214;\n --bg-surface: #1A1A1C;\n --bg-surface-hover: #1F1F22;\n --bg-code: #16161A;\n --text-primary: #E0E0D8;\n --text-secondary: #9A9A92;\n --text-tertiary: #757570;\n --brand-cyan: #FFD000;\n --link: #888880;\n --intent-green: #44DD66;\n --drift-amber: #C8A000;\n --drift-orange: #CC7000;\n --drift-red: #DD3333;\n --info-blue: #00AAA0;\n --grade-a: #44DD66;\n --grade-b: #44DD66;\n --grade-c: #C8A000;\n --grade-d: #CC7000;\n --grade-f: #DD3333;\n --border: #26262A;\n --border-subtle: rgba(38, 38, 42, 0.5);\n --tint-green: rgba(68, 221, 102, 0.04);\n --tint-amber: rgba(200, 160, 0, 0.03);\n --tint-orange: rgba(204, 112, 0, 0.04);\n --tint-red: rgba(221, 51, 51, 0.04);\n --tint-cyan: rgba(255, 208, 0, 0.02);\n --tint-blue: rgba(0, 170, 160, 0.04);\n}\n@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap');\n* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { background: var(--bg-page); color: var(--text-primary); font-family: 'JetBrains Mono', 'SF Mono', 'Consolas', monospace; font-size: 14px; line-height: 1.6; -webkit-font-smoothing: antialiased; }\ncode, .mono { font-family: 'JetBrains Mono', 'SF Mono', 'Consolas', monospace; font-size: 13px; }\nh1, h2, h3, .heading { font-family: 'Space Grotesk', -apple-system, sans-serif; }\n.page { max-width: 960px; margin: 0 auto; padding: 40px 32px; }\n.section { margin-bottom: 48px; }\n.label { font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--text-tertiary); margin-bottom: 16px; }\n.sev-badge { display: inline-block; padding: 2px 8px; font-size: 11px; font-weight: 700; color: var(--bg-page); text-transform: uppercase; letter-spacing: 0.5px; }\n.sticky-header { position: fixed; top: 0; left: 0; right: 0; height: 44px; background: rgba(18,18,20,0.95); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; padding: 0 32px; z-index: 100; opacity: 0; pointer-events: none; transition: opacity 200ms; font-size: 13px; }\n.sticky-header.visible { opacity: 1; pointer-events: auto; }\ndetails summary { list-style: none; }\ndetails summary::-webkit-details-marker { display: none; }\ndetails[open] > summary .chevron { display: inline-block; transform: rotate(90deg); }\n.chevron { display: inline-block; transition: transform 150ms; margin-right: 6px; font-size: 10px; }\na { color: var(--link); text-decoration: none; }\na:hover { color: var(--text-primary); }\n[data-scroll-to] { cursor: pointer; }\n[data-scroll-to]:hover { text-decoration: underline; }\nth[data-sort] { cursor: pointer; }\nth[data-sort]:hover { color: var(--text-primary); }\n.export-btn { background: var(--bg-surface); color: var(--text-secondary); border: 1px solid var(--border); padding: 6px 14px; font-size: 12px; font-weight: 700; cursor: pointer; transition: background 150ms, color 150ms; font-family: inherit; letter-spacing: 0.5px; text-transform: uppercase; }\n.export-btn:hover { background: var(--bg-surface-hover); color: var(--text-primary); }\n::selection { background: #FFD000; color: #121214; }\n::-webkit-scrollbar { width: 4px; }\n::-webkit-scrollbar-track { background: var(--bg-page); }\n::-webkit-scrollbar-thumb { background: #3A3A3D; }\n::-webkit-scrollbar-thumb:hover { background: #555; }\n@media (max-width: 768px) {\n .page { padding: 16px 10px; }\n .section { margin-bottom: 28px; }\n .label { font-size: 10px; letter-spacing: 1.5px; margin-bottom: 10px; }\n\n /* Score hero: stack vertically */\n .score-layout { flex-direction: column !important; gap: 16px !important; }\n .score-layout > div { min-width: 0 !important; width: 100% !important; }\n\n /* Category bars: stack, remove min-widths */\n .score-layout [style*=\"min-width:300px\"],\n .score-layout [style*=\"min-width:280px\"],\n .score-layout [style*=\"min-width:200px\"],\n .score-layout [style*=\"min-width:120px\"] {\n min-width: 0 !important; width: 100% !important;\n }\n\n /* Radar chart: constrain to viewport */\n svg[viewBox] { max-width: 100% !important; }\n\n /* Strongest/Weakest cards: 2-col, tighter */\n .section > div[style*=\"display:flex\"][style*=\"gap:12px\"] {\n gap: 8px !important;\n }\n .section > div[style*=\"display:flex\"] > div[style*=\"min-width:160px\"] {\n min-width: 0 !important; flex: 1 !important;\n }\n\n /* Findings list: tighter padding */\n details > div { padding: 8px 10px !important; }\n details summary { padding: 10px 12px !important; font-size: 13px !important; }\n\n /* File ranking table: horizontal scroll */\n table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }\n table th, table td { padding: 5px 8px !important; font-size: 11px !important; }\n\n /* Code snippets: wrap text */\n pre, code { white-space: pre-wrap !important; word-break: break-word !important; font-size: 12px !important; }\n\n /* Drift coherence bars: full width */\n .section div[style*=\"display:flex\"][style*=\"gap:40px\"] {\n flex-direction: column !important; gap: 16px !important;\n }\n\n /* Summary + AI section: stack */\n .section div[style*=\"display:flex\"][style*=\"gap:20px\"] {\n flex-direction: column !important; gap: 12px !important;\n }\n\n /* Sticky header: tighter padding */\n .sticky-header { padding: 0 12px; font-size: 12px; }\n .sticky-project { display: none !important; }\n\n /* Export buttons: smaller */\n .export-btn { padding: 5px 10px; font-size: 11px; }\n\n /* Code DNA / ML sections: reduce gap */\n .section div[style*=\"gap:10px\"] { gap: 6px !important; }\n\n /* Hide long file paths, truncate */\n td[data-scroll-to] { max-width: 140px !important; }\n}\n@media (max-width: 480px) {\n .page { padding: 12px 8px; }\n body { font-size: 13px; }\n .label { font-size: 9px; }\n .sticky-header { height: 38px; }\n table th, table td { padding: 4px 6px !important; font-size: 10px !important; }\n}\n@media print {\n body { background: #fff; color: #111; font-size: 11px; line-height: 1.4; }\n .sticky-header, .export-btn, [data-copy] { display: none !important; }\n .page { max-width: 100%; padding: 0; }\n .section { margin-bottom: 24px; page-break-inside: avoid; }\n details, details[open] > div, details > div { display: block !important; }\n details > summary { list-style: none; }\n details > summary .chevron { display: none; }\n .sev-badge { border: 1px solid currentColor; background: transparent !important; color: inherit !important; }\n code, .mono { font-size: 10px; }\n * { color-adjust: exact; -webkit-print-color-adjust: exact; print-color-adjust: exact; }\n}\n</style>\n</head>\n<body>\n\n<div class=\"sticky-header\" id=\"sticky-header\">\n <div class=\"sticky-project\" style=\"display:flex;align-items:center;gap:8px\">\n <span style=\"display:inline-block;width:10px;height:10px;background:var(--brand-cyan)\"></span>\n <span style=\"color:var(--text-primary);font-weight:700;letter-spacing:2px;font-size:12px\">VIBEDRIFT</span>\n <span style=\"color:var(--text-tertiary)\">·</span>\n <span style=\"color:var(--text-secondary)\">${esc(projectName)}</span>\n </div>\n <div style=\"display:flex;align-items:center;gap:8px\">\n <span class=\"mono\" style=\"font-weight:700;color:${gradeColor}\">${compositeScore}/${maxCompositeScore}</span>\n <span style=\"padding:2px 8px;border-radius:0;font-size:11px;font-weight:600;background:${gradeColor}18;color:${gradeColor}\">${letter}</span>\n </div>\n</div>\n\n<div class=\"page\">\n\n${buildHeader(result)}\n\n\n${buildAiSummaryWidget(result)}\n\n${buildScoreSection(result)}\n\n${buildRadarSection(result)}\n\n${buildIntentDefinition(intentPatterns)}\n\n${buildCoherenceMatrix(fileCoherence)}\n\n${buildFixFirst(result)}\n\n${buildDriftFindings(result)}\n\n${buildCodeDnaSummary(result)}\n\n${buildSecurityMatrix(result)}\n\n${buildFileRanking(result)}\n\n${buildMlInsights(result)}\n\n${buildStaticFindings(result)}\n\n${buildDeepInsights(result)}\n\n${buildFooter(result)}\n\n</div>\n\n<script>\nwindow.__VIBEDRIFT_DATA = ${buildEmbeddedData(result)};\n</script>\n\n<script>\n// Sticky header\nconst hdr = document.getElementById('report-header');\nconst sticky = document.getElementById('sticky-header');\nif (hdr && sticky) {\n new IntersectionObserver(([e]) => {\n sticky.classList.toggle('visible', !e.isIntersecting);\n }, { threshold: 0 }).observe(hdr);\n}\n\n// Collapsible\ndocument.querySelectorAll('[data-collapse]').forEach(t => {\n t.addEventListener('click', () => {\n const el = document.getElementById(t.dataset.collapse);\n if (el) el.style.display = el.style.display === 'none' ? '' : 'none';\n });\n});\n\n// Scroll-to\ndocument.querySelectorAll('[data-scroll-to]').forEach(l => {\n l.addEventListener('click', e => {\n e.preventDefault();\n const t = document.getElementById(l.dataset.scrollTo);\n if (t) { t.scrollIntoView({ behavior: 'smooth', block: 'center' }); t.style.background = 'rgba(0,212,255,0.06)'; setTimeout(() => t.style.background = '', 2000); }\n });\n});\n\n// Copy\ndocument.querySelectorAll('[data-copy]').forEach(b => {\n b.addEventListener('click', () => {\n navigator.clipboard.writeText(b.dataset.copy).then(() => { const o = b.textContent; b.textContent = 'Copied!'; setTimeout(() => b.textContent = o, 1500); });\n });\n});\n\n// Tooltips\ndocument.querySelectorAll('[data-tooltip]').forEach(el => {\n el.addEventListener('mouseenter', e => {\n const t = document.createElement('div');\n t.textContent = el.dataset.tooltip;\n t.style.cssText = 'position:fixed;background:var(--bg-surface);color:var(--text-primary);padding:6px 10px;border-radius:0;font-size:12px;border:1px solid var(--border);z-index:200;pointer-events:none;max-width:250px';\n document.body.appendChild(t);\n const r = el.getBoundingClientRect();\n t.style.left = r.left + 'px'; t.style.top = (r.bottom + 6) + 'px';\n el._tip = t;\n });\n el.addEventListener('mouseleave', () => { if (el._tip) { el._tip.remove(); el._tip = null; } });\n});\n\n// Table sort\ndocument.querySelectorAll('th[data-sort]').forEach(th => {\n th.addEventListener('click', () => {\n const tb = th.closest('table').querySelector('tbody');\n const rows = Array.from(tb.querySelectorAll('tr'));\n const col = th.cellIndex;\n const dir = th.dataset.dir === 'asc' ? 'desc' : 'asc';\n th.dataset.dir = dir;\n rows.sort((a, b) => {\n const av = a.cells[col]?.textContent?.trim() ?? '';\n const bv = b.cells[col]?.textContent?.trim() ?? '';\n return dir === 'asc' ? av.localeCompare(bv) : bv.localeCompare(av);\n });\n rows.forEach(r => tb.appendChild(r));\n });\n});\n\n// ──── Export: CSV ────\nfunction exportCSV() {\n const d = window.__VIBEDRIFT_DATA;\n if (!d) { alert('Report data not available'); return; }\n const esc = v => { const s = String(v); return s.includes(',') || s.includes('\"') || s.includes('\\\\n') ? '\"'+s.replace(/\"/g,'\"\"')+'\"' : s; };\n const row = (...c) => c.map(esc).join(',');\n const lines = [];\n lines.push('VIBEDRIFT REPORT');\n lines.push(row('Project', d.project));\n lines.push(row('Score', d.score + '/' + d.maxScore));\n lines.push(row('Files', d.fileCount));\n lines.push(row('Lines', d.totalLines));\n lines.push('');\n lines.push('DRIFT FINDINGS');\n lines.push(row('Severity','Category','Finding','Dominant Pattern','Consistency %','Deviating Files','Recommendation'));\n for (const f of d.driftFindings || []) lines.push(row(f.severity, f.category, f.finding, f.dominant, f.consistency, f.devFiles, f.recommendation));\n lines.push('');\n lines.push('ALL FINDINGS');\n lines.push(row('Severity','Analyzer','Message','File','Line','Confidence'));\n for (const f of d.findings || []) lines.push(row(f.severity, f.analyzer, f.message, f.file, f.line, f.confidence));\n lines.push('');\n lines.push('FILE SCORES');\n lines.push(row('File','Score','Findings'));\n for (const f of d.fileScores || []) lines.push(row(f.file, f.score, f.findings));\n\n const blob = new Blob([lines.join('\\\\n')], { type: 'text/csv' });\n const a = document.createElement('a');\n a.href = URL.createObjectURL(blob);\n a.download = d.project + '-vibedrift.csv';\n a.click();\n URL.revokeObjectURL(a.href);\n}\n\n// ──── Export: DOCX (Word-compatible HTML) ────\nfunction buildDocxFindingsHtml(d) {\n let html = '';\n html += '<h1>Drift Findings</h1>';\n for (const f of d.driftFindings || []) {\n const sev = f.severity === 'error' ? 'critical' : f.severity;\n html += '<h2><span class=\"sev-' + sev + '\">[' + (sev === 'critical' ? 'CRITICAL' : sev.toUpperCase()) + ']</span> ' + esc2(f.finding) + '</h2>';\n html += '<p>Category: ' + esc2(f.category) + ' | Consistency: ' + f.consistency + '%</p>';\n html += '<div class=\"intent\"><strong>INTENT (Dominant):</strong> ' + esc2(f.dominant) + '</div>';\n html += '<div class=\"drift\"><strong>DEVIATING:</strong> ' + esc2(f.devFiles) + '</div>';\n if (f.recommendation) html += '<div class=\"rec\"><strong>Fix:</strong> ' + esc2(f.recommendation) + '</div>';\n }\n html += '<div class=\"page-break\"></div><h1>All Findings</h1>';\n html += '<table><tr><th>Severity</th><th>Analyzer</th><th>Finding</th><th>File</th><th>Line</th></tr>';\n for (const f of d.findings || []) {\n html += '<tr><td class=\"sev-' + (f.severity === 'error' ? 'critical' : f.severity) + '\">' + f.severity.toUpperCase() + '</td>';\n html += '<td>' + esc2(f.analyzer) + '</td><td>' + esc2(f.message) + '</td>';\n html += '<td><code>' + esc2(f.file) + '</code></td><td>' + f.line + '</td></tr>';\n }\n html += '</table>';\n return html;\n}\n\nfunction buildDocxScoresHtml(d) {\n let html = '';\n html += '<div class=\"page-break\"></div><h1>File Scores</h1>';\n html += '<table><tr><th>File</th><th>Score</th><th>Findings</th></tr>';\n for (const f of d.fileScores || []) {\n html += '<tr><td><code>' + esc2(f.file) + '</code></td><td>' + f.score + '/100</td><td>' + f.findings + '</td></tr>';\n }\n html += '</table>';\n if (d.codeDna) {\n html += '<div class=\"page-break\"></div><h1>Code DNA Analysis</h1>';\n if (d.codeDna.sequences && d.codeDna.sequences.length > 0) {\n html += '<h2>Operation Sequence Matches</h2><table><tr><th>Function A</th><th>Function B</th><th>Similarity</th></tr>';\n for (const s of d.codeDna.sequences) html += '<tr><td>' + esc2(s.a) + '</td><td>' + esc2(s.b) + '</td><td>' + s.pct + '%</td></tr>';\n html += '</table>';\n }\n if (d.codeDna.deviations && d.codeDna.deviations.length > 0) {\n html += '<h2>Deviation Analysis</h2><table><tr><th>File</th><th>Verdict</th><th>Pattern</th></tr>';\n for (const dv of d.codeDna.deviations) html += '<tr><td>' + esc2(dv.file) + '</td><td>' + dv.verdict + '</td><td>' + esc2(dv.pattern) + '</td></tr>';\n html += '</table>';\n }\n }\n if (d.deepInsights && d.deepInsights.length > 0) {\n html += '<div class=\"page-break\"></div><h1>Deep Analysis Insights (AI-Powered)</h1>';\n for (const ins of d.deepInsights) {\n html += '<h3>[' + ins.severity.toUpperCase() + '] ' + esc2(ins.title) + '</h3>';\n html += '<p>' + esc2(ins.description) + '</p>';\n if (ins.recommendation) html += '<div class=\"rec\"><strong>Fix:</strong> ' + esc2(ins.recommendation) + '</div>';\n }\n }\n return html;\n}\n\nfunction exportDOCX() {\n const d = window.__VIBEDRIFT_DATA;\n if (!d) { alert('Report data not available'); return; }\n\n let html = '<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:w=\"urn:schemas-microsoft-com:office:word\"><head><meta charset=\"utf-8\"><style>';\n html += 'body{font-family:Calibri,sans-serif;font-size:11pt;color:#222;margin:40px}';\n html += 'h1{font-size:20pt;color:#0B0F15;border-bottom:2px solid #00D4FF;padding-bottom:8px;margin-top:28px}';\n html += 'h2{font-size:14pt;color:#333;margin-top:20px}';\n html += 'h3{font-size:12pt;color:#555;margin-top:14px}';\n html += 'table{border-collapse:collapse;width:100%;margin:10px 0}';\n html += 'th,td{border:1px solid #ddd;padding:6px 10px;text-align:left;font-size:10pt}';\n html += 'th{background:#f0f4f8;font-weight:600}';\n html += '.sev-critical{color:#dc2626;font-weight:700} .sev-warning{color:#d97706;font-weight:700} .sev-info{color:#2563eb}';\n html += '.intent{background:#ecfdf5;border-left:3px solid #10b981;padding:8px 12px;margin:6px 0}';\n html += '.drift{background:#fff7ed;border-left:3px solid #f97316;padding:8px 12px;margin:6px 0}';\n html += '.rec{background:#f0f9ff;border-left:3px solid #0ea5e9;padding:8px 12px;margin:6px 0}';\n html += 'code{font-family:Consolas,monospace;font-size:9pt;background:#f5f5f5;padding:1px 4px}';\n html += '.page-break{page-break-before:always}';\n html += '</style></head><body>';\n\n html += '<div style=\"text-align:center;margin-bottom:30px\">';\n html += '<h1 style=\"border:none;font-size:28pt;color:#00D4FF\">VIBEDRIFT REPORT</h1>';\n html += '<p style=\"font-size:16pt;color:#333\">' + esc2(d.project) + '</p>';\n html += '<p>' + d.fileCount + ' files · ' + d.totalLines.toLocaleString() + ' LOC · Score: <strong>' + d.score + '/' + d.maxScore + '</strong></p>';\n html += '</div>';\n\n html += buildDocxFindingsHtml(d);\n html += buildDocxScoresHtml(d);\n\n html += '<hr><p style=\"color:#999;font-size:9pt\">Generated by VibeDrift v' + d.version + ' | ' + d.fileCount + ' files | No data sent externally</p>';\n html += '</body></html>';\n\n const blob = new Blob([html], { type: 'application/vnd.ms-word' });\n const a = document.createElement('a');\n a.href = URL.createObjectURL(blob);\n a.download = d.project + '-vibedrift.doc';\n a.click();\n URL.revokeObjectURL(a.href);\n}\n\nfunction esc2(s) { return String(s || '').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); }\n</script>\n\n</body>\n</html>`;\n}\n","import { readdir, readFile, writeFile, mkdir } from \"fs/promises\";\nimport { homedir } from \"os\";\nimport { createHash } from \"crypto\";\nimport { join } from \"path\";\nimport type { CategoryScores } from \"./types.js\";\n\n/**\n * Per-project scan history.\n *\n * History lives at $HOME/.vibedrift/scans/<project-hash>/scan-<ts>.json,\n * NOT inside the user's project tree. We never write into the project\n * directory — that pollutes git status and confuses tooling.\n *\n * The project hash is a SHA-256 prefix of the absolute path. It is stable\n * across runs but lets a single user track many projects without leaking\n * paths to anyone reading the directory listing.\n */\n\nconst ROOT_DIR = join(homedir(), \".vibedrift\", \"scans\");\n\nfunction projectHash(rootDir: string): string {\n return createHash(\"sha256\").update(rootDir).digest(\"hex\").slice(0, 16);\n}\n\nfunction projectDir(rootDir: string): string {\n return join(ROOT_DIR, projectHash(rootDir));\n}\n\nexport async function saveScanResult(\n rootDir: string,\n scores: CategoryScores,\n compositeScore: number,\n): Promise<void> {\n const dir = projectDir(rootDir);\n try {\n await mkdir(dir, { recursive: true, mode: 0o700 });\n } catch { /* exists */ }\n\n const data = {\n timestamp: new Date().toISOString(),\n rootDir,\n scores,\n compositeScore,\n };\n\n const filename = `scan-${Date.now()}.json`;\n await writeFile(join(dir, filename), JSON.stringify(data, null, 2));\n}\n\nexport async function loadPreviousScores(\n rootDir: string,\n): Promise<CategoryScores | null> {\n const dir = projectDir(rootDir);\n\n try {\n const files = await readdir(dir);\n const scanFiles = files\n .filter((f) => f.startsWith(\"scan-\") && f.endsWith(\".json\"))\n .sort()\n .reverse();\n\n if (scanFiles.length === 0) return null;\n\n const raw = await readFile(join(dir, scanFiles[0]), \"utf-8\");\n const data = JSON.parse(raw);\n return data.scores ?? null;\n } catch {\n return null;\n }\n}\n","import type { SourceFile } from \"./types.js\";\n\n/**\n * Apply --include / --exclude glob filtering to a discovered file set.\n *\n * Semantics:\n * - If `includes` is non-empty, a file must match AT LEAST ONE include pattern.\n * - A file matching ANY exclude pattern is dropped.\n * - Patterns are matched against the file's `relativePath` (the path\n * relative to the project root that we already track in SourceFile).\n *\n * We implement a small, dependency-free glob → regex converter that supports\n * the patterns developers actually use:\n *\n * * — any sequence within a single path segment\n * ** — any sequence including slashes\n * ? — any single character within a segment\n * {a,b,c} — alternation\n * [abc] — character class\n * trailing / — directory match\n *\n * Negated patterns (`!foo`) are not supported here — use --exclude instead.\n */\n\nexport function applyIncludeExclude(\n files: SourceFile[],\n includes: string[],\n excludes: string[],\n): SourceFile[] {\n const includeRegexes = includes.map(globToRegex);\n const excludeRegexes = excludes.map(globToRegex);\n\n const useInclude = includeRegexes.length > 0;\n\n return files.filter((file) => {\n const path = file.relativePath;\n\n if (useInclude && !includeRegexes.some((re) => re.test(path))) {\n return false;\n }\n if (excludeRegexes.some((re) => re.test(path))) {\n return false;\n }\n return true;\n });\n}\n\n/**\n * Convert a single glob pattern to a JavaScript RegExp.\n * Anchored: matches the *whole* relative path.\n *\n * Test cases this handles:\n * \"src/**\" → src/anything (any depth)\n * \"**\\/*.test.ts\" → any file ending in .test.ts at any depth\n * \"src/?ndex.ts\" → src/index.ts or src/Cndex.ts ...\n * \"src/{a,b}/main.ts\" → src/a/main.ts or src/b/main.ts\n */\nexport function globToRegex(glob: string): RegExp {\n // Strip a leading \"./\"\n let pattern = glob.replace(/^\\.\\//, \"\");\n\n // Trailing \"/\" → directory match (anything inside)\n if (pattern.endsWith(\"/\")) {\n pattern = pattern + \"**\";\n }\n\n let result = \"\";\n let i = 0;\n let inClass = false;\n\n while (i < pattern.length) {\n const ch = pattern[i];\n\n if (inClass) {\n if (ch === \"]\") {\n inClass = false;\n result += \"]\";\n } else {\n // Escape regex meta inside char classes except ! and ^\n result += escapeInClass(ch);\n }\n i++;\n continue;\n }\n\n switch (ch) {\n case \"*\": {\n if (pattern[i + 1] === \"*\") {\n // ** — match any sequence including /\n // Followed by / ⇒ \"(?:.*/)?\" so \"src/**/foo\" matches \"src/foo\" too\n if (pattern[i + 2] === \"/\") {\n result += \"(?:.*/)?\";\n i += 3;\n } else {\n result += \".*\";\n i += 2;\n }\n } else {\n // * — any sequence excluding /\n result += \"[^/]*\";\n i++;\n }\n break;\n }\n case \"?\": {\n result += \"[^/]\";\n i++;\n break;\n }\n case \"[\": {\n inClass = true;\n result += \"[\";\n i++;\n break;\n }\n case \"{\": {\n // {a,b,c} → (?:a|b|c)\n const close = pattern.indexOf(\"}\", i);\n if (close === -1) {\n result += \"\\\\{\";\n i++;\n break;\n }\n const inner = pattern.slice(i + 1, close);\n const parts = inner.split(\",\").map((p) => p.trim()).filter(Boolean);\n if (parts.length > 0) {\n result += \"(?:\" + parts.map(escapeRegex).join(\"|\") + \")\";\n } else {\n result += \"\\\\{\\\\}\";\n }\n i = close + 1;\n break;\n }\n default: {\n result += escapeRegex(ch);\n i++;\n break;\n }\n }\n }\n\n return new RegExp(\"^\" + result + \"$\");\n}\n\nfunction escapeRegex(ch: string): string {\n if (/[.+^${}()|\\\\]/.test(ch)) return \"\\\\\" + ch;\n return ch;\n}\n\nfunction escapeInClass(ch: string): string {\n if (ch === \"\\\\\") return \"\\\\\\\\\";\n return ch;\n}\n","import { readConfig } from \"./config.js\";\n\n/**\n * Token resolution.\n *\n * Priority order (highest first):\n * 1. Explicit CLI flag (--token / --ml-key, kept temporarily for back-compat)\n * 2. VIBEDRIFT_TOKEN environment variable\n * 3. ~/.vibedrift/config.json `token` field\n *\n * Returns null if no token is configured anywhere. Callers decide whether\n * to error, fall back to anonymous mode, or print an actionable message.\n */\n\nexport interface TokenResolutionInput {\n explicitToken?: string;\n}\n\nexport interface ResolvedToken {\n token: string;\n source: \"flag\" | \"env\" | \"config\";\n}\n\nexport async function resolveToken(input: TokenResolutionInput = {}): Promise<ResolvedToken | null> {\n if (input.explicitToken && input.explicitToken.trim().length > 0) {\n return { token: input.explicitToken.trim(), source: \"flag\" };\n }\n\n const fromEnv = process.env.VIBEDRIFT_TOKEN;\n if (fromEnv && fromEnv.trim().length > 0) {\n return { token: fromEnv.trim(), source: \"env\" };\n }\n\n const config = await readConfig();\n if (config.token && config.token.trim().length > 0) {\n return { token: config.token.trim(), source: \"config\" };\n }\n\n return null;\n}\n\n/**\n * API base URL resolution.\n *\n * 1. Explicit CLI flag (--api-url)\n * 2. VIBEDRIFT_API_URL environment variable\n * 3. ~/.vibedrift/config.json `apiUrl` field\n * 4. Built-in default (production)\n */\nexport async function resolveApiUrl(explicitUrl?: string): Promise<string> {\n if (explicitUrl && explicitUrl.trim().length > 0) return explicitUrl.trim();\n if (process.env.VIBEDRIFT_API_URL && process.env.VIBEDRIFT_API_URL.trim().length > 0) {\n return process.env.VIBEDRIFT_API_URL.trim();\n }\n const config = await readConfig();\n if (config.apiUrl && config.apiUrl.trim().length > 0) return config.apiUrl.trim();\n return \"https://vibedrift-api.fly.dev\";\n}\n\n/**\n * Display-friendly token preview (\"vd_live_a3x...\").\n * Shows the **prefix** (not the suffix) so users can tell which key they're\n * using without leaking enough entropy to be useful to an attacker.\n */\nexport function previewToken(token: string): string {\n if (!token) return \"(none)\";\n if (token.length <= 12) return token.slice(0, 4) + \"…\";\n return token.slice(0, 12) + \"…\";\n}\n\n/** Human-readable label for the token source. Shared by status + doctor. */\nexport function describeSource(source: \"flag\" | \"env\" | \"config\"): string {\n switch (source) {\n case \"flag\": return \"command-line flag\";\n case \"env\": return \"VIBEDRIFT_TOKEN environment variable\";\n case \"config\": return \"~/.vibedrift/config.json\";\n }\n}\n","import { homedir } from \"os\";\nimport { join } from \"path\";\nimport { readFile, writeFile, mkdir, chmod, unlink, stat } from \"fs/promises\";\n\n/**\n * VibeDrift CLI configuration storage.\n *\n * Stored at $HOME/.vibedrift/config.json with mode 0600 (user read/write only).\n * Holds the device-auth bearer token plus the plan/email/expiry that\n * vibedrift-api returned alongside it.\n *\n * NOTE: scan history (per-project deltas) lives at $HOME/.vibedrift/scans/\n * — see core/history.ts. The CLI should never write inside the user's\n * project directory.\n */\n\nexport interface VibeDriftConfig {\n /** Bearer token returned by /auth/poll. Opaque, server-generated. */\n token?: string;\n\n /** Email of the authenticated user (display only). */\n email?: string;\n\n /** \"free\" | \"pro\" | \"team\" — last known plan, refreshed on each login. */\n plan?: \"free\" | \"pro\" | \"team\";\n\n /** ISO-8601 timestamp the token expires (server-side enforcement is authoritative). */\n expiresAt?: string;\n\n /** ISO-8601 timestamp the user authenticated. */\n loggedInAt?: string;\n\n /** Override the API base URL (developers / staging only). Set via env or login --api. */\n apiUrl?: string;\n\n /** Stripe customer ID (display only — server is the source of truth). */\n stripeCustomerId?: string;\n}\n\nconst DEFAULT_DIR = join(homedir(), \".vibedrift\");\nconst DEFAULT_FILE = join(DEFAULT_DIR, \"config.json\");\n\nexport function getConfigDir(): string {\n return DEFAULT_DIR;\n}\n\nexport function getConfigPath(): string {\n return DEFAULT_FILE;\n}\n\nexport async function ensureConfigDir(): Promise<void> {\n await mkdir(DEFAULT_DIR, { recursive: true, mode: 0o700 });\n}\n\nexport async function readConfig(): Promise<VibeDriftConfig> {\n try {\n const raw = await readFile(DEFAULT_FILE, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return {};\n return parsed as VibeDriftConfig;\n } catch (err: any) {\n if (err?.code === \"ENOENT\") return {};\n // Corrupt config: don't crash, but warn loudly\n process.stderr.write(`vibedrift: warning — config at ${DEFAULT_FILE} is unreadable (${err?.message ?? err}). Treating as empty.\\n`);\n return {};\n }\n}\n\nexport async function writeConfig(config: VibeDriftConfig): Promise<void> {\n await ensureConfigDir();\n const json = JSON.stringify(config, null, 2);\n await writeFile(DEFAULT_FILE, json, { mode: 0o600 });\n // Belt and braces — ensure mode in case the file already existed with wrong perms.\n try {\n await chmod(DEFAULT_FILE, 0o600);\n } catch {\n // Best-effort only (e.g. on Windows)\n }\n}\n\nexport async function clearConfig(): Promise<void> {\n try {\n await unlink(DEFAULT_FILE);\n } catch (err: any) {\n if (err?.code !== \"ENOENT\") throw err;\n }\n}\n\nexport async function configExists(): Promise<boolean> {\n try {\n await stat(DEFAULT_FILE);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Update specific fields without clobbering the rest of the config.\n * Reads, merges, writes.\n */\nexport async function patchConfig(patch: Partial<VibeDriftConfig>): Promise<VibeDriftConfig> {\n const current = await readConfig();\n const next: VibeDriftConfig = { ...current, ...patch };\n await writeConfig(next);\n return next;\n}\n","import { resolveApiUrl } from \"./resolver.js\";\n\n/**\n * Typed HTTP client for the VibeDrift Auth + Account API.\n *\n * All endpoints live on the same Fly.io app as the analyze endpoint\n * (vibedrift-api.fly.dev). Auth endpoints are unauthenticated; account\n * endpoints require a Bearer token in the Authorization header.\n */\n\nconst REQUEST_TIMEOUT_MS = 30_000;\n\nexport interface DeviceStartResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete: string;\n expires_in: number; // seconds\n interval: number; // seconds — minimum gap between polls\n}\n\nexport interface DevicePollSuccess {\n status: \"authorized\";\n access_token: string;\n email: string;\n plan: \"free\" | \"pro\" | \"team\";\n expires_at: string;\n}\n\nexport interface DevicePollPending {\n status: \"pending\";\n}\n\nexport interface DevicePollDenied {\n status: \"denied\" | \"expired\";\n message?: string;\n}\n\nexport type DevicePollResponse = DevicePollSuccess | DevicePollPending | DevicePollDenied;\n\nexport interface ValidateResponse {\n valid: boolean;\n email?: string;\n plan?: \"free\" | \"pro\" | \"team\";\n expires_at?: string;\n}\n\nexport interface UsageResponse {\n user: {\n email: string;\n plan: \"free\" | \"pro\" | \"team\";\n };\n current_period: {\n start: string;\n end: string;\n scans: number;\n deep_scans: number;\n };\n limits: {\n deep_scans_per_month: number | null; // null = unlimited\n rate_limit_per_min: number;\n };\n recent_scans: Array<{\n id: string;\n project_hash: string;\n score: number | null;\n is_deep: boolean;\n created_at: string;\n }>;\n}\n\nexport interface PortalResponse {\n url: string;\n}\n\nexport interface FeedbackResponse {\n id: string;\n received_at: string;\n}\n\nexport interface CreditsResponse {\n plan: \"free\" | \"pro\" | \"team\";\n unlimited: boolean;\n available_total: number;\n available_welcome: number;\n available_purchased: number;\n available_manual: number;\n welcome_granted: boolean;\n welcome_consumed: boolean;\n has_free_deep_scan: boolean;\n}\n\nexport class VibeDriftApiError extends Error {\n constructor(public status: number, message: string) {\n super(message);\n this.name = \"VibeDriftApiError\";\n }\n}\n\n/** Internal: shared fetch helper with timeout, JSON parsing, error mapping. */\nasync function jsonFetch<T>(url: string, init: RequestInit = {}): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n try {\n const res = await fetch(url, {\n ...init,\n signal: controller.signal,\n headers: {\n Accept: \"application/json\",\n ...(init.body ? { \"Content-Type\": \"application/json\" } : {}),\n ...(init.headers ?? {}),\n },\n });\n\n if (!res.ok) {\n let detail = \"\";\n try {\n const body = await res.json() as { detail?: string; message?: string };\n detail = body.detail ?? body.message ?? \"\";\n } catch {\n try { detail = await res.text(); } catch { /* ignore */ }\n }\n throw new VibeDriftApiError(res.status, detail || `HTTP ${res.status}`);\n }\n\n return await res.json() as T;\n } catch (err: any) {\n if (err?.name === \"AbortError\") {\n throw new VibeDriftApiError(0, `Request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`);\n }\n if (err instanceof VibeDriftApiError) throw err;\n throw new VibeDriftApiError(0, err?.message ?? String(err));\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** Begin a device authorization flow. CLI calls this and prints user_code. */\nexport async function startDeviceAuth(opts?: { apiUrl?: string }): Promise<DeviceStartResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<DeviceStartResponse>(`${base}/auth/device`, {\n method: \"POST\",\n body: JSON.stringify({ client_id: \"vibedrift-cli\" }),\n });\n}\n\n/** Poll for device-auth completion. Server responds with pending/authorized/denied/expired. */\nexport async function pollDeviceAuth(deviceCode: string, opts?: { apiUrl?: string }): Promise<DevicePollResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<DevicePollResponse>(`${base}/auth/poll`, {\n method: \"POST\",\n body: JSON.stringify({ device_code: deviceCode }),\n });\n}\n\n/** Validate a token. Used by `vibedrift status` and `vibedrift doctor`. */\nexport async function validateToken(token: string, opts?: { apiUrl?: string }): Promise<ValidateResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<ValidateResponse>(`${base}/auth/validate`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n\n/** Revoke the current token server-side. Called by `vibedrift logout`. */\nexport async function revokeToken(token: string, opts?: { apiUrl?: string }): Promise<void> {\n const base = await resolveApiUrl(opts?.apiUrl);\n await jsonFetch<{ ok: true }>(`${base}/auth/revoke`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n\n/** Fetch usage stats for the authenticated user. */\nexport async function fetchUsage(token: string, opts?: { apiUrl?: string }): Promise<UsageResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<UsageResponse>(`${base}/account/usage`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n\n/**\n * Send free-form feedback. Auth is OPTIONAL — anonymous submissions\n * are accepted by the server. When `token` is supplied we attach it so\n * the dashboard can correlate the feedback with the user's account.\n */\nexport async function sendFeedback(args: {\n source: \"cli\" | \"dashboard\" | \"landing\";\n message: string;\n token?: string;\n email?: string;\n metadata?: Record<string, unknown>;\n apiUrl?: string;\n}): Promise<FeedbackResponse> {\n const base = await resolveApiUrl(args.apiUrl);\n const headers: Record<string, string> = {};\n if (args.token) headers.Authorization = `Bearer ${args.token}`;\n return jsonFetch<FeedbackResponse>(`${base}/v1/feedback/general`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n source: args.source,\n message: args.message,\n email: args.email,\n metadata: args.metadata,\n }),\n });\n}\n\n/** Fetch the user's credit summary (welcome + purchased + manual). */\nexport async function fetchCredits(token: string, opts?: { apiUrl?: string }): Promise<CreditsResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<CreditsResponse>(`${base}/account/credits`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n\n/** Create a Stripe Customer Portal session and return the URL to open. */\nexport async function createPortalSession(token: string, opts?: { apiUrl?: string }): Promise<PortalResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<PortalResponse>(`${base}/account/portal`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n","import { spawn } from \"child_process\";\nimport chalk from \"chalk\";\n\nconst PACKAGE_NAME = \"@vibedrift/cli\";\nconst REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;\n\nfunction semverGreater(a: string, b: string): boolean {\n const pa = a.split(\".\").map(Number);\n const pb = b.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n const x = pa[i] ?? 0;\n const y = pb[i] ?? 0;\n if (x > y) return true;\n if (x < y) return false;\n }\n return false;\n}\n\nexport async function runUpdate(currentVersion: string): Promise<void> {\n console.log(chalk.dim(\"Checking for updates...\"));\n\n let latest: string;\n try {\n const res = await fetch(REGISTRY_URL, {\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) {\n throw new Error(`registry returned HTTP ${res.status}`);\n }\n const data = (await res.json()) as { version?: string };\n if (!data.version) {\n throw new Error(\"registry response missing version field\");\n }\n latest = data.version;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(chalk.red(`Failed to check for updates: ${message}`));\n console.error(chalk.dim(`Try manually: npm i -g ${PACKAGE_NAME}@latest`));\n process.exit(1);\n }\n\n if (currentVersion === latest) {\n console.log(\n chalk.green(`✓ Already on the latest version (${currentVersion}).`),\n );\n return;\n }\n\n if (!semverGreater(latest, currentVersion)) {\n console.log(\n chalk.yellow(\n `Local version (${currentVersion}) is ahead of the registry (${latest}). Nothing to do.`,\n ),\n );\n return;\n }\n\n console.log(\n chalk.bold(\n `Updating ${PACKAGE_NAME}: ${chalk.dim(currentVersion)} → ${chalk.yellow(latest)}`,\n ),\n );\n console.log(chalk.dim(`Running: npm i -g ${PACKAGE_NAME}@${latest}\\n`));\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\n \"npm\",\n [\"i\", \"-g\", `${PACKAGE_NAME}@${latest}`],\n { stdio: \"inherit\", shell: false },\n );\n child.on(\"error\", (err) => {\n reject(err);\n });\n child.on(\"exit\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`npm exited with code ${code}`));\n }\n });\n })\n .then(() => {\n console.log(chalk.green(`\\n✓ Updated to ${latest}.`));\n console.log(chalk.dim(\"Run `vibedrift --version` to verify.\"));\n })\n .catch((err) => {\n const message = err instanceof Error ? err.message : String(err);\n console.error(chalk.red(`\\nUpdate failed: ${message}`));\n console.error(chalk.dim(\"\\nManual install commands by package manager:\"));\n console.error(chalk.dim(` npm: npm i -g ${PACKAGE_NAME}@latest`));\n console.error(chalk.dim(` pnpm: pnpm add -g ${PACKAGE_NAME}@latest`));\n console.error(chalk.dim(` bun: bun add -g ${PACKAGE_NAME}@latest`));\n console.error(chalk.dim(` yarn: yarn global add ${PACKAGE_NAME}@latest`));\n process.exit(1);\n });\n}\n","import chalk from \"chalk\";\nimport {\n startDeviceAuth,\n pollDeviceAuth,\n fetchCredits,\n VibeDriftApiError,\n} from \"../../auth/api.js\";\nimport { patchConfig, readConfig } from \"../../auth/config.js\";\nimport { openInBrowser } from \"../../auth/browser.js\";\nimport { previewToken } from \"../../auth/resolver.js\";\n\nexport interface LoginOptions {\n apiUrl?: string;\n noBrowser?: boolean;\n}\n\n/**\n * Device-authorization login flow (RFC 8628 inspired, GitHub CLI style).\n *\n * 1. POST /auth/device → server returns user_code, verification_uri, device_code\n * 2. Print user_code, open verification_uri in the browser\n * 3. Poll /auth/poll until status === \"authorized\"\n * 4. Save the resulting access_token to ~/.vibedrift/config.json\n *\n * No password ever touches the CLI. The browser handles the auth and the\n * server hands the CLI back an opaque bearer token.\n */\nexport async function runLogin(options: LoginOptions = {}): Promise<void> {\n // Warn if a token already exists so we don't silently clobber it.\n const existing = await readConfig();\n if (existing.token) {\n console.log(\n chalk.yellow(\n `\\n You're already logged in as ${chalk.bold(existing.email ?? \"unknown\")} (${existing.plan ?? \"free\"}).`,\n ),\n );\n console.log(chalk.dim(` Token: ${previewToken(existing.token)}`));\n console.log(chalk.dim(\" Continuing will replace this token.\\n\"));\n }\n\n let device;\n try {\n device = await startDeviceAuth({ apiUrl: options.apiUrl });\n } catch (err) {\n fail(\"Could not start the login flow\", err);\n return;\n }\n\n console.log(\"\");\n console.log(chalk.bold(\" First, copy your one-time code:\"));\n console.log(\"\");\n console.log(` ${chalk.bgYellow.black.bold(` ${device.user_code} `)}`);\n console.log(\"\");\n console.log(chalk.dim(` This code expires in ${formatDuration(device.expires_in)}.`));\n console.log(\"\");\n\n const opened = !options.noBrowser && openInBrowser(device.verification_uri_complete);\n if (opened) {\n console.log(chalk.bold(\" Opened your browser to:\"));\n } else {\n console.log(chalk.bold(\" Open this URL in your browser:\"));\n }\n console.log(` ${chalk.cyan(device.verification_uri_complete)}`);\n console.log(\"\");\n console.log(chalk.dim(\" Waiting for you to authorize the CLI...\"));\n console.log(\"\");\n\n // Poll loop. Use the server-suggested interval; double on slow_down errors.\n let interval = Math.max(1, device.interval);\n const deadline = Date.now() + device.expires_in * 1000;\n\n while (Date.now() < deadline) {\n await sleep(interval * 1000);\n\n let result;\n try {\n result = await pollDeviceAuth(device.device_code, { apiUrl: options.apiUrl });\n } catch (err) {\n if (err instanceof VibeDriftApiError && err.status === 429) {\n interval = Math.min(interval * 2, 30);\n continue;\n }\n fail(\"Polling for authorization failed\", err);\n return;\n }\n\n if (result.status === \"pending\") continue;\n\n if (result.status === \"authorized\") {\n await handleLoginSuccess(result, options);\n return;\n }\n\n if (result.status === \"denied\") {\n console.error(chalk.red(\"\\n ✗ Authorization was denied in the browser.\"));\n console.error(chalk.dim(\" Run `vibedrift login` again to retry.\\n\"));\n process.exit(1);\n }\n\n if (result.status === \"expired\") {\n console.error(chalk.red(\"\\n ✗ The login code expired before you authorized it.\"));\n console.error(chalk.dim(\" Run `vibedrift login` again to retry.\\n\"));\n process.exit(1);\n }\n }\n\n console.error(chalk.red(\"\\n ✗ Login timed out before authorization completed.\"));\n console.error(chalk.dim(\" Run `vibedrift login` again to retry.\\n\"));\n process.exit(1);\n}\n\nasync function handleLoginSuccess(\n result: { access_token: string; email: string; plan: \"free\" | \"pro\" | \"team\"; expires_at: string },\n options: LoginOptions,\n): Promise<void> {\n await patchConfig({\n token: result.access_token,\n email: result.email,\n plan: result.plan,\n expiresAt: result.expires_at,\n loggedInAt: new Date().toISOString(),\n apiUrl: options.apiUrl,\n });\n console.log(chalk.green(\" ✓ Logged in successfully.\"));\n console.log(\"\");\n console.log(` Account: ${chalk.bold(result.email)}`);\n console.log(` Plan: ${chalk.bold(result.plan)}`);\n console.log(\"\");\n\n // Fetch + announce the one-time welcome credit. Non-fatal if the\n // call fails — older API builds simply won't have this endpoint.\n try {\n const credits = await fetchCredits(result.access_token, {\n apiUrl: options.apiUrl,\n });\n if (credits.has_free_deep_scan && !credits.unlimited) {\n console.log(\n chalk.bgYellow.black.bold(\" 🎁 1 FREE deep scan included with your account \"),\n );\n console.log(\"\");\n console.log(\n chalk.yellow(\" Try the full pipeline (Claude analysis, security review,\"),\n );\n console.log(\n chalk.yellow(\" AI-powered drift detection) on any project — no card needed.\"),\n );\n console.log(\"\");\n console.log(` ${chalk.cyan(\"vibedrift . --deep\")}`);\n console.log(\"\");\n } else if (credits.unlimited) {\n console.log(chalk.dim(\" Run `vibedrift . --deep` to use AI-powered analysis.\"));\n console.log(\"\");\n } else if (credits.available_total > 0) {\n console.log(\n chalk.dim(` You have ${credits.available_total} deep scan credit${credits.available_total === 1 ? \"\" : \"s\"} available.`),\n );\n console.log(chalk.dim(\" Run `vibedrift . --deep` to use one.\"));\n console.log(\"\");\n } else {\n console.log(chalk.dim(\" Run `vibedrift upgrade` to enable deep AI scans.\"));\n console.log(\"\");\n }\n } catch {\n // Endpoint missing or transient error — fall back to legacy hint.\n if (result.plan === \"free\") {\n console.log(chalk.dim(\" Run `vibedrift upgrade` to enable deep AI scans.\"));\n } else {\n console.log(chalk.dim(\" Run `vibedrift . --deep` to use AI-powered analysis.\"));\n }\n console.log(\"\");\n }\n}\n\nfunction fail(intro: string, err: unknown): never {\n const msg = err instanceof VibeDriftApiError\n ? `${err.status ? `HTTP ${err.status}: ` : \"\"}${err.message}`\n : err instanceof Error\n ? err.message\n : String(err);\n console.error(chalk.red(`\\n ✗ ${intro}: ${msg}\\n`));\n process.exit(1);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction formatDuration(seconds: number): string {\n if (seconds < 60) return `${seconds}s`;\n const m = Math.round(seconds / 60);\n return `${m} minute${m === 1 ? \"\" : \"s\"}`;\n}\n","import { spawn } from \"child_process\";\n\n/**\n * Cross-platform browser opener.\n *\n * Returns true if the open command was launched successfully (we cannot\n * tell if the user actually saw the page). Returns false if no opener\n * is available — callers should fall back to printing the URL.\n *\n * Honors the BROWSER environment variable when set (Linux/CI convention).\n * Refuses to open in non-interactive environments (CI=true and no TTY)\n * to avoid spawning hidden processes.\n */\nexport function openInBrowser(url: string): boolean {\n if (!isInteractive()) return false;\n\n const env = process.env.BROWSER;\n if (env && env.length > 0 && env !== \"none\") {\n return spawnDetached(env, [url]);\n }\n\n switch (process.platform) {\n case \"darwin\":\n return spawnDetached(\"open\", [url]);\n case \"win32\":\n return spawnDetached(\"cmd\", [\"/c\", \"start\", \"\", url]);\n default:\n return spawnDetached(\"xdg-open\", [url]);\n }\n}\n\nfunction isInteractive(): boolean {\n if (process.env.CI === \"true\" || process.env.CI === \"1\") return false;\n if (process.env.VIBEDRIFT_NO_BROWSER === \"1\") return false;\n return process.stdout.isTTY ?? false;\n}\n\nfunction spawnDetached(cmd: string, args: string[]): boolean {\n try {\n const child = spawn(cmd, args, {\n detached: true,\n stdio: \"ignore\",\n shell: false,\n });\n child.on(\"error\", () => {\n // Swallow — caller already returned true and printed a fallback URL.\n });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n","import chalk from \"chalk\";\nimport { clearConfig, readConfig } from \"../../auth/config.js\";\nimport { revokeToken, VibeDriftApiError } from \"../../auth/api.js\";\n\n/**\n * Logout: revoke the token server-side and remove the local config file.\n *\n * Local removal happens unconditionally even if the server revoke fails,\n * so users can always recover from a stale/broken token by running\n * `vibedrift logout`. The server revoke is best-effort.\n */\nexport async function runLogout(): Promise<void> {\n const config = await readConfig();\n\n if (!config.token) {\n console.log(chalk.dim(\" Not logged in. Nothing to do.\"));\n return;\n }\n\n // Best-effort server revoke\n try {\n await revokeToken(config.token, { apiUrl: config.apiUrl });\n } catch (err) {\n if (err instanceof VibeDriftApiError && (err.status === 401 || err.status === 404)) {\n // Token was already revoked or unknown — fine, treat as success.\n } else {\n console.warn(\n chalk.yellow(\n ` ⚠ Could not revoke token on the server: ${err instanceof Error ? err.message : String(err)}`,\n ),\n );\n console.warn(chalk.dim(\" Local token will still be removed.\"));\n }\n }\n\n await clearConfig();\n console.log(chalk.green(\" ✓ Logged out.\"));\n}\n","import chalk from \"chalk\";\nimport { readConfig, getConfigPath } from \"../../auth/config.js\";\nimport { previewToken, resolveToken, describeSource } from \"../../auth/resolver.js\";\nimport { validateToken, fetchCredits, VibeDriftApiError } from \"../../auth/api.js\";\nimport { getVersion } from \"../../core/version.js\";\n\n/**\n * `vibedrift status` — show the currently active account, plan, and token preview.\n *\n * Token display rule (security): we show the **prefix**, never the suffix.\n * Suffix-only previews leak the most useful bytes for an attacker.\n */\nexport async function runStatus(): Promise<void> {\n const version = getVersion();\n const config = await readConfig();\n const resolved = await resolveToken();\n\n console.log(\"\");\n console.log(chalk.bold(` VibeDrift CLI v${version}`));\n console.log(\"\");\n\n if (!resolved) {\n console.log(` Status: ${chalk.dim(\"not logged in\")}`);\n console.log(` Config: ${chalk.dim(getConfigPath())}`);\n console.log(\"\");\n console.log(chalk.dim(\" Run `vibedrift login` to authenticate.\"));\n console.log(\"\");\n return;\n }\n\n console.log(` Status: ${chalk.green(\"authenticated\")}`);\n console.log(` Source: ${chalk.dim(describeSource(resolved.source))}`);\n console.log(` Token: ${chalk.dim(previewToken(resolved.token))}`);\n\n // Local config metadata (only meaningful when source === \"config\")\n if (resolved.source === \"config\") {\n if (config.email) console.log(` Account: ${chalk.bold(config.email)}`);\n if (config.plan) console.log(` Plan: ${chalk.bold(config.plan)}`);\n if (config.expiresAt) console.log(` Expires: ${chalk.dim(config.expiresAt)}`);\n console.log(` Config: ${chalk.dim(getConfigPath())}`);\n }\n\n console.log(\"\");\n\n // Server-side validation — confirms the token is still live.\n process.stdout.write(chalk.dim(\" Validating token with server... \"));\n try {\n const result = await validateToken(resolved.token, { apiUrl: config.apiUrl });\n if (result.valid) {\n console.log(chalk.green(\"ok\"));\n if (result.email && result.email !== config.email) {\n console.log(chalk.dim(` Server account: ${result.email} (config out of sync — run \\`vibedrift login\\` to refresh)`));\n }\n if (result.plan && result.plan !== config.plan) {\n console.log(chalk.dim(` Server plan: ${result.plan} (config out of sync — run \\`vibedrift login\\` to refresh)`));\n }\n } else {\n console.log(chalk.red(\"invalid\"));\n console.log(chalk.dim(\" Run `vibedrift login` to re-authenticate.\"));\n }\n } catch (err) {\n console.log(chalk.yellow(\"offline\"));\n if (err instanceof VibeDriftApiError) {\n console.log(chalk.dim(` ${err.message}`));\n }\n }\n\n // Credit summary — surfaces the welcome credit and any purchased ones.\n try {\n const credits = await fetchCredits(resolved.token, { apiUrl: config.apiUrl });\n console.log(\"\");\n if (credits.unlimited) {\n console.log(` Deep scans: ${chalk.bold.green(\"unlimited\")} (${credits.plan})`);\n } else if (credits.has_free_deep_scan) {\n console.log(` Deep scans: ${chalk.bold.yellow(\"1 free\")} + ${credits.available_purchased} purchased`);\n console.log(chalk.dim(\" Run `vibedrift . --deep` to use your free credit.\"));\n } else if (credits.available_total > 0) {\n console.log(` Deep scans: ${chalk.bold(credits.available_total)} credit${credits.available_total === 1 ? \"\" : \"s\"} available`);\n } else {\n console.log(` Deep scans: ${chalk.dim(\"0 credits\")} — run \\`vibedrift upgrade\\` for more`);\n }\n } catch {\n // Older API or transient error — silently skip the credits line.\n }\n\n console.log(\"\");\n}\n\n","import chalk from \"chalk\";\nimport { resolveToken } from \"../../auth/resolver.js\";\nimport { fetchUsage, VibeDriftApiError } from \"../../auth/api.js\";\nimport { readConfig } from \"../../auth/config.js\";\n\n/**\n * `vibedrift usage` — show current-period scan counts and rate limits.\n *\n * Pro plan: unlimited deep scans, but a 60 req/min rate limit.\n * Free plan: a small number of free deep scans included.\n */\nexport async function runUsage(): Promise<void> {\n const resolved = await resolveToken();\n if (!resolved) {\n console.error(chalk.red(\"\\n ✗ Not logged in. Run `vibedrift login` first.\\n\"));\n process.exit(1);\n }\n\n const config = await readConfig();\n let data;\n try {\n data = await fetchUsage(resolved.token, { apiUrl: config.apiUrl });\n } catch (err) {\n if (err instanceof VibeDriftApiError && err.status === 401) {\n console.error(chalk.red(\"\\n ✗ Your token is invalid or expired. Run `vibedrift login` to re-authenticate.\\n\"));\n process.exit(1);\n }\n console.error(chalk.red(`\\n ✗ Could not fetch usage: ${err instanceof Error ? err.message : String(err)}\\n`));\n process.exit(1);\n }\n\n console.log(\"\");\n console.log(chalk.bold(\" Account\"));\n console.log(` Email: ${chalk.bold(data.user.email)}`);\n console.log(` Plan: ${chalk.bold(data.user.plan)}`);\n console.log(\"\");\n\n console.log(chalk.bold(\" Current period\"));\n console.log(` From: ${chalk.dim(formatDate(data.current_period.start))}`);\n console.log(` To: ${chalk.dim(formatDate(data.current_period.end))}`);\n console.log(` Scans: ${chalk.bold(data.current_period.scans.toString())}`);\n console.log(` Deep: ${chalk.bold(data.current_period.deep_scans.toString())}`);\n console.log(\"\");\n\n console.log(chalk.bold(\" Limits\"));\n const deepLimit = data.limits.deep_scans_per_month;\n console.log(` Deep: ${deepLimit === null ? chalk.green(\"unlimited\") : `${deepLimit}/month`}`);\n console.log(` Rate: ${data.limits.rate_limit_per_min} requests/minute`);\n console.log(\"\");\n\n if (data.recent_scans.length > 0) {\n console.log(chalk.bold(` Recent scans (${data.recent_scans.length})`));\n for (const scan of data.recent_scans.slice(0, 10)) {\n const flag = scan.is_deep ? chalk.cyan(\"deep\") : chalk.dim(\"std \");\n const score = scan.score === null ? chalk.dim(\"—\") : chalk.bold(String(Math.round(scan.score))).padEnd(3);\n console.log(` ${flag} ${score} ${chalk.dim(formatDateTime(scan.created_at))} ${chalk.dim(scan.project_hash.slice(0, 12))}`);\n }\n console.log(\"\");\n }\n}\n\nfunction formatDate(iso: string): string {\n try {\n return new Date(iso).toISOString().slice(0, 10);\n } catch { return iso; }\n}\n\nfunction formatDateTime(iso: string): string {\n try {\n const d = new Date(iso);\n return d.toISOString().slice(0, 16).replace(\"T\", \" \");\n } catch { return iso; }\n}\n","import chalk from \"chalk\";\nimport { openInBrowser } from \"../../auth/browser.js\";\n\n/**\n * `vibedrift upgrade` — open the pricing page in the browser.\n *\n * Distinct from `vibedrift --update` which upgrades the CLI binary.\n * \"upgrade\" is for the *plan*; \"update\" is for the *binary*.\n */\nconst PRICING_URL = \"https://vibedrift.ai/pricing\";\n\nexport async function runUpgrade(): Promise<void> {\n console.log(\"\");\n console.log(chalk.bold(\" Upgrade your VibeDrift plan\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(PRICING_URL)}`);\n console.log(\"\");\n\n const opened = openInBrowser(PRICING_URL);\n if (opened) {\n console.log(chalk.dim(\" Opened in your browser.\"));\n } else {\n console.log(chalk.dim(\" Open the link above in your browser.\"));\n }\n console.log(\"\");\n console.log(chalk.dim(\" After upgrading, run `vibedrift login` to refresh your plan locally.\"));\n console.log(\"\");\n}\n","import chalk from \"chalk\";\nimport { resolveToken } from \"../../auth/resolver.js\";\nimport { createPortalSession, VibeDriftApiError } from \"../../auth/api.js\";\nimport { readConfig } from \"../../auth/config.js\";\nimport { openInBrowser } from \"../../auth/browser.js\";\n\n/**\n * `vibedrift billing` — open the Stripe Customer Portal.\n *\n * The server creates a one-time portal session URL bound to the\n * authenticated user's stripe_customer_id and returns it. We open\n * the URL (or print it if no browser is available).\n */\nexport async function runBilling(): Promise<void> {\n const resolved = await resolveToken();\n if (!resolved) {\n console.error(chalk.red(\"\\n ✗ Not logged in. Run `vibedrift login` first.\\n\"));\n process.exit(1);\n }\n\n const config = await readConfig();\n\n let portal;\n try {\n portal = await createPortalSession(resolved.token, { apiUrl: config.apiUrl });\n } catch (err) {\n if (err instanceof VibeDriftApiError) {\n if (err.status === 401) {\n console.error(chalk.red(\"\\n ✗ Your token is invalid or expired. Run `vibedrift login`.\\n\"));\n process.exit(1);\n }\n if (err.status === 402 || err.status === 404) {\n console.error(chalk.yellow(\"\\n ⚠ No billing account found for this user.\"));\n console.error(chalk.dim(\" Run `vibedrift upgrade` to start a paid plan first.\\n\"));\n process.exit(1);\n }\n }\n console.error(chalk.red(`\\n ✗ Could not open billing portal: ${err instanceof Error ? err.message : String(err)}\\n`));\n process.exit(1);\n }\n\n console.log(\"\");\n console.log(chalk.bold(\" Stripe Customer Portal\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(portal.url)}`);\n console.log(\"\");\n\n const opened = openInBrowser(portal.url);\n if (opened) {\n console.log(chalk.dim(\" Opened in your browser. The link is single-use and expires shortly.\"));\n } else {\n console.log(chalk.dim(\" Open the link above in your browser. It's single-use and expires shortly.\"));\n }\n console.log(\"\");\n}\n","import chalk from \"chalk\";\nimport { homedir, platform, arch } from \"os\";\nimport { join } from \"path\";\nimport { stat, access, constants } from \"fs/promises\";\nimport { readConfig, getConfigPath, getConfigDir } from \"../../auth/config.js\";\nimport { resolveToken, resolveApiUrl, previewToken, describeSource } from \"../../auth/resolver.js\";\nimport { validateToken, VibeDriftApiError } from \"../../auth/api.js\";\nimport { getVersion } from \"../../core/version.js\";\n\n/**\n * `vibedrift doctor` — environment diagnostic, intended for bug reports.\n *\n * Reports on:\n * - CLI version, Node version, OS/arch\n * - Auth state (logged in? token source? validates with server?)\n * - Config dir + permissions\n * - API URL reachability\n * - PATH conflict (vibedrift binary location)\n *\n * Exits 0 if everything is healthy, 1 if any check failed.\n */\nasync function checkAuthStatus(): Promise<{\n resolved: Awaited<ReturnType<typeof resolveToken>>;\n authFailures: number;\n}> {\n let authFailures = 0;\n console.log(chalk.bold(\" Authentication\"));\n const config = await readConfig();\n const resolved = await resolveToken();\n\n if (!resolved) {\n info(\"Login state\", \"not logged in\");\n } else {\n ok(\"Token source\", describeSource(resolved.source));\n ok(\"Token preview\", previewToken(resolved.token));\n if (resolved.source === \"config\") {\n if (config.email) ok(\"Email\", config.email);\n if (config.plan) ok(\"Plan\", config.plan);\n if (config.expiresAt) {\n const expires = new Date(config.expiresAt).getTime();\n const now = Date.now();\n if (expires < now) {\n bad(`Token expired ${Math.floor((now - expires) / 86_400_000)} days ago`);\n authFailures++;\n } else {\n ok(\"Token expires\", `${config.expiresAt} (${Math.ceil((expires - now) / 86_400_000)} days)`);\n }\n }\n }\n }\n console.log(\"\");\n return { resolved, authFailures };\n}\n\nasync function checkApiConnectivity(\n resolved: Awaited<ReturnType<typeof resolveToken>>,\n): Promise<number> {\n let failures = 0;\n console.log(chalk.bold(\" API\"));\n const apiUrl = await resolveApiUrl();\n ok(\"API URL\", apiUrl);\n\n if (resolved) {\n process.stdout.write(` ${chalk.dim(\"→ Validating token... \")}`);\n try {\n const result = await validateToken(resolved.token, { apiUrl });\n if (result.valid) {\n console.log(chalk.green(\"ok\"));\n } else {\n console.log(chalk.red(\"invalid token\"));\n failures++;\n }\n } catch (err) {\n console.log(chalk.red(\"unreachable\"));\n console.log(` ${chalk.dim(\" \")}${err instanceof VibeDriftApiError ? err.message : String(err)}`);\n failures++;\n }\n } else {\n process.stdout.write(` ${chalk.dim(\"→ Pinging API... \")}`);\n try {\n const res = await fetch(`${apiUrl}/health`, { signal: AbortSignal.timeout(10_000) });\n if (res.ok) console.log(chalk.green(\"ok\"));\n else { console.log(chalk.yellow(`HTTP ${res.status}`)); failures++; }\n } catch (err) {\n console.log(chalk.red(\"unreachable\"));\n console.log(` ${chalk.dim(\" \")}${err instanceof Error ? err.message : String(err)}`);\n failures++;\n }\n }\n console.log(\"\");\n return failures;\n}\n\nexport async function runDoctor(): Promise<void> {\n let failures = 0;\n\n console.log(\"\");\n console.log(chalk.bold(\" VibeDrift Doctor\"));\n console.log(\"\");\n\n // ── Environment ──\n console.log(chalk.bold(\" Environment\"));\n ok(\"CLI version\", getVersion());\n ok(\"Node\", process.version);\n ok(\"Platform\", `${platform()} ${arch()}`);\n ok(\"HOME\", homedir());\n console.log(\"\");\n\n // ── Config dir ──\n console.log(chalk.bold(\" Config\"));\n const configDir = getConfigDir();\n const configPath = getConfigPath();\n\n let configDirOk = false;\n try {\n const info = await stat(configDir);\n if (info.isDirectory()) {\n configDirOk = true;\n // POSIX mode bits\n const mode = (info.mode & 0o777).toString(8);\n ok(\"Config dir\", `${configDir} (mode ${mode})`);\n } else {\n bad(`Config dir exists but is not a directory: ${configDir}`);\n failures++;\n }\n } catch {\n info(\"Config dir\", `${configDir} (will be created on first login)`);\n configDirOk = true;\n }\n\n if (configDirOk) {\n try {\n await access(configPath, constants.R_OK);\n const info = await stat(configPath);\n const mode = (info.mode & 0o777).toString(8);\n if ((info.mode & 0o077) !== 0) {\n warn(\"Config file\", `${configPath} (mode ${mode}, world/group readable — should be 600)`);\n } else {\n ok(\"Config file\", `${configPath} (mode ${mode})`);\n }\n } catch {\n info(\"Config file\", \"absent (not logged in)\");\n }\n }\n\n // History dir (separate from config — must be ~/.vibedrift/scans)\n const historyDir = join(homedir(), \".vibedrift\", \"scans\");\n try {\n const info = await stat(historyDir);\n if (info.isDirectory()) ok(\"Scan history\", historyDir);\n else warn(\"Scan history\", `${historyDir} exists but is not a directory`);\n } catch {\n info(\"Scan history\", \"empty (no scans run yet)\");\n }\n console.log(\"\");\n\n // ── Authentication ──\n const { resolved, authFailures } = await checkAuthStatus();\n failures += authFailures;\n\n // ── API ──\n const apiFailures = await checkApiConnectivity(resolved);\n failures += apiFailures;\n\n // ── Summary ──\n if (failures === 0) {\n console.log(chalk.green(\" ✓ All checks passed.\"));\n } else {\n console.log(chalk.red(` ✗ ${failures} check${failures === 1 ? \"\" : \"s\"} failed.`));\n }\n console.log(\"\");\n\n process.exit(failures === 0 ? 0 : 1);\n}\n\nfunction ok(label: string, value: string): void {\n console.log(` ${chalk.green(\"✓\")} ${label.padEnd(14)} ${chalk.dim(value)}`);\n}\nfunction warn(label: string, value: string): void {\n console.log(` ${chalk.yellow(\"⚠\")} ${label.padEnd(14)} ${chalk.dim(value)}`);\n}\nfunction bad(value: string): void {\n console.log(` ${chalk.red(\"✗\")} ${chalk.red(value)}`);\n}\nfunction info(label: string, value: string): void {\n console.log(` ${chalk.dim(\"·\")} ${label.padEnd(14)} ${chalk.dim(value)}`);\n}\n\n// describeSource imported from auth/resolver.ts (shared with status.ts)\n","import os from \"os\";\nimport readline from \"readline\";\nimport chalk from \"chalk\";\nimport { resolveToken, resolveApiUrl } from \"../../auth/resolver.js\";\nimport { sendFeedback, VibeDriftApiError } from \"../../auth/api.js\";\nimport { getVersion } from \"../../core/version.js\";\n\nexport interface FeedbackOptions {\n message?: string;\n apiUrl?: string;\n}\n\nconst MAX_MESSAGE_BYTES = 4096;\n\n/**\n * `vibedrift feedback` — send free-form feedback directly from the CLI.\n *\n * Two modes:\n * 1. Inline: `vibedrift feedback \"the install hint is too verbose\"`\n * 2. Interactive: `vibedrift feedback` (prompts on stdin until EOF)\n *\n * Auth is optional. We *try* to attach the user's token so triage can\n * follow up directly, but anonymous feedback works too — the API\n * accepts unauthenticated submissions for exactly this case.\n *\n * Always attaches CLI version, Node version, and OS as metadata so we\n * can correlate complaints with environments without asking the user.\n */\nexport async function runFeedback(opts: FeedbackOptions = {}): Promise<void> {\n console.log(\"\");\n console.log(chalk.bold(\" VibeDrift feedback\"));\n console.log(\n chalk.dim(\" Tell us what's broken, what's confusing, or what you wish existed.\"),\n );\n console.log(\n chalk.dim(\" Goes straight to the maintainer — anonymous unless you're logged in.\"),\n );\n console.log(\"\");\n\n // ── Collect the message ──\n let message = (opts.message ?? \"\").trim();\n if (!message) {\n message = await promptForMultilineMessage();\n }\n\n if (!message) {\n console.error(chalk.red(\" ✗ No feedback provided. Aborting.\"));\n process.exit(1);\n }\n\n if (Buffer.byteLength(message, \"utf8\") > MAX_MESSAGE_BYTES) {\n console.error(\n chalk.red(\n ` ✗ Message too long (max ${MAX_MESSAGE_BYTES} bytes). ` +\n `Please trim it or open an issue on GitHub for longer reports.`,\n ),\n );\n process.exit(1);\n }\n\n // ── Try (best-effort) to attach the user's token ──\n let token: string | null = null;\n try {\n const resolved = await resolveToken();\n if (resolved) token = resolved.token;\n } catch {\n // Anonymous fallback is fine\n }\n\n // ── Build metadata: CLI version + Node + OS ──\n const metadata: Record<string, unknown> = {\n cli_version: getVersion(),\n node_version: process.version,\n platform: process.platform,\n arch: process.arch,\n os_release: os.release(),\n locale: process.env.LANG ?? null,\n tty: process.stdin.isTTY === true,\n };\n\n // ── Send it ──\n process.stdout.write(chalk.dim(\" Sending... \"));\n try {\n const result = await sendFeedback({\n source: \"cli\",\n message,\n token: token ?? undefined,\n metadata,\n apiUrl: await resolveApiUrl(opts.apiUrl),\n });\n console.log(chalk.green(\"ok\"));\n console.log(\"\");\n console.log(` ${chalk.dim(\"Reference:\")} ${chalk.dim(result.id)}`);\n if (token) {\n console.log(\n chalk.dim(\n \" Submitted under your account — we'll reply to your email if needed.\",\n ),\n );\n } else {\n console.log(\n chalk.dim(\n \" Submitted anonymously. If you'd like a reply, run `vibedrift login` first.\",\n ),\n );\n }\n console.log(\"\");\n console.log(chalk.green(\" ✓ Thanks for helping us improve VibeDrift.\"));\n console.log(\"\");\n } catch (err) {\n console.log(chalk.red(\"failed\"));\n console.log(\"\");\n if (err instanceof VibeDriftApiError) {\n console.error(chalk.red(` ✗ ${err.message}`));\n } else {\n console.error(\n chalk.red(` ✗ ${err instanceof Error ? err.message : String(err)}`),\n );\n }\n console.error(\n chalk.dim(\n \" You can also email sami.ahmadkhan12@gmail.com directly.\",\n ),\n );\n console.log(\"\");\n process.exit(1);\n }\n}\n\n/**\n * Multi-line prompt: read until the user submits a line containing only\n * `EOF` or hits Ctrl-D. Falls back to single-line `readline.question` if\n * stdin isn't a TTY (so a piped `echo \"...\"` still works).\n */\nfunction promptForMultilineMessage(): Promise<string> {\n return new Promise((resolve) => {\n if (!process.stdin.isTTY) {\n // Piped input — read everything until EOF\n let buf = \"\";\n process.stdin.setEncoding(\"utf8\");\n process.stdin.on(\"data\", (chunk) => {\n buf += chunk;\n });\n process.stdin.on(\"end\", () => resolve(buf.trim()));\n return;\n }\n\n console.log(\n chalk.dim(\n \" Type your feedback below. Submit with a single line containing 'EOF',\",\n ),\n );\n console.log(chalk.dim(\" or press Ctrl-D when done. Press Ctrl-C to abort.\"));\n console.log(\"\");\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: chalk.yellow(\" > \"),\n });\n\n const lines: string[] = [];\n rl.prompt();\n rl.on(\"line\", (line) => {\n if (line.trim() === \"EOF\") {\n rl.close();\n return;\n }\n lines.push(line);\n rl.prompt();\n });\n rl.on(\"close\", () => {\n console.log(\"\");\n resolve(lines.join(\"\\n\").trim());\n });\n rl.on(\"SIGINT\", () => {\n console.log(chalk.red(\"\\n ✗ Aborted.\"));\n process.exit(1);\n });\n });\n}\n"],"mappings":"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","names":["extractBody","fileURLToPath","join","path","createHash","escapeRegex","path","path","join","readFile","createHash","path","extractAllFunctions","detectProjectIdentity","TIMEOUT_MS","DEFAULT_API_URL","TIMEOUT_MS","path","path","writeFile","stat","chalk","readFile","join","join","info","readFile","cached","lcsLength","path","basename","path","extractFunctions","isEntryPoint","path","data","readdir","readFile","join","path","escapeRegex","homedir","join","readFile","writeFile","mkdir","stat","chalk","runCodeDnaAnalysis","runMlAnalysis","deduplicateFindingsAcrossLayers","fetchAiSummary","logScan","detectProjectIdentity","sanitizeResultForUpload","writeFile","renderCsvReport","renderDocxReport","info","stat","chalk","resolve","chalk","spawn","chalk","resolve","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","homedir","join","stat","chalk","homedir","info","stat","join","chalk","chalk","resolve","path"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/codedna/function-extractor.ts","../src/core/version.ts","../src/codedna/semantic-fingerprint.ts","../src/codedna/operation-sequence.ts","../src/codedna/pattern-classifier.ts","../src/codedna/taint-analysis.ts","../src/codedna/deviation-heuristics.ts","../src/codedna/index.ts","../src/ml-client/sampler.ts","../src/ml-client/client.ts","../src/ml-client/confidence.ts","../src/ml-client/project-name.ts","../src/ml-client/index.ts","../src/scoring/dedup.ts","../src/ml-client/summarize.ts","../src/ml-client/log-scan.ts","../src/ml-client/sanitize-result.ts","../src/output/csv.ts","../src/output/docx.ts","../src/cli/index.ts","../src/cli/commands/scan.ts","../src/core/discovery.ts","../src/core/language.ts","../src/utils/gitignore.ts","../src/utils/ast.ts","../src/analyzers/index.ts","../src/analyzers/naming.ts","../src/analyzers/imports.ts","../src/analyzers/error-handling.ts","../src/utils/text.ts","../src/analyzers/dependencies.ts","../src/analyzers/duplicates.ts","../src/analyzers/todo-density.ts","../src/analyzers/config-drift.ts","../src/analyzers/security.ts","../src/analyzers/complexity.ts","../src/analyzers/intent-clarity.ts","../src/analyzers/dead-code.ts","../src/analyzers/language-specific.ts","../src/drift/index.ts","../src/drift/types.ts","../src/drift/architectural-contradiction.ts","../src/drift/convention-oscillation.ts","../src/drift/security-consistency.ts","../src/drift/semantic-duplication.ts","../src/drift/phantom-scaffolding.ts","../src/scoring/engine.ts","../src/scoring/categories.ts","../src/output/tease.ts","../src/output/terminal.ts","../src/output/format.ts","../src/output/html.ts","../src/core/history.ts","../src/core/file-filter.ts","../src/auth/resolver.ts","../src/auth/config.ts","../src/auth/api.ts","../src/cli/commands/update.ts","../src/cli/commands/login.ts","../src/auth/browser.ts","../src/cli/commands/logout.ts","../src/cli/commands/status.ts","../src/cli/commands/usage.ts","../src/cli/commands/upgrade.ts","../src/cli/commands/billing.ts","../src/cli/commands/doctor.ts","../src/cli/commands/feedback.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Cross-language function extraction for the Code DNA pipeline.\n *\n * Parses function declarations from JS/TS, Go, Python, and Rust sources\n * using regex patterns, then tokenizes their bodies for downstream\n * fingerprinting and operation-sequence analysis.\n */\n\nimport type { SourceFile, SupportedLanguage } from \"../core/types.js\";\nimport type { ExtractedFunction, FunctionRef } from \"./types.js\";\n\n// Domain category detection based on function name and body content\nexport function detectDomainCategory(name: string, body: string): string {\n const lowerName = name.toLowerCase();\n const lowerBody = body.toLowerCase();\n\n if (/(?:format|display|render|stringify|tostring|totext)/i.test(lowerName)) return \"formatting\";\n if (/(?:date|time|timestamp|moment|duration)/i.test(lowerName + lowerBody)) return \"date_manipulation\";\n if (/(?:currency|price|money|dollar|cent|amount)/i.test(lowerName + lowerBody)) return \"currency_handling\";\n if (/(?:valid|check|verify|assert|ensure|sanitize)/i.test(lowerName)) return \"validation\";\n if (/(?:parse|deserialize|unmarshal|decode)/i.test(lowerName)) return \"parsing\";\n if (/(?:serialize|marshal|encode|stringify)/i.test(lowerName)) return \"serialization\";\n if (/(?:fetch|get|load|read|find|query|list|search)/i.test(lowerName)) return \"data_retrieval\";\n if (/(?:create|insert|add|save|store|write|put|post)/i.test(lowerName)) return \"data_mutation\";\n if (/(?:update|patch|modify|edit|set)/i.test(lowerName)) return \"data_update\";\n if (/(?:delete|remove|destroy|drop|revoke)/i.test(lowerName)) return \"data_deletion\";\n if (/(?:transform|convert|map|reduce|filter)/i.test(lowerName)) return \"data_transformation\";\n if (/(?:handle|process|dispatch|route)/i.test(lowerName)) return \"request_handling\";\n if (/(?:auth|login|logout|token|session|permission|role)/i.test(lowerName + lowerBody)) return \"authentication\";\n if (/(?:log|debug|trace|info|warn|error)/i.test(lowerName) && lowerName.length < 15) return \"logging\";\n if (/(?:config|setting|option|preference|env)/i.test(lowerName)) return \"configuration\";\n if (/(?:send|notify|email|sms|push|broadcast)/i.test(lowerName)) return \"notification\";\n\n return \"general\";\n}\n\n// Tokenize body for comparison (strip comments, normalize strings)\nexport function tokenizeBody(body: string): string[] {\n let cleaned = body.replace(/\\/\\/.*$/gm, \"\").replace(/#.*$/gm, \"\");\n cleaned = cleaned.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n cleaned = cleaned.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"\"');\n cleaned = cleaned.replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"''\");\n cleaned = cleaned.replace(/`(?:[^`\\\\]|\\\\.)*`/g, \"``\");\n return cleaned.match(/[a-zA-Z_]\\w*|[0-9]+|[{}()\\[\\];,.:=<>!+\\-*/%&|^~?]/g) ?? [];\n}\n\n// djb2-style hash — fast, deterministic, and sufficient for grouping\n// duplicate candidates (collisions are validated by full token comparison later)\nexport function simpleHash(tokens: string[]): number {\n let h = 0;\n for (const t of tokens) {\n for (let i = 0; i < t.length; i++) {\n h = ((h << 5) - h + t.charCodeAt(i)) | 0;\n }\n }\n return h;\n}\n\nfunction extractBody(content: string, startAfterBrace: number, language: string): string {\n if (language === \"python\") {\n const rest = content.slice(startAfterBrace);\n const lines = rest.split(\"\\n\");\n const bodyLines: string[] = [];\n let baseIndent = -1;\n for (const line of lines) {\n if (line.trim() === \"\") { bodyLines.push(line); continue; }\n const indent = line.search(/\\S/);\n if (baseIndent === -1) baseIndent = indent;\n if (indent >= baseIndent) bodyLines.push(line);\n else break;\n }\n return bodyLines.join(\"\\n\");\n }\n\n let depth = 1;\n let i = startAfterBrace;\n while (i < content.length && depth > 0) {\n if (content[i] === \"{\") depth++;\n else if (content[i] === \"}\") depth--;\n i++;\n }\n return content.slice(startAfterBrace, i);\n}\n\nfunction getLanguagePatterns(language: SupportedLanguage): RegExp[] {\n const patterns: RegExp[] = [];\n if (language === \"go\") {\n patterns.push(/func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)\\s*\\(([^)]*)\\)\\s*(?:[^{]*)?\\{/g);\n } else if (language === \"javascript\" || language === \"typescript\") {\n patterns.push(/(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*(?::\\s*[^{]*)?\\{/g);\n patterns.push(/(?:export\\s+)?const\\s+(\\w+)\\s*=\\s*(?:async\\s+)?\\(([^)]*)\\)\\s*(?::\\s*[^=]*)?\\s*=>\\s*\\{/g);\n } else if (language === \"python\") {\n patterns.push(/def\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*(?:->[^:]*)?:/g);\n } else if (language === \"rust\") {\n patterns.push(/(?:pub\\s+)?(?:async\\s+)?fn\\s+(\\w+)\\s*(?:<[^>]*>)?\\s*\\(([^)]*)\\)\\s*(?:->[^{]*)?\\{/g);\n }\n return patterns;\n}\n\n// Extract all functions from a single source file\nexport function extractFunctionsFromFile(file: SourceFile): ExtractedFunction[] {\n const functions: ExtractedFunction[] = [];\n if (!file.language) return functions;\n\n const patterns = getLanguagePatterns(file.language);\n\n for (const pattern of patterns) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const name = match[1];\n const paramsStr = match[2];\n const startIndex = match.index + match[0].length;\n const line = file.content.slice(0, match.index).split(\"\\n\").length;\n\n const body = extractBody(file.content, startIndex, file.language);\n if (body.length < 10) continue;\n\n const params = paramsStr.trim() ? paramsStr.split(\",\").map((p) => p.trim()) : [];\n const declarationCode = (file.content.split(\"\\n\")[line - 1] ?? \"\").trim();\n const tokens = tokenizeBody(body);\n if (tokens.length < 5) continue;\n\n functions.push({\n name,\n file: file.path,\n relativePath: file.relativePath,\n line,\n language: file.language,\n params,\n paramCount: params.length,\n rawBody: body,\n declarationCode,\n domainCategory: detectDomainCategory(name, body),\n bodyTokens: tokens,\n bodyTokenCount: tokens.length,\n bodyHash: simpleHash(tokens),\n });\n }\n }\n\n return functions;\n}\n\n// Extract all functions from the entire analysis context\nexport function extractAllFunctions(files: SourceFile[]): ExtractedFunction[] {\n const allFunctions: ExtractedFunction[] = [];\n for (const file of files) {\n allFunctions.push(...extractFunctionsFromFile(file));\n }\n return allFunctions;\n}\n\n/** Convert an ExtractedFunction to a FunctionRef. Shared by fingerprint + opseq. */\nexport function toFunctionRef(fn: ExtractedFunction): FunctionRef {\n return { file: fn.file, relativePath: fn.relativePath, name: fn.name, line: fn.line };\n}\n","import { readFileSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\n\nlet cached: string | null = null;\n\n/**\n * Returns the current VibeDrift version, read from package.json at runtime.\n * Works both in the bundled dist/ output and when running from source.\n */\nexport function getVersion(): string {\n if (cached) return cached;\n\n try {\n const here = dirname(fileURLToPath(import.meta.url));\n // dist/index.js → ../package.json\n // src/core/version.ts (dev) → ../../package.json\n const candidates = [\n join(here, \"..\", \"package.json\"),\n join(here, \"..\", \"..\", \"package.json\"),\n join(here, \"..\", \"..\", \"..\", \"package.json\"),\n ];\n\n for (const path of candidates) {\n try {\n const content = readFileSync(path, \"utf-8\");\n const pkg = JSON.parse(content) as { name?: string; version?: string };\n if (pkg.name === \"@vibedrift/cli\" && pkg.version) {\n cached = pkg.version;\n return cached;\n }\n } catch {\n // Try next candidate\n }\n }\n } catch {\n // Fall through\n }\n\n cached = \"0.0.0\";\n return cached;\n}\n","import { createHash } from \"node:crypto\";\nimport type { ExtractedFunction, SemanticFingerprint, SemanticDuplicateGroup, FunctionRef } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\nimport { toFunctionRef } from \"./function-extractor.js\";\n\n// Normalize a function body for fingerprinting:\n// - Strip comments\n// - Replace string literals with STR, numbers with NUM\n// - Replace local variable names with positional placeholders\n// - Normalize whitespace\nfunction normalizeBody(body: string, language: string): string {\n let normalized = body;\n\n // Strip comments\n normalized = normalized.replace(/\\/\\/.*$/gm, \"\");\n normalized = normalized.replace(/#.*$/gm, \"\");\n normalized = normalized.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n\n // Replace string literals with STR\n normalized = normalized.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, \"STR\");\n normalized = normalized.replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"STR\");\n normalized = normalized.replace(/`(?:[^`\\\\]|\\\\.)*`/g, \"STR\");\n\n // Replace number literals with NUM\n normalized = normalized.replace(/\\b\\d+\\.?\\d*\\b/g, \"NUM\");\n\n // Extract local variable names and replace with positional placeholders\n const varNames = new Map<string, string>();\n let varCounter = 0;\n\n // Collect variable declarations\n // Go: var/const + := assignments\n // JS/TS: const/let/var declarations\n // Python: simple assignments\n // Rust: let/let mut\n const declPatterns = [\n /\\b(?:var|let|const)\\s+(\\w+)/g, // JS/TS/Go/Rust\n /(\\w+)\\s*:=/g, // Go short declarations\n /(\\w+)\\s*,\\s*(\\w+)\\s*:=/g, // Go multi-assign\n /^(\\w+)\\s*=/gm, // Python top-level assignment\n ];\n\n for (const pattern of declPatterns) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(normalized)) !== null) {\n for (let i = 1; i < match.length; i++) {\n const name = match[i];\n if (name && !varNames.has(name) && name.length > 1 && !/^(STR|NUM|nil|null|undefined|true|false|err|error|ctx|context)$/i.test(name)) {\n varNames.set(name, `_v${varCounter++}`);\n }\n }\n }\n }\n\n // Also collect function parameter names as variables\n // These should have been captured from the params but we can detect them in the body too\n\n // Replace variable names with placeholders (longest first to avoid partial replacements)\n const sortedVars = [...varNames.entries()].sort((a, b) => b[0].length - a[0].length);\n for (const [name, placeholder] of sortedVars) {\n // Only replace whole-word occurrences\n normalized = normalized.replace(new RegExp(`\\\\b${escapeRegex(name)}\\\\b`, \"g\"), placeholder);\n }\n\n // Normalize whitespace\n normalized = normalized.replace(/\\s+/g, \" \").trim();\n\n return normalized;\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n// Simple SHA-256-like hash using FNV-1a (fast, good distribution, no crypto dependency)\nfunction fnv1aHash(str: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n // Return as hex string, combine two passes for more bits\n const h1 = (hash >>> 0).toString(16).padStart(8, \"0\");\n let hash2 = 0x1a47e90b;\n for (let i = str.length - 1; i >= 0; i--) {\n hash2 ^= str.charCodeAt(i);\n hash2 = Math.imul(hash2, 0x01000193);\n }\n const h2 = (hash2 >>> 0).toString(16).padStart(8, \"0\");\n return h1 + h2;\n}\n\nexport function computeSemanticFingerprints(functions: ExtractedFunction[]): SemanticFingerprint[] {\n return functions.map((fn) => ({\n functionRef: toFunctionRef(fn),\n normalizedHash: fnv1aHash(normalizeBody(fn.rawBody, fn.language)),\n }));\n}\n\nexport function findDuplicateGroups(\n fingerprints: SemanticFingerprint[],\n functions: ExtractedFunction[],\n): SemanticDuplicateGroup[] {\n // Build lookup: \"name:file\" → ExtractedFunction for SHA-256 verification\n const fnLookup = new Map<string, ExtractedFunction>();\n for (const fn of functions) {\n fnLookup.set(`${fn.name}:${fn.file}`, fn);\n }\n\n // Group by FNV-1a hash (fast, but can collide)\n const byHash = new Map<string, SemanticFingerprint[]>();\n for (const fp of fingerprints) {\n if (!byHash.has(fp.normalizedHash)) byHash.set(fp.normalizedHash, []);\n byHash.get(fp.normalizedHash)!.push(fp);\n }\n\n const groups: SemanticDuplicateGroup[] = [];\n let groupCounter = 0;\n\n for (const [hash, fps] of byHash) {\n if (fps.length < 2) continue;\n\n // Verify with SHA-256 of normalized body to eliminate FNV-1a collisions\n const bySha = new Map<string, SemanticFingerprint[]>();\n for (const fp of fps) {\n const key = `${fp.functionRef.name}:${fp.functionRef.file}`;\n const fn = fnLookup.get(key);\n if (!fn) continue;\n\n const sha = createHash(\"sha256\")\n .update(normalizeBody(fn.rawBody, fn.language))\n .digest(\"hex\");\n\n if (!bySha.has(sha)) bySha.set(sha, []);\n bySha.get(sha)!.push(fp);\n }\n\n // Only emit sub-groups where ≥2 functions share the same SHA-256\n for (const [, shaGroup] of bySha) {\n if (shaGroup.length < 2) continue;\n\n const uniqueFiles = new Set(shaGroup.map((fp) => fp.functionRef.file));\n if (uniqueFiles.size < 2) continue;\n\n groups.push({\n groupId: `fingerprint-${groupCounter++}`,\n hash,\n functions: shaGroup.map((fp) => fp.functionRef),\n });\n }\n }\n\n return groups;\n}\n\nexport function fingerprintFindings(groups: SemanticDuplicateGroup[]): Finding[] {\n return groups.map((group) => {\n const names = group.functions.map((f) => `${f.name}()`).join(\", \");\n const files = group.functions.map((f) => f.relativePath);\n\n return {\n analyzerId: \"codedna-fingerprint\",\n severity: \"error\" as const,\n confidence: 1.0,\n message: `Exact semantic duplicate: ${names} have identical normalized bodies across ${files.length} files`,\n locations: group.functions.map((f) => ({\n file: f.relativePath,\n line: f.line,\n snippet: f.name + \"()\",\n })),\n tags: [\"codedna\", \"duplicate\", \"fingerprint\"],\n };\n });\n}\n","import type { ExtractedFunction, Operation, OperationSequence, SequenceSimilarity, FunctionRef } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\nimport { toFunctionRef } from \"./function-extractor.js\";\n\n// Classify each line/statement of a function body into an abstract operation type\nfunction classifyLine(line: string, language: string): Operation | null {\n const trimmed = line.trim();\n if (!trimmed || trimmed === \"{\" || trimmed === \"}\" || trimmed === \")\") return null;\n\n // INPUT — reading parameters, request body, context\n if (/(?:req\\.params|req\\.query|req\\.body|c\\.Param|c\\.QueryParam|c\\.Bind|c\\.FormValue|request\\.args|request\\.form|request\\.json|request\\.GET|request\\.POST|r\\.URL\\.Query|web::Path|web::Query|web::Json)/i.test(trimmed)) {\n return \"INPUT\";\n }\n\n // VALIDATE — schema validation, type checking, bounds\n if (/(?:validate|schema\\.parse|\\.validate\\(|zod\\.|joi\\.|assert|ensure|check.*(?:nil|null|empty|valid)|guard|sanitize)/i.test(trimmed)) {\n return \"VALIDATE\";\n }\n\n // RETURN_ERR — error returns (check before BRANCH since if err != nil { return ... } is common)\n if (/(?:return\\s+(?:nil|null|None),?\\s*(?:err|fmt\\.Errorf|errors\\.)|throw\\s+new|raise\\s+|return\\s+(?:err|error)|res\\.status\\(\\d{3,}\\)|c\\.JSON\\(\\d{3,}|http\\.Error)/i.test(trimmed)) {\n return \"RETURN_ERR\";\n }\n\n // RETURN_OK — success returns\n if (/(?:return\\s+c\\.JSON\\(2|return\\s+res\\.(?:json|send|status\\(2)|return\\s+(?:Ok|Some|jsonify)|c\\.JSON\\(http\\.Status(?:OK|Created))/i.test(trimmed)) {\n return \"RETURN_OK\";\n }\n\n // QUERY — database read operations\n if (/(?:SELECT\\s|\\.find\\(|\\.findOne\\(|\\.findAll\\(|\\.get\\(|repo\\.(?:Get|Find|List|Load)|db\\.Query(?:Row)?\\(|\\.query\\(|cursor\\.execute.*SELECT|\\.Where\\(.*\\.First\\(|\\.Where\\(.*\\.Find\\()/i.test(trimmed)) {\n return \"QUERY\";\n }\n\n // MUTATE — database write operations\n if (/(?:INSERT\\s|UPDATE\\s|DELETE\\s|\\.save\\(|\\.create\\(|\\.insert\\(|repo\\.(?:Create|Save|Store|Insert)|db\\.Exec\\(|cursor\\.execute.*(?:INSERT|UPDATE|DELETE)|\\.Remove\\(|\\.Delete\\(|\\.destroy\\()/i.test(trimmed)) {\n return \"MUTATE\";\n }\n\n // API_CALL — outbound HTTP/gRPC\n if (/(?:fetch\\(|axios\\.|http\\.(?:Get|Post|Put|Delete)\\(|\\.request\\(|requests\\.(?:get|post|put|delete)|grpc\\.|client\\.\\w+\\()/i.test(trimmed)) {\n return \"API_CALL\";\n }\n\n // RESOURCE — open/close/defer\n if (/(?:defer\\s|\\.Close\\(|\\.close\\(|fs\\.open|os\\.Open|with\\s+open|try.*finally|\\.release\\(|\\.dispose\\(|\\.end\\()/i.test(trimmed)) {\n return \"RESOURCE\";\n }\n\n // LOG — logging\n if (/(?:console\\.(?:log|warn|error|info|debug)|log\\.(?:Info|Warn|Error|Debug|Printf|Println)|logger\\.|logging\\.|slog\\.)/i.test(trimmed)) {\n return \"LOG\";\n }\n\n // LOOP — iteration\n if (/(?:^for\\s|^for\\(|\\.forEach\\(|\\.map\\(|\\.filter\\(|while\\s|while\\(|\\.each\\(|range\\s)/i.test(trimmed)) {\n return \"LOOP\";\n }\n\n // BRANCH �� conditional logic\n if (/(?:^if\\s|^if\\(|^else\\s|^else\\{|switch\\s|switch\\(|case\\s|match\\s|\\?\\s)/i.test(trimmed)) {\n return \"BRANCH\";\n }\n\n // TRANSFORM — data manipulation\n if (/(?:\\.map\\(|\\.filter\\(|\\.reduce\\(|\\.sort\\(|\\.slice\\(|\\.splice\\(|JSON\\.(?:parse|stringify)|json\\.(?:Marshal|Unmarshal)|strings\\.|strconv\\.|fmt\\.Sprintf|\\.trim\\(|\\.split\\(|\\.join\\()/i.test(trimmed)) {\n return \"TRANSFORM\";\n }\n\n return null;\n}\n\nexport function extractOperationSequences(functions: ExtractedFunction[]): OperationSequence[] {\n return functions.map((fn) => {\n const lines = fn.rawBody.split(\"\\n\");\n const sequence: Operation[] = [];\n\n for (const line of lines) {\n const op = classifyLine(line, fn.language);\n if (op) {\n if (sequence.length === 0 || sequence[sequence.length - 1] !== op) {\n sequence.push(op);\n }\n }\n }\n\n return { functionRef: toFunctionRef(fn), sequence };\n });\n}\n\n// Longest Common Subsequence length\nfunction lcsLength(a: Operation[], b: Operation[]): number {\n const m = a.length;\n const n = b.length;\n if (m === 0 || n === 0) return 0;\n\n // Space-optimized: only need previous row\n let prev = new Array(n + 1).fill(0);\n let curr = new Array(n + 1).fill(0);\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n curr[j] = prev[j - 1] + 1;\n } else {\n curr[j] = Math.max(prev[j], curr[j - 1]);\n }\n }\n [prev, curr] = [curr, prev];\n curr.fill(0);\n }\n\n return prev[n];\n}\n\nexport function findSequenceSimilarities(\n sequences: OperationSequence[],\n functions: ExtractedFunction[],\n): SequenceSimilarity[] {\n const similarities: SequenceSimilarity[] = [];\n\n // Build a map of domain categories for filtering\n const domainMap = new Map<string, string>();\n for (const fn of functions) {\n const key = `${fn.file}::${fn.name}::${fn.line}`;\n domainMap.set(key, fn.domainCategory);\n }\n\n // Only compare cross-file pairs in the same domain category\n for (let i = 0; i < sequences.length; i++) {\n const seqA = sequences[i];\n if (seqA.sequence.length < 3) continue; // Too short to be meaningful\n\n const keyA = `${seqA.functionRef.file}::${seqA.functionRef.name}::${seqA.functionRef.line}`;\n const domainA = domainMap.get(keyA);\n\n for (let j = i + 1; j < sequences.length; j++) {\n const seqB = sequences[j];\n if (seqB.sequence.length < 3) continue;\n\n // Must be in different files\n if (seqA.functionRef.file === seqB.functionRef.file) continue;\n\n // Must be in same domain category (skip \"general\" and \"request_handling\")\n const keyB = `${seqB.functionRef.file}::${seqB.functionRef.name}::${seqB.functionRef.line}`;\n const domainB = domainMap.get(keyB);\n if (!domainA || !domainB || domainA !== domainB) continue;\n if (domainA === \"general\" || domainA === \"request_handling\") continue;\n\n const lcs = lcsLength(seqA.sequence, seqB.sequence);\n const maxLen = Math.max(seqA.sequence.length, seqB.sequence.length);\n const similarity = maxLen > 0 ? lcs / maxLen : 0;\n\n if (similarity >= 0.80) {\n similarities.push({\n functionA: seqA.functionRef,\n functionB: seqB.functionRef,\n similarity,\n lcsLength: lcs,\n maxLength: maxLen,\n });\n }\n }\n }\n\n return similarities;\n}\n\nexport function sequenceFindings(similarities: SequenceSimilarity[]): Finding[] {\n return similarities.map((sim) => ({\n analyzerId: \"codedna-opseq\",\n severity: \"warning\" as const,\n confidence: Math.min(sim.similarity, 0.95),\n message: `Near-duplicate operation sequence: ${sim.functionA.name}() and ${sim.functionB.name}() share ${Math.round(sim.similarity * 100)}% of their operation flow`,\n locations: [\n { file: sim.functionA.relativePath, line: sim.functionA.line, snippet: sim.functionA.name + \"()\" },\n { file: sim.functionB.relativePath, line: sim.functionB.line, snippet: sim.functionB.name + \"()\" },\n ],\n tags: [\"codedna\", \"duplicate\", \"opseq\"],\n }));\n}\n","import type { SourceFile } from \"../core/types.js\";\nimport type { ArchPattern, PatternDistribution, PatternSignal } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\n\ninterface SignalDef {\n pattern: ArchPattern;\n regex: RegExp;\n label: string;\n}\n\n// Signals that indicate each architectural pattern\nconst SIGNAL_DEFS: SignalDef[] = [\n // Repository pattern\n { pattern: \"repository\", regex: /(?:repository|repo|store)\\.\\w+\\(/i, label: \"calls repo/store method\" },\n { pattern: \"repository\", regex: /import.*(?:repositories|repos|store)\\b/i, label: \"imports from repository layer\" },\n { pattern: \"repository\", regex: /this\\.repo(?:sitory)?\\.|h\\.repo\\.|s\\.store\\.|\\.repository\\./i, label: \"accesses injected repository\" },\n\n // Raw SQL\n { pattern: \"raw_sql\", regex: /(?:SELECT|INSERT\\s+INTO|UPDATE\\s+\\w+\\s+SET|DELETE\\s+FROM)\\s/i, label: \"SQL statement literal\" },\n { pattern: \"raw_sql\", regex: /db\\.Query(?:Row)?\\s*\\(/i, label: \"direct db.Query call\" },\n { pattern: \"raw_sql\", regex: /db\\.Exec\\s*\\(/i, label: \"direct db.Exec call\" },\n { pattern: \"raw_sql\", regex: /cursor\\.execute\\s*\\(/i, label: \"cursor.execute call\" },\n { pattern: \"raw_sql\", regex: /\\.query\\s*\\(\\s*[`'\"]/i, label: \"inline SQL query string\" },\n\n // ORM\n { pattern: \"orm\", regex: /(?:gorm|prisma|sequelize|typeorm|sqlalchemy|django\\.db|ent\\.)\\.?/i, label: \"ORM import/usage\" },\n { pattern: \"orm\", regex: /\\.Find\\(\\s*&|\\.Create\\(\\s*&|\\.Save\\(\\s*&|\\.Where\\(/i, label: \"ORM method call (Go)\" },\n { pattern: \"orm\", regex: /\\.findOne\\(|\\.findAll\\(|\\.create\\(.*{|\\.update\\(.*{|\\.destroy\\(/i, label: \"ORM method call (JS)\" },\n { pattern: \"orm\", regex: /objects\\.(?:filter|get|create|all)\\(/i, label: \"Django ORM call\" },\n\n // Direct DB\n { pattern: \"direct_db\", regex: /sql\\.Open\\(|pgx\\.Connect|mysql\\.Open|mongo\\.Connect/i, label: \"direct DB connection\" },\n { pattern: \"direct_db\", regex: /new\\s+(?:Pool|Client)\\(/i, label: \"direct DB pool/client\" },\n\n // HTTP client\n { pattern: \"http_client\", regex: /http\\.(?:Get|Post|Put|Delete)\\(/i, label: \"HTTP client call\" },\n { pattern: \"http_client\", regex: /fetch\\(|axios\\.|requests\\.(?:get|post)/i, label: \"HTTP fetch/axios/requests\" },\n];\n\n// Files that are likely \"handler\" or \"service\" files (where pattern drift matters)\nfunction isHandlerOrServiceFile(path: string): boolean {\n return /(?:handler|controller|service|route|endpoint|api|resource)/i.test(path);\n}\n\nfunction classifyFile(file: SourceFile): PatternDistribution | null {\n if (!file.language) return null;\n if (!isHandlerOrServiceFile(file.relativePath)) return null;\n\n const lines = file.content.split(\"\\n\");\n const signals: PatternSignal[] = [];\n const counts: Partial<Record<ArchPattern, number>> = {};\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n for (const def of SIGNAL_DEFS) {\n if (def.regex.test(line)) {\n signals.push({ pattern: def.pattern, signal: def.label, line: i + 1 });\n counts[def.pattern] = (counts[def.pattern] ?? 0) + 1;\n }\n }\n }\n\n // No signals found → not classifiable\n const totalSignals = Object.values(counts).reduce((sum, c) => sum + c, 0);\n if (totalSignals === 0) return null;\n\n // Normalize to probability distribution\n const patterns: Partial<Record<ArchPattern, number>> = {};\n for (const [pattern, count] of Object.entries(counts)) {\n patterns[pattern as ArchPattern] = Math.round((count / totalSignals) * 100) / 100;\n }\n\n // Find dominant pattern\n let dominantPattern: ArchPattern = \"none\";\n let maxProb = 0;\n for (const [pattern, prob] of Object.entries(patterns)) {\n if (prob > maxProb) {\n maxProb = prob;\n dominantPattern = pattern as ArchPattern;\n }\n }\n\n // Detect internal inconsistency: no single pattern > 60%\n const isInternallyInconsistent = maxProb < 0.6 && Object.keys(patterns).length > 1;\n\n return {\n file: file.path,\n relativePath: file.relativePath,\n patterns,\n dominantPattern,\n confidence: maxProb,\n signals,\n isInternallyInconsistent,\n };\n}\n\nexport function classifyPatterns(files: SourceFile[]): PatternDistribution[] {\n const distributions: PatternDistribution[] = [];\n for (const file of files) {\n const dist = classifyFile(file);\n if (dist) distributions.push(dist);\n }\n return distributions;\n}\n\nexport function patternFindings(distributions: PatternDistribution[]): Finding[] {\n const findings: Finding[] = [];\n\n if (distributions.length < 2) return findings;\n\n // Find project-wide dominant pattern\n const patternCounts = new Map<ArchPattern, number>();\n for (const dist of distributions) {\n patternCounts.set(dist.dominantPattern, (patternCounts.get(dist.dominantPattern) ?? 0) + 1);\n }\n\n let projectDominant: ArchPattern = \"none\";\n let maxCount = 0;\n for (const [pattern, count] of patternCounts) {\n if (count > maxCount) {\n maxCount = count;\n projectDominant = pattern;\n }\n }\n\n // Flag files that deviate from the project-wide dominant pattern\n for (const dist of distributions) {\n if (dist.dominantPattern !== projectDominant && projectDominant !== \"none\") {\n findings.push({\n analyzerId: \"codedna-pattern\",\n severity: \"warning\",\n confidence: dist.confidence,\n message: `Pattern drift: ${dist.relativePath} uses ${dist.dominantPattern} while ${maxCount}/${distributions.length} files use ${projectDominant}`,\n locations: dist.signals.slice(0, 3).map((s) => ({\n file: dist.relativePath,\n line: s.line,\n snippet: s.signal,\n })),\n tags: [\"codedna\", \"pattern\", \"drift\"],\n });\n }\n\n // Flag internally inconsistent files\n if (dist.isInternallyInconsistent) {\n const patternList = Object.entries(dist.patterns)\n .map(([p, prob]) => `${p}: ${Math.round(prob * 100)}%`)\n .join(\", \");\n findings.push({\n analyzerId: \"codedna-pattern\",\n severity: \"info\",\n confidence: 0.6,\n message: `Mixed patterns in ${dist.relativePath}: ${patternList} — file mixes architectural approaches internally`,\n locations: [{ file: dist.relativePath }],\n tags: [\"codedna\", \"pattern\", \"mixed\"],\n });\n }\n }\n\n return findings;\n}\n","import type { SourceFile, SupportedLanguage } from \"../core/types.js\";\nimport type { TaintFlow, TaintSource, TaintSink } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\nimport type { ExtractedFunction } from \"./types.js\";\n\n// ──── Taint Sources (user input entry points) ────\n\ninterface SourcePattern {\n regex: RegExp;\n label: string;\n}\n\nconst TAINT_SOURCES: Record<string, SourcePattern[]> = {\n go: [\n { regex: /c\\.Param\\s*\\(/, label: \"URL parameter\" },\n { regex: /c\\.QueryParam\\s*\\(/, label: \"query parameter\" },\n { regex: /c\\.Bind\\s*\\(/, label: \"request body binding\" },\n { regex: /c\\.FormValue\\s*\\(/, label: \"form value\" },\n { regex: /r\\.URL\\.Query\\s*\\(\\)/, label: \"query string\" },\n { regex: /r\\.FormValue\\s*\\(/, label: \"form value\" },\n { regex: /json\\.NewDecoder\\s*\\(\\s*r\\.Body/, label: \"request body JSON\" },\n { regex: /mux\\.Vars\\s*\\(/, label: \"URL path variable\" },\n ],\n javascript: [\n { regex: /req\\.params\\.\\w+/, label: \"URL parameter\" },\n { regex: /req\\.query\\.\\w+/, label: \"query parameter\" },\n { regex: /req\\.body\\.\\w+/, label: \"request body\" },\n { regex: /c\\.req\\.param\\s*\\(/, label: \"Hono parameter\" },\n { regex: /event\\.(?:pathParameters|queryStringParameters)/, label: \"Lambda parameter\" },\n ],\n typescript: [\n { regex: /req\\.params\\.\\w+/, label: \"URL parameter\" },\n { regex: /req\\.query\\.\\w+/, label: \"query parameter\" },\n { regex: /req\\.body\\.\\w+/, label: \"request body\" },\n { regex: /c\\.req\\.param\\s*\\(/, label: \"Hono parameter\" },\n ],\n python: [\n { regex: /request\\.args\\.get\\s*\\(/, label: \"query parameter\" },\n { regex: /request\\.form\\.get\\s*\\(/, label: \"form value\" },\n { regex: /request\\.json/, label: \"request JSON body\" },\n { regex: /request\\.GET\\.get\\s*\\(/, label: \"GET parameter\" },\n { regex: /request\\.POST\\.get\\s*\\(/, label: \"POST parameter\" },\n { regex: /request\\.data/, label: \"request data\" },\n ],\n rust: [\n { regex: /web::Path/, label: \"URL path parameter\" },\n { regex: /web::Query/, label: \"query parameter\" },\n { regex: /web::Json/, label: \"request JSON body\" },\n ],\n};\n\n// ──── Dangerous Sinks ────\n\ninterface SinkPattern {\n regex: RegExp;\n label: string;\n severity: \"error\" | \"warning\";\n category: string;\n}\n\nconst TAINT_SINKS: SinkPattern[] = [\n // SQL injection\n { regex: /db\\.Query\\s*\\(/, label: \"SQL query\", severity: \"error\", category: \"sql_injection\" },\n { regex: /db\\.Exec\\s*\\(/, label: \"SQL exec\", severity: \"error\", category: \"sql_injection\" },\n { regex: /\\.query\\s*\\(\\s*[`'\"]/, label: \"SQL query string\", severity: \"error\", category: \"sql_injection\" },\n { regex: /cursor\\.execute\\s*\\(/, label: \"SQL execute\", severity: \"error\", category: \"sql_injection\" },\n { regex: /\\.raw\\s*\\(/, label: \"raw SQL query\", severity: \"error\", category: \"sql_injection\" },\n\n // Command injection\n { regex: /exec\\s*\\(/, label: \"command execution\", severity: \"error\", category: \"command_injection\" },\n { regex: /execSync\\s*\\(/, label: \"sync command execution\", severity: \"error\", category: \"command_injection\" },\n { regex: /child_process/, label: \"child process\", severity: \"error\", category: \"command_injection\" },\n { regex: /os\\.system\\s*\\(/, label: \"OS system call\", severity: \"error\", category: \"command_injection\" },\n { regex: /subprocess\\.(?:call|run|Popen)\\s*\\(/, label: \"subprocess call\", severity: \"error\", category: \"command_injection\" },\n\n // Path traversal\n { regex: /fs\\.readFile\\s*\\(/, label: \"file read\", severity: \"warning\", category: \"path_traversal\" },\n { regex: /fs\\.writeFile\\s*\\(/, label: \"file write\", severity: \"warning\", category: \"path_traversal\" },\n { regex: /os\\.Open\\s*\\(/, label: \"file open\", severity: \"warning\", category: \"path_traversal\" },\n { regex: /open\\s*\\(/, label: \"file open\", severity: \"warning\", category: \"path_traversal\" },\n\n // XSS\n { regex: /innerHTML\\s*=/, label: \"HTML injection\", severity: \"error\", category: \"xss\" },\n { regex: /dangerouslySetInnerHTML/, label: \"React HTML injection\", severity: \"error\", category: \"xss\" },\n { regex: /eval\\s*\\(/, label: \"code evaluation\", severity: \"error\", category: \"code_injection\" },\n { regex: /Function\\s*\\(/, label: \"dynamic function\", severity: \"error\", category: \"code_injection\" },\n\n // Outbound (lower severity)\n { regex: /fetch\\s*\\(/, label: \"outbound HTTP fetch\", severity: \"warning\", category: \"ssrf\" },\n { regex: /http\\.Get\\s*\\(/, label: \"outbound HTTP GET\", severity: \"warning\", category: \"ssrf\" },\n { regex: /axios\\.\\w+\\s*\\(/, label: \"outbound HTTP request\", severity: \"warning\", category: \"ssrf\" },\n];\n\n// ──── Sanitizers that remove taint ────\n\ninterface SanitizerPattern {\n regex: RegExp;\n label: string;\n removes: string | \"all\";\n}\n\nconst SANITIZERS: SanitizerPattern[] = [\n // Type coercion (removes SQL injection for numbers)\n { regex: /parseInt\\s*\\(/, label: \"parseInt\", removes: \"sql_injection\" },\n { regex: /parseFloat\\s*\\(/, label: \"parseFloat\", removes: \"sql_injection\" },\n { regex: /Number\\s*\\(/, label: \"Number()\", removes: \"sql_injection\" },\n { regex: /strconv\\.Atoi\\s*\\(/, label: \"strconv.Atoi\", removes: \"sql_injection\" },\n { regex: /strconv\\.Parse\\w+\\s*\\(/, label: \"strconv.Parse*\", removes: \"sql_injection\" },\n { regex: /int\\s*\\(/, label: \"int()\", removes: \"sql_injection\" },\n\n // Parameterized queries\n { regex: /\\$\\d+/, label: \"parameterized query ($N)\", removes: \"sql_injection\" },\n { regex: /\\?\\s*(?:,|\\)|\\])/, label: \"parameterized query (?)\", removes: \"sql_injection\" },\n\n // Schema validation (removes all taint)\n { regex: /schema\\.parse\\s*\\(/, label: \"schema.parse()\", removes: \"all\" },\n { regex: /\\.validate\\s*\\(/, label: \".validate()\", removes: \"all\" },\n { regex: /zod\\./i, label: \"Zod validation\", removes: \"all\" },\n { regex: /joi\\./i, label: \"Joi validation\", removes: \"all\" },\n\n // HTML escaping\n { regex: /escape\\s*\\(/, label: \"escape()\", removes: \"xss\" },\n { regex: /sanitize\\s*\\(/, label: \"sanitize()\", removes: \"xss\" },\n { regex: /DOMPurify/i, label: \"DOMPurify\", removes: \"xss\" },\n { regex: /html\\.EscapeString/i, label: \"html.EscapeString\", removes: \"xss\" },\n\n // Path sanitization\n { regex: /path\\.(?:join|resolve|normalize)\\s*\\(/, label: \"path.join/resolve\", removes: \"path_traversal\" },\n { regex: /filepath\\.(?:Clean|Abs)\\s*\\(/, label: \"filepath.Clean\", removes: \"path_traversal\" },\n];\n\n// ──── Taint Tracking Engine (per-function scope) ────\n\ninterface TaintedVar {\n name: string;\n source: TaintSource;\n sanitizedFor: Set<string>; // categories sanitized\n}\n\nfunction extractAssignedVariable(line: string): string | null {\n // Go/JS/TS: var/const/let name = ... or name :=\n const declMatch = line.match(/(?:var|const|let)\\s+(\\w+)\\s*[:=]/);\n if (declMatch) return declMatch[1];\n\n const shortDeclMatch = line.match(/(\\w+)\\s*:=/);\n if (shortDeclMatch) return shortDeclMatch[1];\n\n // Simple assignment: name = ...\n const assignMatch = line.match(/^(\\w+)\\s*=/);\n if (assignMatch) return assignMatch[1];\n\n // Python: name = ...\n const pyMatch = line.match(/^\\s*(\\w+)\\s*=/);\n if (pyMatch) return pyMatch[1];\n\n return null;\n}\n\nconst ALL_TAINT_CATEGORIES = new Set([\"sql_injection\", \"command_injection\", \"path_traversal\", \"xss\", \"ssrf\", \"code_injection\"]);\n\nfunction identifySources(\n trimmed: string,\n langSources: SourcePattern[],\n lineNumber: number,\n taintedVars: Map<string, TaintedVar>,\n): void {\n for (const src of langSources) {\n if (src.regex.test(trimmed)) {\n const varName = extractAssignedVariable(trimmed);\n if (varName) {\n taintedVars.set(varName, {\n name: varName,\n source: { type: src.label, variable: varName, line: lineNumber },\n sanitizedFor: new Set(),\n });\n }\n }\n }\n}\n\nfunction checkSanitizers(\n trimmed: string,\n taintedVars: Map<string, TaintedVar>,\n): void {\n for (const [varName, tainted] of taintedVars) {\n if (!trimmed.includes(varName)) continue;\n for (const san of SANITIZERS) {\n if (san.regex.test(trimmed)) {\n if (san.removes === \"all\") {\n tainted.sanitizedFor = new Set(ALL_TAINT_CATEGORIES);\n } else {\n tainted.sanitizedFor.add(san.removes);\n }\n }\n }\n }\n}\n\nfunction identifySinks(\n trimmed: string,\n fn: ExtractedFunction,\n lineNumber: number,\n taintedVars: Map<string, TaintedVar>,\n flows: TaintFlow[],\n): void {\n for (const sink of TAINT_SINKS) {\n if (!sink.regex.test(trimmed)) continue;\n\n for (const [varName, tainted] of taintedVars) {\n if (!trimmed.includes(varName)) continue;\n if (tainted.sanitizedFor.has(sink.category)) continue;\n\n // Check inline sanitization on the same line\n let inlineSanitized = false;\n for (const san of SANITIZERS) {\n if (san.regex.test(trimmed) && (san.removes === \"all\" || san.removes === sink.category)) {\n inlineSanitized = true;\n break;\n }\n }\n if (inlineSanitized) continue;\n\n flows.push({\n file: fn.file,\n relativePath: fn.relativePath,\n functionName: fn.name,\n source: tainted.source,\n sink: { type: sink.label, expression: trimmed.slice(0, 100), line: lineNumber, severity: sink.severity },\n sanitized: false,\n language: fn.language,\n });\n }\n }\n}\n\nfunction analyzeFunction(\n fn: ExtractedFunction,\n): TaintFlow[] {\n const flows: TaintFlow[] = [];\n const lines = fn.rawBody.split(\"\\n\");\n const taintedVars = new Map<string, TaintedVar>();\n const langSources = TAINT_SOURCES[fn.language] ?? [];\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n const lineNumber = fn.line + i;\n\n identifySources(trimmed, langSources, lineNumber, taintedVars);\n checkSanitizers(trimmed, taintedVars);\n identifySinks(trimmed, fn, lineNumber, taintedVars, flows);\n }\n\n return flows;\n}\n\nexport function analyzeTaintFlows(functions: ExtractedFunction[]): TaintFlow[] {\n const allFlows: TaintFlow[] = [];\n for (const fn of functions) {\n allFlows.push(...analyzeFunction(fn));\n }\n return allFlows;\n}\n\nexport function taintFindings(flows: TaintFlow[]): Finding[] {\n // Deduplicate by file+function+sink type\n const seen = new Set<string>();\n\n return flows\n .filter((flow) => {\n const key = `${flow.relativePath}:${flow.functionName}:${flow.sink.type}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .map((flow) => ({\n analyzerId: \"codedna-taint\",\n severity: flow.sink.severity,\n confidence: 0.75,\n message: `Unsanitized ${flow.source.type} reaches ${flow.sink.type} in ${flow.functionName}(): ${flow.source.variable} (line ${flow.source.line}) → ${flow.sink.type} (line ${flow.sink.line})`,\n locations: [\n { file: flow.relativePath, line: flow.source.line, snippet: `${flow.source.variable} = ${flow.source.type}` },\n { file: flow.relativePath, line: flow.sink.line, snippet: flow.sink.expression.slice(0, 80) },\n ],\n tags: [\"codedna\", \"taint\", \"security\"],\n }));\n}\n","import type { SourceFile } from \"../core/types.js\";\nimport type { PatternDistribution, DeviationJustification, JustificationSignal, ArchPattern } from \"./types.js\";\nimport type { Finding } from \"../core/types.js\";\n\n// Special directories where deviations are more likely justified\nconst SPECIAL_DIRS = /(?:reporting|analytics|admin|migration|scripts|tools|benchmark|seed|fixtures|test)/i;\n\n// Complex SQL indicators (justify raw SQL over repository pattern)\nconst COMPLEX_SQL_INDICATORS = [\n /\\bGROUP\\s+BY\\b/i,\n /\\bHAVING\\b/i,\n /\\bWINDOW\\b/i,\n /\\bOVER\\s*\\(/i,\n /\\bWITH\\s+\\w+\\s+AS\\s*\\(/i, // CTEs\n /\\bUNION\\b/i,\n /\\bEXCEPT\\b/i,\n /\\bINTERSECT\\b/i,\n /JOIN.*JOIN.*JOIN/is, // 3+ JOINs\n /\\bLATERAL\\b/i,\n /\\bEXISTS\\s*\\(/i,\n];\n\n// Explanatory comment patterns near deviations\nconst COMMENT_EXPLAINS = /(?:performance|optimization|complex\\s+query|custom\\s+sql|raw\\s+sql|aggregate|report|analytics|workaround|intentional|reason|because|note:|todo:|hack:)/i;\n\nfunction countComplexSqlSignals(content: string): number {\n let count = 0;\n for (const pattern of COMPLEX_SQL_INDICATORS) {\n if (pattern.test(content)) count++;\n }\n return count;\n}\n\nfunction hasExplanatoryComment(content: string, lines: string[], deviationLine?: number): boolean {\n // Check comments near the deviation (within 5 lines above the SQL/pattern usage)\n if (deviationLine !== undefined) {\n const start = Math.max(0, deviationLine - 5);\n const end = Math.min(lines.length, deviationLine + 3);\n const nearby = lines.slice(start, end).join(\"\\n\");\n if (COMMENT_EXPLAINS.test(nearby)) return true;\n }\n\n // Also check file-level comments\n const firstLines = lines.slice(0, 10).join(\"\\n\");\n return COMMENT_EXPLAINS.test(firstLines);\n}\n\nfunction isInSpecialDirectory(path: string): boolean {\n return SPECIAL_DIRS.test(path);\n}\n\nfunction computeSignalScore(\n file: SourceFile,\n devDist: PatternDistribution,\n dominantFiles: PatternDistribution[],\n projectDominant: ArchPattern,\n): { signals: JustificationSignal[]; totalWeight: number } {\n const lines = file.content.split(\"\\n\");\n const signals: JustificationSignal[] = [];\n let totalWeight = 0;\n\n // Complex SQL present\n const sqlComplexity = countComplexSqlSignals(file.content);\n if (sqlComplexity > 0) {\n const weight = Math.min(sqlComplexity * 0.15, 0.3);\n signals.push({ type: \"complex_sql\", present: true, weight, evidence: `${sqlComplexity} complex SQL indicators` });\n totalWeight += weight;\n } else {\n signals.push({ type: \"complex_sql\", present: false, weight: 0 });\n }\n\n // Explanatory comment\n const firstSignalLine = devDist.signals[0]?.line;\n if (hasExplanatoryComment(file.content, lines, firstSignalLine)) {\n signals.push({ type: \"explanatory_comment\", present: true, weight: 0.2, evidence: \"comment explains deviation\" });\n totalWeight += 0.2;\n } else {\n signals.push({ type: \"no_comment\", present: true, weight: -0.1, evidence: \"no explanatory comment\" });\n totalWeight -= 0.1;\n }\n\n // Special directory\n if (isInSpecialDirectory(devDist.relativePath)) {\n signals.push({ type: \"special_directory\", present: true, weight: 0.2, evidence: devDist.relativePath });\n totalWeight += 0.2;\n }\n\n // Simple CRUD SQL (no complex indicators)\n if (devDist.dominantPattern === \"raw_sql\" && sqlComplexity === 0) {\n const hasCrudOnly = /(?:SELECT\\s+\\*|INSERT\\s+INTO|UPDATE\\s+\\w+\\s+SET|DELETE\\s+FROM)/i.test(file.content);\n if (hasCrudOnly) {\n signals.push({ type: \"simple_crud\", present: true, weight: -0.3, evidence: \"simple CRUD SQL without complex operations\" });\n totalWeight -= 0.3;\n }\n }\n\n // Same directory as dominant-pattern files\n const devDir = devDist.relativePath.includes(\"/\") ? devDist.relativePath.slice(0, devDist.relativePath.lastIndexOf(\"/\")) : \".\";\n const sameDir = dominantFiles.filter((d) => {\n const dir = d.relativePath.includes(\"/\") ? d.relativePath.slice(0, d.relativePath.lastIndexOf(\"/\")) : \".\";\n return dir === devDir;\n });\n if (sameDir.length > 0) {\n signals.push({ type: \"same_directory_as_dominant\", present: true, weight: -0.2, evidence: `${sameDir.length} files in same directory use ${projectDominant}` });\n totalWeight -= 0.2;\n }\n\n return { signals, totalWeight };\n}\n\nfunction classifyDeviation(totalWeight: number): { justificationScore: number; verdict: DeviationJustification[\"verdict\"] } {\n const rawScore = 0.5 + totalWeight;\n const justificationScore = Math.max(0, Math.min(1, rawScore));\n\n let verdict: DeviationJustification[\"verdict\"];\n if (justificationScore >= 0.6) verdict = \"likely_justified\";\n else if (justificationScore <= 0.3) verdict = \"likely_accidental\";\n else verdict = \"uncertain\";\n\n return { justificationScore, verdict };\n}\n\nexport function scoreDeviations(\n distributions: PatternDistribution[],\n files: SourceFile[],\n): DeviationJustification[] {\n if (distributions.length < 2) return [];\n\n // Find project-wide dominant pattern\n const patternCounts = new Map<ArchPattern, number>();\n for (const dist of distributions) {\n patternCounts.set(dist.dominantPattern, (patternCounts.get(dist.dominantPattern) ?? 0) + 1);\n }\n\n let projectDominant: ArchPattern = \"none\";\n let maxCount = 0;\n for (const [pattern, count] of patternCounts) {\n if (count > maxCount) {\n maxCount = count;\n projectDominant = pattern;\n }\n }\n\n if (projectDominant === \"none\") return [];\n\n const justifications: DeviationJustification[] = [];\n\n // Find files deviating from the dominant pattern\n const dominantFiles = distributions.filter((d) => d.dominantPattern === projectDominant);\n const deviatingFiles = distributions.filter((d) => d.dominantPattern !== projectDominant);\n\n for (const devDist of deviatingFiles) {\n const file = files.find((f) => f.path === devDist.file || f.relativePath === devDist.relativePath);\n if (!file) continue;\n\n const { signals, totalWeight } = computeSignalScore(file, devDist, dominantFiles, projectDominant);\n const { justificationScore, verdict } = classifyDeviation(totalWeight);\n\n justifications.push({\n file: devDist.file,\n relativePath: devDist.relativePath,\n deviatingPattern: devDist.dominantPattern,\n dominantPattern: projectDominant,\n justificationScore,\n signals,\n verdict,\n });\n }\n\n return justifications;\n}\n\nexport function deviationFindings(justifications: DeviationJustification[]): Finding[] {\n return justifications\n .filter((j) => j.verdict === \"likely_accidental\")\n .map((j) => {\n const signalSummary = j.signals\n .filter((s) => s.present && s.weight !== 0)\n .map((s) => s.evidence)\n .filter(Boolean)\n .join(\"; \");\n\n return {\n analyzerId: \"codedna-deviation\",\n severity: \"warning\" as const,\n confidence: Math.max(0.5, 1 - j.justificationScore),\n message: `Likely accidental deviation: ${j.relativePath} uses ${j.deviatingPattern} while project uses ${j.dominantPattern}. Signals: ${signalSummary}`,\n locations: [{ file: j.relativePath }],\n tags: [\"codedna\", \"deviation\", \"accidental\"],\n };\n });\n}\n","import type { AnalysisContext, Finding } from \"../core/types.js\";\nimport type { CodeDnaResult } from \"./types.js\";\nimport { extractAllFunctions } from \"./function-extractor.js\";\nimport { computeSemanticFingerprints, findDuplicateGroups, fingerprintFindings } from \"./semantic-fingerprint.js\";\nimport { extractOperationSequences, findSequenceSimilarities, sequenceFindings } from \"./operation-sequence.js\";\nimport { classifyPatterns, patternFindings } from \"./pattern-classifier.js\";\nimport { analyzeTaintFlows, taintFindings } from \"./taint-analysis.js\";\nimport { scoreDeviations, deviationFindings } from \"./deviation-heuristics.js\";\n\nexport function runCodeDnaAnalysis(ctx: AnalysisContext): CodeDnaResult {\n const timings = {\n extractionMs: 0,\n fingerprintMs: 0,\n sequenceMs: 0,\n patternMs: 0,\n taintMs: 0,\n deviationMs: 0,\n totalMs: 0,\n };\n\n const totalStart = Date.now();\n\n // 1. Extract all functions (shared across modules)\n let t = Date.now();\n const functions = extractAllFunctions(ctx.files);\n timings.extractionMs = Date.now() - t;\n\n // 2. Semantic fingerprinting (Module 1)\n t = Date.now();\n const fingerprints = computeSemanticFingerprints(functions);\n const duplicateGroups = findDuplicateGroups(fingerprints, functions);\n timings.fingerprintMs = Date.now() - t;\n\n // 3. Operation sequence analysis (Module 2)\n t = Date.now();\n const sequences = extractOperationSequences(functions);\n const sequenceSimilarities = findSequenceSimilarities(sequences, functions);\n timings.sequenceMs = Date.now() - t;\n\n // 4. Pattern classification (Module 3)\n t = Date.now();\n const patternDistributions = classifyPatterns(ctx.files);\n timings.patternMs = Date.now() - t;\n\n // 5. Taint analysis (Module 4)\n t = Date.now();\n const taintFlows = analyzeTaintFlows(functions);\n timings.taintMs = Date.now() - t;\n\n // 6. Deviation heuristics (Module 5) — uses pattern distributions\n t = Date.now();\n const deviationJustifications = scoreDeviations(patternDistributions, ctx.files);\n timings.deviationMs = Date.now() - t;\n\n // Aggregate all findings\n const findings: Finding[] = [\n ...fingerprintFindings(duplicateGroups),\n ...sequenceFindings(sequenceSimilarities),\n ...patternFindings(patternDistributions),\n ...taintFindings(taintFlows),\n ...deviationFindings(deviationJustifications),\n ];\n\n timings.totalMs = Date.now() - totalStart;\n\n return {\n functions,\n fingerprints,\n duplicateGroups,\n sequenceSimilarities,\n patternDistributions,\n taintFlows,\n deviationJustifications,\n findings,\n timings,\n };\n}\n","import type { AnalysisContext, Finding } from \"../core/types.js\";\nimport type { ExtractedFunction } from \"../codedna/types.js\";\nimport type { MlFunctionPayload } from \"./types.js\";\n\nconst MAX_FUNCTIONS = 30;\nconst MAX_LINES_PER_FUNCTION = 60;\n\nexport function sampleFunctionsForMl(\n functions: ExtractedFunction[],\n findings: Finding[],\n): MlFunctionPayload[] {\n // Score functions by importance\n const scored = functions.map((fn) => {\n let score = 0;\n\n // Entry point files are high priority\n if (/(?:main|index|app|server|lib|mod)\\./i.test(fn.file)) score += 10;\n\n // Files with existing findings\n const fnFindings = findings.filter((f) =>\n f.locations.some((l) => l.file === fn.relativePath),\n );\n score += fnFindings.length * 3;\n\n // Larger functions are more interesting\n const bodyLines = fn.rawBody.split(\"\\n\").length;\n score += Math.min(bodyLines / 20, 5);\n\n // Handler/service files\n if (/(?:handler|controller|service|route|endpoint)/i.test(fn.file)) score += 3;\n\n return { fn, score };\n });\n\n // Sort by score descending, take top N\n scored.sort((a, b) => b.score - a.score);\n const selected = scored.slice(0, MAX_FUNCTIONS);\n\n return selected.map(({ fn }) => {\n // Truncate body to max lines\n const bodyLines = fn.rawBody.split(\"\\n\");\n const truncatedBody =\n bodyLines.length > MAX_LINES_PER_FUNCTION\n ? bodyLines.slice(0, MAX_LINES_PER_FUNCTION).join(\"\\n\") + \"\\n// ... truncated\"\n : fn.rawBody;\n\n return {\n id: `${fn.relativePath}::${fn.name}`,\n name: fn.name,\n file: fn.relativePath,\n body: truncatedBody,\n line_start: fn.line,\n line_end: fn.line + bodyLines.length,\n language: fn.language,\n };\n });\n}\n","import type { MlAnalyzeRequest, MlAnalyzeResponse } from \"./types.js\";\n\nconst DEFAULT_API_URL = \"https://vibedrift-api.fly.dev\";\nconst TIMEOUT_MS = 90_000; // 90s to handle cold starts with model loading\n\n/**\n * Call the VibeDrift deep-analysis API.\n *\n * Authenticates with a Bearer token from the user's `vibedrift login`\n * session (stored at ~/.vibedrift/config.json or in VIBEDRIFT_TOKEN).\n */\nexport async function callMlApi(\n request: MlAnalyzeRequest,\n token?: string,\n apiUrl?: string,\n): Promise<MlAnalyzeResponse> {\n const url = `${apiUrl ?? DEFAULT_API_URL}/v1/analyze`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(request),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"\");\n throw new Error(`Deep-analysis API error ${response.status}: ${errorBody.slice(0, 200)}`);\n }\n\n return (await response.json()) as MlAnalyzeResponse;\n } finally {\n clearTimeout(timeout);\n }\n}\n","import type { Finding } from \"../core/types.js\";\nimport type {\n MlAnalyzeResponse,\n MlFindingForLlm,\n FilteredMlResults,\n} from \"./types.js\";\n\nconst HIGH_CONFIDENCE_THRESHOLD = 0.85;\nconst MEDIUM_CONFIDENCE_THRESHOLD = 0.50;\nconst MAX_LLM_CANDIDATES = 5;\n\nexport function filterByConfidence(response: MlAnalyzeResponse): FilteredMlResults {\n const highConfidence: Finding[] = [];\n const mediumConfidence: MlFindingForLlm[] = [];\n let droppedCount = 0;\n\n // ──── Process duplicates ────\n for (const dup of response.duplicates) {\n if (dup.confidence >= HIGH_CONFIDENCE_THRESHOLD) {\n highConfidence.push({\n analyzerId: \"ml-duplicate\",\n severity: \"error\",\n confidence: dup.confidence,\n message: `ML-detected semantic duplicate: ${dup.function_a} and ${dup.function_b} (${Math.round(dup.similarity * 100)}% similar)`,\n locations: [\n { file: dup.function_a.split(\"::\")[0] },\n { file: dup.function_b.split(\"::\")[0] },\n ],\n tags: [\"ml\", \"duplicate\"],\n });\n } else if (dup.confidence >= MEDIUM_CONFIDENCE_THRESHOLD) {\n mediumConfidence.push({\n type: \"duplicate\",\n confidence: dup.confidence,\n detail: dup,\n question: `Are ${dup.function_a} and ${dup.function_b} doing the same thing? Similarity: ${Math.round(dup.similarity * 100)}%`,\n });\n } else {\n droppedCount++;\n }\n }\n\n // ──── Process intent mismatches ────\n // Single-word function names (Accept, Quote, List, Verify) are inherently hard\n // to embed semantically — a single word can't convey enough meaning for reliable\n // name-body comparison. Only flag names with 2+ words where semantic distance is clear.\n const GENERIC_SINGLE_WORDS = new Set([\n \"handle\", \"process\", \"get\", \"set\", \"run\", \"do\", \"make\", \"create\",\n \"update\", \"delete\", \"find\", \"check\", \"init\", \"start\", \"stop\",\n \"accept\", \"quote\", \"ingest\", \"verify\", \"request\", \"list\", \"serve\",\n \"parse\", \"build\", \"load\", \"save\", \"send\", \"read\", \"write\", \"close\",\n \"open\", \"reset\", \"flush\", \"sync\", \"fetch\", \"push\", \"pull\", \"setup\",\n \"execute\", \"invoke\", \"dispatch\", \"resolve\", \"reject\", \"validate\",\n \"render\", \"mount\", \"unmount\", \"connect\", \"disconnect\",\n ]);\n\n // CRUD verbs followed by a domain noun are standard handler patterns — the name\n // perfectly describes the intent. Embedding models struggle because the body involves\n // many steps (parse request, validate, DB call, return response) beyond the literal verb.\n const CRUD_PREFIXES = /^(create|update|delete|remove|get|list|find|fetch|search|add|edit|patch|upsert|insert|save|read|load|count|check|validate|verify|accept|reject|approve|deny|submit|publish|archive|restore|activate|deactivate|enable|disable|cancel|revoke|grant|assign|unassign|invite|register|login|logout|signup|signin|signout|reset|confirm|generate|send|export|import|download|upload|sync|refresh|clone|copy|move|merge|split|batch|bulk|process|handle|serve|render|show|display|index|new|close|open|start|stop|pause|resume|retry|queue|schedule|trigger|execute|run|init|setup|configure|install|deploy|migrate|seed|clear|flush|purge|mark|flag|tag|rate|score|vote|like|follow|subscribe|unsubscribe|notify|broadcast|log|track|record|audit|monitor|watch|inspect|scan|analyze|parse|transform|convert|format|encode|decode|encrypt|decrypt|hash|sign|wrap|unwrap|serialize|deserialize|marshal|unmarshal|quote|ingest|request)[A-Z_]/i;\n\n for (const intent of response.intent_mismatches) {\n // Skip single-word names — they generate false positives\n const nameWords = intent.name.replace(/([a-z])([A-Z])/g, \"$1 $2\").split(/[\\s_]+/);\n if (nameWords.length <= 1 || GENERIC_SINGLE_WORDS.has(intent.name.toLowerCase())) {\n droppedCount++;\n continue;\n }\n\n // Skip CRUD verb + domain noun patterns — these names describe the intent correctly,\n // but embedding models can't match a verb-noun name to a complex handler body\n if (CRUD_PREFIXES.test(intent.name)) {\n droppedCount++;\n continue;\n }\n\n if (intent.confidence >= HIGH_CONFIDENCE_THRESHOLD) {\n highConfidence.push({\n analyzerId: \"ml-intent\",\n severity: \"warning\",\n confidence: intent.confidence,\n message: `Function name mismatch: ${intent.name}() — name doesn't match behavior (${Math.round(intent.similarity * 100)}% name-body alignment)`,\n locations: [{ file: intent.function_id.split(\"::\")[0] }],\n tags: [\"ml\", \"intent\"],\n });\n } else if (intent.confidence >= MEDIUM_CONFIDENCE_THRESHOLD) {\n mediumConfidence.push({\n type: \"intent_mismatch\",\n confidence: intent.confidence,\n detail: intent,\n question: `Does ${intent.name}() actually do what its name suggests? Name-body similarity is only ${Math.round(intent.similarity * 100)}%.`,\n });\n } else {\n droppedCount++;\n }\n }\n\n // ──── Process anomalies ────\n for (const anomaly of response.anomalies) {\n if (anomaly.confidence >= HIGH_CONFIDENCE_THRESHOLD) {\n highConfidence.push({\n analyzerId: \"ml-anomaly\",\n severity: \"info\",\n confidence: anomaly.confidence,\n message: `Pattern outlier: ${anomaly.function_id} doesn't cluster with its ${anomaly.cluster_size} peers (distance: ${anomaly.distance_from_cluster.toFixed(2)})`,\n locations: [{ file: anomaly.function_id.split(\"::\")[0] }],\n tags: [\"ml\", \"anomaly\"],\n });\n } else if (anomaly.confidence >= MEDIUM_CONFIDENCE_THRESHOLD) {\n mediumConfidence.push({\n type: \"anomaly\",\n confidence: anomaly.confidence,\n detail: anomaly,\n question: `Is ${anomaly.function_id} intentionally different from the ${anomaly.cluster_size} similar functions?`,\n });\n } else {\n droppedCount++;\n }\n }\n\n // Cap LLM candidates at MAX_LLM_CANDIDATES (highest confidence first)\n mediumConfidence.sort((a, b) => b.confidence - a.confidence);\n droppedCount += Math.max(0, mediumConfidence.length - MAX_LLM_CANDIDATES);\n\n return {\n highConfidence,\n mediumConfidence: mediumConfidence.slice(0, MAX_LLM_CANDIDATES),\n droppedCount,\n };\n}\n","import { basename, join } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\n\n/**\n * Project identity helpers.\n *\n * The dashboard groups scans by `project_hash` and displays them under a\n * human-readable `project_name`. Both values are computed CLI-side so the\n * server never sees absolute paths, only hashes.\n *\n * Autodetect order for `project_name`:\n * 1. --project-name <flag> (explicit override)\n * 2. package.json.name (Node/TS projects)\n * 3. Cargo.toml [package] name (Rust)\n * 4. go.mod module basename (Go)\n * 5. pyproject.toml [project] / [tool.poetry] name (Python)\n * 6. basename(rootDir) (fallback)\n *\n * `project_hash` is always SHA-256 of the absolute rootDir so the same\n * checkout always groups under the same project, even if the user\n * renames it. Collisions across machines are fine — the hash is scoped\n * to the user's scan history.\n */\n\nexport interface ProjectIdentity {\n name: string;\n hash: string;\n}\n\nexport async function detectProjectIdentity(\n rootDir: string,\n override?: string,\n): Promise<ProjectIdentity> {\n const hash = createHash(\"sha256\").update(rootDir).digest(\"hex\");\n\n // Explicit override wins\n if (override && override.trim()) {\n return { name: override.trim(), hash };\n }\n\n // package.json\n const fromPackageJson = await readJsonField(\n join(rootDir, \"package.json\"),\n \"name\",\n );\n if (fromPackageJson) return { name: fromPackageJson, hash };\n\n // Cargo.toml — grep for `name = \"xyz\"` in [package] section\n const fromCargo = await readTomlFieldInSection(\n join(rootDir, \"Cargo.toml\"),\n \"package\",\n \"name\",\n );\n if (fromCargo) return { name: fromCargo, hash };\n\n // go.mod — first \"module github.com/foo/bar\" line, take the last segment\n const fromGoMod = await readGoModule(join(rootDir, \"go.mod\"));\n if (fromGoMod) return { name: fromGoMod, hash };\n\n // pyproject.toml — [project] name or [tool.poetry] name\n const fromPyProject =\n (await readTomlFieldInSection(\n join(rootDir, \"pyproject.toml\"),\n \"project\",\n \"name\",\n )) ??\n (await readTomlFieldInSection(\n join(rootDir, \"pyproject.toml\"),\n \"tool.poetry\",\n \"name\",\n ));\n if (fromPyProject) return { name: fromPyProject, hash };\n\n // Final fallback: directory name\n return { name: basename(rootDir) || \"untitled\", hash };\n}\n\nasync function readJsonField(path: string, field: string): Promise<string | null> {\n try {\n const raw = await readFile(path, \"utf-8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n const value = parsed[field];\n if (typeof value === \"string\" && value.trim()) return value.trim();\n } catch {\n // File missing or malformed — treat as \"not found\"\n }\n return null;\n}\n\n/**\n * Minimal TOML reader — finds `[section]` then the first `key = \"value\"`\n * line within it. Good enough for Cargo.toml / pyproject.toml which\n * both follow a strict structure. Doesn't handle multi-line strings or\n * nested tables, which is fine for our use case.\n */\nasync function readTomlFieldInSection(\n path: string,\n section: string,\n key: string,\n): Promise<string | null> {\n try {\n const raw = await readFile(path, \"utf-8\");\n const lines = raw.split(\"\\n\");\n let inSection = false;\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"[\") && trimmed.endsWith(\"]\")) {\n inSection = trimmed === `[${section}]`;\n continue;\n }\n if (!inSection) continue;\n const match = trimmed.match(/^([\\w-]+)\\s*=\\s*\"([^\"]+)\"/);\n if (match && match[1] === key && match[2]) {\n return match[2];\n }\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nasync function readGoModule(path: string): Promise<string | null> {\n try {\n const raw = await readFile(path, \"utf-8\");\n const match = raw.match(/^\\s*module\\s+(\\S+)/m);\n if (match && match[1]) {\n // Take the last path segment so \"github.com/foo/bar\" → \"bar\"\n const segs = match[1].split(\"/\");\n const last = segs[segs.length - 1];\n if (last) return last;\n }\n } catch {\n // ignore\n }\n return null;\n}\n","import type { AnalysisContext, Finding, DriftFindingReport } from \"../core/types.js\";\nimport type { CodeDnaResult } from \"../codedna/types.js\";\nimport type { FilteredMlResults, MlDeviationPayload, MlLlmValidationPayload } from \"./types.js\";\nimport { sampleFunctionsForMl } from \"./sampler.js\";\nimport { callMlApi } from \"./client.js\";\nimport { filterByConfidence } from \"./confidence.js\";\n\nexport interface MlAnalysisOptions {\n /** Bearer token from `vibedrift login` (~/.vibedrift/config.json or VIBEDRIFT_TOKEN). */\n token?: string;\n /** Override the API base URL — staging/dev only. */\n apiUrl?: string;\n verbose?: boolean;\n driftFindings?: DriftFindingReport[];\n /** Optional human-readable project name override (--project-name flag). */\n projectName?: string;\n /** Composite score (0-100) from local scoring, sent for dashboard history. */\n scoreHint?: number;\n /** Letter grade from local scoring. */\n gradeHint?: string;\n}\n\n/**\n * Build deviation payloads from Code DNA and drift findings for the ML API's\n * deviation classifier. This enables the paid feature: ML-powered verdict\n * (justified vs accidental) that improves on the local heuristic.\n */\nfunction buildDeviationPayloads(\n codeDnaResult: CodeDnaResult | undefined,\n driftFindings: DriftFindingReport[],\n): MlDeviationPayload[] {\n const deviations: MlDeviationPayload[] = [];\n const seen = new Set<string>();\n\n // Code DNA deviations have the richest structural data\n if (codeDnaResult?.deviationJustifications) {\n for (const dj of codeDnaResult.deviationJustifications) {\n const key = `${dj.relativePath}::${dj.deviatingPattern}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const hasComment = dj.signals?.some((s) => s.type === \"explanatory_comment\" && s.present) ?? false;\n const sqlComplexity = dj.signals?.find((s) => s.type === \"complex_sql\")?.present ? 3 : 0;\n const funcComplexity = dj.signals?.reduce((sum, s) => sum + (s.present ? Math.abs(s.weight) : 0), 0) ?? 0;\n\n // Map the deviation pattern to the API's DEVIATION_TYPE_MAP categories:\n // data_access, error_handling, auth, naming, di, config\n // The API model was trained on these 6 types — sending \"architectural\"\n // (which is not in the map) causes it to default to 0.5 and lose signal.\n const patternToType: Record<string, string> = {\n repository: \"data_access\", raw_sql: \"data_access\", orm: \"data_access\",\n direct_db: \"data_access\", http_client: \"data_access\",\n wrap_with_context: \"error_handling\", raw_propagation: \"error_handling\",\n swallow: \"error_handling\", http_error_response: \"error_handling\",\n exception_throw: \"error_handling\", result_type: \"error_handling\",\n constructor_injection: \"di\", global_import: \"di\",\n service_locator: \"di\", no_di: \"di\",\n env_direct: \"config\", config_struct_di: \"config\",\n };\n const inferredType =\n patternToType[dj.deviatingPattern] ??\n patternToType[dj.dominantPattern] ??\n \"data_access\";\n\n deviations.push({\n file: dj.relativePath,\n deviation_type: inferredType,\n dominant_pattern: dj.dominantPattern,\n actual_pattern: dj.deviatingPattern,\n dominant_count: 0,\n total_files: 0,\n snippet: \"\",\n has_comment: hasComment,\n sql_complexity: sqlComplexity,\n function_complexity: Math.round(funcComplexity * 10),\n directory: dj.relativePath.split(\"/\").slice(0, -1).join(\"/\"),\n });\n }\n }\n\n // Drift findings provide dominant/total counts and code evidence\n for (const d of driftFindings) {\n if (d.driftCategory !== \"architectural_consistency\") continue;\n\n for (const df of d.deviatingFiles) {\n const key = `${df.path}::${df.detectedPattern}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n deviations.push({\n file: df.path,\n deviation_type: d.subCategory ?? \"data_access\",\n dominant_pattern: d.dominantPattern,\n actual_pattern: df.detectedPattern,\n dominant_count: d.dominantCount,\n total_files: d.totalRelevantFiles,\n snippet: df.evidence?.[0]?.code?.slice(0, 200) ?? \"\",\n has_comment: false,\n sql_complexity: 0,\n function_complexity: 0,\n directory: df.path.split(\"/\").slice(0, -1).join(\"/\"),\n });\n }\n }\n\n return deviations.slice(0, 20); // API limit\n}\n\n/**\n * Build LLM validation payloads from medium-confidence ML findings.\n * These get sent to the API for surgical Claude validation.\n */\nfunction buildLlmValidationPayloads(\n mediumConfidence: FilteredMlResults[\"mediumConfidence\"],\n): MlLlmValidationPayload[] {\n return mediumConfidence.map((mc) => ({\n finding: mc.question,\n confidence: mc.confidence,\n snippet_a: mc.snippetA ?? \"\",\n snippet_b: mc.snippetB ?? \"\",\n question: mc.question,\n }));\n}\n\nexport async function runMlAnalysis(\n ctx: AnalysisContext,\n codeDnaResult: CodeDnaResult | undefined,\n findings: Finding[],\n options: MlAnalysisOptions,\n): Promise<FilteredMlResults> {\n // Use Code DNA's extracted functions if available, otherwise we need to extract\n let functions = codeDnaResult?.functions ?? [];\n\n if (functions.length === 0) {\n // Fallback: extract functions\n const { extractAllFunctions } = await import(\"../codedna/function-extractor.js\");\n functions = extractAllFunctions(ctx.files);\n }\n\n if (functions.length === 0) {\n return { highConfidence: [], mediumConfidence: [], droppedCount: 0 };\n }\n\n // Sample top functions for the API\n const sampled = sampleFunctionsForMl(functions, findings);\n\n // Build deviation payloads from Code DNA + drift findings\n const deviations = buildDeviationPayloads(codeDnaResult, options.driftFindings ?? []);\n\n // Calculate payload size for transparency\n const payloadSize = JSON.stringify(sampled).length + JSON.stringify(deviations).length;\n\n if (options.verbose) {\n console.error(`[deep] Sending ${sampled.length} functions + ${deviations.length} deviations (${Math.round(payloadSize / 1024)}KB) to VibeDrift API...`);\n console.error(`[deep] No full files transmitted — only function snippets and structural metadata.`);\n }\n\n // Detect project identity (project_name + stable project_hash) so the\n // dashboard can group scans under a user-visible label. Autodetects from\n // package.json / Cargo.toml / go.mod / pyproject.toml, or uses the\n // --project-name override if one was passed.\n const { detectProjectIdentity } = await import(\"./project-name.js\");\n const projectIdentity = await detectProjectIdentity(\n ctx.rootDir,\n options.projectName,\n );\n\n // Build request\n const request = {\n language: ctx.dominantLanguage ?? \"unknown\",\n file_count: ctx.files.length,\n project_hash: projectIdentity.hash,\n project_name: projectIdentity.name,\n score_hint: options.scoreHint,\n grade_hint: options.gradeHint,\n // Tell the server NOT to persist a row from the analyze call —\n // the CLI logs the full scan summary via /v1/scans/log AFTER the\n // pipeline finishes, which has accurate metadata.\n defer_persist: true,\n functions: sampled,\n deviations,\n llm_validations: [] as MlLlmValidationPayload[],\n };\n\n // Call the API\n const response = await callMlApi(request, options.token, options.apiUrl);\n\n if (options.verbose) {\n console.error(\n `[deep] API returned: ${response.duplicates.length} duplicates, ` +\n `${response.intent_mismatches.length} intent mismatches, ` +\n `${response.anomalies.length} anomalies, ` +\n `${response.deviations?.length ?? 0} deviation verdicts — ${response.processing_time_ms}ms`,\n );\n }\n\n // Filter by confidence\n const filtered = filterByConfidence(response);\n\n // Surface the persisted scan id so the caller can upload the HTML report\n if (response.scan_id) {\n filtered.scanId = response.scan_id;\n }\n\n // If API returned ML deviation verdicts, override Code DNA's local heuristic verdicts\n if (response.deviations?.length > 0 && codeDnaResult?.deviationJustifications) {\n for (const mlDev of response.deviations) {\n const local = codeDnaResult.deviationJustifications.find(\n (dj: any) => dj.relativePath === mlDev.file || dj.file === mlDev.file,\n );\n if (local && mlDev.confidence > 0.6) {\n // ML classifier overrides local heuristic\n (local as any).verdict = mlDev.verdict === \"justified\" ? \"likely_justified\"\n : mlDev.verdict === \"accidental\" ? \"likely_accidental\" : local.verdict;\n }\n }\n }\n\n return filtered;\n}\n","import type { Finding } from \"../core/types.js\";\n\n// Analyzer IDs that detect duplicates, in priority order (highest first)\nconst DUPLICATE_ANALYZER_IDS = [\"ml-duplicate\", \"codedna-fingerprint\", \"codedna-opseq\", \"duplicates\"];\nconst DUPLICATE_IDS_SET = new Set(DUPLICATE_ANALYZER_IDS);\n\n/**\n * Deduplicate findings across the three duplicate detection layers.\n *\n * The same function pair can be reported by static analysis, Code DNA, and ML embeddings.\n * We keep only the highest-priority detection per file pair:\n * ML-confirmed > Code DNA fingerprint > Code DNA opseq > Static\n *\n * Non-duplicate findings pass through unchanged.\n */\nexport function deduplicateFindingsAcrossLayers(findings: Finding[]): Finding[] {\n const nonDuplicate: Finding[] = [];\n const duplicateFindings: Finding[] = [];\n\n for (const f of findings) {\n if (DUPLICATE_IDS_SET.has(f.analyzerId)) {\n duplicateFindings.push(f);\n } else {\n nonDuplicate.push(f);\n }\n }\n\n if (duplicateFindings.length === 0) return findings;\n\n // Group duplicate findings by the set of files they involve\n const byFilePair = new Map<string, Finding[]>();\n\n for (const f of duplicateFindings) {\n const key = makeFilePairKey(f);\n if (!byFilePair.has(key)) byFilePair.set(key, []);\n byFilePair.get(key)!.push(f);\n }\n\n // For each file pair group, keep only the highest-priority finding\n const dedupedDuplicates: Finding[] = [];\n\n for (const [, group] of byFilePair) {\n if (group.length === 1) {\n dedupedDuplicates.push(group[0]);\n continue;\n }\n\n // Sort by priority (ML > Code DNA fingerprint > Code DNA opseq > Static)\n group.sort((a, b) => {\n const pa = DUPLICATE_ANALYZER_IDS.indexOf(a.analyzerId);\n const pb = DUPLICATE_ANALYZER_IDS.indexOf(b.analyzerId);\n return pa - pb; // lower index = higher priority\n });\n\n const best = group[0];\n const sources = [...new Set(group.map((f) => f.analyzerId))];\n\n // Annotate the winning finding with detection source info\n if (sources.length > 1) {\n const sourceLabels = sources.map((s) =>\n s === \"ml-duplicate\" ? \"ML embeddings\"\n : s === \"codedna-fingerprint\" ? \"Code DNA fingerprint\"\n : s === \"codedna-opseq\" ? \"Code DNA sequence\"\n : \"static analysis\"\n );\n best.message += ` [confirmed by ${sourceLabels.join(\", \")}]`;\n }\n\n dedupedDuplicates.push(best);\n }\n\n return [...nonDuplicate, ...dedupedDuplicates];\n}\n\n/**\n * Create a normalized key for a finding based on its involved files.\n * For single-file findings, uses the file + analyzer as key.\n * For multi-file findings (duplicates), sorts file paths for consistency.\n */\nfunction makeFilePairKey(f: Finding): string {\n // Use ALL unique files (sorted + deduped) so 3+-file clusters merge\n // correctly when reported by different layers. The old approach used\n // only the first two files, which meant {A,B,C} and {A,C} could\n // produce different keys and inflate the duplicate count.\n const files = [...new Set(\n f.locations.map((l) => l.file).filter(Boolean),\n )].sort();\n\n if (files.length >= 2) {\n return `dup::${files.join(\"::\")}`;\n }\n\n // Single-file duplicate findings (e.g., static \"X pairs of duplicates in this file\")\n return `dup::${files[0] ?? \"unknown\"}::${f.analyzerId}`;\n}\n","import type { ScanResult } from \"../core/types.js\";\n\nconst TIMEOUT_MS = 30_000;\n\ninterface SummaryResponse {\n summary: string;\n highlights: string[];\n processingTimeMs: number;\n}\n\nexport async function fetchAiSummary(\n result: ScanResult,\n apiUrl: string,\n token?: string,\n): Promise<{ summary: string; highlights: string[] } | null> {\n const dna = result.codeDnaResult;\n const mlFindings = result.findings.filter((f) => f.tags?.includes(\"ml\"));\n\n const body = {\n project: result.context.rootDir.split(\"/\").pop() ?? \"project\",\n score: result.compositeScore,\n maxScore: result.maxCompositeScore,\n grade: getGrade(result.compositeScore, result.maxCompositeScore),\n fileCount: result.context.files.length,\n totalLines: result.context.totalLines,\n languages: [...result.context.languageBreakdown.entries()]\n .map(([l, s]) => `${l}: ${s.files} files`)\n .join(\", \"),\n driftFindings: (result.driftFindings ?? []).map((d) => ({\n severity: d.severity,\n finding: d.finding,\n category: d.driftCategory,\n consistency: d.consistencyScore,\n dominant: d.dominantPattern,\n deviatingFiles: d.deviatingFiles.map((f) => f.path).join(\", \"),\n })),\n codeDnaSummary: dna ? {\n functions: dna.functions?.length ?? 0,\n fingerprints: dna.duplicateGroups?.length ?? 0,\n sequences: dna.sequenceSimilarities?.length ?? 0,\n taintFlows: dna.taintFlows?.length ?? 0,\n deviations: dna.deviationJustifications?.length ?? 0,\n } : null,\n mlSummary: mlFindings.length > 0 ? {\n duplicates: mlFindings.filter((f) => f.analyzerId === \"ml-duplicate\").length,\n intentMismatches: mlFindings.filter((f) => f.analyzerId === \"ml-intent\").length,\n anomalies: mlFindings.filter((f) => f.analyzerId === \"ml-anomaly\").length,\n } : null,\n topIssues: (result.driftFindings ?? [])\n .sort((a, b) => {\n const sev = { error: 3, warning: 2, info: 1 };\n return (sev[b.severity as keyof typeof sev] ?? 0) - (sev[a.severity as keyof typeof sev] ?? 0);\n })\n .slice(0, 5)\n .map((d) => d.recommendation),\n };\n\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);\n\n try {\n const response = await fetch(`${apiUrl}/v1/summarize`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as SummaryResponse;\n return { summary: data.summary, highlights: data.highlights };\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction getGrade(score: number, max: number): string {\n const pct = max > 0 ? (score / max) * 100 : 0;\n if (pct >= 90) return \"A\";\n if (pct >= 75) return \"B\";\n if (pct >= 50) return \"C\";\n if (pct >= 25) return \"D\";\n return \"F\";\n}\n","/**\n * Log a completed scan to the dashboard via /v1/scans/log.\n *\n * Called by the CLI for EVERY scan, free or deep, after the local\n * pipeline + scoring + HTML rendering has finished. This is the single\n * source of truth for what shows up in the user's dashboard — the\n * values sent here are what the user sees in the dashboard's metadata\n * strip and timeline.\n *\n * Silent on failure (network down, server 500, etc.) — the scan\n * already succeeded locally so a failed log shouldn't surface an error.\n */\n\nconst DEFAULT_API_URL = \"https://vibedrift-api.fly.dev\";\nconst TIMEOUT_MS = 20_000;\nconst MAX_HTML_BYTES = 1_500_000;\n\nexport interface ScanLogPayload {\n project_hash?: string;\n project_name?: string;\n language: string;\n file_count: number;\n function_count: number;\n finding_count: number;\n score?: number | null;\n grade?: string | null;\n duplicates_found: number;\n intent_mismatches: number;\n anomalies_found: number;\n is_deep: boolean;\n processing_time_ms: number;\n /** Full self-contained HTML report. Truncated server-side if too large. */\n report_html?: string;\n /**\n * Sanitized full ScanResult — the canonical source of truth for the\n * dashboard. Both the metadata strip and the embedded HTML report\n * are derived from this object, so they're guaranteed consistent.\n * Absolute paths are stripped before sending.\n */\n result_json?: Record<string, unknown>;\n}\n\nexport interface ScanLogResult {\n ok: boolean;\n scanId?: string;\n projectId?: string;\n bytesStored?: number;\n error?: string;\n}\n\nexport async function logScan(opts: {\n payload: ScanLogPayload;\n token: string;\n apiUrl?: string;\n verbose?: boolean;\n}): Promise<ScanLogResult> {\n const { payload, token, apiUrl, verbose } = opts;\n const base = apiUrl ?? DEFAULT_API_URL;\n\n // Trim HTML if it exceeds the cap so we still log the metadata\n const trimmed = { ...payload };\n if (trimmed.report_html) {\n const size = Buffer.byteLength(trimmed.report_html, \"utf-8\");\n if (size > MAX_HTML_BYTES) {\n if (verbose) {\n console.error(\n `[scan-log] HTML too large (${Math.round(size / 1024)}KB), dropping the blob`,\n );\n }\n delete trimmed.report_html;\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);\n\n try {\n const res = await fetch(`${base}/v1/scans/log`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(trimmed),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n if (verbose) {\n console.error(`[scan-log] HTTP ${res.status}: ${text.slice(0, 200)}`);\n }\n return { ok: false, error: `HTTP ${res.status}` };\n }\n\n const data = (await res.json().catch(() => ({}))) as {\n scan_id?: string;\n project_id?: string;\n bytes_stored?: number;\n };\n\n if (verbose) {\n console.error(\n `[scan-log] Logged scan ${data.scan_id?.slice(0, 8) ?? \"?\"} ` +\n `(project ${data.project_id?.slice(0, 8) ?? \"?\"}, ` +\n `${data.bytes_stored ?? 0} HTML bytes)`,\n );\n }\n\n return {\n ok: true,\n scanId: data.scan_id,\n projectId: data.project_id,\n bytesStored: data.bytes_stored,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (verbose) console.error(`[scan-log] Failed: ${msg}`);\n return { ok: false, error: msg };\n } finally {\n clearTimeout(timer);\n }\n}\n","import type { ScanResult } from \"../core/types.js\";\n\n/**\n * Convert a ScanResult into a JSON-safe object suitable for upload to the\n * dashboard. The on-the-wire shape becomes the single source of truth: both\n * the dashboard metadata strip AND the embedded HTML report are derived\n * from this object, so they're guaranteed consistent.\n *\n * What we strip:\n * - `context.rootDir` (absolute path on the user's machine — privacy)\n * - Any absolute path that starts with `rootDir` is rewritten relative\n *\n * What we keep:\n * - All findings (metadata only — no file contents)\n * - All drift findings + per-category scores\n * - codeDnaResult summary (function names, hashes, deviation verdicts)\n * - Composite scores, grade, language breakdown\n * - Per-file scores (with relative paths)\n *\n * What we drop entirely (large + not needed for the dashboard):\n * - Raw file contents from `context.files`\n * - tree-sitter AST nodes\n * - Map / Set instances (converted to plain object/array)\n */\ntype StripPathFn = (p: string | undefined | null) => string | null;\ntype SanitizeNodeFn = (node: unknown) => unknown;\n\nfunction createStripPath(rootDir: string): StripPathFn {\n return (p: string | undefined | null): string | null => {\n if (!p) return null;\n if (rootDir && p.startsWith(rootDir)) {\n const rel = p.slice(rootDir.length).replace(/^\\/+/, \"\");\n return rel || \".\";\n }\n return p;\n };\n}\n\nfunction createSanitizeNode(stripPath: StripPathFn): SanitizeNodeFn {\n const sanitizeNode = (node: unknown): unknown => {\n if (typeof node === \"string\") return stripPath(node) ?? node;\n if (Array.isArray(node)) return node.map(sanitizeNode);\n if (node instanceof Map) {\n return sanitizeMapNode(node, stripPath, sanitizeNode);\n }\n if (node instanceof Set) {\n return [...node].map(sanitizeNode);\n }\n if (node && typeof node === \"object\") {\n return sanitizeObjectNode(node as Record<string, unknown>, stripPath, sanitizeNode);\n }\n return node;\n };\n return sanitizeNode;\n}\n\nfunction sanitizeObjectNode(\n node: Record<string, unknown>,\n stripPath: StripPathFn,\n sanitizeNode: SanitizeNodeFn,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(node)) {\n if (k === \"rootDir\") continue;\n if (k === \"files\" && Array.isArray(v)) {\n out[k] = sanitizeFilesList(v as Array<Record<string, unknown>>, stripPath);\n continue;\n }\n if (k === \"ast\" || k === \"treeSitterNode\") continue;\n out[k] = sanitizeNode(v);\n }\n return out;\n}\n\nfunction sanitizeFilesList(\n files: Array<Record<string, unknown>>,\n stripPath: StripPathFn,\n): Array<Record<string, unknown>> {\n return files.map((f) => ({\n relativePath: stripPath(f.relativePath as string) ?? f.relativePath,\n lineCount: f.lineCount,\n language: f.language,\n }));\n}\n\nfunction sanitizeMapNode(\n node: Map<unknown, unknown>,\n stripPath: StripPathFn,\n sanitizeNode: SanitizeNodeFn,\n): Record<string, unknown> {\n const obj: Record<string, unknown> = {};\n for (const [k, v] of node.entries()) {\n const safeKey = typeof k === \"string\" ? stripPath(k) ?? k : String(k);\n obj[safeKey] = sanitizeNode(v);\n }\n return obj;\n}\n\nexport function sanitizeResultForUpload(result: ScanResult): Record<string, unknown> {\n const ctx = result.context;\n const rootDir = ctx?.rootDir ?? \"\";\n\n const stripPath = createStripPath(rootDir);\n const sanitizeNode = createSanitizeNode(stripPath);\n\n return {\n schema: \"vibedrift-scan-result/v1\",\n project: {},\n language: {\n dominant: ctx?.dominantLanguage ?? null,\n breakdown: sanitizeNode(ctx?.languageBreakdown),\n totalLines: ctx?.totalLines ?? 0,\n },\n fileCount: (ctx?.files ?? []).length,\n files: sanitizeNode(ctx?.files),\n score: {\n composite: result.compositeScore,\n max: result.maxCompositeScore,\n categories: sanitizeNode(result.scores),\n },\n findings: sanitizeNode(result.findings),\n driftFindings: sanitizeNode(result.driftFindings),\n driftScores: sanitizeNode(result.driftScores),\n codeDnaResult: sanitizeNode(result.codeDnaResult),\n perFileScores: sanitizeNode(result.perFileScores),\n teaseMessages: result.teaseMessages,\n aiSummary: result.aiSummary ?? null,\n scanTimeMs: result.scanTimeMs,\n };\n}\n","/**\n * CSV report renderer for VibeDrift scan results.\n *\n * Produces a multi-section CSV document covering summary stats, category scores,\n * drift findings, Code DNA results (duplicates, taint flows, pattern distributions),\n * per-file scores, and deep insights. Designed for spreadsheet import and CI\n * artifact archiving.\n */\n\nimport type { ScanResult } from \"../core/types.js\";\n\nfunction csvEscape(val: string): string {\n if (val.includes(\",\") || val.includes('\"') || val.includes(\"\\n\")) {\n return '\"' + val.replace(/\"/g, '\"\"') + '\"';\n }\n return val;\n}\n\nfunction row(...cells: (string | number)[]): string {\n return cells.map((c) => csvEscape(String(c))).join(\",\");\n}\n\nfunction csvMetadata(result: ScanResult): string[] {\n return [\n \"VIBEDRIFT REPORT\",\n row(\"Project\", result.context.rootDir.split(\"/\").pop() ?? \"\"),\n row(\"Files Scanned\", result.context.files.length),\n row(\"Total Lines\", result.context.totalLines),\n row(\"Scan Time (ms)\", result.scanTimeMs),\n row(\"Composite Score\", result.compositeScore),\n row(\"Max Score\", result.maxCompositeScore),\n \"\",\n ];\n}\n\nfunction csvScoreCategories(result: ScanResult): string[] {\n const lines: string[] = [];\n lines.push(\"CATEGORY SCORES\");\n lines.push(row(\"Category\", \"Score\", \"Max Score\", \"Finding Count\"));\n for (const [key, val] of Object.entries(result.scores)) {\n lines.push(row(key, val.score, val.maxScore, val.findingCount));\n }\n lines.push(\"\");\n\n const ds = result.driftScores ?? {};\n if (Object.keys(ds).length > 0) {\n lines.push(\"DRIFT SCORES\");\n lines.push(row(\"Category\", \"Score\", \"Max Score\", \"Findings\", \"Grade\"));\n for (const [key, val] of Object.entries(ds)) {\n if (key === \"composite\" || key === \"grade\") continue;\n const v = val as any;\n if (v?.score !== undefined) {\n lines.push(row(key, v.score, v.maxScore, v.findings ?? 0));\n }\n }\n lines.push(\"\");\n }\n return lines;\n}\n\nfunction csvDriftFindings(result: ScanResult): string[] {\n if ((result.driftFindings ?? []).length === 0) return [];\n const lines: string[] = [];\n lines.push(\"DRIFT FINDINGS\");\n lines.push(row(\"Severity\", \"Category\", \"Finding\", \"Dominant Pattern\", \"Dominant Count\", \"Total Files\", \"Consistency %\", \"Deviating Files\", \"Recommendation\"));\n for (const d of result.driftFindings) {\n const devFiles = d.deviatingFiles.map((f) => f.path).join(\"; \");\n lines.push(row(\n d.severity, d.driftCategory, d.finding,\n d.dominantPattern, d.dominantCount, d.totalRelevantFiles, d.consistencyScore,\n devFiles, d.recommendation,\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvDuplicateGroups(dna: any): string[] {\n if (!dna.duplicateGroups?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: SEMANTIC DUPLICATES\");\n lines.push(row(\"Group\", \"Functions\", \"Files\"));\n for (const g of dna.duplicateGroups) {\n const fns = g.functions.map((f: any) => f.name + \"()\").join(\"; \");\n const files = g.functions.map((f: any) => f.relativePath || f.file).join(\"; \");\n lines.push(row(g.groupId, fns, files));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvSequenceSimilarities(dna: any): string[] {\n if (!dna.sequenceSimilarities?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: OPERATION SEQUENCE MATCHES\");\n lines.push(row(\"Function A\", \"File A\", \"Function B\", \"File B\", \"Similarity %\"));\n for (const s of dna.sequenceSimilarities) {\n lines.push(row(\n s.functionA.name, s.functionA.relativePath || s.functionA.file,\n s.functionB.name, s.functionB.relativePath || s.functionB.file,\n Math.round(s.similarity * 100),\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvTaintFlows(dna: any): string[] {\n if (!dna.taintFlows?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: TAINT FLOWS\");\n lines.push(row(\"File\", \"Function\", \"Source Type\", \"Source Line\", \"Sink Type\", \"Sink Line\", \"Sanitized\"));\n for (const t of dna.taintFlows) {\n lines.push(row(\n t.relativePath || t.file, t.functionName,\n t.source.type, t.source.line, t.sink.type, t.sink.line,\n t.sanitized ? \"Yes\" : \"No\",\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvDeviations(dna: any): string[] {\n if (!dna.deviationJustifications?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: DEVIATION ANALYSIS\");\n lines.push(row(\"File\", \"Deviating Pattern\", \"Dominant Pattern\", \"Verdict\", \"Score\"));\n for (const dj of dna.deviationJustifications) {\n lines.push(row(\n dj.relativePath || dj.file, dj.deviatingPattern, dj.dominantPattern,\n dj.verdict, Math.round(dj.justificationScore * 100),\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvPatterns(dna: any): string[] {\n if (!dna.patternDistributions?.length) return [];\n const lines: string[] = [];\n lines.push(\"CODE DNA: PATTERN DISTRIBUTIONS\");\n lines.push(row(\"File\", \"Dominant Pattern\", \"Confidence\", \"Internally Inconsistent\"));\n for (const pd of dna.patternDistributions) {\n lines.push(row(\n pd.relativePath || pd.file, pd.dominantPattern,\n Math.round(pd.confidence * 100), pd.isInternallyInconsistent ? \"Yes\" : \"No\",\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvCodeDna(result: ScanResult): string[] {\n const dna = result.codeDnaResult;\n if (!dna) return [];\n return [\n ...csvDuplicateGroups(dna),\n ...csvSequenceSimilarities(dna),\n ...csvTaintFlows(dna),\n ...csvDeviations(dna),\n ...csvPatterns(dna),\n ];\n}\n\nfunction csvFindings(result: ScanResult): string[] {\n const lines: string[] = [];\n lines.push(\"ALL FINDINGS\");\n lines.push(row(\"Severity\", \"Analyzer\", \"Confidence %\", \"Message\", \"File\", \"Line\", \"Tags\"));\n for (const f of result.findings) {\n const loc = f.locations[0];\n lines.push(row(\n f.severity, f.analyzerId, Math.round(f.confidence * 100),\n f.message, loc?.file ?? \"\", loc?.line ?? \"\",\n (f.tags ?? []).join(\"; \"),\n ));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvPerFileScores(result: ScanResult): string[] {\n const lines: string[] = [];\n lines.push(\"PER-FILE SCORES\");\n lines.push(row(\"File\", \"Score\", \"Finding Count\"));\n const fileSorted = [...result.perFileScores.entries()].sort((a, b) => a[1].score - b[1].score);\n for (const [path, data] of fileSorted) {\n lines.push(row(path, data.score, data.findings.length));\n }\n lines.push(\"\");\n return lines;\n}\n\nfunction csvAiSummary(result: ScanResult): string[] {\n if ((result.deepInsights ?? []).length === 0) return [];\n const lines: string[] = [];\n lines.push(\"DEEP ANALYSIS INSIGHTS\");\n lines.push(row(\"Category\", \"Severity\", \"Title\", \"Description\", \"Related Files\", \"Recommendation\"));\n for (const ins of result.deepInsights) {\n lines.push(row(\n ins.category, ins.severity, ins.title, ins.description,\n ins.relatedFiles.join(\"; \"), ins.recommendation ?? \"\",\n ));\n }\n return lines;\n}\n\nexport function renderCsvReport(result: ScanResult): string {\n return [\n ...csvMetadata(result),\n ...csvScoreCategories(result),\n ...csvDriftFindings(result),\n ...csvCodeDna(result),\n ...csvFindings(result),\n ...csvPerFileScores(result),\n ...csvAiSummary(result),\n ].join(\"\\n\");\n}\n","import { deflateRawSync } from \"zlib\";\nimport type { ScanResult } from \"../core/types.js\";\nimport { getVersion } from \"../core/version.js\";\n\n// ──── Minimal ZIP generator (OOXML requires ZIP container) ────\n\ninterface ZipEntry {\n name: string;\n data: Buffer;\n}\n\nfunction buildZip(entries: ZipEntry[]): Buffer {\n const centralDir: Buffer[] = [];\n const localFiles: Buffer[] = [];\n let offset = 0;\n\n for (const entry of entries) {\n const compressed = deflateRawSync(entry.data);\n const nameBytes = Buffer.from(entry.name, \"utf-8\");\n const crc = crc32(entry.data);\n\n // Local file header\n const local = Buffer.alloc(30 + nameBytes.length);\n local.writeUInt32LE(0x04034b50, 0); // signature\n local.writeUInt16LE(20, 4); // version needed\n local.writeUInt16LE(0, 6); // flags\n local.writeUInt16LE(8, 8); // compression: deflate\n local.writeUInt16LE(0, 10); // mod time\n local.writeUInt16LE(0, 12); // mod date\n local.writeUInt32LE(crc, 14); // crc32\n local.writeUInt32LE(compressed.length, 18); // compressed size\n local.writeUInt32LE(entry.data.length, 22); // uncompressed size\n local.writeUInt16LE(nameBytes.length, 26); // name length\n local.writeUInt16LE(0, 28); // extra length\n nameBytes.copy(local, 30);\n\n localFiles.push(local);\n localFiles.push(compressed);\n\n // Central directory header\n const central = Buffer.alloc(46 + nameBytes.length);\n central.writeUInt32LE(0x02014b50, 0); // signature\n central.writeUInt16LE(20, 4); // version made by\n central.writeUInt16LE(20, 6); // version needed\n central.writeUInt16LE(0, 8); // flags\n central.writeUInt16LE(8, 10); // compression\n central.writeUInt16LE(0, 12); // mod time\n central.writeUInt16LE(0, 14); // mod date\n central.writeUInt32LE(crc, 16); // crc32\n central.writeUInt32LE(compressed.length, 20);\n central.writeUInt32LE(entry.data.length, 24);\n central.writeUInt16LE(nameBytes.length, 28);\n central.writeUInt16LE(0, 30); // extra length\n central.writeUInt16LE(0, 32); // comment length\n central.writeUInt16LE(0, 34); // disk number\n central.writeUInt16LE(0, 36); // internal attrs\n central.writeUInt32LE(0, 38); // external attrs\n central.writeUInt32LE(offset, 42); // relative offset\n nameBytes.copy(central, 46);\n\n centralDir.push(central);\n offset += local.length + compressed.length;\n }\n\n const centralDirBuf = Buffer.concat(centralDir);\n const centralDirOffset = offset;\n\n // End of central directory\n const eocd = Buffer.alloc(22);\n eocd.writeUInt32LE(0x06054b50, 0); // signature\n eocd.writeUInt16LE(0, 4); // disk number\n eocd.writeUInt16LE(0, 6); // disk of central dir\n eocd.writeUInt16LE(entries.length, 8); // entries on disk\n eocd.writeUInt16LE(entries.length, 10); // total entries\n eocd.writeUInt32LE(centralDirBuf.length, 12); // central dir size\n eocd.writeUInt32LE(centralDirOffset, 16); // central dir offset\n eocd.writeUInt16LE(0, 20); // comment length\n\n return Buffer.concat([...localFiles, centralDirBuf, eocd]);\n}\n\nfunction crc32(buf: Buffer): number {\n let crc = 0xFFFFFFFF;\n for (let i = 0; i < buf.length; i++) {\n crc ^= buf[i];\n for (let j = 0; j < 8; j++) {\n crc = (crc >>> 1) ^ ((crc & 1) ? 0xEDB88320 : 0);\n }\n }\n return (crc ^ 0xFFFFFFFF) >>> 0;\n}\n\n// ──── OOXML Document Parts ────\n\nfunction contentTypes(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>\n <Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>\n</Types>`;\n}\n\nfunction rootRels(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/>\n</Relationships>`;\n}\n\nfunction docRels(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>`;\n}\n\nfunction styles(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:styles xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:style w:type=\"paragraph\" w:styleId=\"Title\"><w:name w:val=\"Title\"/><w:pPr><w:spacing w:after=\"200\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"52\"/><w:color w:val=\"00D4FF\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading1\"><w:name w:val=\"heading 1\"/><w:pPr><w:spacing w:before=\"400\" w:after=\"200\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"32\"/><w:color w:val=\"E2E8F0\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Heading2\"><w:name w:val=\"heading 2\"/><w:pPr><w:spacing w:before=\"300\" w:after=\"100\"/></w:pPr><w:rPr><w:b/><w:sz w:val=\"26\"/><w:color w:val=\"8B9DB8\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/><w:rPr><w:sz w:val=\"22\"/><w:rFonts w:ascii=\"Calibri\" w:hAnsi=\"Calibri\"/></w:rPr></w:style>\n <w:style w:type=\"paragraph\" w:styleId=\"Code\"><w:name w:val=\"Code\"/><w:pPr><w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"F5F5F5\"/><w:spacing w:before=\"60\" w:after=\"60\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Consolas\" w:hAnsi=\"Consolas\"/><w:sz w:val=\"18\"/></w:rPr></w:style>\n</w:styles>`;\n}\n\n// ──── XML Helpers ────\n\nconst W = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\";\n\nfunction xml(s: string): string {\n return s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nfunction para(text: string, style?: string, props?: string): string {\n const pPr = style ? `<w:pPr><w:pStyle w:val=\"${style}\"/>${props ?? \"\"}</w:pPr>` : (props ? `<w:pPr>${props}</w:pPr>` : \"\");\n return `<w:p>${pPr}<w:r><w:t xml:space=\"preserve\">${xml(text)}</w:t></w:r></w:p>`;\n}\n\nfunction boldPara(text: string, color?: string): string {\n const rPr = `<w:rPr><w:b/>${color ? `<w:color w:val=\"${color}\"/>` : \"\"}</w:rPr>`;\n return `<w:p><w:r>${rPr}<w:t xml:space=\"preserve\">${xml(text)}</w:t></w:r></w:p>`;\n}\n\nfunction colorRun(text: string, color: string, bold?: boolean): string {\n const rPr = `<w:rPr>${bold ? \"<w:b/>\" : \"\"}<w:color w:val=\"${color}\"/></w:rPr>`;\n return `<w:r>${rPr}<w:t xml:space=\"preserve\">${xml(text)}</w:t></w:r>`;\n}\n\nfunction multiRunPara(runs: string[]): string {\n return `<w:p>${runs.join(\"\")}</w:p>`;\n}\n\nfunction tableCellSimple(text: string, shade?: string, bold?: boolean): string {\n const shd = shade ? `<w:tcPr><w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"${shade}\"/></w:tcPr>` : \"\";\n const rPr = bold ? \"<w:rPr><w:b/></w:rPr>\" : \"\";\n return `<w:tc>${shd}<w:p><w:r>${rPr}<w:t xml:space=\"preserve\">${xml(text)}</w:t></w:r></w:p></w:tc>`;\n}\n\nfunction tableRow(cells: string[]): string {\n return `<w:tr>${cells.join(\"\")}</w:tr>`;\n}\n\nfunction hr(): string {\n return `<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"1\" w:color=\"CCCCCC\"/></w:pBdr></w:pPr></w:p>`;\n}\n\n// ──── Document Body Builder (helpers) ────\n\nconst TABLE_BORDERS = `<w:tblBorders><w:top w:val=\"single\" w:sz=\"4\" w:color=\"CCCCCC\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:color=\"CCCCCC\"/><w:insideH w:val=\"single\" w:sz=\"4\" w:color=\"E0E0E0\"/><w:insideV w:val=\"single\" w:sz=\"4\" w:color=\"E0E0E0\"/></w:tblBorders>`;\n\nfunction wrapTable(rows: string): string {\n return `<w:tbl><w:tblPr>${TABLE_BORDERS}<w:tblW w:w=\"5000\" w:type=\"pct\"/></w:tblPr>${rows}</w:tbl>`;\n}\n\nfunction buildDocxTitlePage(result: ScanResult): string {\n const parts: string[] = [];\n const name = result.context.rootDir.split(\"/\").pop() ?? \"project\";\n const date = new Date().toLocaleDateString(\"en-US\", { month: \"long\", day: \"numeric\", year: \"numeric\" });\n\n parts.push(para(\"VIBEDRIFT REPORT\", \"Title\"));\n parts.push(para(`${name}`, \"Heading1\"));\n parts.push(para(`Generated: ${date} | Files: ${result.context.files.length} | Lines: ${result.context.totalLines.toLocaleString()} | Scan: ${(result.scanTimeMs / 1000).toFixed(1)}s`));\n const langs = [...result.context.languageBreakdown.entries()].map(([l, s]) => `${l}: ${s.files} files`).join(\", \");\n parts.push(para(`Languages: ${langs}`));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxScoreTable(result: ScanResult): string {\n const parts: string[] = [];\n const pct = result.maxCompositeScore > 0 ? (result.compositeScore / result.maxCompositeScore) * 100 : 0;\n const grade = pct >= 90 ? \"A\" : pct >= 75 ? \"B\" : pct >= 50 ? \"C\" : pct >= 25 ? \"D\" : \"F\";\n\n parts.push(para(\"1. SCORE SUMMARY\", \"Heading1\"));\n parts.push(boldPara(`Composite Score: ${result.compositeScore} / ${result.maxCompositeScore} (Grade ${grade})`));\n parts.push(para(\"\"));\n\n const ds = result.driftScores ?? {};\n const catRows = [\n [\"Architectural Consistency\", ds.architectural_consistency],\n [\"Security Posture\", ds.security_posture],\n [\"Semantic Duplication\", ds.semantic_duplication],\n [\"Convention Drift\", ds.naming_conventions],\n [\"Phantom Scaffolding\", ds.phantom_scaffolding],\n ];\n\n const headerRow = tableRow([\n tableCellSimple(\"Category\", \"D9E2F3\", true),\n tableCellSimple(\"Score\", \"D9E2F3\", true),\n tableCellSimple(\"Max\", \"D9E2F3\", true),\n tableCellSimple(\"Findings\", \"D9E2F3\", true),\n ]);\n const dataRows = catRows.map(([catName, catScore]) => {\n const cs = catScore as any;\n return tableRow([\n tableCellSimple(catName as string),\n tableCellSimple(String(cs?.score ?? 0)),\n tableCellSimple(String(cs?.maxScore ?? 0)),\n tableCellSimple(String(cs?.findings ?? 0)),\n ]);\n }).join(\"\");\n\n parts.push(wrapTable(headerRow + dataRows));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxIntentSection(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"2. CODEBASE INTENT\", \"Heading1\"));\n parts.push(para(\"The following patterns represent the dominant approach established by the majority of files in this codebase.\"));\n parts.push(para(\"\"));\n\n const intentSeen = new Set<string>();\n for (const d of (result.driftFindings ?? [])) {\n const key = d.driftCategory + \"::\" + d.dominantPattern;\n if (intentSeen.has(key)) continue;\n intentSeen.add(key);\n parts.push(boldPara(`${d.driftCategory.replace(/_/g, \" \").toUpperCase()}: ${d.dominantPattern}`));\n parts.push(para(` ${d.dominantCount} of ${d.totalRelevantFiles} files follow this pattern (${d.consistencyScore}% consistency)`));\n }\n if (intentSeen.size === 0) parts.push(para(\"No dominant patterns detected — codebase may be too small or highly consistent.\"));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxDriftSection(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"3. DRIFT FINDINGS\", \"Heading1\"));\n parts.push(para(`${(result.driftFindings ?? []).length} cross-file contradictions detected.`));\n parts.push(para(\"\"));\n\n for (const d of (result.driftFindings ?? [])) {\n const sevStr = d.severity === \"error\" ? \"CRITICAL\" : d.severity === \"warning\" ? \"WARNING\" : \"INFO\";\n parts.push(para(`[${sevStr}] ${d.finding}`, \"Heading2\"));\n parts.push(para(`Category: ${d.driftCategory.replace(/_/g, \" \")} | Consistency: ${d.consistencyScore}% | Confidence: ${Math.round(d.confidence * 100)}%`));\n parts.push(para(\"\"));\n\n parts.push(boldPara(\"INTENT (DOMINANT PATTERN)\", \"10B981\"));\n parts.push(para(`Pattern: ${d.dominantPattern} — used by ${d.dominantCount} of ${d.totalRelevantFiles} files`));\n parts.push(para(\"\"));\n\n parts.push(boldPara(\"DEVIATING FILES\", \"F97316\"));\n for (const df of d.deviatingFiles) {\n parts.push(para(` File: ${df.path}`));\n parts.push(para(` Pattern: ${df.detectedPattern}`));\n for (const ev of df.evidence.slice(0, 3)) {\n parts.push(para(` Line ${ev.line}: ${ev.code.slice(0, 100)}`, \"Code\"));\n }\n parts.push(para(\"\"));\n }\n\n parts.push(boldPara(\"Pattern Distribution:\"));\n parts.push(para(` ${d.dominantPattern}: ${d.dominantCount} files (${Math.round((d.dominantCount / d.totalRelevantFiles) * 100)}%)`));\n parts.push(para(` Deviating: ${d.totalRelevantFiles - d.dominantCount} files (${Math.round(((d.totalRelevantFiles - d.dominantCount) / d.totalRelevantFiles) * 100)}%)`));\n parts.push(para(\"\"));\n\n if (d.recommendation) {\n parts.push(boldPara(\"RECOMMENDATION:\", \"00D4FF\"));\n parts.push(para(` ${d.recommendation}`));\n }\n parts.push(hr());\n }\n return parts.join(\"\\n \");\n}\n\nfunction docxDnaDuplicates(dna: any): string[] {\n if (!dna.duplicateGroups?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Semantic Fingerprint Duplicates\", \"Heading2\"));\n for (const g of dna.duplicateGroups) {\n const fns = g.functions.map((f: any) => `${f.name}() in ${f.relativePath || f.file}`).join(\", \");\n parts.push(para(` Group: ${fns}`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction docxDnaSequences(dna: any): string[] {\n if (!dna.sequenceSimilarities?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Operation Sequence Matches\", \"Heading2\"));\n for (const s of dna.sequenceSimilarities) {\n parts.push(para(` ${Math.round(s.similarity * 100)}% match: ${s.functionA.name}() in ${s.functionA.relativePath || s.functionA.file} ↔ ${s.functionB.name}() in ${s.functionB.relativePath || s.functionB.file}`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction docxDnaTaintFlows(dna: any): string[] {\n if (!dna.taintFlows?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Taint Flows\", \"Heading2\"));\n for (const t of dna.taintFlows) {\n parts.push(para(` [${t.sink.severity.toUpperCase()}] ${t.functionName}() in ${t.relativePath || t.file}: ${t.source.type} (line ${t.source.line}) → ${t.sink.type} (line ${t.sink.line}) — ${t.sanitized ? \"SANITIZED\" : \"UNSANITIZED\"}`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction docxDnaDeviations(dna: any): string[] {\n if (!dna.deviationJustifications?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Deviation Justification Analysis\", \"Heading2\"));\n for (const dj of dna.deviationJustifications) {\n const verdict = dj.verdict === \"likely_justified\" ? \"JUSTIFIED\" : dj.verdict === \"likely_accidental\" ? \"ACCIDENTAL\" : \"UNCERTAIN\";\n parts.push(para(` [${verdict}] ${dj.relativePath || dj.file}: uses ${dj.deviatingPattern} vs project ${dj.dominantPattern} (score: ${Math.round(dj.justificationScore * 100)}%)`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction docxDnaPatterns(dna: any): string[] {\n if (!dna.patternDistributions?.length) return [];\n const parts: string[] = [];\n parts.push(para(\"Pattern Classification\", \"Heading2\"));\n for (const pd of dna.patternDistributions) {\n const mixed = pd.isInternallyInconsistent ? \" [MIXED]\" : \"\";\n parts.push(para(` ${pd.relativePath || pd.file}: ${pd.dominantPattern} (${Math.round(pd.confidence * 100)}% confidence)${mixed}`));\n }\n parts.push(para(\"\"));\n return parts;\n}\n\nfunction buildDocxCodeDnaSection(result: ScanResult): string {\n const dna = result.codeDnaResult;\n if (!dna) return \"\";\n\n const parts: string[] = [];\n parts.push(para(\"4. CODE DNA ANALYSIS\", \"Heading1\"));\n parts.push(para(`${dna.functions?.length ?? 0} functions analyzed in ${dna.timings?.totalMs ?? 0}ms. ${dna.findings?.length ?? 0} findings.`));\n parts.push(para(\"\"));\n\n parts.push(\n ...docxDnaDuplicates(dna),\n ...docxDnaSequences(dna),\n ...docxDnaTaintFlows(dna),\n ...docxDnaDeviations(dna),\n ...docxDnaPatterns(dna),\n );\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxPerFileTable(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"5. FILE RANKING\", \"Heading1\"));\n const fileSorted = [...result.perFileScores.entries()].sort((a, b) => a[1].score - b[1].score);\n parts.push(para(`${fileSorted.length} files scanned. Ranked worst to best.`));\n parts.push(para(\"\"));\n\n const fileHeaderRow = tableRow([\n tableCellSimple(\"File\", \"D9E2F3\", true),\n tableCellSimple(\"Score\", \"D9E2F3\", true),\n tableCellSimple(\"Drift\", \"D9E2F3\", true),\n tableCellSimple(\"Static\", \"D9E2F3\", true),\n ]);\n const fileDataRows = fileSorted.slice(0, 40).map(([path, data]) => {\n const driftCount = data.findings.filter((f) => f.tags?.includes(\"drift\") || f.tags?.includes(\"codedna\")).length;\n const staticCount = data.findings.length - driftCount;\n return tableRow([\n tableCellSimple(path),\n tableCellSimple(`${data.score}/100`),\n tableCellSimple(String(driftCount)),\n tableCellSimple(String(staticCount)),\n ]);\n }).join(\"\");\n\n parts.push(wrapTable(fileHeaderRow + fileDataRows));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxFindingsTable(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"6. STATIC ANALYSIS FINDINGS\", \"Heading1\"));\n const statics = result.findings.filter((f) => !f.tags?.includes(\"drift\") && !f.tags?.includes(\"codedna\"));\n parts.push(para(`${statics.length} findings from ${13} static analyzers.`));\n parts.push(para(\"\"));\n\n for (const f of statics.slice(0, 50)) {\n const loc = f.locations[0];\n const sevStr = f.severity === \"error\" ? \"ERROR\" : f.severity === \"warning\" ? \"WARNING\" : \"INFO\";\n parts.push(para(`[${sevStr}] [${f.analyzerId}] ${f.message}`));\n if (loc) parts.push(para(` File: ${loc.file}${loc.line ? `:${loc.line}` : \"\"} | Confidence: ${Math.round(f.confidence * 100)}%`));\n }\n if (statics.length > 50) parts.push(para(`... and ${statics.length - 50} more findings.`));\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxDeepInsights(result: ScanResult): string {\n if ((result.deepInsights ?? []).length === 0) return \"\";\n\n const parts: string[] = [];\n parts.push(para(\"7. DEEP ANALYSIS INSIGHTS (AI-POWERED)\", \"Heading1\"));\n for (const ins of result.deepInsights) {\n const sevStr = ins.severity === \"error\" ? \"CRITICAL\" : ins.severity === \"warning\" ? \"WARNING\" : \"INFO\";\n parts.push(para(`[${sevStr}] ${ins.title}`, \"Heading2\"));\n parts.push(para(ins.description));\n if (ins.relatedFiles.length > 0) parts.push(para(` Files: ${ins.relatedFiles.join(\", \")}`));\n if (ins.recommendation) {\n parts.push(boldPara(\"Recommendation:\", \"00D4FF\"));\n parts.push(para(` ${ins.recommendation}`));\n }\n parts.push(para(\"\"));\n }\n parts.push(hr());\n return parts.join(\"\\n \");\n}\n\nfunction buildDocxFooter(result: ScanResult): string {\n const parts: string[] = [];\n parts.push(para(\"\"));\n parts.push(para(`Generated by VibeDrift v${getVersion()} | ${result.context.files.length} files | ${result.context.totalLines.toLocaleString()} lines | ${(result.scanTimeMs / 1000).toFixed(1)}s | No data sent externally`));\n parts.push(para(\"Re-scan: npx vibedrift .\"));\n return parts.join(\"\\n \");\n}\n\n// ──── Document Body Builder ────\n\nfunction buildDocumentXml(result: ScanResult): string {\n const sections = [\n buildDocxTitlePage(result),\n buildDocxScoreTable(result),\n buildDocxIntentSection(result),\n buildDocxDriftSection(result),\n buildDocxCodeDnaSection(result),\n buildDocxPerFileTable(result),\n buildDocxFindingsTable(result),\n buildDocxDeepInsights(result),\n buildDocxFooter(result),\n ].filter(Boolean);\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:document xmlns:w=\"${W}\">\n <w:body>\n ${sections.join(\"\\n \")}\n <w:sectPr>\n <w:pgSz w:w=\"12240\" w:h=\"15840\"/>\n <w:pgMar w:top=\"1440\" w:right=\"1440\" w:bottom=\"1440\" w:left=\"1440\"/>\n </w:sectPr>\n </w:body>\n</w:document>`;\n}\n\n// ──── Public API ────\n\nexport function renderDocxReport(result: ScanResult): Buffer {\n const entries: ZipEntry[] = [\n { name: \"[Content_Types].xml\", data: Buffer.from(contentTypes(), \"utf-8\") },\n { name: \"_rels/.rels\", data: Buffer.from(rootRels(), \"utf-8\") },\n { name: \"word/_rels/document.xml.rels\", data: Buffer.from(docRels(), \"utf-8\") },\n { name: \"word/styles.xml\", data: Buffer.from(styles(), \"utf-8\") },\n { name: \"word/document.xml\", data: Buffer.from(buildDocumentXml(result), \"utf-8\") },\n ];\n return buildZip(entries);\n}\n","/**\n * CLI entry point — wires Commander.js commands to their handlers.\n *\n * \"scan\" is the default command (runs when no subcommand is given). Account\n * commands (login, logout, status, usage, upgrade, billing) manage auth and\n * Stripe integration. Maintenance commands (update, doctor, feedback) handle\n * self-update, diagnostics, and user feedback.\n */\n\nimport { Command, Option } from \"commander\";\nimport { runScan } from \"./commands/scan.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { runLogin } from \"./commands/login.js\";\nimport { runLogout } from \"./commands/logout.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { runUsage } from \"./commands/usage.js\";\nimport { runUpgrade } from \"./commands/upgrade.js\";\nimport { runBilling } from \"./commands/billing.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { runFeedback } from \"./commands/feedback.js\";\nimport { getVersion } from \"../core/version.js\";\n\nconst VERSION = getVersion();\n\nfunction parseScoreThreshold(value: string): number {\n const n = parseFloat(value);\n if (Number.isNaN(n) || n < 0 || n > 100) {\n console.error(\n `Error: --fail-on-score must be a number between 0 and 100, got \"${value}\"`,\n );\n process.exit(1);\n }\n return n;\n}\n\nfunction collect(value: string, previous: string[]): string[] {\n return previous.concat([value]);\n}\n\nconst program = new Command();\n\nprogram\n .name(\"vibedrift\")\n .description(\n \"Detect drift, contradictions, and security gaps in AI-generated codebases.\",\n )\n .version(VERSION, \"-V, --version\", \"show the installed version\")\n .helpOption(\"-h, --help\", \"show this help\");\n\n// ──── Default subcommand: scan ────\nprogram\n .command(\"scan\", { isDefault: true })\n .description(\"Scan a project for vibe drift (default command)\")\n .argument(\"[path]\", \"path to project directory\", \".\")\n // Output\n .option(\n \"--format <type>\",\n \"output format: html, terminal, json, csv, docx\",\n \"html\",\n )\n .option(\"--output <path>\", \"write report to a file\")\n .option(\"--json\", \"shorthand for --format json\")\n .option(\n \"--fail-on-score <n>\",\n \"exit with code 1 if composite score is below this threshold\",\n parseScoreThreshold,\n )\n // Analysis toggles\n .option(\"--no-codedna\", \"skip Code DNA semantic analysis\")\n .option(\n \"--deep\",\n \"enable AI-powered deep analysis (requires `vibedrift login`)\",\n )\n .option(\n \"--project-name <name>\",\n \"override the auto-detected project name shown in the dashboard\",\n )\n // File filtering\n .option(\n \"--include <pattern>\",\n \"only scan files matching this glob (repeatable)\",\n collect,\n [],\n )\n .option(\n \"--exclude <pattern>\",\n \"exclude files matching this glob (repeatable)\",\n collect,\n [],\n )\n // Maintenance\n .option(\n \"--update\",\n \"update the VibeDrift CLI to the latest version (alias for `vibedrift update`)\",\n )\n .option(\n \"--feedback [message...]\",\n \"send feedback to the maintainer (alias for `vibedrift feedback`)\",\n )\n .option(\"--verbose\", \"show timing breakdown and analyzer details\")\n // Hidden / advanced\n .addOption(\n new Option(\"--api-url <url>\", \"override the VibeDrift API base URL\")\n .hideHelp(),\n )\n .action(async (path: string, options) => {\n if (options.update) {\n await runUpdate(VERSION);\n return;\n }\n if (options.feedback) {\n // --feedback can be a bare flag (`true`) or carry inline words\n // (`[\"the\", \"install\", \"is\", \"broken\"]`); normalize both into a string\n const inline = Array.isArray(options.feedback)\n ? options.feedback.join(\" \").trim()\n : \"\";\n await runFeedback({\n message: inline || undefined,\n apiUrl: options.apiUrl,\n });\n return;\n }\n\n await runScan(path, {\n json: options.json,\n format: options.json ? \"json\" : options.format,\n output: options.output,\n failOnScore: options.failOnScore,\n codedna: options.codedna,\n deep: options.deep,\n apiUrl: options.apiUrl,\n include: options.include,\n exclude: options.exclude,\n verbose: options.verbose,\n projectName: options.projectName,\n });\n });\n\n// ──── Account / auth subcommands ────\nprogram\n .command(\"login\")\n .description(\"Log in to your VibeDrift account\")\n .option(\"--no-browser\", \"don't open the browser automatically\")\n .addOption(\n new Option(\"--api-url <url>\", \"override the API base URL\")\n .hideHelp(),\n )\n .action(async (options) => {\n await runLogin({\n apiUrl: options.apiUrl,\n noBrowser: options.browser === false,\n });\n });\n\nprogram\n .command(\"logout\")\n .description(\"Log out and revoke the current token\")\n .action(async () => {\n await runLogout();\n });\n\nprogram\n .command(\"status\")\n .description(\"Show the current account, plan, and token\")\n .action(async () => {\n await runStatus();\n });\n\nprogram\n .command(\"usage\")\n .description(\"Show your current billing period's scan usage\")\n .action(async () => {\n await runUsage();\n });\n\nprogram\n .command(\"upgrade\")\n .description(\"Open the VibeDrift pricing page\")\n .action(async () => {\n await runUpgrade();\n });\n\nprogram\n .command(\"billing\")\n .description(\"Open the Stripe Customer Portal to manage your subscription\")\n .action(async () => {\n await runBilling();\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Diagnose CLI installation, auth, and API connectivity\")\n .action(async () => {\n await runDoctor();\n });\n\nprogram\n .command(\"update\")\n .description(\"Update the VibeDrift CLI to the latest version\")\n .action(async () => {\n await runUpdate(VERSION);\n });\n\nprogram\n .command(\"feedback\")\n .description(\"Send feedback, bug reports, or feature requests directly to the maintainer\")\n .argument(\n \"[message...]\",\n \"feedback text (omit to be prompted interactively)\",\n )\n .addOption(\n new Option(\"--api-url <url>\", \"override the API base URL\").hideHelp(),\n )\n .action(async (messageWords: string[], options) => {\n const message = (messageWords ?? []).join(\" \").trim() || undefined;\n await runFeedback({ message, apiUrl: options.apiUrl });\n });\n\nprogram.addHelpText(\n \"after\",\n `\nExamples:\n $ vibedrift scan the current directory\n $ vibedrift ./my-project scan a specific project\n $ vibedrift --format terminal print results to the terminal\n $ vibedrift --json > report.json pipe JSON output to a file\n $ vibedrift --fail-on-score 70 fail CI if score drops below 70\n $ vibedrift --include \"src/**\" only scan files under src/\n $ vibedrift --exclude \"**/*.spec.*\" skip test files\n $ vibedrift --deep run premium AI-powered deep analysis\n $ vibedrift login sign in to enable --deep\n $ vibedrift status check current auth state\n $ vibedrift usage view this month's scan usage\n $ vibedrift upgrade open the pricing page\n $ vibedrift billing manage your Stripe subscription\n $ vibedrift update update to the latest CLI version\n $ vibedrift feedback open an interactive feedback prompt\n $ vibedrift feedback \"the install is broken on Windows\"\n send inline feedback in one shot\n $ vibedrift --feedback \"...\" same as above, top-level shortcut\n\nEnvironment:\n VIBEDRIFT_TOKEN bearer token (overrides ~/.vibedrift/config.json)\n VIBEDRIFT_API_URL override the API base URL\n VIBEDRIFT_NO_BROWSER if \"1\", never auto-open the browser\n\nLearn more: https://vibedrift.ai`,\n);\n\n// Top-level catch ensures unhandled rejections from any command\n// produce a clean error message instead of a stack trace\nprogram.parseAsync().catch((err) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","import { resolve } from \"path\";\nimport { writeFile } from \"fs/promises\";\nimport { stat } from \"fs/promises\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { buildAnalysisContext } from \"../../core/discovery.js\";\nimport { parseFiles } from \"../../utils/ast.js\";\nimport { createAnalyzerRegistry } from \"../../analyzers/index.js\";\nimport { runDriftDetection } from \"../../drift/index.js\";\nimport { computeScores } from \"../../scoring/engine.js\";\nimport { generateTeaseMessages } from \"../../output/tease.js\";\nimport { renderTerminalOutput, renderJsonOutput } from \"../../output/terminal.js\";\nimport { renderHtmlReport } from \"../../output/html.js\";\nimport { saveScanResult, loadPreviousScores } from \"../../core/history.js\";\nimport { applyIncludeExclude } from \"../../core/file-filter.js\";\nimport { resolveToken, resolveApiUrl } from \"../../auth/resolver.js\";\nimport { fetchCredits } from \"../../auth/api.js\";\nimport type { Finding, ScanResult, ScanOptions, SourceFile } from \"../../core/types.js\";\n\n// ────────────────────────────────────────────────────────────────────\n// 1. resolveAuthAndBanner\n// ────────────────────────────────────────────────────────────────────\nasync function resolveAuthAndBanner(\n options: ScanOptions,\n): Promise<{ bearerToken: string | null; apiUrl: string | undefined }> {\n // ──── Resolve token *before* the scan starts ────\n // Required for --deep (the API call would 401 anyway), but ALSO attempted\n // for free scans so we can log them to the user's dashboard. Free scans\n // without a token still work — they just don't appear in the dashboard.\n let bearerToken: string | null = null;\n let apiUrl: string | undefined = options.apiUrl;\n if (options.deep) {\n const resolved = await resolveToken();\n if (!resolved) {\n console.error(\"\");\n console.error(chalk.red(\" ✗ Deep scans require a VibeDrift account.\"));\n console.error(\"\");\n console.error(chalk.bgYellow.black.bold(\" 🎁 Free accounts get 3 deep scans per month. \"));\n console.error(\"\");\n console.error(\" Run \" + chalk.bold(\"vibedrift login\") + \" to sign in and claim it.\");\n console.error(\" Or set \" + chalk.bold(\"VIBEDRIFT_TOKEN\") + \" in your environment for CI.\");\n console.error(\"\");\n process.exit(1);\n }\n bearerToken = resolved.token;\n apiUrl = await resolveApiUrl(options.apiUrl);\n } else {\n // Free scan: best-effort token resolution. If the user is logged in\n // we log the scan to their dashboard; if not, the local scan still\n // runs to completion.\n try {\n const resolved = await resolveToken();\n if (resolved) {\n bearerToken = resolved.token;\n apiUrl = await resolveApiUrl(options.apiUrl);\n }\n } catch {\n // ignore — free scans don't require auth\n }\n }\n\n // ──── Advertise the one-time welcome credit ────\n // Three cases:\n // 1. Logged in + has welcome credit unconsumed → \"🎁 1 free deep scan ready\"\n // 2. Logged in + already used / pro plan → no banner\n // 3. Not logged in → \"Sign up to get 1 free deep scan\"\n //\n // Visible for both `--format html` (default) and `--format terminal`,\n // suppressed for `--json` and explicit deep scans (the banner only\n // makes sense before a free scan, not during a deep one).\n if (!options.json && options.format !== \"json\" && !options.deep) {\n if (bearerToken) {\n try {\n const credits = await fetchCredits(bearerToken, { apiUrl });\n if (credits.has_free_deep_scan && !credits.unlimited) {\n console.log(\"\");\n console.log(chalk.bgYellow.black.bold(\" 🎁 3 FREE DEEP SCANS EVERY MONTH \"));\n console.log(chalk.yellow(\" Run with --deep to use AI-powered analysis (3 free per month).\"));\n console.log(\"\");\n }\n } catch {\n // Older API build or transient error — skip the banner.\n }\n } else {\n console.log(\"\");\n console.log(chalk.dim(\" Tip: \") + chalk.yellow(\"sign up free — 3 deep scans per month included\"));\n console.log(chalk.dim(\" Run \") + chalk.bold(\"vibedrift login\") + chalk.dim(\" to claim it (no card required).\"));\n console.log(\"\");\n }\n }\n\n return { bearerToken, apiUrl };\n}\n\n// ────────────────────────────────────────────────────────────────────\n// 2. runAnalysisPipeline\n// ────────────────────────────────────────────────────────────────────\nasync function discoverAndFilterFiles(\n rootDir: string,\n options: ScanOptions,\n spinner: ReturnType<typeof ora> | null,\n): Promise<{\n ctx: Awaited<ReturnType<typeof buildAnalysisContext>>[\"ctx\"];\n discoveryMs: number;\n}> {\n const isTerminal = options.format === \"terminal\" && !options.json;\n const t0 = Date.now();\n const { ctx, warnings } = await buildAnalysisContext(rootDir);\n\n // Apply --include / --exclude glob filters in-place on the context's files.\n const includes = options.include ?? [];\n const excludes = options.exclude ?? [];\n if (includes.length > 0 || excludes.length > 0) {\n const before = ctx.files.length;\n const filtered = applyIncludeExclude(ctx.files, includes, excludes);\n ctx.files = filtered;\n ctx.totalLines = filtered.reduce((sum: number, f: SourceFile) => sum + f.lineCount, 0);\n if (options.verbose) {\n console.error(chalk.dim(`[filter] ${before} → ${filtered.length} files after include/exclude`));\n }\n }\n\n const discoveryMs = Date.now() - t0;\n\n // Report discovery warnings\n if (isTerminal) {\n if (warnings.truncated) {\n console.warn(chalk.yellow(`\\nWarning: File limit reached (${warnings.truncatedAt}). Only partial coverage — results may be incomplete.`));\n }\n if (warnings.skippedDirs.length > 0) {\n console.warn(chalk.yellow(`Warning: ${warnings.skippedDirs.length} directories skipped (permission denied): ${warnings.skippedDirs.slice(0, 3).join(\", \")}${warnings.skippedDirs.length > 3 ? \"...\" : \"\"}`));\n }\n if (warnings.unreadableFiles.length > 0) {\n console.warn(chalk.yellow(`Warning: ${warnings.unreadableFiles.length} files unreadable: ${warnings.unreadableFiles.slice(0, 3).join(\", \")}${warnings.unreadableFiles.length > 3 ? \"...\" : \"\"}`));\n }\n }\n\n if (ctx.files.length === 0) {\n if (spinner) spinner.stop();\n console.log(\"No source files found to analyze.\");\n process.exit(0);\n }\n\n return { ctx, discoveryMs };\n}\n\nasync function runAnalysisPipeline(\n rootDir: string,\n options: ScanOptions,\n spinner: ReturnType<typeof ora> | null,\n): Promise<{\n ctx: Awaited<ReturnType<typeof buildAnalysisContext>>[\"ctx\"];\n allFindings: Finding[];\n driftResult: ReturnType<typeof runDriftDetection>;\n codeDnaResult: any;\n timings: Record<string, number>;\n}> {\n const isTerminal = options.format === \"terminal\" && !options.json;\n const timings: Record<string, number> = {};\n\n const { ctx, discoveryMs } = await discoverAndFilterFiles(rootDir, options, spinner);\n timings.discovery = discoveryMs;\n\n if (spinner) spinner.text = `Parsing ${ctx.files.length} files...`;\n\n // Parse ASTs\n const t1 = Date.now();\n await parseFiles(ctx.files);\n timings.parsing = Date.now() - t1;\n\n // Run analyzers\n const t2 = Date.now();\n const analyzers = createAnalyzerRegistry();\n if (spinner) spinner.text = `Running ${analyzers.length} analyzers...`;\n const allFindings: Finding[] = [];\n\n for (const analyzer of analyzers) {\n const findings = await analyzer.analyze(ctx);\n allFindings.push(...findings);\n }\n\n timings.analyzers = Date.now() - t2;\n\n // Run cross-file drift detection\n const t3 = Date.now();\n if (spinner) spinner.text = \"Detecting vibe drift...\";\n const driftResult = runDriftDetection(ctx);\n allFindings.push(...driftResult.findings);\n timings.drift = Date.now() - t3;\n\n // Run Code DNA analysis (Layer 1.7)\n let codeDnaResult: any = undefined;\n if (options.codedna !== false) {\n const t4 = Date.now();\n if (spinner) spinner.text = \"Running Code DNA analysis...\";\n const { runCodeDnaAnalysis } = await import(\"../../codedna/index.js\");\n codeDnaResult = runCodeDnaAnalysis(ctx);\n allFindings.push(...codeDnaResult.findings);\n timings.codedna = Date.now() - t4;\n if (isTerminal && options.verbose) {\n console.error(`[codedna] ${codeDnaResult.functions.length} functions analyzed in ${codeDnaResult.timings.totalMs}ms`);\n console.error(`[codedna] ${codeDnaResult.duplicateGroups.length} fingerprint duplicates, ${codeDnaResult.sequenceSimilarities.length} sequence matches, ${codeDnaResult.taintFlows.length} taint flows`);\n }\n }\n\n return { ctx, allFindings, driftResult, codeDnaResult, timings };\n}\n\n// ────────────────────────────────────────────────────────────────────\n// 3. runDeepAnalysis\n// ────────────────────────────────────────────────────────────────────\nasync function runDeepAnalysis(\n pipeline: {\n allFindings: Finding[];\n ctx: Awaited<ReturnType<typeof buildAnalysisContext>>[\"ctx\"];\n codeDnaResult: any;\n driftResult: ReturnType<typeof runDriftDetection>;\n },\n options: ScanOptions,\n bearerToken: string,\n apiUrl: string | undefined,\n spinner: ReturnType<typeof ora> | null,\n): Promise<{ timings: Record<string, number> }> {\n const { allFindings, ctx, codeDnaResult, driftResult } = pipeline;\n const timings: Record<string, number> = {};\n\n // Run AI deep analysis (Layer 2) — opt-in with --deep\n let mlMediumConfidence: any[] = [];\n const t5 = Date.now();\n if (spinner) spinner.text = \"Running AI deep analysis (may take ~30s on cold start)...\";\n try {\n const { runMlAnalysis } = await import(\"../../ml-client/index.js\");\n const mlResult = await runMlAnalysis(ctx, codeDnaResult, allFindings, {\n token: bearerToken,\n apiUrl,\n verbose: options.verbose,\n driftFindings: driftResult.driftFindings,\n projectName: options.projectName,\n });\n allFindings.push(...mlResult.highConfidence);\n mlMediumConfidence = mlResult.mediumConfidence;\n if (options.verbose) {\n console.error(`[deep] ${mlResult.highConfidence.length} high-confidence findings shipped, ${mlResult.mediumConfidence.length} sent to LLM, ${mlResult.droppedCount} dropped`);\n }\n } catch (err: any) {\n console.error(chalk.red(`[deep] AI analysis failed: ${err.message}`));\n console.error(chalk.dim(\" The local scan will continue. Run `vibedrift doctor` if this persists.\"));\n }\n timings.deep = Date.now() - t5;\n\n // Deduplicate findings across layers (AI > Code DNA > Static)\n const { deduplicateFindingsAcrossLayers } = await import(\"../../scoring/dedup.js\");\n const dedupedCount = allFindings.length;\n const dedupedFindings = deduplicateFindingsAcrossLayers(allFindings);\n if (options.verbose && dedupedFindings.length < dedupedCount) {\n console.error(`[dedup] Removed ${dedupedCount - dedupedFindings.length} cross-layer duplicate findings`);\n }\n // Replace allFindings with deduplicated version\n allFindings.length = 0;\n allFindings.push(...dedupedFindings);\n\n // suppress unused-var lint (mlMediumConfidence is reserved for future use)\n void mlMediumConfidence;\n\n return { timings };\n}\n\n// ────────────────────────────────────────────────────────────────────\n// 4. buildScanResult\n// ────────────────────────────────────────────────────────────────────\nasync function buildScanResult(\n pipeline: {\n ctx: Awaited<ReturnType<typeof buildAnalysisContext>>[\"ctx\"];\n allFindings: Finding[];\n driftResult: ReturnType<typeof runDriftDetection>;\n codeDnaResult: any;\n },\n options: ScanOptions,\n startTime: number,\n timings: Record<string, number>,\n bearerToken: string | null,\n apiUrl: string | undefined,\n spinner: ReturnType<typeof ora> | null,\n): Promise<ScanResult> {\n const { ctx, allFindings, driftResult, codeDnaResult } = pipeline;\n const rootDir = ctx.rootDir;\n\n // Load previous scores for delta\n const previousScores = await loadPreviousScores(rootDir);\n\n // Score\n if (spinner) spinner.text = \"Computing scores...\";\n const { scores, compositeScore, maxCompositeScore, perFileScores } = computeScores(\n allFindings,\n ctx.totalLines,\n ctx,\n previousScores ?? undefined,\n );\n\n // Deep insights are reserved for the premium AI tier (routed via VibeDrift API).\n // No direct Anthropic key path is exposed to end users.\n const deepInsights: ScanResult[\"deepInsights\"] = [];\n\n // Tease — show \"run --deep\" upsell only when user is *not* using deep mode.\n const teaseMessages = generateTeaseMessages(ctx, allFindings, options.deep === true);\n\n const scanTimeMs = Date.now() - startTime;\n if (spinner) spinner.stop();\n\n // Print timing breakdown so the user knows what's taking time\n const layer1Ms = (timings.discovery ?? 0) + (timings.parsing ?? 0) + (timings.analyzers ?? 0) + (timings.drift ?? 0);\n const parts = [`Layer 1: ${(layer1Ms / 1000).toFixed(1)}s`];\n if (timings.codedna) parts.push(`Code DNA: ${(timings.codedna / 1000).toFixed(1)}s`);\n if (timings.deep) parts.push(`AI: ${(timings.deep / 1000).toFixed(1)}s`);\n parts.push(`Total: ${(scanTimeMs / 1000).toFixed(1)}s`);\n console.error(chalk.dim(` ${parts.join(\" · \")}`));\n\n const result: ScanResult = {\n context: ctx,\n findings: allFindings,\n driftFindings: driftResult.driftFindings,\n driftScores: driftResult.driftScores,\n scores,\n compositeScore,\n maxCompositeScore,\n teaseMessages,\n deepInsights,\n scanTimeMs,\n perFileScores,\n codeDnaResult,\n };\n\n // AI Summary (when --deep is enabled, call the VibeDrift API for an executive summary)\n if (options.deep && bearerToken) {\n if (spinner) spinner.text = \"Generating AI summary...\";\n try {\n const { fetchAiSummary } = await import(\"../../ml-client/summarize.js\");\n const targetUrl = apiUrl ?? \"https://vibedrift-api.fly.dev\";\n if (options.verbose) console.error(`[summary] Calling ${targetUrl}/v1/summarize...`);\n const summary = await fetchAiSummary(result, targetUrl, bearerToken);\n if (summary) {\n result.aiSummary = summary;\n if (options.verbose) console.error(`[summary] AI summary generated (${summary.highlights.length} highlights)`);\n } else {\n if (options.verbose) console.error(`[summary] API returned null`);\n }\n } catch (err: any) {\n if (options.verbose) console.error(`[summary] Failed: ${err.message}`);\n }\n }\n\n return result;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// 5. logAndRender\n// ────────────────────────────────────────────────────────────────────\nasync function logAndRender(\n result: ScanResult,\n options: ScanOptions,\n bearerToken: string | null,\n apiUrl: string | undefined,\n rootDir: string,\n codeDnaResult: any,\n): Promise<void> {\n const { findings: allFindings, compositeScore, maxCompositeScore, scanTimeMs } = result;\n\n // ── Log the scan to the dashboard ──\n // The CLI's full ScanResult (sanitized) is the single source of truth.\n // Both the dashboard's metadata strip AND the embedded HTML report\n // are derived from this object, so they're guaranteed consistent.\n // Runs for both free and deep scans whenever the user is logged in.\n // Silent on failure — the scan already succeeded locally.\n if (bearerToken) {\n try {\n const { logScan } = await import(\"../../ml-client/log-scan.js\");\n const { detectProjectIdentity } = await import(\"../../ml-client/project-name.js\");\n const { sanitizeResultForUpload } = await import(\"../../ml-client/sanitize-result.js\");\n const projectIdentity = await detectProjectIdentity(\n rootDir,\n options.projectName,\n );\n\n // Tally per-detector ML counts (only present for deep scans).\n const mlDuplicates = allFindings.filter((f) => f.analyzerId === \"ml-duplicate\").length;\n const mlIntent = allFindings.filter((f) => f.analyzerId === \"ml-intent\").length;\n const mlAnomaly = allFindings.filter((f) => f.analyzerId === \"ml-anomaly\").length;\n\n // Render the HTML once and ship it. Failures here are fine — the\n // server stores metadata even if the HTML upload is dropped.\n let html: string | undefined;\n try {\n html = renderHtmlReport(result);\n } catch {\n html = undefined;\n }\n\n // Letter grade — MUST match the thresholds in src/output/html.ts\n // gradeFor() so the dashboard's metadata strip agrees with the\n // report it embeds. (A=90, B=75, C=50, D=25, F<25)\n const pct = maxCompositeScore > 0 ? (compositeScore / maxCompositeScore) * 100 : 0;\n const grade =\n pct >= 90 ? \"A\" : pct >= 75 ? \"B\" : pct >= 50 ? \"C\" : pct >= 25 ? \"D\" : \"F\";\n\n // Sanitize the full ScanResult so we can ship it as the canonical\n // metadata blob. Strips ctx.rootDir + any absolute paths.\n const sanitizedResult = sanitizeResultForUpload(result);\n // Stamp the project identity onto the envelope (the sanitizer\n // doesn't know it because it's computed by detectProjectIdentity).\n (sanitizedResult.project as Record<string, unknown>) = {\n name: projectIdentity.name,\n hash: projectIdentity.hash,\n };\n sanitizedResult.grade = grade;\n sanitizedResult.scanType = options.deep ? \"deep\" : \"free\";\n sanitizedResult.scannedAt = new Date().toISOString();\n\n await logScan({\n token: bearerToken,\n apiUrl,\n verbose: options.verbose,\n payload: {\n project_hash: projectIdentity.hash,\n project_name: projectIdentity.name,\n language: result.context.dominantLanguage ?? \"unknown\",\n file_count: result.context.files.length,\n function_count: codeDnaResult?.functions?.length ?? 0,\n finding_count: allFindings.length,\n score: compositeScore,\n grade,\n duplicates_found: mlDuplicates,\n intent_mismatches: mlIntent,\n anomalies_found: mlAnomaly,\n is_deep: !!options.deep,\n processing_time_ms: scanTimeMs,\n report_html: html,\n result_json: sanitizedResult,\n },\n });\n } catch (err: any) {\n if (options.verbose) {\n console.error(chalk.dim(`[scan-log] Failed: ${err.message}`));\n }\n }\n }\n\n // Output\n const format = options.format ?? (options.json ? \"json\" : \"html\");\n await renderToFormat(result, format, options);\n\n // Fail on score threshold\n if (options.failOnScore !== undefined && compositeScore < options.failOnScore) {\n process.exit(1);\n }\n}\n\nasync function renderToFormat(\n result: ScanResult,\n format: string,\n options: ScanOptions,\n): Promise<void> {\n if (format === \"html\") {\n const html = renderHtmlReport(result);\n const outputPath = options.output ?? \"vibedrift-report.html\";\n await writeFile(outputPath, html);\n // Serve on localhost\n const { createServer } = await import(\"http\");\n const server = createServer((req, res) => {\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(html);\n });\n const port = 4173 + Math.floor(Math.random() * 100);\n server.listen(port, () => {\n console.log(`\\n Report saved to ${outputPath}`);\n console.log(` View in browser: \\x1b[36mhttp://localhost:${port}\\x1b[0m\\n`);\n });\n // Keep alive for 10 minutes then auto-close\n setTimeout(() => { server.close(); process.exit(0); }, 600_000);\n // But don't block if user presses Ctrl+C\n process.on(\"SIGINT\", () => { server.close(); process.exit(0); });\n return; // Don't exit — server is running\n } else if (format === \"csv\") {\n const { renderCsvReport } = await import(\"../../output/csv.js\");\n const csv = renderCsvReport(result);\n const outputPath = options.output ?? \"vibedrift-report.csv\";\n await writeFile(outputPath, csv);\n console.log(`CSV report written to ${outputPath}`);\n } else if (format === \"docx\") {\n const { renderDocxReport } = await import(\"../../output/docx.js\");\n const docx = renderDocxReport(result);\n const outputPath = options.output ?? \"vibedrift-report.docx\";\n await writeFile(outputPath, docx);\n console.log(`DOCX report written to ${outputPath}`);\n } else if (format === \"json\") {\n const json = renderJsonOutput(result);\n if (options.output) {\n await writeFile(options.output, json);\n console.log(`JSON report written to ${options.output}`);\n } else {\n console.log(json);\n }\n } else {\n console.log(renderTerminalOutput(result));\n }\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Orchestrator\n// ────────────────────────────────────────────────────────────────────\nexport async function runScan(\n targetPath: string,\n options: ScanOptions,\n): Promise<void> {\n const rootDir = resolve(targetPath);\n\n try {\n const info = await stat(rootDir);\n if (!info.isDirectory()) {\n console.error(`Error: ${rootDir} is not a directory`);\n process.exit(1);\n }\n } catch {\n console.error(`Error: ${rootDir} does not exist`);\n process.exit(1);\n }\n\n const { bearerToken, apiUrl } = await resolveAuthAndBanner(options);\n\n const startTime = Date.now();\n const isTerminal = options.format === \"terminal\" && !options.json;\n const spinner = isTerminal ? ora(\"Discovering files...\").start() : null;\n\n const pipeline = await runAnalysisPipeline(rootDir, options, spinner);\n\n const deepTimings = options.deep && bearerToken\n ? await runDeepAnalysis(pipeline, options, bearerToken, apiUrl, spinner)\n : { timings: {} };\n\n const timings = { ...pipeline.timings, ...deepTimings.timings };\n\n const result = await buildScanResult(pipeline, options, startTime, timings, bearerToken, apiUrl, spinner);\n\n // Save history (per-project, in user home dir — not in the project itself)\n await saveScanResult(rootDir, result.scores, result.compositeScore);\n\n await logAndRender(result, options, bearerToken, apiUrl, rootDir, pipeline.codeDnaResult);\n}\n","/**\n * Project file discovery and manifest loading.\n *\n * Recursively walks the project directory, respects .gitignore rules, and\n * loads ecosystem manifests (package.json, go.mod, Cargo.toml, etc.) to\n * build the AnalysisContext that every analyzer receives.\n */\n\nimport { readdir, readFile, stat } from \"fs/promises\";\nimport { join, relative } from \"path\";\nimport type {\n SourceFile,\n PackageJson,\n GoMod,\n CargoToml,\n AnalysisContext,\n SupportedLanguage,\n} from \"./types.js\";\nimport { detectLanguage } from \"./language.js\";\nimport { loadGitignore } from \"../utils/gitignore.js\";\n\nconst SKIP_DIRS = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \".nuxt\",\n \"target\", \"vendor\", \"__pycache__\", \".venv\", \"venv\",\n \"coverage\", \".turbo\", \".cache\", \".idea\", \".vscode\",\n]);\n\nconst MAX_FILE_SIZE = 1024 * 1024;\nconst MAX_FILE_COUNT = 5000;\n\nexport interface DiscoveryWarnings {\n truncated: boolean;\n truncatedAt: number;\n skippedDirs: string[];\n unreadableFiles: string[];\n}\n\nexport async function discoverFiles(rootDir: string): Promise<{ files: SourceFile[]; warnings: DiscoveryWarnings }> {\n const ig = await loadGitignore(rootDir);\n const files: SourceFile[] = [];\n const warnings: DiscoveryWarnings = {\n truncated: false,\n truncatedAt: 0,\n skippedDirs: [],\n unreadableFiles: [],\n };\n\n async function walk(dir: string) {\n if (files.length >= MAX_FILE_COUNT) {\n warnings.truncated = true;\n warnings.truncatedAt = MAX_FILE_COUNT;\n return;\n }\n\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch (err: any) {\n // Permission denied, etc — skip this directory, don't crash\n warnings.skippedDirs.push(relative(rootDir, dir) || dir);\n return;\n }\n\n for (const entry of entries) {\n if (files.length >= MAX_FILE_COUNT) {\n warnings.truncated = true;\n warnings.truncatedAt = MAX_FILE_COUNT;\n break;\n }\n\n const fullPath = join(dir, entry.name);\n const relPath = relative(rootDir, fullPath);\n\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name) || entry.name.startsWith(\".\")) continue;\n if (ig.ignores(relPath + \"/\")) continue;\n await walk(fullPath);\n } else if (entry.isFile()) {\n if (ig.ignores(relPath)) continue;\n const language = detectLanguage(entry.name);\n if (!language) continue;\n\n try {\n const info = await stat(fullPath);\n if (info.size > MAX_FILE_SIZE) continue;\n\n const content = await readFile(fullPath, \"utf-8\");\n const lineCount = content.split(\"\\n\").length;\n files.push({ path: fullPath, relativePath: relPath, language, content, lineCount });\n } catch {\n // Unreadable file — permission denied, broken symlink, etc.\n warnings.unreadableFiles.push(relPath);\n }\n }\n }\n }\n\n await walk(rootDir);\n return { files, warnings };\n}\n\nexport async function loadPackageJson(rootDir: string): Promise<PackageJson | null> {\n try {\n const raw = await readFile(join(rootDir, \"package.json\"), \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\nexport async function loadGoMod(rootDir: string): Promise<GoMod | null> {\n try {\n const raw = await readFile(join(rootDir, \"go.mod\"), \"utf-8\");\n const lines = raw.split(\"\\n\");\n const result: GoMod = { module: \"\", require: [] };\n\n // State-machine parser: track whether we're inside a `require (` block\n let inRequire = false;\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"module \")) {\n result.module = trimmed.slice(7).trim();\n } else if (trimmed.startsWith(\"go \")) {\n result.goVersion = trimmed.slice(3).trim();\n } else if (trimmed === \"require (\") {\n inRequire = true;\n } else if (trimmed === \")\") {\n inRequire = false;\n } else if (inRequire && trimmed && !trimmed.startsWith(\"//\")) {\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n result.require.push({ path: parts[0], version: parts[1] });\n }\n } else if (trimmed.startsWith(\"require \") && !trimmed.includes(\"(\")) {\n const parts = trimmed.slice(8).trim().split(/\\s+/);\n if (parts.length >= 2) {\n result.require.push({ path: parts[0], version: parts[1] });\n }\n }\n }\n\n return result.module ? result : null;\n } catch {\n return null;\n }\n}\n\nexport async function loadCargoToml(rootDir: string): Promise<CargoToml | null> {\n try {\n const raw = await readFile(join(rootDir, \"Cargo.toml\"), \"utf-8\");\n const result: CargoToml = { dependencies: {} };\n\n let inDeps = false;\n let inPackage = false;\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"[package]\") { inPackage = true; inDeps = false; }\n else if (trimmed === \"[dependencies]\") { inDeps = true; inPackage = false; }\n else if (trimmed.startsWith(\"[\")) { inDeps = false; inPackage = false; }\n else if (inPackage && trimmed.startsWith(\"name\")) {\n const match = trimmed.match(/name\\s*=\\s*\"([^\"]+)\"/);\n if (match) result.name = match[1];\n } else if (inDeps && trimmed.includes(\"=\") && !trimmed.startsWith(\"#\")) {\n const eqIdx = trimmed.indexOf(\"=\");\n const depName = trimmed.slice(0, eqIdx).trim();\n const depVal = trimmed.slice(eqIdx + 1).trim().replace(/\"/g, \"\");\n result.dependencies[depName] = depVal;\n }\n }\n\n return Object.keys(result.dependencies).length > 0 || result.name ? result : null;\n } catch {\n return null;\n }\n}\n\nexport async function loadRequirementsTxt(rootDir: string): Promise<string[] | null> {\n for (const file of [\"requirements.txt\", \"requirements/base.txt\"]) {\n try {\n const raw = await readFile(join(rootDir, file), \"utf-8\");\n const deps: string[] = [];\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\") || trimmed.startsWith(\"-\")) continue;\n const name = trimmed.split(/[>=<!\\[\\s]/)[0];\n if (name) deps.push(name.toLowerCase());\n }\n return deps.length > 0 ? deps : null;\n } catch {\n continue;\n }\n }\n\n try {\n const raw = await readFile(join(rootDir, \"pyproject.toml\"), \"utf-8\");\n const deps: string[] = [];\n let inDeps = false;\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"dependencies = [\") inDeps = true;\n else if (inDeps && trimmed === \"]\") inDeps = false;\n else if (inDeps) {\n const match = trimmed.match(/^\"([^>=<!\\s\"]+)/);\n if (match) deps.push(match[1].toLowerCase());\n }\n }\n return deps.length > 0 ? deps : null;\n } catch {\n return null;\n }\n}\n\nexport async function loadEnvExample(rootDir: string): Promise<Map<string, string> | null> {\n try {\n const raw = await readFile(join(rootDir, \".env.example\"), \"utf-8\");\n const vars = new Map<string, string>();\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx > 0) {\n vars.set(trimmed.slice(0, eqIdx).trim(), trimmed.slice(eqIdx + 1).trim());\n }\n }\n return vars.size > 0 ? vars : null;\n } catch {\n return null;\n }\n}\n\nfunction computeLanguageBreakdown(\n files: SourceFile[],\n): { breakdown: Map<SupportedLanguage, { files: number; lines: number }>; dominant: SupportedLanguage | null } {\n const breakdown = new Map<SupportedLanguage, { files: number; lines: number }>();\n\n for (const file of files) {\n if (!file.language) continue;\n const existing = breakdown.get(file.language) ?? { files: 0, lines: 0 };\n existing.files++;\n existing.lines += file.lineCount;\n breakdown.set(file.language, existing);\n }\n\n let dominant: SupportedLanguage | null = null;\n let maxLines = 0;\n for (const [lang, stats] of breakdown) {\n if (stats.lines > maxLines) { maxLines = stats.lines; dominant = lang; }\n }\n\n return { breakdown, dominant };\n}\n\nexport async function buildAnalysisContext(rootDir: string): Promise<{ ctx: AnalysisContext; warnings: DiscoveryWarnings }> {\n // Load file tree and all manifest types in parallel to minimize I/O wait\n const [discovery, packageJson, goMod, cargoToml, requirementsTxt, envExample] = await Promise.all([\n discoverFiles(rootDir),\n loadPackageJson(rootDir),\n loadGoMod(rootDir),\n loadCargoToml(rootDir),\n loadRequirementsTxt(rootDir),\n loadEnvExample(rootDir),\n ]);\n\n const { files, warnings } = discovery;\n const totalLines = files.reduce((sum, f) => sum + f.lineCount, 0);\n const { breakdown, dominant } = computeLanguageBreakdown(files);\n\n const ctx: AnalysisContext = {\n rootDir,\n files,\n packageJson,\n goMod,\n cargoToml,\n requirementsTxt,\n envExample,\n totalLines,\n languageBreakdown: breakdown,\n dominantLanguage: dominant,\n };\n\n return { ctx, warnings };\n}\n","import type { SupportedLanguage } from \"./types.js\";\n\nconst EXTENSION_MAP: Record<string, SupportedLanguage> = {\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".ts\": \"typescript\",\n \".tsx\": \"typescript\",\n \".mts\": \"typescript\",\n \".cts\": \"typescript\",\n \".py\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n};\n\nexport function detectLanguage(filePath: string): SupportedLanguage | null {\n const ext = filePath.slice(filePath.lastIndexOf(\".\"));\n return EXTENSION_MAP[ext] ?? null;\n}\n\nexport function getLanguageDisplayName(lang: SupportedLanguage): string {\n const names: Record<SupportedLanguage, string> = {\n javascript: \"JS\",\n typescript: \"TS\",\n python: \"Python\",\n go: \"Go\",\n rust: \"Rust\",\n };\n return names[lang];\n}\n","import ignore, { type Ignore } from \"ignore\";\nimport { readFile } from \"fs/promises\";\nimport { join } from \"path\";\n\nexport async function loadGitignore(rootDir: string): Promise<Ignore> {\n const ig = ignore();\n\n for (const file of [\".gitignore\", \".vibedriftignore\"]) {\n try {\n const content = await readFile(join(rootDir, file), \"utf-8\");\n ig.add(content);\n } catch {\n // file doesn't exist, skip\n }\n }\n\n return ig;\n}\n","import { Parser, Language } from \"web-tree-sitter\";\nimport type { Tree } from \"web-tree-sitter\";\nimport type { SupportedLanguage, SourceFile } from \"../core/types.js\";\n\nlet initialized = false;\nconst languageCache = new Map<string, Language>();\n\nasync function ensureInit(): Promise<void> {\n if (initialized) return;\n await Parser.init();\n initialized = true;\n}\n\nasync function getLanguage(lang: SupportedLanguage): Promise<Language> {\n const grammarMap: Record<SupportedLanguage, string> = {\n javascript: \"javascript\",\n typescript: \"typescript\",\n python: \"python\",\n go: \"go\",\n rust: \"rust\",\n };\n\n const grammarName = grammarMap[lang];\n const cached = languageCache.get(grammarName);\n if (cached) return cached;\n\n const wasmModule = await import(\"tree-sitter-wasms\");\n const wasmPath =\n (wasmModule as Record<string, string>)[`tree_sitter_${grammarName}`] ??\n (wasmModule.default as Record<string, string>)?.[\n `tree_sitter_${grammarName}`\n ];\n\n if (!wasmPath) {\n throw new Error(`No WASM grammar found for language: ${lang}`);\n }\n\n const language = await Language.load(wasmPath);\n languageCache.set(grammarName, language);\n return language;\n}\n\nexport async function parseFile(file: SourceFile): Promise<Tree | null> {\n if (!file.language) return null;\n\n try {\n await ensureInit();\n const language = await getLanguage(file.language);\n const parser = new Parser();\n parser.setLanguage(language);\n const tree = parser.parse(file.content);\n return tree;\n } catch {\n return null;\n }\n}\n\nexport async function parseFiles(files: SourceFile[]): Promise<void> {\n for (const file of files) {\n if (file.language) {\n file.tree = (await parseFile(file)) ?? undefined;\n }\n }\n}\n","import type { Analyzer } from \"./base.js\";\nimport { namingAnalyzer } from \"./naming.js\";\nimport { importsAnalyzer } from \"./imports.js\";\nimport { errorHandlingAnalyzer } from \"./error-handling.js\";\nimport { dependenciesAnalyzer } from \"./dependencies.js\";\nimport { duplicatesAnalyzer } from \"./duplicates.js\";\nimport { todoDensityAnalyzer } from \"./todo-density.js\";\nimport { configDriftAnalyzer } from \"./config-drift.js\";\nimport { securityAnalyzer } from \"./security.js\";\nimport { complexityAnalyzer } from \"./complexity.js\";\nimport { intentClarityAnalyzer } from \"./intent-clarity.js\";\nimport { deadCodeAnalyzer } from \"./dead-code.js\";\nimport { languageSpecificAnalyzer } from \"./language-specific.js\";\n\nexport function createAnalyzerRegistry(): Analyzer[] {\n return [\n // Architectural Consistency\n namingAnalyzer,\n importsAnalyzer,\n errorHandlingAnalyzer,\n languageSpecificAnalyzer,\n // Redundancy\n duplicatesAnalyzer,\n todoDensityAnalyzer,\n deadCodeAnalyzer,\n // Dependency Health\n dependenciesAnalyzer,\n configDriftAnalyzer,\n // Security Posture\n securityAnalyzer,\n // Intent Clarity\n intentClarityAnalyzer,\n complexityAnalyzer,\n ];\n}\n","/**\n * Naming convention consistency analyzer.\n *\n * Detects the dominant casing convention (camelCase vs snake_case) across\n * all identifiers in the project, then flags files that deviate from it.\n * Works with AST when available, falls back to regex extraction otherwise.\n */\n\nimport type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding, SyntaxNode } from \"../core/types.js\";\n\ntype Convention = \"camelCase\" | \"snake_case\" | \"PascalCase\" | \"SCREAMING_SNAKE\";\n\nfunction detectConvention(name: string): Convention | null {\n if (/^[A-Z][A-Z0-9_]+$/.test(name)) return \"SCREAMING_SNAKE\";\n if (/^[A-Z][a-zA-Z0-9]*$/.test(name)) return \"PascalCase\";\n if (/^[a-z][a-zA-Z0-9]*$/.test(name)) return \"camelCase\";\n if (/^[a-z][a-z0-9_]*$/.test(name)) return \"snake_case\";\n return null;\n}\n\nfunction extractIdentifiers(node: SyntaxNode): string[] {\n const ids: string[] = [];\n const targetTypes = new Set([\n \"variable_declarator\", \"function_declaration\", \"method_definition\",\n \"lexical_declaration\", \"short_var_declaration\", \"function_item\",\n \"let_declaration\",\n ]);\n\n function walk(n: SyntaxNode) {\n if (targetTypes.has(n.type)) {\n const nameNode = n.childForFieldName(\"name\");\n if (nameNode) ids.push(nameNode.text);\n }\n for (let i = 0; i < n.childCount; i++) {\n walk(n.child(i)!);\n }\n }\n\n walk(node);\n return ids;\n}\n\n// Regex fallback for files without AST\nfunction extractIdentifiersRegex(content: string): string[] {\n const ids: string[] = [];\n const patterns = [\n /(?:const|let|var|function)\\s+(\\w+)/g,\n /def\\s+(\\w+)/g, // Python\n /func\\s+(\\w+)/g, // Go\n /fn\\s+(\\w+)/g, // Rust\n ];\n for (const p of patterns) {\n const regex = new RegExp(p.source, p.flags);\n let m;\n while ((m = regex.exec(content)) !== null) {\n ids.push(m[1]);\n }\n }\n return ids;\n}\n\nexport const namingAnalyzer: Analyzer = {\n id: \"naming\",\n name: \"Naming Conventions\",\n category: \"architecturalConsistency\",\n requiresAST: false, // works with regex fallback too\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const conventionCounts = new Map<Convention, string[]>();\n\n for (const file of ctx.files) {\n const ids = file.tree\n ? extractIdentifiers(file.tree.rootNode)\n : extractIdentifiersRegex(file.content);\n\n for (const id of ids) {\n if (id.length <= 1 || id.startsWith(\"_\")) continue;\n const conv = detectConvention(id);\n // Exclude SCREAMING_SNAKE (constants) and PascalCase (types/classes)\n // since those are cross-convention by design\n if (!conv || conv === \"SCREAMING_SNAKE\" || conv === \"PascalCase\") continue;\n if (!conventionCounts.has(conv)) conventionCounts.set(conv, []);\n conventionCounts.get(conv)!.push(file.relativePath);\n }\n }\n\n // Sort by frequency so the most-used convention is at index 0 (\"dominant\")\n const conventions = [...conventionCounts.entries()].sort(\n (a, b) => b[1].length - a[1].length,\n );\n\n // Only flag inconsistency when at least two conventions coexist\n if (conventions.length >= 2) {\n const dominant = conventions[0];\n for (const [conv, files] of conventions.slice(1)) {\n const uniqueFiles = [...new Set(files)];\n if (uniqueFiles.length >= 2) {\n findings.push({\n analyzerId: \"naming\",\n severity: \"warning\",\n confidence: 0.8,\n message: `${uniqueFiles.length} files use ${conv} while majority uses ${dominant[0]}`,\n locations: uniqueFiles.slice(0, 10).map((f) => ({ file: f })),\n tags: [\"naming\", \"inconsistency\"],\n });\n }\n }\n }\n\n return findings;\n },\n};\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\n\nconst ESM_PATTERN = /\\b(?:import\\s+|export\\s+(?:default\\s+)?(?:function|class|const|let|var|{))/;\nconst CJS_PATTERN = /\\b(?:require\\s*\\(|module\\.exports|exports\\.)/;\nconst CONFIG_FILE_PATTERN = /(?:\\.config\\.|\\.setup\\.|\\.rc\\.|jest\\.|babel\\.|webpack\\.|rollup\\.|vite\\.|next\\.config|tailwind\\.config|postcss\\.config|tsconfig|eslint\\.config|prettier\\.config|svelte\\.config|nuxt\\.config|astro\\.config|vitest\\.config|tsup\\.config|esbuild\\.config|turbo\\.json|\\.cjs$|\\.mjs$)/;\n\nexport const importsAnalyzer: Analyzer = {\n id: \"imports\",\n name: \"Import Patterns\",\n category: \"architecturalConsistency\",\n requiresAST: false,\n applicableLanguages: [\"javascript\", \"typescript\"],\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const jsFiles = ctx.files.filter(\n (f) => f.language === \"javascript\" || f.language === \"typescript\",\n );\n\n const esmFiles: string[] = [];\n const cjsFiles: string[] = [];\n\n // Skip test fixtures (intentionally mixed) and analyzer files\n // (which have CJS patterns as detection targets inside regex strings)\n const SKIP_PATH = /(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\\\]/i;\n\n for (const file of jsFiles) {\n if (CONFIG_FILE_PATTERN.test(file.relativePath)) continue;\n if (SKIP_PATH.test(file.relativePath)) continue;\n\n // Strip regex literals and string contents before checking for CJS\n // patterns. This prevents analyzer files that have /require\\s*\\(/\n // inside their pattern definitions from being flagged as CJS.\n const stripped = file.content\n .replace(/\\/[^/\\n]+\\/[gimsuvy]*/g, '\"\"') // regex literals → empty string\n .replace(/`[^`]*`/g, '\"\"'); // template literals → empty\n const hasESM = ESM_PATTERN.test(file.content);\n const hasCJS = CJS_PATTERN.test(stripped);\n\n if (hasESM && hasCJS) {\n findings.push({\n analyzerId: \"imports\",\n severity: \"warning\",\n confidence: 0.9,\n message: `Mixed ESM and CommonJS in ${file.relativePath}`,\n locations: [{ file: file.relativePath }],\n tags: [\"imports\", \"mixed\"],\n });\n }\n\n if (hasESM) esmFiles.push(file.relativePath);\n if (hasCJS) cjsFiles.push(file.relativePath);\n }\n\n if (esmFiles.length > 0 && cjsFiles.length > 0) {\n const minorityFiles = esmFiles.length >= cjsFiles.length ? cjsFiles : esmFiles;\n findings.push({\n analyzerId: \"imports\",\n severity: \"warning\",\n confidence: 0.85,\n message: `Mixed ESM/CommonJS across project: ${esmFiles.length} ESM files, ${cjsFiles.length} CJS files`,\n locations: minorityFiles.slice(0, 10).map((f) => ({ file: f })),\n tags: [\"imports\", \"project-inconsistency\"],\n });\n }\n\n return findings;\n },\n};\n","/**\n * Error handling quality analyzer for JavaScript/TypeScript.\n *\n * Detects two anti-patterns: (1) empty catch blocks that silently swallow\n * errors, and (2) async functions using `await` without any try/catch or\n * .catch() — a common source of unhandled promise rejections.\n */\n\nimport type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\nconst EMPTY_CATCH_PATTERN = /catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}/g;\nconst TRY_CATCH_PATTERN = /\\btry\\s*\\{/g;\nconst ASYNC_PATTERN = /\\basync\\s+(?:function|\\(|[a-zA-Z])/g;\n\nexport const errorHandlingAnalyzer: Analyzer = {\n id: \"error-handling\",\n name: \"Error Handling\",\n category: \"architecturalConsistency\",\n requiresAST: false,\n applicableLanguages: [\"javascript\", \"typescript\"],\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const jsFiles = ctx.files.filter(\n (f) => f.language === \"javascript\" || f.language === \"typescript\",\n );\n\n let totalEmptyCatches = 0;\n const emptyCatchLocations: { file: string; line: number; snippet?: string }[] = [];\n\n for (const file of jsFiles) {\n const emptyRegex = new RegExp(EMPTY_CATCH_PATTERN.source, \"g\");\n let match;\n while ((match = emptyRegex.exec(file.content)) !== null) {\n totalEmptyCatches++;\n const line = getLineNumber(file.content, match.index);\n emptyCatchLocations.push({\n file: file.relativePath,\n line,\n snippet: match[0],\n });\n }\n }\n\n if (totalEmptyCatches > 0) {\n findings.push({\n analyzerId: \"error-handling\",\n severity: totalEmptyCatches > 5 ? \"error\" : \"warning\",\n confidence: 0.95,\n message: `${totalEmptyCatches} empty catch blocks found`,\n locations: emptyCatchLocations.slice(0, 10),\n tags: [\"error-handling\", \"empty-catch\"],\n });\n }\n\n const ASYNC_FN_PATTERN =\n /async\\s+(?:function\\s+\\w+|\\(\\w*\\)|\\w+)\\s*\\([^)]*\\)\\s*(?::\\s*[^{]*)?\\s*\\{/g;\n const ERROR_HANDLING_PATTERNS = [\n /\\btry\\s*\\{/,\n /\\.catch\\s*\\(/,\n /\\bcatch\\s*\\(/,\n /\\b(?:Result|Either)\\s*[<(]/,\n ];\n\n // Aggregate unhandled async counts per directory to avoid flooding\n // the report with one finding per function\n const dirUnhandled = new Map<string, number>();\n\n for (const file of jsFiles) {\n const dir = file.relativePath.includes(\"/\")\n ? file.relativePath.slice(0, file.relativePath.lastIndexOf(\"/\"))\n : \".\";\n\n const asyncRegex = new RegExp(ASYNC_FN_PATTERN.source, \"g\");\n let fnMatch;\n while ((fnMatch = asyncRegex.exec(file.content)) !== null) {\n // Extract the function body via brace-depth counting so we can\n // check if error handling exists within this specific function scope\n const openBrace = file.content.indexOf(\"{\", fnMatch.index + fnMatch[0].length - 1);\n if (openBrace === -1) continue;\n let depth = 1;\n let pos = openBrace + 1;\n while (pos < file.content.length && depth > 0) {\n if (file.content[pos] === \"{\") depth++;\n else if (file.content[pos] === \"}\") depth--;\n pos++;\n }\n const body = file.content.slice(openBrace + 1, pos - 1);\n\n // Only flag if the body uses await but has no error handling\n if (!/\\bawait\\b/.test(body)) continue;\n const hasHandling = ERROR_HANDLING_PATTERNS.some((p) => p.test(body));\n if (!hasHandling) {\n dirUnhandled.set(dir, (dirUnhandled.get(dir) ?? 0) + 1);\n }\n }\n }\n\n for (const [dir, count] of dirUnhandled) {\n if (count > 3) {\n findings.push({\n analyzerId: \"error-handling\",\n severity: \"info\",\n confidence: 0.6,\n message: `${count} async functions without error handling in ${dir}/`,\n locations: [{ file: dir }],\n tags: [\"error-handling\", \"unhandled-async\"],\n });\n }\n }\n\n return findings;\n },\n};\n","export function getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split(\"\\n\").length;\n}\n\nexport function densityPer1K(count: number, totalLines: number): number {\n if (totalLines === 0) return 0;\n return Math.round((count / totalLines) * 1000 * 10) / 10;\n}\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\n\nconst NODE_BUILTINS = new Set([\n \"assert\", \"buffer\", \"child_process\", \"cluster\", \"console\", \"constants\",\n \"crypto\", \"dgram\", \"dns\", \"domain\", \"events\", \"fs\", \"http\", \"http2\",\n \"https\", \"module\", \"net\", \"os\", \"path\", \"perf_hooks\", \"process\",\n \"punycode\", \"querystring\", \"readline\", \"repl\", \"stream\", \"string_decoder\",\n \"sys\", \"timers\", \"tls\", \"tty\", \"url\", \"util\", \"v8\", \"vm\", \"wasi\",\n \"worker_threads\", \"zlib\",\n]);\n\nconst JS_IMPORT_PATTERNS = [\n /(?:import|from)\\s+['\"]([^./][^'\"]*)['\"]/g,\n /require\\(\\s*['\"]([^./][^'\"]*)['\"]\\s*\\)/g,\n // Dynamic imports: await import(\"pkg\") or import(\"pkg\")\n /import\\(\\s*['\"]([^./][^'\"]*)['\"]\\s*\\)/g,\n];\n\n// Test fixture directories — their imports are intentionally broken/nonexistent\nconst FIXTURE_PATH_PATTERN = /(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\\\]/i;\n\n// We extract Go imports by finding import blocks, not raw string matching\nfunction extractGoImports(content: string): string[] {\n const imports: string[] = [];\n\n // Single import: import \"path\"\n const singlePattern = /^import\\s+\"([^\"]+)\"/gm;\n let m;\n while ((m = singlePattern.exec(content)) !== null) {\n imports.push(m[1]);\n }\n\n // Block import: import ( ... )\n const blockPattern = /^import\\s*\\(([\\s\\S]*?)\\)/gm;\n while ((m = blockPattern.exec(content)) !== null) {\n const block = m[1];\n const linePattern = /^\\s*(?:\\w+\\s+)?\"([^\"]+)\"/gm;\n let lineMatch;\n while ((lineMatch = linePattern.exec(block)) !== null) {\n imports.push(lineMatch[1]);\n }\n }\n\n return imports;\n}\nconst PYTHON_IMPORT_PATTERN = /^(?:import|from)\\s+(\\w+)/gm;\nconst RUST_USE_PATTERN = /^use\\s+(\\w+)/gm;\n\nfunction extractJsPackageName(specifier: string): string {\n if (specifier.startsWith(\"@\")) {\n const parts = specifier.split(\"/\");\n return parts.slice(0, 2).join(\"/\");\n }\n return specifier.split(\"/\")[0];\n}\n\nconst DEV_TOOL_PATTERNS = [\n \"@types/\", \"eslint\", \"prettier\", \"tsup\", \"vitest\", \"typescript\",\n \"jest\", \"mocha\", \"webpack\", \"rollup\", \"vite\", \"babel\", \"postcss\",\n \"tailwindcss\", \"autoprefixer\", \"lint-staged\", \"husky\",\n];\n\nexport const dependenciesAnalyzer: Analyzer = {\n id: \"dependencies\",\n name: \"Dependency Health\",\n category: \"dependencyHealth\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n // JS/TS dependency analysis\n if (ctx.packageJson) {\n findings.push(...analyzeJsDeps(ctx));\n }\n\n // Go dependency analysis\n if (ctx.goMod) {\n findings.push(...analyzeGoDeps(ctx));\n }\n\n // Python dependency analysis\n if (ctx.requirementsTxt) {\n findings.push(...analyzePythonDeps(ctx));\n }\n\n // Rust dependency analysis\n if (ctx.cargoToml) {\n findings.push(...analyzeRustDeps(ctx));\n }\n\n return findings;\n },\n};\n\nfunction collectImportedPackages(\n files: { content: string; relativePath: string }[],\n): { imported: Set<string>; importLocations: Map<string, { file: string; line: number }[]> } {\n const imported = new Set<string>();\n const importLocations = new Map<string, { file: string; line: number }[]>();\n\n for (const file of files) {\n for (const pattern of JS_IMPORT_PATTERNS) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const pkg = extractJsPackageName(match[1]);\n if (NODE_BUILTINS.has(pkg) || pkg.startsWith(\"node:\") || pkg.startsWith(\"@/\") || pkg.startsWith(\"~\")) continue;\n imported.add(pkg);\n if (!importLocations.has(pkg)) importLocations.set(pkg, []);\n importLocations.get(pkg)!.push({\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n });\n }\n }\n }\n\n return { imported, importLocations };\n}\n\nfunction detectPhantomDeps(declared: Set<string>, imported: Set<string>, devToolPatterns: string[]): Finding[] {\n const phantom = [...declared].filter((d) => !imported.has(d));\n const realPhantom = phantom.filter(\n (p) => !devToolPatterns.some((pat) => p.includes(pat)),\n );\n\n if (realPhantom.length > 0) {\n return [{\n analyzerId: \"dependencies\",\n severity: realPhantom.length > 5 ? \"error\" : \"warning\",\n confidence: 0.75,\n message: `${realPhantom.length} phantom dependencies (declared but unused): ${realPhantom.slice(0, 5).join(\", \")}${realPhantom.length > 5 ? \"...\" : \"\"}`,\n locations: realPhantom.map((p) => ({ file: \"package.json\" })),\n tags: [\"deps\", \"phantom\", \"js\"],\n }];\n }\n\n return [];\n}\n\n// Filter out common bundler aliases, virtual modules, and workspace-internal packages\nconst ALIAS_PATTERNS = [\n /^#/, /^virtual:/, /^vite\\//, /^next\\//,\n /^\\$/, /^server-only$/, /^client-only$/,\n];\n\nfunction detectMissingDeps(\n declared: Set<string>,\n imported: Set<string>,\n isMonorepo: boolean,\n importLocations: Map<string, { file: string; line: number }[]>,\n): Finding[] {\n const missing = [...imported].filter((i) => {\n if (declared.has(i)) return false;\n if (ALIAS_PATTERNS.some((p) => p.test(i))) return false;\n return true;\n });\n\n // In monorepos/workspaces, missing deps are likely workspace packages — lower severity\n const missingConfidence = isMonorepo ? 0.4 : 0.75;\n const missingSeverity = isMonorepo ? \"warning\" as const : \"error\" as const;\n\n if (missing.length > 0) {\n return [{\n analyzerId: \"dependencies\",\n severity: missingSeverity,\n confidence: missingConfidence,\n message: `${missing.length} packages imported but not in package.json: ${missing.slice(0, 5).join(\", \")}${missing.length > 5 ? \"...\" : \"\"}${isMonorepo ? \" (may be workspace packages)\" : \"\"}`,\n locations: missing.slice(0, 5).flatMap((p) => importLocations.get(p) ?? []),\n tags: [\"deps\", \"missing\", \"js\"],\n }];\n }\n\n return [];\n}\n\nfunction analyzeJsDeps(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const pkg = ctx.packageJson!;\n\n // Include optionalDependencies and detect workspace packages\n const declared = new Set<string>([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ...Object.keys(pkg.peerDependencies ?? {}),\n ...Object.keys((pkg as any).optionalDependencies ?? {}),\n ]);\n\n // Detect monorepo workspace packages (workspace:* protocol, or packages\n // whose versions are \"workspace:*\", \"workspace:^\", \"workspace:~\", \"*\")\n const isMonorepo = [...Object.values(pkg.dependencies ?? {}),\n ...Object.values(pkg.devDependencies ?? {})].some(\n (v) => typeof v === \"string\" && (v.startsWith(\"workspace:\") || v === \"*\"),\n );\n // Also check for workspaces field\n const hasWorkspaces = !!(pkg as any).workspaces;\n\n const jsFiles = ctx.files.filter(\n (f) =>\n (f.language === \"javascript\" || f.language === \"typescript\") &&\n !FIXTURE_PATH_PATTERN.test(f.relativePath),\n );\n\n const { imported, importLocations } = collectImportedPackages(jsFiles);\n\n findings.push(...detectPhantomDeps(declared, imported, DEV_TOOL_PATTERNS));\n findings.push(...detectMissingDeps(declared, imported, isMonorepo || hasWorkspaces, importLocations));\n\n return findings;\n}\n\nfunction analyzeGoDeps(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const goMod = ctx.goMod!;\n const declaredPaths = new Set(goMod.require.map((r) => r.path));\n\n const importedPaths = new Set<string>();\n const goFiles = ctx.files.filter((f) => f.language === \"go\");\n\n for (const file of goFiles) {\n const goImports = extractGoImports(file.content);\n for (const importPath of goImports) {\n // Skip stdlib (no dots in first segment)\n if (!importPath.includes(\".\")) continue;\n // Skip URLs\n if (importPath.startsWith(\"http://\") || importPath.startsWith(\"https://\")) continue;\n // Skip internal module imports\n if (importPath.startsWith(goMod.module)) continue;\n // Extract module path (first 3 segments for github.com/x/y style)\n const segments = importPath.split(\"/\");\n const modPath = segments.length >= 3 ? segments.slice(0, 3).join(\"/\") : importPath;\n importedPaths.add(modPath);\n }\n }\n\n const phantom = [...declaredPaths].filter((d) => !importedPaths.has(d));\n if (phantom.length > 0) {\n findings.push({\n analyzerId: \"dependencies\",\n severity: \"warning\",\n confidence: 0.7,\n message: `${phantom.length} potentially unused Go modules: ${phantom.slice(0, 3).join(\", \")}${phantom.length > 3 ? \"...\" : \"\"}`,\n locations: [{ file: \"go.mod\" }],\n tags: [\"deps\", \"phantom\", \"go\"],\n });\n }\n\n const missing = [...importedPaths].filter((i) => !declaredPaths.has(i));\n if (missing.length > 0) {\n findings.push({\n analyzerId: \"dependencies\",\n severity: \"error\",\n confidence: 0.8,\n message: `${missing.length} Go imports not in go.mod: ${missing.slice(0, 3).join(\", \")}${missing.length > 3 ? \"...\" : \"\"}`,\n locations: [{ file: \"go.mod\" }],\n tags: [\"deps\", \"missing\", \"go\"],\n });\n }\n\n return findings;\n}\n\nfunction analyzePythonDeps(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const declared = new Set(ctx.requirementsTxt!);\n\n const imported = new Set<string>();\n const pyFiles = ctx.files.filter((f) => f.language === \"python\");\n\n const PYTHON_STDLIB = new Set([\n \"os\", \"sys\", \"re\", \"json\", \"math\", \"datetime\", \"collections\", \"itertools\",\n \"functools\", \"pathlib\", \"typing\", \"abc\", \"io\", \"time\", \"logging\", \"copy\",\n \"hashlib\", \"base64\", \"subprocess\", \"threading\", \"multiprocessing\", \"socket\",\n \"http\", \"urllib\", \"email\", \"html\", \"xml\", \"csv\", \"sqlite3\", \"unittest\",\n \"argparse\", \"configparser\", \"dataclasses\", \"enum\", \"contextlib\", \"inspect\",\n \"asyncio\", \"concurrent\", \"signal\", \"shutil\", \"glob\", \"tempfile\", \"pickle\",\n \"struct\", \"textwrap\", \"string\", \"operator\", \"warnings\",\n ]);\n\n for (const file of pyFiles) {\n const regex = new RegExp(PYTHON_IMPORT_PATTERN.source, PYTHON_IMPORT_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const mod = match[1].toLowerCase();\n if (PYTHON_STDLIB.has(mod)) continue;\n imported.add(mod);\n }\n }\n\n const phantom = [...declared].filter((d) => !imported.has(d));\n if (phantom.length > 2) {\n findings.push({\n analyzerId: \"dependencies\",\n severity: \"warning\",\n confidence: 0.65,\n message: `${phantom.length} potentially unused Python packages: ${phantom.slice(0, 5).join(\", \")}`,\n locations: [{ file: \"requirements.txt\" }],\n tags: [\"deps\", \"phantom\", \"python\"],\n });\n }\n\n return findings;\n}\n\nfunction analyzeRustDeps(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const declared = new Set(Object.keys(ctx.cargoToml!.dependencies));\n\n const imported = new Set<string>();\n const rsFiles = ctx.files.filter((f) => f.language === \"rust\");\n\n for (const file of rsFiles) {\n const regex = new RegExp(RUST_USE_PATTERN.source, RUST_USE_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const crateName = match[1];\n if ([\"std\", \"core\", \"alloc\", \"self\", \"super\", \"crate\"].includes(crateName)) continue;\n imported.add(crateName);\n }\n }\n\n const phantom = [...declared].filter(\n (d) => !imported.has(d) && !imported.has(d.replace(/-/g, \"_\")),\n );\n if (phantom.length > 0) {\n findings.push({\n analyzerId: \"dependencies\",\n severity: \"warning\",\n confidence: 0.7,\n message: `${phantom.length} potentially unused Rust crates: ${phantom.slice(0, 5).join(\", \")}`,\n locations: [{ file: \"Cargo.toml\" }],\n tags: [\"deps\", \"phantom\", \"rust\"],\n });\n }\n\n return findings;\n}\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\n\ninterface TokenSequence {\n file: string;\n line: number;\n funcName: string;\n tokens: string[];\n hash: number;\n}\n\n// Tokenize source: strip comments, whitespace, normalize identifiers\nfunction tokenize(source: string): string[] {\n // Remove single-line comments\n let cleaned = source.replace(/\\/\\/.*$/gm, \"\");\n cleaned = cleaned.replace(/#.*$/gm, \"\");\n // Remove multi-line comments\n cleaned = cleaned.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n // Remove string literals (replace with placeholder)\n cleaned = cleaned.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"STR\"');\n cleaned = cleaned.replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"'STR'\");\n cleaned = cleaned.replace(/`(?:[^`\\\\]|\\\\.)*`/g, \"`STR`\");\n\n // Split into tokens\n const tokens = cleaned.match(/[a-zA-Z_]\\w*|[0-9]+(?:\\.[0-9]+)?|[{}()\\[\\];,.:=<>!+\\-*/%&|^~?@#]/g);\n return tokens ?? [];\n}\n\n// Simple hash for fast comparison (FNV-1a inspired)\nfunction hashTokens(tokens: string[]): number {\n let hash = 2166136261;\n for (const t of tokens) {\n for (let i = 0; i < t.length; i++) {\n hash ^= t.charCodeAt(i);\n hash = (hash * 16777619) | 0;\n }\n hash ^= 31; // separator\n }\n return hash;\n}\n\n// Normalize tokens: replace specific identifiers with placeholders\nfunction normalizeTokens(tokens: string[]): string[] {\n const identifierMap = new Map<string, string>();\n let counter = 0;\n\n return tokens.map((t) => {\n // Keep keywords and operators\n if (isKeywordOrOperator(t)) return t;\n // Keep number literals\n if (/^[0-9]/.test(t)) return \"NUM\";\n // Keep string placeholders\n if (t === \"STR\") return \"STR\";\n\n // Normalize identifiers\n if (!identifierMap.has(t)) {\n identifierMap.set(t, `ID${counter++}`);\n }\n return identifierMap.get(t)!;\n });\n}\n\nconst KEYWORDS = new Set([\n \"function\", \"const\", \"let\", \"var\", \"if\", \"else\", \"for\", \"while\", \"do\",\n \"switch\", \"case\", \"break\", \"continue\", \"return\", \"throw\", \"try\", \"catch\",\n \"finally\", \"new\", \"delete\", \"typeof\", \"instanceof\", \"void\", \"in\", \"of\",\n \"class\", \"extends\", \"super\", \"import\", \"export\", \"default\", \"from\",\n \"async\", \"await\", \"yield\", \"static\", \"public\", \"private\", \"protected\",\n \"true\", \"false\", \"null\", \"undefined\", \"this\",\n // Go\n \"func\", \"type\", \"struct\", \"interface\", \"map\", \"chan\", \"go\", \"select\",\n \"defer\", \"range\", \"package\",\n // Python\n \"def\", \"class\", \"elif\", \"except\", \"lambda\", \"with\", \"as\", \"pass\",\n \"raise\", \"global\", \"nonlocal\", \"assert\", \"and\", \"or\", \"not\", \"is\",\n \"None\", \"True\", \"False\",\n // Rust\n \"fn\", \"let\", \"mut\", \"impl\", \"trait\", \"enum\", \"match\", \"pub\", \"mod\",\n \"use\", \"crate\", \"self\", \"where\", \"unsafe\", \"move\", \"ref\",\n]);\n\nfunction isKeywordOrOperator(t: string): boolean {\n if (KEYWORDS.has(t)) return true;\n return /^[{}()\\[\\];,.:=<>!+\\-*/%&|^~?@#]$/.test(t);\n}\n\n// Extract function bodies as token sequences\nfunction extractFunctionTokens(content: string, file: string): TokenSequence[] {\n const sequences: TokenSequence[] = [];\n const funcPatterns = [\n /(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\([^)]*\\)\\s*\\{/g,\n /(?:export\\s+)?const\\s+(\\w+)\\s*=\\s*(?:async\\s+)?\\([^)]*\\)\\s*=>\\s*\\{/g,\n /def\\s+(\\w+)\\s*\\([^)]*\\)\\s*:/g,\n /func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)\\s*\\([^)]*\\)\\s*(?:\\([^)]*\\)\\s*)?\\{/g,\n /(?:pub\\s+)?(?:async\\s+)?fn\\s+(\\w+)\\s*(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*(?:->[^{]*)?\\{/g,\n ];\n\n for (const pattern of funcPatterns) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(content)) !== null) {\n const funcName = match[1];\n const startIndex = match.index;\n const line = content.slice(0, startIndex).split(\"\\n\").length;\n\n // Find function body (brace matching or indent-based for Python)\n const body = extractBody(content, startIndex + match[0].length - 1);\n if (body.length < 20) continue; // too short to be meaningful\n\n const tokens = tokenize(body);\n if (tokens.length < 15) continue; // minimum token threshold\n\n const normalized = normalizeTokens(tokens);\n sequences.push({\n file,\n line,\n funcName,\n tokens: normalized,\n hash: hashTokens(normalized),\n });\n }\n }\n\n return sequences;\n}\n\nfunction extractBody(content: string, openBraceIndex: number): string {\n const ch = content[openBraceIndex];\n\n if (ch === \"{\") {\n // Brace-delimited\n let depth = 1;\n let i = openBraceIndex + 1;\n while (i < content.length && depth > 0) {\n if (content[i] === \"{\") depth++;\n else if (content[i] === \"}\") depth--;\n i++;\n }\n return content.slice(openBraceIndex, i);\n }\n\n if (ch === \":\") {\n // Python: indent-based, take until dedent\n const lines = content.slice(openBraceIndex + 1).split(\"\\n\");\n const bodyLines: string[] = [];\n let baseIndent = -1;\n\n for (const line of lines) {\n if (line.trim() === \"\") {\n bodyLines.push(line);\n continue;\n }\n const indent = line.search(/\\S/);\n if (baseIndent === -1) {\n baseIndent = indent;\n }\n if (indent >= baseIndent) {\n bodyLines.push(line);\n } else {\n break;\n }\n }\n return bodyLines.join(\"\\n\");\n }\n\n return \"\";\n}\n\n// Compare two token sequences for similarity using LCS ratio\nfunction tokenSimilarity(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n\n // Use rolling window comparison for efficiency on larger functions\n const minLen = Math.min(a.length, b.length);\n const maxLen = Math.max(a.length, b.length);\n\n // Quick reject: length ratio too different\n if (minLen / maxLen < 0.5) return 0;\n\n // LCS-based similarity (O(n*m) but bounded by function size)\n if (minLen > 500) {\n // For very long functions, use sampled comparison\n return sampledSimilarity(a, b);\n }\n\n const dp: number[][] = Array.from({ length: a.length + 1 }, () =>\n new Array(b.length + 1).fill(0),\n );\n\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n if (a[i - 1] === b[j - 1]) {\n dp[i][j] = dp[i - 1][j - 1] + 1;\n } else {\n dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);\n }\n }\n }\n\n const lcsLength = dp[a.length][b.length];\n return (2 * lcsLength) / (a.length + b.length);\n}\n\nfunction sampledSimilarity(a: string[], b: string[]): number {\n // Sample every Nth token and compare\n const sampleRate = Math.max(1, Math.floor(Math.min(a.length, b.length) / 100));\n const sampledA = a.filter((_, i) => i % sampleRate === 0);\n const sampledB = b.filter((_, i) => i % sampleRate === 0);\n\n let matches = 0;\n const bSet = new Set(sampledB);\n for (const t of sampledA) {\n if (bSet.has(t)) matches++;\n }\n\n return (2 * matches) / (sampledA.length + sampledB.length);\n}\n\nexport const duplicatesAnalyzer: Analyzer = {\n id: \"duplicates\",\n name: \"Code Duplication\",\n category: \"redundancy\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const allSequences: TokenSequence[] = [];\n\n for (const file of ctx.files) {\n if (!file.language) continue;\n const sequences = extractFunctionTokens(file.content, file.relativePath);\n allSequences.push(...sequences);\n }\n\n // Group by hash for fast comparison\n const hashGroups = new Map<number, TokenSequence[]>();\n for (const seq of allSequences) {\n if (!hashGroups.has(seq.hash)) hashGroups.set(seq.hash, []);\n hashGroups.get(seq.hash)!.push(seq);\n }\n\n // Check exact hash matches first\n const duplicatePairs: { a: TokenSequence; b: TokenSequence; similarity: number }[] = [];\n\n for (const [, group] of hashGroups) {\n if (group.length > 1) {\n for (let i = 0; i < group.length; i++) {\n for (let j = i + 1; j < group.length; j++) {\n if (group[i].file === group[j].file) continue;\n const sim = tokenSimilarity(group[i].tokens, group[j].tokens);\n if (sim >= 0.8) {\n duplicatePairs.push({ a: group[i], b: group[j], similarity: sim });\n }\n }\n }\n }\n }\n\n // Also compare across different hashes (slower, do pairwise for small sets)\n if (allSequences.length > 200) {\n findings.push({\n analyzerId: \"duplicates\",\n severity: \"info\",\n confidence: 0.3,\n message: `Cross-function duplicate detection limited to hash-based matching (${allSequences.length} functions exceeds the 200-function threshold for full comparison). Use --include to narrow scope for deeper analysis.`,\n locations: [],\n tags: [\"duplicates\", \"scalability\"],\n });\n }\n if (allSequences.length <= 200) {\n for (let i = 0; i < allSequences.length; i++) {\n for (let j = i + 1; j < allSequences.length; j++) {\n if (allSequences[i].file === allSequences[j].file) continue;\n if (allSequences[i].hash === allSequences[j].hash) continue; // already checked\n\n // Quick length filter\n const lenRatio = Math.min(allSequences[i].tokens.length, allSequences[j].tokens.length) /\n Math.max(allSequences[i].tokens.length, allSequences[j].tokens.length);\n if (lenRatio < 0.6) continue;\n\n const sim = tokenSimilarity(allSequences[i].tokens, allSequences[j].tokens);\n if (sim >= 0.7) {\n duplicatePairs.push({\n a: allSequences[i],\n b: allSequences[j],\n similarity: sim,\n });\n }\n }\n }\n }\n\n // Deduplicate pairs\n const seenPairs = new Set<string>();\n const uniquePairs = duplicatePairs.filter((p) => {\n const key = [p.a.file + \":\" + p.a.funcName, p.b.file + \":\" + p.b.funcName].sort().join(\"|\");\n if (seenPairs.has(key)) return false;\n seenPairs.add(key);\n return true;\n });\n\n if (uniquePairs.length > 0) {\n // Sort by similarity descending\n uniquePairs.sort((a, b) => b.similarity - a.similarity);\n\n findings.push({\n analyzerId: \"duplicates\",\n severity: uniquePairs.length > 5 ? \"error\" : \"warning\",\n confidence: 0.75,\n message: `${uniquePairs.length} pairs of duplicate/near-duplicate functions detected`,\n locations: uniquePairs.slice(0, 10).flatMap((p) => {\n const sim = Math.round(p.similarity * 100);\n // When names are identical, include file paths to disambiguate\n const aLabel = p.a.funcName === p.b.funcName\n ? `${p.a.file}:${p.a.funcName}()`\n : `${p.a.funcName}()`;\n const bLabel = p.b.funcName === p.a.funcName\n ? `${p.b.file}:${p.b.funcName}()`\n : `${p.b.funcName}()`;\n return [\n { file: p.a.file, line: p.a.line, snippet: `${aLabel} — ${sim}% similar to ${bLabel}` },\n { file: p.b.file, line: p.b.line, snippet: `${bLabel} — ${sim}% similar to ${aLabel}` },\n ];\n }),\n tags: [\"duplicates\", \"token-based\"],\n });\n }\n\n return findings;\n },\n};\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { densityPer1K, getLineNumber } from \"../utils/text.js\";\n\nconst TODO_PATTERN = /\\b(TODO|FIXME|HACK|XXX|TEMP)\\b/gi;\n\nexport const todoDensityAnalyzer: Analyzer = {\n id: \"todo-density\",\n name: \"TODO/FIXME Density\",\n category: \"redundancy\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n let totalCount = 0;\n const fileHits: { file: string; count: number; lines: number[] }[] = [];\n\n for (const file of ctx.files) {\n const matches = [...file.content.matchAll(TODO_PATTERN)];\n if (matches.length === 0) continue;\n totalCount += matches.length;\n const lines = matches.map((m) => getLineNumber(file.content, m.index!));\n fileHits.push({ file: file.relativePath, count: matches.length, lines });\n }\n\n if (totalCount === 0) return findings;\n\n const density = densityPer1K(totalCount, ctx.totalLines);\n\n if (density > 2) {\n findings.push({\n analyzerId: \"todo-density\",\n severity: density > 5 ? \"error\" : \"warning\",\n confidence: 1.0,\n message: `${totalCount} TODOs/FIXMEs across ${fileHits.length} files (density: ${density}/1K lines)`,\n locations: fileHits.map((h) => ({ file: h.file, line: h.lines[0] })),\n tags: [\"todo\", \"debt\"],\n });\n }\n\n for (const hit of fileHits) {\n if (hit.count >= 3) {\n findings.push({\n analyzerId: \"todo-density\",\n severity: \"info\",\n confidence: 1.0,\n message: `${hit.count} TODOs clustered in ${hit.file}`,\n locations: hit.lines.map((l) => ({ file: hit.file, line: l })),\n tags: [\"todo\", \"cluster\"],\n });\n }\n }\n\n return findings;\n },\n};\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\nconst ENV_PATTERNS = [\n /process\\.env\\.(\\w+)/g,\n /import\\.meta\\.env\\.(\\w+)/g,\n /os\\.environ(?:\\.get)?\\(\\s*['\"](\\w+)['\"]/g,\n /os\\.Getenv\\(\\s*\"(\\w+)\"\\s*\\)/g, // Go\n /env::var\\(\\s*\"(\\w+)\"\\s*\\)/g, // Rust\n];\n\nexport const configDriftAnalyzer: Analyzer = {\n id: \"config-drift\",\n name: \"Config Drift\",\n category: \"dependencyHealth\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const envUsages = new Map<string, { file: string; line: number }[]>();\n\n for (const file of ctx.files) {\n for (const pattern of ENV_PATTERNS) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const varName = match[1];\n if (!envUsages.has(varName)) envUsages.set(varName, []);\n envUsages.get(varName)!.push({\n file: file.relativePath,\n line: getLineNumber(file.content, match.index),\n });\n }\n }\n }\n\n if (envUsages.size === 0) return findings;\n\n if (ctx.envExample) {\n const undocumented: string[] = [];\n for (const [varName, locations] of envUsages) {\n if (!ctx.envExample.has(varName) && !varName.startsWith(\"NODE_\") && varName !== \"NODE_ENV\") {\n undocumented.push(varName);\n findings.push({\n analyzerId: \"config-drift\",\n severity: \"warning\",\n confidence: 0.85,\n message: `Env var ${varName} used in code but missing from .env.example`,\n locations,\n tags: [\"config\", \"env\"],\n });\n }\n }\n if (undocumented.length > 0) {\n findings.push({\n analyzerId: \"config-drift\",\n severity: \"warning\",\n confidence: 0.85,\n message: `${undocumented.length} env vars used in code but missing from .env.example`,\n locations: [],\n tags: [\"config\", \"summary\"],\n });\n }\n } else if (envUsages.size > 3) {\n findings.push({\n analyzerId: \"config-drift\",\n severity: \"info\",\n confidence: 0.7,\n message: `${envUsages.size} env vars used but no .env.example file found`,\n locations: [],\n tags: [\"config\", \"missing-example\"],\n });\n }\n\n return findings;\n },\n};\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding, FileLocation, SupportedLanguage } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\ninterface SecurityPattern {\n id: string;\n name: string;\n pattern: RegExp;\n severity: \"info\" | \"warning\" | \"error\";\n confidence: number;\n message: string;\n languages: SupportedLanguage[] | \"all\";\n tags: string[];\n // If provided, a second regex that must NOT match on the same line (reduces false positives)\n negativeFilter?: RegExp;\n // If provided, the pattern is only flagged when the surrounding ±5 lines\n // contain at least one match for this regex (security context proximity check)\n contextRequired?: RegExp;\n}\n\nconst SECURITY_PATTERNS: SecurityPattern[] = [\n // === Hardcoded Secrets ===\n {\n id: \"hardcoded-api-key\",\n name: \"Hardcoded API key\",\n pattern: /(?:api[_-]?key|apikey|api[_-]?secret)\\s*[:=]\\s*['\"][A-Za-z0-9_\\-]{16,}['\"]/gi,\n severity: \"error\",\n confidence: 0.85,\n message: \"Potential hardcoded API key\",\n languages: \"all\",\n tags: [\"security\", \"secrets\"],\n negativeFilter: /(?:example|placeholder|your[_-]|xxx|test|dummy|fake|sample)/i,\n },\n {\n id: \"hardcoded-password\",\n name: \"Hardcoded password\",\n pattern: /(?:password|passwd|pwd)\\s*[:=]\\s*['\"][^'\"]{4,}['\"]/gi,\n severity: \"error\",\n confidence: 0.75,\n message: \"Potential hardcoded password\",\n languages: \"all\",\n tags: [\"security\", \"secrets\"],\n negativeFilter: /(?:example|placeholder|your[_-]|xxx|test|dummy|fake|sample|\\$\\{|process\\.env|os\\.environ|os\\.Getenv)/i,\n },\n {\n id: \"hardcoded-token\",\n name: \"Hardcoded token\",\n pattern: /(?:token|bearer|jwt|auth[_-]?token|access[_-]?token|secret[_-]?key)\\s*[:=]\\s*['\"][A-Za-z0-9_.\\-]{20,}['\"]/gi,\n severity: \"error\",\n confidence: 0.8,\n message: \"Potential hardcoded authentication token\",\n languages: \"all\",\n tags: [\"security\", \"secrets\"],\n negativeFilter: /(?:example|placeholder|your[_-]|xxx|test|dummy|fake|sample)/i,\n },\n {\n id: \"private-key\",\n name: \"Private key in source\",\n pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/g,\n severity: \"error\",\n confidence: 0.98,\n message: \"Private key embedded in source code\",\n languages: \"all\",\n tags: [\"security\", \"secrets\", \"critical\"],\n },\n {\n id: \"aws-key\",\n name: \"AWS access key\",\n pattern: /(?:AKIA|ASIA)[A-Z0-9]{16}/g,\n severity: \"error\",\n confidence: 0.95,\n message: \"AWS access key ID detected\",\n languages: \"all\",\n tags: [\"security\", \"secrets\", \"aws\"],\n },\n\n // === Injection Vulnerabilities ===\n {\n id: \"sql-injection\",\n name: \"SQL injection risk\",\n pattern: /(?:query|exec|execute|raw)\\s*\\(\\s*[`'\"](?:SELECT|INSERT|UPDATE|DELETE|DROP)\\b[^`'\"]*\\$\\{/gi,\n severity: \"error\",\n confidence: 0.8,\n message: \"Potential SQL injection: string interpolation in query\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"injection\", \"sql\"],\n },\n {\n id: \"sql-concat\",\n name: \"SQL concatenation\",\n pattern: /(?:query|exec|execute)\\s*\\(\\s*['\"](?:SELECT|INSERT|UPDATE|DELETE)\\b[^'\"]*['\"]\\s*\\+/gi,\n severity: \"error\",\n confidence: 0.85,\n message: \"Potential SQL injection: string concatenation in query\",\n languages: [\"javascript\", \"typescript\", \"python\"],\n tags: [\"security\", \"injection\", \"sql\"],\n },\n {\n id: \"go-sql-fmt\",\n name: \"Go SQL fmt injection\",\n pattern: /(?:db\\.(?:Query|Exec|QueryRow))\\s*\\(\\s*fmt\\.Sprintf\\s*\\(/g,\n severity: \"error\",\n confidence: 0.9,\n message: \"SQL injection risk: fmt.Sprintf used in database query\",\n languages: [\"go\"],\n tags: [\"security\", \"injection\", \"sql\"],\n },\n {\n id: \"command-injection\",\n name: \"Command injection\",\n pattern: /(?:exec|execSync|spawn|execFile)\\s*\\([^)]*\\+/g,\n severity: \"error\",\n confidence: 0.75,\n message: \"Potential command injection: dynamic value in shell execution\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"injection\", \"command\"],\n },\n {\n id: \"python-shell-injection\",\n name: \"Python shell injection\",\n pattern: /subprocess\\.(?:call|run|Popen)\\s*\\([^)]*shell\\s*=\\s*True/g,\n severity: \"error\",\n confidence: 0.85,\n message: \"Shell injection risk: subprocess with shell=True\",\n languages: [\"python\"],\n tags: [\"security\", \"injection\", \"command\"],\n },\n\n // === Unsafe Functions ===\n {\n id: \"eval-usage\",\n name: \"eval() usage\",\n pattern: /\\beval\\s*\\(/g,\n severity: \"error\",\n confidence: 0.9,\n message: \"Use of eval() — potential code injection vector\",\n languages: [\"javascript\", \"typescript\", \"python\"],\n tags: [\"security\", \"unsafe-function\"],\n negativeFilter: /(?:eslint|no-eval|# noqa)/i,\n },\n {\n id: \"function-constructor\",\n name: \"Function constructor\",\n pattern: /new\\s+Function\\s*\\(/g,\n severity: \"error\",\n confidence: 0.9,\n message: \"Use of Function constructor — equivalent to eval()\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"unsafe-function\"],\n },\n {\n id: \"innerHTML-assignment\",\n name: \"innerHTML assignment\",\n pattern: /\\.innerHTML\\s*=/g,\n severity: \"warning\",\n confidence: 0.7,\n message: \"Direct innerHTML assignment — potential XSS vector\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"xss\"],\n },\n {\n id: \"dangerously-set-html\",\n name: \"dangerouslySetInnerHTML\",\n pattern: /dangerouslySetInnerHTML/g,\n severity: \"warning\",\n confidence: 0.8,\n message: \"dangerouslySetInnerHTML used — ensure input is sanitized\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"xss\", \"react\"],\n },\n\n // === Insecure Crypto ===\n {\n id: \"weak-hash-md5\",\n name: \"MD5 hash usage\",\n pattern: /(?:createHash|hashlib\\.md5|md5\\.New|Md5::new)\\s*\\(\\s*['\"]?md5['\"]?\\s*\\)/gi,\n severity: \"warning\",\n confidence: 0.85,\n message: \"MD5 is cryptographically broken — use SHA-256 or better\",\n languages: \"all\",\n tags: [\"security\", \"crypto\"],\n },\n {\n id: \"weak-hash-sha1\",\n name: \"SHA1 hash usage\",\n pattern: /(?:createHash|hashlib\\.sha1|sha1\\.New|Sha1::new)\\s*\\(\\s*['\"]?sha1['\"]?\\s*\\)/gi,\n severity: \"warning\",\n confidence: 0.8,\n message: \"SHA-1 is deprecated for security — use SHA-256 or better\",\n languages: \"all\",\n tags: [\"security\", \"crypto\"],\n },\n {\n id: \"math-random-crypto\",\n name: \"Math.random for security\",\n pattern: /Math\\.random\\s*\\(\\)/g,\n severity: \"warning\",\n confidence: 0.5,\n message: \"Math.random() is not cryptographically secure — use crypto.randomUUID()\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"crypto\"],\n negativeFilter: /(?:test|mock|seed|shuffle|animation|color|position|offset|delay|jitter)/i,\n // Only flag near security-relevant code — UI shuffles/animations are not a risk\n contextRequired: /(?:token|secret|password|key|nonce|salt|hash|crypto|auth|session|jwt|api.?key|credential)/i,\n },\n\n // === Path Traversal ===\n {\n id: \"path-traversal\",\n name: \"Path traversal risk\",\n pattern: /(?:readFile|readFileSync|createReadStream|open)\\s*\\([^)]*\\+/g,\n severity: \"warning\",\n confidence: 0.6,\n message: \"Potential path traversal: dynamic value in file operation\",\n languages: [\"javascript\", \"typescript\"],\n tags: [\"security\", \"path-traversal\"],\n },\n\n // === SSRF ===\n {\n id: \"ssrf-risk\",\n name: \"SSRF risk\",\n pattern: /(?:fetch|axios\\.get|http\\.get|requests\\.get|httpClient)\\s*\\(\\s*(?:[`'\"].*\\$\\{|[^'\"]*\\+)/g,\n severity: \"info\",\n confidence: 0.4,\n message: \"URL constructed from variable — review if the source is user-controlled\",\n languages: \"all\",\n tags: [\"security\", \"ssrf\"],\n negativeFilter: /(?:API_URL|BASE_URL|apiUrl|baseUrl|base\\s*\\+|endpoint|config\\.|process\\.env)/i,\n },\n\n // === Python-specific ===\n {\n id: \"python-pickle\",\n name: \"Unsafe pickle.load\",\n pattern: /pickle\\.loads?\\s*\\(/g,\n severity: \"error\",\n confidence: 0.85,\n message: \"pickle.load can execute arbitrary code — use json or safer alternatives\",\n languages: [\"python\"],\n tags: [\"security\", \"deserialization\"],\n },\n {\n id: \"python-yaml-unsafe\",\n name: \"Unsafe YAML load\",\n pattern: /yaml\\.load\\s*\\([^)]*(?!\\bLoader\\b)/g,\n severity: \"error\",\n confidence: 0.8,\n message: \"yaml.load without SafeLoader can execute arbitrary code\",\n languages: [\"python\"],\n tags: [\"security\", \"deserialization\"],\n negativeFilter: /SafeLoader|FullLoader|BaseLoader/,\n },\n\n // === Go-specific ===\n {\n id: \"go-tls-skip-verify\",\n name: \"Go TLS skip verify\",\n pattern: /InsecureSkipVerify\\s*:\\s*true/g,\n severity: \"error\",\n confidence: 0.95,\n message: \"TLS certificate verification disabled\",\n languages: [\"go\"],\n tags: [\"security\", \"tls\"],\n },\n\n // === Rust-specific ===\n {\n id: \"rust-unsafe\",\n name: \"Rust unsafe blocks\",\n pattern: /\\bunsafe\\s*\\{/g,\n severity: \"warning\",\n confidence: 0.7,\n message: \"Unsafe block — ensure memory safety invariants are upheld\",\n languages: [\"rust\"],\n tags: [\"security\", \"memory-safety\"],\n },\n];\n\nexport const securityAnalyzer: Analyzer = {\n id: \"security\",\n name: \"Security Posture\",\n category: \"securityPosture\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const projectLanguages = [...ctx.languageBreakdown.keys()];\n\n // Skip matches inside pattern definitions (regex literals, analyzer\n // config objects). Prevents the security analyzer from flagging its\n // own detection pattern strings.\n const PATTERN_DEF = /(?:pattern\\s*:|regex\\s*:|RegExp\\s*\\(|name\\s*:|message\\s*:|id\\s*:|label\\s*:)/;\n\n for (const file of ctx.files) {\n // Skip test fixture files — they contain intentionally insecure code\n if (/(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\\\]/i.test(file.relativePath)) continue;\n\n for (const pattern of SECURITY_PATTERNS) {\n if (pattern.languages !== \"all\") {\n if (!file.language || !pattern.languages.includes(file.language)) continue;\n }\n\n const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const lineStart = file.content.lastIndexOf(\"\\n\", match.index) + 1;\n const lineEnd = file.content.indexOf(\"\\n\", match.index);\n const line = file.content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd);\n\n // Skip matches inside pattern/config definitions\n if (PATTERN_DEF.test(line)) continue;\n\n // Apply negative filter\n if (pattern.negativeFilter) {\n if (pattern.negativeFilter.test(line)) continue;\n }\n\n // Context proximity check: only flag if surrounding ±5 lines\n // contain security-relevant keywords\n if (pattern.contextRequired) {\n const lines = file.content.split(\"\\n\");\n const matchLine = file.content.slice(0, match.index).split(\"\\n\").length - 1;\n const start = Math.max(0, matchLine - 5);\n const end = Math.min(lines.length, matchLine + 6);\n const context = lines.slice(start, end).join(\"\\n\");\n if (!pattern.contextRequired.test(context)) continue;\n }\n\n const lineNum = getLineNumber(file.content, match.index);\n const snippet = line.trim();\n\n findings.push({\n analyzerId: \"security\",\n severity: pattern.severity,\n confidence: pattern.confidence,\n message: `${pattern.message} in ${file.relativePath}:${lineNum}`,\n locations: [{\n file: file.relativePath,\n line: lineNum,\n snippet: snippet.length > 120 ? snippet.slice(0, 120) + \"...\" : snippet,\n }],\n tags: pattern.tags,\n });\n }\n }\n }\n\n // Deduplicate similar findings in the same file\n return deduplicateFindings(findings);\n },\n};\n\nfunction deduplicateFindings(findings: Finding[]): Finding[] {\n const seen = new Map<string, Finding>();\n for (const f of findings) {\n const key = `${f.locations[0]?.file}:${f.locations[0]?.line}:${f.tags.join(\",\")}`;\n const existing = seen.get(key);\n if (!existing || f.confidence > existing.confidence) {\n seen.set(key, f);\n }\n }\n return [...seen.values()];\n}\n","/**\n * Cyclomatic complexity analyzer.\n *\n * Computes per-function cyclomatic complexity using AST decision-node counting\n * (when tree-sitter is available) or regex-based pattern matching as fallback.\n * Flags individual functions exceeding complexity 10/20 and warns if the\n * project-wide average exceeds 8.\n */\n\nimport type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding, SyntaxNode } from \"../core/types.js\";\n\n// Cyclomatic complexity: M = E - N + 2P\n// Simplified: start at 1, add 1 for each decision point\n\n// Decision-point node types per language\nconst DECISION_NODES: Record<string, Set<string>> = {\n javascript: new Set([\n \"if_statement\", \"else_clause\", \"for_statement\", \"for_in_statement\",\n \"while_statement\", \"do_statement\", \"switch_case\", \"catch_clause\",\n \"ternary_expression\", \"binary_expression\", // && and || counted below\n ]),\n typescript: new Set([\n \"if_statement\", \"else_clause\", \"for_statement\", \"for_in_statement\",\n \"while_statement\", \"do_statement\", \"switch_case\", \"catch_clause\",\n \"ternary_expression\", \"binary_expression\",\n ]),\n python: new Set([\n \"if_statement\", \"elif_clause\", \"for_statement\", \"while_statement\",\n \"except_clause\", \"conditional_expression\", \"boolean_operator\",\n \"list_comprehension\", \"dictionary_comprehension\", \"set_comprehension\",\n ]),\n go: new Set([\n \"if_statement\", \"for_statement\", \"expression_case\", \"type_case\",\n \"select_statement\", \"communication_case\",\n ]),\n rust: new Set([\n \"if_expression\", \"for_expression\", \"while_expression\", \"loop_expression\",\n \"match_arm\", \"if_let_expression\", \"while_let_expression\",\n ]),\n};\n\nconst LOGICAL_OPS = new Set([\"&&\", \"||\", \"and\", \"or\"]);\n\ninterface FunctionInfo {\n name: string;\n file: string;\n line: number;\n complexity: number;\n lineCount: number;\n}\n\nfunction computeComplexityAST(node: SyntaxNode, language: string): number {\n let complexity = 1; // base complexity\n const decisionNodes = DECISION_NODES[language] ?? DECISION_NODES[\"javascript\"];\n\n function walk(n: SyntaxNode) {\n if (decisionNodes.has(n.type)) {\n // binary_expression includes arithmetic — only && / || / and / or add branches\n if (n.type === \"binary_expression\" || n.type === \"boolean_operator\") {\n const op = n.childForFieldName(\"operator\");\n if (op && LOGICAL_OPS.has(op.text)) {\n complexity++;\n }\n } else {\n complexity++;\n }\n }\n for (let i = 0; i < n.childCount; i++) {\n walk(n.child(i)!);\n }\n }\n\n walk(node);\n return complexity;\n}\n\n// Strip comments so the regex fallback doesn't count && / || inside comments\nfunction stripComments(code: string): string {\n return code\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\") // multi-line /* ... */\n .replace(/\\/\\/.*$/gm, \"\") // single-line //\n .replace(/#.*$/gm, \"\"); // single-line # (Python)\n}\n\n// Regex fallback: count decision points in source text\nfunction computeComplexityRegex(content: string): number {\n const stripped = stripComments(content);\n let complexity = 1;\n const patterns = [\n /\\bif\\s*\\(/g, /\\belse\\s+if\\b/g, /\\belif\\b/g,\n /\\bfor\\s*\\(/g, /\\bfor\\s+\\w/g, // for-in, for range\n /\\bwhile\\s*\\(/g, /\\bwhile\\s+/g,\n /\\bcase\\s+/g,\n /\\bcatch\\s*\\(/g, /\\bexcept\\s/g,\n /\\?\\s*[^?:]+\\s*:/g, // ternary\n /\\s&&\\s/g, /\\s\\|\\|\\s/g,\n /\\band\\b/g, /\\bor\\b/g,\n ];\n\n for (const p of patterns) {\n const regex = new RegExp(p.source, p.flags);\n const matches = stripped.match(regex);\n if (matches) complexity += matches.length;\n }\n\n return complexity;\n}\n\nfunction extractFunctions(node: SyntaxNode, file: string, language: string): FunctionInfo[] {\n const functions: FunctionInfo[] = [];\n const functionTypes = new Set([\n \"function_declaration\", \"method_definition\", \"arrow_function\",\n \"function_definition\", \"method_declaration\", // Python, Go\n \"function_item\", \"impl_item\", // Rust\n ]);\n\n function walk(n: SyntaxNode) {\n if (functionTypes.has(n.type)) {\n const nameNode = n.childForFieldName(\"name\");\n const name = nameNode?.text ?? \"(anonymous)\";\n const startLine = n.startPosition.row + 1;\n const lineCount = n.endPosition.row - n.startPosition.row + 1;\n const complexity = computeComplexityAST(n, language);\n\n functions.push({ name, file, line: startLine, complexity, lineCount });\n }\n for (let i = 0; i < n.childCount; i++) {\n walk(n.child(i)!);\n }\n }\n\n walk(node);\n return functions;\n}\n\n// Regex-based function extraction fallback\nfunction extractFunctionsRegex(content: string, file: string): FunctionInfo[] {\n const functionPattern = /(?:(?:async\\s+)?function\\s+(\\w+)|(?:const|let|var)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?(?:\\([^)]*\\)|[a-zA-Z_]\\w*)\\s*=>|def\\s+(\\w+)|func\\s+(\\w+)|fn\\s+(\\w+))/g;\n\n // First pass: collect all function start positions\n const starts: { name: string; index: number; line: number }[] = [];\n let match;\n while ((match = functionPattern.exec(content)) !== null) {\n const name = match[1] || match[2] || match[3] || match[4] || match[5];\n const line = content.slice(0, match.index).split(\"\\n\").length;\n starts.push({ name, index: match.index, line });\n }\n\n // Second pass: slice between consecutive starts to approximate each body,\n // then run the regex complexity counter on each slice\n const functions: FunctionInfo[] = [];\n for (let i = 0; i < starts.length; i++) {\n const start = starts[i];\n const bodyEnd = i + 1 < starts.length ? starts[i + 1].index : content.length;\n const body = content.slice(start.index, bodyEnd);\n const complexity = computeComplexityRegex(body);\n const lineCount = body.split(\"\\n\").length;\n functions.push({ name: start.name, file, line: start.line, complexity, lineCount });\n }\n\n return functions;\n}\n\nexport const complexityAnalyzer: Analyzer = {\n id: \"complexity\",\n name: \"Code Complexity\",\n category: \"intentClarity\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n const allFunctions: FunctionInfo[] = [];\n\n for (const file of ctx.files) {\n if (!file.language) continue;\n const fns = file.tree\n ? extractFunctions(file.tree.rootNode, file.relativePath, file.language)\n : extractFunctionsRegex(file.content, file.relativePath);\n allFunctions.push(...fns);\n }\n\n // Flag individual high-complexity functions.\n //\n // Three tiers with graduated severity and confidence:\n // CC >20 → error (conf 0.9) — too complex, needs decomposition\n // CC 16-20 → warning (conf 0.75) — worth attention, moderate penalty\n // CC 11-15 → info (conf 0.5) — normal for real-world multi-language\n // handlers; barely penalizes the score\n //\n // Rationale: CC=12 is the natural complexity of a function handling\n // 3 languages with a couple of error paths. Penalizing it as heavily\n // as CC=19 doesn't reflect real quality differences.\n for (const fn of allFunctions) {\n if (fn.complexity > 20) {\n findings.push({\n analyzerId: \"complexity\",\n severity: \"error\",\n confidence: 0.9,\n message: `Function \"${fn.name}\" has cyclomatic complexity ${fn.complexity} (threshold: 20)`,\n locations: [{\n file: fn.file, line: fn.line,\n snippet: `${fn.name}() — ${fn.lineCount} lines, complexity ${fn.complexity}`,\n }],\n tags: [\"complexity\", \"critical\"],\n });\n } else if (fn.complexity > 15) {\n findings.push({\n analyzerId: \"complexity\",\n severity: \"warning\",\n confidence: 0.75,\n message: `Function \"${fn.name}\" has cyclomatic complexity ${fn.complexity} (threshold: 15)`,\n locations: [{\n file: fn.file, line: fn.line,\n snippet: `${fn.name}() — ${fn.lineCount} lines, complexity ${fn.complexity}`,\n }],\n tags: [\"complexity\", \"high\"],\n });\n } else if (fn.complexity > 10) {\n findings.push({\n analyzerId: \"complexity\",\n severity: \"info\",\n confidence: 0.5,\n message: `Function \"${fn.name}\" has cyclomatic complexity ${fn.complexity} (threshold: 10)`,\n locations: [{\n file: fn.file, line: fn.line,\n snippet: `${fn.name}() — ${fn.lineCount} lines, complexity ${fn.complexity}`,\n }],\n tags: [\"complexity\", \"moderate\"],\n });\n }\n }\n\n // Project-level complexity summary\n if (allFunctions.length > 0) {\n const avgComplexity = allFunctions.reduce((s, f) => s + f.complexity, 0) / allFunctions.length;\n if (avgComplexity > 8) {\n findings.push({\n analyzerId: \"complexity\",\n severity: \"warning\",\n confidence: 0.8,\n message: `High average complexity: ${avgComplexity.toFixed(1)} across ${allFunctions.length} functions`,\n locations: [],\n tags: [\"complexity\", \"average\"],\n });\n }\n }\n\n return findings;\n },\n};\n","/**\n * Intent clarity analyzer — measures how well code communicates its purpose.\n *\n * Runs four sub-checks: (1) commented-out code blocks that add noise,\n * (2) generic/unclear function names, (3) functions exceeding 50 lines that\n * likely do too much, and (4) low documentation density on large files and\n * undocumented public exports.\n */\n\nimport type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\n// Detect commented-out code blocks (not documentation comments)\nconst CODE_COMMENT_PATTERNS = [\n // JS/TS/Go/Rust: // or /* ... */ containing code-like syntax\n /\\/\\/\\s*(?:const|let|var|function|return|if|for|import|export|class)\\s/g,\n /\\/\\/\\s*\\w+\\s*[=(]/g,\n // Python: # followed by code-like syntax\n /#\\s*(?:def|class|import|return|if|for|while|try|except)\\s/g,\n /#\\s*\\w+\\s*[=(]/g,\n];\n\n// Multi-line commented-out code (3+ consecutive comment lines with code patterns)\nconst MULTI_LINE_COMMENT_CODE = /(?:^[ \\t]*\\/\\/.*(?:\\{|;|=|return|const|let|var|function)\\s*$\\n?){3,}/gm;\nconst MULTI_LINE_COMMENT_CODE_PY = /(?:^[ \\t]*#.*(?::|=|return|def|class|import)\\s*$\\n?){3,}/gm;\n\n// Generic / unclear naming patterns\nconst GENERIC_NAMES = new Set([\n \"data\", \"temp\", \"tmp\", \"val\", \"value\", \"item\", \"obj\", \"thing\",\n \"foo\", \"bar\", \"baz\", \"test\", \"handle\", \"process\", \"do\", \"run\",\n \"manager\", \"helper\", \"utils\", \"misc\",\n]);\n\nconst SHORT_NAME_MIN = 3;\n\nexport const intentClarityAnalyzer: Analyzer = {\n id: \"intent-clarity\",\n name: \"Intent Clarity\",\n category: \"intentClarity\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n findings.push(...detectCommentedOutCode(ctx));\n findings.push(...detectUnclearNaming(ctx));\n findings.push(...detectLongFunctions(ctx));\n findings.push(...detectLowDocumentation(ctx));\n\n return findings;\n },\n};\n\nfunction detectCommentedOutCode(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n let totalBlocks = 0;\n const blockLocations: { file: string; line: number; snippet: string }[] = [];\n\n for (const file of ctx.files) {\n // Multi-line commented code blocks\n const pattern = file.language === \"python\"\n ? MULTI_LINE_COMMENT_CODE_PY\n : MULTI_LINE_COMMENT_CODE;\n\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n totalBlocks++;\n const line = getLineNumber(file.content, match.index);\n const lines = match[0].trim().split(\"\\n\");\n blockLocations.push({\n file: file.relativePath,\n line,\n snippet: lines[0].trim().slice(0, 80) + (lines.length > 1 ? ` (+${lines.length - 1} lines)` : \"\"),\n });\n }\n }\n\n if (totalBlocks > 0) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: totalBlocks > 10 ? \"error\" : totalBlocks > 3 ? \"warning\" : \"info\",\n confidence: 0.7,\n message: `${totalBlocks} blocks of commented-out code found`,\n locations: blockLocations.slice(0, 15),\n tags: [\"intent\", \"commented-code\"],\n });\n }\n\n return findings;\n}\n\nfunction detectUnclearNaming(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const funcNamePatterns = [\n /(?:function|const|let|var)\\s+(\\w+)\\s*(?:=\\s*(?:async\\s+)?(?:\\(|function)|\\()/g,\n /def\\s+(\\w+)\\s*\\(/g,\n /func\\s+(\\w+)\\s*\\(/g,\n /fn\\s+(\\w+)\\s*[(<]/g,\n ];\n\n const genericFunctions: { name: string; file: string; line: number }[] = [];\n const shortFunctions: { name: string; file: string; line: number }[] = [];\n\n for (const file of ctx.files) {\n for (const pattern of funcNamePatterns) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const name = match[1];\n const line = getLineNumber(file.content, match.index);\n\n if (name.length < SHORT_NAME_MIN && ![\"go\", \"fn\", \"ok\", \"id\"].includes(name)) {\n shortFunctions.push({ name, file: file.relativePath, line });\n }\n\n const lowerName = name.toLowerCase();\n if (GENERIC_NAMES.has(lowerName)) {\n genericFunctions.push({ name, file: file.relativePath, line });\n }\n }\n }\n }\n\n if (genericFunctions.length > 3) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: \"warning\",\n confidence: 0.65,\n message: `${genericFunctions.length} functions with generic/unclear names (${[...new Set(genericFunctions.map((f) => f.name))].slice(0, 5).join(\", \")})`,\n locations: genericFunctions.slice(0, 10).map((f) => ({\n file: f.file,\n line: f.line,\n snippet: `function ${f.name}(...)`,\n })),\n tags: [\"intent\", \"naming\"],\n });\n }\n\n if (shortFunctions.length > 5) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: \"info\",\n confidence: 0.5,\n message: `${shortFunctions.length} functions with very short names (<${SHORT_NAME_MIN} chars)`,\n locations: shortFunctions.slice(0, 10).map((f) => ({\n file: f.file,\n line: f.line,\n })),\n tags: [\"intent\", \"naming\", \"short\"],\n });\n }\n\n return findings;\n}\n\nfunction detectLongFunctions(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n\n // Heuristic: detect functions longer than 50 lines\n // We look for function starts and measure to next function or end\n const functionStarts = [\n /^(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)/gm,\n /^def\\s+(\\w+)/gm,\n /^func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)/gm,\n /^(?:pub\\s+)?(?:async\\s+)?fn\\s+(\\w+)/gm,\n ];\n\n const longFunctions: { name: string; file: string; line: number; lines: number }[] = [];\n const LONG_THRESHOLD = 50;\n\n for (const file of ctx.files) {\n const lineOffsets: number[] = [];\n let offset = 0;\n for (const line of file.content.split(\"\\n\")) {\n lineOffsets.push(offset);\n offset += line.length + 1;\n }\n\n const starts: { name: string; offset: number; line: number }[] = [];\n\n for (const pattern of functionStarts) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n starts.push({\n name: match[1],\n offset: match.index,\n line: getLineNumber(file.content, match.index),\n });\n }\n }\n\n starts.sort((a, b) => a.offset - b.offset);\n\n // Approximate each function's length by measuring from its start to the\n // next function's start (or EOF). Imprecise but avoids needing an AST.\n for (let i = 0; i < starts.length; i++) {\n const start = starts[i];\n const endOffset = i + 1 < starts.length ? starts[i + 1].offset : file.content.length;\n const body = file.content.slice(start.offset, endOffset);\n const lineCount = body.split(\"\\n\").length;\n\n if (lineCount > LONG_THRESHOLD) {\n longFunctions.push({\n name: start.name,\n file: file.relativePath,\n line: start.line,\n lines: lineCount,\n });\n }\n }\n }\n\n if (longFunctions.length > 0) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: longFunctions.some((f) => f.lines > 100) ? \"error\" : \"warning\",\n confidence: 0.85,\n message: `${longFunctions.length} functions exceed ${LONG_THRESHOLD} lines`,\n locations: longFunctions.slice(0, 10).map((f) => ({\n file: f.file,\n line: f.line,\n snippet: `${f.name}() — ${f.lines} lines`,\n })),\n tags: [\"intent\", \"long-function\"],\n });\n }\n\n return findings;\n}\n\nfunction countFileCommentDensity(file: { content: string; lineCount: number }): {\n lines: number;\n commentLines: number;\n density: number;\n} {\n const lines = file.content.split(\"\\n\");\n let commentLines = 0;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (\n trimmed.startsWith(\"//\") || trimmed.startsWith(\"#\") ||\n trimmed.startsWith(\"/*\") || trimmed.startsWith(\"*\") ||\n trimmed.startsWith(\"///\") || trimmed.startsWith('\"\"\"')\n ) {\n commentLines++;\n }\n }\n\n return {\n lines: file.lineCount,\n commentLines,\n density: commentLines / file.lineCount,\n };\n}\n\nfunction findUndocumentedExports(\n files: { content: string; language: string | null; relativePath: string }[],\n): { file: string; name: string; line: number }[] {\n const undocumentedExports: { file: string; name: string; line: number }[] = [];\n\n for (const file of files) {\n if (!file.language) continue;\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let exportedName: string | null = null;\n\n if (file.language === \"go\") {\n const m = line.match(/^func\\s+(?:\\([^)]*\\)\\s+)?([A-Z]\\w+)\\s*\\(/);\n if (m) exportedName = m[1];\n } else if (file.language === \"python\") {\n const m = line.match(/^def\\s+(\\w+)\\s*\\(/);\n if (m && !m[1].startsWith(\"_\")) exportedName = m[1];\n } else if (file.language === \"rust\") {\n const m = line.match(/^pub\\s+(?:async\\s+)?fn\\s+(\\w+)/);\n if (m) exportedName = m[1];\n }\n\n if (!exportedName) continue;\n\n const prevLine = i > 0 ? lines[i - 1].trim() : \"\";\n const hasDoc = prevLine.startsWith(\"//\") || prevLine.startsWith(\"///\") ||\n prevLine.startsWith(\"/*\") || prevLine.startsWith('\"\"\"') ||\n prevLine.startsWith(\"#\");\n\n if (!hasDoc) {\n undocumentedExports.push({ file: file.relativePath, name: exportedName, line: i + 1 });\n }\n }\n }\n\n return undocumentedExports;\n}\n\nfunction detectLowDocumentation(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n\n const underdocumented: { file: string; lines: number; commentRatio: number }[] = [];\n\n for (const file of ctx.files) {\n if (file.lineCount < 100) continue;\n\n const { density } = countFileCommentDensity(file);\n\n // 5% is a pragmatic floor — below this, even experienced developers\n // struggle to understand intent without reading every line\n if (density < 0.05) {\n underdocumented.push({\n file: file.relativePath,\n lines: file.lineCount,\n commentRatio: Math.round(density * 100),\n });\n }\n }\n\n if (underdocumented.length > 2) {\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: underdocumented.length > 5 ? \"warning\" : \"info\",\n confidence: 0.6,\n message: `${underdocumented.length} files over 100 lines have <5% comment density — intent may be unclear to maintainers`,\n locations: underdocumented.slice(0, 10).map((f) => ({\n file: f.file,\n snippet: `${f.lines} lines, ${f.commentRatio}% comments`,\n })),\n tags: [\"intent\", \"documentation\"],\n });\n }\n\n const undocumentedExports = findUndocumentedExports(ctx.files);\n\n if (undocumentedExports.length > 10) {\n const ratio = ctx.files.length > 0\n ? Math.round((undocumentedExports.length / ctx.files.length) * 10) / 10\n : 0;\n findings.push({\n analyzerId: \"intent-clarity\",\n severity: undocumentedExports.length > 30 ? \"warning\" : \"info\",\n confidence: 0.55,\n message: `${undocumentedExports.length} exported functions lack documentation (~${ratio} per file)`,\n locations: undocumentedExports.slice(0, 10).map((e) => ({\n file: e.file,\n line: e.line,\n snippet: `${e.name}() — no doc comment`,\n })),\n tags: [\"intent\", \"undocumented\"],\n });\n }\n\n return findings;\n}\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\n\n// Entry point filenames that should not be flagged\nconst ENTRY_POINTS = new Set([\n \"index\", \"main\", \"app\", \"server\", \"mod\", \"lib\", \"init\", \"__init__\",\n \"setup\", \"config\", \"routes\", \"handler\", \"handlers\",\n]);\n\ninterface ExportedSymbol {\n name: string;\n file: string;\n line: number;\n isDefault: boolean;\n}\n\ninterface ImportedSymbol {\n name: string;\n source: string; // the import path\n importingFile: string;\n}\n\nconst EXPORT_PATTERNS = [\n // JS/TS named exports\n /export\\s+(?:async\\s+)?(?:function|class|const|let|var|type|interface|enum)\\s+(\\w+)/g,\n // JS/TS export { name }\n /export\\s*\\{([^}]+)\\}/g,\n];\n\nconst DEFAULT_EXPORT_PATTERN = /export\\s+default\\s+(?:(?:async\\s+)?(?:function|class)\\s+(\\w+)|(\\w+))/g;\n\nconst IMPORT_PATTERNS_JS = [\n // import { name } from 'path'\n /import\\s*\\{([^}]+)\\}\\s*from\\s*['\"]([^'\"]+)['\"]/g,\n // import name from 'path'\n /import\\s+(\\w+)\\s+from\\s*['\"]([^'\"]+)['\"]/g,\n // import * as name from 'path'\n /import\\s*\\*\\s*as\\s+(\\w+)\\s+from\\s*['\"]([^'\"]+)['\"]/g,\n // const { name } = require('path')\n /(?:const|let|var)\\s*\\{([^}]+)\\}\\s*=\\s*require\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g,\n // const name = require('path')\n /(?:const|let|var)\\s+(\\w+)\\s*=\\s*require\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g,\n];\n\n// Go exports: capitalized functions/types\nconst GO_EXPORT_PATTERN = /^(?:func|type|var|const)\\s+([A-Z]\\w+)/gm;\nconst GO_USAGE_PATTERN = /\\b([A-Z]\\w+)\\b/g;\n\n// Python: functions at module level\nconst PYTHON_DEF_PATTERN = /^def\\s+(\\w+)/gm;\nconst PYTHON_IMPORT_PATTERN = /from\\s+\\.\\w*\\s+import\\s+(.+)/g;\n\nfunction isEntryPoint(filePath: string): boolean {\n const base = filePath.split(\"/\").pop()?.replace(/\\.[^.]+$/, \"\") ?? \"\";\n return ENTRY_POINTS.has(base);\n}\n\nexport const deadCodeAnalyzer: Analyzer = {\n id: \"dead-code\",\n name: \"Dead Code Detection\",\n category: \"redundancy\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n const jsFiles = ctx.files.filter(\n (f) => f.language === \"javascript\" || f.language === \"typescript\",\n );\n const goFiles = ctx.files.filter((f) => f.language === \"go\");\n const pyFiles = ctx.files.filter((f) => f.language === \"python\");\n\n if (jsFiles.length > 0) {\n findings.push(...analyzeJsDeadExports(jsFiles));\n }\n if (goFiles.length > 0) {\n findings.push(...analyzeGoDeadExports(goFiles));\n }\n if (pyFiles.length > 0) {\n findings.push(...analyzePythonDeadCode(pyFiles));\n }\n\n // Unreachable code after return/throw (all languages)\n findings.push(...detectUnreachableCode(ctx));\n\n return findings;\n },\n};\n\nfunction buildExportMap(files: any[]): ExportedSymbol[] {\n const exports: ExportedSymbol[] = [];\n for (const file of files) {\n if (isEntryPoint(file.relativePath)) continue;\n\n // Named exports\n for (const pattern of EXPORT_PATTERNS) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const captured = match[1];\n if (captured.includes(\",\")) {\n for (const name of captured.split(\",\")) {\n const trimmed = name.trim().split(/\\s+as\\s+/)[0].trim();\n if (trimmed) {\n exports.push({\n name: trimmed,\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n isDefault: false,\n });\n }\n }\n } else {\n exports.push({\n name: captured,\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n isDefault: false,\n });\n }\n }\n }\n\n // Default exports\n {\n const regex = new RegExp(DEFAULT_EXPORT_PATTERN.source, DEFAULT_EXPORT_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const name = match[1] || match[2];\n if (name) {\n exports.push({\n name,\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n isDefault: true,\n });\n }\n }\n }\n }\n\n return exports;\n}\n\nfunction buildImportSet(files: any[]): Set<string> {\n const importedNames = new Set<string>();\n for (const file of files) {\n for (const pattern of IMPORT_PATTERNS_JS) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const names = match[1];\n if (names.includes(\",\") || names.includes(\"{\")) {\n for (const n of names.split(\",\")) {\n const trimmed = n.trim().split(/\\s+as\\s+/)[0].trim().replace(/[{}]/g, \"\");\n if (trimmed) importedNames.add(trimmed);\n }\n } else {\n importedNames.add(names.trim());\n }\n }\n }\n }\n\n return importedNames;\n}\n\nfunction identifyDeadExports(\n exports: ExportedSymbol[],\n importedNames: Set<string>,\n allContent: string,\n): ExportedSymbol[] {\n // Track default import usage — files that import defaults reference the export indirectly\n // \"import Foo from './bar'\" means bar's default export is used\n // We track this by marking any file that HAS a default import as having its default used\n\n // Also check for usage via string matching (handles re-exports, dynamic usage)\n return exports.filter(\n (e) => !importedNames.has(e.name) && countOccurrences(allContent, e.name) <= 1,\n );\n}\n\nfunction analyzeJsDeadExports(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n const exports = buildExportMap(files);\n const importedNames = buildImportSet(files);\n const allContent = files.map((f: any) => f.content).join(\"\\n\");\n const deadExports = identifyDeadExports(exports, importedNames, allContent);\n\n if (deadExports.length > 3) {\n findings.push({\n analyzerId: \"dead-code\",\n severity: deadExports.length > 10 ? \"error\" : \"warning\",\n confidence: 0.6,\n message: `${deadExports.length} exported symbols appear unused: ${deadExports.slice(0, 5).map((e) => e.name).join(\", \")}${deadExports.length > 5 ? \"...\" : \"\"}`,\n locations: deadExports.slice(0, 15).map((e) => ({\n file: e.file,\n line: e.line,\n snippet: `export ${e.name}`,\n })),\n tags: [\"dead-code\", \"unused-export\"],\n });\n }\n\n return findings;\n}\n\nfunction analyzeGoDeadExports(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n // In Go, exported = capitalized. Collect all exports.\n const exports: { name: string; file: string; line: number }[] = [];\n for (const file of files) {\n if (isEntryPoint(file.relativePath)) continue;\n const regex = new RegExp(GO_EXPORT_PATTERN.source, GO_EXPORT_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n exports.push({\n name: match[1],\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n });\n }\n }\n\n // Count usage across all files\n const allContent = files.map((f: any) => f.content).join(\"\\n\");\n const deadExports = exports.filter(\n (e) => countOccurrences(allContent, e.name) <= 1,\n );\n\n if (deadExports.length > 3) {\n findings.push({\n analyzerId: \"dead-code\",\n severity: \"warning\",\n confidence: 0.55,\n message: `${deadExports.length} Go exported symbols appear unused: ${deadExports.slice(0, 5).map((e) => e.name).join(\", \")}${deadExports.length > 5 ? \"...\" : \"\"}`,\n locations: deadExports.slice(0, 10).map((e) => ({\n file: e.file,\n line: e.line,\n })),\n tags: [\"dead-code\", \"unused-export\", \"go\"],\n });\n }\n\n return findings;\n}\n\nfunction analyzePythonDeadCode(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n const defs: { name: string; file: string; line: number }[] = [];\n for (const file of files) {\n if (isEntryPoint(file.relativePath)) continue;\n const regex = new RegExp(PYTHON_DEF_PATTERN.source, PYTHON_DEF_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const name = match[1];\n if (name.startsWith(\"_\")) continue; // private\n defs.push({\n name,\n file: file.relativePath,\n line: file.content.slice(0, match.index).split(\"\\n\").length,\n });\n }\n }\n\n const allContent = files.map((f: any) => f.content).join(\"\\n\");\n const dead = defs.filter((d) => countOccurrences(allContent, d.name) <= 1);\n\n if (dead.length > 3) {\n findings.push({\n analyzerId: \"dead-code\",\n severity: \"warning\",\n confidence: 0.5,\n message: `${dead.length} Python functions appear unused: ${dead.slice(0, 5).map((d) => d.name).join(\", \")}${dead.length > 5 ? \"...\" : \"\"}`,\n locations: dead.slice(0, 10).map((d) => ({ file: d.file, line: d.line })),\n tags: [\"dead-code\", \"unused-def\", \"python\"],\n });\n }\n\n return findings;\n}\n\nfunction detectUnreachableCode(ctx: AnalysisContext): Finding[] {\n const findings: Finding[] = [];\n const unreachableLocations: { file: string; line: number; snippet: string }[] = [];\n\n // Pattern: return/throw/break/continue followed by non-closing-brace code on next line\n const UNREACHABLE_PATTERN = /^(\\s*)(?:return\\b|throw\\b|break\\b|continue\\b).*;?\\s*$\\n(?!\\s*\\}|\\s*$|\\s*\\/\\/|\\s*case\\b|\\s*default\\b|\\s*else\\b|\\s*catch\\b|\\s*finally\\b)(\\s*)(\\S.+)$/gm;\n\n for (const file of ctx.files) {\n const regex = new RegExp(UNREACHABLE_PATTERN.source, UNREACHABLE_PATTERN.flags);\n let match;\n while ((match = regex.exec(file.content)) !== null) {\n const returnIndent = match[1].length;\n const nextIndent = match[2].length;\n // Only flag if next line has same or deeper indentation\n if (nextIndent >= returnIndent) {\n const line = file.content.slice(0, match.index).split(\"\\n\").length + 1;\n unreachableLocations.push({\n file: file.relativePath,\n line: line + 1,\n snippet: match[3].trim().slice(0, 60),\n });\n }\n }\n }\n\n if (unreachableLocations.length > 0) {\n findings.push({\n analyzerId: \"dead-code\",\n severity: \"warning\",\n confidence: 0.65,\n message: `${unreachableLocations.length} potentially unreachable code blocks after return/throw`,\n locations: unreachableLocations.slice(0, 10),\n tags: [\"dead-code\", \"unreachable\"],\n });\n }\n\n return findings;\n}\n\nfunction countOccurrences(text: string, word: string): number {\n const regex = new RegExp(`\\\\b${escapeRegex(word)}\\\\b`, \"g\");\n const matches = text.match(regex);\n return matches ? matches.length : 0;\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import type { Analyzer } from \"./base.js\";\nimport type { AnalysisContext, Finding } from \"../core/types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\nexport const languageSpecificAnalyzer: Analyzer = {\n id: \"language-specific\",\n name: \"Language-Specific Patterns\",\n category: \"architecturalConsistency\",\n requiresAST: false,\n applicableLanguages: \"all\",\n\n async analyze(ctx: AnalysisContext): Promise<Finding[]> {\n const findings: Finding[] = [];\n\n const goFiles = ctx.files.filter((f) => f.language === \"go\");\n const pyFiles = ctx.files.filter((f) => f.language === \"python\");\n const rsFiles = ctx.files.filter((f) => f.language === \"rust\");\n\n if (goFiles.length > 0) findings.push(...analyzeGo(goFiles));\n if (pyFiles.length > 0) findings.push(...analyzePython(pyFiles));\n if (rsFiles.length > 0) findings.push(...analyzeRust(rsFiles));\n\n return findings;\n },\n};\n\n// ===== Go Analysis =====\n\nfunction detectGoUncheckedErrors(\n files: any[],\n): { count: number; locations: { file: string; line: number; snippet: string }[] } {\n let count = 0;\n const locations: { file: string; line: number; snippet: string }[] = [];\n\n for (const file of files) {\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n\n // Unchecked error: line assigns to err (or _) but next non-blank line doesn't check it\n if (/\\berr\\s*[:=]/.test(trimmed) && !trimmed.startsWith(\"//\")) {\n // Look at the next non-empty, non-comment line\n let nextLine = \"\";\n for (let j = i + 1; j < Math.min(i + 4, lines.length); j++) {\n const next = lines[j].trim();\n if (next && !next.startsWith(\"//\")) {\n nextLine = next;\n break;\n }\n }\n if (nextLine && !nextLine.includes(\"err\") && !nextLine.startsWith(\"return\")) {\n count++;\n locations.push({\n file: file.relativePath,\n line: i + 1,\n snippet: trimmed.slice(0, 80),\n });\n }\n }\n }\n }\n\n return { count, locations };\n}\n\nfunction detectGoNakedGoroutines(\n files: any[],\n): { count: number; locations: { file: string; line: number }[] } {\n let count = 0;\n const locations: { file: string; line: number }[] = [];\n\n for (const file of files) {\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Goroutine: go func() without context.Context in nearby scope\n if (/^\\s*go\\s+func\\s*\\(/.test(line) || /^\\s*go\\s+\\w+\\s*\\(/.test(line)) {\n // Check if context is passed (heuristic: \"ctx\" in the go call or surrounding 3 lines)\n const nearby = lines.slice(Math.max(0, i - 2), i + 3).join(\" \");\n if (!/\\bctx\\b/.test(nearby) && !/context\\./.test(nearby)) {\n count++;\n locations.push({ file: file.relativePath, line: i + 1 });\n }\n }\n }\n }\n\n return { count, locations };\n}\n\nfunction detectGoUnsafeMutex(\n files: any[],\n): { count: number; locations: { file: string; line: number }[] } {\n let count = 0;\n const locations: { file: string; line: number }[] = [];\n\n for (const file of files) {\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n\n // Mutex: .Lock() without defer .Unlock() within next 3 lines\n if (/\\.Lock\\(\\)/.test(trimmed)) {\n const nextLines = lines.slice(i + 1, i + 4).join(\" \");\n if (!/defer\\s+.*\\.Unlock\\(\\)/.test(nextLines) && !/\\.Unlock\\(\\)/.test(trimmed)) {\n count++;\n locations.push({ file: file.relativePath, line: i + 1 });\n }\n }\n }\n }\n\n return { count, locations };\n}\n\nfunction analyzeGo(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n const uncheckedErrors = detectGoUncheckedErrors(files);\n const nakedGoroutines = detectGoNakedGoroutines(files);\n const unsafeMutex = detectGoUnsafeMutex(files);\n\n if (uncheckedErrors.count > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: uncheckedErrors.count > 10 ? \"error\" : \"warning\",\n confidence: 0.7,\n message: `${uncheckedErrors.count} potentially unchecked errors in Go code`,\n locations: uncheckedErrors.locations.slice(0, 10),\n tags: [\"go\", \"error-handling\", \"unchecked-error\"],\n });\n }\n\n if (nakedGoroutines.count > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: \"warning\",\n confidence: 0.6,\n message: `${nakedGoroutines.count} goroutines launched without context — potential leak risk`,\n locations: nakedGoroutines.locations.slice(0, 10),\n tags: [\"go\", \"goroutine\", \"leak\"],\n });\n }\n\n if (unsafeMutex.count > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: \"warning\",\n confidence: 0.75,\n message: `${unsafeMutex.count} mutex locks without defer Unlock — risk of deadlock`,\n locations: unsafeMutex.locations.slice(0, 10),\n tags: [\"go\", \"mutex\", \"concurrency\"],\n });\n }\n\n return findings;\n}\n\n// ===== Python Analysis =====\n\nfunction analyzePython(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n let bareExcepts = 0;\n const bareExceptLocations: { file: string; line: number }[] = [];\n\n let mutableDefaults = 0;\n const mutableDefaultLocations: { file: string; line: number; snippet: string }[] = [];\n\n for (const file of files) {\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n\n // Bare except (catches everything including SystemExit, KeyboardInterrupt)\n if (/^except\\s*:/.test(trimmed)) {\n bareExcepts++;\n bareExceptLocations.push({ file: file.relativePath, line: i + 1 });\n }\n\n // Mutable default arguments\n if (/^def\\s+\\w+\\s*\\(/.test(trimmed)) {\n // Check for mutable defaults: list=[], dict={}, set()\n if (/=\\s*\\[\\s*\\]|=\\s*\\{\\s*\\}|=\\s*set\\s*\\(\\s*\\)/.test(trimmed)) {\n mutableDefaults++;\n mutableDefaultLocations.push({\n file: file.relativePath,\n line: i + 1,\n snippet: trimmed.slice(0, 80),\n });\n }\n }\n }\n }\n\n if (bareExcepts > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: \"error\",\n confidence: 0.95,\n message: `${bareExcepts} bare except clauses — catches SystemExit and KeyboardInterrupt`,\n locations: bareExceptLocations.slice(0, 10),\n tags: [\"python\", \"error-handling\", \"bare-except\"],\n });\n }\n\n if (mutableDefaults > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: \"warning\",\n confidence: 0.9,\n message: `${mutableDefaults} functions with mutable default arguments`,\n locations: mutableDefaultLocations.slice(0, 10),\n tags: [\"python\", \"mutable-default\"],\n });\n }\n\n return findings;\n}\n\n// ===== Rust Analysis =====\n\nfunction analyzeRust(files: any[]): Finding[] {\n const findings: Finding[] = [];\n\n let unwrapCount = 0;\n const unwrapLocations: { file: string; line: number; snippet: string }[] = [];\n\n let unsafeCount = 0;\n const unsafeLocations: { file: string; line: number }[] = [];\n\n for (const file of files) {\n // Count .unwrap() calls\n const unwrapPattern = /\\.unwrap\\(\\)/g;\n let match;\n while ((match = unwrapPattern.exec(file.content)) !== null) {\n unwrapCount++;\n const line = getLineNumber(file.content, match.index);\n const lineStart = file.content.lastIndexOf(\"\\n\", match.index) + 1;\n const lineEnd = file.content.indexOf(\"\\n\", match.index);\n const snippet = file.content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd).trim();\n unwrapLocations.push({\n file: file.relativePath,\n line,\n snippet: snippet.slice(0, 80),\n });\n }\n\n // Count unsafe blocks\n const unsafePattern = /\\bunsafe\\s*\\{/g;\n while ((match = unsafePattern.exec(file.content)) !== null) {\n unsafeCount++;\n unsafeLocations.push({\n file: file.relativePath,\n line: getLineNumber(file.content, match.index),\n });\n }\n }\n\n if (unwrapCount > 2) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: unwrapCount > 20 ? \"error\" : \"warning\",\n confidence: 0.8,\n message: `${unwrapCount} .unwrap() calls — consider using ? operator or expect() with context`,\n locations: unwrapLocations.slice(0, 10),\n tags: [\"rust\", \"unwrap\", \"error-handling\"],\n });\n }\n\n if (unsafeCount > 0) {\n findings.push({\n analyzerId: \"language-specific\",\n severity: unsafeCount > 5 ? \"error\" : \"warning\",\n confidence: 0.85,\n message: `${unsafeCount} unsafe blocks in Rust code`,\n locations: unsafeLocations.slice(0, 10),\n tags: [\"rust\", \"unsafe\"],\n });\n }\n\n return findings;\n}\n","import type { AnalysisContext, Finding } from \"../core/types.js\";\nimport type { DriftContext, DriftFinding, DriftDetector, DriftCategory } from \"./types.js\";\nimport { DRIFT_WEIGHTS } from \"./types.js\";\nimport { architecturalContradiction } from \"./architectural-contradiction.js\";\nimport { conventionOscillation } from \"./convention-oscillation.js\";\nimport { securityConsistency } from \"./security-consistency.js\";\nimport { semanticDuplication } from \"./semantic-duplication.js\";\nimport { phantomScaffolding } from \"./phantom-scaffolding.js\";\n\nexport function createDriftDetectors(): DriftDetector[] {\n return [\n architecturalContradiction,\n conventionOscillation,\n securityConsistency,\n semanticDuplication,\n phantomScaffolding,\n ];\n}\n\nexport function buildDriftContext(ctx: AnalysisContext): DriftContext {\n return {\n files: ctx.files.map((f) => ({\n path: f.relativePath,\n language: f.language,\n content: f.content,\n lineCount: f.lineCount,\n })),\n totalLines: ctx.totalLines,\n dominantLanguage: ctx.dominantLanguage,\n };\n}\n\nexport interface DriftScores {\n architectural_consistency: { score: number; maxScore: number; findings: number };\n security_posture: { score: number; maxScore: number; findings: number };\n semantic_duplication: { score: number; maxScore: number; findings: number };\n naming_conventions: { score: number; maxScore: number; findings: number };\n phantom_scaffolding: { score: number; maxScore: number; findings: number };\n composite: number; // 0-100 weighted score\n grade: string; // A-F\n}\n\nexport function runDriftDetection(ctx: AnalysisContext): {\n findings: Finding[];\n driftFindings: DriftFinding[];\n driftScores: DriftScores;\n} {\n const driftCtx = buildDriftContext(ctx);\n const detectors = createDriftDetectors();\n const allDrift: DriftFinding[] = [];\n\n for (const detector of detectors) {\n const driftFindings = detector.detect(driftCtx);\n allDrift.push(...driftFindings);\n }\n\n // Compute drift-specific scores\n const driftScores = computeDriftScores(allDrift);\n\n // Convert to standard Finding format for the existing pipeline\n const findings = allDrift.map(driftFindingToFinding);\n\n return { findings, driftFindings: allDrift, driftScores };\n}\n\nfunction computeDriftScores(findings: DriftFinding[]): DriftScores {\n const categories: DriftCategory[] = [\n \"architectural_consistency\",\n \"security_posture\",\n \"semantic_duplication\",\n \"naming_conventions\",\n \"phantom_scaffolding\",\n ];\n\n const scores: Record<string, { score: number; maxScore: number; findings: number }> = {};\n\n for (const cat of categories) {\n const catFindings = findings.filter((f) => f.driftCategory === cat);\n const weight = DRIFT_WEIGHTS[cat];\n\n if (catFindings.length === 0) {\n scores[cat] = { score: weight, maxScore: weight, findings: 0 };\n continue;\n }\n\n // Use consistency scores from findings\n // Average consistency score of all findings in this category\n const avgConsistency = catFindings.reduce((sum, f) => sum + f.consistencyScore, 0) / catFindings.length;\n\n // Scale: consistency 100% = full score, consistency 50% = half score\n // But also penalize by severity: errors reduce score more\n let severityPenalty = 0;\n for (const f of catFindings) {\n if (f.severity === \"error\") severityPenalty += 3;\n else if (f.severity === \"warning\") severityPenalty += 1.5;\n else severityPenalty += 0.5;\n }\n\n // Base score from consistency, reduced by severity penalty\n const rawScore = (avgConsistency / 100) * weight;\n const penalty = Math.min(rawScore, severityPenalty * (weight / 20));\n const score = Math.max(0, Math.round((rawScore - penalty) * 10) / 10);\n\n scores[cat] = { score, maxScore: weight, findings: catFindings.length };\n }\n\n // Composite: sum of all category scores\n const composite = Math.round(\n Object.values(scores).reduce((sum, s) => sum + s.score, 0) * 10,\n ) / 10;\n\n // Grade\n let grade: string;\n // Must match the canonical thresholds used by html.ts, docx.ts, scan.ts,\n // and ml-client/summarize.ts: A≥90, B≥75, C≥50, D≥25, F<25.\n if (composite >= 90) grade = \"A\";\n else if (composite >= 75) grade = \"B\";\n else if (composite >= 50) grade = \"C\";\n else if (composite >= 25) grade = \"D\";\n else grade = \"F\";\n\n return {\n ...(scores as any),\n composite,\n grade,\n };\n}\n\nfunction driftFindingToFinding(d: DriftFinding): Finding {\n return {\n analyzerId: `drift-${d.detector}`,\n severity: d.severity,\n confidence: d.confidence,\n message: `DRIFT: ${d.finding}`,\n locations: d.deviatingFiles.slice(0, 15).map((df) => ({\n file: df.path,\n line: df.evidence[0]?.line,\n snippet: df.evidence[0]?.code ?? df.detectedPattern,\n })),\n tags: [\"drift\", d.driftCategory, \"cross-file\"],\n };\n}\n","import type { Finding } from \"../core/types.js\";\n\nexport interface DriftDetector {\n id: string;\n name: string;\n category: DriftCategory;\n detect(ctx: DriftContext): DriftFinding[];\n}\n\nexport type DriftCategory =\n | \"architectural_consistency\"\n | \"security_posture\"\n | \"semantic_duplication\"\n | \"naming_conventions\"\n | \"phantom_scaffolding\";\n\nexport const DRIFT_WEIGHTS: Record<DriftCategory, number> = {\n architectural_consistency: 25,\n security_posture: 25,\n semantic_duplication: 20,\n naming_conventions: 15,\n phantom_scaffolding: 15,\n};\n\nexport interface DriftContext {\n files: DriftFile[];\n totalLines: number;\n dominantLanguage: string | null;\n}\n\nexport interface DriftFile {\n path: string;\n language: string | null;\n content: string;\n lineCount: number;\n}\n\nexport interface Evidence {\n line: number;\n code: string;\n}\n\nexport interface DeviatingFile {\n path: string;\n detectedPattern: string;\n evidence: Evidence[];\n}\n\nexport interface DriftFinding {\n detector: string;\n subCategory?: string;\n driftCategory: DriftCategory;\n severity: \"info\" | \"warning\" | \"error\";\n confidence: number;\n finding: string;\n dominantPattern: string;\n dominantCount: number;\n totalRelevantFiles: number;\n consistencyScore: number; // 0-100: (dominant/total)*100\n deviatingFiles: DeviatingFile[];\n recommendation: string;\n}\n","import type { DriftDetector, DriftContext, DriftFinding, DriftFile, Evidence, DeviatingFile } from \"./types.js\";\nimport { getLineNumber } from \"../utils/text.js\";\n\ntype DataAccessPattern = \"repository\" | \"raw_sql\" | \"orm\" | \"direct_db\" | \"http_client\" | \"in_memory\";\ntype ErrorHandlingPattern = \"wrap_with_context\" | \"raw_propagation\" | \"swallow\" | \"http_error_response\" | \"exception_throw\" | \"result_type\";\ntype ConfigPattern = \"env_direct\" | \"config_struct_di\" | \"hardcoded\" | \"mixed\";\ntype DIPattern = \"constructor_injection\" | \"global_import\" | \"service_locator\" | \"no_di\";\n\ninterface FileArchProfile {\n file: string;\n language: string;\n dataAccess: { pattern: DataAccessPattern; evidence: Evidence[] }[];\n errorHandling: { pattern: ErrorHandlingPattern; evidence: Evidence[] }[];\n config: { pattern: ConfigPattern; evidence: Evidence[] }[];\n di: { pattern: DIPattern; evidence: Evidence[] }[];\n}\n\n\nfunction getLineContent(content: string, lineNum: number): string {\n return (content.split(\"\\n\")[lineNum - 1] ?? \"\").trim();\n}\n\nfunction extractEvidence(content: string, pattern: RegExp, maxResults = 3): Evidence[] {\n const evidence: Evidence[] = [];\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(content)) !== null && evidence.length < maxResults) {\n const line = getLineNumber(content, match.index);\n evidence.push({ line, code: getLineContent(content, line) });\n }\n return evidence;\n}\n\nfunction isHandlerOrController(path: string): boolean {\n return /(?:handler|controller|route|endpoint|view|api|resource|page|action)/i.test(path)\n && !/(?:repository|repo|store|dal|model|query|migration|test|spec|mock)/i.test(path);\n}\n\n// --- Data Access Pattern Detection ---\n\nfunction detectDataAccess(file: DriftFile): { pattern: DataAccessPattern; evidence: Evidence[] }[] {\n const results: { pattern: DataAccessPattern; evidence: Evidence[] }[] = [];\n const c = file.content;\n\n // Repository pattern\n const repoEvidence = extractEvidence(c, /\\b(?:store|repo|repository)\\.\\w+\\s*\\(/g);\n if (repoEvidence.length > 0) results.push({ pattern: \"repository\", evidence: repoEvidence });\n\n // Raw SQL\n const sqlEvidence = extractEvidence(c, /(?:SELECT|INSERT|UPDATE|DELETE)\\s+(?:FROM|INTO|SET|\\*)\\b/gi);\n if (sqlEvidence.length > 0 && !isRepoFile(file.path)) {\n results.push({ pattern: \"raw_sql\", evidence: sqlEvidence });\n }\n\n // ORM\n const ormPatterns = /\\.(?:Where|Find|Create|Save|Delete|First|Preload|findOne|findMany|findAll|objects\\.filter)\\s*\\(/g;\n const ormEvidence = extractEvidence(c, ormPatterns);\n if (ormEvidence.length > 0) results.push({ pattern: \"orm\", evidence: ormEvidence });\n\n // Direct DB\n const dbEvidence = extractEvidence(c, /\\b(?:db|pool|client)\\.\\s*(?:Query|Exec|QueryRow|query|execute|raw)\\s*\\(/g);\n if (dbEvidence.length > 0 && !isRepoFile(file.path)) {\n results.push({ pattern: \"direct_db\", evidence: dbEvidence });\n }\n\n // HTTP client calls in business logic (not in dedicated service layer)\n const httpEvidence = extractEvidence(c, /\\b(?:fetch|axios|http\\.(?:Get|Post|Put)|requests\\.(?:get|post))\\s*\\(/g);\n if (httpEvidence.length > 0 && isHandlerOrController(file.path)) {\n results.push({ pattern: \"http_client\", evidence: httpEvidence });\n }\n\n return results;\n}\n\nfunction isRepoFile(path: string): boolean {\n return /(?:repository|repo|store|dal|model|query)/i.test(path);\n}\n\n// --- Error Handling Pattern Detection ---\n\nfunction detectErrorHandling(file: DriftFile): { pattern: ErrorHandlingPattern; evidence: Evidence[] }[] {\n const results: { pattern: ErrorHandlingPattern; evidence: Evidence[] }[] = [];\n const c = file.content;\n\n if (file.language === \"go\") {\n const wrapEvidence = extractEvidence(c, /fmt\\.Errorf\\([^)]*%w/g);\n if (wrapEvidence.length > 0) results.push({ pattern: \"wrap_with_context\", evidence: wrapEvidence });\n\n const rawEvidence = extractEvidence(c, /return\\s+(?:\\w+,\\s*)?err\\b/g);\n if (rawEvidence.length > 0) results.push({ pattern: \"raw_propagation\", evidence: rawEvidence });\n\n const swallowEvidence = extractEvidence(c, /\\b_\\s*=\\s*\\w+\\.\\w+\\(/g);\n if (swallowEvidence.length > 0) results.push({ pattern: \"swallow\", evidence: swallowEvidence });\n\n const httpErrEvidence = extractEvidence(c, /echo\\.NewHTTPError|http\\.Error|c\\.JSON\\(\\s*http\\.Status/g);\n if (httpErrEvidence.length > 0) results.push({ pattern: \"http_error_response\", evidence: httpErrEvidence });\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n const wrapEvidence = extractEvidence(c, /new\\s+(?:\\w+)?Error\\([^)]*\\+|throw\\s+new\\s+\\w*Error\\(/g);\n if (wrapEvidence.length > 0) results.push({ pattern: \"wrap_with_context\", evidence: wrapEvidence });\n\n const swallowEvidence = extractEvidence(c, /catch\\s*\\([^)]*\\)\\s*\\{\\s*(?:\\/\\/.*\\n\\s*)?(?:console\\.(?:log|warn)|logger\\.\\w+)[^}]*\\}/g);\n if (swallowEvidence.length > 0) results.push({ pattern: \"swallow\", evidence: swallowEvidence });\n\n const httpErrEvidence = extractEvidence(c, /res\\.status\\(\\d+\\)\\.json|\\.json\\(\\s*\\{[^}]*error/g);\n if (httpErrEvidence.length > 0) results.push({ pattern: \"http_error_response\", evidence: httpErrEvidence });\n\n const resultEvidence = extractEvidence(c, /Result<|Either<|\\.ok\\(|\\.err\\(/g);\n if (resultEvidence.length > 0) results.push({ pattern: \"result_type\", evidence: resultEvidence });\n } else if (file.language === \"python\") {\n const swallowEvidence = extractEvidence(c, /except[^:]*:\\s*\\n\\s*(?:pass|\\.\\.\\.)\\b/g);\n if (swallowEvidence.length > 0) results.push({ pattern: \"swallow\", evidence: swallowEvidence });\n\n const raiseEvidence = extractEvidence(c, /raise\\s+\\w+/g);\n if (raiseEvidence.length > 0) results.push({ pattern: \"exception_throw\", evidence: raiseEvidence });\n }\n\n return results;\n}\n\n// --- Config Pattern Detection ---\n\nfunction detectConfigPattern(file: DriftFile): { pattern: ConfigPattern; evidence: Evidence[] }[] {\n const results: { pattern: ConfigPattern; evidence: Evidence[] }[] = [];\n const c = file.content;\n\n const envEvidence = extractEvidence(c, /(?:process\\.env\\.\\w+|os\\.Getenv\\(|os\\.environ|import\\.meta\\.env\\.\\w+|env::var\\()/g);\n if (envEvidence.length > 0) results.push({ pattern: \"env_direct\", evidence: envEvidence });\n\n const configDI = extractEvidence(c, /\\b(?:cfg|config|settings)\\.\\w+/g);\n if (configDI.length > 0) results.push({ pattern: \"config_struct_di\", evidence: configDI });\n\n return results;\n}\n\n// --- DI Pattern Detection ---\n\nfunction detectDIPattern(file: DriftFile): { pattern: DIPattern; evidence: Evidence[] }[] {\n const results: { pattern: DIPattern; evidence: Evidence[] }[] = [];\n const c = file.content;\n\n if (file.language === \"go\") {\n const constructorEvidence = extractEvidence(c, /func\\s+New\\w+\\s*\\([^)]*\\)\\s*\\*/g);\n if (constructorEvidence.length > 0) results.push({ pattern: \"constructor_injection\", evidence: constructorEvidence });\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n const constructorEvidence = extractEvidence(c, /constructor\\s*\\([^)]*(?:private|readonly|public)\\s+\\w+/g);\n if (constructorEvidence.length > 0) results.push({ pattern: \"constructor_injection\", evidence: constructorEvidence });\n\n const factoryEvidence = extractEvidence(c, /(?:create|make|build)\\w+\\s*\\([^)]*(?:store|repo|service|client)/g);\n if (factoryEvidence.length > 0) results.push({ pattern: \"constructor_injection\", evidence: factoryEvidence });\n }\n\n return results;\n}\n\nfunction buildProfile(file: DriftFile): FileArchProfile | null {\n if (!file.language || !isHandlerOrController(file.path)) return null;\n\n const dataAccess = detectDataAccess(file);\n const errorHandling = detectErrorHandling(file);\n const config = detectConfigPattern(file);\n const di = detectDIPattern(file);\n\n // Only include files that have meaningful patterns\n if (dataAccess.length === 0 && errorHandling.length === 0) return null;\n\n return { file: file.path, language: file.language, dataAccess, errorHandling, config, di };\n}\n\nfunction detectFilePattern<T extends string>(\n patterns: { pattern: T; evidence: Evidence[] }[],\n): T | null {\n // Use the primary (most common) pattern per file\n const fileCounts = new Map<T, number>();\n for (const { pattern } of patterns) {\n fileCounts.set(pattern, (fileCounts.get(pattern) ?? 0) + 1);\n }\n let primaryPattern: T | null = null;\n let maxCount = 0;\n for (const [pat, count] of fileCounts) {\n if (count > maxCount) { maxCount = count; primaryPattern = pat; }\n }\n return primaryPattern;\n}\n\nfunction buildPatternDistribution<T extends string>(\n profiles: { file: string; patterns: { pattern: T; evidence: Evidence[] }[] }[],\n): Map<T, { count: number; files: string[] }> {\n const counts = new Map<T, { count: number; files: string[] }>();\n\n for (const p of profiles) {\n const primaryPattern = detectFilePattern(p.patterns);\n if (!primaryPattern) continue;\n\n if (!counts.has(primaryPattern)) counts.set(primaryPattern, { count: 0, files: [] });\n const entry = counts.get(primaryPattern)!;\n entry.count++;\n entry.files.push(p.file);\n }\n\n return counts;\n}\n\nfunction collectDeviatingFiles<T extends string>(\n counts: Map<T, { count: number; files: string[] }>,\n dominant: T,\n profiles: { file: string; patterns: { pattern: T; evidence: Evidence[] }[] }[],\n patternNames: Record<T, string>,\n): DeviatingFile[] {\n const deviating: DeviatingFile[] = [];\n for (const [pattern, data] of counts) {\n if (pattern === dominant) continue;\n for (const filePath of data.files) {\n const profile = profiles.find((p) => p.file === filePath);\n const evidence = profile?.patterns\n .filter((pp) => pp.pattern === pattern)\n .flatMap((pp) => pp.evidence) ?? [];\n deviating.push({\n path: filePath,\n detectedPattern: patternNames[pattern],\n evidence: evidence.slice(0, 3),\n });\n }\n }\n return deviating;\n}\n\nfunction findDominantPattern<T extends string>(\n counts: Map<T, { count: number; files: string[] }>,\n): { dominant: T; dominantCount: number } | null {\n let dominant: T | null = null;\n let dominantCount = 0;\n for (const [pattern, data] of counts) {\n if (data.count > dominantCount) { dominantCount = data.count; dominant = pattern; }\n }\n if (!dominant) return null;\n return { dominant, dominantCount };\n}\n\nfunction analyzePatternDistribution<T extends string>(\n profiles: { file: string; patterns: { pattern: T; evidence: Evidence[] }[] }[],\n patternNames: Record<T, string>,\n): DriftFinding | null {\n const counts = buildPatternDistribution(profiles);\n\n if (counts.size < 2) return null;\n\n const result = findDominantPattern(counts);\n if (!result) return null;\n\n const { dominant, dominantCount } = result;\n const totalFiles = profiles.length;\n const consistencyScore = Math.round((dominantCount / totalFiles) * 100);\n\n const deviating = collectDeviatingFiles(counts, dominant, profiles, patternNames);\n if (deviating.length === 0) return null;\n\n return {\n detector: \"architectural_consistency\",\n driftCategory: \"architectural_consistency\",\n severity: deviating.length >= 3 ? \"error\" : \"warning\",\n confidence: 0.85,\n finding: `${deviating.length} files use ${[...new Set(deviating.map((d) => d.detectedPattern))].join(\", \")} while ${dominantCount} use ${patternNames[dominant]}`,\n dominantPattern: patternNames[dominant],\n dominantCount,\n totalRelevantFiles: totalFiles,\n consistencyScore,\n deviatingFiles: deviating,\n recommendation: `${dominantCount} of ${totalFiles} files use ${patternNames[dominant]}. Migrate deviating files for consistency.`,\n };\n}\n\nconst DATA_ACCESS_NAMES: Record<DataAccessPattern, string> = {\n repository: \"repository pattern\",\n raw_sql: \"raw SQL queries\",\n orm: \"ORM methods\",\n direct_db: \"direct database calls\",\n http_client: \"inline HTTP client calls\",\n in_memory: \"in-memory data\",\n};\n\nconst ERROR_HANDLING_NAMES: Record<ErrorHandlingPattern, string> = {\n wrap_with_context: \"error wrapping with context\",\n raw_propagation: \"raw error propagation\",\n swallow: \"error swallowing\",\n http_error_response: \"direct HTTP error responses\",\n exception_throw: \"exception throwing\",\n result_type: \"Result/Either types\",\n};\n\nconst CONFIG_NAMES: Record<ConfigPattern, string> = {\n env_direct: \"direct env var access\",\n config_struct_di: \"config struct via DI\",\n hardcoded: \"hardcoded values\",\n mixed: \"mixed config approaches\",\n};\n\nconst DI_NAMES: Record<DIPattern, string> = {\n constructor_injection: \"constructor injection\",\n global_import: \"global singleton imports\",\n service_locator: \"service locator\",\n no_di: \"no dependency injection\",\n};\n\nexport const architecturalContradiction: DriftDetector = {\n id: \"architectural-contradiction\",\n name: \"Architectural Pattern Contradictions\",\n category: \"architectural_consistency\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n const findings: DriftFinding[] = [];\n const profiles: FileArchProfile[] = [];\n\n for (const file of ctx.files) {\n const p = buildProfile(file);\n if (p) profiles.push(p);\n }\n\n if (profiles.length < 2) return findings;\n\n // Analyze data access patterns\n const dataAccessProfiles = profiles\n .filter((p) => p.dataAccess.length > 0)\n .map((p) => ({ file: p.file, patterns: p.dataAccess }));\n const dataAccessFinding = analyzePatternDistribution(dataAccessProfiles, DATA_ACCESS_NAMES);\n if (dataAccessFinding) {\n dataAccessFinding.subCategory = \"data_access\";\n findings.push(dataAccessFinding);\n }\n\n // Analyze error handling patterns\n const errorProfiles = profiles\n .filter((p) => p.errorHandling.length > 0)\n .map((p) => ({ file: p.file, patterns: p.errorHandling }));\n const errorFinding = analyzePatternDistribution(errorProfiles, ERROR_HANDLING_NAMES);\n if (errorFinding) {\n errorFinding.subCategory = \"error_handling\";\n findings.push(errorFinding);\n }\n\n // Analyze config patterns (only in handler files, not config files)\n const configProfiles = profiles\n .filter((p) => p.config.length > 0)\n .map((p) => ({ file: p.file, patterns: p.config }));\n if (configProfiles.length >= 3) {\n const configFinding = analyzePatternDistribution(configProfiles, CONFIG_NAMES);\n if (configFinding) {\n configFinding.subCategory = \"configuration\";\n findings.push(configFinding);\n }\n }\n\n // Analyze DI patterns\n const diProfiles = profiles.map((p) => ({\n file: p.file,\n patterns: p.di.length > 0 ? p.di : [{ pattern: \"no_di\" as DIPattern, evidence: [] as Evidence[] }],\n }));\n if (diProfiles.length >= 3) {\n const diFinding = analyzePatternDistribution(diProfiles, DI_NAMES);\n if (diFinding) {\n diFinding.subCategory = \"dependency_injection\";\n findings.push(diFinding);\n }\n }\n\n return findings;\n },\n};\n","import type { DriftDetector, DriftContext, DriftFinding, DriftFile, DeviatingFile } from \"./types.js\";\n\ntype NamingConvention = \"camelCase\" | \"snake_case\" | \"PascalCase\" | \"SCREAMING_SNAKE\" | \"kebab-case\";\n\nfunction classifyName(name: string): NamingConvention | null {\n if (/^[A-Z][A-Z0-9_]+$/.test(name)) return \"SCREAMING_SNAKE\";\n if (/^[A-Z][a-zA-Z0-9]*$/.test(name)) return \"PascalCase\";\n if (/^[a-z][a-zA-Z0-9]*$/.test(name) && /[A-Z]/.test(name)) return \"camelCase\";\n if (/^[a-z][a-z0-9_]*$/.test(name) && name.includes(\"_\")) return \"snake_case\";\n if (/^[a-z][a-z0-9-]*$/.test(name) && name.includes(\"-\")) return \"kebab-case\";\n if (/^[a-z][a-z0-9]*$/.test(name)) return \"camelCase\"; // single-word lowercase = camelCase\n return null;\n}\n\n// Language-idiomatic exclusions: don't flag these as drift\n\nfunction isIdiomaticGo(name: string, convention: NamingConvention): boolean {\n if (convention === \"PascalCase\" && /^[A-Z]/.test(name)) return true;\n if (/^(?:HTTP|URL|ID|JSON|XML|SQL|API|DNS|TCP|UDP|IP|TLS|SSH|EOF)/.test(name)) return true;\n return false;\n}\n\nfunction isIdiomaticJsTs(name: string, convention: NamingConvention, symbolType: string): boolean {\n if (symbolType === \"class\" && convention === \"PascalCase\") return true;\n if (symbolType === \"function\" && convention === \"PascalCase\" && /^[A-Z]\\w*$/.test(name)) return true;\n return false;\n}\n\nfunction isIdiomaticPython(name: string, convention: NamingConvention, symbolType: string): boolean {\n if (symbolType === \"class\" && convention === \"PascalCase\") return true;\n if (name.startsWith(\"__\") && name.endsWith(\"__\")) return true;\n return false;\n}\n\nfunction isIdiomatic(name: string, convention: NamingConvention, symbolType: string, language: string): boolean {\n if (language === \"go\" && isIdiomaticGo(name, convention)) return true;\n if ((language === \"javascript\" || language === \"typescript\") && isIdiomaticJsTs(name, convention, symbolType)) return true;\n if (language === \"python\" && isIdiomaticPython(name, convention, symbolType)) return true;\n\n // Constants: SCREAMING_SNAKE is expected\n if (symbolType === \"constant\" && convention === \"SCREAMING_SNAKE\") return true;\n\n return false;\n}\n\ninterface SymbolInfo {\n name: string;\n convention: NamingConvention;\n symbolType: string;\n file: string;\n line: number;\n}\n\nfunction extractSymbols(file: DriftFile): SymbolInfo[] {\n const symbols: SymbolInfo[] = [];\n if (!file.language) return symbols;\n\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Functions\n const funcPatterns: { regex: RegExp; type: string }[] = [];\n if (file.language === \"go\") {\n funcPatterns.push({ regex: /func\\s+(?:\\([^)]*\\)\\s+)?(\\w+)\\s*\\(/g, type: \"function\" });\n } else if (file.language === \"python\") {\n funcPatterns.push({ regex: /def\\s+(\\w+)\\s*\\(/g, type: \"function\" });\n funcPatterns.push({ regex: /class\\s+(\\w+)/g, type: \"class\" });\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n funcPatterns.push({ regex: /(?:async\\s+)?function\\s+(\\w+)/g, type: \"function\" });\n funcPatterns.push({ regex: /(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?(?:\\([^)]*\\)|[a-zA-Z_]\\w*)\\s*=>/g, type: \"function\" });\n funcPatterns.push({ regex: /class\\s+(\\w+)/g, type: \"class\" });\n funcPatterns.push({ regex: /interface\\s+(\\w+)/g, type: \"type\" });\n funcPatterns.push({ regex: /type\\s+(\\w+)/g, type: \"type\" });\n }\n\n for (const { regex, type } of funcPatterns) {\n const r = new RegExp(regex.source, regex.flags);\n let m;\n while ((m = r.exec(line)) !== null) {\n const name = m[1];\n if (name.length <= 1) continue;\n const conv = classifyName(name);\n if (!conv) continue;\n\n // Skip idiomatic patterns\n if (isIdiomatic(name, conv, type, file.language)) continue;\n\n symbols.push({ name, convention: conv, symbolType: type, file: file.path, line: i + 1 });\n }\n }\n }\n\n return symbols;\n}\n\nfunction classifyBaseName(filePath: string): { basename: string; convention: NamingConvention } | null {\n const basename = filePath.split(\"/\").pop()?.replace(/\\.[^.]+$/, \"\") ?? \"\";\n if (basename.length <= 1) return null;\n // Skip test files, config files\n if (/(?:test|spec|config|setup|__)/i.test(basename)) return null;\n\n const convention = classifyName(basename);\n if (!convention) return null;\n\n return { basename, convention };\n}\n\nfunction findDominantConvention(\n fileNameConventions: Map<NamingConvention, string[]>,\n): { dominant: NamingConvention; maxCount: number; totalFiles: number } | null {\n let dominant: NamingConvention | null = null;\n let maxCount = 0;\n let totalFiles = 0;\n for (const [conv, files] of fileNameConventions) {\n totalFiles += files.length;\n if (files.length > maxCount) { maxCount = files.length; dominant = conv; }\n }\n\n if (!dominant || maxCount === totalFiles) return null;\n\n return { dominant, maxCount, totalFiles };\n}\n\n// Also analyze file naming conventions\nfunction analyzeFileNaming(files: DriftFile[]): DriftFinding | null {\n const fileNameConventions = new Map<NamingConvention, string[]>();\n\n for (const file of files) {\n const classified = classifyBaseName(file.path);\n if (!classified) continue;\n\n if (!fileNameConventions.has(classified.convention)) fileNameConventions.set(classified.convention, []);\n fileNameConventions.get(classified.convention)!.push(file.path);\n }\n\n if (fileNameConventions.size < 2) return null;\n\n const result = findDominantConvention(fileNameConventions);\n if (!result) return null;\n\n const { dominant, maxCount, totalFiles } = result;\n\n const deviating: DeviatingFile[] = [];\n for (const [conv, filePaths] of fileNameConventions) {\n if (conv === dominant) continue;\n for (const fp of filePaths) {\n deviating.push({ path: fp, detectedPattern: conv, evidence: [] });\n }\n }\n\n if (deviating.length < 2) return null;\n\n return {\n detector: \"naming_conventions\",\n subCategory: \"file_names\",\n driftCategory: \"naming_conventions\",\n severity: \"warning\",\n confidence: 0.75,\n finding: `File naming convention oscillates: ${dominant} dominant (${maxCount}/${totalFiles}), ${deviating.length} files deviate`,\n dominantPattern: dominant,\n dominantCount: maxCount,\n totalRelevantFiles: totalFiles,\n consistencyScore: Math.round((maxCount / totalFiles) * 100),\n deviatingFiles: deviating.slice(0, 10),\n recommendation: `Standardize file names to ${dominant}. ${deviating.length} files use a different convention.`,\n };\n}\n\nfunction collectDeviantFiles(\n convCounts: Map<NamingConvention, SymbolInfo[]>,\n dominant: NamingConvention,\n): DeviatingFile[] {\n const fileDeviants = new Map<string, SymbolInfo[]>();\n for (const [conv, syms] of convCounts) {\n if (conv === dominant) continue;\n for (const s of syms) {\n if (!fileDeviants.has(s.file)) fileDeviants.set(s.file, []);\n fileDeviants.get(s.file)!.push(s);\n }\n }\n\n const deviatingFiles: DeviatingFile[] = [];\n for (const [filePath, syms] of fileDeviants) {\n const uniqueConventions = [...new Set(syms.map((s) => s.convention))];\n deviatingFiles.push({\n path: filePath,\n detectedPattern: uniqueConventions.join(\", \"),\n evidence: syms.slice(0, 3).map((s) => ({ line: s.line, code: s.name })),\n });\n }\n return deviatingFiles;\n}\n\nfunction buildConventionFinding(\n type: string,\n dominant: NamingConvention,\n maxCount: number,\n totalSymbols: number,\n deviatingFiles: DeviatingFile[],\n): DriftFinding {\n const deviantCount = totalSymbols - maxCount;\n const consistencyScore = Math.round((maxCount / totalSymbols) * 100);\n return {\n detector: \"naming_conventions\",\n subCategory: `${type}_names`,\n driftCategory: \"naming_conventions\",\n severity: deviatingFiles.length > 5 ? \"error\" : \"warning\",\n confidence: 0.8,\n finding: `${type} naming convention oscillates: ${maxCount} use ${dominant}, ${deviantCount} use other conventions — likely from different AI sessions`,\n dominantPattern: dominant,\n dominantCount: maxCount,\n totalRelevantFiles: totalSymbols,\n consistencyScore,\n deviatingFiles: deviatingFiles.slice(0, 10),\n recommendation: `${maxCount} of ${totalSymbols} ${type} names use ${dominant}. Standardize deviating names.`,\n };\n}\n\nfunction analyzeSymbolTypeConventions(\n type: string,\n typeSymbols: SymbolInfo[],\n): DriftFinding | null {\n if (typeSymbols.length < 3) return null;\n\n const convCounts = new Map<NamingConvention, SymbolInfo[]>();\n for (const s of typeSymbols) {\n if (!convCounts.has(s.convention)) convCounts.set(s.convention, []);\n convCounts.get(s.convention)!.push(s);\n }\n\n if (convCounts.size < 2) return null;\n\n let dominant: NamingConvention | null = null;\n let maxCount = 0;\n for (const [conv, syms] of convCounts) {\n if (syms.length > maxCount) { maxCount = syms.length; dominant = conv; }\n }\n\n if (!dominant) return null;\n\n const totalSymbols = typeSymbols.length;\n const deviantCount = totalSymbols - maxCount;\n if (deviantCount < 3 || deviantCount / totalSymbols < 0.1) return null;\n\n const deviatingFiles = collectDeviantFiles(convCounts, dominant);\n if (deviatingFiles.length < 2) return null;\n\n return buildConventionFinding(type, dominant, maxCount, totalSymbols, deviatingFiles);\n}\n\nexport const conventionOscillation: DriftDetector = {\n id: \"convention-oscillation\",\n name: \"Naming Convention Oscillation\",\n category: \"naming_conventions\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n const findings: DriftFinding[] = [];\n\n const allSymbols: SymbolInfo[] = [];\n for (const file of ctx.files) {\n allSymbols.push(...extractSymbols(file));\n }\n\n if (allSymbols.length < 5) return findings;\n\n const symbolTypes = [...new Set(allSymbols.map((s) => s.symbolType))];\n\n for (const type of symbolTypes) {\n const typeSymbols = allSymbols.filter((s) => s.symbolType === type);\n const finding = analyzeSymbolTypeConventions(type, typeSymbols);\n if (finding) findings.push(finding);\n }\n\n const fileNaming = analyzeFileNaming(ctx.files);\n if (fileNaming) findings.push(fileNaming);\n\n return findings;\n },\n};\n","/**\n * Route-level security posture drift detection.\n *\n * Extracts HTTP routes from Express, Echo, Gorilla, Flask, and FastAPI codebases,\n * then checks whether security properties (auth, validation, rate-limiting) are\n * applied consistently. Routes that lack a property the majority has are flagged\n * as accidental drift from the project's established security posture.\n */\n\nimport type { DriftDetector, DriftContext, DriftFinding, DriftFile, DeviatingFile } from \"./types.js\";\n\ninterface RouteInfo {\n method: string;\n path: string;\n file: string;\n line: number;\n hasAuth: boolean;\n hasValidation: boolean;\n hasRateLimit: boolean;\n hasErrorHandler: boolean;\n}\n\nfunction extractRoutes(files: DriftFile[]): RouteInfo[] {\n const routes: RouteInfo[] = [];\n\n for (const file of files) {\n if (!file.language) continue;\n if (file.language === \"go\") extractGoRoutes(file, routes);\n else if (file.language === \"javascript\" || file.language === \"typescript\") extractJsRoutes(file, routes);\n else if (file.language === \"python\") extractPythonRoutes(file, routes);\n }\n\n return routes;\n}\n\nfunction extractGoRoutes(file: DriftFile, routes: RouteInfo[]) {\n const lines = file.content.split(\"\\n\");\n const echoPattern = /\\.\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\s*\\(\\s*\"([^\"]+)\"/;\n const gorillaPattern = /HandleFunc\\s*\\(\\s*\"([^\"]+)\".*\\.Methods\\s*\\(\\s*\"(\\w+)\"/;\n const hasGroupAuth = /\\.Use\\s*\\(\\s*\\w*[Aa]uth/.test(file.content);\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let method = \"\", path = \"\";\n\n const echoMatch = line.match(echoPattern);\n if (echoMatch) { method = echoMatch[1]; path = echoMatch[2]; }\n const gorillaMatch = line.match(gorillaPattern);\n if (gorillaMatch) { path = gorillaMatch[1]; method = gorillaMatch[2]; }\n\n if (!method || !path) continue;\n\n const context = lines.slice(Math.max(0, i - 10), i + 10).join(\"\\n\");\n const handlerContent = findHandlerContent(file.content, path);\n\n routes.push({\n method, path, file: file.path, line: i + 1,\n hasAuth: hasGroupAuth || /[Aa]uth|[Tt]oken|require[A-Z]|middleware\\.\\w*[Aa]uth/.test(context),\n hasValidation: /[Bb]ind|[Vv]alidat|[Pp]arse/.test(handlerContent),\n hasRateLimit: /[Rr]ate[Ll]imit|[Tt]hrottle/.test(context + handlerContent),\n hasErrorHandler: /catch|err\\s*!=\\s*nil|try|except|\\.catch/.test(handlerContent),\n });\n }\n}\n\nfunction extractJsRoutes(file: DriftFile, routes: RouteInfo[]) {\n const lines = file.content.split(\"\\n\");\n const expressPattern = /\\.(?:get|post|put|patch|delete|all)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/;\n const hasGroupAuth = /\\.use\\s*\\(\\s*\\w*[Aa]uth/.test(file.content);\n\n for (let i = 0; i < lines.length; i++) {\n const match = lines[i].match(expressPattern);\n if (!match) continue;\n const path = match[1];\n const method = match[0].match(/\\.(get|post|put|patch|delete|all)/)?.[1]?.toUpperCase() ?? \"ANY\";\n const context = lines.slice(Math.max(0, i - 5), i + 20).join(\"\\n\");\n\n routes.push({\n method, path, file: file.path, line: i + 1,\n hasAuth: hasGroupAuth || /auth|[Tt]oken|passport|requireAuth|isAuthenticated/.test(context),\n hasValidation: /validate|joi|zod|yup|celebrate|body\\(|query\\(/.test(context),\n hasRateLimit: /rateLimit|throttle|limiter/.test(context),\n hasErrorHandler: /catch|try|\\.catch|next\\(err/.test(context),\n });\n }\n}\n\nfunction extractPythonRoutes(file: DriftFile, routes: RouteInfo[]) {\n const lines = file.content.split(\"\\n\");\n const routePattern = /@\\w+\\.(?:route|get|post|put|patch|delete)\\s*\\(\\s*['\"]([^'\"]+)['\"]/;\n\n for (let i = 0; i < lines.length; i++) {\n const match = lines[i].match(routePattern);\n if (!match) continue;\n const path = match[1];\n const method = lines[i].match(/\\.(get|post|put|patch|delete)/)?.[1]?.toUpperCase() ?? \"ANY\";\n const context = lines.slice(i, Math.min(lines.length, i + 30)).join(\"\\n\");\n const nextDef = lines.slice(i + 1, i + 5).find((l) => /def\\s+(\\w+)/.test(l.trim()));\n const handlerName = nextDef?.match(/def\\s+(\\w+)/)?.[1] ?? \"anonymous\";\n\n routes.push({\n method, path, file: file.path, line: i + 1,\n hasAuth: /login_required|auth|token|permission|jwt|@requires/.test(context),\n hasValidation: /pydantic|validate|Schema|Serializer/.test(context),\n hasRateLimit: /rate_limit|throttle|limiter/.test(context),\n hasErrorHandler: /try|except|raise/.test(context),\n });\n }\n}\n\n// Grab a ~2.5KB window around the route registration to catch the handler body,\n// since the handler is usually defined near (or inline with) the route path string\nfunction findHandlerContent(fullContent: string, routePath: string): string {\n const idx = fullContent.indexOf(routePath);\n if (idx === -1) return \"\";\n return fullContent.slice(Math.max(0, idx - 500), Math.min(fullContent.length, idx + 2000));\n}\n\nfunction analyzeSecurityProperty(\n routes: RouteInfo[],\n propertyName: string,\n getter: (r: RouteInfo) => boolean,\n excludePaths: RegExp,\n): DriftFinding | null {\n const applicableRoutes = routes.filter((r) => !excludePaths.test(r.path));\n if (applicableRoutes.length < 2) return null;\n\n const withProperty = applicableRoutes.filter(getter);\n const withoutProperty = applicableRoutes.filter((r) => !getter(r));\n const ratio = withProperty.length / applicableRoutes.length;\n\n // Only flag if strong majority (>75%) have it — 60% was too low and\n // flagged legitimate mixed public/private APIs as drift\n if (ratio <= 0.75 || withoutProperty.length === 0) return null;\n\n return {\n detector: \"security_posture\",\n subCategory: propertyName,\n driftCategory: \"security_posture\",\n severity: withoutProperty.length > 2 ? \"error\" : \"warning\",\n confidence: 0.75,\n finding: `${propertyName} missing on ${withoutProperty.length} of ${applicableRoutes.length} routes`,\n dominantPattern: `${propertyName} applied`,\n dominantCount: withProperty.length,\n totalRelevantFiles: applicableRoutes.length,\n consistencyScore: Math.round(ratio * 100),\n deviatingFiles: withoutProperty.map((r) => ({\n path: r.file,\n detectedPattern: `${r.method} ${r.path} — no ${propertyName}`,\n evidence: [{ line: r.line, code: `${r.method} ${r.path}` }],\n })),\n recommendation: `${withProperty.length} of ${applicableRoutes.length} routes have ${propertyName}. Review ${withoutProperty.length} unprotected routes — likely built in a session where ${propertyName} wasn't discussed.`,\n };\n}\n\nexport const securityConsistency: DriftDetector = {\n id: \"security-consistency\",\n name: \"Security Posture Consistency\",\n category: \"security_posture\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n const findings: DriftFinding[] = [];\n const routes = extractRoutes(ctx.files);\n\n if (routes.length < 2) return findings;\n\n const healthPaths = /^\\/(?:health|healthz|ready|metrics|ping)$/;\n\n const authFinding = analyzeSecurityProperty(routes, \"Auth middleware\", (r) => r.hasAuth, healthPaths);\n if (authFinding) findings.push(authFinding);\n\n // Input validation only matters for state-changing methods (POST/PUT/PATCH);\n // GETs legitimately skip validation in most APIs\n const mutationRoutes = routes.filter((r) => [\"POST\", \"PUT\", \"PATCH\"].includes(r.method));\n if (mutationRoutes.length >= 2) {\n const valFinding = analyzeSecurityProperty(mutationRoutes, \"Input validation\", (r) => r.hasValidation, healthPaths);\n if (valFinding) findings.push(valFinding);\n }\n\n const rateLimitFinding = analyzeSecurityProperty(routes, \"Rate limiting\", (r) => r.hasRateLimit, healthPaths);\n if (rateLimitFinding) findings.push(rateLimitFinding);\n\n return findings;\n },\n};\n","import type { DriftDetector, DriftContext, DriftFinding, DriftFile, Evidence, DeviatingFile } from \"./types.js\";\nimport { extractFunctionsFromFile } from \"../codedna/function-extractor.js\";\nimport type { ExtractedFunction } from \"../codedna/types.js\";\n\n// Adapter: convert ExtractedFunction → FunctionSignature for backward compat\ninterface FunctionSignature {\n name: string;\n file: string;\n line: number;\n paramCount: number;\n declarationCode: string;\n bodySnippet: string;\n domainCategory: string;\n bodyTokenCount: number;\n bodyHash: number;\n}\n\nfunction toFunctionSignature(ef: ExtractedFunction): FunctionSignature {\n return {\n name: ef.name,\n file: ef.file,\n line: ef.line,\n paramCount: ef.paramCount,\n declarationCode: ef.declarationCode,\n bodySnippet: ef.rawBody.slice(0, 200),\n domainCategory: ef.domainCategory,\n bodyTokenCount: ef.bodyTokenCount,\n bodyHash: ef.bodyHash,\n };\n}\n\nfunction extractFunctions(file: DriftFile): FunctionSignature[] {\n // DriftFile.path is actually relativePath; adapt for shared extractor\n const sourceFile = {\n path: file.path,\n relativePath: file.path,\n language: file.language as any,\n content: file.content,\n lineCount: file.lineCount,\n };\n const extracted = extractFunctionsFromFile(sourceFile);\n return extracted.map(toFunctionSignature);\n}\n\n// Names that are framework conventions / interface methods — NOT duplicates\nconst CONVENTION_NAMES = new Set([\n \"registerroutes\", \"register\", \"routes\", \"setup\", \"init\", \"initialize\",\n \"close\", \"shutdown\", \"start\", \"stop\", \"run\", \"main\", \"new\", \"string\",\n \"error\", \"serve\", \"listen\", \"handle\", \"middleware\", \"mount\",\n \"marshal\", \"unmarshal\", \"serialize\", \"deserialize\",\n \"validate\", \"reset\", \"clone\", \"equals\", \"hash\", \"compare\",\n]);\n\n// Detect interface+implementation pairs (same name, one in interface/abstract file)\nfunction isInterfaceImplPair(a: FunctionSignature, b: FunctionSignature): boolean {\n const aIsInterface = /(?:interface|store|contract|abstract|base|types)\\./i.test(a.file) || a.bodyTokenCount < 10;\n const bIsInterface = /(?:interface|store|contract|abstract|base|types)\\./i.test(b.file) || b.bodyTokenCount < 10;\n // One is interface, other is implementation\n return (aIsInterface && !bIsInterface) || (!aIsInterface && bIsInterface);\n}\n\n// Check if a function name is a framework/interface convention\nfunction isConventionalName(name: string): boolean {\n return CONVENTION_NAMES.has(name.toLowerCase());\n}\n\n// Check if two functions have structurally similar signatures\nfunction areStructurallySimilar(a: FunctionSignature, b: FunctionSignature): boolean {\n if (a.domainCategory !== b.domainCategory || a.domainCategory === \"general\") return false;\n if (a.file === b.file) return false;\n if (Math.abs(a.paramCount - b.paramCount) > 1) return false;\n const sizeRatio = Math.min(a.bodyTokenCount, b.bodyTokenCount) / Math.max(a.bodyTokenCount, b.bodyTokenCount);\n return sizeRatio >= 0.4;\n}\n\n// Check if two function names are similar enough to be duplicates\nfunction areNamesSimilar(nameA: string, nameB: string, hashA: number, hashB: number, tokenCountA: number): boolean {\n if (nameA === nameB) return true;\n if (nameA.length >= 6 && nameB.length >= 6 && levenshtein(nameA, nameB) <= 3) return true;\n if (hashA === hashB && tokenCountA > 20) return true;\n return false;\n}\n\n// Check if two functions are in a handler/repo layer pair (intentional architecture)\nfunction isLayerPair(a: FunctionSignature, b: FunctionSignature): boolean {\n const aIsRepo = /(?:repository|repo|store|postgres|mysql|mongo|dal)/i.test(a.file);\n const bIsRepo = /(?:repository|repo|store|postgres|mysql|mongo|dal)/i.test(b.file);\n const aIsHandler = /(?:handler|controller|route|endpoint|api)/i.test(a.file);\n const bIsHandler = /(?:handler|controller|route|endpoint|api)/i.test(b.file);\n\n if ((aIsHandler && bIsRepo) || (aIsRepo && bIsHandler)) return true;\n\n const nameA = a.name.toLowerCase();\n const nameB = b.name.toLowerCase();\n\n if (nameA === nameB && a.paramCount === b.paramCount) {\n if (aIsHandler && bIsHandler) return true;\n if (aIsRepo && bIsRepo) return true;\n }\n return false;\n}\n\n// Compare two function signatures for semantic similarity\nfunction areSemanticallySimlar(a: FunctionSignature, b: FunctionSignature): boolean {\n if (!areStructurallySimilar(a, b)) return false;\n\n const nameA = a.name.toLowerCase();\n const nameB = b.name.toLowerCase();\n\n if (isConventionalName(nameA) || isConventionalName(nameB)) return false;\n\n // Exclude common handler names that are EXPECTED to have same signature\n if (nameA === nameB && /(?:handler|controller|resource|api)/i.test(a.file) && /(?:handler|controller|resource|api)/i.test(b.file)) {\n if ([\"list\", \"get\", \"create\", \"update\", \"delete\", \"find\", \"search\"].includes(nameA)) return false;\n }\n\n if (nameA === nameB && isInterfaceImplPair(a, b)) return false;\n if (isLayerPair(a, b)) return false;\n\n return areNamesSimilar(nameA, nameB, a.bodyHash, b.bodyHash, a.bodyTokenCount);\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length, n = b.length;\n if (m === 0) return n;\n if (n === 0) return m;\n const dp: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\n// Detect inline code that duplicates an existing utility function\nfunction detectInlineDuplicates(\n utilFunctions: FunctionSignature[],\n allFiles: DriftFile[],\n): DriftFinding[] {\n const findings: DriftFinding[] = [];\n\n // Build a map of utility function \"operations\" by keywords\n for (const util of utilFunctions) {\n const keywords = extractOperationKeywords(util.bodySnippet);\n if (keywords.length < 2) continue;\n\n // Search other files for inline code with the same keywords\n for (const file of allFiles) {\n if (file.path === util.file) continue;\n if (!file.language) continue;\n\n // Check if this file does NOT import from the utility file\n const utilModule = util.file.replace(/\\.[^.]+$/, \"\");\n if (file.content.includes(utilModule)) continue; // Already imports it\n\n // Look for inline code with similar operations\n const inlineMatches = findInlineOperations(file.content, keywords);\n if (inlineMatches.length === 0) continue;\n\n for (const inlineMatch of inlineMatches) {\n findings.push({\n detector: \"semantic_duplication\",\n driftCategory: \"semantic_duplication\",\n severity: \"warning\",\n confidence: 0.65,\n finding: `Inline ${util.domainCategory} logic in ${file.path} duplicates ${util.name}() in ${util.file}`,\n dominantPattern: `Utility function ${util.name}()`,\n dominantCount: 1,\n totalRelevantFiles: 2,\n consistencyScore: 50,\n deviatingFiles: [{\n path: file.path,\n detectedPattern: `inline ${util.domainCategory} code`,\n evidence: [{ line: inlineMatch.line, code: inlineMatch.code }],\n }],\n recommendation: `Replace inline ${util.domainCategory} logic at ${file.path}:${inlineMatch.line} with a call to ${util.name}() from ${util.file}.`,\n });\n }\n }\n }\n\n return findings;\n}\n\nfunction extractOperationKeywords(body: string): string[] {\n const keywords: string[] = [];\n if (/toFixed|toLocaleString/i.test(body)) keywords.push(\"number_format\");\n if (/\\$|currency|usd|eur/i.test(body)) keywords.push(\"currency\");\n if (/toISOString|getFullYear|getMonth|moment/i.test(body)) keywords.push(\"date_format\");\n if (/toLowerCase|toUpperCase|trim|replace|split|join/i.test(body)) keywords.push(\"string_transform\");\n if (/parseInt|parseFloat|Number\\(/i.test(body)) keywords.push(\"number_parse\");\n if (/JSON\\.parse|JSON\\.stringify/i.test(body)) keywords.push(\"json_serialize\");\n if (/encodeURI|decodeURI|btoa|atob/i.test(body)) keywords.push(\"encoding\");\n return keywords;\n}\n\nfunction findInlineOperations(content: string, keywords: string[]): { line: number; code: string }[] {\n const results: { line: number; code: string }[] = [];\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let matchCount = 0;\n for (const kw of keywords) {\n if (kw === \"number_format\" && /toFixed|toLocaleString/i.test(line)) matchCount++;\n if (kw === \"currency\" && /\\$|currency/i.test(line) && /toFixed/i.test(line)) matchCount++;\n if (kw === \"date_format\" && /toISOString|getFullYear|format/i.test(line)) matchCount++;\n if (kw === \"string_transform\" && /replace|split|join/i.test(line)) matchCount++;\n }\n if (matchCount >= 2) {\n results.push({ line: i + 1, code: line.trim().slice(0, 100) });\n }\n }\n\n return results.slice(0, 3);\n}\n\nexport const semanticDuplication: DriftDetector = {\n id: \"semantic-duplication\",\n name: \"Semantic Duplication\",\n category: \"semantic_duplication\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n const findings: DriftFinding[] = [];\n\n // Extract all functions\n const allFunctions: FunctionSignature[] = [];\n for (const file of ctx.files) {\n allFunctions.push(...extractFunctions(file));\n }\n\n if (allFunctions.length < 3) return findings;\n\n // Group by domain category\n const byDomain = new Map<string, FunctionSignature[]>();\n for (const fn of allFunctions) {\n if (fn.domainCategory === \"general\" || fn.domainCategory === \"request_handling\") continue;\n if (!byDomain.has(fn.domainCategory)) byDomain.set(fn.domainCategory, []);\n byDomain.get(fn.domainCategory)!.push(fn);\n }\n\n // Within each domain, find semantic duplicates\n for (const [domain, functions] of byDomain) {\n if (functions.length < 2) continue;\n\n const pairs: { a: FunctionSignature; b: FunctionSignature }[] = [];\n for (let i = 0; i < functions.length; i++) {\n for (let j = i + 1; j < functions.length; j++) {\n if (areSemanticallySimlar(functions[i], functions[j])) {\n pairs.push({ a: functions[i], b: functions[j] });\n }\n }\n }\n\n // Deduplicate\n const seenKeys = new Set<string>();\n for (const pair of pairs) {\n const key = [pair.a.file + \":\" + pair.a.name, pair.b.file + \":\" + pair.b.name].sort().join(\"|\");\n if (seenKeys.has(key)) continue;\n seenKeys.add(key);\n\n findings.push({\n detector: \"semantic_duplication\",\n subCategory: domain,\n driftCategory: \"semantic_duplication\",\n severity: \"error\",\n confidence: 0.75,\n finding: `Duplicate ${domain.replace(/_/g, \" \")} logic: ${pair.a.name}() in ${pair.a.file} and ${pair.b.name}() in ${pair.b.file}`,\n dominantPattern: `${pair.a.name}()`,\n dominantCount: 1,\n totalRelevantFiles: 2,\n consistencyScore: 50,\n deviatingFiles: [\n {\n path: pair.a.file,\n detectedPattern: `${pair.a.name}(${pair.a.paramCount} params)`,\n evidence: [{ line: pair.a.line, code: pair.a.declarationCode || pair.a.name + \"()\" }],\n },\n {\n path: pair.b.file,\n detectedPattern: `${pair.b.name}(${pair.b.paramCount} params)`,\n evidence: [{ line: pair.b.line, code: pair.b.declarationCode || pair.b.name + \"()\" }],\n },\n ],\n recommendation: `Extract shared ${domain.replace(/_/g, \" \")} logic into a single utility function. Both ${pair.a.name}() and ${pair.b.name}() appear to do the same thing.`,\n });\n }\n }\n\n // Also check for inline code duplicating utility functions\n const utilFiles = ctx.files.filter((f) => /(?:util|helper|lib|common|shared)/i.test(f.path));\n const utilFunctions = allFunctions.filter((fn) => /(?:util|helper|lib|common|shared)/i.test(fn.file));\n if (utilFunctions.length > 0) {\n findings.push(...detectInlineDuplicates(utilFunctions, ctx.files));\n }\n\n return findings;\n },\n};\n","import type { DriftDetector, DriftContext, DriftFinding, DriftFile, Evidence, DeviatingFile } from \"./types.js\";\n\ninterface ExportedFunction {\n name: string;\n file: string;\n line: number;\n crudType: \"create\" | \"read\" | \"update\" | \"delete\" | \"list\" | \"other\";\n}\n\ninterface RouteRegistration {\n method: string;\n path: string;\n handlerName: string;\n file: string;\n line: number;\n}\n\n// Classify function by CRUD type based on name\nfunction classifyCRUD(name: string): ExportedFunction[\"crudType\"] {\n const lower = name.toLowerCase();\n if (/^(?:create|add|insert|new|post|register|store|save)/.test(lower)) return \"create\";\n if (/^(?:get|find|fetch|read|load|retrieve|show|detail)/.test(lower)) return \"read\";\n if (/^(?:list|search|browse|index|all|query|paginate)/.test(lower)) return \"list\";\n if (/^(?:update|edit|modify|patch|change|set|put)/.test(lower)) return \"update\";\n if (/^(?:delete|remove|destroy|revoke|drop|unregister|purge)/.test(lower)) return \"delete\";\n return \"other\";\n}\n\nfunction extractExportedFunctions(file: DriftFile): ExportedFunction[] {\n const functions: ExportedFunction[] = [];\n if (!file.language) return functions;\n\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let name: string | null = null;\n\n if (file.language === \"go\") {\n // Exported Go functions: func Name( or func (recv) Name(\n const m = line.match(/^func\\s+(?:\\([^)]*\\)\\s+)?([A-Z]\\w+)\\s*\\(/);\n if (m) name = m[1];\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n const m = line.match(/export\\s+(?:async\\s+)?(?:function|const|class)\\s+(\\w+)/);\n if (m) name = m[1];\n } else if (file.language === \"python\") {\n // Non-private functions at module level\n const m = line.match(/^def\\s+(\\w+)\\s*\\(/);\n if (m && !m[1].startsWith(\"_\")) name = m[1];\n } else if (file.language === \"rust\") {\n const m = line.match(/^pub\\s+(?:async\\s+)?fn\\s+(\\w+)/);\n if (m) name = m[1];\n }\n\n if (name) {\n functions.push({\n name,\n file: file.path,\n line: i + 1,\n crudType: classifyCRUD(name),\n });\n }\n }\n\n return functions;\n}\n\nfunction extractRouteRegistrations(file: DriftFile): RouteRegistration[] {\n const routes: RouteRegistration[] = [];\n if (!file.language) return routes;\n\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Go Echo: .GET(\"/path\", handler) or .POST(\"/path\", handler.Method)\n const echoMatch = line.match(/\\.\\s*(GET|POST|PUT|PATCH|DELETE)\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*(\\w+(?:\\.\\w+)?)/);\n if (echoMatch) {\n routes.push({ method: echoMatch[1], path: echoMatch[2], handlerName: echoMatch[3], file: file.path, line: i + 1 });\n continue;\n }\n\n // Go Gorilla mux: HandleFunc(\"/path\", handler).Methods(\"GET\")\n const gorillaMatch = line.match(/HandleFunc\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*(\\w+(?:\\.\\w+)?)\\)/);\n if (gorillaMatch) {\n const methodMatch = lines.slice(i, i + 2).join(\"\").match(/Methods\\s*\\(\\s*\"(\\w+)\"/);\n routes.push({ method: methodMatch?.[1] ?? \"ANY\", path: gorillaMatch[1], handlerName: gorillaMatch[2], file: file.path, line: i + 1 });\n continue;\n }\n\n // JS/TS Express: app.get('/path', handler) or router.post('/path', handler)\n const expressMatch = line.match(/\\.\\s*(get|post|put|patch|delete)\\s*\\(\\s*['\"]([^'\"]+)['\"](?:\\s*,\\s*(\\w+))?/);\n if (expressMatch) {\n routes.push({ method: expressMatch[1].toUpperCase(), path: expressMatch[2], handlerName: expressMatch[3] ?? \"anonymous\", file: file.path, line: i + 1 });\n continue;\n }\n\n // Python Flask/FastAPI: @app.get('/path') or @router.post('/path')\n const pyMatch = line.match(/@\\w+\\.\\s*(get|post|put|patch|delete)\\s*\\(\\s*['\"]([^'\"]+)['\"]/);\n if (pyMatch) {\n // Next def is the handler\n const nextDef = lines.slice(i + 1, i + 5).find((l) => /^(?:async\\s+)?def\\s+(\\w+)/.test(l.trim()));\n const handlerName = nextDef?.match(/def\\s+(\\w+)/)?.[1] ?? \"anonymous\";\n routes.push({ method: pyMatch[1].toUpperCase(), path: pyMatch[2], handlerName, file: file.path, line: i + 1 });\n }\n }\n\n return routes;\n}\n\nfunction buildUsageGraph(files: DriftFile[]): Map<string, Set<string>> {\n // Map: symbol name → set of files that reference it\n const usage = new Map<string, Set<string>>();\n\n const allContent = files.map((f) => ({ path: f.path, content: f.content }));\n\n for (const file of allContent) {\n // Find all identifiers used in this file\n const identifiers = file.content.match(/\\b[A-Z]\\w+\\b/g) ?? [];\n for (const id of identifiers) {\n if (!usage.has(id)) usage.set(id, new Set());\n usage.get(id)!.add(file.path);\n }\n }\n\n return usage;\n}\n\nfunction isReferencedExternally(\n name: string,\n usage: Map<string, Set<string>>,\n currentFile: string,\n allRoutes: RouteRegistration[],\n): boolean {\n const references = usage.get(name);\n // A function is \"used\" if referenced from a different file\n const usedExternally = references && [...references].some((f) => f !== currentFile);\n\n // Also check if it's in a route registration\n const isRouted = allRoutes.some((r) =>\n r.handlerName.includes(name) || r.handlerName.endsWith(\".\" + name),\n );\n\n return !!(usedExternally || isRouted);\n}\n\nfunction detectScaffoldingPattern(\n filePath: string,\n crudFunctions: ExportedFunction[],\n usage: Map<string, Set<string>>,\n allRoutes: RouteRegistration[],\n): DriftFinding | null {\n const usedFunctions: ExportedFunction[] = [];\n const unusedFunctions: ExportedFunction[] = [];\n\n for (const fn of crudFunctions) {\n if (isReferencedExternally(fn.name, usage, filePath, allRoutes)) {\n usedFunctions.push(fn);\n } else {\n unusedFunctions.push(fn);\n }\n }\n\n // Only flag if there's a GROUP of unused CRUD functions (not individual)\n if (unusedFunctions.length < 2 || usedFunctions.length < 1) return null;\n\n const usedTypes = usedFunctions.map((f) => f.crudType);\n const unusedTypes = unusedFunctions.map((f) => f.crudType);\n\n // Classic scaffolding: Read is used, Create/Update/Delete are not\n const isScaffoldingLike =\n usedTypes.some((t) => t === \"read\" || t === \"list\") &&\n unusedTypes.some((t) => t === \"create\" || t === \"update\" || t === \"delete\");\n\n return {\n detector: \"phantom_scaffolding\",\n driftCategory: \"phantom_scaffolding\",\n severity: isScaffoldingLike ? \"warning\" : \"info\",\n confidence: isScaffoldingLike ? 0.8 : 0.6,\n finding: `CRUD scaffolding detected in ${filePath} — ${usedFunctions.length} functions used, ${unusedFunctions.length} appear unused`,\n dominantPattern: \"used CRUD operations\",\n dominantCount: usedFunctions.length,\n totalRelevantFiles: usedFunctions.length + unusedFunctions.length,\n consistencyScore: Math.round((usedFunctions.length / (usedFunctions.length + unusedFunctions.length)) * 100),\n deviatingFiles: [{\n path: filePath,\n detectedPattern: `unused: ${unusedFunctions.map((f) => f.name).join(\", \")}`,\n evidence: unusedFunctions.slice(0, 5).map((f) => ({\n line: f.line,\n code: `${f.name} (${f.crudType}) — defined but not routed or imported`,\n })),\n }],\n recommendation: `${unusedFunctions.map((f) => f.name).join(\", \")} are defined in ${filePath.split(\"/\").pop()} but never registered in routes or called externally. This looks like AI-generated CRUD scaffolding — remove unused handlers or wire them to routes.`,\n };\n}\n\nfunction detectUnroutedHandlers(\n allExports: ExportedFunction[],\n allRoutes: RouteRegistration[],\n usage: Map<string, Set<string>>,\n): DriftFinding[] {\n const findings: DriftFinding[] = [];\n\n // Find handler files that have CRUD functions\n const handlerFiles = new Map<string, ExportedFunction[]>();\n for (const exp of allExports) {\n if (exp.crudType === \"other\") continue;\n if (!handlerFiles.has(exp.file)) handlerFiles.set(exp.file, []);\n handlerFiles.get(exp.file)!.push(exp);\n }\n\n // For each handler file with CRUD functions, check which are actually used\n for (const [filePath, functions] of handlerFiles) {\n const crudFunctions = functions.filter((f) => f.crudType !== \"other\");\n if (crudFunctions.length < 2) continue; // Need at least 2 CRUD operations to detect scaffolding\n\n const finding = detectScaffoldingPattern(filePath, crudFunctions, usage, allRoutes);\n if (finding) findings.push(finding);\n }\n\n return findings;\n}\n\nfunction extractTypeDefinitions(\n files: DriftFile[],\n): { name: string; file: string; line: number }[] {\n const typeDefinitions: { name: string; file: string; line: number }[] = [];\n\n // In Go, types used as method receivers are NOT unused — find them\n const goMethodReceivers = new Set<string>();\n for (const file of files) {\n if (file.language !== \"go\") continue;\n const receiverPattern = /func\\s+\\(\\s*\\w+\\s+\\*?(\\w+)\\s*\\)/g;\n let m;\n while ((m = receiverPattern.exec(file.content)) !== null) {\n goMethodReceivers.add(m[1]);\n }\n }\n\n for (const file of files) {\n if (!file.language) continue;\n const lines = file.content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let typeName: string | null = null;\n\n if (file.language === \"go\") {\n const m = line.match(/^type\\s+([A-Z]\\w+)\\s+struct\\b/);\n if (m) typeName = m[1];\n } else if (file.language === \"javascript\" || file.language === \"typescript\") {\n const m = line.match(/export\\s+(?:interface|type|class)\\s+(\\w+)/);\n if (m) typeName = m[1];\n }\n\n if (!typeName) continue;\n if (file.language === \"go\" && goMethodReceivers.has(typeName)) continue;\n if (/(?:Request|Response|Params|Config|Options|Input|Output|Payload|Body|DTO)$/i.test(typeName)) continue;\n\n typeDefinitions.push({ name: typeName, file: file.path, line: i + 1 });\n }\n }\n\n return typeDefinitions;\n}\n\nfunction findUnusedTypes(\n typeDefinitions: { name: string; file: string; line: number }[],\n usage: Map<string, Set<string>>,\n): Map<string, { name: string; line: number }[]> {\n const unusedTypesByFile = new Map<string, { name: string; line: number }[]>();\n for (const td of typeDefinitions) {\n const refs = usage.get(td.name);\n const usedExternally = refs && [...refs].some((f) => f !== td.file);\n if (!usedExternally) {\n if (!unusedTypesByFile.has(td.file)) unusedTypesByFile.set(td.file, []);\n unusedTypesByFile.get(td.file)!.push(td);\n }\n }\n return unusedTypesByFile;\n}\n\nfunction detectUnusedTypeScaffolding(\n files: DriftFile[],\n usage: Map<string, Set<string>>,\n): DriftFinding[] {\n const findings: DriftFinding[] = [];\n const typeDefinitions = extractTypeDefinitions(files);\n const unusedTypesByFile = findUnusedTypes(typeDefinitions, usage);\n\n for (const [filePath, unusedTypes] of unusedTypesByFile) {\n if (unusedTypes.length < 3) continue;\n\n findings.push({\n detector: \"phantom_scaffolding\",\n subCategory: \"unused_types\",\n driftCategory: \"phantom_scaffolding\",\n severity: \"info\",\n confidence: 0.55,\n finding: `${unusedTypes.length} types/structs in ${filePath} appear unused outside their file`,\n dominantPattern: \"used types\",\n dominantCount: typeDefinitions.length - unusedTypes.length,\n totalRelevantFiles: typeDefinitions.length,\n consistencyScore: Math.round(((typeDefinitions.length - unusedTypes.length) / typeDefinitions.length) * 100),\n deviatingFiles: [{\n path: filePath,\n detectedPattern: `unused types: ${unusedTypes.map((t) => t.name).join(\", \")}`,\n evidence: unusedTypes.slice(0, 5).map((t) => ({\n line: t.line,\n code: `type ${t.name} — defined but never imported`,\n })),\n }],\n recommendation: `${unusedTypes.length} types in ${filePath.split(\"/\").pop()} are never used outside their file. They may be AI-generated scaffolding that was never needed.`,\n });\n }\n\n return findings;\n}\n\nexport const phantomScaffolding: DriftDetector = {\n id: \"phantom-scaffolding\",\n name: \"Phantom Scaffolding\",\n category: \"phantom_scaffolding\",\n\n detect(ctx: DriftContext): DriftFinding[] {\n // Extract all exported functions and route registrations\n const allExports: ExportedFunction[] = [];\n const allRoutes: RouteRegistration[] = [];\n\n for (const file of ctx.files) {\n allExports.push(...extractExportedFunctions(file));\n allRoutes.push(...extractRouteRegistrations(file));\n }\n\n if (allExports.length < 3) return [];\n\n // Build usage graph\n const usage = buildUsageGraph(ctx.files);\n\n const findings: DriftFinding[] = [];\n\n // Detect unrouted handler functions\n findings.push(...detectUnroutedHandlers(allExports, allRoutes, usage));\n\n // Detect unused type/struct scaffolding\n findings.push(...detectUnusedTypeScaffolding(ctx.files, usage));\n\n return findings;\n },\n};\n","import type {\n Finding,\n CategoryScores,\n CategoryScore,\n SupportedLanguage,\n PerFileScore,\n AnalysisContext,\n} from \"../core/types.js\";\nimport {\n CATEGORY_CONFIG,\n ALL_CATEGORIES,\n isCategoryApplicable,\n getApplicableAnalyzerIds,\n type ScoringCategory,\n} from \"./categories.js\";\n\nconst SEVERITY_WEIGHTS = { error: 3, warning: 1.5, info: 0.5 };\n\nconst ENTRY_POINT_PATTERNS = [\n /index\\.[jt]sx?$/, /main\\.[jt]s$/, /app\\.[jt]sx?$/, /server\\.[jt]s$/,\n /main\\.go$/, /main\\.py$/, /lib\\.rs$/, /mod\\.rs$/,\n /\\.config\\.[jt]s$/, /\\.env/,\n];\n\nfunction isEntryPoint(filePath: string): boolean {\n return ENTRY_POINT_PATTERNS.some((p) => p.test(filePath));\n}\n\nfunction computeFileImportanceWeight(filePath: string): number {\n if (isEntryPoint(filePath)) return 1.5;\n return 1.0;\n}\n\nfunction computeCorrelationAmplifier(findings: Finding[]): Map<string, number> {\n const fileAnalyzers = new Map<string, Set<string>>();\n for (const f of findings) {\n for (const loc of f.locations) {\n if (!loc.file) continue;\n if (!fileAnalyzers.has(loc.file)) fileAnalyzers.set(loc.file, new Set());\n fileAnalyzers.get(loc.file)!.add(f.analyzerId);\n }\n }\n\n const amplifiers = new Map<string, number>();\n for (const [file, analyzers] of fileAnalyzers) {\n const count = analyzers.size;\n amplifiers.set(file, count >= 4 ? 1.5 : count >= 3 ? 1.3 : 1.0);\n }\n return amplifiers;\n}\n\n/**\n * Scoring philosophy: the score should HURT when there are real issues.\n *\n * Formula per category (0-20):\n * 1. Sum weighted severity of all findings (error=3, warning=1.5, info=0.5)\n * × confidence × file importance × correlation amplifier\n * 2. Apply mild project-size adjustment (sqrt scale, not linear divide)\n * 3. Map through exponential decay: score = maxScore × e^(-k × adjustedWeight)\n * where k is tuned so that ~10 weighted points = ~50% score\n *\n * This means:\n * - 0 findings → 20/20\n * - 2-3 warnings → ~17/20\n * - 5 warnings → ~14/20\n * - 10 warnings or 3 errors → ~10/20\n * - 20+ weighted points → <5/20\n */\nfunction computeCategoryScore(\n findings: Finding[],\n maxScore: number,\n totalLines: number,\n applicable: boolean,\n correlationAmplifiers: Map<string, number>,\n): CategoryScore {\n if (!applicable) {\n return { score: 0, maxScore, locked: false, findingCount: 0, applicable: false };\n }\n\n if (findings.length === 0) {\n return { score: maxScore, maxScore, locked: false, findingCount: 0, applicable: true };\n }\n\n // Sum weighted severity\n let rawWeight = 0;\n for (const f of findings) {\n const base = SEVERITY_WEIGHTS[f.severity];\n const confidence = f.confidence ?? 1.0;\n let fileWeight = 1.0;\n let corrWeight = 1.0;\n for (const loc of f.locations) {\n if (loc.file) {\n fileWeight = Math.max(fileWeight, computeFileImportanceWeight(loc.file));\n corrWeight = Math.max(corrWeight, correlationAmplifiers.get(loc.file) ?? 1.0);\n }\n }\n rawWeight += base * confidence * fileWeight * corrWeight;\n }\n\n // Mild project-size adjustment: larger projects tolerate slightly more issues.\n // Projects under 500 lines get no penalty — prevents tiny demos from scoring F.\n // Uses sqrt scale — a 10K line project gets ~3x tolerance vs 500 lines, not 100x\n const sizeFactor = totalLines > 500 ? Math.sqrt(totalLines / 1000) : 1.0;\n // Clamp to [0.5, 3.0] — never more than 3x tolerance\n const clampedSizeFactor = Math.max(0.5, Math.min(3.0, sizeFactor));\n const adjustedWeight = rawWeight / clampedSizeFactor;\n\n // Exponential decay: score = max × e^(-k × weight)\n // k = ln(2)/15 means 15 weighted points = 50% score (softer than the\n // original /10 — two error findings no longer tank a category)\n const k = Math.LN2 / 15;\n const factor = Math.exp(-k * adjustedWeight);\n const score = Math.round(maxScore * factor * 10) / 10;\n\n return {\n score: Math.max(0, Math.min(maxScore, score)),\n maxScore,\n locked: false,\n findingCount: findings.length,\n applicable: true,\n };\n}\n\nexport function computeScores(\n findings: Finding[],\n totalLines: number,\n ctx?: AnalysisContext,\n previousScores?: CategoryScores,\n): { scores: CategoryScores; compositeScore: number; maxCompositeScore: number; perFileScores: Map<string, PerFileScore> } {\n const projectLanguages: SupportedLanguage[] = ctx\n ? [...ctx.languageBreakdown.keys()]\n : [\"javascript\", \"typescript\"];\n\n const correlationAmplifiers = computeCorrelationAmplifier(findings);\n\n const findingsByCategory = new Map<ScoringCategory, Finding[]>();\n for (const cat of ALL_CATEGORIES) {\n const applicableIds = getApplicableAnalyzerIds(cat, projectLanguages);\n findingsByCategory.set(cat, findings.filter((f) => applicableIds.includes(f.analyzerId)));\n }\n\n const categoryScores: Record<string, CategoryScore> = {};\n\n for (const cat of ALL_CATEGORIES) {\n const config = CATEGORY_CONFIG[cat];\n const applicable = isCategoryApplicable(cat, projectLanguages);\n const catFindings = findingsByCategory.get(cat) ?? [];\n\n const score = computeCategoryScore(\n catFindings,\n config.maxScore,\n totalLines,\n applicable,\n correlationAmplifiers,\n );\n\n if (previousScores) {\n const prev = previousScores[cat];\n if (prev && prev.applicable) {\n score.delta = Math.round((score.score - prev.score) * 10) / 10;\n }\n }\n\n categoryScores[cat] = score;\n }\n\n const scores = categoryScores as unknown as CategoryScores;\n\n let compositeScore = 0;\n let maxCompositeScore = 0;\n for (const cat of ALL_CATEGORIES) {\n const s = scores[cat];\n if (s.applicable) {\n compositeScore += s.score;\n maxCompositeScore += s.maxScore;\n }\n }\n\n // Drag penalty: when critical categories score poorly, the composite score\n // shouldn't be rescued by perfect scores in less impactful categories.\n // Architecture and redundancy are load-bearing — if they're broken, the\n // overall health should reflect that urgency.\n const DRAG_CATEGORIES: ScoringCategory[] = [\"architecturalConsistency\", \"redundancy\"];\n const DRAG_THRESHOLD = 0.50; // below 50% health triggers drag\n const DRAG_MAX_PENALTY = 0.10; // up to 10% composite penalty per category (reduced from 15% to avoid double-punishment)\n\n for (const cat of DRAG_CATEGORIES) {\n const s = scores[cat];\n if (!s.applicable || s.maxScore === 0) continue;\n const healthPct = s.score / s.maxScore;\n if (healthPct < DRAG_THRESHOLD) {\n // Linear penalty: 0% health → full penalty, 50% health → 0 penalty\n const penaltyFraction = (DRAG_THRESHOLD - healthPct) / DRAG_THRESHOLD;\n const penalty = DRAG_MAX_PENALTY * penaltyFraction * maxCompositeScore;\n compositeScore -= penalty;\n }\n }\n\n compositeScore = Math.max(0, Math.round(compositeScore * 10) / 10);\n\n const perFileScores = computePerFileScores(findings, ctx);\n\n return { scores, compositeScore, maxCompositeScore, perFileScores };\n}\n\nfunction computePerFileScores(\n findings: Finding[],\n ctx?: AnalysisContext,\n): Map<string, PerFileScore> {\n const perFile = new Map<string, PerFileScore>();\n if (!ctx) return perFile;\n\n for (const file of ctx.files) {\n perFile.set(file.relativePath, {\n file: file.relativePath,\n findings: [],\n score: 100,\n maxScore: 100,\n });\n }\n\n for (const finding of findings) {\n // Deduplicate: add each finding to a file only once, even if it has\n // multiple locations pointing to the same file\n const seenFiles = new Set<string>();\n for (const loc of finding.locations) {\n if (!loc.file || seenFiles.has(loc.file)) continue;\n seenFiles.add(loc.file);\n const entry = perFile.get(loc.file);\n if (entry) entry.findings.push(finding);\n }\n }\n\n for (const [, entry] of perFile) {\n if (entry.findings.length === 0) continue;\n let penalty = 0;\n for (const f of entry.findings) {\n penalty += SEVERITY_WEIGHTS[f.severity] * (f.confidence ?? 1.0);\n }\n // Exponential decay per file too\n const k = Math.LN2 / 5; // 5 weighted points = 50 score\n entry.score = Math.max(0, Math.round(100 * Math.exp(-k * penalty)));\n }\n\n return perFile;\n}\n","import type { SupportedLanguage } from \"../core/types.js\";\n\nexport type ScoringCategory =\n | \"architecturalConsistency\"\n | \"redundancy\"\n | \"dependencyHealth\"\n | \"securityPosture\"\n | \"intentClarity\";\n\nexport interface AnalyzerMeta {\n id: string;\n applicableLanguages: SupportedLanguage[] | \"all\";\n}\n\nexport interface CategoryConfig {\n name: string;\n maxScore: number;\n analyzers: AnalyzerMeta[];\n}\n\nexport const CATEGORY_CONFIG: Record<ScoringCategory, CategoryConfig> = {\n architecturalConsistency: {\n name: \"Architectural Consistency\",\n maxScore: 20,\n analyzers: [\n { id: \"naming\", applicableLanguages: \"all\" },\n { id: \"imports\", applicableLanguages: [\"javascript\", \"typescript\"] },\n { id: \"error-handling\", applicableLanguages: [\"javascript\", \"typescript\"] },\n { id: \"language-specific\", applicableLanguages: \"all\" },\n // Drift detectors (cross-file)\n { id: \"drift-architectural_consistency\", applicableLanguages: \"all\" },\n { id: \"drift-convention-oscillation\", applicableLanguages: \"all\" },\n // Code DNA\n { id: \"codedna-pattern\", applicableLanguages: \"all\" },\n { id: \"codedna-deviation\", applicableLanguages: \"all\" },\n // ML\n { id: \"ml-anomaly\", applicableLanguages: \"all\" },\n ],\n },\n redundancy: {\n name: \"Redundancy\",\n maxScore: 20,\n analyzers: [\n { id: \"duplicates\", applicableLanguages: \"all\" },\n { id: \"todo-density\", applicableLanguages: \"all\" },\n { id: \"dead-code\", applicableLanguages: \"all\" },\n // Code DNA\n { id: \"codedna-fingerprint\", applicableLanguages: \"all\" },\n { id: \"codedna-opseq\", applicableLanguages: \"all\" },\n // ML\n { id: \"ml-duplicate\", applicableLanguages: \"all\" },\n ],\n },\n dependencyHealth: {\n name: \"Dependency Health\",\n maxScore: 20,\n analyzers: [\n { id: \"dependencies\", applicableLanguages: \"all\" },\n { id: \"config-drift\", applicableLanguages: \"all\" },\n ],\n },\n securityPosture: {\n name: \"Security Posture\",\n maxScore: 20,\n analyzers: [\n { id: \"security\", applicableLanguages: \"all\" },\n { id: \"drift-security_posture\", applicableLanguages: \"all\" },\n // Code DNA\n { id: \"codedna-taint\", applicableLanguages: \"all\" },\n ],\n },\n intentClarity: {\n name: \"Intent Clarity\",\n maxScore: 20,\n analyzers: [\n { id: \"intent-clarity\", applicableLanguages: \"all\" },\n { id: \"complexity\", applicableLanguages: \"all\" },\n // ML\n { id: \"ml-intent\", applicableLanguages: \"all\" },\n ],\n },\n};\n\nexport const ALL_CATEGORIES = Object.keys(CATEGORY_CONFIG) as ScoringCategory[];\n\nexport function getApplicableAnalyzerIds(\n category: ScoringCategory,\n projectLanguages: SupportedLanguage[],\n): string[] {\n return CATEGORY_CONFIG[category].analyzers\n .filter((a) => {\n if (a.applicableLanguages === \"all\") return true;\n return a.applicableLanguages.some((l) => projectLanguages.includes(l));\n })\n .map((a) => a.id);\n}\n\nexport function isCategoryApplicable(\n category: ScoringCategory,\n projectLanguages: SupportedLanguage[],\n): boolean {\n return getApplicableAnalyzerIds(category, projectLanguages).length > 0;\n}\n","import type { AnalysisContext, Finding } from \"../core/types.js\";\n\nexport function generateTeaseMessages(\n ctx: AnalysisContext,\n findings: Finding[],\n deepUsed: boolean,\n): string[] {\n if (deepUsed) return []; // No tease needed when deep AI analysis already ran\n\n const messages: string[] = [];\n\n const securityFindings = findings.filter((f) => f.analyzerId === \"security\");\n if (securityFindings.length > 0) {\n const errorCount = securityFindings.filter((f) => f.severity === \"error\").length;\n messages.push(\n `${securityFindings.length} security issues found${errorCount > 0 ? ` (${errorCount} critical)` : \"\"} — run \\`vibedrift --deep\\` for AI-powered context analysis`,\n );\n }\n\n const complexityFindings = findings.filter((f) => f.analyzerId === \"complexity\");\n if (complexityFindings.length > 0) {\n messages.push(\n `${complexityFindings.length} complexity concerns detected — run \\`vibedrift --deep\\` for AI-powered architectural recommendations`,\n );\n }\n\n const deadCodeFindings = findings.filter((f) => f.analyzerId === \"dead-code\");\n if (deadCodeFindings.length > 0) {\n messages.push(\n `Potential dead code detected — run \\`vibedrift --deep\\` for AI-powered semantic analysis`,\n );\n }\n\n if (ctx.files.length > 10 && messages.length === 0) {\n messages.push(\n `Run \\`vibedrift --deep\\` for AI-powered architectural pattern detection and intent analysis`,\n );\n }\n\n if (messages.length > 0) {\n messages.push(`Sign in first with \\`vibedrift login\\` — it's free.`);\n }\n\n return messages;\n}\n","/**\n * Terminal output renderer for VibeDrift scan reports.\n *\n * Formats the full scan result (findings, category scores, deep insights)\n * as a colorized, human-readable terminal report using chalk. Also provides\n * a structured JSON renderer for piping to files or CI systems.\n */\n\nimport chalk from \"chalk\";\nimport type { ScanResult, Finding } from \"../core/types.js\";\nimport { CATEGORY_CONFIG, ALL_CATEGORIES, type ScoringCategory } from \"../scoring/categories.js\";\nimport { scoreBar, padRight } from \"./format.js\";\nimport { getLanguageDisplayName } from \"../core/language.js\";\nimport type { SupportedLanguage } from \"../core/types.js\";\nimport { getVersion } from \"../core/version.js\";\n\nfunction severityIcon(severity: Finding[\"severity\"]): string {\n switch (severity) {\n case \"error\": return chalk.red(\"\\u2718\");\n case \"warning\": return chalk.yellow(\"\\u26A0\");\n case \"info\": return chalk.blue(\"\\u2139\");\n }\n}\n\nfunction scoreColorFn(score: number, max: number): typeof chalk {\n const ratio = score / max;\n if (ratio >= 0.8) return chalk.green;\n if (ratio >= 0.5) return chalk.yellow;\n return chalk.red;\n}\n\nfunction renderFindingsList(result: ScanResult): string[] {\n const lines: string[] = [];\n for (const cat of ALL_CATEGORIES) {\n const config = CATEGORY_CONFIG[cat];\n const s = result.scores[cat];\n\n if (!s.applicable) {\n lines.push(chalk.dim(`\\u2500\\u2500 ${config.name} (N/A) \\u2500\\u2500\\u2500`));\n lines.push(chalk.dim(\" Not applicable for this project's languages\"));\n lines.push(\"\");\n continue;\n }\n\n lines.push(chalk.bold(`\\u2500\\u2500 ${config.name} ${\"─\".repeat(Math.max(0, 48 - config.name.length))}`));\n\n const catAnalyzerIds = config.analyzers.map((a) => a.id);\n const catFindings = result.findings.filter((f) => catAnalyzerIds.includes(f.analyzerId));\n\n if (catFindings.length === 0) {\n lines.push(chalk.green(\" \\u2713 No issues found\"));\n } else {\n for (const finding of catFindings) {\n lines.push(` ${severityIcon(finding.severity)} ${finding.message}`);\n if (finding.locations.length > 0 && finding.locations.length <= 5) {\n for (const loc of finding.locations) {\n const lineStr = loc.line ? `:${loc.line}` : \"\";\n lines.push(chalk.dim(` ${loc.file}${lineStr}`));\n }\n } else if (finding.locations.length > 5) {\n for (const loc of finding.locations.slice(0, 3)) {\n const lineStr = loc.line ? `:${loc.line}` : \"\";\n lines.push(chalk.dim(` ${loc.file}${lineStr}`));\n }\n lines.push(chalk.dim(` ... and ${finding.locations.length - 3} more`));\n }\n }\n }\n lines.push(\"\");\n }\n return lines;\n}\n\nfunction renderCategoryBars(result: ScanResult): string[] {\n const lines: string[] = [];\n lines.push(chalk.bold(\"\\u2500\\u2500 Vibe Debt Score \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\"));\n\n for (const cat of ALL_CATEGORIES) {\n const config = CATEGORY_CONFIG[cat];\n const s = result.scores[cat];\n const label = padRight(config.name, 28);\n\n if (!s.applicable) {\n lines.push(chalk.dim(` ${label} N/A`));\n } else {\n const color = scoreColorFn(s.score, s.maxScore);\n const bar = color(scoreBar(s.score, s.maxScore));\n let deltaStr = \"\";\n if (s.delta !== undefined && s.delta !== 0) {\n const dColor = s.delta > 0 ? chalk.green : chalk.red;\n const arrow = s.delta > 0 ? \"\\u25B2\" : \"\\u25BC\";\n deltaStr = \" \" + dColor(`${arrow}${Math.abs(s.delta).toFixed(1)}`);\n }\n lines.push(` ${label} ${color(`${s.score.toFixed(0).padStart(2)}/${s.maxScore}`)} ${bar}${deltaStr}`);\n }\n }\n\n lines.push(` ${\"─\".repeat(34)}`);\n const totalColor = scoreColorFn(result.compositeScore, result.maxCompositeScore);\n lines.push(` ${padRight(\"Total Score:\", 28)} ${totalColor(`${result.compositeScore.toFixed(0)}/${result.maxCompositeScore}`)}`);\n lines.push(\"\");\n return lines;\n}\n\nfunction renderScoreSection(result: ScanResult): string[] {\n const lines: string[] = [];\n\n const banner = ` VibeDrift v${getVersion()} `;\n const border = \"\\u2500\".repeat(banner.length);\n lines.push(chalk.cyan(`\\u256D${border}\\u256E`));\n lines.push(chalk.cyan(`\\u2502${banner}\\u2502`));\n lines.push(chalk.cyan(`\\u2570${border}\\u256F`));\n lines.push(\"\");\n\n const langCounts = new Map<string, number>();\n for (const f of result.context.files) {\n if (f.language) {\n const label = getLanguageDisplayName(f.language as SupportedLanguage);\n langCounts.set(label, (langCounts.get(label) ?? 0) + 1);\n }\n }\n const langStr = [...langCounts.entries()].map(([l, c]) => `${l}: ${c}`).join(\", \");\n\n lines.push(chalk.dim(`Scanning: ${result.context.rootDir}`));\n lines.push(chalk.dim(`Files: ${result.context.files.length} (${langStr}) | Lines: ${result.context.totalLines.toLocaleString()} | Time: ${(result.scanTimeMs / 1000).toFixed(1)}s`));\n lines.push(\"\");\n return lines;\n}\n\nexport function renderTerminalOutput(result: ScanResult): string {\n const lines: string[] = [\n ...renderScoreSection(result),\n ...renderFindingsList(result),\n ...renderCategoryBars(result),\n ];\n\n // Deep insights\n if (result.deepInsights.length > 0) {\n lines.push(chalk.bold(\"\\u2500\\u2500 Deep Analysis (AI-Powered) \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\"));\n for (const insight of result.deepInsights.slice(0, 10)) {\n const icon = severityIcon(insight.severity);\n lines.push(` ${icon} [${insight.category}] ${insight.title}`);\n lines.push(chalk.dim(` ${insight.description.slice(0, 120)}${insight.description.length > 120 ? \"...\" : \"\"}`));\n if (insight.recommendation) {\n lines.push(chalk.green(` \\u2192 ${insight.recommendation.slice(0, 100)}`));\n }\n }\n lines.push(\"\");\n }\n\n // Tease\n if (result.teaseMessages.length > 0) {\n lines.push(chalk.bold(\"\\u2500\\u2500 Deep Analysis Preview \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\"));\n for (const msg of result.teaseMessages) {\n lines.push(chalk.dim(` \\u00B7 ${msg}`));\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function renderJsonOutput(result: ScanResult): string {\n return JSON.stringify(\n {\n version: getVersion(),\n project: result.context.rootDir,\n fileCount: result.context.files.length,\n totalLines: result.context.totalLines,\n dominantLanguage: result.context.dominantLanguage,\n scanTimeMs: result.scanTimeMs,\n scores: result.scores,\n compositeScore: result.compositeScore,\n maxCompositeScore: result.maxCompositeScore,\n findings: result.findings,\n deepInsights: result.deepInsights,\n perFileScores: Object.fromEntries(result.perFileScores),\n },\n null,\n 2,\n );\n}\n","export function scoreBar(score: number, max: number, width = 20): string {\n const filled = Math.round((score / max) * width);\n return \"\\u2588\".repeat(filled) + \"\\u2591\".repeat(width - filled);\n}\n\nexport function padRight(str: string, len: number): string {\n return str + \" \".repeat(Math.max(0, len - str.length));\n}\n","import type { ScanResult, Finding, DriftFindingReport } from \"../core/types.js\";\nimport { getVersion } from \"../core/version.js\";\n\nfunction esc(s: string): string {\n return s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\");\n}\n\nfunction gradeFor(score: number, max: number): { letter: string; color: string } {\n const pct = max > 0 ? (score / max) * 100 : 0;\n if (pct >= 90) return { letter: \"A\", color: \"var(--grade-a)\" };\n if (pct >= 75) return { letter: \"B\", color: \"var(--grade-b)\" };\n if (pct >= 50) return { letter: \"C\", color: \"var(--grade-c)\" };\n if (pct >= 25) return { letter: \"D\", color: \"var(--grade-d)\" };\n return { letter: \"F\", color: \"var(--grade-f)\" };\n}\n\nfunction sevColor(sev: string): string {\n if (sev === \"error\") return \"var(--drift-red)\";\n if (sev === \"warning\") return \"var(--drift-orange)\";\n return \"var(--info-blue)\";\n}\n\nfunction sevLabel(sev: string): string {\n if (sev === \"error\") return \"CRITICAL\";\n if (sev === \"warning\") return \"WARNING\";\n return \"INFO\";\n}\n\nfunction scoreColor(score: number): string {\n if (score <= 25) return \"var(--drift-red)\";\n if (score <= 50) return \"var(--drift-orange)\";\n if (score <= 75) return \"var(--drift-amber)\";\n if (score <= 90) return \"var(--grade-b)\";\n return \"var(--grade-a)\";\n}\n\nfunction shortPath(p: string): string {\n const parts = p.split(\"/\");\n return parts.length > 3 ? \".../\" + parts.slice(-2).join(\"/\") : p;\n}\n\n// ──── Extract intent patterns from drift findings ────\n\ninterface IntentPattern {\n category: string;\n label: string;\n dominantCount: number;\n totalRelevant: number;\n consistency: number;\n}\n\nfunction extractIntentPatterns(result: ScanResult): IntentPattern[] {\n const patterns: IntentPattern[] = [];\n const seen = new Set<string>();\n\n for (const d of (result.driftFindings ?? [])) {\n const key = d.driftCategory + \"::\" + (d.subCategory ?? \"\") + \"::\" + d.dominantPattern;\n if (seen.has(key)) continue;\n seen.add(key);\n\n // Use subCategory for architectural_consistency to get precise labels\n const subCatNames: Record<string, string> = {\n data_access: \"Data Access\",\n error_handling: \"Error Handling\",\n dependency_injection: \"Dependency Injection\",\n configuration: \"Configuration\",\n };\n\n const catNames: Record<string, string> = {\n architectural_consistency: \"Architecture\",\n security_posture: \"Security\",\n semantic_duplication: \"Duplication\",\n naming_conventions: \"Naming\",\n phantom_scaffolding: \"Scaffolding\",\n };\n\n // Prefer subCategory label for architectural findings, fallback to category\n const category = (d.driftCategory === \"architectural_consistency\" && d.subCategory)\n ? (subCatNames[d.subCategory] ?? catNames[d.driftCategory] ?? d.driftCategory)\n : (catNames[d.driftCategory] ?? d.driftCategory);\n\n // Skip \"no clear dominant\" cards — they add confusion, not clarity\n if (d.consistencyScore < 60) continue;\n\n patterns.push({\n category,\n label: d.dominantPattern,\n dominantCount: d.dominantCount,\n totalRelevant: d.totalRelevantFiles,\n consistency: d.consistencyScore,\n });\n }\n\n // Add Code DNA patterns\n const dna = result.codeDnaResult;\n if (dna?.patternDistributions?.length > 0) {\n const patternCounts = new Map<string, number>();\n for (const pd of dna.patternDistributions) {\n patternCounts.set(pd.dominantPattern, (patternCounts.get(pd.dominantPattern) ?? 0) + 1);\n }\n let dominant = \"\";\n let maxC = 0;\n for (const [p, c] of patternCounts) {\n if (c > maxC) { maxC = c; dominant = p; }\n }\n if (dominant && !seen.has(\"codedna::\" + dominant)) {\n patterns.push({\n category: \"Architecture\",\n label: dominant,\n dominantCount: maxC,\n totalRelevant: dna.patternDistributions.length,\n consistency: Math.round((maxC / dna.patternDistributions.length) * 100),\n });\n }\n }\n\n return patterns;\n}\n\n// ──── Build coherence data per file ────\n\ninterface FileCoherence {\n path: string;\n score: number;\n alignments: { category: string; matches: boolean; actual?: string }[];\n alignmentPct: number;\n driftCount: number;\n staticCount: number;\n}\n\nfunction buildDriftFileMap(result: ScanResult): Map<string, { category: string; pattern: string }[]> {\n const driftFiles = new Map<string, { category: string; pattern: string }[]>();\n for (const d of (result.driftFindings ?? [])) {\n for (const df of d.deviatingFiles) {\n if (!driftFiles.has(df.path)) driftFiles.set(df.path, []);\n const catKey = (d.driftCategory === \"architectural_consistency\" && d.subCategory)\n ? d.driftCategory + \"::\" + d.subCategory\n : d.driftCategory;\n driftFiles.get(df.path)!.push({ category: catKey, pattern: df.detectedPattern });\n }\n }\n return driftFiles;\n}\n\nfunction buildCategorySet(result: ScanResult): Map<string, string> {\n const subCatNames: Record<string, string> = {\n data_access: \"Data Access\",\n error_handling: \"Error Handling\",\n dependency_injection: \"Dep. Injection\",\n configuration: \"Configuration\",\n };\n const baseCatNames: Record<string, string> = {\n security_posture: \"Security\",\n naming_conventions: \"Naming\",\n phantom_scaffolding: \"Scaffolding\",\n };\n\n const catSet = new Map<string, string>();\n for (const d of (result.driftFindings ?? [])) {\n if (d.driftCategory === \"architectural_consistency\" && d.subCategory) {\n const label = subCatNames[d.subCategory] ?? d.subCategory;\n catSet.set(d.driftCategory + \"::\" + d.subCategory, label);\n } else if (baseCatNames[d.driftCategory]) {\n catSet.set(d.driftCategory, baseCatNames[d.driftCategory]);\n }\n }\n return catSet;\n}\n\nfunction buildCodeDnaPatternData(result: ScanResult): { projectDominantPattern: string; filePatternMap: Map<string, string> } {\n const filePatternMap = new Map<string, string>();\n let projectDominantPattern = \"\";\n const dna = result.codeDnaResult;\n\n if (dna?.patternDistributions?.length > 0) {\n const patternCounts = new Map<string, number>();\n for (const pd of dna.patternDistributions) {\n if (pd.dominantPattern !== \"none\") {\n patternCounts.set(pd.dominantPattern, (patternCounts.get(pd.dominantPattern) ?? 0) + 1);\n }\n filePatternMap.set(pd.relativePath, pd.dominantPattern);\n }\n let maxC = 0;\n for (const [p, c] of patternCounts) {\n if (c > maxC) { maxC = c; projectDominantPattern = p; }\n }\n }\n return { projectDominantPattern, filePatternMap };\n}\n\nfunction buildFileCoherence(result: ScanResult): FileCoherence[] {\n const entries = [...result.perFileScores.entries()];\n const driftFiles = buildDriftFileMap(result);\n const catSet = buildCategorySet(result);\n\n const { projectDominantPattern, filePatternMap } = buildCodeDnaPatternData(result);\n if (projectDominantPattern) {\n catSet.set(\"codedna_architecture\", \"Architecture\");\n }\n\n const categories = [...catSet.values()];\n const catKeys = [...catSet.keys()];\n\n return entries.map(([path, data]) => {\n const deviations = driftFiles.get(path) ?? [];\n const alignments = catKeys.map((key, i) => {\n if (key === \"codedna_architecture\") {\n // Check file's pattern against project dominant\n const filePattern = filePatternMap.get(path);\n if (!filePattern || filePattern === \"none\") {\n return { category: categories[i], matches: true }; // no pattern data = assume aligned\n }\n const matches = filePattern === projectDominantPattern;\n return { category: categories[i], matches, actual: matches ? undefined : filePattern };\n }\n const dev = deviations.find((d) => d.category === key);\n return { category: categories[i], matches: !dev, actual: dev?.pattern };\n });\n const matchCount = alignments.filter((a) => a.matches).length;\n const driftCount = data.findings.filter((f) => f.tags?.includes(\"drift\") || f.tags?.includes(\"codedna\")).length;\n const staticCount = data.findings.filter((f) => !f.tags?.includes(\"drift\") && !f.tags?.includes(\"codedna\")).length;\n\n return {\n path,\n score: data.score,\n alignments,\n alignmentPct: categories.length > 0 ? Math.round((matchCount / categories.length) * 100) : 100,\n driftCount,\n staticCount,\n };\n }).sort((a, b) => a.alignmentPct - b.alignmentPct || a.score - b.score);\n}\n\n// ──── Section Builders ────\n\nfunction buildHeader(result: ScanResult): string {\n const name = result.context.rootDir.split(\"/\").pop() ?? \"project\";\n const date = new Date().toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\", year: \"numeric\" });\n const time = (result.scanTimeMs / 1000).toFixed(1);\n const langs = [...result.context.languageBreakdown.entries()]\n .sort((a, b) => b[1].files - a[1].files)\n .map(([l, s]) => `${l.charAt(0).toUpperCase() + l.slice(1)} (${Math.round((s.files / result.context.files.length) * 100)}%)`)\n .join(\", \");\n\n return `<header id=\"report-header\" style=\"padding:32px 0 24px;border-bottom:1px solid var(--border)\">\n <div style=\"display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:8px\">\n <div>\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:4px\"><span style=\"display:inline-block;width:10px;height:10px;background:var(--brand-cyan)\"></span><span class=\"label\" style=\"margin-bottom:0;letter-spacing:2px\">VIBEDRIFT REPORT</span></div>\n <div class=\"heading\" style=\"font-size:24px;font-weight:700;color:var(--text-primary);text-transform:uppercase;letter-spacing:-0.5px\">${esc(name)}</div>\n </div>\n <div style=\"text-align:right;font-size:13px;color:var(--text-secondary)\">\n <div>${date} · ${time}s</div>\n <div>${result.context.files.length} files · ${result.context.totalLines.toLocaleString()} LOC</div>\n <div style=\"color:var(--text-tertiary)\">${langs}</div>\n </div>\n </div>\n</header>`;\n}\n\nfunction buildIntentDefinition(patterns: IntentPattern[]): string {\n if (patterns.length === 0) return \"\";\n\n const cards = patterns.map((p) => {\n return `<div style=\"background:var(--bg-surface);border-left:3px solid var(--intent-green);border-radius:0;padding:14px 16px;min-width:160px;flex:1\">\n <div class=\"label\" style=\"color:var(--text-tertiary)\">${esc(p.category)}</div>\n <div style=\"font-size:14px;font-weight:500;color:var(--text-primary);margin:4px 0\">${esc(p.label)}</div>\n <div class=\"mono\" style=\"font-size:12px;color:var(--intent-green)\">${p.dominantCount} of ${p.totalRelevant} files (${p.consistency}%)</div>\n </div>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">CODEBASE INTENT</div>\n <div style=\"display:flex;gap:12px;flex-wrap:wrap\">${cards}</div>\n</section>`;\n}\n\nfunction buildCoherenceMatrix(files: FileCoherence[]): string {\n if (files.length === 0) return \"\";\n\n const categories = files[0]?.alignments.map((a) => a.category) ?? [];\n if (categories.length === 0) return \"\";\n\n // Split into aligned (100%) and drifting\n const aligned = files.filter((f) => f.alignmentPct === 100);\n const drifting = files.filter((f) => f.alignmentPct < 100).sort((a, b) => a.alignmentPct - b.alignmentPct);\n\n const colHeaders = categories.map((c) =>\n `<th style=\"padding:6px 12px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;text-align:center;font-weight:600\">${esc(c)}</th>`\n ).join(\"\");\n\n function buildAlignmentCells(f: FileCoherence): { cells: string; deviations: string[] } {\n const deviations: string[] = [];\n const cells = f.alignments.map((a) => {\n if (a.matches) return `<td style=\"text-align:center;padding:6px 12px;color:var(--intent-green);font-size:14px\">●</td>`;\n const devColor = f.alignmentPct <= 25 ? \"var(--drift-red)\" : f.alignmentPct <= 50 ? \"var(--drift-orange)\" : \"var(--drift-amber)\";\n deviations.push(`${a.category}: ${a.actual ?? \"deviates\"}`);\n return `<td style=\"text-align:center;padding:6px 12px;color:${devColor};font-size:13px\" data-tooltip=\"${esc(a.actual ?? \"deviates\")}\">◆</td>`;\n }).join(\"\");\n return { cells, deviations };\n }\n\n function buildDeviationSummary(deviations: string[]): string {\n return deviations.length > 0\n ? `<td style=\"padding:6px 12px;font-size:11px;color:var(--text-secondary);max-width:250px\">${deviations.map((d) => esc(d)).join(\"; \")}</td>`\n : `<td style=\"padding:6px 12px;font-size:11px;color:var(--intent-green)\">Fully aligned</td>`;\n }\n\n function fileRow(f: FileCoherence, open?: boolean): string {\n const pctColor = f.alignmentPct >= 100 ? \"var(--intent-green)\" : f.alignmentPct >= 50 ? \"var(--drift-amber)\" : \"var(--drift-red)\";\n const bgTint = f.alignmentPct < 50 ? \"var(--tint-red)\" : f.alignmentPct < 100 ? \"var(--tint-amber)\" : \"transparent\";\n const { cells, deviations } = buildAlignmentCells(f);\n const summary = buildDeviationSummary(deviations);\n\n return `<tr style=\"background:${bgTint}\" id=\"file-${esc(f.path.replace(/[^a-zA-Z0-9]/g, \"-\"))}\">\n <td class=\"mono\" style=\"padding:6px 12px;font-size:12px;color:var(--text-secondary);white-space:nowrap;max-width:280px;overflow:hidden;text-overflow:ellipsis\" data-scroll-to=\"rank-${esc(f.path.replace(/[^a-zA-Z0-9]/g, \"-\"))}\">${esc(f.path)}</td>\n ${cells}\n <td class=\"mono\" style=\"padding:6px 12px;text-align:right;font-weight:600;color:${pctColor}\">${f.alignmentPct}%</td>\n ${summary}\n </tr>`;\n }\n\n const colCount = categories.length + 3; // file + categories + align + summary\n\n // Show first 3 aligned, then collapse rest\n const alignedRows = aligned.slice(0, 3).map((f) => fileRow(f)).join(\"\");\n const collapsedAligned = aligned.length > 3\n ? `<tr><td colspan=\"${colCount}\" style=\"padding:6px 12px;font-size:12px;color:var(--text-tertiary);cursor:pointer\" data-collapse=\"aligned-rest\">··· ${aligned.length - 3} more at 100% ···</td></tr>\n <tbody id=\"aligned-rest\" style=\"display:none\">${aligned.slice(3).map((f) => fileRow(f)).join(\"\")}</tbody>` : \"\";\n\n // Collapse files with identical single-issue deviations to reduce noise\n // e.g., \"8 files deviate on naming only (camelCase)\" as a collapsed row\n const singleIssueDrifting = new Map<string, FileCoherence[]>(); // deviation key → files\n const multiIssueDrifting: FileCoherence[] = [];\n\n for (const f of drifting) {\n const devs = f.alignments.filter((a) => !a.matches);\n if (devs.length === 1) {\n const key = `${devs[0].category}: ${devs[0].actual ?? \"deviates\"}`;\n if (!singleIssueDrifting.has(key)) singleIssueDrifting.set(key, []);\n singleIssueDrifting.get(key)!.push(f);\n } else {\n multiIssueDrifting.push(f);\n }\n }\n\n // Render multi-issue files individually (these are the interesting ones)\n let driftingRows = multiIssueDrifting.map((f) => fileRow(f)).join(\"\");\n\n // Render single-issue groups: if >=4 files share the same deviation, collapse them\n for (const [devKey, files2] of singleIssueDrifting) {\n if (files2.length >= 4) {\n // Show first file, then collapse the rest\n driftingRows += fileRow(files2[0]);\n const collapseId = `single-dev-${devKey.replace(/[^a-zA-Z0-9]/g, \"-\")}`;\n driftingRows += `<tr><td colspan=\"${colCount}\" style=\"padding:4px 12px;font-size:12px;color:var(--text-tertiary);cursor:pointer\" data-collapse=\"${collapseId}\">··· ${files2.length - 1} more files with same issue (${esc(devKey)}) ···</td></tr>`;\n driftingRows += `<tbody id=\"${collapseId}\" style=\"display:none\">${files2.slice(1).map((f) => fileRow(f)).join(\"\")}</tbody>`;\n } else {\n driftingRows += files2.map((f) => fileRow(f)).join(\"\");\n }\n }\n\n // Summary bar\n const total = files.length;\n const fullAlign = aligned.length;\n const partial = drifting.filter((f) => f.alignmentPct >= 50).length;\n const significant = drifting.filter((f) => f.alignmentPct > 0 && f.alignmentPct < 50).length;\n const critical = drifting.filter((f) => f.alignmentPct === 0).length;\n const coherencePct = total > 0 ? Math.round((fullAlign / total) * 100) : 100;\n\n const barSegments = [\n { pct: (fullAlign / total) * 100, color: \"var(--intent-green)\" },\n { pct: (partial / total) * 100, color: \"var(--drift-amber)\" },\n { pct: (significant / total) * 100, color: \"var(--drift-orange)\" },\n { pct: (critical / total) * 100, color: \"var(--drift-red)\" },\n ].filter((s) => s.pct > 0).map((s) =>\n `<div style=\"width:${s.pct}%;height:100%;background:${s.color}\"></div>`\n ).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">INTENT COHERENCE</div>\n <div style=\"display:flex;gap:20px;margin-bottom:16px;font-size:12px;color:var(--text-secondary);flex-wrap:wrap;align-items:center\">\n <span style=\"display:flex;align-items:center;gap:5px\"><span style=\"color:var(--intent-green);font-size:14px\">●</span> Follows dominant pattern</span>\n <span style=\"display:flex;align-items:center;gap:5px\"><span style=\"color:var(--drift-amber);font-size:13px\">◆</span> Deviates from intent</span>\n <span style=\"display:flex;align-items:center;gap:5px\"><span style=\"color:var(--drift-orange);font-size:13px\">◆</span> Multiple deviations</span>\n <span style=\"display:flex;align-items:center;gap:5px\"><span style=\"color:var(--drift-red);font-size:13px\">◆</span> Critical drift</span>\n </div>\n <div style=\"overflow-x:auto\">\n <table style=\"width:100%;border-collapse:collapse;font-size:13px\">\n <thead><tr style=\"border-bottom:1px solid var(--border)\">\n <th style=\"padding:6px 12px;text-align:left;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">File</th>\n ${colHeaders}\n <th style=\"padding:6px 12px;text-align:right;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Align</th>\n <th style=\"padding:6px 12px;text-align:left;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Issue</th>\n </tr></thead>\n <tbody>\n ${driftingRows}\n ${alignedRows}\n ${collapsedAligned}\n </tbody>\n </table>\n </div>\n <div style=\"margin-top:16px\">\n <div style=\"display:flex;height:6px;border-radius:0;overflow:hidden;gap:2px\">${barSegments}</div>\n <div style=\"display:flex;gap:16px;margin-top:6px;font-size:12px;color:var(--text-tertiary);flex-wrap:wrap\">\n <span style=\"color:var(--intent-green)\">${fullAlign} aligned</span>\n ${partial > 0 ? `<span style=\"color:var(--drift-amber)\">${partial} partial</span>` : \"\"}\n ${significant > 0 ? `<span style=\"color:var(--drift-orange)\">${significant} significant</span>` : \"\"}\n ${critical > 0 ? `<span style=\"color:var(--drift-red)\">${critical} critical</span>` : \"\"}\n <span style=\"margin-left:auto;font-weight:500;color:var(--text-secondary)\">${coherencePct}% intent coherence</span>\n </div>\n </div>\n</section>`;\n}\n\nfunction buildAiSummaryWidget(result: ScanResult): string {\n const ai = result.aiSummary;\n if (!ai) return \"\";\n\n const highlights = (ai.highlights ?? []).map((h) =>\n `<li style=\"margin:4px 0;font-size:13px;color:var(--text-primary)\">${esc(h)}</li>`\n ).join(\"\");\n\n return `<section class=\"section\" style=\"margin-bottom:32px\">\n <div style=\"background:rgba(255,208,0,0.03);border:1px solid var(--border);border-radius:0;padding:24px 28px;position:relative;overflow:hidden\">\n <div style=\"position:absolute;top:0;left:0;width:3px;height:100%;background:var(--border)\"></div>\n <div class=\"score-layout\" style=\"display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap\">\n <div style=\"flex:1;min-width:280px\">\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:10px\">\n <span style=\"font-size:16px\">🤖</span>\n <span class=\"label\" style=\"margin-bottom:0\">AI SUMMARY</span>\n </div>\n <p style=\"font-size:15px;color:var(--text-primary);line-height:1.7;margin:0\">${esc(ai.summary)}</p>\n </div>\n ${highlights ? `<div style=\"min-width:200px;max-width:300px;background:var(--bg-surface);border-radius:0;padding:14px 18px\">\n <div style=\"font-size:11px;font-weight:600;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:1px;margin-bottom:8px\">Key Takeaways</div>\n <ul style=\"list-style:none;padding:0;margin:0\">${highlights}</ul>\n </div>` : \"\"}\n </div>\n <div style=\"margin-top:10px;font-size:10px;color:var(--text-tertiary)\">Generated by Claude Haiku</div>\n </div>\n</section>`;\n}\n\nfunction getDriftCats(result: ScanResult) {\n const ds = result.driftScores ?? {};\n return [\n { name: \"Architectural Consistency\", shortName: \"Architecture\", score: ds.architectural_consistency?.score ?? 0, max: ds.architectural_consistency?.maxScore ?? 25, findings: ds.architectural_consistency?.findings ?? 0 },\n { name: \"Security Posture\", shortName: \"Security\", score: ds.security_posture?.score ?? 0, max: ds.security_posture?.maxScore ?? 25, findings: ds.security_posture?.findings ?? 0 },\n { name: \"Semantic Duplication\", shortName: \"Duplication\", score: ds.semantic_duplication?.score ?? 0, max: ds.semantic_duplication?.maxScore ?? 20, findings: ds.semantic_duplication?.findings ?? 0 },\n { name: \"Convention Drift\", shortName: \"Conventions\", score: ds.naming_conventions?.score ?? 0, max: ds.naming_conventions?.maxScore ?? 15, findings: ds.naming_conventions?.findings ?? 0 },\n { name: \"Phantom Scaffolding\", shortName: \"Scaffolding\", score: ds.phantom_scaffolding?.score ?? 0, max: ds.phantom_scaffolding?.maxScore ?? 15, findings: ds.phantom_scaffolding?.findings ?? 0 },\n ];\n}\n\nfunction buildScoreSection(result: ScanResult): string {\n const { compositeScore, maxCompositeScore } = result;\n const { letter, color } = gradeFor(compositeScore, maxCompositeScore);\n const cats = getDriftCats(result);\n\n const bars = cats.map((c) => {\n const pct = c.max > 0 ? (c.score / c.max) * 100 : 0;\n const { color: barColor } = gradeFor(c.score, c.max);\n return `<div style=\"display:flex;align-items:center;gap:10px;margin:6px 0\">\n <span style=\"font-size:13px;color:var(--text-primary);min-width:190px\">${esc(c.name)}</span>\n <div style=\"flex:1;height:6px;border-radius:0;background:var(--border)\"><div style=\"width:${pct}%;height:100%;border-radius:0;background:${barColor}\"></div></div>\n <span class=\"mono\" style=\"font-size:12px;font-weight:600;color:${barColor};min-width:50px;text-align:right\">${c.score}/${c.max}</span>\n </div>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">SCORE OVERVIEW</div>\n <div class=\"score-layout\" style=\"display:flex;gap:40px;align-items:flex-start;flex-wrap:wrap\">\n <div style=\"text-align:center;min-width:120px\">\n <div class=\"mono\" style=\"font-size:72px;font-weight:800;color:${color};line-height:1\">${compositeScore}</div>\n <div class=\"mono\" style=\"font-size:16px;color:var(--text-tertiary)\">/ ${maxCompositeScore}</div>\n <div style=\"margin-top:8px\"><span style=\"display:inline-block;padding:4px 14px;border-radius:0;font-size:14px;font-weight:600;background:${color}18;color:${color}\">Grade ${letter}</span></div>\n </div>\n <div style=\"flex:1;min-width:300px\">${bars}</div>\n </div>\n</section>`;\n}\n\nfunction buildRadarSection(result: ScanResult): string {\n const cats = getDriftCats(result);\n const n = cats.length;\n if (n === 0) return \"\";\n\n // Wider viewBox (520x440) so labels on left/right/bottom aren't clipped.\n // Center shifted right to 260 and down to 200 to balance label room.\n const cx = 260, cy = 200, r = 130, step = (2 * Math.PI) / n;\n let grid = \"\", dots = \"\", labels = \"\";\n const pts: string[] = [];\n\n // Concentric rings with percentage labels\n for (const ring of [0.25, 0.5, 0.75, 1.0]) {\n grid += `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${r * ring}\" fill=\"none\" stroke=\"#1E2A3A\" stroke-width=\"${ring === 1 ? \"1\" : \"0.5\"}\" stroke-dasharray=\"${ring < 1 ? \"3,3\" : \"none\"}\"/>`;\n if (ring < 1) {\n grid += `<text x=\"${cx + 4}\" y=\"${cy - r * ring + 4}\" fill=\"#3A4555\" font-size=\"9\" font-family=\"-apple-system,sans-serif\">${Math.round(ring * 100)}%</text>`;\n }\n }\n\n // Axis lines and data points\n for (let i = 0; i < n; i++) {\n const a = -Math.PI / 2 + i * step;\n const ex = cx + r * Math.cos(a), ey = cy + r * Math.sin(a);\n grid += `<line x1=\"${cx}\" y1=\"${cy}\" x2=\"${ex}\" y2=\"${ey}\" stroke=\"#1E2A3A\" stroke-width=\"0.5\"/>`;\n\n const ratio = cats[i].max > 0 ? cats[i].score / cats[i].max : 0;\n const px = cx + r * ratio * Math.cos(a), py = cy + r * ratio * Math.sin(a);\n pts.push(`${px},${py}`);\n dots += `<circle cx=\"${px}\" cy=\"${py}\" r=\"5\" fill=\"var(--text-secondary)\" stroke=\"var(--bg-page)\" stroke-width=\"2\"/>`;\n\n // Labels: full name + score\n const labelDist = r + 35;\n const lx = cx + labelDist * Math.cos(a), ly = cy + labelDist * Math.sin(a);\n const anchor = Math.abs(Math.cos(a)) < 0.3 ? \"middle\" : Math.cos(a) > 0 ? \"start\" : \"end\";\n const { color: catColor } = gradeFor(cats[i].score, cats[i].max);\n labels += `<text x=\"${lx}\" y=\"${ly - 7}\" fill=\"${catColor}\" font-size=\"12\" font-weight=\"600\" font-family=\"-apple-system,sans-serif\" text-anchor=\"${anchor}\" dominant-baseline=\"middle\">${esc(cats[i].shortName)}</text>`;\n labels += `<text x=\"${lx}\" y=\"${ly + 8}\" fill=\"#5A6A7E\" font-size=\"11\" font-weight=\"500\" font-family=\"'SF Mono',Consolas,monospace\" text-anchor=\"${anchor}\" dominant-baseline=\"middle\">${cats[i].score}/${cats[i].max} ${cats[i].findings > 0 ? \"(\" + cats[i].findings + \" issues)\" : \"\"}</text>`;\n }\n\n const radar = `<svg viewBox=\"0 0 520 440\" style=\"width:100%;max-width:560px;height:auto;margin:0 auto;display:block\">${grid}<polygon points=\"${pts.join(\" \")}\" fill=\"rgba(255,208,0,0.04)\" stroke=\"rgba(255,208,0,0.3)\" stroke-width=\"1.5\"/>${dots}${labels}</svg>`;\n\n // Find the weakest category for the description\n const weakest = [...cats].sort((a, b) => {\n const pctA = a.max > 0 ? a.score / a.max : 1;\n const pctB = b.max > 0 ? b.score / b.max : 1;\n return pctA - pctB;\n })[0];\n const weakPct = weakest.max > 0 ? Math.round((weakest.score / weakest.max) * 100) : 100;\n\n const strongest = [...cats].sort((a, b) => {\n const pctA = a.max > 0 ? a.score / a.max : 0;\n const pctB = b.max > 0 ? b.score / b.max : 0;\n return pctB - pctA;\n })[0];\n const strongPct = strongest.max > 0 ? Math.round((strongest.score / strongest.max) * 100) : 0;\n\n return `<section class=\"section\">\n <div class=\"label\">DRIFT FINGERPRINT</div>\n <p style=\"font-size:13px;color:var(--text-secondary);margin-bottom:20px;line-height:1.6\">\n This radar shows how well your codebase maintains consistency across 5 drift categories.\n The outer edge represents a perfect score in each category. Points closer to the center indicate more drift.\n A balanced shape means consistent quality; an uneven shape reveals where drift concentrates.\n </p>\n ${radar}\n <div style=\"display:flex;gap:20px;justify-content:center;margin-top:20px;flex-wrap:wrap\">\n <div style=\"background:var(--bg-surface);border-radius:0;padding:12px 18px;text-align:center;min-width:160px\">\n <div style=\"font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:1px;margin-bottom:4px\">Strongest</div>\n <div style=\"font-size:15px;font-weight:600;color:var(--intent-green)\">${esc(strongest.shortName)}</div>\n <div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\">${strongPct}% health</div>\n </div>\n <div style=\"background:var(--bg-surface);border-radius:0;padding:12px 18px;text-align:center;min-width:160px\">\n <div style=\"font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:1px;margin-bottom:4px\">Needs Attention</div>\n <div style=\"font-size:15px;font-weight:600;color:var(--drift-orange)\">${esc(weakest.shortName)}</div>\n <div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\">${weakPct}% health${weakest.findings > 0 ? \" · \" + weakest.findings + \" issues\" : \"\"}</div>\n </div>\n </div>\n</section>`;\n}\n\nfunction buildFixFirst(result: ScanResult): string {\n // Category importance: architectural issues always outrank convention issues\n // regardless of how many files are affected. Renaming files is cosmetic\n // compared to fixing raw SQL vs repository pattern inconsistencies.\n const catWeight: Record<string, number> = {\n architectural_consistency: 10,\n security_posture: 8,\n semantic_duplication: 6,\n phantom_scaffolding: 3,\n naming_conventions: 1,\n };\n\n const ranked = [...(result.driftFindings ?? [])].sort((a, b) => {\n const sev = { error: 3, warning: 2, info: 1 };\n const wA = (catWeight[a.driftCategory] ?? 1) * (sev[a.severity as keyof typeof sev] ?? 0);\n const wB = (catWeight[b.driftCategory] ?? 1) * (sev[b.severity as keyof typeof sev] ?? 0);\n if (wB !== wA) return wB - wA;\n // Tiebreak by file count\n return b.deviatingFiles.length - a.deviatingFiles.length;\n }).slice(0, 3);\n\n if (ranked.length === 0) return \"\";\n\n const cards = ranked.map((d, i) => {\n const severity = d.severity === \"error\" ? \"CRITICAL\" : d.severity === \"warning\" ? \"HIGH\" : \"MEDIUM\";\n const sColor = sevColor(d.severity);\n const files = d.deviatingFiles.map((f) => f.path).slice(0, 3);\n\n // Make recommendations specific with file names and code references\n let recText = d.recommendation ?? \"\";\n let exampleRef = \"\";\n if (d.deviatingFiles.length > 0) {\n const firstDev = d.deviatingFiles[0];\n const firstEvidence = firstDev.evidence?.[0];\n // Find files that follow the dominant pattern (for \"see example in...\" reference)\n const allFiles = [...(result.perFileScores?.keys() ?? [])];\n const deviatingPaths = new Set(d.deviatingFiles.map((f) => f.path));\n const dominantFiles = allFiles.filter((f) => !deviatingPaths.has(f));\n\n if (recText.includes(\"Migrate deviating files\") || recText.includes(\"Standardize deviating\")) {\n const fileNames = d.deviatingFiles.slice(0, 3).map((f) => f.path.split(\"/\").pop()).join(\", \");\n recText = `In ${fileNames}${d.deviatingFiles.length > 3 ? ` (+${d.deviatingFiles.length - 3} more)` : \"\"}: replace ${firstDev.detectedPattern} with the dominant ${d.dominantPattern} pattern (used by ${d.dominantCount}/${d.totalRelevantFiles} files).`;\n if (firstEvidence) {\n recText += ` See ${firstDev.path.split(\"/\").pop()}:${firstEvidence.line}.`;\n }\n }\n // Add example reference file that follows the dominant pattern\n if (dominantFiles.length > 0) {\n const example = dominantFiles.find((f) => f.includes(\"handler\") || f.includes(\"service\")) ?? dominantFiles[0];\n exampleRef = `Follow the pattern in ${example.split(\"/\").pop()}`;\n }\n }\n\n return `<div style=\"background:var(--bg-surface);border-radius:0;padding:20px 24px;margin-bottom:12px;border-left:3px solid ${sColor}\">\n <div style=\"display:flex;align-items:center;gap:10px;margin-bottom:10px\">\n <span class=\"mono\" style=\"font-size:28px;font-weight:800;color:var(--text-tertiary)\">${i + 1}</span>\n <span class=\"sev-badge\" style=\"background:${sColor}\">${severity}</span>\n </div>\n <p style=\"font-size:15px;font-weight:500;color:var(--text-primary);line-height:1.6;margin:0 0 8px\">${esc(recText)}</p>\n <p style=\"font-size:13px;color:var(--text-secondary);margin:0 0 8px\">Impact: Resolves ${d.deviatingFiles.length} deviating file${d.deviatingFiles.length > 1 ? \"s\" : \"\"} in ${d.driftCategory.replace(/_/g, \" \")}.${exampleRef ? \" \" + esc(exampleRef) + \".\" : \"\"}</p>\n <div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\">${files.map((f) => esc(f)).join(\" · \")}</div>\n </div>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">FIX FIRST</div>\n ${cards}\n</section>`;\n}\n\nfunction buildDeviatingBlocks(d: DriftFindingReport): string {\n const isConvention = d.driftCategory === \"naming_conventions\";\n const devByPattern = new Map<string, typeof d.deviatingFiles>();\n for (const df of d.deviatingFiles) {\n const key = df.detectedPattern;\n if (!devByPattern.has(key)) devByPattern.set(key, []);\n devByPattern.get(key)!.push(df);\n }\n\n if (isConvention && d.deviatingFiles.length > 4) {\n return [...devByPattern.entries()].map(([pattern, files]) => {\n const fileList = files.map((df) => esc(df.path)).join(\"</div><div style='padding:1px 0'>\");\n const collapseId = `conv-${pattern.replace(/[^a-zA-Z0-9]/g, \"-\")}-${Math.random().toString(36).slice(2, 6)}`;\n return `<div style=\"background:var(--tint-orange);border-left:3px solid var(--drift-orange);border-radius:0;padding:12px 16px;margin:8px 0\">\n <div class=\"label\" style=\"color:var(--drift-orange);margin-bottom:4px\">DRIFT — ${esc(pattern)} — ${files.length} files</div>\n <div style=\"cursor:pointer;font-size:12px;color:var(--text-secondary);margin-top:6px\" data-collapse=\"${collapseId}\">▶ Show ${files.length} files</div>\n <div id=\"${collapseId}\" style=\"display:none;padding:6px 0\" class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\"><div style=\"padding:1px 0\">${fileList}</div></div>\n </div>`;\n }).join(\"\");\n }\n\n return d.deviatingFiles.slice(0, 4).map((df) => {\n const evidence = df.evidence.slice(0, 3).map((e) =>\n `<div style=\"background:var(--bg-code);padding:6px 12px;border-radius:0;margin:4px 0;overflow-x:auto\" class=\"mono\"><span style=\"color:var(--text-tertiary);margin-right:12px;user-select:none\">${e.line}</span>${esc(e.code.slice(0, 120))}</div>`\n ).join(\"\");\n return `<div style=\"background:var(--tint-orange);border-left:3px solid var(--drift-orange);border-radius:0;padding:12px 16px;margin:8px 0\">\n <div class=\"label\" style=\"color:var(--drift-orange);margin-bottom:4px\">DRIFT — ${esc(df.detectedPattern)}</div>\n <div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary);margin-bottom:6px\">${esc(df.path)}</div>\n ${evidence}\n </div>`;\n }).join(\"\");\n}\n\nfunction buildDriftRecommendation(d: DriftFindingReport): string {\n let recText = d.recommendation ?? \"\";\n if (recText && d.deviatingFiles.length > 0) {\n const firstDev = d.deviatingFiles[0];\n const firstEvidence = firstDev.evidence?.[0];\n if (recText.includes(\"Migrate deviating files\") || recText.includes(\"Standardize deviating\")) {\n const fileList = d.deviatingFiles.slice(0, 3).map((f) => f.path.split(\"/\").pop()).join(\", \");\n recText = `In ${fileList}${d.deviatingFiles.length > 3 ? ` (+${d.deviatingFiles.length - 3} more)` : \"\"}: replace ${firstDev.detectedPattern} with the dominant ${d.dominantPattern} pattern (used by ${d.dominantCount}/${d.totalRelevantFiles} files).`;\n if (firstEvidence) {\n recText += ` Example: ${firstDev.path.split(\"/\").pop()}:${firstEvidence.line} currently uses ${firstDev.detectedPattern}.`;\n }\n }\n }\n return recText;\n}\n\nfunction buildDistributionBar(d: DriftFindingReport): string {\n const domPct = d.totalRelevantFiles > 0 ? Math.round((d.dominantCount / d.totalRelevantFiles) * 100) : 0;\n const devPct = 100 - domPct;\n return `<div style=\"margin:12px 0\">\n <div style=\"display:flex;height:6px;border-radius:0;overflow:hidden;gap:2px\">\n <div style=\"width:${domPct}%;background:var(--intent-green);border-radius:0\"></div>\n <div style=\"width:${devPct}%;background:var(--drift-orange);border-radius:0\"></div>\n </div>\n <div style=\"display:flex;gap:16px;margin-top:4px;font-size:11px;color:var(--text-tertiary)\">\n <span>${esc(d.dominantPattern)} (${d.dominantCount})</span>\n <span>Deviating (${d.totalRelevantFiles - d.dominantCount})</span>\n <span style=\"margin-left:auto\">${d.consistencyScore}% consistent</span>\n </div>\n </div>`;\n}\n\nfunction buildDriftFindings(result: ScanResult): string {\n const driftCats = [\"architectural_consistency\", \"security_posture\", \"semantic_duplication\", \"naming_conventions\", \"phantom_scaffolding\"];\n const catLabels: Record<string, string> = {\n architectural_consistency: \"Architectural contradictions\",\n security_posture: \"Security posture gaps\",\n semantic_duplication: \"Semantic duplication\",\n naming_conventions: \"Convention drift\",\n phantom_scaffolding: \"Phantom scaffolding\",\n };\n\n const groups = driftCats.map((cat) => ({\n cat,\n label: catLabels[cat] ?? cat,\n findings: (result.driftFindings ?? []).filter((f) => f.driftCategory === cat),\n })).filter((g) => g.findings.length > 0);\n\n if (groups.length === 0) return \"\";\n\n const totalFindings = groups.reduce((s, g) => s + g.findings.length, 0);\n\n const sections = groups.map((g, gi) => {\n const cards = g.findings.map((d) => {\n const domPctVal = d.totalRelevantFiles > 0 ? Math.round((d.dominantCount / d.totalRelevantFiles) * 100) : 0;\n const closeSplitNote = domPctVal < 70 && domPctVal >= 50\n ? ` <span style=\"font-size:11px;font-weight:400;color:var(--drift-amber)\">(close split at ${domPctVal}%)</span>`\n : \"\";\n const domBlock = `<div style=\"background:var(--tint-green);border-left:3px solid var(--intent-green);border-radius:0;padding:12px 16px;margin:8px 0\">\n <div class=\"label\" style=\"color:var(--intent-green);margin-bottom:6px\">INTENT (DOMINANT) — ${esc(d.dominantPattern)} — ${d.dominantCount} files${closeSplitNote}</div>\n </div>`;\n\n const devBlocks = buildDeviatingBlocks(d);\n const distBar = buildDistributionBar(d);\n const recText = buildDriftRecommendation(d);\n\n const closeSplitQualifier = domPctVal < 70 && domPctVal >= 50\n ? `<div style=\"margin-top:8px;padding:8px 14px;background:var(--tint-amber);border-left:3px solid var(--drift-amber);border-radius:0;font-size:13px;line-height:1.6;color:var(--text-secondary)\">\n <strong>${esc(d.dominantPattern)}</strong> is dominant at ${domPctVal}%, but the split is close.\n If your team prefers <strong>${esc(d.deviatingFiles[0]?.detectedPattern ?? \"the alternative\")}</strong>, adopt that instead.\n The important thing is consistency, not which pattern wins.\n </div>`\n : \"\";\n\n const rec = recText ? `<div style=\"margin-top:12px;padding:10px 16px;background:var(--tint-cyan);border-left:3px solid var(--border);border-radius:0;font-size:14px;line-height:1.6;color:var(--text-primary)\">\n <span style=\"color:var(--text-secondary);font-weight:700;margin-right:4px\">→</span> ${esc(recText)}\n </div>` : \"\";\n\n return `<div style=\"background:var(--bg-surface);border-radius:0;padding:20px 24px;margin-bottom:10px;border:1px solid var(--border)\">\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap\">\n <span class=\"sev-badge\" style=\"background:${sevColor(d.severity)}\">${sevLabel(d.severity)}</span>\n <span style=\"font-size:15px;font-weight:500;color:var(--text-primary);flex:1\">${esc(d.finding)}</span>\n <span class=\"mono\" style=\"font-size:12px;color:var(--text-tertiary)\">${d.dominantCount}/${d.totalRelevantFiles}</span>\n </div>\n ${domBlock}\n ${devBlocks}\n ${distBar}\n ${rec}\n ${closeSplitQualifier}\n </div>`;\n }).join(\"\");\n\n return `<details ${gi === 0 ? \"open\" : \"\"} style=\"margin-bottom:8px\">\n <summary style=\"cursor:pointer;padding:12px 18px;background:var(--bg-surface);border-radius:0;display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;color:var(--text-primary);list-style:none;border:1px solid var(--border)\">\n <span class=\"chevron\">▶</span>\n ${esc(g.label)}\n <span style=\"margin-left:auto;font-size:12px;color:var(--text-tertiary)\">${g.findings.length} finding${g.findings.length > 1 ? \"s\" : \"\"}</span>\n </summary>\n <div style=\"padding:8px 0\">${cards}</div>\n </details>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">DRIFT FINDINGS <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--text-tertiary);margin-left:8px\">${totalFindings} cross-file contradictions</span></div>\n ${sections}\n</section>`;\n}\n\nfunction buildSecurityMatrix(result: ScanResult): string {\n const secFindings = (result.driftFindings ?? []).filter((d) => d.driftCategory === \"security_posture\");\n if (secFindings.length === 0) return \"\";\n\n const rows = secFindings.flatMap((f) =>\n f.deviatingFiles.map((df) => `<tr style=\"background:var(--tint-red)\">\n <td class=\"mono\" style=\"padding:8px 12px;border-bottom:1px solid var(--border-subtle);font-size:12px;color:var(--text-primary)\">${esc(df.evidence[0]?.code ?? df.path)}</td>\n <td style=\"padding:8px 12px;border-bottom:1px solid var(--border-subtle);text-align:center;color:var(--drift-red);font-weight:700\">✗</td>\n <td class=\"mono\" style=\"padding:8px 12px;border-bottom:1px solid var(--border-subtle);font-size:12px;color:var(--text-tertiary)\">${esc(df.path)}</td>\n <td style=\"padding:8px 12px;border-bottom:1px solid var(--border-subtle);font-size:11px;color:var(--drift-red)\">DRIFT</td>\n </tr>`)\n );\n\n if (rows.length === 0) return \"\";\n\n return `<section class=\"section\">\n <div class=\"label\">SECURITY MATRIX</div>\n <div style=\"overflow-x:auto\">\n <table style=\"width:100%;border-collapse:collapse;font-size:13px\">\n <thead><tr style=\"border-bottom:1px solid var(--border)\">\n <th style=\"text-align:left;padding:8px 12px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Route / Endpoint</th>\n <th style=\"text-align:center;padding:8px 12px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Status</th>\n <th style=\"text-align:left;padding:8px 12px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">File</th>\n <th style=\"padding:8px 12px;font-size:11px;color:var(--text-tertiary);font-weight:600\"></th>\n </tr></thead>\n <tbody>${rows.join(\"\")}</tbody>\n </table>\n </div>\n</section>`;\n}\n\nfunction buildFileRanking(result: ScanResult): string {\n const entries = [...result.perFileScores.entries()];\n const withFindings = entries.filter(([, v]) => v.findings.length > 0).sort((a, b) => a[1].score - b[1].score);\n const clean = entries.filter(([, v]) => v.findings.length === 0);\n\n if (entries.length === 0) return \"\";\n\n const fileCards = withFindings.slice(0, 25).map(([file, data], i) => {\n const color = scoreColor(data.score);\n const { letter } = gradeFor(data.score, 100);\n const driftFindings = data.findings.filter((f) => f.tags?.includes(\"drift\") || f.tags?.includes(\"codedna\"));\n const staticFindings = data.findings.filter((f) => !f.tags?.includes(\"drift\") && !f.tags?.includes(\"codedna\"));\n\n // Deduplicate findings using semantic key — same issue from different analyzers should collapse\n const seenKeys = new Set<string>();\n function findingKey(f: Finding): string {\n // For duplicate-type findings, normalize by sorted file paths\n if ([\"duplicates\", \"codedna-fingerprint\", \"codedna-opseq\", \"ml-duplicate\"].includes(f.analyzerId)) {\n const files = f.locations.map((l) => l.file).filter(Boolean).sort().join(\"::\");\n return `dup::${files || f.message}`;\n }\n // For all others, use analyzer + message as key\n return `${f.analyzerId}::${f.message}`;\n }\n const dedupedDrift = driftFindings.filter((f) => { const k = findingKey(f); if (seenKeys.has(k)) return false; seenKeys.add(k); return true; });\n const dedupedStatic = staticFindings.filter((f) => { const k = findingKey(f); if (seenKeys.has(k)) return false; seenKeys.add(k); return true; });\n\n const findingList = [...dedupedDrift.slice(0, 4), ...dedupedStatic.slice(0, 4)].map((f) => {\n const isDrift = f.tags?.includes(\"drift\") || f.tags?.includes(\"codedna\");\n return `<div style=\"padding:3px 0;font-size:12px;color:var(--text-secondary);display:flex;align-items:baseline;gap:6px\">\n <span style=\"color:${isDrift ? \"var(--drift-orange)\" : \"var(--text-tertiary)\"};font-size:10px;font-weight:600;min-width:42px\">${isDrift ? \"◆ DRIFT\" : \"● STATIC\"}</span>\n <span>${esc(f.message.slice(0, 90))}${f.message.length > 90 ? \"...\" : \"\"}</span>\n </div>`;\n }).join(\"\");\n\n return `<details ${i === 0 ? \"open\" : \"\"} style=\"margin-bottom:4px\" id=\"rank-${esc(file.replace(/[^a-zA-Z0-9]/g, \"-\"))}\">\n <summary style=\"cursor:pointer;padding:10px 16px;background:var(--bg-surface);border-radius:0;display:flex;align-items:center;gap:10px;font-size:13px;border:1px solid var(--border);list-style:none\">\n <div style=\"width:4px;height:22px;border-radius:2px;background:${color}\"></div>\n <span class=\"mono\" style=\"color:var(--text-secondary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\">${esc(file)}</span>\n <span class=\"mono\" style=\"font-weight:600;color:${color}\">${data.score}/100</span>\n <span style=\"font-size:12px;font-weight:600;color:${color}\">${letter}</span>\n <span style=\"font-size:11px;color:var(--text-tertiary)\">${driftFindings.length} drift · ${staticFindings.length} static</span>\n </summary>\n <div style=\"padding:6px 16px 10px 32px\">${findingList}</div>\n </details>`;\n }).join(\"\");\n\n const cleanSection = clean.length > 0 ? `<details style=\"margin-top:8px\">\n <summary style=\"cursor:pointer;padding:8px 16px;font-size:12px;color:var(--text-tertiary);list-style:none\">── ${clean.length} files with no findings ──</summary>\n <div style=\"padding:4px 16px;font-size:12px;color:var(--text-tertiary)\" class=\"mono\">${clean.slice(0, 20).map(([f]) => `<div style=\"padding:1px 0\">${esc(f)} <span style=\"color:var(--intent-green)\">100/100 A ✓</span></div>`).join(\"\")}${clean.length > 20 ? `<div style=\"color:var(--text-tertiary)\">··· ${clean.length - 20} more</div>` : \"\"}</div>\n </details>` : \"\";\n\n return `<section class=\"section\">\n <div class=\"label\">FILE RANKING <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--text-tertiary);margin-left:8px\">${entries.length} files scanned</span></div>\n ${fileCards}\n ${cleanSection}\n</section>`;\n}\n\nfunction buildMlInsights(result: ScanResult): string {\n const mlFindings = result.findings.filter((f) => f.tags?.includes(\"ml\"));\n if (mlFindings.length === 0) return \"\";\n\n const byType: Record<string, typeof mlFindings> = {};\n for (const f of mlFindings) {\n const type = f.analyzerId === \"ml-duplicate\" ? \"Semantic Duplicates\"\n : f.analyzerId === \"ml-intent\" ? \"Intent Mismatches\"\n : f.analyzerId === \"ml-anomaly\" ? \"Pattern Anomalies\" : \"Other\";\n if (!byType[type]) byType[type] = [];\n byType[type].push(f);\n }\n\n const sections = Object.entries(byType).map(([type, findings]) => {\n const icon = type === \"Semantic Duplicates\" ? \"🔁\" : type === \"Intent Mismatches\" ? \"🎯\" : \"🔎\";\n const typeColor = type === \"Semantic Duplicates\" ? \"var(--drift-red)\" : type === \"Intent Mismatches\" ? \"var(--drift-orange)\" : \"var(--info-blue)\";\n\n const cards = findings.map((f) => {\n const sColor = sevColor(f.severity);\n const files = f.locations.map((l) => l.file).filter(Boolean);\n // Add actionable recommendations for anomalies\n let recommendation = \"\";\n if (f.analyzerId === \"ml-anomaly\" && files.length > 0) {\n const funcName = f.message.match(/Pattern outlier: (.+?) doesn/)?.[1]?.split(\"::\").pop() ?? \"\";\n const fileName = files[0]?.split(\"/\").pop() ?? \"\";\n if (funcName && fileName) {\n recommendation = `<div style=\"margin-top:6px;padding:6px 12px;background:var(--tint-cyan);border-left:2px solid var(--border);border-radius:0 4px 4px 0;font-size:12px;color:var(--text-secondary)\"><span style=\"color:var(--text-secondary);font-weight:700;margin-right:4px\">→</span> Consider extracting ${esc(funcName)} from ${esc(fileName)} into a shared utils package, or verify it belongs in this module.</div>`;\n }\n }\n return `<div style=\"background:var(--bg-surface);border-radius:0;padding:14px 18px;margin-bottom:8px;border-left:3px solid ${sColor}\">\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:6px\">\n <span class=\"sev-badge\" style=\"background:${sColor}\">${sevLabel(f.severity)}</span>\n <span style=\"font-size:14px;font-weight:500;color:var(--text-primary);flex:1\">${esc(f.message)}</span>\n <span class=\"mono\" style=\"font-size:11px;color:var(--text-tertiary)\">${Math.round(f.confidence * 100)}%</span>\n </div>\n ${files.length > 0 ? `<div class=\"mono\" style=\"font-size:12px;color:var(--text-secondary);margin-top:4px\">${files.map((fp) => esc(fp)).join(\" · \")}</div>` : \"\"}\n ${recommendation}\n </div>`;\n }).join(\"\");\n\n return `<details open style=\"margin-bottom:10px\">\n <summary style=\"cursor:pointer;padding:10px 16px;background:var(--bg-surface);border-radius:0;display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:var(--text-primary);list-style:none;border:1px solid var(--border)\">\n <span class=\"chevron\">▶</span>\n <span>${icon}</span>\n <span style=\"color:${typeColor}\">${esc(type)}</span>\n <span style=\"margin-left:auto;font-size:12px;color:var(--text-tertiary)\">${findings.length} finding${findings.length > 1 ? \"s\" : \"\"}</span>\n </summary>\n <div style=\"padding:8px 0\">${cards}</div>\n </details>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">AI ANALYSIS <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--info-blue);margin-left:8px\">Deep Layer · Code Embeddings · ${mlFindings.length} findings</span></div>\n <p style=\"font-size:13px;color:var(--text-secondary);margin-bottom:16px;line-height:1.6\">\n These findings were detected by VibeDrift’s AI inference API. Only function snippets (not full files) were sent for analysis — snippets are processed in memory and not stored.\n Functions were embedded as 768-dimensional vectors and compared for semantic similarity, name-body alignment, and clustering anomalies.\n </p>\n ${sections}\n</section>`;\n}\n\nfunction buildStaticFindings(result: ScanResult): string {\n const statics = result.findings.filter((f) => !f.tags?.includes(\"drift\") && !f.tags?.includes(\"codedna\") && !f.tags?.includes(\"ml\"));\n if (statics.length === 0) return \"\";\n\n const sorted = [...statics].sort((a, b) => {\n const sev = { error: 0, warning: 1, info: 2 };\n return (sev[a.severity as keyof typeof sev] ?? 2) - (sev[b.severity as keyof typeof sev] ?? 2);\n });\n\n const rows = sorted.slice(0, 30).map((f) => {\n const sColor = f.severity === \"error\" ? \"var(--drift-orange)\" : f.severity === \"warning\" ? \"var(--drift-amber)\" : \"var(--info-blue)\";\n const loc = f.locations[0];\n return `<tr>\n <td style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle)\"><span class=\"sev-badge\" style=\"background:${sColor};font-size:10px\">${f.severity === \"error\" ? \"ERROR\" : f.severity === \"warning\" ? \"WARN\" : \"INFO\"}</span></td>\n <td style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle);font-size:12px;color:var(--text-tertiary)\">${esc(f.analyzerId)}</td>\n <td style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle);font-size:13px;color:var(--text-primary)\">${esc(f.message.slice(0, 80))}${f.message.length > 80 ? \"...\" : \"\"}</td>\n <td class=\"mono\" style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle);font-size:11px;color:var(--text-secondary);white-space:nowrap\">${loc ? esc(shortPath(loc.file)) + (loc.line ? \":\" + loc.line : \"\") : \"\"}</td>\n <td class=\"mono\" style=\"padding:6px 10px;border-bottom:1px solid var(--border-subtle);font-size:11px;color:var(--text-tertiary)\">${Math.round(f.confidence * 100)}%</td>\n </tr>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">STATIC ANALYSIS <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--text-tertiary);margin-left:8px\">${statics.length} findings</span></div>\n <div style=\"overflow-x:auto\">\n <table style=\"width:100%;border-collapse:collapse;font-size:13px\">\n <thead><tr style=\"border-bottom:1px solid var(--border)\">\n <th style=\"text-align:left;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\" data-sort>Sev</th>\n <th style=\"text-align:left;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\" data-sort>Analyzer</th>\n <th style=\"text-align:left;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Finding</th>\n <th style=\"text-align:left;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">File</th>\n <th style=\"text-align:right;padding:6px 10px;font-size:11px;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:0.5px;font-weight:600\">Conf</th>\n </tr></thead>\n <tbody>${rows}</tbody>\n </table>\n </div>\n ${statics.length > 30 ? `<div style=\"font-size:12px;color:var(--text-tertiary);margin-top:8px\">${statics.length - 30} more findings not shown</div>` : \"\"}\n</section>`;\n}\n\nfunction buildDeepInsights(result: ScanResult): string {\n const insights = result.deepInsights ?? [];\n if (insights.length === 0) return \"\";\n\n const cards = insights.map((ins) => {\n const sColor = sevColor(ins.severity);\n return `<div style=\"background:var(--bg-surface);border-left:3px solid var(--info-blue);border-radius:0;padding:16px 20px;margin-bottom:10px\">\n <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:6px\">\n <span class=\"sev-badge\" style=\"background:${sColor}\">${sevLabel(ins.severity)}</span>\n <span style=\"font-size:14px;font-weight:500;color:var(--text-primary)\">${esc(ins.title)}</span>\n </div>\n <p style=\"font-size:13px;color:var(--text-secondary);line-height:1.6;margin:0\">${esc(ins.description)}</p>\n ${ins.relatedFiles.length > 0 ? `<div class=\"mono\" style=\"font-size:11px;color:var(--text-tertiary);margin-top:6px\">${ins.relatedFiles.slice(0, 4).map((f) => esc(f)).join(\" · \")}</div>` : \"\"}\n ${ins.recommendation ? `<div style=\"margin-top:8px;padding:8px 14px;background:var(--tint-cyan);border-left:3px solid var(--border);border-radius:0;font-size:13px;color:var(--text-primary)\"><span style=\"color:var(--text-secondary);font-weight:700;margin-right:4px\">→</span> ${esc(ins.recommendation)}</div>` : \"\"}\n </div>`;\n }).join(\"\");\n\n return `<section class=\"section\">\n <div class=\"label\">DEEP ANALYSIS INSIGHTS <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--info-blue);margin-left:8px\">AI-powered · ${insights.length} insights</span></div>\n ${cards}\n</section>`;\n}\n\nfunction buildSequenceCards(similarities: any[]): string {\n const seqCards = similarities.slice(0, 6).map((sim: any) => {\n const pct = Math.round(sim.similarity * 100);\n const color = pct >= 90 ? \"var(--drift-red)\" : \"var(--drift-orange)\";\n const matchLabel = pct >= 100 ? \"Exact duplicate\" : pct >= 90 ? \"Near-exact match\" : \"Similar\";\n return `<div style=\"display:flex;align-items:center;gap:12px;padding:6px 0;border-bottom:1px solid var(--border-subtle)\">\n <span class=\"mono\" style=\"min-width:40px;font-weight:700;color:${color}\">${pct}%</span>\n <div style=\"flex:1\">\n <span style=\"font-size:11px;font-weight:600;color:${color};margin-right:6px\">${matchLabel}</span>\n <span class=\"mono\" style=\"font-size:12px;color:var(--text-secondary)\">${esc(sim.functionA.name)}()</span>\n <span style=\"font-size:11px;color:var(--text-tertiary)\"> in ${esc(shortPath(sim.functionA.relativePath || sim.functionA.file))}</span>\n <span style=\"color:var(--text-tertiary);margin:0 4px\">↔</span>\n <span class=\"mono\" style=\"font-size:12px;color:var(--drift-orange)\">${esc(sim.functionB.name)}()</span>\n <span style=\"font-size:11px;color:var(--text-tertiary)\"> in ${esc(shortPath(sim.functionB.relativePath || sim.functionB.file))}</span>\n </div>\n </div>`;\n }).join(\"\");\n return `<details style=\"margin-bottom:8px\"><summary style=\"cursor:pointer;font-size:13px;font-weight:500;color:var(--text-primary);list-style:none;padding:6px 0\"><span class=\"chevron\">▶</span> Operation sequence matches <span style=\"color:var(--text-tertiary);font-weight:400\">${similarities.length} pairs</span></summary><div style=\"padding:4px 0 4px 16px\">${seqCards}</div></details>`;\n}\n\nfunction buildDeviationCards(justifications: any[]): string {\n const devCards = justifications.map((dj: any) => {\n const vColor = dj.verdict === \"likely_justified\" ? \"var(--intent-green)\" : dj.verdict === \"likely_accidental\" ? \"var(--drift-red)\" : \"var(--drift-amber)\";\n const vLabel = dj.verdict === \"likely_justified\" ? \"JUSTIFIED\" : dj.verdict === \"likely_accidental\" ? \"ACCIDENTAL\" : \"UNCERTAIN\";\n return `<div style=\"display:flex;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid var(--border-subtle)\">\n <span class=\"sev-badge\" style=\"background:${vColor};min-width:80px;text-align:center\">${vLabel}</span>\n <span class=\"mono\" style=\"font-size:12px;color:var(--text-secondary);flex:1\">${esc(shortPath(dj.relativePath || dj.file))}</span>\n <span style=\"font-size:12px;color:var(--text-tertiary)\">${esc(dj.deviatingPattern)} vs ${esc(dj.dominantPattern)}</span>\n </div>`;\n }).join(\"\");\n return `<details style=\"margin-bottom:8px\"><summary style=\"cursor:pointer;font-size:13px;font-weight:500;color:var(--text-primary);list-style:none;padding:6px 0\"><span class=\"chevron\">▶</span> Deviation analysis <span style=\"color:var(--text-tertiary);font-weight:400\">${justifications.length}</span></summary><div style=\"padding:4px 0 4px 16px\">${devCards}</div></details>`;\n}\n\nfunction buildCodeDnaSummary(result: ScanResult): string {\n const dna = result.codeDnaResult;\n if (!dna) return \"\";\n\n const hasDupes = dna.duplicateGroups?.length > 0;\n const hasSeqs = dna.sequenceSimilarities?.length > 0;\n const hasTaint = dna.taintFlows?.length > 0;\n const hasDevs = dna.deviationJustifications?.length > 0;\n\n if (!hasDupes && !hasSeqs && !hasTaint && !hasDevs) return \"\";\n\n const parts: string[] = [];\n\n if (hasSeqs) {\n parts.push(buildSequenceCards(dna.sequenceSimilarities));\n }\n\n if (hasDevs) {\n parts.push(buildDeviationCards(dna.deviationJustifications));\n }\n\n if (parts.length === 0) return \"\";\n\n const totalFindings = dna.findings?.length ?? 0;\n const timeMs = dna.timings?.totalMs ?? 0;\n\n return `<section class=\"section\">\n <div class=\"label\">CODE DNA <span style=\"font-size:11px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--intent-green);margin-left:8px\">Layer 1.7 · ${totalFindings} findings · ${dna.functions?.length ?? 0} functions · ${timeMs}ms</span></div>\n ${parts.join(\"\")}\n</section>`;\n}\n\nfunction buildFooter(result: ScanResult): string {\n const hasDeep = result.findings.some((f) => f.tags?.includes(\"ml\")) || !!result.aiSummary;\n const premiumUpsell = !hasDeep ? `<div style=\"margin-top:16px;padding:14px 18px;background:var(--bg-surface);border-radius:0;border-left:3px solid var(--border);text-align:left;font-size:13px;color:var(--text-secondary);max-width:520px;margin-left:auto;margin-right:auto\">\n Want AI-powered deep analysis? Sign in once with <code class=\"mono\" style=\"color:var(--text-primary);background:var(--bg-code);padding:2px 6px;border-radius:0\">vibedrift login</code> then run:<br>\n <code class=\"mono\" style=\"color:var(--text-primary);background:var(--bg-code);padding:2px 6px;border-radius:0;margin-top:4px;display:inline-block\">vibedrift . --deep</code>\n <span data-copy=\"vibedrift . --deep\" style=\"cursor:pointer;margin-left:6px;font-size:11px;color:var(--text-tertiary)\">[copy]</span>\n </div>` : \"\";\n\n return `<footer style=\"border-top:1px solid var(--border);padding-top:28px;margin-top:48px;text-align:center;color:var(--text-tertiary);font-size:13px\">\n <div style=\"display:flex;gap:8px;justify-content:center;margin-bottom:20px;flex-wrap:wrap\">\n <button onclick=\"exportCSV()\" class=\"export-btn\">Export CSV</button>\n <button onclick=\"exportDOCX()\" class=\"export-btn\">Export DOCX</button>\n <button onclick=\"window.print()\" class=\"export-btn\">Export PDF</button>\n </div>\n <p>Generated by <span style=\"color:var(--text-primary);font-weight:600\">VibeDrift v${getVersion()}</span></p>\n <p style=\"margin:4px 0\">${result.context.files.length} files · ${result.context.totalLines.toLocaleString()} lines · ${(result.scanTimeMs / 1000).toFixed(1)}s</p>\n <p style=\"margin:4px 0;font-size:12px\">${hasDeep\n ? \"Function snippets were sent to VibeDrift’s AI API for analysis. No full files transmitted. Snippets processed in memory and not stored.\"\n : \"No data sent externally.\"}</p>\n <p style=\"margin-top:10px\">Fix the top issues and re-scan: <code class=\"mono\" style=\"background:var(--bg-code);padding:2px 6px;border-radius:0;color:var(--text-primary)\">vibedrift .</code> <span data-copy=\"vibedrift .\" style=\"cursor:pointer;font-size:11px;color:var(--text-tertiary)\">[copy]</span></p>\n ${premiumUpsell}\n <div style=\"margin-top:16px;padding:12px 18px;background:var(--bg-surface);border-radius:0;display:inline-block;text-align:left\">\n <div style=\"font-size:11px;color:var(--text-tertiary);margin-bottom:6px\">Add to your README:</div>\n <code class=\"mono\" style=\"font-size:11px;color:var(--text-secondary)\">[}-${result.compositeScore >= 75 ? \"brightgreen\" : result.compositeScore >= 50 ? \"yellow\" : \"red\"})](https://vibedrift.ai)</code>\n <span data-copy=\"[}-${result.compositeScore >= 75 ? \"brightgreen\" : result.compositeScore >= 50 ? \"yellow\" : \"red\"})](https://vibedrift.ai)\" style=\"cursor:pointer;margin-left:8px;font-size:11px;color:var(--text-tertiary)\">[copy]</span>\n </div>\n <p style=\"margin-top:16px;font-size:11px;color:var(--border)\">vibedrift.ai · Built by the creator of <a href=\"https://thevibelang.org\" style=\"color:var(--text-tertiary);text-decoration:none\">VibeLang</a></p>\n</footer>`;\n}\n\n// ──── Embedded data for client-side exports ────\n\nfunction buildEmbeddedData(result: ScanResult): string {\n const dna = result.codeDnaResult;\n\n const data = {\n version: getVersion(),\n project: result.context.rootDir.split(\"/\").pop() ?? \"project\",\n score: result.compositeScore,\n maxScore: result.maxCompositeScore,\n fileCount: result.context.files.length,\n totalLines: result.context.totalLines,\n scanTimeMs: result.scanTimeMs,\n driftFindings: (result.driftFindings ?? []).map((d) => ({\n severity: d.severity,\n category: d.driftCategory,\n finding: d.finding,\n dominant: d.dominantPattern,\n consistency: d.consistencyScore,\n devFiles: d.deviatingFiles.map((f) => f.path).join(\"; \"),\n recommendation: d.recommendation,\n })),\n findings: result.findings.map((f) => ({\n severity: f.severity,\n analyzer: f.analyzerId,\n message: f.message,\n file: f.locations[0]?.file ?? \"\",\n line: f.locations[0]?.line ?? \"\",\n confidence: Math.round(f.confidence * 100),\n })),\n fileScores: [...result.perFileScores.entries()].sort((a, b) => a[1].score - b[1].score).map(([path, data]) => ({\n file: path,\n score: data.score,\n findings: data.findings.length,\n })),\n codeDna: dna ? {\n sequences: (dna.sequenceSimilarities ?? []).map((s: any) => ({\n a: s.functionA.name + \"() in \" + (s.functionA.relativePath || s.functionA.file),\n b: s.functionB.name + \"() in \" + (s.functionB.relativePath || s.functionB.file),\n pct: Math.round(s.similarity * 100),\n })),\n deviations: (dna.deviationJustifications ?? []).map((dj: any) => ({\n file: dj.relativePath || dj.file,\n verdict: dj.verdict,\n pattern: dj.deviatingPattern + \" vs \" + dj.dominantPattern,\n })),\n } : null,\n deepInsights: (result.deepInsights ?? []).map((ins) => ({\n severity: ins.severity,\n title: ins.title,\n description: ins.description,\n recommendation: ins.recommendation ?? \"\",\n })),\n };\n\n return JSON.stringify(data);\n}\n\n// ──── Main Report ────\n\nexport function renderHtmlReport(result: ScanResult): string {\n const projectName = result.context.rootDir.split(\"/\").pop() ?? \"project\";\n const { compositeScore, maxCompositeScore } = result;\n const { letter, color: gradeColor } = gradeFor(compositeScore, maxCompositeScore);\n const intentPatterns = extractIntentPatterns(result);\n const fileCoherence = buildFileCoherence(result);\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>VibeDrift Report — ${esc(projectName)}</title>\n<style>\n:root {\n --bg-page: #121214;\n --bg-surface: #1A1A1C;\n --bg-surface-hover: #1F1F22;\n --bg-code: #16161A;\n --text-primary: #E0E0D8;\n --text-secondary: #9A9A92;\n --text-tertiary: #757570;\n --brand-cyan: #FFD000;\n --link: #888880;\n --intent-green: #44DD66;\n --drift-amber: #C8A000;\n --drift-orange: #CC7000;\n --drift-red: #DD3333;\n --info-blue: #00AAA0;\n --grade-a: #44DD66;\n --grade-b: #44DD66;\n --grade-c: #C8A000;\n --grade-d: #CC7000;\n --grade-f: #DD3333;\n --border: #26262A;\n --border-subtle: rgba(38, 38, 42, 0.5);\n --tint-green: rgba(68, 221, 102, 0.04);\n --tint-amber: rgba(200, 160, 0, 0.03);\n --tint-orange: rgba(204, 112, 0, 0.04);\n --tint-red: rgba(221, 51, 51, 0.04);\n --tint-cyan: rgba(255, 208, 0, 0.02);\n --tint-blue: rgba(0, 170, 160, 0.04);\n}\n@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap');\n* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { background: var(--bg-page); color: var(--text-primary); font-family: 'JetBrains Mono', 'SF Mono', 'Consolas', monospace; font-size: 14px; line-height: 1.6; -webkit-font-smoothing: antialiased; }\ncode, .mono { font-family: 'JetBrains Mono', 'SF Mono', 'Consolas', monospace; font-size: 13px; }\nh1, h2, h3, .heading { font-family: 'Space Grotesk', -apple-system, sans-serif; }\n.page { max-width: 960px; margin: 0 auto; padding: 40px 32px; }\n.section { margin-bottom: 48px; }\n.label { font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--text-tertiary); margin-bottom: 16px; }\n.sev-badge { display: inline-block; padding: 2px 8px; font-size: 11px; font-weight: 700; color: var(--bg-page); text-transform: uppercase; letter-spacing: 0.5px; }\n.sticky-header { position: fixed; top: 0; left: 0; right: 0; height: 44px; background: rgba(18,18,20,0.95); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; padding: 0 32px; z-index: 100; opacity: 0; pointer-events: none; transition: opacity 200ms; font-size: 13px; }\n.sticky-header.visible { opacity: 1; pointer-events: auto; }\ndetails summary { list-style: none; }\ndetails summary::-webkit-details-marker { display: none; }\ndetails[open] > summary .chevron { display: inline-block; transform: rotate(90deg); }\n.chevron { display: inline-block; transition: transform 150ms; margin-right: 6px; font-size: 10px; }\na { color: var(--link); text-decoration: none; }\na:hover { color: var(--text-primary); }\n[data-scroll-to] { cursor: pointer; }\n[data-scroll-to]:hover { text-decoration: underline; }\nth[data-sort] { cursor: pointer; }\nth[data-sort]:hover { color: var(--text-primary); }\n.export-btn { background: var(--bg-surface); color: var(--text-secondary); border: 1px solid var(--border); padding: 6px 14px; font-size: 12px; font-weight: 700; cursor: pointer; transition: background 150ms, color 150ms; font-family: inherit; letter-spacing: 0.5px; text-transform: uppercase; }\n.export-btn:hover { background: var(--bg-surface-hover); color: var(--text-primary); }\n::selection { background: #FFD000; color: #121214; }\n::-webkit-scrollbar { width: 4px; }\n::-webkit-scrollbar-track { background: var(--bg-page); }\n::-webkit-scrollbar-thumb { background: #3A3A3D; }\n::-webkit-scrollbar-thumb:hover { background: #555; }\n@media (max-width: 768px) {\n .page { padding: 16px 10px; }\n .section { margin-bottom: 28px; }\n .label { font-size: 10px; letter-spacing: 1.5px; margin-bottom: 10px; }\n\n /* Score hero: stack vertically */\n .score-layout { flex-direction: column !important; gap: 16px !important; }\n .score-layout > div { min-width: 0 !important; width: 100% !important; }\n\n /* Category bars: stack, remove min-widths */\n .score-layout [style*=\"min-width:300px\"],\n .score-layout [style*=\"min-width:280px\"],\n .score-layout [style*=\"min-width:200px\"],\n .score-layout [style*=\"min-width:120px\"] {\n min-width: 0 !important; width: 100% !important;\n }\n\n /* Radar chart: constrain to viewport */\n svg[viewBox] { max-width: 100% !important; }\n\n /* Strongest/Weakest cards: 2-col, tighter */\n .section > div[style*=\"display:flex\"][style*=\"gap:12px\"] {\n gap: 8px !important;\n }\n .section > div[style*=\"display:flex\"] > div[style*=\"min-width:160px\"] {\n min-width: 0 !important; flex: 1 !important;\n }\n\n /* Findings list: tighter padding */\n details > div { padding: 8px 10px !important; }\n details summary { padding: 10px 12px !important; font-size: 13px !important; }\n\n /* File ranking table: horizontal scroll */\n table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }\n table th, table td { padding: 5px 8px !important; font-size: 11px !important; }\n\n /* Code snippets: wrap text */\n pre, code { white-space: pre-wrap !important; word-break: break-word !important; font-size: 12px !important; }\n\n /* Drift coherence bars: full width */\n .section div[style*=\"display:flex\"][style*=\"gap:40px\"] {\n flex-direction: column !important; gap: 16px !important;\n }\n\n /* Summary + AI section: stack */\n .section div[style*=\"display:flex\"][style*=\"gap:20px\"] {\n flex-direction: column !important; gap: 12px !important;\n }\n\n /* Sticky header: tighter padding */\n .sticky-header { padding: 0 12px; font-size: 12px; }\n .sticky-project { display: none !important; }\n\n /* Export buttons: smaller */\n .export-btn { padding: 5px 10px; font-size: 11px; }\n\n /* Code DNA / ML sections: reduce gap */\n .section div[style*=\"gap:10px\"] { gap: 6px !important; }\n\n /* Hide long file paths, truncate */\n td[data-scroll-to] { max-width: 140px !important; }\n}\n@media (max-width: 480px) {\n .page { padding: 12px 8px; }\n body { font-size: 13px; }\n .label { font-size: 9px; }\n .sticky-header { height: 38px; }\n table th, table td { padding: 4px 6px !important; font-size: 10px !important; }\n}\n@media print {\n body { background: #fff; color: #111; font-size: 11px; line-height: 1.4; }\n .sticky-header, .export-btn, [data-copy] { display: none !important; }\n .page { max-width: 100%; padding: 0; }\n .section { margin-bottom: 24px; page-break-inside: avoid; }\n details, details[open] > div, details > div { display: block !important; }\n details > summary { list-style: none; }\n details > summary .chevron { display: none; }\n .sev-badge { border: 1px solid currentColor; background: transparent !important; color: inherit !important; }\n code, .mono { font-size: 10px; }\n * { color-adjust: exact; -webkit-print-color-adjust: exact; print-color-adjust: exact; }\n}\n</style>\n</head>\n<body>\n\n<div class=\"sticky-header\" id=\"sticky-header\">\n <div class=\"sticky-project\" style=\"display:flex;align-items:center;gap:8px\">\n <span style=\"display:inline-block;width:10px;height:10px;background:var(--brand-cyan)\"></span>\n <span style=\"color:var(--text-primary);font-weight:700;letter-spacing:2px;font-size:12px\">VIBEDRIFT</span>\n <span style=\"color:var(--text-tertiary)\">·</span>\n <span style=\"color:var(--text-secondary)\">${esc(projectName)}</span>\n </div>\n <div style=\"display:flex;align-items:center;gap:8px\">\n <span class=\"mono\" style=\"font-weight:700;color:${gradeColor}\">${compositeScore}/${maxCompositeScore}</span>\n <span style=\"padding:2px 8px;border-radius:0;font-size:11px;font-weight:600;background:${gradeColor}18;color:${gradeColor}\">${letter}</span>\n </div>\n</div>\n\n<div class=\"page\">\n\n${buildHeader(result)}\n\n\n${buildAiSummaryWidget(result)}\n\n${buildScoreSection(result)}\n\n${buildRadarSection(result)}\n\n${buildIntentDefinition(intentPatterns)}\n\n${buildCoherenceMatrix(fileCoherence)}\n\n${buildFixFirst(result)}\n\n${buildDriftFindings(result)}\n\n${buildCodeDnaSummary(result)}\n\n${buildSecurityMatrix(result)}\n\n${buildFileRanking(result)}\n\n${buildMlInsights(result)}\n\n${buildStaticFindings(result)}\n\n${buildDeepInsights(result)}\n\n${buildFooter(result)}\n\n</div>\n\n<script>\nwindow.__VIBEDRIFT_DATA = ${buildEmbeddedData(result)};\n</script>\n\n<script>\n// Sticky header\nconst hdr = document.getElementById('report-header');\nconst sticky = document.getElementById('sticky-header');\nif (hdr && sticky) {\n new IntersectionObserver(([e]) => {\n sticky.classList.toggle('visible', !e.isIntersecting);\n }, { threshold: 0 }).observe(hdr);\n}\n\n// Collapsible\ndocument.querySelectorAll('[data-collapse]').forEach(t => {\n t.addEventListener('click', () => {\n const el = document.getElementById(t.dataset.collapse);\n if (el) el.style.display = el.style.display === 'none' ? '' : 'none';\n });\n});\n\n// Scroll-to\ndocument.querySelectorAll('[data-scroll-to]').forEach(l => {\n l.addEventListener('click', e => {\n e.preventDefault();\n const t = document.getElementById(l.dataset.scrollTo);\n if (t) { t.scrollIntoView({ behavior: 'smooth', block: 'center' }); t.style.background = 'rgba(0,212,255,0.06)'; setTimeout(() => t.style.background = '', 2000); }\n });\n});\n\n// Copy\ndocument.querySelectorAll('[data-copy]').forEach(b => {\n b.addEventListener('click', () => {\n navigator.clipboard.writeText(b.dataset.copy).then(() => { const o = b.textContent; b.textContent = 'Copied!'; setTimeout(() => b.textContent = o, 1500); });\n });\n});\n\n// Tooltips\ndocument.querySelectorAll('[data-tooltip]').forEach(el => {\n el.addEventListener('mouseenter', e => {\n const t = document.createElement('div');\n t.textContent = el.dataset.tooltip;\n t.style.cssText = 'position:fixed;background:var(--bg-surface);color:var(--text-primary);padding:6px 10px;border-radius:0;font-size:12px;border:1px solid var(--border);z-index:200;pointer-events:none;max-width:250px';\n document.body.appendChild(t);\n const r = el.getBoundingClientRect();\n t.style.left = r.left + 'px'; t.style.top = (r.bottom + 6) + 'px';\n el._tip = t;\n });\n el.addEventListener('mouseleave', () => { if (el._tip) { el._tip.remove(); el._tip = null; } });\n});\n\n// Table sort\ndocument.querySelectorAll('th[data-sort]').forEach(th => {\n th.addEventListener('click', () => {\n const tb = th.closest('table').querySelector('tbody');\n const rows = Array.from(tb.querySelectorAll('tr'));\n const col = th.cellIndex;\n const dir = th.dataset.dir === 'asc' ? 'desc' : 'asc';\n th.dataset.dir = dir;\n rows.sort((a, b) => {\n const av = a.cells[col]?.textContent?.trim() ?? '';\n const bv = b.cells[col]?.textContent?.trim() ?? '';\n return dir === 'asc' ? av.localeCompare(bv) : bv.localeCompare(av);\n });\n rows.forEach(r => tb.appendChild(r));\n });\n});\n\n// ──── Export: CSV ────\nfunction exportCSV() {\n const d = window.__VIBEDRIFT_DATA;\n if (!d) { alert('Report data not available'); return; }\n const esc = v => { const s = String(v); return s.includes(',') || s.includes('\"') || s.includes('\\\\n') ? '\"'+s.replace(/\"/g,'\"\"')+'\"' : s; };\n const row = (...c) => c.map(esc).join(',');\n const lines = [];\n lines.push('VIBEDRIFT REPORT');\n lines.push(row('Project', d.project));\n lines.push(row('Score', d.score + '/' + d.maxScore));\n lines.push(row('Files', d.fileCount));\n lines.push(row('Lines', d.totalLines));\n lines.push('');\n lines.push('DRIFT FINDINGS');\n lines.push(row('Severity','Category','Finding','Dominant Pattern','Consistency %','Deviating Files','Recommendation'));\n for (const f of d.driftFindings || []) lines.push(row(f.severity, f.category, f.finding, f.dominant, f.consistency, f.devFiles, f.recommendation));\n lines.push('');\n lines.push('ALL FINDINGS');\n lines.push(row('Severity','Analyzer','Message','File','Line','Confidence'));\n for (const f of d.findings || []) lines.push(row(f.severity, f.analyzer, f.message, f.file, f.line, f.confidence));\n lines.push('');\n lines.push('FILE SCORES');\n lines.push(row('File','Score','Findings'));\n for (const f of d.fileScores || []) lines.push(row(f.file, f.score, f.findings));\n\n const blob = new Blob([lines.join('\\\\n')], { type: 'text/csv' });\n const a = document.createElement('a');\n a.href = URL.createObjectURL(blob);\n a.download = d.project + '-vibedrift.csv';\n a.click();\n URL.revokeObjectURL(a.href);\n}\n\n// ──── Export: DOCX (Word-compatible HTML) ────\nfunction buildDocxFindingsHtml(d) {\n let html = '';\n html += '<h1>Drift Findings</h1>';\n for (const f of d.driftFindings || []) {\n const sev = f.severity === 'error' ? 'critical' : f.severity;\n html += '<h2><span class=\"sev-' + sev + '\">[' + (sev === 'critical' ? 'CRITICAL' : sev.toUpperCase()) + ']</span> ' + esc2(f.finding) + '</h2>';\n html += '<p>Category: ' + esc2(f.category) + ' | Consistency: ' + f.consistency + '%</p>';\n html += '<div class=\"intent\"><strong>INTENT (Dominant):</strong> ' + esc2(f.dominant) + '</div>';\n html += '<div class=\"drift\"><strong>DEVIATING:</strong> ' + esc2(f.devFiles) + '</div>';\n if (f.recommendation) html += '<div class=\"rec\"><strong>Fix:</strong> ' + esc2(f.recommendation) + '</div>';\n }\n html += '<div class=\"page-break\"></div><h1>All Findings</h1>';\n html += '<table><tr><th>Severity</th><th>Analyzer</th><th>Finding</th><th>File</th><th>Line</th></tr>';\n for (const f of d.findings || []) {\n html += '<tr><td class=\"sev-' + (f.severity === 'error' ? 'critical' : f.severity) + '\">' + f.severity.toUpperCase() + '</td>';\n html += '<td>' + esc2(f.analyzer) + '</td><td>' + esc2(f.message) + '</td>';\n html += '<td><code>' + esc2(f.file) + '</code></td><td>' + f.line + '</td></tr>';\n }\n html += '</table>';\n return html;\n}\n\nfunction buildDocxScoresHtml(d) {\n let html = '';\n html += '<div class=\"page-break\"></div><h1>File Scores</h1>';\n html += '<table><tr><th>File</th><th>Score</th><th>Findings</th></tr>';\n for (const f of d.fileScores || []) {\n html += '<tr><td><code>' + esc2(f.file) + '</code></td><td>' + f.score + '/100</td><td>' + f.findings + '</td></tr>';\n }\n html += '</table>';\n if (d.codeDna) {\n html += '<div class=\"page-break\"></div><h1>Code DNA Analysis</h1>';\n if (d.codeDna.sequences && d.codeDna.sequences.length > 0) {\n html += '<h2>Operation Sequence Matches</h2><table><tr><th>Function A</th><th>Function B</th><th>Similarity</th></tr>';\n for (const s of d.codeDna.sequences) html += '<tr><td>' + esc2(s.a) + '</td><td>' + esc2(s.b) + '</td><td>' + s.pct + '%</td></tr>';\n html += '</table>';\n }\n if (d.codeDna.deviations && d.codeDna.deviations.length > 0) {\n html += '<h2>Deviation Analysis</h2><table><tr><th>File</th><th>Verdict</th><th>Pattern</th></tr>';\n for (const dv of d.codeDna.deviations) html += '<tr><td>' + esc2(dv.file) + '</td><td>' + dv.verdict + '</td><td>' + esc2(dv.pattern) + '</td></tr>';\n html += '</table>';\n }\n }\n if (d.deepInsights && d.deepInsights.length > 0) {\n html += '<div class=\"page-break\"></div><h1>Deep Analysis Insights (AI-Powered)</h1>';\n for (const ins of d.deepInsights) {\n html += '<h3>[' + ins.severity.toUpperCase() + '] ' + esc2(ins.title) + '</h3>';\n html += '<p>' + esc2(ins.description) + '</p>';\n if (ins.recommendation) html += '<div class=\"rec\"><strong>Fix:</strong> ' + esc2(ins.recommendation) + '</div>';\n }\n }\n return html;\n}\n\nfunction exportDOCX() {\n const d = window.__VIBEDRIFT_DATA;\n if (!d) { alert('Report data not available'); return; }\n\n let html = '<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:w=\"urn:schemas-microsoft-com:office:word\"><head><meta charset=\"utf-8\"><style>';\n html += 'body{font-family:Calibri,sans-serif;font-size:11pt;color:#222;margin:40px}';\n html += 'h1{font-size:20pt;color:#0B0F15;border-bottom:2px solid #00D4FF;padding-bottom:8px;margin-top:28px}';\n html += 'h2{font-size:14pt;color:#333;margin-top:20px}';\n html += 'h3{font-size:12pt;color:#555;margin-top:14px}';\n html += 'table{border-collapse:collapse;width:100%;margin:10px 0}';\n html += 'th,td{border:1px solid #ddd;padding:6px 10px;text-align:left;font-size:10pt}';\n html += 'th{background:#f0f4f8;font-weight:600}';\n html += '.sev-critical{color:#dc2626;font-weight:700} .sev-warning{color:#d97706;font-weight:700} .sev-info{color:#2563eb}';\n html += '.intent{background:#ecfdf5;border-left:3px solid #10b981;padding:8px 12px;margin:6px 0}';\n html += '.drift{background:#fff7ed;border-left:3px solid #f97316;padding:8px 12px;margin:6px 0}';\n html += '.rec{background:#f0f9ff;border-left:3px solid #0ea5e9;padding:8px 12px;margin:6px 0}';\n html += 'code{font-family:Consolas,monospace;font-size:9pt;background:#f5f5f5;padding:1px 4px}';\n html += '.page-break{page-break-before:always}';\n html += '</style></head><body>';\n\n html += '<div style=\"text-align:center;margin-bottom:30px\">';\n html += '<h1 style=\"border:none;font-size:28pt;color:#00D4FF\">VIBEDRIFT REPORT</h1>';\n html += '<p style=\"font-size:16pt;color:#333\">' + esc2(d.project) + '</p>';\n html += '<p>' + d.fileCount + ' files · ' + d.totalLines.toLocaleString() + ' LOC · Score: <strong>' + d.score + '/' + d.maxScore + '</strong></p>';\n html += '</div>';\n\n html += buildDocxFindingsHtml(d);\n html += buildDocxScoresHtml(d);\n\n html += '<hr><p style=\"color:#999;font-size:9pt\">Generated by VibeDrift v' + d.version + ' | ' + d.fileCount + ' files | No data sent externally</p>';\n html += '</body></html>';\n\n const blob = new Blob([html], { type: 'application/vnd.ms-word' });\n const a = document.createElement('a');\n a.href = URL.createObjectURL(blob);\n a.download = d.project + '-vibedrift.doc';\n a.click();\n URL.revokeObjectURL(a.href);\n}\n\nfunction esc2(s) { return String(s || '').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); }\n</script>\n\n</body>\n</html>`;\n}\n","import { readdir, readFile, writeFile, mkdir } from \"fs/promises\";\nimport { homedir } from \"os\";\nimport { createHash } from \"crypto\";\nimport { join } from \"path\";\nimport type { CategoryScores } from \"./types.js\";\n\n/**\n * Per-project scan history.\n *\n * History lives at $HOME/.vibedrift/scans/<project-hash>/scan-<ts>.json,\n * NOT inside the user's project tree. We never write into the project\n * directory — that pollutes git status and confuses tooling.\n *\n * The project hash is a SHA-256 prefix of the absolute path. It is stable\n * across runs but lets a single user track many projects without leaking\n * paths to anyone reading the directory listing.\n */\n\nconst ROOT_DIR = join(homedir(), \".vibedrift\", \"scans\");\n\nfunction projectHash(rootDir: string): string {\n return createHash(\"sha256\").update(rootDir).digest(\"hex\").slice(0, 16);\n}\n\nfunction projectDir(rootDir: string): string {\n return join(ROOT_DIR, projectHash(rootDir));\n}\n\nexport async function saveScanResult(\n rootDir: string,\n scores: CategoryScores,\n compositeScore: number,\n): Promise<void> {\n const dir = projectDir(rootDir);\n try {\n await mkdir(dir, { recursive: true, mode: 0o700 });\n } catch { /* exists */ }\n\n const data = {\n timestamp: new Date().toISOString(),\n rootDir,\n scores,\n compositeScore,\n };\n\n const filename = `scan-${Date.now()}.json`;\n await writeFile(join(dir, filename), JSON.stringify(data, null, 2));\n}\n\nexport async function loadPreviousScores(\n rootDir: string,\n): Promise<CategoryScores | null> {\n const dir = projectDir(rootDir);\n\n try {\n const files = await readdir(dir);\n const scanFiles = files\n .filter((f) => f.startsWith(\"scan-\") && f.endsWith(\".json\"))\n .sort()\n .reverse();\n\n if (scanFiles.length === 0) return null;\n\n const raw = await readFile(join(dir, scanFiles[0]), \"utf-8\");\n const data = JSON.parse(raw);\n return data.scores ?? null;\n } catch {\n return null;\n }\n}\n","import type { SourceFile } from \"./types.js\";\n\n/**\n * Apply --include / --exclude glob filtering to a discovered file set.\n *\n * Semantics:\n * - If `includes` is non-empty, a file must match AT LEAST ONE include pattern.\n * - A file matching ANY exclude pattern is dropped.\n * - Patterns are matched against the file's `relativePath` (the path\n * relative to the project root that we already track in SourceFile).\n *\n * We implement a small, dependency-free glob → regex converter that supports\n * the patterns developers actually use:\n *\n * * — any sequence within a single path segment\n * ** — any sequence including slashes\n * ? — any single character within a segment\n * {a,b,c} — alternation\n * [abc] — character class\n * trailing / — directory match\n *\n * Negated patterns (`!foo`) are not supported here — use --exclude instead.\n */\n\nexport function applyIncludeExclude(\n files: SourceFile[],\n includes: string[],\n excludes: string[],\n): SourceFile[] {\n const includeRegexes = includes.map(globToRegex);\n const excludeRegexes = excludes.map(globToRegex);\n\n const useInclude = includeRegexes.length > 0;\n\n return files.filter((file) => {\n const path = file.relativePath;\n\n if (useInclude && !includeRegexes.some((re) => re.test(path))) {\n return false;\n }\n if (excludeRegexes.some((re) => re.test(path))) {\n return false;\n }\n return true;\n });\n}\n\n/**\n * Convert a single glob pattern to a JavaScript RegExp.\n * Anchored: matches the *whole* relative path.\n *\n * Test cases this handles:\n * \"src/**\" → src/anything (any depth)\n * \"**\\/*.test.ts\" → any file ending in .test.ts at any depth\n * \"src/?ndex.ts\" → src/index.ts or src/Cndex.ts ...\n * \"src/{a,b}/main.ts\" → src/a/main.ts or src/b/main.ts\n */\nexport function globToRegex(glob: string): RegExp {\n // Strip a leading \"./\"\n let pattern = glob.replace(/^\\.\\//, \"\");\n\n // Trailing \"/\" → directory match (anything inside)\n if (pattern.endsWith(\"/\")) {\n pattern = pattern + \"**\";\n }\n\n let result = \"\";\n let i = 0;\n let inClass = false;\n\n while (i < pattern.length) {\n const ch = pattern[i];\n\n if (inClass) {\n if (ch === \"]\") {\n inClass = false;\n result += \"]\";\n } else {\n // Escape regex meta inside char classes except ! and ^\n result += escapeInClass(ch);\n }\n i++;\n continue;\n }\n\n switch (ch) {\n case \"*\": {\n if (pattern[i + 1] === \"*\") {\n // ** — match any sequence including /\n // Followed by / ⇒ \"(?:.*/)?\" so \"src/**/foo\" matches \"src/foo\" too\n if (pattern[i + 2] === \"/\") {\n result += \"(?:.*/)?\";\n i += 3;\n } else {\n result += \".*\";\n i += 2;\n }\n } else {\n // * — any sequence excluding /\n result += \"[^/]*\";\n i++;\n }\n break;\n }\n case \"?\": {\n result += \"[^/]\";\n i++;\n break;\n }\n case \"[\": {\n inClass = true;\n result += \"[\";\n i++;\n break;\n }\n case \"{\": {\n // {a,b,c} → (?:a|b|c)\n const close = pattern.indexOf(\"}\", i);\n if (close === -1) {\n result += \"\\\\{\";\n i++;\n break;\n }\n const inner = pattern.slice(i + 1, close);\n const parts = inner.split(\",\").map((p) => p.trim()).filter(Boolean);\n if (parts.length > 0) {\n result += \"(?:\" + parts.map(escapeRegex).join(\"|\") + \")\";\n } else {\n result += \"\\\\{\\\\}\";\n }\n i = close + 1;\n break;\n }\n default: {\n result += escapeRegex(ch);\n i++;\n break;\n }\n }\n }\n\n return new RegExp(\"^\" + result + \"$\");\n}\n\nfunction escapeRegex(ch: string): string {\n if (/[.+^${}()|\\\\]/.test(ch)) return \"\\\\\" + ch;\n return ch;\n}\n\nfunction escapeInClass(ch: string): string {\n if (ch === \"\\\\\") return \"\\\\\\\\\";\n return ch;\n}\n","import { readConfig } from \"./config.js\";\n\n/**\n * Token resolution.\n *\n * Priority order (highest first):\n * 1. Explicit CLI flag (--token / --ml-key, kept temporarily for back-compat)\n * 2. VIBEDRIFT_TOKEN environment variable\n * 3. ~/.vibedrift/config.json `token` field\n *\n * Returns null if no token is configured anywhere. Callers decide whether\n * to error, fall back to anonymous mode, or print an actionable message.\n */\n\nexport interface TokenResolutionInput {\n explicitToken?: string;\n}\n\nexport interface ResolvedToken {\n token: string;\n source: \"flag\" | \"env\" | \"config\";\n}\n\nexport async function resolveToken(input: TokenResolutionInput = {}): Promise<ResolvedToken | null> {\n if (input.explicitToken && input.explicitToken.trim().length > 0) {\n return { token: input.explicitToken.trim(), source: \"flag\" };\n }\n\n const fromEnv = process.env.VIBEDRIFT_TOKEN;\n if (fromEnv && fromEnv.trim().length > 0) {\n return { token: fromEnv.trim(), source: \"env\" };\n }\n\n const config = await readConfig();\n if (config.token && config.token.trim().length > 0) {\n return { token: config.token.trim(), source: \"config\" };\n }\n\n return null;\n}\n\n/**\n * API base URL resolution.\n *\n * 1. Explicit CLI flag (--api-url)\n * 2. VIBEDRIFT_API_URL environment variable\n * 3. ~/.vibedrift/config.json `apiUrl` field\n * 4. Built-in default (production)\n */\nexport async function resolveApiUrl(explicitUrl?: string): Promise<string> {\n if (explicitUrl && explicitUrl.trim().length > 0) return explicitUrl.trim();\n if (process.env.VIBEDRIFT_API_URL && process.env.VIBEDRIFT_API_URL.trim().length > 0) {\n return process.env.VIBEDRIFT_API_URL.trim();\n }\n const config = await readConfig();\n if (config.apiUrl && config.apiUrl.trim().length > 0) return config.apiUrl.trim();\n return \"https://vibedrift-api.fly.dev\";\n}\n\n/**\n * Display-friendly token preview (\"vd_live_a3x...\").\n * Shows the **prefix** (not the suffix) so users can tell which key they're\n * using without leaking enough entropy to be useful to an attacker.\n */\nexport function previewToken(token: string): string {\n if (!token) return \"(none)\";\n if (token.length <= 12) return token.slice(0, 4) + \"…\";\n return token.slice(0, 12) + \"…\";\n}\n\n/** Human-readable label for the token source. Shared by status + doctor. */\nexport function describeSource(source: \"flag\" | \"env\" | \"config\"): string {\n switch (source) {\n case \"flag\": return \"command-line flag\";\n case \"env\": return \"VIBEDRIFT_TOKEN environment variable\";\n case \"config\": return \"~/.vibedrift/config.json\";\n }\n}\n","import { homedir } from \"os\";\nimport { join } from \"path\";\nimport { readFile, writeFile, mkdir, chmod, unlink, stat } from \"fs/promises\";\n\n/**\n * VibeDrift CLI configuration storage.\n *\n * Stored at $HOME/.vibedrift/config.json with mode 0600 (user read/write only).\n * Holds the device-auth bearer token plus the plan/email/expiry that\n * vibedrift-api returned alongside it.\n *\n * NOTE: scan history (per-project deltas) lives at $HOME/.vibedrift/scans/\n * — see core/history.ts. The CLI should never write inside the user's\n * project directory.\n */\n\nexport interface VibeDriftConfig {\n /** Bearer token returned by /auth/poll. Opaque, server-generated. */\n token?: string;\n\n /** Email of the authenticated user (display only). */\n email?: string;\n\n /** \"free\" | \"pro\" | \"team\" — last known plan, refreshed on each login. */\n plan?: \"free\" | \"pro\" | \"team\";\n\n /** ISO-8601 timestamp the token expires (server-side enforcement is authoritative). */\n expiresAt?: string;\n\n /** ISO-8601 timestamp the user authenticated. */\n loggedInAt?: string;\n\n /** Override the API base URL (developers / staging only). Set via env or login --api. */\n apiUrl?: string;\n\n /** Stripe customer ID (display only — server is the source of truth). */\n stripeCustomerId?: string;\n}\n\nconst DEFAULT_DIR = join(homedir(), \".vibedrift\");\nconst DEFAULT_FILE = join(DEFAULT_DIR, \"config.json\");\n\nexport function getConfigDir(): string {\n return DEFAULT_DIR;\n}\n\nexport function getConfigPath(): string {\n return DEFAULT_FILE;\n}\n\nexport async function ensureConfigDir(): Promise<void> {\n await mkdir(DEFAULT_DIR, { recursive: true, mode: 0o700 });\n}\n\nexport async function readConfig(): Promise<VibeDriftConfig> {\n try {\n const raw = await readFile(DEFAULT_FILE, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return {};\n return parsed as VibeDriftConfig;\n } catch (err: any) {\n if (err?.code === \"ENOENT\") return {};\n // Corrupt config: don't crash, but warn loudly\n process.stderr.write(`vibedrift: warning — config at ${DEFAULT_FILE} is unreadable (${err?.message ?? err}). Treating as empty.\\n`);\n return {};\n }\n}\n\nexport async function writeConfig(config: VibeDriftConfig): Promise<void> {\n await ensureConfigDir();\n const json = JSON.stringify(config, null, 2);\n await writeFile(DEFAULT_FILE, json, { mode: 0o600 });\n // Belt and braces — ensure mode in case the file already existed with wrong perms.\n try {\n await chmod(DEFAULT_FILE, 0o600);\n } catch {\n // Best-effort only (e.g. on Windows)\n }\n}\n\nexport async function clearConfig(): Promise<void> {\n try {\n await unlink(DEFAULT_FILE);\n } catch (err: any) {\n if (err?.code !== \"ENOENT\") throw err;\n }\n}\n\nexport async function configExists(): Promise<boolean> {\n try {\n await stat(DEFAULT_FILE);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Update specific fields without clobbering the rest of the config.\n * Reads, merges, writes.\n */\nexport async function patchConfig(patch: Partial<VibeDriftConfig>): Promise<VibeDriftConfig> {\n const current = await readConfig();\n const next: VibeDriftConfig = { ...current, ...patch };\n await writeConfig(next);\n return next;\n}\n","import { resolveApiUrl } from \"./resolver.js\";\n\n/**\n * Typed HTTP client for the VibeDrift Auth + Account API.\n *\n * All endpoints live on the same Fly.io app as the analyze endpoint\n * (vibedrift-api.fly.dev). Auth endpoints are unauthenticated; account\n * endpoints require a Bearer token in the Authorization header.\n */\n\nconst REQUEST_TIMEOUT_MS = 30_000;\n\nexport interface DeviceStartResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete: string;\n expires_in: number; // seconds\n interval: number; // seconds — minimum gap between polls\n}\n\nexport interface DevicePollSuccess {\n status: \"authorized\";\n access_token: string;\n email: string;\n plan: \"free\" | \"pro\" | \"team\";\n expires_at: string;\n}\n\nexport interface DevicePollPending {\n status: \"pending\";\n}\n\nexport interface DevicePollDenied {\n status: \"denied\" | \"expired\";\n message?: string;\n}\n\nexport type DevicePollResponse = DevicePollSuccess | DevicePollPending | DevicePollDenied;\n\nexport interface ValidateResponse {\n valid: boolean;\n email?: string;\n plan?: \"free\" | \"pro\" | \"team\";\n expires_at?: string;\n}\n\nexport interface UsageResponse {\n user: {\n email: string;\n plan: \"free\" | \"pro\" | \"team\";\n };\n current_period: {\n start: string;\n end: string;\n scans: number;\n deep_scans: number;\n };\n limits: {\n deep_scans_per_month: number | null; // null = unlimited\n rate_limit_per_min: number;\n };\n recent_scans: Array<{\n id: string;\n project_hash: string;\n score: number | null;\n is_deep: boolean;\n created_at: string;\n }>;\n}\n\nexport interface PortalResponse {\n url: string;\n}\n\nexport interface FeedbackResponse {\n id: string;\n received_at: string;\n}\n\nexport interface CreditsResponse {\n plan: \"free\" | \"pro\" | \"team\";\n unlimited: boolean;\n available_total: number;\n available_welcome: number;\n available_purchased: number;\n available_manual: number;\n welcome_granted: boolean;\n welcome_consumed: boolean;\n has_free_deep_scan: boolean;\n}\n\nexport class VibeDriftApiError extends Error {\n constructor(public status: number, message: string) {\n super(message);\n this.name = \"VibeDriftApiError\";\n }\n}\n\n/** Internal: shared fetch helper with timeout, JSON parsing, error mapping. */\nasync function jsonFetch<T>(url: string, init: RequestInit = {}): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n try {\n const res = await fetch(url, {\n ...init,\n signal: controller.signal,\n headers: {\n Accept: \"application/json\",\n ...(init.body ? { \"Content-Type\": \"application/json\" } : {}),\n ...(init.headers ?? {}),\n },\n });\n\n if (!res.ok) {\n let detail = \"\";\n try {\n const body = await res.json() as { detail?: string; message?: string };\n detail = body.detail ?? body.message ?? \"\";\n } catch {\n try { detail = await res.text(); } catch { /* ignore */ }\n }\n throw new VibeDriftApiError(res.status, detail || `HTTP ${res.status}`);\n }\n\n return await res.json() as T;\n } catch (err: any) {\n if (err?.name === \"AbortError\") {\n throw new VibeDriftApiError(0, `Request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`);\n }\n if (err instanceof VibeDriftApiError) throw err;\n throw new VibeDriftApiError(0, err?.message ?? String(err));\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** Begin a device authorization flow. CLI calls this and prints user_code. */\nexport async function startDeviceAuth(opts?: { apiUrl?: string }): Promise<DeviceStartResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<DeviceStartResponse>(`${base}/auth/device`, {\n method: \"POST\",\n body: JSON.stringify({ client_id: \"vibedrift-cli\" }),\n });\n}\n\n/** Poll for device-auth completion. Server responds with pending/authorized/denied/expired. */\nexport async function pollDeviceAuth(deviceCode: string, opts?: { apiUrl?: string }): Promise<DevicePollResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<DevicePollResponse>(`${base}/auth/poll`, {\n method: \"POST\",\n body: JSON.stringify({ device_code: deviceCode }),\n });\n}\n\n/** Validate a token. Used by `vibedrift status` and `vibedrift doctor`. */\nexport async function validateToken(token: string, opts?: { apiUrl?: string }): Promise<ValidateResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<ValidateResponse>(`${base}/auth/validate`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n\n/** Revoke the current token server-side. Called by `vibedrift logout`. */\nexport async function revokeToken(token: string, opts?: { apiUrl?: string }): Promise<void> {\n const base = await resolveApiUrl(opts?.apiUrl);\n await jsonFetch<{ ok: true }>(`${base}/auth/revoke`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n\n/** Fetch usage stats for the authenticated user. */\nexport async function fetchUsage(token: string, opts?: { apiUrl?: string }): Promise<UsageResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<UsageResponse>(`${base}/account/usage`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n\n/**\n * Send free-form feedback. Auth is OPTIONAL — anonymous submissions\n * are accepted by the server. When `token` is supplied we attach it so\n * the dashboard can correlate the feedback with the user's account.\n */\nexport async function sendFeedback(args: {\n source: \"cli\" | \"dashboard\" | \"landing\";\n message: string;\n token?: string;\n email?: string;\n metadata?: Record<string, unknown>;\n apiUrl?: string;\n}): Promise<FeedbackResponse> {\n const base = await resolveApiUrl(args.apiUrl);\n const headers: Record<string, string> = {};\n if (args.token) headers.Authorization = `Bearer ${args.token}`;\n return jsonFetch<FeedbackResponse>(`${base}/v1/feedback/general`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n source: args.source,\n message: args.message,\n email: args.email,\n metadata: args.metadata,\n }),\n });\n}\n\n/** Fetch the user's credit summary (welcome + purchased + manual). */\nexport async function fetchCredits(token: string, opts?: { apiUrl?: string }): Promise<CreditsResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<CreditsResponse>(`${base}/account/credits`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n\n/** Create a Stripe Customer Portal session and return the URL to open. */\nexport async function createPortalSession(token: string, opts?: { apiUrl?: string }): Promise<PortalResponse> {\n const base = await resolveApiUrl(opts?.apiUrl);\n return jsonFetch<PortalResponse>(`${base}/account/portal`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${token}` },\n });\n}\n","import { spawn } from \"child_process\";\nimport chalk from \"chalk\";\n\nconst PACKAGE_NAME = \"@vibedrift/cli\";\nconst REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;\n\nfunction semverGreater(a: string, b: string): boolean {\n const pa = a.split(\".\").map(Number);\n const pb = b.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n const x = pa[i] ?? 0;\n const y = pb[i] ?? 0;\n if (x > y) return true;\n if (x < y) return false;\n }\n return false;\n}\n\nexport async function runUpdate(currentVersion: string): Promise<void> {\n console.log(chalk.dim(\"Checking for updates...\"));\n\n let latest: string;\n try {\n const res = await fetch(REGISTRY_URL, {\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) {\n throw new Error(`registry returned HTTP ${res.status}`);\n }\n const data = (await res.json()) as { version?: string };\n if (!data.version) {\n throw new Error(\"registry response missing version field\");\n }\n latest = data.version;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(chalk.red(`Failed to check for updates: ${message}`));\n console.error(chalk.dim(`Try manually: npm i -g ${PACKAGE_NAME}@latest`));\n process.exit(1);\n }\n\n if (currentVersion === latest) {\n console.log(\n chalk.green(`✓ Already on the latest version (${currentVersion}).`),\n );\n return;\n }\n\n if (!semverGreater(latest, currentVersion)) {\n console.log(\n chalk.yellow(\n `Local version (${currentVersion}) is ahead of the registry (${latest}). Nothing to do.`,\n ),\n );\n return;\n }\n\n console.log(\n chalk.bold(\n `Updating ${PACKAGE_NAME}: ${chalk.dim(currentVersion)} → ${chalk.yellow(latest)}`,\n ),\n );\n console.log(chalk.dim(`Running: npm i -g ${PACKAGE_NAME}@${latest}\\n`));\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\n \"npm\",\n [\"i\", \"-g\", `${PACKAGE_NAME}@${latest}`],\n { stdio: \"inherit\", shell: false },\n );\n child.on(\"error\", (err) => {\n reject(err);\n });\n child.on(\"exit\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`npm exited with code ${code}`));\n }\n });\n })\n .then(() => {\n console.log(chalk.green(`\\n✓ Updated to ${latest}.`));\n console.log(chalk.dim(\"Run `vibedrift --version` to verify.\"));\n })\n .catch((err) => {\n const message = err instanceof Error ? err.message : String(err);\n console.error(chalk.red(`\\nUpdate failed: ${message}`));\n console.error(chalk.dim(\"\\nManual install commands by package manager:\"));\n console.error(chalk.dim(` npm: npm i -g ${PACKAGE_NAME}@latest`));\n console.error(chalk.dim(` pnpm: pnpm add -g ${PACKAGE_NAME}@latest`));\n console.error(chalk.dim(` bun: bun add -g ${PACKAGE_NAME}@latest`));\n console.error(chalk.dim(` yarn: yarn global add ${PACKAGE_NAME}@latest`));\n process.exit(1);\n });\n}\n","import chalk from \"chalk\";\nimport {\n startDeviceAuth,\n pollDeviceAuth,\n fetchCredits,\n VibeDriftApiError,\n} from \"../../auth/api.js\";\nimport { patchConfig, readConfig } from \"../../auth/config.js\";\nimport { openInBrowser } from \"../../auth/browser.js\";\nimport { previewToken } from \"../../auth/resolver.js\";\n\nexport interface LoginOptions {\n apiUrl?: string;\n noBrowser?: boolean;\n}\n\n/**\n * Device-authorization login flow (RFC 8628 inspired, GitHub CLI style).\n *\n * 1. POST /auth/device → server returns user_code, verification_uri, device_code\n * 2. Print user_code, open verification_uri in the browser\n * 3. Poll /auth/poll until status === \"authorized\"\n * 4. Save the resulting access_token to ~/.vibedrift/config.json\n *\n * No password ever touches the CLI. The browser handles the auth and the\n * server hands the CLI back an opaque bearer token.\n */\nexport async function runLogin(options: LoginOptions = {}): Promise<void> {\n // Warn if a token already exists so we don't silently clobber it.\n const existing = await readConfig();\n if (existing.token) {\n console.log(\n chalk.yellow(\n `\\n You're already logged in as ${chalk.bold(existing.email ?? \"unknown\")} (${existing.plan ?? \"free\"}).`,\n ),\n );\n console.log(chalk.dim(` Token: ${previewToken(existing.token)}`));\n console.log(chalk.dim(\" Continuing will replace this token.\\n\"));\n }\n\n let device;\n try {\n device = await startDeviceAuth({ apiUrl: options.apiUrl });\n } catch (err) {\n fail(\"Could not start the login flow\", err);\n return;\n }\n\n console.log(\"\");\n console.log(chalk.bold(\" First, copy your one-time code:\"));\n console.log(\"\");\n console.log(` ${chalk.bgYellow.black.bold(` ${device.user_code} `)}`);\n console.log(\"\");\n console.log(chalk.dim(` This code expires in ${formatDuration(device.expires_in)}.`));\n console.log(\"\");\n\n const opened = !options.noBrowser && openInBrowser(device.verification_uri_complete);\n if (opened) {\n console.log(chalk.bold(\" Opened your browser to:\"));\n } else {\n console.log(chalk.bold(\" Open this URL in your browser:\"));\n }\n console.log(` ${chalk.cyan(device.verification_uri_complete)}`);\n console.log(\"\");\n console.log(chalk.dim(\" Waiting for you to authorize the CLI...\"));\n console.log(\"\");\n\n // Poll loop. Use the server-suggested interval; double on slow_down errors.\n let interval = Math.max(1, device.interval);\n const deadline = Date.now() + device.expires_in * 1000;\n\n while (Date.now() < deadline) {\n await sleep(interval * 1000);\n\n let result;\n try {\n result = await pollDeviceAuth(device.device_code, { apiUrl: options.apiUrl });\n } catch (err) {\n if (err instanceof VibeDriftApiError && err.status === 429) {\n interval = Math.min(interval * 2, 30);\n continue;\n }\n fail(\"Polling for authorization failed\", err);\n return;\n }\n\n if (result.status === \"pending\") continue;\n\n if (result.status === \"authorized\") {\n await handleLoginSuccess(result, options);\n return;\n }\n\n if (result.status === \"denied\") {\n console.error(chalk.red(\"\\n ✗ Authorization was denied in the browser.\"));\n console.error(chalk.dim(\" Run `vibedrift login` again to retry.\\n\"));\n process.exit(1);\n }\n\n if (result.status === \"expired\") {\n console.error(chalk.red(\"\\n ✗ The login code expired before you authorized it.\"));\n console.error(chalk.dim(\" Run `vibedrift login` again to retry.\\n\"));\n process.exit(1);\n }\n }\n\n console.error(chalk.red(\"\\n ✗ Login timed out before authorization completed.\"));\n console.error(chalk.dim(\" Run `vibedrift login` again to retry.\\n\"));\n process.exit(1);\n}\n\nasync function handleLoginSuccess(\n result: { access_token: string; email: string; plan: \"free\" | \"pro\" | \"team\"; expires_at: string },\n options: LoginOptions,\n): Promise<void> {\n await patchConfig({\n token: result.access_token,\n email: result.email,\n plan: result.plan,\n expiresAt: result.expires_at,\n loggedInAt: new Date().toISOString(),\n apiUrl: options.apiUrl,\n });\n console.log(chalk.green(\" ✓ Logged in successfully.\"));\n console.log(\"\");\n console.log(` Account: ${chalk.bold(result.email)}`);\n console.log(` Plan: ${chalk.bold(result.plan)}`);\n console.log(\"\");\n\n // Fetch + announce the one-time welcome credit. Non-fatal if the\n // call fails — older API builds simply won't have this endpoint.\n try {\n const credits = await fetchCredits(result.access_token, {\n apiUrl: options.apiUrl,\n });\n if (credits.has_free_deep_scan && !credits.unlimited) {\n console.log(\n chalk.bgYellow.black.bold(\" 🎁 3 FREE deep scans every month with your account \"),\n );\n console.log(\"\");\n console.log(\n chalk.yellow(\" Try the full pipeline (Claude analysis, security review,\"),\n );\n console.log(\n chalk.yellow(\" AI-powered drift detection) on any project — no card needed.\"),\n );\n console.log(\"\");\n console.log(` ${chalk.cyan(\"vibedrift . --deep\")}`);\n console.log(\"\");\n } else if (credits.unlimited) {\n console.log(chalk.dim(\" Run `vibedrift . --deep` to use AI-powered analysis.\"));\n console.log(\"\");\n } else if (credits.available_total > 0) {\n console.log(\n chalk.dim(` You have ${credits.available_total} deep scan credit${credits.available_total === 1 ? \"\" : \"s\"} available.`),\n );\n console.log(chalk.dim(\" Run `vibedrift . --deep` to use one.\"));\n console.log(\"\");\n } else {\n console.log(chalk.dim(\" Run `vibedrift upgrade` to enable deep AI scans.\"));\n console.log(\"\");\n }\n } catch {\n // Endpoint missing or transient error — fall back to legacy hint.\n if (result.plan === \"free\") {\n console.log(chalk.dim(\" Run `vibedrift upgrade` to enable deep AI scans.\"));\n } else {\n console.log(chalk.dim(\" Run `vibedrift . --deep` to use AI-powered analysis.\"));\n }\n console.log(\"\");\n }\n}\n\nfunction fail(intro: string, err: unknown): never {\n const msg = err instanceof VibeDriftApiError\n ? `${err.status ? `HTTP ${err.status}: ` : \"\"}${err.message}`\n : err instanceof Error\n ? err.message\n : String(err);\n console.error(chalk.red(`\\n ✗ ${intro}: ${msg}\\n`));\n process.exit(1);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction formatDuration(seconds: number): string {\n if (seconds < 60) return `${seconds}s`;\n const m = Math.round(seconds / 60);\n return `${m} minute${m === 1 ? \"\" : \"s\"}`;\n}\n","import { spawn } from \"child_process\";\n\n/**\n * Cross-platform browser opener.\n *\n * Returns true if the open command was launched successfully (we cannot\n * tell if the user actually saw the page). Returns false if no opener\n * is available — callers should fall back to printing the URL.\n *\n * Honors the BROWSER environment variable when set (Linux/CI convention).\n * Refuses to open in non-interactive environments (CI=true and no TTY)\n * to avoid spawning hidden processes.\n */\nexport function openInBrowser(url: string): boolean {\n if (!isInteractive()) return false;\n\n const env = process.env.BROWSER;\n if (env && env.length > 0 && env !== \"none\") {\n return spawnDetached(env, [url]);\n }\n\n switch (process.platform) {\n case \"darwin\":\n return spawnDetached(\"open\", [url]);\n case \"win32\":\n return spawnDetached(\"cmd\", [\"/c\", \"start\", \"\", url]);\n default:\n return spawnDetached(\"xdg-open\", [url]);\n }\n}\n\nfunction isInteractive(): boolean {\n if (process.env.CI === \"true\" || process.env.CI === \"1\") return false;\n if (process.env.VIBEDRIFT_NO_BROWSER === \"1\") return false;\n return process.stdout.isTTY ?? false;\n}\n\nfunction spawnDetached(cmd: string, args: string[]): boolean {\n try {\n const child = spawn(cmd, args, {\n detached: true,\n stdio: \"ignore\",\n shell: false,\n });\n child.on(\"error\", () => {\n // Swallow — caller already returned true and printed a fallback URL.\n });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n","import chalk from \"chalk\";\nimport { clearConfig, readConfig } from \"../../auth/config.js\";\nimport { revokeToken, VibeDriftApiError } from \"../../auth/api.js\";\n\n/**\n * Logout: revoke the token server-side and remove the local config file.\n *\n * Local removal happens unconditionally even if the server revoke fails,\n * so users can always recover from a stale/broken token by running\n * `vibedrift logout`. The server revoke is best-effort.\n */\nexport async function runLogout(): Promise<void> {\n const config = await readConfig();\n\n if (!config.token) {\n console.log(chalk.dim(\" Not logged in. Nothing to do.\"));\n return;\n }\n\n // Best-effort server revoke\n try {\n await revokeToken(config.token, { apiUrl: config.apiUrl });\n } catch (err) {\n if (err instanceof VibeDriftApiError && (err.status === 401 || err.status === 404)) {\n // Token was already revoked or unknown — fine, treat as success.\n } else {\n console.warn(\n chalk.yellow(\n ` ⚠ Could not revoke token on the server: ${err instanceof Error ? err.message : String(err)}`,\n ),\n );\n console.warn(chalk.dim(\" Local token will still be removed.\"));\n }\n }\n\n await clearConfig();\n console.log(chalk.green(\" ✓ Logged out.\"));\n}\n","import chalk from \"chalk\";\nimport { readConfig, getConfigPath } from \"../../auth/config.js\";\nimport { previewToken, resolveToken, describeSource } from \"../../auth/resolver.js\";\nimport { validateToken, fetchCredits, VibeDriftApiError } from \"../../auth/api.js\";\nimport { getVersion } from \"../../core/version.js\";\n\n/**\n * `vibedrift status` — show the currently active account, plan, and token preview.\n *\n * Token display rule (security): we show the **prefix**, never the suffix.\n * Suffix-only previews leak the most useful bytes for an attacker.\n */\nexport async function runStatus(): Promise<void> {\n const version = getVersion();\n const config = await readConfig();\n const resolved = await resolveToken();\n\n console.log(\"\");\n console.log(chalk.bold(` VibeDrift CLI v${version}`));\n console.log(\"\");\n\n if (!resolved) {\n console.log(` Status: ${chalk.dim(\"not logged in\")}`);\n console.log(` Config: ${chalk.dim(getConfigPath())}`);\n console.log(\"\");\n console.log(chalk.dim(\" Run `vibedrift login` to authenticate.\"));\n console.log(\"\");\n return;\n }\n\n console.log(` Status: ${chalk.green(\"authenticated\")}`);\n console.log(` Source: ${chalk.dim(describeSource(resolved.source))}`);\n console.log(` Token: ${chalk.dim(previewToken(resolved.token))}`);\n\n // Local config metadata (only meaningful when source === \"config\")\n if (resolved.source === \"config\") {\n if (config.email) console.log(` Account: ${chalk.bold(config.email)}`);\n if (config.plan) console.log(` Plan: ${chalk.bold(config.plan)}`);\n if (config.expiresAt) console.log(` Expires: ${chalk.dim(config.expiresAt)}`);\n console.log(` Config: ${chalk.dim(getConfigPath())}`);\n }\n\n console.log(\"\");\n\n // Server-side validation — confirms the token is still live.\n process.stdout.write(chalk.dim(\" Validating token with server... \"));\n try {\n const result = await validateToken(resolved.token, { apiUrl: config.apiUrl });\n if (result.valid) {\n console.log(chalk.green(\"ok\"));\n if (result.email && result.email !== config.email) {\n console.log(chalk.dim(` Server account: ${result.email} (config out of sync — run \\`vibedrift login\\` to refresh)`));\n }\n if (result.plan && result.plan !== config.plan) {\n console.log(chalk.dim(` Server plan: ${result.plan} (config out of sync — run \\`vibedrift login\\` to refresh)`));\n }\n } else {\n console.log(chalk.red(\"invalid\"));\n console.log(chalk.dim(\" Run `vibedrift login` to re-authenticate.\"));\n }\n } catch (err) {\n console.log(chalk.yellow(\"offline\"));\n if (err instanceof VibeDriftApiError) {\n console.log(chalk.dim(` ${err.message}`));\n }\n }\n\n // Credit summary — surfaces the welcome credit and any purchased ones.\n try {\n const credits = await fetchCredits(resolved.token, { apiUrl: config.apiUrl });\n console.log(\"\");\n if (credits.unlimited) {\n console.log(` Deep scans: ${chalk.bold.green(\"unlimited\")} (${credits.plan})`);\n } else if (credits.has_free_deep_scan) {\n console.log(` Deep scans: ${chalk.bold.yellow(\"1 free\")} + ${credits.available_purchased} purchased`);\n console.log(chalk.dim(\" Run `vibedrift . --deep` to use your free credit.\"));\n } else if (credits.available_total > 0) {\n console.log(` Deep scans: ${chalk.bold(credits.available_total)} credit${credits.available_total === 1 ? \"\" : \"s\"} available`);\n } else {\n console.log(` Deep scans: ${chalk.dim(\"0 credits\")} — run \\`vibedrift upgrade\\` for more`);\n }\n } catch {\n // Older API or transient error — silently skip the credits line.\n }\n\n console.log(\"\");\n}\n\n","import chalk from \"chalk\";\nimport { resolveToken } from \"../../auth/resolver.js\";\nimport { fetchUsage, VibeDriftApiError } from \"../../auth/api.js\";\nimport { readConfig } from \"../../auth/config.js\";\n\n/**\n * `vibedrift usage` — show current-period scan counts and rate limits.\n *\n * Pro plan: unlimited deep scans, but a 60 req/min rate limit.\n * Free plan: a small number of free deep scans included.\n */\nexport async function runUsage(): Promise<void> {\n const resolved = await resolveToken();\n if (!resolved) {\n console.error(chalk.red(\"\\n ✗ Not logged in. Run `vibedrift login` first.\\n\"));\n process.exit(1);\n }\n\n const config = await readConfig();\n let data;\n try {\n data = await fetchUsage(resolved.token, { apiUrl: config.apiUrl });\n } catch (err) {\n if (err instanceof VibeDriftApiError && err.status === 401) {\n console.error(chalk.red(\"\\n ✗ Your token is invalid or expired. Run `vibedrift login` to re-authenticate.\\n\"));\n process.exit(1);\n }\n console.error(chalk.red(`\\n ✗ Could not fetch usage: ${err instanceof Error ? err.message : String(err)}\\n`));\n process.exit(1);\n }\n\n console.log(\"\");\n console.log(chalk.bold(\" Account\"));\n console.log(` Email: ${chalk.bold(data.user.email)}`);\n console.log(` Plan: ${chalk.bold(data.user.plan)}`);\n console.log(\"\");\n\n console.log(chalk.bold(\" Current period\"));\n console.log(` From: ${chalk.dim(formatDate(data.current_period.start))}`);\n console.log(` To: ${chalk.dim(formatDate(data.current_period.end))}`);\n console.log(` Scans: ${chalk.bold(data.current_period.scans.toString())}`);\n console.log(` Deep: ${chalk.bold(data.current_period.deep_scans.toString())}`);\n console.log(\"\");\n\n console.log(chalk.bold(\" Limits\"));\n const deepLimit = data.limits.deep_scans_per_month;\n console.log(` Deep: ${deepLimit === null ? chalk.green(\"unlimited\") : `${deepLimit}/month`}`);\n console.log(` Rate: ${data.limits.rate_limit_per_min} requests/minute`);\n console.log(\"\");\n\n if (data.recent_scans.length > 0) {\n console.log(chalk.bold(` Recent scans (${data.recent_scans.length})`));\n for (const scan of data.recent_scans.slice(0, 10)) {\n const flag = scan.is_deep ? chalk.cyan(\"deep\") : chalk.dim(\"std \");\n const score = scan.score === null ? chalk.dim(\"—\") : chalk.bold(String(Math.round(scan.score))).padEnd(3);\n console.log(` ${flag} ${score} ${chalk.dim(formatDateTime(scan.created_at))} ${chalk.dim(scan.project_hash.slice(0, 12))}`);\n }\n console.log(\"\");\n }\n}\n\nfunction formatDate(iso: string): string {\n try {\n return new Date(iso).toISOString().slice(0, 10);\n } catch { return iso; }\n}\n\nfunction formatDateTime(iso: string): string {\n try {\n const d = new Date(iso);\n return d.toISOString().slice(0, 16).replace(\"T\", \" \");\n } catch { return iso; }\n}\n","import chalk from \"chalk\";\nimport { openInBrowser } from \"../../auth/browser.js\";\n\n/**\n * `vibedrift upgrade` — open the pricing page in the browser.\n *\n * Distinct from `vibedrift --update` which upgrades the CLI binary.\n * \"upgrade\" is for the *plan*; \"update\" is for the *binary*.\n */\nconst PRICING_URL = \"https://vibedrift.ai/pricing\";\n\nexport async function runUpgrade(): Promise<void> {\n console.log(\"\");\n console.log(chalk.bold(\" Upgrade your VibeDrift plan\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(PRICING_URL)}`);\n console.log(\"\");\n\n const opened = openInBrowser(PRICING_URL);\n if (opened) {\n console.log(chalk.dim(\" Opened in your browser.\"));\n } else {\n console.log(chalk.dim(\" Open the link above in your browser.\"));\n }\n console.log(\"\");\n console.log(chalk.dim(\" After upgrading, run `vibedrift login` to refresh your plan locally.\"));\n console.log(\"\");\n}\n","import chalk from \"chalk\";\nimport { resolveToken } from \"../../auth/resolver.js\";\nimport { createPortalSession, VibeDriftApiError } from \"../../auth/api.js\";\nimport { readConfig } from \"../../auth/config.js\";\nimport { openInBrowser } from \"../../auth/browser.js\";\n\n/**\n * `vibedrift billing` — open the Stripe Customer Portal.\n *\n * The server creates a one-time portal session URL bound to the\n * authenticated user's stripe_customer_id and returns it. We open\n * the URL (or print it if no browser is available).\n */\nexport async function runBilling(): Promise<void> {\n const resolved = await resolveToken();\n if (!resolved) {\n console.error(chalk.red(\"\\n ✗ Not logged in. Run `vibedrift login` first.\\n\"));\n process.exit(1);\n }\n\n const config = await readConfig();\n\n let portal;\n try {\n portal = await createPortalSession(resolved.token, { apiUrl: config.apiUrl });\n } catch (err) {\n if (err instanceof VibeDriftApiError) {\n if (err.status === 401) {\n console.error(chalk.red(\"\\n ✗ Your token is invalid or expired. Run `vibedrift login`.\\n\"));\n process.exit(1);\n }\n if (err.status === 402 || err.status === 404) {\n console.error(chalk.yellow(\"\\n ⚠ No billing account found for this user.\"));\n console.error(chalk.dim(\" Run `vibedrift upgrade` to start a paid plan first.\\n\"));\n process.exit(1);\n }\n }\n console.error(chalk.red(`\\n ✗ Could not open billing portal: ${err instanceof Error ? err.message : String(err)}\\n`));\n process.exit(1);\n }\n\n console.log(\"\");\n console.log(chalk.bold(\" Stripe Customer Portal\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(portal.url)}`);\n console.log(\"\");\n\n const opened = openInBrowser(portal.url);\n if (opened) {\n console.log(chalk.dim(\" Opened in your browser. The link is single-use and expires shortly.\"));\n } else {\n console.log(chalk.dim(\" Open the link above in your browser. It's single-use and expires shortly.\"));\n }\n console.log(\"\");\n}\n","import chalk from \"chalk\";\nimport { homedir, platform, arch } from \"os\";\nimport { join } from \"path\";\nimport { stat, access, constants } from \"fs/promises\";\nimport { readConfig, getConfigPath, getConfigDir } from \"../../auth/config.js\";\nimport { resolveToken, resolveApiUrl, previewToken, describeSource } from \"../../auth/resolver.js\";\nimport { validateToken, VibeDriftApiError } from \"../../auth/api.js\";\nimport { getVersion } from \"../../core/version.js\";\n\n/**\n * `vibedrift doctor` — environment diagnostic, intended for bug reports.\n *\n * Reports on:\n * - CLI version, Node version, OS/arch\n * - Auth state (logged in? token source? validates with server?)\n * - Config dir + permissions\n * - API URL reachability\n * - PATH conflict (vibedrift binary location)\n *\n * Exits 0 if everything is healthy, 1 if any check failed.\n */\nasync function checkAuthStatus(): Promise<{\n resolved: Awaited<ReturnType<typeof resolveToken>>;\n authFailures: number;\n}> {\n let authFailures = 0;\n console.log(chalk.bold(\" Authentication\"));\n const config = await readConfig();\n const resolved = await resolveToken();\n\n if (!resolved) {\n info(\"Login state\", \"not logged in\");\n } else {\n ok(\"Token source\", describeSource(resolved.source));\n ok(\"Token preview\", previewToken(resolved.token));\n if (resolved.source === \"config\") {\n if (config.email) ok(\"Email\", config.email);\n if (config.plan) ok(\"Plan\", config.plan);\n if (config.expiresAt) {\n const expires = new Date(config.expiresAt).getTime();\n const now = Date.now();\n if (expires < now) {\n bad(`Token expired ${Math.floor((now - expires) / 86_400_000)} days ago`);\n authFailures++;\n } else {\n ok(\"Token expires\", `${config.expiresAt} (${Math.ceil((expires - now) / 86_400_000)} days)`);\n }\n }\n }\n }\n console.log(\"\");\n return { resolved, authFailures };\n}\n\nasync function checkApiConnectivity(\n resolved: Awaited<ReturnType<typeof resolveToken>>,\n): Promise<number> {\n let failures = 0;\n console.log(chalk.bold(\" API\"));\n const apiUrl = await resolveApiUrl();\n ok(\"API URL\", apiUrl);\n\n if (resolved) {\n process.stdout.write(` ${chalk.dim(\"→ Validating token... \")}`);\n try {\n const result = await validateToken(resolved.token, { apiUrl });\n if (result.valid) {\n console.log(chalk.green(\"ok\"));\n } else {\n console.log(chalk.red(\"invalid token\"));\n failures++;\n }\n } catch (err) {\n console.log(chalk.red(\"unreachable\"));\n console.log(` ${chalk.dim(\" \")}${err instanceof VibeDriftApiError ? err.message : String(err)}`);\n failures++;\n }\n } else {\n process.stdout.write(` ${chalk.dim(\"→ Pinging API... \")}`);\n try {\n const res = await fetch(`${apiUrl}/health`, { signal: AbortSignal.timeout(10_000) });\n if (res.ok) console.log(chalk.green(\"ok\"));\n else { console.log(chalk.yellow(`HTTP ${res.status}`)); failures++; }\n } catch (err) {\n console.log(chalk.red(\"unreachable\"));\n console.log(` ${chalk.dim(\" \")}${err instanceof Error ? err.message : String(err)}`);\n failures++;\n }\n }\n console.log(\"\");\n return failures;\n}\n\nexport async function runDoctor(): Promise<void> {\n let failures = 0;\n\n console.log(\"\");\n console.log(chalk.bold(\" VibeDrift Doctor\"));\n console.log(\"\");\n\n // ── Environment ──\n console.log(chalk.bold(\" Environment\"));\n ok(\"CLI version\", getVersion());\n ok(\"Node\", process.version);\n ok(\"Platform\", `${platform()} ${arch()}`);\n ok(\"HOME\", homedir());\n console.log(\"\");\n\n // ── Config dir ──\n console.log(chalk.bold(\" Config\"));\n const configDir = getConfigDir();\n const configPath = getConfigPath();\n\n let configDirOk = false;\n try {\n const info = await stat(configDir);\n if (info.isDirectory()) {\n configDirOk = true;\n // POSIX mode bits\n const mode = (info.mode & 0o777).toString(8);\n ok(\"Config dir\", `${configDir} (mode ${mode})`);\n } else {\n bad(`Config dir exists but is not a directory: ${configDir}`);\n failures++;\n }\n } catch {\n info(\"Config dir\", `${configDir} (will be created on first login)`);\n configDirOk = true;\n }\n\n if (configDirOk) {\n try {\n await access(configPath, constants.R_OK);\n const info = await stat(configPath);\n const mode = (info.mode & 0o777).toString(8);\n if ((info.mode & 0o077) !== 0) {\n warn(\"Config file\", `${configPath} (mode ${mode}, world/group readable — should be 600)`);\n } else {\n ok(\"Config file\", `${configPath} (mode ${mode})`);\n }\n } catch {\n info(\"Config file\", \"absent (not logged in)\");\n }\n }\n\n // History dir (separate from config — must be ~/.vibedrift/scans)\n const historyDir = join(homedir(), \".vibedrift\", \"scans\");\n try {\n const info = await stat(historyDir);\n if (info.isDirectory()) ok(\"Scan history\", historyDir);\n else warn(\"Scan history\", `${historyDir} exists but is not a directory`);\n } catch {\n info(\"Scan history\", \"empty (no scans run yet)\");\n }\n console.log(\"\");\n\n // ── Authentication ──\n const { resolved, authFailures } = await checkAuthStatus();\n failures += authFailures;\n\n // ── API ──\n const apiFailures = await checkApiConnectivity(resolved);\n failures += apiFailures;\n\n // ── Summary ──\n if (failures === 0) {\n console.log(chalk.green(\" ✓ All checks passed.\"));\n } else {\n console.log(chalk.red(` ✗ ${failures} check${failures === 1 ? \"\" : \"s\"} failed.`));\n }\n console.log(\"\");\n\n process.exit(failures === 0 ? 0 : 1);\n}\n\nfunction ok(label: string, value: string): void {\n console.log(` ${chalk.green(\"✓\")} ${label.padEnd(14)} ${chalk.dim(value)}`);\n}\nfunction warn(label: string, value: string): void {\n console.log(` ${chalk.yellow(\"⚠\")} ${label.padEnd(14)} ${chalk.dim(value)}`);\n}\nfunction bad(value: string): void {\n console.log(` ${chalk.red(\"✗\")} ${chalk.red(value)}`);\n}\nfunction info(label: string, value: string): void {\n console.log(` ${chalk.dim(\"·\")} ${label.padEnd(14)} ${chalk.dim(value)}`);\n}\n\n// describeSource imported from auth/resolver.ts (shared with status.ts)\n","import os from \"os\";\nimport readline from \"readline\";\nimport chalk from \"chalk\";\nimport { resolveToken, resolveApiUrl } from \"../../auth/resolver.js\";\nimport { sendFeedback, VibeDriftApiError } from \"../../auth/api.js\";\nimport { getVersion } from \"../../core/version.js\";\n\nexport interface FeedbackOptions {\n message?: string;\n apiUrl?: string;\n}\n\nconst MAX_MESSAGE_BYTES = 4096;\n\n/**\n * `vibedrift feedback` — send free-form feedback directly from the CLI.\n *\n * Two modes:\n * 1. Inline: `vibedrift feedback \"the install hint is too verbose\"`\n * 2. Interactive: `vibedrift feedback` (prompts on stdin until EOF)\n *\n * Auth is optional. We *try* to attach the user's token so triage can\n * follow up directly, but anonymous feedback works too — the API\n * accepts unauthenticated submissions for exactly this case.\n *\n * Always attaches CLI version, Node version, and OS as metadata so we\n * can correlate complaints with environments without asking the user.\n */\nexport async function runFeedback(opts: FeedbackOptions = {}): Promise<void> {\n console.log(\"\");\n console.log(chalk.bold(\" VibeDrift feedback\"));\n console.log(\n chalk.dim(\" Tell us what's broken, what's confusing, or what you wish existed.\"),\n );\n console.log(\n chalk.dim(\" Goes straight to the maintainer — anonymous unless you're logged in.\"),\n );\n console.log(\"\");\n\n // ── Collect the message ──\n let message = (opts.message ?? \"\").trim();\n if (!message) {\n message = await promptForMultilineMessage();\n }\n\n if (!message) {\n console.error(chalk.red(\" ✗ No feedback provided. Aborting.\"));\n process.exit(1);\n }\n\n if (Buffer.byteLength(message, \"utf8\") > MAX_MESSAGE_BYTES) {\n console.error(\n chalk.red(\n ` ✗ Message too long (max ${MAX_MESSAGE_BYTES} bytes). ` +\n `Please trim it or open an issue on GitHub for longer reports.`,\n ),\n );\n process.exit(1);\n }\n\n // ── Try (best-effort) to attach the user's token ──\n let token: string | null = null;\n try {\n const resolved = await resolveToken();\n if (resolved) token = resolved.token;\n } catch {\n // Anonymous fallback is fine\n }\n\n // ── Build metadata: CLI version + Node + OS ──\n const metadata: Record<string, unknown> = {\n cli_version: getVersion(),\n node_version: process.version,\n platform: process.platform,\n arch: process.arch,\n os_release: os.release(),\n locale: process.env.LANG ?? null,\n tty: process.stdin.isTTY === true,\n };\n\n // ── Send it ──\n process.stdout.write(chalk.dim(\" Sending... \"));\n try {\n const result = await sendFeedback({\n source: \"cli\",\n message,\n token: token ?? undefined,\n metadata,\n apiUrl: await resolveApiUrl(opts.apiUrl),\n });\n console.log(chalk.green(\"ok\"));\n console.log(\"\");\n console.log(` ${chalk.dim(\"Reference:\")} ${chalk.dim(result.id)}`);\n if (token) {\n console.log(\n chalk.dim(\n \" Submitted under your account — we'll reply to your email if needed.\",\n ),\n );\n } else {\n console.log(\n chalk.dim(\n \" Submitted anonymously. If you'd like a reply, run `vibedrift login` first.\",\n ),\n );\n }\n console.log(\"\");\n console.log(chalk.green(\" ✓ Thanks for helping us improve VibeDrift.\"));\n console.log(\"\");\n } catch (err) {\n console.log(chalk.red(\"failed\"));\n console.log(\"\");\n if (err instanceof VibeDriftApiError) {\n console.error(chalk.red(` ✗ ${err.message}`));\n } else {\n console.error(\n chalk.red(` ✗ ${err instanceof Error ? err.message : String(err)}`),\n );\n }\n console.error(\n chalk.dim(\n \" You can also email sami.ahmadkhan12@gmail.com directly.\",\n ),\n );\n console.log(\"\");\n process.exit(1);\n }\n}\n\n/**\n * Multi-line prompt: read until the user submits a line containing only\n * `EOF` or hits Ctrl-D. Falls back to single-line `readline.question` if\n * stdin isn't a TTY (so a piped `echo \"...\"` still works).\n */\nfunction promptForMultilineMessage(): Promise<string> {\n return new Promise((resolve) => {\n if (!process.stdin.isTTY) {\n // Piped input — read everything until EOF\n let buf = \"\";\n process.stdin.setEncoding(\"utf8\");\n process.stdin.on(\"data\", (chunk) => {\n buf += chunk;\n });\n process.stdin.on(\"end\", () => resolve(buf.trim()));\n return;\n }\n\n console.log(\n chalk.dim(\n \" Type your feedback below. Submit with a single line containing 'EOF',\",\n ),\n );\n console.log(chalk.dim(\" or press Ctrl-D when done. Press Ctrl-C to abort.\"));\n console.log(\"\");\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: chalk.yellow(\" > \"),\n });\n\n const lines: string[] = [];\n rl.prompt();\n rl.on(\"line\", (line) => {\n if (line.trim() === \"EOF\") {\n rl.close();\n return;\n }\n lines.push(line);\n rl.prompt();\n });\n rl.on(\"close\", () => {\n console.log(\"\");\n resolve(lines.join(\"\\n\").trim());\n });\n rl.on(\"SIGINT\", () => {\n console.log(chalk.red(\"\\n ✗ Aborted.\"));\n process.exit(1);\n });\n });\n}\n"],"mappings":"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","names":["extractBody","fileURLToPath","join","path","createHash","escapeRegex","path","path","join","readFile","createHash","path","extractAllFunctions","detectProjectIdentity","TIMEOUT_MS","DEFAULT_API_URL","TIMEOUT_MS","path","path","writeFile","stat","chalk","readFile","join","join","info","readFile","cached","lcsLength","path","basename","path","extractFunctions","isEntryPoint","path","data","readdir","readFile","join","path","escapeRegex","homedir","join","readFile","writeFile","mkdir","stat","chalk","runCodeDnaAnalysis","runMlAnalysis","deduplicateFindingsAcrossLayers","fetchAiSummary","logScan","detectProjectIdentity","sanitizeResultForUpload","writeFile","renderCsvReport","renderDocxReport","info","stat","chalk","resolve","chalk","spawn","chalk","resolve","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","homedir","join","stat","chalk","homedir","info","stat","join","chalk","chalk","resolve","path"]}
|