codemap-ai 3.2.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -1
- package/dist/{chunk-VB74K47A.js → chunk-BRVRY5KT.js} +62 -1
- package/dist/chunk-BRVRY5KT.js.map +1 -0
- package/dist/{chunk-LXZ73T7X.js → chunk-EEMILSZ4.js} +58 -3
- package/dist/chunk-EEMILSZ4.js.map +1 -0
- package/dist/cli.js +1828 -44
- package/dist/cli.js.map +1 -1
- package/dist/{flow-server-UQEOUP2C.js → flow-server-FMPWJSLK.js} +3 -3
- package/dist/{flow-server-UQEOUP2C.js.map → flow-server-FMPWJSLK.js.map} +1 -1
- package/dist/index.js +1052 -21
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +2 -2
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-LXZ73T7X.js.map +0 -1
- package/dist/chunk-VB74K47A.js.map +0 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli-flow.ts","../src/flow/builder.ts","../src/parsers/base.ts","../src/parsers/typescript.ts","../src/parsers/python.ts","../src/parsers/index.ts","../src/types.ts","../src/commands/impact.ts","../src/utils/git.ts","../src/analysis/imports.ts","../src/analysis/docker.ts"],"sourcesContent":["/**\n * CodeMap Flow Edition - Simplified CLI\n * Only 2 commands: index and mcp-server\n */\n\nimport { Command } from \"commander\";\nimport { resolve, join } from \"path\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { FlowBuilder, FlowStorage } from \"./flow/index.js\";\nimport { DEFAULT_CONFIG } from \"./types.js\";\nimport { analyzeImpact } from \"./commands/impact.js\";\nimport { isGitRepository, getGitStatus } from \"./utils/git.js\";\n\n// Import parsers to register them\nimport \"./parsers/index.js\";\n\nconst program = new Command();\n\n/**\n * Configure MCP server in Claude Code config\n */\nfunction configureMCPServer(projectPath: string): boolean {\n try {\n const claudeConfigPath = join(homedir(), \".claude\", \"config.json\");\n\n if (!existsSync(claudeConfigPath)) {\n return false;\n }\n\n const config = JSON.parse(readFileSync(claudeConfigPath, \"utf-8\"));\n\n if (!config.mcpServers) {\n config.mcpServers = {};\n }\n\n // Add or update codemap server\n config.mcpServers.codemap = {\n command: \"npx\",\n args: [\"codemap-ai\", \"mcp-server\", \"--path\", projectPath],\n };\n\n writeFileSync(claudeConfigPath, JSON.stringify(config, null, 2));\n return true;\n } catch (error) {\n return false;\n }\n}\n\nprogram\n .name(\"codemap\")\n .description(\"CodeMap Flow - Call graph analyzer for understanding code impact\")\n .version(\"3.2.0\");\n\n// ============ Index Command ============\n\nprogram\n .command(\"index\")\n .description(\"Build call graph for your codebase\")\n .argument(\"[path]\", \"Path to the project root\", \".\")\n .option(\"-f, --force\", \"Force reindex all files (ignore cache)\")\n .option(\"--include <patterns...>\", \"Glob patterns to include\")\n .option(\"--exclude <patterns...>\", \"Glob patterns to exclude\")\n .action(async (path: string, options) => {\n const rootPath = resolve(path);\n const outputDir = join(rootPath, \".codemap\");\n\n console.log(chalk.blue.bold(\"\\n CodeMap Call Graph Indexer\\n\"));\n console.log(chalk.gray(` Project: ${rootPath}\\n`));\n\n // Create output directory\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n const dbPath = join(outputDir, \"graph.db\");\n const storage = new FlowStorage(dbPath);\n\n const builder = new FlowBuilder(storage, {\n rootPath,\n include: options.include || DEFAULT_CONFIG.include!,\n exclude: options.exclude || DEFAULT_CONFIG.exclude!,\n forceReindex: options.force || false,\n });\n\n const spinner = ora(\"Discovering files...\").start();\n\n builder.setProgressCallback((progress) => {\n switch (progress.phase) {\n case \"discovering\":\n spinner.text = \"Discovering files...\";\n break;\n case \"parsing\":\n spinner.text = `Parsing (${progress.current}/${progress.total}): ${progress.currentFile}`;\n break;\n case \"resolving\":\n spinner.text = \"Resolving cross-file calls...\";\n break;\n case \"complete\":\n spinner.succeed(chalk.green(\"Indexing complete!\"));\n break;\n }\n });\n\n try {\n const result = await builder.build();\n\n console.log(chalk.blue(\"\\n Results:\\n\"));\n console.log(` ${chalk.bold(\"Indexed:\")} ${result.indexed} files`);\n console.log(` ${chalk.bold(\"Skipped:\")} ${result.skipped} files (unchanged)`);\n console.log(` ${chalk.bold(\"Resolved:\")} ${result.resolved} function calls`);\n console.log(` ${chalk.bold(\"Unresolved:\")} ${result.unresolved} calls (external/dynamic)`);\n\n // Show enhanced stats\n const stats = storage.getStats();\n if (stats.httpEndpoints > 0) {\n console.log(chalk.cyan(`\\n ${chalk.bold(\"Framework Detection:\")}`));\n console.log(` ${chalk.bold(\"HTTP Endpoints:\")} ${stats.httpEndpoints} routes detected`);\n console.log(` ${chalk.bold(\"Dependencies:\")} ${stats.resolvedDependencies}/${stats.frameworkDependencies} resolved (FastAPI Depends)`);\n }\n\n if (result.errors.length > 0) {\n console.log(chalk.yellow(`\\n Errors: ${result.errors.length} files failed`));\n for (const err of result.errors.slice(0, 5)) {\n console.log(chalk.gray(` - ${err}`));\n }\n if (result.errors.length > 5) {\n console.log(chalk.gray(` ... and ${result.errors.length - 5} more`));\n }\n }\n\n const resolveRate = result.resolved + result.unresolved > 0\n ? Math.round((result.resolved / (result.resolved + result.unresolved)) * 100)\n : 0;\n const dependencyRate = stats.frameworkDependencies > 0\n ? Math.round((stats.resolvedDependencies / stats.frameworkDependencies) * 100)\n : 0;\n\n console.log(chalk.gray(`\\n Call resolution rate: ${resolveRate}%`));\n if (stats.frameworkDependencies > 0) {\n console.log(chalk.gray(` Dependency resolution rate: ${dependencyRate}%`));\n }\n console.log(chalk.gray(` Database saved to: ${dbPath}\\n`));\n\n console.log(chalk.cyan(\" Next steps:\"));\n console.log(chalk.gray(\" • Configure MCP server: claude mcp add codemap -- npx codemap-ai mcp-server\"));\n console.log(chalk.gray(\" • Ask Claude: 'What would break if I change authenticate_user?'\\n\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Indexing failed\"));\n console.error(error);\n process.exit(1);\n } finally {\n storage.close();\n }\n });\n\n// ============ Init Command ============\n\nprogram\n .command(\"init\")\n .description(\"Initialize CodeMap (index + setup MCP)\")\n .argument(\"[path]\", \"Path to the project root\", \".\")\n .option(\"--include <patterns...>\", \"Glob patterns to include\")\n .option(\"--exclude <patterns...>\", \"Glob patterns to exclude\")\n .option(\"--skip-mcp\", \"Skip MCP server configuration\")\n .action(async (path: string, options) => {\n const rootPath = resolve(path);\n const outputDir = join(rootPath, \".codemap\");\n\n console.log(chalk.blue.bold(\"\\n CodeMap Initialization\\n\"));\n console.log(chalk.gray(` Project: ${rootPath}\\n`));\n\n // Check if already initialized\n if (existsSync(join(outputDir, \"graph.db\")) && !options.force) {\n console.log(chalk.yellow(\" Already initialized. Use 'codemap reindex' to rebuild.\\n\"));\n return;\n }\n\n // Create output directory\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n const dbPath = join(outputDir, \"graph.db\");\n const storage = new FlowStorage(dbPath);\n\n const builder = new FlowBuilder(storage, {\n rootPath,\n include: options.include || DEFAULT_CONFIG.include!,\n exclude: options.exclude || DEFAULT_CONFIG.exclude!,\n forceReindex: true,\n });\n\n const spinner = ora(\"Indexing codebase...\").start();\n\n builder.setProgressCallback((progress) => {\n switch (progress.phase) {\n case \"discovering\":\n spinner.text = \"Discovering files...\";\n break;\n case \"parsing\":\n spinner.text = `Parsing (${progress.current}/${progress.total}): ${progress.currentFile}`;\n break;\n case \"resolving\":\n spinner.text = \"Resolving cross-file calls...\";\n break;\n case \"complete\":\n spinner.succeed(chalk.green(\"Indexing complete!\"));\n break;\n }\n });\n\n try {\n const result = await builder.build();\n\n console.log(chalk.blue(\"\\n Results:\\n\"));\n console.log(` ${chalk.bold(\"Indexed:\")} ${result.indexed} files`);\n console.log(` ${chalk.bold(\"Resolved:\")} ${result.resolved} function calls`);\n\n const stats = storage.getStats();\n if (stats.httpEndpoints > 0) {\n console.log(chalk.cyan(`\\n ${chalk.bold(\"Framework Detection:\")}`));\n console.log(` ${chalk.bold(\"HTTP Endpoints:\")} ${stats.httpEndpoints} routes`);\n }\n\n const resolveRate = result.resolved + result.unresolved > 0\n ? Math.round((result.resolved / (result.resolved + result.unresolved)) * 100)\n : 0;\n\n console.log(chalk.gray(`\\n Call resolution: ${resolveRate}%`));\n console.log(chalk.gray(` Database: ${dbPath}\\n`));\n\n // Configure MCP server\n if (!options.skipMcp) {\n const mcpConfigured = configureMCPServer(rootPath);\n if (mcpConfigured) {\n console.log(chalk.green(\" ✓ MCP server configured in Claude Code\\n\"));\n } else {\n console.log(chalk.yellow(\" ⚠ Could not auto-configure MCP (Claude Code not found)\"));\n console.log(chalk.gray(\" Run manually: claude mcp add codemap -- npx codemap-ai mcp-server\\n\"));\n }\n }\n\n console.log(chalk.cyan(\" Ready!\"));\n console.log(chalk.gray(\" Ask Claude: 'What would break if I change authenticate_user?'\\n\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Initialization failed\"));\n console.error(error);\n process.exit(1);\n } finally {\n storage.close();\n }\n });\n\n// ============ Impact Command ============\n\nprogram\n .command(\"impact\")\n .description(\"Analyze impact of code changes\")\n .argument(\"[path]\", \"Path to the project root\", \".\")\n .option(\"-v, --verbose\", \"Show detailed output\")\n .action(async (path: string, options) => {\n const rootPath = resolve(path);\n const dbPath = join(rootPath, \".codemap\", \"graph.db\");\n\n console.log(chalk.blue.bold(\"\\n CodeMap Impact Analysis\\n\"));\n\n if (!existsSync(dbPath)) {\n console.log(chalk.red(\" Error: Not initialized. Run 'codemap init' first.\\n\"));\n process.exit(1);\n }\n\n // Check for changes\n const spinner = ora(\"Detecting changes...\").start();\n\n try {\n const result = await analyzeImpact({ path: rootPath, verbose: options.verbose });\n\n if (result.changedFiles.length === 0) {\n spinner.succeed(chalk.green(\"No changes detected\"));\n console.log(chalk.gray(\" All files are up to date.\\n\"));\n return;\n }\n\n spinner.succeed(chalk.green(`Detected ${result.changedFiles.length} modified files`));\n\n // Show changed files\n console.log(chalk.blue(\"\\n Modified Files:\\n\"));\n for (const file of result.changedFiles.slice(0, 10)) {\n console.log(chalk.gray(` • ${file}`));\n }\n if (result.changedFiles.length > 10) {\n console.log(chalk.gray(` ... and ${result.changedFiles.length - 10} more`));\n }\n\n // Show changed functions (if available from git)\n if (result.changedFunctions.length > 0) {\n console.log(chalk.blue(\"\\n Changed Functions:\\n\"));\n for (const func of result.changedFunctions) {\n console.log(chalk.gray(` • ${func.functionName} (${func.file}:${func.lineNumber})`));\n }\n }\n\n // Show impact\n if (result.directCallers.size > 0) {\n console.log(chalk.blue(\"\\n Impact Analysis:\\n\"));\n for (const [funcName, callers] of result.directCallers.entries()) {\n console.log(chalk.yellow(` ${funcName}:`));\n console.log(chalk.gray(` ${callers.length} direct callers`));\n if (options.verbose) {\n for (const caller of callers.slice(0, 5)) {\n console.log(chalk.gray(` • ${caller.name} (${caller.file}:${caller.line})`));\n }\n if (callers.length > 5) {\n console.log(chalk.gray(` ... and ${callers.length - 5} more`));\n }\n }\n }\n }\n\n // Show affected endpoints\n if (result.affectedEndpoints.length > 0) {\n console.log(chalk.blue(\"\\n Affected HTTP Endpoints:\\n\"));\n for (const endpoint of result.affectedEndpoints) {\n console.log(chalk.gray(` • ${endpoint}`));\n }\n }\n\n // NEW: Show import issues\n if (result.importIssues.size > 0) {\n console.log(chalk.blue(\"\\n 🔍 Import Analysis:\\n\"));\n for (const [file, issues] of result.importIssues.entries()) {\n if (issues.missing.length > 0) {\n console.log(chalk.red(` ❌ CRITICAL: ${file} - Missing imports still in use:`));\n for (const missing of issues.missing.slice(0, 5)) {\n const usageInfo = missing.usedAt ? ` (used at lines: ${missing.usedAt.slice(0, 3).join(\", \")}${missing.usedAt.length > 3 ? \"...\" : \"\"})` : \"\";\n console.log(chalk.gray(` • ${missing.identifier}${usageInfo}`));\n }\n if (issues.missing.length > 5) {\n console.log(chalk.gray(` ... and ${issues.missing.length - 5} more`));\n }\n }\n if (issues.unused.length > 0 && options.verbose) {\n console.log(chalk.yellow(` ⚠️ ${file} - Unused imports:`));\n for (const unused of issues.unused.slice(0, 3)) {\n console.log(chalk.gray(` • ${unused.identifier} (line ${unused.line})`));\n }\n }\n }\n }\n\n // NEW: Show Docker impact\n if (result.dockerImpact) {\n console.log(chalk.blue(\"\\n 📦 Docker Service Impact:\\n\"));\n console.log(chalk.red(` ⚠️ Entry point file(s) modified - service(s) will not start:`));\n for (const file of result.dockerImpact.entryPointFiles) {\n console.log(chalk.gray(` • ${file}`));\n }\n console.log(chalk.red(`\\n 💥 Affected Services (${result.dockerImpact.affectedServices.length}):`));\n for (const service of result.dockerImpact.affectedServices) {\n console.log(chalk.gray(` • ${service}`));\n }\n console.log(chalk.yellow(`\\n → If entry point crashes, these services WILL FAIL`));\n }\n\n // Show risk level\n console.log(chalk.blue(\"\\n Risk Assessment:\\n\"));\n const riskColor = result.riskLevel === \"CRITICAL\"\n ? chalk.red.bold\n : result.riskLevel === \"HIGH\"\n ? chalk.red\n : result.riskLevel === \"MEDIUM\"\n ? chalk.yellow\n : chalk.green;\n console.log(` ${riskColor(result.riskLevel)} - ${result.totalImpact} components affected`);\n\n if (result.riskLevel === \"CRITICAL\") {\n console.log(chalk.red.bold(\"\\n ⚠️ DO NOT DEPLOY - System-wide failure risk\"));\n console.log(chalk.gray(\" Fix critical issues before proceeding\"));\n } else if (result.riskLevel === \"HIGH\") {\n console.log(chalk.yellow(\"\\n ⚠️ High risk - Extensive testing required\"));\n }\n\n console.log();\n } catch (error) {\n spinner.fail(chalk.red(\"Impact analysis failed\"));\n console.error(error);\n process.exit(1);\n }\n });\n\n// ============ Reindex Command ============\n\nprogram\n .command(\"reindex\")\n .description(\"Force full re-index of codebase\")\n .argument(\"[path]\", \"Path to the project root\", \".\")\n .option(\"--include <patterns...>\", \"Glob patterns to include\")\n .option(\"--exclude <patterns...>\", \"Glob patterns to exclude\")\n .action(async (path: string, options) => {\n // Just call index with force flag\n const indexCommand = program.commands.find((cmd) => cmd.name() === \"index\");\n if (indexCommand) {\n await indexCommand.parseAsync([path, \"--force\", ...(options.include ? [\"--include\", ...options.include] : []), ...(options.exclude ? [\"--exclude\", ...options.exclude] : [])], { from: \"user\" });\n }\n });\n\n// ============ MCP Server Command ============\n\nprogram\n .command(\"mcp-server\")\n .description(\"Start MCP server for Claude Code integration\")\n .option(\"-p, --path <path>\", \"Project root path\", \".\")\n .action(async (options) => {\n process.env.CODEMAP_PROJECT_ROOT = resolve(options.path);\n process.env.CODEMAP_DB_PATH = join(resolve(options.path), \".codemap\", \"graph.db\");\n\n // Start the flow MCP server\n await import(\"./mcp/flow-server.js\");\n });\n\n// Parse and run\nprogram.parse();\n","/**\n * Flow Builder - Builds call graphs with resolved references\n * Core implementation for CodeMap Flow Edition\n */\n\nimport { readFileSync, statSync } from \"fs\";\nimport { createHash } from \"crypto\";\nimport { glob } from \"glob\";\nimport { resolve, relative, dirname, basename, extname } from \"path\";\nimport { FlowStorage } from \"./storage.js\";\nimport { parserRegistry } from \"../parsers/index.js\";\nimport type { FileAnalysis, GraphNode, GraphEdge } from \"../types.js\";\n\nexport interface FlowConfig {\n rootPath: string;\n include: string[];\n exclude: string[];\n forceReindex: boolean;\n}\n\nexport interface FlowProgress {\n phase: \"discovering\" | \"parsing\" | \"resolving\" | \"complete\";\n total: number;\n current: number;\n currentFile: string;\n}\n\nexport type ProgressCallback = (progress: FlowProgress) => void;\n\ninterface ModuleExports {\n [symbolName: string]: string; // symbol name → node ID\n}\n\nexport class FlowBuilder {\n private storage: FlowStorage;\n private config: FlowConfig;\n private onProgress?: ProgressCallback;\n private moduleMap = new Map<string, ModuleExports>(); // file path → exports\n private errors: string[] = [];\n\n constructor(storage: FlowStorage, config: FlowConfig) {\n this.storage = storage;\n this.config = config;\n }\n\n setProgressCallback(callback: ProgressCallback): void {\n this.onProgress = callback;\n }\n\n async build(): Promise<{\n indexed: number;\n skipped: number;\n resolved: number;\n unresolved: number;\n errors: string[];\n }> {\n const rootPath = resolve(this.config.rootPath);\n\n // Phase 1: Discover files\n this.emitProgress({\n phase: \"discovering\",\n total: 0,\n current: 0,\n currentFile: \"\",\n });\n\n const allFiles = await this.discoverFiles(rootPath);\n const filesToIndex: Array<{ path: string; hash: string }> = [];\n let skipped = 0;\n\n // Check which files need indexing\n for (const filePath of allFiles) {\n const content = readFileSync(filePath, \"utf-8\");\n const hash = this.hashContent(content);\n\n if (!this.config.forceReindex) {\n const existingHash = this.storage.getFileHash(filePath);\n if (existingHash === hash) {\n skipped++;\n continue;\n }\n }\n\n filesToIndex.push({ path: filePath, hash });\n }\n\n // Phase 2: Parse files and extract symbols\n let indexed = 0;\n for (const file of filesToIndex) {\n this.emitProgress({\n phase: \"parsing\",\n total: filesToIndex.length,\n current: indexed + 1,\n currentFile: relative(rootPath, file.path),\n });\n\n try {\n await this.parseAndStore(file.path, file.hash, rootPath);\n indexed++;\n } catch (error) {\n this.errors.push(`${relative(rootPath, file.path)}: ${error}`);\n }\n }\n\n // Phase 3: Resolve cross-file calls\n this.emitProgress({\n phase: \"resolving\",\n total: filesToIndex.length,\n current: filesToIndex.length,\n currentFile: \"\",\n });\n\n this.resolveAllCalls();\n\n const stats = this.storage.getStats();\n\n this.emitProgress({\n phase: \"complete\",\n total: filesToIndex.length,\n current: filesToIndex.length,\n currentFile: \"\",\n });\n\n return {\n indexed,\n skipped,\n resolved: stats.resolvedCalls,\n unresolved: stats.unresolvedCalls,\n errors: this.errors,\n };\n }\n\n private async discoverFiles(rootPath: string): Promise<string[]> {\n const allFiles: string[] = [];\n\n for (const pattern of this.config.include) {\n const matches = await glob(pattern, {\n cwd: rootPath,\n absolute: true,\n ignore: this.config.exclude,\n nodir: true,\n });\n allFiles.push(...matches);\n }\n\n // Filter by supported extensions and size\n const supportedExts = new Set([\".py\", \".ts\", \".tsx\", \".js\", \".jsx\"]);\n const uniqueFiles = [...new Set(allFiles)].filter((f) => {\n const ext = extname(f);\n if (!supportedExts.has(ext)) return false;\n\n try {\n const stats = statSync(f);\n if (stats.size > 200000) return false; // Skip files > 200KB\n } catch {\n return false;\n }\n return true;\n });\n\n return uniqueFiles.sort();\n }\n\n private hashContent(content: string): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n }\n\n private async parseAndStore(filePath: string, hash: string, rootPath: string): Promise<void> {\n const language = this.getLanguage(filePath);\n const content = readFileSync(filePath, \"utf-8\");\n\n // Get parser for this language\n const parser = parserRegistry.getByLanguage(language);\n if (!parser) {\n throw new Error(`No parser found for language: ${language}`);\n }\n\n // Parse with tree-sitter\n const analysis = parser.parse(filePath, content);\n\n // Delete old data for this file\n this.storage.deleteFileData(filePath);\n\n // Store nodes with hashes\n const fileExports: ModuleExports = {};\n\n for (const node of analysis.nodes) {\n // Add hash to node\n const nodeHash = this.hashContent(`${node.name}:${node.startLine}:${node.endLine}`);\n const nodeWithHash = { ...node, hash: nodeHash };\n\n this.storage.insertNode(nodeWithHash);\n\n // Track exports (top-level functions and classes)\n if (node.type === \"function\" || node.type === \"class\") {\n fileExports[node.name] = node.id;\n this.storage.registerExport(filePath, node.name, node.id);\n }\n }\n\n // Store exports in module map\n this.moduleMap.set(filePath, fileExports);\n\n // Store edges (including unresolved refs)\n for (const edge of analysis.edges) {\n this.storage.insertEdge(edge);\n }\n\n // Store imports\n for (const imp of analysis.imports) {\n for (const spec of imp.specifiers) {\n this.storage.registerImport(filePath, spec, imp.source, imp.line);\n }\n }\n\n // Store variable types\n if (analysis.variableTypes) {\n for (const varType of analysis.variableTypes) {\n this.storage.registerVariableType(\n varType.variableName,\n varType.typeName,\n varType.scopeId,\n filePath,\n varType.line\n );\n }\n }\n\n // Store database operations\n if (analysis.databaseOperations) {\n for (const dbOp of analysis.databaseOperations) {\n this.storage.insertDatabaseOperation({\n id: `${dbOp.nodeId}:db:${dbOp.line}`,\n node_id: dbOp.nodeId,\n database_type: dbOp.databaseType,\n operation: dbOp.operation,\n collection: dbOp.collection,\n line: dbOp.line,\n });\n }\n }\n\n // Store file record\n this.storage.upsertFile(filePath, language, hash);\n\n // Process framework-specific patterns\n this.processFrameworkPatterns(analysis.nodes, filePath);\n }\n\n /**\n * Process framework-specific patterns (FastAPI routes, Depends, etc.)\n */\n private processFrameworkPatterns(nodes: GraphNode[], filePath: string): void {\n for (const node of nodes) {\n if (node.type === \"function\" && node.metadata) {\n // 1. Process FastAPI HTTP endpoints\n const httpEndpoint = node.metadata.httpEndpoint as { method: string; path: string } | undefined;\n if (httpEndpoint) {\n const endpointId = `${httpEndpoint.method}:${httpEndpoint.path}`;\n this.storage.insertHttpEndpoint({\n id: endpointId,\n method: httpEndpoint.method,\n path: httpEndpoint.path,\n handler_node_id: node.id,\n container_id: undefined, // Will be set when docker-compose is parsed\n metadata: {\n filePath,\n functionName: node.name,\n line: node.startLine,\n },\n });\n }\n\n // 2. Process FastAPI Depends() patterns\n const depends = node.metadata.depends as Array<{\n parameterName: string;\n dependencyName: string;\n line: number;\n }> | undefined;\n\n if (depends) {\n for (const dep of depends) {\n const depId = `${node.id}:depends:${dep.parameterName}`;\n this.storage.insertFrameworkDependency({\n id: depId,\n source_node_id: node.id,\n target_node_id: undefined, // Will be resolved later\n framework: \"fastapi\",\n pattern: \"depends\",\n parameter_name: dep.parameterName,\n line: dep.line,\n unresolved_name: dep.dependencyName,\n metadata: {\n filePath,\n functionName: node.name,\n },\n });\n }\n }\n }\n }\n }\n\n private resolveAllCalls(): void {\n // Get all unresolved edges (target_id starts with \"ref:\")\n const unresolvedEdges = this.storage.db\n .prepare(`SELECT * FROM edges WHERE target_id LIKE 'ref:%'`)\n .all() as Array<{\n id: string;\n source_id: string;\n target_id: string;\n type: string;\n metadata: string | null;\n }>;\n\n for (const edge of unresolvedEdges) {\n const refName = edge.target_id.replace(\"ref:\", \"\");\n const sourceNode = this.storage.getNode(edge.source_id);\n\n if (!sourceNode) continue;\n\n // Try to resolve the reference (pass source node ID for scope resolution)\n const resolvedId = this.resolveReference(sourceNode.filePath, refName, edge.source_id);\n\n if (resolvedId) {\n // Update edge with resolved target\n this.storage.insertEdge({\n id: edge.id,\n type: edge.type as GraphEdge[\"type\"],\n sourceId: edge.source_id,\n targetId: resolvedId,\n metadata: edge.metadata ? JSON.parse(edge.metadata) : undefined,\n });\n }\n }\n\n // Also resolve framework dependencies (FastAPI Depends)\n this.resolveFrameworkDependencies();\n }\n\n /**\n * Resolve framework dependencies (e.g., FastAPI Depends())\n */\n private resolveFrameworkDependencies(): void {\n const unresolvedDeps = this.storage.getAllUnresolvedDependencies();\n\n for (const dep of unresolvedDeps) {\n const sourceNode = this.storage.getNode(dep.source_node_id);\n if (!sourceNode) continue;\n\n // Try to resolve the dependency name to an actual node\n const resolvedId = this.resolveReference(sourceNode.filePath, dep.unresolved_name);\n\n if (resolvedId) {\n // Update the dependency with resolved target\n this.storage.updateFrameworkDependencyTarget(dep.id, resolvedId);\n\n // Also create an edge for the call graph\n this.storage.insertEdge({\n id: `${dep.id}:edge`,\n type: \"calls\",\n sourceId: dep.source_node_id,\n targetId: resolvedId,\n metadata: {\n framework: \"fastapi\",\n pattern: \"depends\",\n line: dep.line,\n },\n });\n }\n }\n }\n\n private resolveReference(sourceFilePath: string, refName: string, scopeNodeId?: string): string | null {\n // Strategy 0a: Handle super() calls\n if (refName.startsWith(\"super().\") && scopeNodeId) {\n const methodName = refName.replace(\"super().\", \"\");\n const resolvedSuper = this.storage.resolveSuperMethod(methodName, scopeNodeId);\n if (resolvedSuper) {\n return resolvedSuper;\n }\n }\n\n // Strategy 0b: Handle attribute calls (variable.method or ClassName.method)\n if (refName.includes(\".\")) {\n const parts = refName.split(\".\");\n if (parts.length === 2) {\n const [objectName, methodName] = parts;\n\n // Try variable.method resolution first (if we have scope)\n if (scopeNodeId) {\n const resolvedVarMethod = this.storage.resolveVariableMethod(objectName, methodName, scopeNodeId);\n if (resolvedVarMethod) {\n return resolvedVarMethod;\n }\n }\n\n // Fall back to ClassName.method resolution\n const resolvedClassMethod = this.storage.resolveClassMethod(objectName, methodName, sourceFilePath);\n if (resolvedClassMethod) {\n return resolvedClassMethod;\n }\n }\n }\n\n // Strategy 1: Look in the same file\n const nodesInFile = this.storage.getNodesByFile(sourceFilePath);\n for (const node of nodesInFile) {\n if (node.name === refName) {\n return node.id;\n }\n }\n\n // Strategy 2: Check imports\n const resolvedFromImport = this.storage.resolveImport(sourceFilePath, refName);\n if (resolvedFromImport) {\n return resolvedFromImport;\n }\n\n // Strategy 3: Search all nodes (fallback)\n const matches = this.storage.searchNodesByName(refName);\n if (matches.length === 1) {\n return matches[0].id;\n }\n\n return null;\n }\n\n private getLanguage(filePath: string): string {\n const ext = extname(filePath);\n if (ext === \".py\") return \"python\";\n if (ext === \".ts\" || ext === \".tsx\") return \"typescript\";\n if (ext === \".js\" || ext === \".jsx\") return \"javascript\";\n return \"unknown\";\n }\n\n private emitProgress(progress: FlowProgress): void {\n if (this.onProgress) {\n this.onProgress(progress);\n }\n }\n}\n","/**\n * Base parser interface and utilities\n */\n\nimport type { FileAnalysis, GraphNode, GraphEdge, ImportInfo, ExportInfo } from \"../types.js\";\n\nexport interface Parser {\n language: string;\n extensions: string[];\n parse(filePath: string, content: string): FileAnalysis;\n}\n\nexport abstract class BaseParser implements Parser {\n abstract language: string;\n abstract extensions: string[];\n\n protected nodeIdCounter = 0;\n protected edgeIdCounter = 0;\n\n abstract parse(filePath: string, content: string): FileAnalysis;\n\n protected generateNodeId(filePath: string, name: string, line: number): string {\n return `${filePath}:${name}:${line}`;\n }\n\n protected generateEdgeId(): string {\n return `edge_${++this.edgeIdCounter}`;\n }\n\n protected createNode(\n type: GraphNode[\"type\"],\n name: string,\n filePath: string,\n startLine: number,\n endLine: number,\n metadata?: Record<string, unknown>\n ): GraphNode {\n return {\n id: this.generateNodeId(filePath, name, startLine),\n type,\n name,\n filePath,\n startLine,\n endLine,\n language: this.language,\n metadata,\n };\n }\n\n protected createEdge(\n type: GraphEdge[\"type\"],\n sourceId: string,\n targetId: string,\n metadata?: Record<string, unknown>\n ): GraphEdge {\n return {\n id: this.generateEdgeId(),\n type,\n sourceId,\n targetId,\n metadata,\n };\n }\n\n protected createEmptyAnalysis(filePath: string): FileAnalysis {\n return {\n filePath,\n language: this.language,\n nodes: [],\n edges: [],\n imports: [],\n exports: [],\n };\n }\n}\n\n/**\n * Registry for all parsers\n */\nexport class ParserRegistry {\n private parsers: Map<string, Parser> = new Map();\n private extensionMap: Map<string, Parser> = new Map();\n\n register(parser: Parser): void {\n this.parsers.set(parser.language, parser);\n for (const ext of parser.extensions) {\n this.extensionMap.set(ext, parser);\n }\n }\n\n getByLanguage(language: string): Parser | undefined {\n return this.parsers.get(language);\n }\n\n getByExtension(extension: string): Parser | undefined {\n // Normalize extension (remove leading dot if present)\n const ext = extension.startsWith(\".\") ? extension : `.${extension}`;\n return this.extensionMap.get(ext);\n }\n\n getForFile(filePath: string): Parser | undefined {\n const ext = filePath.substring(filePath.lastIndexOf(\".\"));\n return this.getByExtension(ext);\n }\n\n getSupportedExtensions(): string[] {\n return Array.from(this.extensionMap.keys());\n }\n\n getSupportedLanguages(): string[] {\n return Array.from(this.parsers.keys());\n }\n}\n\nexport const parserRegistry = new ParserRegistry();\n","/**\n * TypeScript/JavaScript parser using Tree-sitter\n */\n\nimport Parser from \"tree-sitter\";\nimport TypeScript from \"tree-sitter-typescript\";\nimport JavaScript from \"tree-sitter-javascript\";\nimport { BaseParser } from \"./base.js\";\nimport type { FileAnalysis, GraphNode, GraphEdge, ImportInfo, ExportInfo } from \"../types.js\";\n\nexport class TypeScriptParser extends BaseParser {\n language = \"typescript\";\n extensions = [\".ts\", \".tsx\"];\n\n private parser: Parser;\n\n constructor() {\n super();\n this.parser = new Parser();\n this.parser.setLanguage(TypeScript.typescript);\n }\n\n parse(filePath: string, content: string): FileAnalysis {\n const analysis = this.createEmptyAnalysis(filePath);\n\n // Ensure content is a string (not Buffer)\n const sourceCode = typeof content === \"string\" ? content : String(content);\n\n // Skip extremely large files (>500KB) to prevent memory issues\n if (sourceCode.length > 500000) {\n const lines = sourceCode.split(\"\\n\");\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n return analysis;\n }\n\n // Use TSX parser for .tsx files\n if (filePath.endsWith(\".tsx\")) {\n this.parser.setLanguage(TypeScript.tsx);\n } else {\n this.parser.setLanguage(TypeScript.typescript);\n }\n\n let tree;\n try {\n tree = this.parser.parse(sourceCode);\n } catch {\n // If parsing fails, just return the file node\n const lines = sourceCode.split(\"\\n\");\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n return analysis;\n }\n\n const lines = sourceCode.split(\"\\n\");\n\n // Create file node\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n\n // Walk the tree\n this.walkTree(tree.rootNode, filePath, analysis, fileNode.id);\n\n return analysis;\n }\n\n private walkTree(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n switch (node.type) {\n case \"import_statement\":\n this.handleImport(node, analysis);\n break;\n\n case \"export_statement\":\n this.handleExport(node, filePath, analysis, parentId);\n break;\n\n case \"function_declaration\":\n case \"arrow_function\":\n case \"function_expression\":\n this.handleFunction(node, filePath, analysis, parentId);\n break;\n\n case \"class_declaration\":\n this.handleClass(node, filePath, analysis, parentId);\n break;\n\n case \"method_definition\":\n this.handleMethod(node, filePath, analysis, parentId);\n break;\n\n case \"call_expression\":\n this.handleCall(node, filePath, analysis, parentId);\n break;\n\n case \"variable_declaration\":\n this.handleVariable(node, filePath, analysis, parentId);\n break;\n }\n\n // Recurse into children\n for (const child of node.children) {\n this.walkTree(child, filePath, analysis, parentId);\n }\n }\n\n private handleImport(node: Parser.SyntaxNode, analysis: FileAnalysis): void {\n const sourceNode = node.childForFieldName(\"source\");\n if (!sourceNode) return;\n\n const source = sourceNode.text.replace(/['\"]/g, \"\");\n const specifiers: string[] = [];\n let isDefault = false;\n let isNamespace = false;\n\n // Find import clause\n for (const child of node.children) {\n if (child.type === \"import_clause\") {\n for (const clauseChild of child.children) {\n if (clauseChild.type === \"identifier\") {\n specifiers.push(clauseChild.text);\n isDefault = true;\n } else if (clauseChild.type === \"namespace_import\") {\n isNamespace = true;\n const nameNode = clauseChild.childForFieldName(\"name\");\n if (nameNode) specifiers.push(nameNode.text);\n } else if (clauseChild.type === \"named_imports\") {\n for (const importSpec of clauseChild.children) {\n if (importSpec.type === \"import_specifier\") {\n const name = importSpec.childForFieldName(\"name\");\n if (name) specifiers.push(name.text);\n }\n }\n }\n }\n }\n }\n\n analysis.imports.push({\n source,\n specifiers,\n isDefault,\n isNamespace,\n line: node.startPosition.row + 1,\n });\n }\n\n private handleExport(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const isDefault = node.children.some((c) => c.type === \"default\");\n\n // Find what's being exported\n for (const child of node.children) {\n if (child.type === \"function_declaration\") {\n const nameNode = child.childForFieldName(\"name\");\n if (nameNode) {\n analysis.exports.push({\n name: nameNode.text,\n isDefault,\n line: node.startPosition.row + 1,\n });\n }\n this.handleFunction(child, filePath, analysis, parentId);\n } else if (child.type === \"class_declaration\") {\n const nameNode = child.childForFieldName(\"name\");\n if (nameNode) {\n analysis.exports.push({\n name: nameNode.text,\n isDefault,\n line: node.startPosition.row + 1,\n });\n }\n this.handleClass(child, filePath, analysis, parentId);\n } else if (child.type === \"identifier\") {\n analysis.exports.push({\n name: child.text,\n isDefault,\n line: node.startPosition.row + 1,\n });\n }\n }\n }\n\n private handleFunction(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n let name = \"anonymous\";\n const nameNode = node.childForFieldName(\"name\");\n if (nameNode) {\n name = nameNode.text;\n }\n\n const funcNode = this.createNode(\n \"function\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n async: node.children.some((c) => c.type === \"async\"),\n generator: node.children.some((c) => c.text === \"*\"),\n }\n );\n\n analysis.nodes.push(funcNode);\n\n // Add contains edge from parent\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, funcNode.id)\n );\n }\n\n private handleClass(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const classNode = this.createNode(\n \"class\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1\n );\n\n analysis.nodes.push(classNode);\n\n // Add contains edge\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, classNode.id)\n );\n\n // Check for extends\n for (const child of node.children) {\n if (child.type === \"class_heritage\") {\n const extendsClause = child.children.find((c) => c.type === \"extends_clause\");\n if (extendsClause) {\n const baseClass = extendsClause.children.find((c) => c.type === \"identifier\");\n if (baseClass) {\n // Create a reference edge (will be resolved later)\n analysis.edges.push(\n this.createEdge(\"extends\", classNode.id, `ref:${baseClass.text}`, {\n unresolvedName: baseClass.text,\n })\n );\n }\n }\n }\n }\n\n // Process class body for methods\n const body = node.childForFieldName(\"body\");\n if (body) {\n for (const member of body.children) {\n if (member.type === \"method_definition\") {\n this.handleMethod(member, filePath, analysis, classNode.id);\n }\n }\n }\n }\n\n private handleMethod(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const methodNode = this.createNode(\n \"method\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n static: node.children.some((c) => c.type === \"static\"),\n async: node.children.some((c) => c.type === \"async\"),\n }\n );\n\n analysis.nodes.push(methodNode);\n\n // Add contains edge\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, methodNode.id)\n );\n }\n\n private handleCall(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const funcNode = node.childForFieldName(\"function\");\n if (!funcNode) return;\n\n let calledName = \"\";\n if (funcNode.type === \"identifier\") {\n calledName = funcNode.text;\n } else if (funcNode.type === \"member_expression\") {\n // Get the full member expression (e.g., \"console.log\")\n calledName = funcNode.text;\n }\n\n if (calledName) {\n analysis.edges.push(\n this.createEdge(\"calls\", parentId, `ref:${calledName}`, {\n unresolvedName: calledName,\n line: node.startPosition.row + 1,\n })\n );\n }\n }\n\n private handleVariable(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n for (const child of node.children) {\n if (child.type === \"variable_declarator\") {\n const nameNode = child.childForFieldName(\"name\");\n const valueNode = child.childForFieldName(\"value\");\n\n if (nameNode && nameNode.type === \"identifier\") {\n // Check if it's a function expression or arrow function\n if (\n valueNode &&\n (valueNode.type === \"arrow_function\" ||\n valueNode.type === \"function_expression\")\n ) {\n const funcNode = this.createNode(\n \"function\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n kind: node.children[0]?.text || \"const\",\n }\n );\n analysis.nodes.push(funcNode);\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, funcNode.id)\n );\n }\n }\n }\n }\n }\n}\n\nexport class JavaScriptParser extends TypeScriptParser {\n language = \"javascript\";\n extensions = [\".js\", \".jsx\", \".mjs\", \".cjs\"];\n\n constructor() {\n super();\n // Override to use JavaScript grammar\n (this as any).parser = new Parser();\n (this as any).parser.setLanguage(JavaScript);\n }\n\n parse(filePath: string, content: string): FileAnalysis {\n // Ensure content is a string\n const sourceCode = typeof content === \"string\" ? content : String(content);\n\n // Use JSX parser for .jsx files\n if (filePath.endsWith(\".jsx\")) {\n // JSX needs TSX parser\n (this as any).parser.setLanguage(TypeScript.tsx);\n } else {\n (this as any).parser.setLanguage(JavaScript);\n }\n\n // Use base implementation but mark as javascript\n const analysis = super.parse(filePath, sourceCode);\n analysis.language = \"javascript\";\n for (const node of analysis.nodes) {\n node.language = \"javascript\";\n }\n return analysis;\n }\n}\n","/**\n * Python parser using Tree-sitter\n */\n\nimport Parser from \"tree-sitter\";\nimport Python from \"tree-sitter-python\";\nimport { BaseParser } from \"./base.js\";\nimport type { FileAnalysis, GraphNode, GraphEdge, ImportInfo, ExportInfo } from \"../types.js\";\n\nexport class PythonParser extends BaseParser {\n language = \"python\";\n extensions = [\".py\"];\n\n private parser: Parser;\n\n constructor() {\n super();\n this.parser = new Parser();\n this.parser.setLanguage(Python);\n }\n\n parse(filePath: string, content: string): FileAnalysis {\n const analysis = this.createEmptyAnalysis(filePath);\n\n // Ensure content is a string (not Buffer)\n const sourceCode = typeof content === \"string\" ? content : String(content);\n\n // Skip extremely large files (>500KB) to prevent memory issues\n if (sourceCode.length > 500000) {\n const lines = sourceCode.split(\"\\n\");\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n return analysis;\n }\n\n let tree;\n try {\n // Use callback-based parsing to avoid \"Invalid argument\" errors with large files\n // This is more robust than passing the string directly\n tree = this.parser.parse((index, position) => {\n if (index >= sourceCode.length) {\n return null;\n }\n const endIndex = Math.min(index + 1024, sourceCode.length);\n return sourceCode.substring(index, endIndex);\n });\n } catch (error) {\n // If parsing fails, just return the file node\n const lines = sourceCode.split(\"\\n\");\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n return analysis;\n }\n\n const lines = sourceCode.split(\"\\n\");\n\n // Create file node\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n\n // Walk the tree\n this.walkTree(tree.rootNode, filePath, analysis, fileNode.id);\n\n return analysis;\n }\n\n private walkTree(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n switch (node.type) {\n case \"import_statement\":\n this.handleImport(node, analysis);\n break;\n\n case \"import_from_statement\":\n this.handleFromImport(node, analysis);\n break;\n\n case \"function_definition\":\n this.handleFunction(node, filePath, analysis, parentId);\n return; // Don't recurse into function body for top-level analysis\n\n case \"class_definition\":\n this.handleClass(node, filePath, analysis, parentId);\n return; // Don't recurse, class handler will process methods\n\n case \"call\":\n this.handleCall(node, filePath, analysis, parentId);\n break;\n }\n\n // Recurse into children\n for (const child of node.children) {\n this.walkTree(child, filePath, analysis, parentId);\n }\n }\n\n private handleImport(node: Parser.SyntaxNode, analysis: FileAnalysis): void {\n // import foo, bar, baz\n for (const child of node.children) {\n if (child.type === \"dotted_name\") {\n analysis.imports.push({\n source: child.text,\n specifiers: [child.text.split(\".\").pop() || child.text],\n isDefault: false,\n isNamespace: true,\n line: node.startPosition.row + 1,\n });\n } else if (child.type === \"aliased_import\") {\n const nameNode = child.childForFieldName(\"name\");\n const aliasNode = child.childForFieldName(\"alias\");\n if (nameNode) {\n analysis.imports.push({\n source: nameNode.text,\n specifiers: [aliasNode?.text || nameNode.text],\n isDefault: false,\n isNamespace: true,\n line: node.startPosition.row + 1,\n });\n }\n }\n }\n }\n\n private handleFromImport(node: Parser.SyntaxNode, analysis: FileAnalysis): void {\n // from foo import bar, baz\n const moduleNode = node.childForFieldName(\"module_name\");\n if (!moduleNode) return;\n\n const source = moduleNode.text;\n const specifiers: string[] = [];\n\n for (const child of node.children) {\n if (child.type === \"import_prefix\") {\n // Handle relative imports (from . import x, from .. import y)\n continue;\n }\n\n if (child.type === \"dotted_name\" && child !== moduleNode) {\n specifiers.push(child.text);\n } else if (child.type === \"aliased_import\") {\n const nameNode = child.childForFieldName(\"name\");\n if (nameNode) {\n specifiers.push(nameNode.text);\n }\n } else if (child.type === \"wildcard_import\") {\n specifiers.push(\"*\");\n }\n }\n\n if (specifiers.length === 0) {\n // Check for named imports in different structure\n for (const child of node.children) {\n if (child.type === \"import_list\" || child.type === \"import_from_specifier\") {\n for (const spec of child.children) {\n if (spec.type === \"dotted_name\" || spec.type === \"identifier\") {\n specifiers.push(spec.text);\n }\n }\n }\n }\n }\n\n analysis.imports.push({\n source,\n specifiers,\n isDefault: false,\n isNamespace: specifiers.includes(\"*\"),\n line: node.startPosition.row + 1,\n });\n }\n\n private handleFunction(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const name = nameNode.text;\n\n // Check for decorators - they are siblings within parent decorated_definition\n const decorators: string[] = [];\n const decoratorDetails: Array<{ name: string; args: string[]; kwargs?: Record<string, string> }> = [];\n\n // Check if parent is decorated_definition\n if (node.parent?.type === \"decorated_definition\") {\n // Decorators are children of decorated_definition, before the function_definition\n for (const sibling of node.parent.children) {\n if (sibling.type === \"decorator\") {\n // Find the decorator call or attribute\n const decoratorCall = sibling.children.find((c) => c.type === \"call\");\n const decoratorAttr = sibling.children.find((c) => c.type === \"attribute\" || c.type === \"identifier\");\n\n if (decoratorCall) {\n // Decorator with arguments: @router.post(\"/chat\")\n const funcName = decoratorCall.children.find((c) => c.type === \"attribute\" || c.type === \"identifier\");\n if (funcName) {\n const fullDecorator = funcName.text;\n decorators.push(fullDecorator);\n\n // Extract arguments (both positional and keyword)\n const args: string[] = [];\n const kwargs: Record<string, string> = {};\n const argList = decoratorCall.children.find((c) => c.type === \"argument_list\");\n if (argList) {\n for (const arg of argList.children) {\n if (arg.type === \"string\") {\n // Positional string argument\n const stringContent = arg.children.find((c) => c.type === \"string_content\");\n const argText = stringContent ? stringContent.text : arg.text.replace(/^[\"']|[\"']$/g, \"\");\n args.push(argText);\n } else if (arg.type === \"keyword_argument\") {\n // Keyword argument: tags=[\"chat\"]\n const keyNode = arg.childForFieldName(\"name\");\n const valueNode = arg.childForFieldName(\"value\");\n if (keyNode && valueNode) {\n const key = keyNode.text;\n let value = valueNode.text;\n // Simplify list values\n if (valueNode.type === \"list\") {\n const items: string[] = [];\n for (const child of valueNode.children) {\n if (child.type === \"string\") {\n const stringContent = child.children.find((c) => c.type === \"string_content\");\n items.push(stringContent ? stringContent.text : child.text.replace(/^[\"']|[\"']$/g, \"\"));\n }\n }\n value = items.length > 0 ? items.join(\",\") : value;\n }\n kwargs[key] = value;\n }\n } else if (arg.type === \"identifier\") {\n // Positional identifier argument\n args.push(arg.text);\n }\n }\n }\n\n decoratorDetails.push({ name: fullDecorator, args, kwargs });\n }\n } else if (decoratorAttr) {\n // Simple decorator without arguments: @property\n const fullDecorator = decoratorAttr.text;\n decorators.push(fullDecorator);\n decoratorDetails.push({ name: fullDecorator, args: [] });\n }\n }\n }\n }\n\n // Check if async\n const isAsync = node.children.some((c) => c.type === \"async\");\n\n // Extract return type hint from -> annotation\n let returnType: string | undefined;\n const returnTypeNode = node.childForFieldName(\"return_type\");\n if (returnTypeNode) {\n returnType = returnTypeNode.text;\n // Clean up the type (remove quotes, generic parameters for simple matching)\n returnType = returnType.replace(/[\"']/g, \"\").split(\"[\")[0].trim();\n }\n\n const funcNode = this.createNode(\n \"function\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n async: isAsync,\n decorators,\n decoratorDetails: JSON.stringify(decoratorDetails),\n isPrivate: name.startsWith(\"_\"),\n isDunder: name.startsWith(\"__\") && name.endsWith(\"__\"),\n returnType,\n }\n );\n\n analysis.nodes.push(funcNode);\n analysis.edges.push(this.createEdge(\"contains\", parentId, funcNode.id));\n\n // Check for FastAPI route decorators (@router.get, @router.post, etc.)\n this.detectFastAPIRoute(decoratorDetails, funcNode, analysis);\n\n // Parse function parameters for Depends() and type hints\n const parameters = node.childForFieldName(\"parameters\");\n if (parameters) {\n this.detectDependsPattern(parameters, funcNode, analysis);\n this.extractParameterTypes(parameters, funcNode.id, filePath, analysis);\n }\n\n // Parse function body for calls\n const body = node.childForFieldName(\"body\");\n if (body) {\n this.parseBodyForCalls(body, filePath, analysis, funcNode.id);\n }\n\n // If not private, consider it exported\n if (!name.startsWith(\"_\")) {\n analysis.exports.push({\n name,\n isDefault: false,\n line: node.startPosition.row + 1,\n });\n }\n }\n\n /**\n * Detect FastAPI route decorators like @router.post(\"/chat\")\n */\n private detectFastAPIRoute(\n decoratorDetails: Array<{ name: string; args: string[]; kwargs?: Record<string, string> }>,\n funcNode: GraphNode,\n analysis: FileAnalysis\n ): void {\n for (const dec of decoratorDetails) {\n // Match patterns: router.get, router.post, app.get, etc.\n const routeMatch = dec.name.match(/^(router|app)\\.(get|post|put|patch|delete|options|head)$/);\n if (routeMatch && dec.args.length > 0) {\n const method = routeMatch[2].toUpperCase();\n const path = dec.args[0]; // First argument is the path\n\n // Store as metadata in the function node\n if (!funcNode.metadata) funcNode.metadata = {};\n funcNode.metadata.httpEndpoint = {\n method,\n path,\n };\n }\n }\n }\n\n /**\n * Detect Depends() pattern in function parameters\n * Example: user: User = Depends(authenticate_user)\n */\n private detectDependsPattern(\n parameters: Parser.SyntaxNode,\n funcNode: GraphNode,\n analysis: FileAnalysis\n ): void {\n for (const param of parameters.children) {\n if (param.type === \"typed_parameter\" || param.type === \"default_parameter\") {\n // Look for default value\n const defaultValue = param.children.find((c) => c.type === \"call\");\n if (defaultValue) {\n // Check if it's a Depends() call\n const funcCall = defaultValue.childForFieldName(\"function\");\n if (funcCall && funcCall.text === \"Depends\") {\n // Extract the argument to Depends()\n const argList = defaultValue.childForFieldName(\"arguments\");\n if (argList) {\n for (const arg of argList.children) {\n if (arg.type === \"identifier\") {\n const dependencyName = arg.text;\n\n // Get parameter name\n const paramName = param.children.find(\n (c) => c.type === \"identifier\"\n )?.text;\n\n // Store in metadata\n if (!funcNode.metadata) funcNode.metadata = {};\n if (!funcNode.metadata.depends) funcNode.metadata.depends = [];\n (funcNode.metadata.depends as any[]).push({\n parameterName: paramName,\n dependencyName,\n line: param.startPosition.row + 1,\n });\n\n // Create an edge to represent this dependency\n // We'll use a special edge type that will be resolved later\n analysis.edges.push(\n this.createEdge(\"depends\", funcNode.id, `ref:${dependencyName}`, {\n unresolvedName: dependencyName,\n parameterName: paramName,\n line: param.startPosition.row + 1,\n })\n );\n }\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Extract parameter type hints and register as variable types\n * Example: def process(user: User, config: Config)\n */\n private extractParameterTypes(\n parameters: Parser.SyntaxNode,\n scopeId: string,\n filePath: string,\n analysis: FileAnalysis\n ): void {\n for (const param of parameters.children) {\n if (param.type === \"typed_parameter\") {\n // Get parameter name\n const nameNode = param.children.find((c) => c.type === \"identifier\");\n if (!nameNode) continue;\n\n const paramName = nameNode.text;\n\n // Skip self and cls\n if (paramName === \"self\" || paramName === \"cls\") continue;\n\n // Get type annotation\n const typeNode = param.children.find((c) => c.type === \"type\");\n if (!typeNode) continue;\n\n let typeName = typeNode.text;\n\n // Clean up type (remove quotes, Optional[], List[], etc.)\n typeName = typeName.replace(/[\"']/g, \"\").trim();\n\n // Extract base type from generics: Optional[User] -> User, List[Item] -> Item\n const genericMatch = typeName.match(/(?:Optional|List|Dict|Set)\\[([^\\]]+)\\]/);\n if (genericMatch) {\n typeName = genericMatch[1].trim();\n }\n\n // Store as variable type in function scope\n if (!analysis.variableTypes) {\n analysis.variableTypes = [];\n }\n\n analysis.variableTypes.push({\n variableName: paramName,\n typeName,\n scopeId,\n line: param.startPosition.row + 1,\n });\n }\n }\n }\n\n private handleClass(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const name = nameNode.text;\n\n // Check for base classes\n const bases: string[] = [];\n const argumentList = node.children.find((c) => c.type === \"argument_list\");\n if (argumentList) {\n for (const arg of argumentList.children) {\n if (arg.type === \"identifier\" || arg.type === \"attribute\") {\n bases.push(arg.text);\n }\n }\n }\n\n const classNode = this.createNode(\n \"class\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n bases,\n isPrivate: name.startsWith(\"_\"),\n }\n );\n\n analysis.nodes.push(classNode);\n analysis.edges.push(this.createEdge(\"contains\", parentId, classNode.id));\n\n // Add extends edges\n for (const base of bases) {\n analysis.edges.push(\n this.createEdge(\"extends\", classNode.id, `ref:${base}`, {\n unresolvedName: base,\n })\n );\n }\n\n // Parse class body for methods\n const body = node.childForFieldName(\"body\");\n if (body) {\n for (const child of body.children) {\n if (child.type === \"function_definition\") {\n this.handleMethod(child, filePath, analysis, classNode.id);\n } else if (child.type === \"decorated_definition\") {\n // Handle decorated methods (@classmethod, @staticmethod, @property, etc.)\n const funcNode = child.children.find((c) => c.type === \"function_definition\");\n if (funcNode) {\n this.handleMethod(funcNode, filePath, analysis, classNode.id);\n }\n }\n }\n }\n\n // Consider non-private classes as exports\n if (!name.startsWith(\"_\")) {\n analysis.exports.push({\n name,\n isDefault: false,\n line: node.startPosition.row + 1,\n });\n }\n }\n\n private handleMethod(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n classId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const name = nameNode.text;\n\n // Check for decorators - they are siblings within parent decorated_definition\n const decorators: string[] = [];\n\n // Check if parent is decorated_definition (same as for top-level functions)\n if (node.parent?.type === \"decorated_definition\") {\n for (const sibling of node.parent.children) {\n if (sibling.type === \"decorator\") {\n const decoratorAttr = sibling.children.find((c) => c.type === \"attribute\" || c.type === \"identifier\");\n if (decoratorAttr) {\n decorators.push(decoratorAttr.text);\n }\n }\n }\n }\n\n const isStatic = decorators.includes(\"staticmethod\");\n const isClassMethod = decorators.includes(\"classmethod\");\n const isProperty = decorators.includes(\"property\");\n const isAsync = node.children.some((c) => c.type === \"async\");\n\n const methodNode = this.createNode(\n \"method\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n async: isAsync,\n decorators,\n static: isStatic,\n classmethod: isClassMethod,\n property: isProperty,\n isPrivate: name.startsWith(\"_\"),\n isDunder: name.startsWith(\"__\") && name.endsWith(\"__\"),\n }\n );\n\n analysis.nodes.push(methodNode);\n analysis.edges.push(this.createEdge(\"contains\", classId, methodNode.id));\n\n // Parse method body for calls\n const body = node.childForFieldName(\"body\");\n if (body) {\n this.parseBodyForCalls(body, filePath, analysis, methodNode.id);\n }\n }\n\n private handleCall(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const funcNode = node.childForFieldName(\"function\");\n if (!funcNode) return;\n\n let calledName = \"\";\n if (funcNode.type === \"identifier\") {\n calledName = funcNode.text;\n } else if (funcNode.type === \"attribute\") {\n // Get the full attribute access (e.g., \"self.method\", \"module.func\")\n calledName = funcNode.text;\n }\n\n if (calledName) {\n // Track all calls including self.method for proper resolution\n analysis.edges.push(\n this.createEdge(\"calls\", parentId, `ref:${calledName}`, {\n unresolvedName: calledName,\n line: node.startPosition.row + 1,\n })\n );\n\n // Detect database operations (MongoDB patterns)\n this.detectDatabaseOperation(calledName, node, parentId, analysis);\n }\n }\n\n /**\n * Detect database operations (MongoDB, SQL, etc.)\n * Examples: collection.find_one(), db.users.insert_one(), collection.update_many()\n */\n private detectDatabaseOperation(\n calledName: string,\n node: Parser.SyntaxNode,\n parentId: string,\n analysis: FileAnalysis\n ): void {\n // MongoDB operation patterns\n const mongoOps = [\n \"find_one\",\n \"find\",\n \"insert_one\",\n \"insert_many\",\n \"update_one\",\n \"update_many\",\n \"delete_one\",\n \"delete_many\",\n \"aggregate\",\n \"count_documents\",\n \"replace_one\",\n ];\n\n // Check if the called method is a MongoDB operation\n const parts = calledName.split(\".\");\n const operation = parts[parts.length - 1];\n\n if (mongoOps.includes(operation)) {\n // Try to extract collection name\n let collection = \"unknown\";\n if (parts.length >= 2) {\n collection = parts[parts.length - 2];\n }\n\n // Store database operation metadata\n if (!analysis.databaseOperations) {\n analysis.databaseOperations = [];\n }\n\n analysis.databaseOperations.push({\n nodeId: parentId,\n operation,\n collection,\n databaseType: \"mongodb\",\n line: node.startPosition.row + 1,\n });\n }\n }\n\n private parseBodyForCalls(\n body: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const walkForCalls = (node: Parser.SyntaxNode): void => {\n if (node.type === \"call\") {\n this.handleCall(node, filePath, analysis, parentId);\n } else if (node.type === \"import_statement\") {\n // Handle local imports inside functions\n this.handleImport(node, analysis);\n } else if (node.type === \"import_from_statement\") {\n // Handle local from imports inside functions\n this.handleFromImport(node, analysis);\n } else if (node.type === \"assignment\") {\n // Track variable assignments for type inference\n this.handleAssignment(node, filePath, analysis, parentId);\n }\n for (const child of node.children) {\n walkForCalls(child);\n }\n };\n walkForCalls(body);\n }\n\n /**\n * Handle variable assignments to track types\n * Examples:\n * user = get_user(id) # Track if get_user has type hint\n * handler = UserHandler(db) # Track: handler -> UserHandler\n * org_handler = OrgHandler.get_instance() # Track: org_handler -> OrgHandler\n */\n private handleAssignment(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n scopeId: string\n ): void {\n // Get left side (variable name)\n const leftNode = node.childForFieldName(\"left\");\n if (!leftNode || leftNode.type !== \"identifier\") return;\n\n const variableName = leftNode.text;\n\n // Get right side (value being assigned)\n const rightNode = node.childForFieldName(\"right\");\n if (!rightNode) return;\n\n let typeName: string | null = null;\n\n // Pattern 1: Direct class instantiation - handler = UserHandler(...)\n if (rightNode.type === \"call\") {\n const funcNode = rightNode.childForFieldName(\"function\");\n if (funcNode) {\n if (funcNode.type === \"identifier\") {\n // Simple: ClassName(...) or function_call()\n const funcName = funcNode.text;\n\n // Check if it's a known class (starts with capital) - instant assign\n if (funcName[0] === funcName[0].toUpperCase()) {\n typeName = funcName;\n } else {\n // It's a function call - we'll need to look up return type later\n // Store as a pending type resolution\n typeName = `@call:${funcName}`;\n }\n } else if (funcNode.type === \"attribute\") {\n // Class method: ClassName.method()\n const parts = funcNode.text.split(\".\");\n if (parts.length >= 2) {\n const className = parts[0];\n const methodName = parts[1];\n\n // If className is capitalized, assume the method returns that class type\n if (className[0] === className[0].toUpperCase()) {\n typeName = className;\n } else {\n // Store for later resolution\n typeName = `@call:${funcNode.text}`;\n }\n }\n }\n }\n }\n\n if (typeName && !analysis.variableTypes) {\n analysis.variableTypes = [];\n }\n\n if (typeName) {\n analysis.variableTypes!.push({\n variableName,\n typeName,\n scopeId,\n line: node.startPosition.row + 1,\n });\n }\n }\n}\n","/**\n * Parser registry and exports\n */\n\nexport { BaseParser, ParserRegistry, parserRegistry } from \"./base.js\";\nexport { TypeScriptParser, JavaScriptParser } from \"./typescript.js\";\nexport { PythonParser } from \"./python.js\";\n\nimport { parserRegistry } from \"./base.js\";\nimport { TypeScriptParser, JavaScriptParser } from \"./typescript.js\";\nimport { PythonParser } from \"./python.js\";\n\n// Register all parsers\nexport function registerAllParsers(): void {\n parserRegistry.register(new TypeScriptParser());\n parserRegistry.register(new JavaScriptParser());\n parserRegistry.register(new PythonParser());\n}\n\n// Auto-register on import\nregisterAllParsers();\n","/**\n * Core types for CodeMap\n */\n\n// ============ Graph Node Types ============\n\nexport type NodeType =\n | \"file\"\n | \"function\"\n | \"class\"\n | \"method\"\n | \"variable\"\n | \"module\"\n | \"import\";\n\nexport interface GraphNode {\n id: string;\n type: NodeType;\n name: string;\n filePath: string;\n startLine: number;\n endLine: number;\n language: string;\n metadata?: Record<string, unknown>;\n}\n\n// ============ Graph Edge Types ============\n\nexport type EdgeType =\n | \"imports\"\n | \"calls\"\n | \"extends\"\n | \"implements\"\n | \"contains\"\n | \"uses\"\n | \"exports\"\n | \"depends\";\n\nexport interface GraphEdge {\n id: string;\n type: EdgeType;\n sourceId: string;\n targetId: string;\n metadata?: Record<string, unknown>;\n}\n\n// ============ Analysis Results ============\n\nexport interface FileAnalysis {\n filePath: string;\n language: string;\n nodes: GraphNode[];\n edges: GraphEdge[];\n imports: ImportInfo[];\n exports: ExportInfo[];\n variableTypes?: VariableTypeInfo[];\n databaseOperations?: DatabaseOperationInfo[];\n}\n\nexport interface VariableTypeInfo {\n variableName: string;\n typeName: string;\n scopeId: string;\n line: number;\n}\n\nexport interface DatabaseOperationInfo {\n nodeId: string;\n operation: string;\n collection: string;\n databaseType: string;\n line: number;\n}\n\nexport interface ImportInfo {\n source: string;\n specifiers: string[];\n isDefault: boolean;\n isNamespace: boolean;\n line: number;\n}\n\nexport interface ExportInfo {\n name: string;\n isDefault: boolean;\n line: number;\n}\n\n// ============ Project Analysis ============\n\nexport interface ProjectAnalysis {\n rootPath: string;\n files: FileAnalysis[];\n totalNodes: number;\n totalEdges: number;\n languages: Record<string, number>;\n analyzedAt: string;\n parseErrors?: string[];\n}\n\n// ============ Query Results ============\n\nexport interface AffectedFile {\n filePath: string;\n reason: string;\n depth: number;\n connections: string[];\n}\n\nexport interface CallChain {\n caller: GraphNode;\n callee: GraphNode;\n filePath: string;\n line: number;\n}\n\n// ============ Skill Generation ============\n\nexport interface GeneratedSkill {\n name: string;\n description: string;\n content: string;\n filePath: string;\n}\n\nexport interface SkillConfig {\n projectName: string;\n outputDir: string;\n includeArchitecture: boolean;\n includePatterns: boolean;\n includeDependencies: boolean;\n}\n\n// ============ Configuration ============\n\nexport interface CodeMapConfig {\n rootPath: string;\n include: string[];\n exclude: string[];\n languages: string[];\n dbPath: string;\n skillsOutputDir: string;\n}\n\nexport const DEFAULT_CONFIG: Partial<CodeMapConfig> = {\n include: [\"**/*.ts\", \"**/*.tsx\", \"**/*.js\", \"**/*.jsx\", \"**/*.py\"],\n exclude: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.git/**\",\n \"**/venv/**\",\n \"**/__pycache__/**\",\n \"**/.next/**\",\n ],\n languages: [\"typescript\", \"javascript\", \"python\"],\n};\n\n// ============ MCP Types ============\n\nexport interface MCPToolResult {\n content: Array<{\n type: \"text\";\n text: string;\n }>;\n}\n\nexport interface MCPResource {\n uri: string;\n name: string;\n description: string;\n mimeType: string;\n}\n","/**\n * Impact analysis command\n * Detects changes and calculates their impact on the codebase\n */\n\nimport { resolve, join, relative } from \"path\";\nimport { FlowStorage } from \"../flow/storage.js\";\nimport { FlowBuilder } from \"../flow/builder.js\";\nimport { DEFAULT_CONFIG } from \"../types.js\";\nimport {\n isGitRepository,\n getGitChangedFiles,\n parseGitDiffForFunctions,\n getGitStatus,\n type GitChangedFunction,\n} from \"../utils/git.js\";\nimport { analyzeImports, type ImportAnalysisResult } from \"../analysis/imports.js\";\nimport {\n parseDockerCompose,\n calculateServiceBlastRadius,\n type DockerDependencyGraph,\n} from \"../analysis/docker.js\";\n\nexport interface ImpactResult {\n changedFiles: string[];\n changedFunctions: GitChangedFunction[];\n directCallers: Map<string, { name: string; file: string; line: number }[]>;\n affectedEndpoints: string[];\n importIssues: Map<string, ImportAnalysisResult>;\n dockerImpact?: {\n affectedServices: string[];\n entryPointFiles: string[];\n };\n riskLevel: \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\";\n totalImpact: number;\n}\n\nexport interface ImpactOptions {\n path?: string;\n verbose?: boolean;\n}\n\n/**\n * Analyze impact of code changes\n */\nexport async function analyzeImpact(options: ImpactOptions = {}): Promise<ImpactResult> {\n const rootPath = resolve(options.path || \".\");\n const dbPath = join(rootPath, \".codemap\", \"graph.db\");\n const storage = new FlowStorage(dbPath);\n\n try {\n // Check if git repository\n if (isGitRepository(rootPath)) {\n return await analyzeImpactWithGit(storage, rootPath, options);\n } else {\n return await analyzeImpactWithHash(storage, rootPath, options);\n }\n } finally {\n storage.close();\n }\n}\n\n/**\n * Analyze impact using git diff (precise)\n */\nasync function analyzeImpactWithGit(\n storage: FlowStorage,\n rootPath: string,\n options: ImpactOptions\n): Promise<ImpactResult> {\n // Get git status\n const gitStatus = getGitStatus(rootPath);\n if (!gitStatus.hasChanges) {\n return {\n changedFiles: [],\n changedFunctions: [],\n directCallers: new Map(),\n affectedEndpoints: [],\n importIssues: new Map(),\n riskLevel: \"LOW\",\n totalImpact: 0,\n };\n }\n\n // Get changed files from git\n const changedFiles = getGitChangedFiles(rootPath);\n const changedFilePaths = changedFiles.map((f) => f.path);\n\n // Parse git diff to find changed functions\n const changedFunctions = parseGitDiffForFunctions(rootPath, changedFiles);\n\n // Re-index only changed files\n const builder = new FlowBuilder(storage, {\n rootPath,\n include: changedFilePaths.map((f) => f),\n exclude: [],\n forceReindex: true,\n });\n\n await builder.build();\n\n // Calculate impact for each changed function\n const directCallers = new Map<string, { name: string; file: string; line: number }[]>();\n const affectedEndpoints: string[] = [];\n\n for (const func of changedFunctions) {\n // Find all nodes matching this function name in this file\n const nodes = storage\n .getNodesByFile(join(rootPath, func.file))\n .filter((n) => n.name === func.functionName);\n\n for (const node of nodes) {\n // Get callers\n const callers = storage.getResolvedCallersWithLocation(node.id);\n if (callers.length > 0) {\n directCallers.set(func.functionName, callers);\n }\n\n // Check if this is an HTTP endpoint\n const endpoints = storage.getHttpEndpointsByHandler(node.id);\n for (const endpoint of endpoints) {\n affectedEndpoints.push(`${endpoint.method} ${endpoint.path}`);\n }\n }\n }\n\n // NEW: Analyze imports for each changed file\n const importIssues = new Map<string, ImportAnalysisResult>();\n for (const filePath of changedFilePaths) {\n const fullPath = join(rootPath, filePath);\n const analysis = analyzeImports(fullPath);\n\n if (analysis.missing.length > 0 || analysis.unused.length > 0) {\n importIssues.set(relative(rootPath, fullPath), analysis);\n }\n }\n\n // NEW: Analyze Docker Compose dependencies\n const dockerGraph = parseDockerCompose(rootPath);\n let dockerImpact: { affectedServices: string[]; entryPointFiles: string[] } | undefined;\n\n // Check if any changed file is a Docker entry point\n const entryPointFiles: string[] = [];\n const affectedServices = new Set<string>();\n\n for (const [serviceName, entryPoint] of dockerGraph.entryPoints) {\n // Check if this entry point matches any changed file\n for (const changedFile of changedFilePaths) {\n if (changedFile.includes(entryPoint) || entryPoint.includes(changedFile)) {\n entryPointFiles.push(entryPoint);\n\n // Calculate blast radius\n const blastRadius = calculateServiceBlastRadius(dockerGraph, serviceName);\n blastRadius.forEach((s) => affectedServices.add(s));\n }\n }\n }\n\n if (affectedServices.size > 0) {\n dockerImpact = {\n affectedServices: Array.from(affectedServices),\n entryPointFiles,\n };\n }\n\n // Calculate risk level (enhanced with import and Docker analysis)\n const totalCallers = Array.from(directCallers.values()).reduce((sum, callers) => sum + callers.length, 0);\n const hasCriticalImportIssues = Array.from(importIssues.values()).some((i) => i.missing.length > 0);\n const hasDockerImpact = dockerImpact && dockerImpact.affectedServices.length > 0;\n\n let riskLevel: \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\" = \"LOW\";\n\n if (hasCriticalImportIssues && hasDockerImpact) {\n riskLevel = \"CRITICAL\";\n } else if (hasCriticalImportIssues || (hasDockerImpact && dockerImpact!.affectedServices.length > 2)) {\n riskLevel = \"HIGH\";\n } else if (totalCallers > 20 || affectedEndpoints.length > 5) {\n riskLevel = \"HIGH\";\n } else if (totalCallers > 10 || affectedEndpoints.length > 2 || hasDockerImpact) {\n riskLevel = \"MEDIUM\";\n }\n\n return {\n changedFiles: changedFilePaths,\n changedFunctions,\n directCallers,\n affectedEndpoints,\n importIssues,\n dockerImpact,\n riskLevel,\n totalImpact: totalCallers + (dockerImpact?.affectedServices.length || 0),\n };\n}\n\n/**\n * Analyze impact using hash comparison (fallback)\n */\nasync function analyzeImpactWithHash(\n storage: FlowStorage,\n rootPath: string,\n options: ImpactOptions\n): Promise<ImpactResult> {\n // Get all files and their hashes before re-index\n const oldHashes = storage.getAllFileHashes();\n\n // Re-index with force\n const builder = new FlowBuilder(storage, {\n rootPath,\n include: DEFAULT_CONFIG.include!,\n exclude: DEFAULT_CONFIG.exclude!,\n forceReindex: false, // Use hash comparison\n });\n\n const result = await builder.build();\n\n // Find files that were re-indexed (hash changed)\n const changedFiles: string[] = [];\n const newHashes = storage.getAllFileHashes();\n\n for (const [filePath, newHash] of Object.entries(newHashes)) {\n const oldHash = oldHashes[filePath];\n if (!oldHash || oldHash !== newHash) {\n changedFiles.push(filePath);\n }\n }\n\n // Analyze imports for changed files\n const importIssues = new Map<string, ImportAnalysisResult>();\n for (const filePath of changedFiles) {\n const analysis = analyzeImports(filePath);\n if (analysis.missing.length > 0 || analysis.unused.length > 0) {\n importIssues.set(relative(rootPath, filePath), analysis);\n }\n }\n\n // For hash-based, we can't determine specific functions\n // Just return file-level impact\n const hasCriticalImportIssues = Array.from(importIssues.values()).some((i) => i.missing.length > 0);\n\n return {\n changedFiles,\n changedFunctions: [],\n directCallers: new Map(),\n affectedEndpoints: [],\n importIssues,\n riskLevel: hasCriticalImportIssues\n ? \"CRITICAL\"\n : changedFiles.length > 10\n ? \"HIGH\"\n : changedFiles.length > 5\n ? \"MEDIUM\"\n : \"LOW\",\n totalImpact: result.indexed,\n };\n}\n","/**\n * Git utilities for detecting changes\n */\n\nimport { execSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface GitChangedFile {\n path: string;\n status: \"modified\" | \"added\" | \"deleted\";\n}\n\nexport interface GitChangedFunction {\n file: string;\n functionName: string;\n lineNumber: number;\n changeType: \"added\" | \"modified\" | \"deleted\";\n}\n\n/**\n * Check if directory is a git repository\n */\nexport function isGitRepository(path: string): boolean {\n return existsSync(join(path, \".git\"));\n}\n\n/**\n * Get list of changed files from git diff\n */\nexport function getGitChangedFiles(rootPath: string): GitChangedFile[] {\n try {\n // Get changed files (both staged and unstaged)\n const output = execSync(\"git diff HEAD --name-status\", {\n cwd: rootPath,\n encoding: \"utf-8\",\n }).trim();\n\n if (!output) {\n return [];\n }\n\n const files: GitChangedFile[] = [];\n for (const line of output.split(\"\\n\")) {\n const [status, path] = line.split(\"\\t\");\n if (path) {\n files.push({\n path,\n status: status === \"A\" ? \"added\" : status === \"D\" ? \"deleted\" : \"modified\",\n });\n }\n }\n\n return files;\n } catch (error) {\n return [];\n }\n}\n\n/**\n * Parse git diff to find changed functions\n */\nexport function parseGitDiffForFunctions(rootPath: string, files: GitChangedFile[]): GitChangedFunction[] {\n const changedFunctions: GitChangedFunction[] = [];\n\n for (const file of files) {\n if (file.status === \"deleted\") {\n continue;\n }\n\n try {\n // Get detailed diff for this file\n const diff = execSync(`git diff HEAD -- \"${file.path}\"`, {\n cwd: rootPath,\n encoding: \"utf-8\",\n });\n\n // Parse diff to find function definitions\n const lines = diff.split(\"\\n\");\n let currentFunction: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Look for hunk headers with function context\n // @@ -47,6 +48,8 @@ def handle_chat():\n // @@ -120,1 +121,1 @@ async def authenticate_user(token: str):\n if (line.startsWith(\"@@\")) {\n const contextMatch = line.match(/@@.*@@\\s*(.*)/);\n if (contextMatch) {\n const context = contextMatch[1];\n\n // Python: def/async def\n const pythonMatch = context.match(/(?:async\\s+)?def\\s+(\\w+)/);\n if (pythonMatch) {\n currentFunction = pythonMatch[1];\n }\n\n // TypeScript/JavaScript: function/const/class\n const jsMatch = context.match(/(?:function|const|class)\\s+(\\w+)/);\n if (jsMatch) {\n currentFunction = jsMatch[1];\n }\n\n // Extract line number\n const lineMatch = line.match(/\\+(\\d+)/);\n const lineNumber = lineMatch ? parseInt(lineMatch[1]) : 0;\n\n if (currentFunction) {\n changedFunctions.push({\n file: file.path,\n functionName: currentFunction,\n lineNumber,\n changeType: file.status === \"added\" ? \"added\" : \"modified\",\n });\n }\n }\n }\n }\n } catch (error) {\n // Skip files with diff errors\n continue;\n }\n }\n\n return changedFunctions;\n}\n\n/**\n * Get uncommitted changes summary\n */\nexport function getGitStatus(rootPath: string): {\n hasChanges: boolean;\n modifiedFiles: number;\n stagedFiles: number;\n} {\n try {\n const statusOutput = execSync(\"git status --porcelain\", {\n cwd: rootPath,\n encoding: \"utf-8\",\n }).trim();\n\n const lines = statusOutput.split(\"\\n\").filter((l) => l.trim());\n const staged = lines.filter((l) => l[0] !== \" \" && l[0] !== \"?\").length;\n const modified = lines.length;\n\n return {\n hasChanges: modified > 0,\n modifiedFiles: modified,\n stagedFiles: staged,\n };\n } catch (error) {\n return {\n hasChanges: false,\n modifiedFiles: 0,\n stagedFiles: 0,\n };\n }\n}\n","/**\n * Import dependency analyzer\n * Detects missing/unused imports and tracks what they're used for\n * Uses regex-based parsing for fast analysis\n */\n\nimport { readFileSync } from \"fs\";\n\nexport interface ImportIssue {\n identifier: string;\n line: number;\n type: \"missing\" | \"unused\";\n usedAt?: number[]; // Line numbers where it's used (for missing imports)\n}\n\nexport interface ImportAnalysisResult {\n missing: ImportIssue[];\n unused: ImportIssue[];\n}\n\n/**\n * Analyze import integrity in a JavaScript/TypeScript file\n */\nexport function analyzeJavaScriptImports(filePath: string): ImportAnalysisResult {\n const content = readFileSync(filePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n // Extract imports using regex\n const imports = new Map<string, number>(); // identifier -> line number\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Match: import X from 'Y'\n const defaultMatch = line.match(/import\\s+(\\w+)\\s+from\\s+['\"]([^'\"]+)['\"]/);\n if (defaultMatch) {\n imports.set(defaultMatch[1], i + 1);\n }\n\n // Match: import { X, Y } from 'Z'\n const namedMatch = line.match(/import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]([^'\"]+)['\"]/);\n if (namedMatch) {\n const names = namedMatch[1].split(\",\").map(n => n.trim().split(\" as \")[0].trim());\n names.forEach(name => imports.set(name, i + 1));\n }\n }\n\n // Extract used identifiers (simplified - exclude comments/strings)\n const usedIdentifiers = new Map<string, number[]>(); // identifier -> line numbers\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Skip import lines and comments\n if (line.trim().startsWith(\"import \") || line.trim().startsWith(\"//\") || line.trim().startsWith(\"*\")) {\n continue;\n }\n\n // Find all identifiers in this line\n for (const [identifier] of imports) {\n // Simple regex to find identifier usage (not perfect but good enough)\n const regex = new RegExp(`\\\\b${identifier}\\\\b`, \"g\");\n if (regex.test(line)) {\n if (!usedIdentifiers.has(identifier)) {\n usedIdentifiers.set(identifier, []);\n }\n usedIdentifiers.get(identifier)!.push(i + 1);\n }\n }\n }\n\n // Find unused imports\n const unused: ImportIssue[] = [];\n for (const [identifier, line] of imports) {\n const usage = usedIdentifiers.get(identifier);\n if (!usage || usage.length === 0) {\n unused.push({ identifier, line, type: \"unused\" });\n }\n }\n\n // Find missing imports (simplified - check for common patterns)\n const missing: ImportIssue[] = [];\n const commonLibraries = [\"express\", \"cors\", \"winston\", \"Redis\", \"MongoClient\", \"mongoose\", \"axios\"];\n\n for (const lib of commonLibraries) {\n if (!imports.has(lib)) {\n // Check if it's used in the code\n const usageLines: number[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.includes(lib) && !line.trim().startsWith(\"//\")) {\n usageLines.push(i + 1);\n }\n }\n\n if (usageLines.length > 0) {\n missing.push({\n identifier: lib,\n line: usageLines[0],\n type: \"missing\",\n usedAt: usageLines,\n });\n }\n }\n }\n\n return { missing, unused };\n}\n\n/**\n * Analyze import integrity in a Python file\n */\nexport function analyzePythonImports(filePath: string): ImportAnalysisResult {\n const content = readFileSync(filePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n // Extract imports\n const imports = new Map<string, number>(); // identifier -> line number\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Match: import X\n const importMatch = line.match(/^import\\s+(\\w+)/);\n if (importMatch) {\n imports.set(importMatch[1], i + 1);\n }\n\n // Match: from X import Y\n const fromMatch = line.match(/^from\\s+[\\w.]+\\s+import\\s+(.+)/);\n if (fromMatch) {\n const names = fromMatch[1].split(\",\").map(n => n.trim().split(\" as \")[0].trim());\n names.forEach(name => imports.set(name, i + 1));\n }\n }\n\n // Extract used identifiers\n const usedIdentifiers = new Map<string, number[]>();\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Skip import lines and comments\n if (line.trim().startsWith(\"import \") || line.trim().startsWith(\"from \") || line.trim().startsWith(\"#\")) {\n continue;\n }\n\n // Find all identifiers in this line\n for (const [identifier] of imports) {\n const regex = new RegExp(`\\\\b${identifier}\\\\b`, \"g\");\n if (regex.test(line)) {\n if (!usedIdentifiers.has(identifier)) {\n usedIdentifiers.set(identifier, []);\n }\n usedIdentifiers.get(identifier)!.push(i + 1);\n }\n }\n }\n\n // Find unused imports\n const unused: ImportIssue[] = [];\n for (const [identifier, line] of imports) {\n const usage = usedIdentifiers.get(identifier);\n if (!usage || usage.length === 0) {\n unused.push({ identifier, line, type: \"unused\" });\n }\n }\n\n return { missing: [], unused };\n}\n\n/**\n * Main entry point - analyzes imports based on file type\n */\nexport function analyzeImports(filePath: string): ImportAnalysisResult {\n if (filePath.endsWith(\".py\")) {\n return analyzePythonImports(filePath);\n } else if (filePath.match(/\\.(js|jsx|ts|tsx)$/)) {\n return analyzeJavaScriptImports(filePath);\n }\n\n return { missing: [], unused: [] };\n}\n","/**\n * Docker Compose dependency analyzer\n * Parses docker-compose files and Dockerfiles to build service dependency graph\n */\n\nimport { readFileSync, existsSync } from \"fs\";\nimport { load as parseYaml } from \"js-yaml\";\nimport { join } from \"path\";\n\n/**\n * Parse Dockerfile to extract CMD or ENTRYPOINT\n */\nfunction parseDockerfile(dockerfilePath: string): string | null {\n if (!existsSync(dockerfilePath)) {\n return null;\n }\n\n const content = readFileSync(dockerfilePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n // Look for CMD or ENTRYPOINT (skip HEALTHCHECK lines)\n let inHealthCheck = false;\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Track if we're in a HEALTHCHECK block\n if (line.includes(\"HEALTHCHECK\")) {\n inHealthCheck = true;\n continue;\n }\n\n // If we were in a HEALTHCHECK and this line doesn't continue it, exit HEALTHCHECK mode\n if (inHealthCheck && !line.startsWith(\" \") && !line.startsWith(\"\\t\")) {\n inHealthCheck = false;\n }\n\n // Skip CMD lines that are part of HEALTHCHECK\n if (inHealthCheck) {\n continue;\n }\n\n // CMD [\"node\", \"server.js\"]\n if (trimmed.startsWith(\"CMD\")) {\n const match = trimmed.match(/CMD\\s+\\[([^\\]]+)\\]/);\n if (match) {\n const parts = match[1].split(\",\").map((p) => p.trim().replace(/\"/g, \"\"));\n const commandStr = parts.join(\" \");\n return extractEntryPointFromCommand(commandStr);\n }\n\n // CMD node server.js\n const shellMatch = trimmed.match(/CMD\\s+(.+)/);\n if (shellMatch) {\n return extractEntryPointFromCommand(shellMatch[1]);\n }\n }\n\n // ENTRYPOINT [\"node\", \"server.js\"]\n if (trimmed.startsWith(\"ENTRYPOINT\")) {\n const match = trimmed.match(/ENTRYPOINT\\s+\\[([^\\]]+)\\]/);\n if (match) {\n const parts = match[1].split(\",\").map((p) => p.trim().replace(/\"/g, \"\"));\n const commandStr = parts.join(\" \");\n return extractEntryPointFromCommand(commandStr);\n }\n }\n }\n\n return null;\n}\n\n/**\n * Extract entry point file from a command string\n */\nfunction extractEntryPointFromCommand(command: string | string[]): string | null {\n const commandStr = Array.isArray(command) ? command.join(\" \") : command;\n\n // Match patterns like: node server.js, python -m backend.api, uvicorn main:app\n const patterns = [\n /node\\s+([^\\s]+\\.js)/,\n /python\\s+-m\\s+([\\w.]+)/,\n /python\\s+([^\\s]+\\.py)/,\n /uvicorn\\s+([\\w:]+)/,\n /npm\\s+start/,\n ];\n\n for (const pattern of patterns) {\n const match = commandStr.match(pattern);\n if (match) {\n const entryFile = match[1];\n\n // Convert to file path\n if (entryFile.endsWith(\".js\") || entryFile.endsWith(\".py\")) {\n return entryFile;\n } else if (entryFile.includes(\":\")) {\n // uvicorn main:app -> main.py\n const file = entryFile.split(\":\")[0];\n return `${file}.py`;\n } else {\n // python -m backend.api -> backend/api.py\n const file = entryFile.replace(/\\./g, \"/\");\n return `${file}.py`;\n }\n }\n }\n\n return null;\n}\n\nexport interface DockerService {\n name: string;\n dependsOn: string[];\n volumes: string[];\n entryPoint?: string;\n command?: string;\n}\n\nexport interface DockerDependencyGraph {\n services: Map<string, DockerService>;\n entryPoints: Map<string, string>; // service name -> entry point file path\n}\n\n/**\n * Parse docker-compose.yaml and build service dependency graph\n */\nexport function parseDockerCompose(projectRoot: string): DockerDependencyGraph {\n const graph: DockerDependencyGraph = {\n services: new Map(),\n entryPoints: new Map(),\n };\n\n // Find docker-compose files\n const composeFiles = [\n join(projectRoot, \"docker-compose.yaml\"),\n join(projectRoot, \"docker-compose.yml\"),\n join(projectRoot, \"compose.yaml\"),\n join(projectRoot, \"compose.yml\"),\n ];\n\n let composeData: any = null;\n\n for (const file of composeFiles) {\n if (existsSync(file)) {\n const content = readFileSync(file, \"utf-8\");\n composeData = parseYaml(content) as any;\n break;\n }\n }\n\n if (!composeData || !composeData.services) {\n return graph;\n }\n\n // Parse each service\n for (const [serviceName, serviceConfig] of Object.entries(composeData.services)) {\n const config = serviceConfig as any;\n\n const service: DockerService = {\n name: serviceName,\n dependsOn: [],\n volumes: [],\n entryPoint: config.entrypoint,\n command: config.command,\n };\n\n // Extract depends_on\n if (config.depends_on) {\n if (Array.isArray(config.depends_on)) {\n service.dependsOn = config.depends_on;\n } else if (typeof config.depends_on === \"object\") {\n service.dependsOn = Object.keys(config.depends_on);\n }\n }\n\n // Extract volumes\n if (config.volumes && Array.isArray(config.volumes)) {\n service.volumes = config.volumes\n .filter((v: string) => typeof v === \"string\")\n .map((v: string) => v.split(\":\")[0]);\n }\n\n // Try to detect entry point file from docker-compose command\n if (config.command) {\n const entryFile = extractEntryPointFromCommand(config.command);\n if (entryFile) {\n graph.entryPoints.set(serviceName, entryFile);\n }\n }\n\n // If no command in docker-compose, check Dockerfile\n if (!graph.entryPoints.has(serviceName) && config.build) {\n const buildContext = typeof config.build === \"string\" ? config.build : config.build.context;\n if (buildContext) {\n const dockerfilePath = join(projectRoot, buildContext, \"Dockerfile\");\n const entryFile = parseDockerfile(dockerfilePath);\n if (entryFile) {\n graph.entryPoints.set(serviceName, entryFile);\n }\n }\n }\n\n graph.services.set(serviceName, service);\n }\n\n return graph;\n}\n\n/**\n * Find which services depend on a given service\n */\nexport function findDependentServices(\n graph: DockerDependencyGraph,\n serviceName: string\n): string[] {\n const dependents: string[] = [];\n\n for (const [name, service] of graph.services) {\n if (service.dependsOn.includes(serviceName)) {\n dependents.push(name);\n }\n }\n\n return dependents;\n}\n\n/**\n * Calculate blast radius for a service failure\n */\nexport function calculateServiceBlastRadius(\n graph: DockerDependencyGraph,\n serviceName: string\n): string[] {\n const affected = new Set<string>();\n const queue = [serviceName];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (affected.has(current)) continue;\n\n affected.add(current);\n\n // Find services that depend on this one\n const dependents = findDependentServices(graph, current);\n queue.push(...dependents);\n }\n\n return Array.from(affected);\n}\n"],"mappings":"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","names":["resolve","join","existsSync","readFileSync","lines","fileNode","Parser","Parser","lines","fileNode","resolve","join","relative","readFileSync","readFileSync","existsSync","join","resolve","join","relative","join","existsSync","readFileSync","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli-flow.ts","../src/flow/builder.ts","../src/analysis/class-hierarchy.ts","../src/flow/enhanced-resolver.ts","../src/parsers/base.ts","../src/parsers/typescript.ts","../src/parsers/python.ts","../src/parsers/index.ts","../src/flow/phase3-analyzer.ts","../src/analysis/property-tracker.ts","../src/analysis/return-analyzer.ts","../src/flow/storage-queries-phase3.ts","../src/types.ts","../src/commands/impact.ts","../src/utils/git.ts","../src/analysis/imports.ts","../src/analysis/docker.ts","../src/analysis/line-diff.ts","../src/analysis/removed-calls.ts","../src/analysis/removed-call-impact.ts"],"sourcesContent":["/**\n * CodeMap Flow Edition - Simplified CLI\n * Only 2 commands: index and mcp-server\n */\n\nimport { Command } from \"commander\";\nimport { resolve, join } from \"path\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { FlowBuilder, FlowStorage } from \"./flow/index.js\";\nimport { DEFAULT_CONFIG } from \"./types.js\";\nimport { analyzeImpact } from \"./commands/impact.js\";\nimport { isGitRepository, getGitStatus } from \"./utils/git.js\";\n\n// Import parsers to register them\nimport \"./parsers/index.js\";\n\nconst program = new Command();\n\n/**\n * Configure MCP server in Claude Code config\n */\nfunction configureMCPServer(projectPath: string): boolean {\n try {\n const claudeConfigPath = join(homedir(), \".claude\", \"config.json\");\n\n if (!existsSync(claudeConfigPath)) {\n return false;\n }\n\n const config = JSON.parse(readFileSync(claudeConfigPath, \"utf-8\"));\n\n if (!config.mcpServers) {\n config.mcpServers = {};\n }\n\n // Add or update codemap server\n config.mcpServers.codemap = {\n command: \"npx\",\n args: [\"codemap-ai\", \"mcp-server\", \"--path\", projectPath],\n };\n\n writeFileSync(claudeConfigPath, JSON.stringify(config, null, 2));\n return true;\n } catch (error) {\n return false;\n }\n}\n\nprogram\n .name(\"codemap\")\n .description(\"CodeMap Flow - Call graph analyzer for understanding code impact\")\n .version(\"3.5.0\");\n\n// ============ Index Command ============\n\nprogram\n .command(\"index\")\n .description(\"Build call graph for your codebase\")\n .argument(\"[path]\", \"Path to the project root\", \".\")\n .option(\"-f, --force\", \"Force reindex all files (ignore cache)\")\n .option(\"--include <patterns...>\", \"Glob patterns to include\")\n .option(\"--exclude <patterns...>\", \"Glob patterns to exclude\")\n .action(async (path: string, options) => {\n const rootPath = resolve(path);\n const outputDir = join(rootPath, \".codemap\");\n\n console.log(chalk.blue.bold(\"\\n CodeMap Call Graph Indexer\\n\"));\n console.log(chalk.gray(` Project: ${rootPath}\\n`));\n\n // Create output directory\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n const dbPath = join(outputDir, \"graph.db\");\n const storage = new FlowStorage(dbPath);\n\n const builder = new FlowBuilder(storage, {\n rootPath,\n include: options.include || DEFAULT_CONFIG.include!,\n exclude: options.exclude || DEFAULT_CONFIG.exclude!,\n forceReindex: options.force || false,\n });\n\n const spinner = ora(\"Discovering files...\").start();\n\n builder.setProgressCallback((progress) => {\n switch (progress.phase) {\n case \"discovering\":\n spinner.text = \"Discovering files...\";\n break;\n case \"parsing\":\n spinner.text = `Parsing (${progress.current}/${progress.total}): ${progress.currentFile}`;\n break;\n case \"resolving\":\n spinner.text = \"Resolving cross-file calls...\";\n break;\n case \"complete\":\n spinner.succeed(chalk.green(\"Indexing complete!\"));\n break;\n }\n });\n\n try {\n const result = await builder.build();\n\n console.log(chalk.blue(\"\\n Results:\\n\"));\n console.log(` ${chalk.bold(\"Indexed:\")} ${result.indexed} files`);\n console.log(` ${chalk.bold(\"Skipped:\")} ${result.skipped} files (unchanged)`);\n console.log(` ${chalk.bold(\"Resolved:\")} ${result.resolved} function calls`);\n console.log(` ${chalk.bold(\"Unresolved:\")} ${result.unresolved} calls (external/dynamic)`);\n\n // Show enhanced stats\n const stats = storage.getStats();\n if (stats.httpEndpoints > 0) {\n console.log(chalk.cyan(`\\n ${chalk.bold(\"Framework Detection:\")}`));\n console.log(` ${chalk.bold(\"HTTP Endpoints:\")} ${stats.httpEndpoints} routes detected`);\n console.log(` ${chalk.bold(\"Dependencies:\")} ${stats.resolvedDependencies}/${stats.frameworkDependencies} resolved (FastAPI Depends)`);\n }\n\n if (result.errors.length > 0) {\n console.log(chalk.yellow(`\\n Errors: ${result.errors.length} files failed`));\n for (const err of result.errors.slice(0, 5)) {\n console.log(chalk.gray(` - ${err}`));\n }\n if (result.errors.length > 5) {\n console.log(chalk.gray(` ... and ${result.errors.length - 5} more`));\n }\n }\n\n const resolveRate = result.resolved + result.unresolved > 0\n ? Math.round((result.resolved / (result.resolved + result.unresolved)) * 100)\n : 0;\n const dependencyRate = stats.frameworkDependencies > 0\n ? Math.round((stats.resolvedDependencies / stats.frameworkDependencies) * 100)\n : 0;\n\n console.log(chalk.gray(`\\n Call resolution rate: ${resolveRate}%`));\n if (stats.frameworkDependencies > 0) {\n console.log(chalk.gray(` Dependency resolution rate: ${dependencyRate}%`));\n }\n console.log(chalk.gray(` Database saved to: ${dbPath}\\n`));\n\n console.log(chalk.cyan(\" Next steps:\"));\n console.log(chalk.gray(\" • Configure MCP server: claude mcp add codemap -- npx codemap-ai mcp-server\"));\n console.log(chalk.gray(\" • Ask Claude: 'What would break if I change authenticate_user?'\\n\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Indexing failed\"));\n console.error(error);\n process.exit(1);\n } finally {\n storage.close();\n }\n });\n\n// ============ Init Command ============\n\nprogram\n .command(\"init\")\n .description(\"Initialize CodeMap (index + setup MCP)\")\n .argument(\"[path]\", \"Path to the project root\", \".\")\n .option(\"--include <patterns...>\", \"Glob patterns to include\")\n .option(\"--exclude <patterns...>\", \"Glob patterns to exclude\")\n .option(\"--skip-mcp\", \"Skip MCP server configuration\")\n .action(async (path: string, options) => {\n const rootPath = resolve(path);\n const outputDir = join(rootPath, \".codemap\");\n\n console.log(chalk.blue.bold(\"\\n CodeMap Initialization\\n\"));\n console.log(chalk.gray(` Project: ${rootPath}\\n`));\n\n // Check if already initialized\n if (existsSync(join(outputDir, \"graph.db\")) && !options.force) {\n console.log(chalk.yellow(\" Already initialized. Use 'codemap reindex' to rebuild.\\n\"));\n return;\n }\n\n // Create output directory\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n const dbPath = join(outputDir, \"graph.db\");\n const storage = new FlowStorage(dbPath);\n\n const builder = new FlowBuilder(storage, {\n rootPath,\n include: options.include || DEFAULT_CONFIG.include!,\n exclude: options.exclude || DEFAULT_CONFIG.exclude!,\n forceReindex: true,\n });\n\n const spinner = ora(\"Indexing codebase...\").start();\n\n builder.setProgressCallback((progress) => {\n switch (progress.phase) {\n case \"discovering\":\n spinner.text = \"Discovering files...\";\n break;\n case \"parsing\":\n spinner.text = `Parsing (${progress.current}/${progress.total}): ${progress.currentFile}`;\n break;\n case \"resolving\":\n spinner.text = \"Resolving cross-file calls...\";\n break;\n case \"complete\":\n spinner.succeed(chalk.green(\"Indexing complete!\"));\n break;\n }\n });\n\n try {\n const result = await builder.build();\n\n console.log(chalk.blue(\"\\n Results:\\n\"));\n console.log(` ${chalk.bold(\"Indexed:\")} ${result.indexed} files`);\n console.log(` ${chalk.bold(\"Resolved:\")} ${result.resolved} function calls`);\n\n const stats = storage.getStats();\n if (stats.httpEndpoints > 0) {\n console.log(chalk.cyan(`\\n ${chalk.bold(\"Framework Detection:\")}`));\n console.log(` ${chalk.bold(\"HTTP Endpoints:\")} ${stats.httpEndpoints} routes`);\n }\n\n const resolveRate = result.resolved + result.unresolved > 0\n ? Math.round((result.resolved / (result.resolved + result.unresolved)) * 100)\n : 0;\n\n console.log(chalk.gray(`\\n Call resolution: ${resolveRate}%`));\n console.log(chalk.gray(` Database: ${dbPath}\\n`));\n\n // Configure MCP server\n if (!options.skipMcp) {\n const mcpConfigured = configureMCPServer(rootPath);\n if (mcpConfigured) {\n console.log(chalk.green(\" ✓ MCP server configured in Claude Code\\n\"));\n } else {\n console.log(chalk.yellow(\" ⚠ Could not auto-configure MCP (Claude Code not found)\"));\n console.log(chalk.gray(\" Run manually: claude mcp add codemap -- npx codemap-ai mcp-server\\n\"));\n }\n }\n\n console.log(chalk.cyan(\" Ready!\"));\n console.log(chalk.gray(\" Ask Claude: 'What would break if I change authenticate_user?'\\n\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Initialization failed\"));\n console.error(error);\n process.exit(1);\n } finally {\n storage.close();\n }\n });\n\n// ============ Impact Command ============\n\nprogram\n .command(\"impact\")\n .description(\"Analyze impact of code changes\")\n .argument(\"[path]\", \"Path to the project root\", \".\")\n .option(\"-v, --verbose\", \"Show detailed output\")\n .action(async (path: string, options) => {\n const rootPath = resolve(path);\n const dbPath = join(rootPath, \".codemap\", \"graph.db\");\n\n console.log(chalk.blue.bold(\"\\n CodeMap Impact Analysis\\n\"));\n\n if (!existsSync(dbPath)) {\n console.log(chalk.red(\" Error: Not initialized. Run 'codemap init' first.\\n\"));\n process.exit(1);\n }\n\n // Check for changes\n const spinner = ora(\"Detecting changes...\").start();\n\n try {\n const result = await analyzeImpact({ path: rootPath, verbose: options.verbose });\n\n if (result.changedFiles.length === 0) {\n spinner.succeed(chalk.green(\"No changes detected\"));\n console.log(chalk.gray(\" All files are up to date.\\n\"));\n return;\n }\n\n spinner.succeed(chalk.green(`Detected ${result.changedFiles.length} modified files`));\n\n // Show changed files\n console.log(chalk.blue(\"\\n Modified Files:\\n\"));\n for (const file of result.changedFiles.slice(0, 10)) {\n console.log(chalk.gray(` • ${file}`));\n }\n if (result.changedFiles.length > 10) {\n console.log(chalk.gray(` ... and ${result.changedFiles.length - 10} more`));\n }\n\n // Show changed functions (if available from git)\n if (result.changedFunctions.length > 0) {\n console.log(chalk.blue(\"\\n Changed Functions:\\n\"));\n for (const func of result.changedFunctions) {\n console.log(chalk.gray(` • ${func.functionName} (${func.file}:${func.lineNumber})`));\n }\n }\n\n // Show impact\n if (result.directCallers.size > 0) {\n console.log(chalk.blue(\"\\n Impact Analysis:\\n\"));\n for (const [funcName, callers] of result.directCallers.entries()) {\n console.log(chalk.yellow(` ${funcName}:`));\n console.log(chalk.gray(` ${callers.length} direct callers`));\n if (options.verbose) {\n for (const caller of callers.slice(0, 5)) {\n console.log(chalk.gray(` • ${caller.name} (${caller.file}:${caller.line})`));\n }\n if (callers.length > 5) {\n console.log(chalk.gray(` ... and ${callers.length - 5} more`));\n }\n }\n }\n }\n\n // Show affected endpoints\n if (result.affectedEndpoints.length > 0) {\n console.log(chalk.blue(\"\\n Affected HTTP Endpoints:\\n\"));\n for (const endpoint of result.affectedEndpoints) {\n console.log(chalk.gray(` • ${endpoint}`));\n }\n }\n\n // NEW: Show import issues\n if (result.importIssues.size > 0) {\n console.log(chalk.blue(\"\\n 🔍 Import Analysis:\\n\"));\n for (const [file, issues] of result.importIssues.entries()) {\n if (issues.missing.length > 0) {\n console.log(chalk.red(` ❌ CRITICAL: ${file} - Missing imports still in use:`));\n for (const missing of issues.missing.slice(0, 10)) {\n const usageInfo = missing.usedAt ? ` (used at lines: ${missing.usedAt.slice(0, 3).join(\", \")}${missing.usedAt.length > 3 ? \"...\" : \"\"})` : \"\";\n console.log(chalk.gray(` • ${missing.identifier}${usageInfo}`));\n }\n if (issues.missing.length > 10) {\n console.log(chalk.gray(` ... and ${issues.missing.length - 10} more`));\n }\n }\n if (issues.unused.length > 0 && options.verbose) {\n console.log(chalk.yellow(` ⚠️ ${file} - Unused imports:`));\n for (const unused of issues.unused.slice(0, 3)) {\n console.log(chalk.gray(` • ${unused.identifier} (line ${unused.line})`));\n }\n }\n }\n }\n\n // NEW: Show removed call impacts\n if (result.removedCallImpacts && result.removedCallImpacts.length > 0) {\n console.log(chalk.blue(\"\\n 🚨 Removed Function Calls:\\n\"));\n\n for (const impact of result.removedCallImpacts) {\n // Color by severity\n const severityColors = {\n 'CRITICAL': chalk.red,\n 'HIGH': chalk.red,\n 'MEDIUM': chalk.yellow,\n 'LOW': chalk.gray,\n };\n const severityColor = severityColors[impact.severity];\n\n console.log(severityColor(` ${impact.severity}: ${impact.removedCall.callee}()`));\n console.log(chalk.gray(` Removed from: ${impact.removedCall.removedFrom}() at line ${impact.removedCall.lineNumber}`));\n console.log(chalk.gray(` File: ${impact.removedCall.file}`));\n\n if (impact.stillCalledBy.length === 0) {\n console.log(chalk.red(` ⚠️ ORPHANED: No longer called anywhere!`));\n } else {\n const callerNames = impact.stillCalledBy.slice(0, 3).map(c => c.name).join(', ');\n const moreCount = impact.stillCalledBy.length > 3 ? ` and ${impact.stillCalledBy.length - 3} more` : '';\n console.log(chalk.gray(` Still called by: ${callerNames}${moreCount}`));\n }\n\n if (impact.impactedFunctions.length > 0) {\n console.log(chalk.gray(` Impact: ${impact.impactedFunctions.length} dependent function${impact.impactedFunctions.length === 1 ? '' : 's'}`));\n\n // Show top 3 impacted functions\n const topImpacted = impact.impactedFunctions.slice(0, 3);\n for (const func of topImpacted) {\n console.log(chalk.gray(` • ${func.name} (${func.file}:${func.line})`));\n }\n if (impact.impactedFunctions.length > 3) {\n console.log(chalk.gray(` ... and ${impact.impactedFunctions.length - 3} more`));\n }\n }\n\n if (impact.severity === 'CRITICAL') {\n console.log(chalk.red(` 🔴 ${impact.description.split('\\n').pop()}`));\n }\n\n console.log(); // Blank line between impacts\n }\n }\n\n // NEW: Show Docker impact\n if (result.dockerImpact) {\n console.log(chalk.blue(\"\\n 📦 Docker Service Impact:\\n\"));\n console.log(chalk.red(` ⚠️ Entry point file(s) modified - service(s) will not start:`));\n for (const file of result.dockerImpact.entryPointFiles) {\n console.log(chalk.gray(` • ${file}`));\n }\n console.log(chalk.red(`\\n 💥 Affected Services (${result.dockerImpact.affectedServices.length}):`));\n for (const service of result.dockerImpact.affectedServices) {\n console.log(chalk.gray(` • ${service}`));\n }\n console.log(chalk.yellow(`\\n → If entry point crashes, these services WILL FAIL`));\n }\n\n // Show risk level\n console.log(chalk.blue(\"\\n Risk Assessment:\\n\"));\n const riskColor = result.riskLevel === \"CRITICAL\"\n ? chalk.red.bold\n : result.riskLevel === \"HIGH\"\n ? chalk.red\n : result.riskLevel === \"MEDIUM\"\n ? chalk.yellow\n : chalk.green;\n console.log(` ${riskColor(result.riskLevel)} - ${result.totalImpact} components affected`);\n\n if (result.riskLevel === \"CRITICAL\") {\n console.log(chalk.red.bold(\"\\n ⚠️ DO NOT DEPLOY - System-wide failure risk\"));\n console.log(chalk.gray(\" Fix critical issues before proceeding\"));\n } else if (result.riskLevel === \"HIGH\") {\n console.log(chalk.yellow(\"\\n ⚠️ High risk - Extensive testing required\"));\n }\n\n console.log();\n } catch (error) {\n spinner.fail(chalk.red(\"Impact analysis failed\"));\n console.error(error);\n process.exit(1);\n }\n });\n\n// ============ Reindex Command ============\n\nprogram\n .command(\"reindex\")\n .description(\"Force full re-index of codebase\")\n .argument(\"[path]\", \"Path to the project root\", \".\")\n .option(\"--include <patterns...>\", \"Glob patterns to include\")\n .option(\"--exclude <patterns...>\", \"Glob patterns to exclude\")\n .action(async (path: string, options) => {\n // Just call index with force flag\n const indexCommand = program.commands.find((cmd) => cmd.name() === \"index\");\n if (indexCommand) {\n await indexCommand.parseAsync([path, \"--force\", ...(options.include ? [\"--include\", ...options.include] : []), ...(options.exclude ? [\"--exclude\", ...options.exclude] : [])], { from: \"user\" });\n }\n });\n\n// ============ MCP Server Command ============\n\nprogram\n .command(\"mcp-server\")\n .description(\"Start MCP server for Claude Code integration\")\n .option(\"-p, --path <path>\", \"Project root path\", \".\")\n .action(async (options) => {\n process.env.CODEMAP_PROJECT_ROOT = resolve(options.path);\n process.env.CODEMAP_DB_PATH = join(resolve(options.path), \".codemap\", \"graph.db\");\n\n // Start the flow MCP server\n await import(\"./mcp/flow-server.js\");\n });\n\n// Parse and run\nprogram.parse();\n","/**\n * Flow Builder - Builds call graphs with resolved references\n * Core implementation for CodeMap Flow Edition\n */\n\nimport { readFileSync, statSync } from \"fs\";\nimport { createHash } from \"crypto\";\nimport { glob } from \"glob\";\nimport { resolve, relative, dirname, basename, extname } from \"path\";\nimport { FlowStorage } from \"./storage.js\";\nimport { EnhancedResolver } from \"./enhanced-resolver.js\";\nimport { parserRegistry } from \"../parsers/index.js\";\nimport type { FileAnalysis, GraphNode, GraphEdge } from \"../types.js\";\nimport { analyzeDataFlow, getPhase3Stats } from \"./builder-phase3.js\";\nimport { analyzeFileForPhase3 } from \"./phase3-analyzer.js\";\n\nexport interface FlowConfig {\n rootPath: string;\n include: string[];\n exclude: string[];\n forceReindex: boolean;\n}\n\nexport interface FlowProgress {\n phase: \"discovering\" | \"parsing\" | \"resolving\" | \"complete\";\n total: number;\n current: number;\n currentFile: string;\n}\n\nexport type ProgressCallback = (progress: FlowProgress) => void;\n\ninterface ModuleExports {\n [symbolName: string]: string; // symbol name → node ID\n}\n\nexport class FlowBuilder {\n private storage: FlowStorage;\n private config: FlowConfig;\n private onProgress?: ProgressCallback;\n private moduleMap = new Map<string, ModuleExports>(); // file path → exports\n private errors: string[] = [];\n\n constructor(storage: FlowStorage, config: FlowConfig) {\n this.storage = storage;\n this.config = config;\n }\n\n setProgressCallback(callback: ProgressCallback): void {\n this.onProgress = callback;\n }\n\n async build(): Promise<{\n indexed: number;\n skipped: number;\n resolved: number;\n unresolved: number;\n errors: string[];\n }> {\n const rootPath = resolve(this.config.rootPath);\n\n // Phase 1: Discover files\n this.emitProgress({\n phase: \"discovering\",\n total: 0,\n current: 0,\n currentFile: \"\",\n });\n\n const allFiles = await this.discoverFiles(rootPath);\n const filesToIndex: Array<{ path: string; hash: string }> = [];\n let skipped = 0;\n\n // Check which files need indexing\n for (const filePath of allFiles) {\n const content = readFileSync(filePath, \"utf-8\");\n const hash = this.hashContent(content);\n\n if (!this.config.forceReindex) {\n const existingHash = this.storage.getFileHash(filePath);\n if (existingHash === hash) {\n skipped++;\n continue;\n }\n }\n\n filesToIndex.push({ path: filePath, hash });\n }\n\n // Phase 2: Parse files and extract symbols\n let indexed = 0;\n for (const file of filesToIndex) {\n this.emitProgress({\n phase: \"parsing\",\n total: filesToIndex.length,\n current: indexed + 1,\n currentFile: relative(rootPath, file.path),\n });\n\n try {\n await this.parseAndStore(file.path, file.hash, rootPath);\n indexed++;\n } catch (error) {\n this.errors.push(`${relative(rootPath, file.path)}: ${error}`);\n }\n }\n\n // Phase 3: Resolve cross-file calls\n this.emitProgress({\n phase: \"resolving\",\n total: filesToIndex.length,\n current: filesToIndex.length,\n currentFile: \"\",\n });\n\n // First pass: Basic resolution (existing logic)\n this.resolveAllCalls();\n\n // Second pass: Enhanced resolution with type tracking\n const enhancedResolver = new EnhancedResolver(this.storage);\n enhancedResolver.buildHierarchy();\n const enhancedResolved = enhancedResolver.resolveAllCalls();\n\n // Log improvement\n if (enhancedResolved.length > 0) {\n console.log(`✨ Enhanced resolver: resolved ${enhancedResolved.length} additional calls`);\n }\n\n const stats = this.storage.getStats();\n\n this.emitProgress({\n phase: \"complete\",\n total: filesToIndex.length,\n current: filesToIndex.length,\n currentFile: \"\",\n });\n\n return {\n indexed,\n skipped,\n resolved: stats.resolvedCalls,\n unresolved: stats.unresolvedCalls,\n errors: this.errors,\n };\n }\n\n private async discoverFiles(rootPath: string): Promise<string[]> {\n const allFiles: string[] = [];\n\n for (const pattern of this.config.include) {\n const matches = await glob(pattern, {\n cwd: rootPath,\n absolute: true,\n ignore: this.config.exclude,\n nodir: true,\n });\n allFiles.push(...matches);\n }\n\n // Filter by supported extensions and size\n const supportedExts = new Set([\".py\", \".ts\", \".tsx\", \".js\", \".jsx\"]);\n const uniqueFiles = [...new Set(allFiles)].filter((f) => {\n const ext = extname(f);\n if (!supportedExts.has(ext)) return false;\n\n try {\n const stats = statSync(f);\n if (stats.size > 200000) return false; // Skip files > 200KB\n } catch {\n return false;\n }\n return true;\n });\n\n return uniqueFiles.sort();\n }\n\n private hashContent(content: string): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n }\n\n private async parseAndStore(filePath: string, hash: string, rootPath: string): Promise<void> {\n const language = this.getLanguage(filePath);\n const content = readFileSync(filePath, \"utf-8\");\n\n // Get parser for this language\n const parser = parserRegistry.getByLanguage(language);\n if (!parser) {\n throw new Error(`No parser found for language: ${language}`);\n }\n\n // Parse with tree-sitter\n const analysis = parser.parse(filePath, content);\n\n // Delete old data for this file\n this.storage.deleteFileData(filePath);\n\n // Store nodes with hashes\n const fileExports: ModuleExports = {};\n\n for (const node of analysis.nodes) {\n // Add hash to node\n const nodeHash = this.hashContent(`${node.name}:${node.startLine}:${node.endLine}`);\n const nodeWithHash = { ...node, hash: nodeHash };\n\n this.storage.insertNode(nodeWithHash);\n\n // Track exports (top-level functions and classes)\n if (node.type === \"function\" || node.type === \"class\") {\n fileExports[node.name] = node.id;\n this.storage.registerExport(filePath, node.name, node.id);\n }\n }\n\n // Store exports in module map\n this.moduleMap.set(filePath, fileExports);\n\n // Store edges (including unresolved refs)\n for (const edge of analysis.edges) {\n this.storage.insertEdge(edge);\n }\n\n // Store imports\n for (const imp of analysis.imports) {\n for (const spec of imp.specifiers) {\n this.storage.registerImport(filePath, spec, imp.source, imp.line);\n }\n }\n\n // Store variable types\n if (analysis.variableTypes) {\n for (const varType of analysis.variableTypes) {\n this.storage.registerVariableType(\n varType.variableName,\n varType.typeName,\n varType.scopeId,\n filePath,\n varType.line\n );\n }\n }\n\n // Phase 3: Analyze data flow for functions and methods\n const functionNodes = analysis.nodes\n .filter((n) => n.type === \"function\" || n.type === \"method\")\n .map((n) => ({\n id: n.id,\n name: n.name,\n startLine: n.startLine,\n endLine: n.endLine,\n }));\n\n if (functionNodes.length > 0) {\n analyzeFileForPhase3(filePath, functionNodes, this.storage.db);\n }\n\n // Store database operations\n if (analysis.databaseOperations) {\n for (const dbOp of analysis.databaseOperations) {\n this.storage.insertDatabaseOperation({\n id: `${dbOp.nodeId}:db:${dbOp.line}`,\n node_id: dbOp.nodeId,\n database_type: dbOp.databaseType,\n operation: dbOp.operation,\n collection: dbOp.collection,\n line: dbOp.line,\n });\n }\n }\n\n // Store file record\n this.storage.upsertFile(filePath, language, hash);\n\n // Process framework-specific patterns\n this.processFrameworkPatterns(analysis.nodes, filePath);\n }\n\n /**\n * Process framework-specific patterns (FastAPI routes, Depends, etc.)\n */\n private processFrameworkPatterns(nodes: GraphNode[], filePath: string): void {\n for (const node of nodes) {\n if (node.type === \"function\" && node.metadata) {\n // 1. Process FastAPI HTTP endpoints\n const httpEndpoint = node.metadata.httpEndpoint as { method: string; path: string } | undefined;\n if (httpEndpoint) {\n const endpointId = `${httpEndpoint.method}:${httpEndpoint.path}`;\n this.storage.insertHttpEndpoint({\n id: endpointId,\n method: httpEndpoint.method,\n path: httpEndpoint.path,\n handler_node_id: node.id,\n container_id: undefined, // Will be set when docker-compose is parsed\n metadata: {\n filePath,\n functionName: node.name,\n line: node.startLine,\n },\n });\n }\n\n // 2. Process FastAPI Depends() patterns\n const depends = node.metadata.depends as Array<{\n parameterName: string;\n dependencyName: string;\n line: number;\n }> | undefined;\n\n if (depends) {\n for (const dep of depends) {\n const depId = `${node.id}:depends:${dep.parameterName}`;\n this.storage.insertFrameworkDependency({\n id: depId,\n source_node_id: node.id,\n target_node_id: undefined, // Will be resolved later\n framework: \"fastapi\",\n pattern: \"depends\",\n parameter_name: dep.parameterName,\n line: dep.line,\n unresolved_name: dep.dependencyName,\n metadata: {\n filePath,\n functionName: node.name,\n },\n });\n }\n }\n }\n }\n }\n\n private resolveAllCalls(): void {\n // Get all unresolved edges (target_id starts with \"ref:\")\n const unresolvedEdges = this.storage.db\n .prepare(`SELECT * FROM edges WHERE target_id LIKE 'ref:%'`)\n .all() as Array<{\n id: string;\n source_id: string;\n target_id: string;\n type: string;\n metadata: string | null;\n }>;\n\n for (const edge of unresolvedEdges) {\n const refName = edge.target_id.replace(\"ref:\", \"\");\n const sourceNode = this.storage.getNode(edge.source_id);\n\n if (!sourceNode) continue;\n\n // Try to resolve the reference (pass source node ID for scope resolution)\n const resolvedId = this.resolveReference(sourceNode.filePath, refName, edge.source_id);\n\n if (resolvedId) {\n // Update edge with resolved target\n this.storage.insertEdge({\n id: edge.id,\n type: edge.type as GraphEdge[\"type\"],\n sourceId: edge.source_id,\n targetId: resolvedId,\n metadata: edge.metadata ? JSON.parse(edge.metadata) : undefined,\n });\n }\n }\n\n // Also resolve framework dependencies (FastAPI Depends)\n this.resolveFrameworkDependencies();\n }\n\n /**\n * Resolve framework dependencies (e.g., FastAPI Depends())\n */\n private resolveFrameworkDependencies(): void {\n const unresolvedDeps = this.storage.getAllUnresolvedDependencies();\n\n for (const dep of unresolvedDeps) {\n const sourceNode = this.storage.getNode(dep.source_node_id);\n if (!sourceNode) continue;\n\n // Try to resolve the dependency name to an actual node\n const resolvedId = this.resolveReference(sourceNode.filePath, dep.unresolved_name);\n\n if (resolvedId) {\n // Update the dependency with resolved target\n this.storage.updateFrameworkDependencyTarget(dep.id, resolvedId);\n\n // Also create an edge for the call graph\n this.storage.insertEdge({\n id: `${dep.id}:edge`,\n type: \"calls\",\n sourceId: dep.source_node_id,\n targetId: resolvedId,\n metadata: {\n framework: \"fastapi\",\n pattern: \"depends\",\n line: dep.line,\n },\n });\n }\n }\n }\n\n private resolveReference(sourceFilePath: string, refName: string, scopeNodeId?: string): string | null {\n // Strategy 0a: Handle super() calls\n if (refName.startsWith(\"super().\") && scopeNodeId) {\n const methodName = refName.replace(\"super().\", \"\");\n const resolvedSuper = this.storage.resolveSuperMethod(methodName, scopeNodeId);\n if (resolvedSuper) {\n return resolvedSuper;\n }\n }\n\n // Strategy 0b: Handle attribute calls (variable.method or ClassName.method)\n if (refName.includes(\".\")) {\n const parts = refName.split(\".\");\n if (parts.length === 2) {\n const [objectName, methodName] = parts;\n\n // Try variable.method resolution first (if we have scope)\n if (scopeNodeId) {\n const resolvedVarMethod = this.storage.resolveVariableMethod(objectName, methodName, scopeNodeId);\n if (resolvedVarMethod) {\n return resolvedVarMethod;\n }\n }\n\n // Fall back to ClassName.method resolution\n const resolvedClassMethod = this.storage.resolveClassMethod(objectName, methodName, sourceFilePath);\n if (resolvedClassMethod) {\n return resolvedClassMethod;\n }\n }\n }\n\n // Strategy 1: Look in the same file\n const nodesInFile = this.storage.getNodesByFile(sourceFilePath);\n for (const node of nodesInFile) {\n if (node.name === refName) {\n return node.id;\n }\n }\n\n // Strategy 2: Check imports\n const resolvedFromImport = this.storage.resolveImport(sourceFilePath, refName);\n if (resolvedFromImport) {\n return resolvedFromImport;\n }\n\n // Strategy 3: Search all nodes (fallback)\n const matches = this.storage.searchNodesByName(refName);\n if (matches.length === 1) {\n return matches[0].id;\n }\n\n return null;\n }\n\n private getLanguage(filePath: string): string {\n const ext = extname(filePath);\n if (ext === \".py\") return \"python\";\n if (ext === \".ts\" || ext === \".tsx\") return \"typescript\";\n if (ext === \".js\" || ext === \".jsx\") return \"javascript\";\n return \"unknown\";\n }\n\n private emitProgress(progress: FlowProgress): void {\n if (this.onProgress) {\n this.onProgress(progress);\n }\n }\n}\n","/**\n * Class Hierarchy Builder\n * Builds inheritance trees for improved method resolution\n */\n\nimport type { FlowNode } from \"../graph/types.js\";\n\nexport interface ClassNode {\n id: string; // Node ID\n name: string; // Class name\n file: string; // File path\n line: number; // Start line\n extends: string[]; // Parent class names\n methods: string[]; // Method names defined in this class\n}\n\nexport interface ClassHierarchy {\n classes: Map<string, ClassNode>; // class_name -> ClassNode\n children: Map<string, string[]>; // parent_name -> [child_name, ...]\n parents: Map<string, string[]>; // child_name -> [parent_name, ...]\n}\n\n/**\n * Build class hierarchy from flow nodes\n */\nexport function buildClassHierarchy(nodes: FlowNode[]): ClassHierarchy {\n const classes = new Map<string, ClassNode>();\n const children = new Map<string, string[]>();\n const parents = new Map<string, string[]>();\n\n // Step 1: Collect all class nodes\n for (const node of nodes) {\n if (node.type === \"class\") {\n const classNode: ClassNode = {\n id: node.id,\n name: node.name,\n file: node.filePath,\n line: node.startLine,\n extends: node.extends || [],\n methods: [], // Will populate in next step\n };\n\n classes.set(node.name, classNode);\n }\n }\n\n // Step 2: Find methods for each class\n for (const node of nodes) {\n if (node.type === \"method\" && node.parentClass) {\n const classNode = classes.get(node.parentClass);\n if (classNode) {\n classNode.methods.push(node.name);\n }\n }\n }\n\n // Step 3: Build parent-child relationships\n for (const [className, classNode] of classes) {\n for (const parentName of classNode.extends) {\n // Add to children map (parent -> children)\n if (!children.has(parentName)) {\n children.set(parentName, []);\n }\n children.get(parentName)!.push(className);\n\n // Add to parents map (child -> parents)\n if (!parents.has(className)) {\n parents.set(className, []);\n }\n parents.get(className)!.push(parentName);\n }\n }\n\n return {\n classes,\n children,\n parents,\n };\n}\n\n/**\n * Get all methods available for a class (including inherited)\n */\nexport function getAvailableMethods(\n className: string,\n hierarchy: ClassHierarchy\n): string[] {\n const methods = new Set<string>();\n const visited = new Set<string>();\n\n // BFS up the inheritance chain\n const queue = [className];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n // Add methods from current class\n const classNode = hierarchy.classes.get(current);\n if (classNode) {\n for (const method of classNode.methods) {\n methods.add(method);\n }\n\n // Add parent classes to queue\n const parentNames = hierarchy.parents.get(current) || [];\n for (const parent of parentNames) {\n queue.push(parent);\n }\n }\n }\n\n return Array.from(methods);\n}\n\n/**\n * Find which class defines a method (searching up inheritance chain)\n */\nexport function findMethodDefinition(\n className: string,\n methodName: string,\n hierarchy: ClassHierarchy\n): ClassNode | null {\n const visited = new Set<string>();\n const queue = [className];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n const classNode = hierarchy.classes.get(current);\n if (classNode) {\n // Check if this class defines the method\n if (classNode.methods.includes(methodName)) {\n return classNode;\n }\n\n // Search parent classes\n const parentNames = hierarchy.parents.get(current) || [];\n for (const parent of parentNames) {\n queue.push(parent);\n }\n }\n }\n\n return null;\n}\n\n/**\n * Check if a class inherits from another class\n */\nexport function inheritsFrom(\n childClass: string,\n parentClass: string,\n hierarchy: ClassHierarchy\n): boolean {\n const visited = new Set<string>();\n const queue = [childClass];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n if (current === parentClass) {\n return true;\n }\n\n // Check parents\n const parentNames = hierarchy.parents.get(current) || [];\n for (const parent of parentNames) {\n queue.push(parent);\n }\n }\n\n return false;\n}\n\n/**\n * Get all descendants of a class\n */\nexport function getDescendants(\n className: string,\n hierarchy: ClassHierarchy\n): string[] {\n const descendants: string[] = [];\n const visited = new Set<string>();\n const queue = [className];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n // Add children\n const childNames = hierarchy.children.get(current) || [];\n for (const child of childNames) {\n descendants.push(child);\n queue.push(child);\n }\n }\n\n return descendants;\n}\n\n/**\n * Get the full inheritance chain for a class\n */\nexport function getInheritanceChain(\n className: string,\n hierarchy: ClassHierarchy\n): string[] {\n const chain: string[] = [className];\n const visited = new Set<string>();\n let current = className;\n\n while (true) {\n if (visited.has(current)) {\n break;\n }\n visited.add(current);\n\n const parentNames = hierarchy.parents.get(current) || [];\n if (parentNames.length === 0) {\n break;\n }\n\n // Take first parent (for simplicity, handle multiple inheritance later)\n const parent = parentNames[0];\n chain.push(parent);\n current = parent;\n }\n\n return chain;\n}\n\n/**\n * Resolve method call on a class instance\n * Returns the class node that defines the method\n */\nexport function resolveMethodCall(\n instanceType: string,\n methodName: string,\n hierarchy: ClassHierarchy\n): ClassNode | null {\n return findMethodDefinition(instanceType, methodName, hierarchy);\n}\n\n/**\n * Get statistics about class hierarchy\n */\nexport function getHierarchyStats(hierarchy: ClassHierarchy): {\n totalClasses: number;\n classesWithParents: number;\n classesWithChildren: number;\n maxDepth: number;\n} {\n const totalClasses = hierarchy.classes.size;\n const classesWithParents = hierarchy.parents.size;\n const classesWithChildren = hierarchy.children.size;\n\n // Calculate max depth\n let maxDepth = 0;\n for (const className of hierarchy.classes.keys()) {\n const chain = getInheritanceChain(className, hierarchy);\n maxDepth = Math.max(maxDepth, chain.length);\n }\n\n return {\n totalClasses,\n classesWithParents,\n classesWithChildren,\n maxDepth,\n };\n}\n","/**\n * Enhanced Call Resolver\n * Resolves method calls using type information and class hierarchy\n */\n\nimport type { FlowStorage } from \"./storage.js\";\nimport type { GraphNode, GraphEdge } from \"../types.js\";\nimport type { VariableType } from \"../analysis/type-tracker.js\";\nimport {\n buildClassHierarchy,\n resolveMethodCall,\n type ClassHierarchy,\n} from \"../analysis/class-hierarchy.js\";\n\nexport interface ResolvedCall {\n originalEdge: GraphEdge;\n targetNode: GraphNode | null;\n confidence: \"HIGH\" | \"MEDIUM\" | \"LOW\";\n reason: string;\n}\n\n/**\n * Enhanced resolver that uses type tracking and class hierarchy\n */\nexport class EnhancedResolver {\n private hierarchy: ClassHierarchy | null = null;\n private variableTypes: Map<string, VariableType[]> = new Map();\n\n constructor(private storage: FlowStorage) {}\n\n /**\n * Build class hierarchy from all nodes in storage\n */\n buildHierarchy(): void {\n const nodes = this.getAllNodes();\n this.hierarchy = buildClassHierarchy(nodes);\n }\n\n /**\n * Load variable type information from storage\n */\n loadVariableTypes(): void {\n const stmt = this.storage.db.prepare(`\n SELECT * FROM variable_types\n `);\n\n const rows = stmt.all() as Array<{\n id: string;\n variable_name: string;\n type_name: string;\n scope_node_id: string;\n file_path: string;\n line: number;\n }>;\n\n for (const row of rows) {\n const scopeId = row.scope_node_id;\n if (!this.variableTypes.has(scopeId)) {\n this.variableTypes.set(scopeId, []);\n }\n\n this.variableTypes.get(scopeId)!.push({\n name: row.variable_name,\n type: row.type_name,\n scope: scopeId,\n line: row.line,\n });\n }\n }\n\n /**\n * Resolve all unresolved edges using type information\n */\n resolveAllCalls(): ResolvedCall[] {\n if (!this.hierarchy) {\n this.buildHierarchy();\n }\n\n this.loadVariableTypes();\n\n const resolvedCalls: ResolvedCall[] = [];\n\n // Get all unresolved edges (target starts with 'ref:')\n const stmt = this.storage.db.prepare(`\n SELECT * FROM edges\n WHERE target_id LIKE 'ref:%'\n AND type = 'calls'\n `);\n\n const edges = stmt.all() as Array<{\n id: string;\n type: string;\n source_id: string;\n target_id: string;\n metadata: string | null;\n }>;\n\n for (const edgeRow of edges) {\n const edge: GraphEdge = {\n id: edgeRow.id,\n type: edgeRow.type as GraphEdge[\"type\"],\n sourceId: edgeRow.source_id,\n targetId: edgeRow.target_id,\n metadata: edgeRow.metadata ? JSON.parse(edgeRow.metadata) : undefined,\n };\n\n const resolved = this.resolveCall(edge);\n if (resolved.targetNode) {\n resolvedCalls.push(resolved);\n\n // Update edge in database\n this.updateEdgeTarget(edge.id, resolved.targetNode.id);\n }\n }\n\n return resolvedCalls;\n }\n\n /**\n * Resolve a single call edge\n */\n resolveCall(edge: GraphEdge): ResolvedCall {\n const unresolvedName = edge.metadata?.unresolvedName as string;\n if (!unresolvedName) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"No unresolved name in metadata\",\n };\n }\n\n // Get source node (the function/method making the call)\n const sourceNode = this.storage.getNode(edge.sourceId);\n if (!sourceNode) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"Source node not found\",\n };\n }\n\n // Pattern 1: Simple function call - functionName()\n if (!unresolvedName.includes(\".\")) {\n return this.resolveSimpleCall(unresolvedName, sourceNode, edge);\n }\n\n // Pattern 2: Method call - obj.method()\n return this.resolveMethodCall(unresolvedName, sourceNode, edge);\n }\n\n /**\n * Resolve simple function call (no dot notation)\n */\n private resolveSimpleCall(\n functionName: string,\n sourceNode: GraphNode,\n edge: GraphEdge\n ): ResolvedCall {\n // Search for function in same file first\n const sameFileNodes = this.storage.getNodesByFile(sourceNode.filePath);\n const localMatch = sameFileNodes.find(\n (n) => (n.type === \"function\" || n.type === \"method\") && n.name === functionName\n );\n\n if (localMatch) {\n return {\n originalEdge: edge,\n targetNode: localMatch,\n confidence: \"HIGH\",\n reason: \"Found in same file\",\n };\n }\n\n // Search globally\n const globalMatches = this.storage.searchNodesByName(functionName);\n if (globalMatches.length === 1) {\n return {\n originalEdge: edge,\n targetNode: globalMatches[0],\n confidence: \"MEDIUM\",\n reason: \"Single global match\",\n };\n }\n\n if (globalMatches.length > 1) {\n // Multiple matches - prefer same directory\n const sourceDir = sourceNode.filePath.split(\"/\").slice(0, -1).join(\"/\");\n const sameDirMatch = globalMatches.find((n) => n.filePath.startsWith(sourceDir));\n\n if (sameDirMatch) {\n return {\n originalEdge: edge,\n targetNode: sameDirMatch,\n confidence: \"MEDIUM\",\n reason: \"Multiple matches, picked same directory\",\n };\n }\n\n return {\n originalEdge: edge,\n targetNode: globalMatches[0],\n confidence: \"LOW\",\n reason: `Multiple matches (${globalMatches.length}), picked first`,\n };\n }\n\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"No matches found\",\n };\n }\n\n /**\n * Resolve method call using type information\n * Pattern: obj.method() or self.method()\n */\n private resolveMethodCall(\n fullName: string,\n sourceNode: GraphNode,\n edge: GraphEdge\n ): ResolvedCall {\n const parts = fullName.split(\".\");\n const varName = parts[0];\n const methodName = parts.slice(1).join(\".\");\n\n // Special case: self.method() or this.method()\n if (varName === \"self\" || varName === \"this\") {\n return this.resolveSelfMethodCall(methodName, sourceNode, edge);\n }\n\n // Look up variable type in current scope\n const scopeTypes = this.variableTypes.get(sourceNode.id) || [];\n const varType = scopeTypes.find((v) => v.name === varName);\n\n if (!varType) {\n // Fallback to simple name matching\n return this.resolveSimpleCall(methodName, sourceNode, edge);\n }\n\n // Use class hierarchy to resolve method\n if (!this.hierarchy) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"Class hierarchy not built\",\n };\n }\n\n const classNode = resolveMethodCall(varType.type, methodName, this.hierarchy);\n\n if (classNode) {\n // Find the actual method node\n const methodNode = this.findMethodInClass(classNode.name, methodName);\n\n if (methodNode) {\n return {\n originalEdge: edge,\n targetNode: methodNode,\n confidence: \"HIGH\",\n reason: `Resolved via type tracking: ${varName}: ${varType.type}`,\n };\n }\n }\n\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: `Type found (${varType.type}) but method not resolved`,\n };\n }\n\n /**\n * Resolve self.method() or this.method()\n */\n private resolveSelfMethodCall(\n methodName: string,\n sourceNode: GraphNode,\n edge: GraphEdge\n ): ResolvedCall {\n // Find parent class of source method\n const parentClass = sourceNode.metadata?.parentClass as string | undefined;\n\n if (!parentClass) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"self/this call but no parent class\",\n };\n }\n\n // Search in class hierarchy\n if (!this.hierarchy) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"Class hierarchy not built\",\n };\n }\n\n const classNode = resolveMethodCall(parentClass, methodName, this.hierarchy);\n\n if (classNode) {\n const methodNode = this.findMethodInClass(classNode.name, methodName);\n\n if (methodNode) {\n return {\n originalEdge: edge,\n targetNode: methodNode,\n confidence: \"HIGH\",\n reason: `Resolved self.${methodName} in ${parentClass}`,\n };\n }\n }\n\n // Fallback: search in same file\n const sameFileNodes = this.storage.getNodesByFile(sourceNode.filePath);\n const methodNode = sameFileNodes.find(\n (n) => n.type === \"method\" && n.name === methodName\n );\n\n if (methodNode) {\n return {\n originalEdge: edge,\n targetNode: methodNode,\n confidence: \"MEDIUM\",\n reason: \"Found method in same file\",\n };\n }\n\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: `Method ${methodName} not found in ${parentClass}`,\n };\n }\n\n /**\n * Find method node in a class\n */\n private findMethodInClass(className: string, methodName: string): GraphNode | null {\n const stmt = this.storage.db.prepare(`\n SELECT * FROM nodes\n WHERE type = 'method'\n AND name = ?\n AND json_extract(metadata, '$.parentClass') = ?\n `);\n\n const row = stmt.get(methodName, className) as Record<string, unknown> | undefined;\n if (!row) return null;\n\n return {\n id: row.id as string,\n type: row.type as GraphNode[\"type\"],\n name: row.name as string,\n filePath: row.file_path as string,\n startLine: row.start_line as number,\n endLine: row.end_line as number,\n language: row.language as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n };\n }\n\n /**\n * Get all nodes from storage\n */\n private getAllNodes(): GraphNode[] {\n const stmt = this.storage.db.prepare(\"SELECT * FROM nodes\");\n const rows = stmt.all() as Array<Record<string, unknown>>;\n\n return rows.map((row) => ({\n id: row.id as string,\n type: row.type as GraphNode[\"type\"],\n name: row.name as string,\n filePath: row.file_path as string,\n startLine: row.start_line as number,\n endLine: row.end_line as number,\n language: row.language as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n }));\n }\n\n /**\n * Update edge target in database\n */\n private updateEdgeTarget(edgeId: string, newTargetId: string): void {\n const stmt = this.storage.db.prepare(`\n UPDATE edges\n SET target_id = ?\n WHERE id = ?\n `);\n stmt.run(newTargetId, edgeId);\n }\n\n /**\n * Get resolution statistics\n */\n getStats(): {\n totalCalls: number;\n resolvedCalls: number;\n unresolvedCalls: number;\n resolutionRate: number;\n } {\n const totalStmt = this.storage.db.prepare(`\n SELECT COUNT(*) as count FROM edges WHERE type = 'calls'\n `);\n const totalRow = totalStmt.get() as { count: number };\n const totalCalls = totalRow.count;\n\n const resolvedStmt = this.storage.db.prepare(`\n SELECT COUNT(*) as count FROM edges\n WHERE type = 'calls' AND target_id NOT LIKE 'ref:%'\n `);\n const resolvedRow = resolvedStmt.get() as { count: number };\n const resolvedCalls = resolvedRow.count;\n\n const unresolvedCalls = totalCalls - resolvedCalls;\n const resolutionRate = totalCalls > 0 ? (resolvedCalls / totalCalls) * 100 : 0;\n\n return {\n totalCalls,\n resolvedCalls,\n unresolvedCalls,\n resolutionRate,\n };\n }\n}\n","/**\n * Base parser interface and utilities\n */\n\nimport type { FileAnalysis, GraphNode, GraphEdge, ImportInfo, ExportInfo } from \"../types.js\";\n\nexport interface Parser {\n language: string;\n extensions: string[];\n treeSitterParser?: any; // Optional: tree-sitter parser for Phase 3 AST access\n parse(filePath: string, content: string): FileAnalysis;\n}\n\nexport abstract class BaseParser implements Parser {\n abstract language: string;\n abstract extensions: string[];\n\n protected nodeIdCounter = 0;\n protected edgeIdCounter = 0;\n\n abstract parse(filePath: string, content: string): FileAnalysis;\n\n protected generateNodeId(filePath: string, name: string, line: number): string {\n return `${filePath}:${name}:${line}`;\n }\n\n protected generateEdgeId(): string {\n return `edge_${++this.edgeIdCounter}`;\n }\n\n protected createNode(\n type: GraphNode[\"type\"],\n name: string,\n filePath: string,\n startLine: number,\n endLine: number,\n metadata?: Record<string, unknown>\n ): GraphNode {\n return {\n id: this.generateNodeId(filePath, name, startLine),\n type,\n name,\n filePath,\n startLine,\n endLine,\n language: this.language,\n metadata,\n };\n }\n\n protected createEdge(\n type: GraphEdge[\"type\"],\n sourceId: string,\n targetId: string,\n metadata?: Record<string, unknown>\n ): GraphEdge {\n return {\n id: this.generateEdgeId(),\n type,\n sourceId,\n targetId,\n metadata,\n };\n }\n\n protected createEmptyAnalysis(filePath: string): FileAnalysis {\n return {\n filePath,\n language: this.language,\n nodes: [],\n edges: [],\n imports: [],\n exports: [],\n };\n }\n}\n\n/**\n * Registry for all parsers\n */\nexport class ParserRegistry {\n private parsers: Map<string, Parser> = new Map();\n private extensionMap: Map<string, Parser> = new Map();\n\n register(parser: Parser): void {\n this.parsers.set(parser.language, parser);\n for (const ext of parser.extensions) {\n this.extensionMap.set(ext, parser);\n }\n }\n\n getByLanguage(language: string): Parser | undefined {\n return this.parsers.get(language);\n }\n\n getByExtension(extension: string): Parser | undefined {\n // Normalize extension (remove leading dot if present)\n const ext = extension.startsWith(\".\") ? extension : `.${extension}`;\n return this.extensionMap.get(ext);\n }\n\n getForFile(filePath: string): Parser | undefined {\n const ext = filePath.substring(filePath.lastIndexOf(\".\"));\n return this.getByExtension(ext);\n }\n\n getSupportedExtensions(): string[] {\n return Array.from(this.extensionMap.keys());\n }\n\n getSupportedLanguages(): string[] {\n return Array.from(this.parsers.keys());\n }\n}\n\nexport const parserRegistry = new ParserRegistry();\n","/**\n * TypeScript/JavaScript parser using Tree-sitter\n */\n\nimport Parser from \"tree-sitter\";\nimport TypeScript from \"tree-sitter-typescript\";\nimport JavaScript from \"tree-sitter-javascript\";\nimport { BaseParser } from \"./base.js\";\nimport type { FileAnalysis, GraphNode, GraphEdge, ImportInfo, ExportInfo } from \"../types.js\";\n\nexport class TypeScriptParser extends BaseParser {\n language = \"typescript\";\n extensions = [\".ts\", \".tsx\"];\n\n private parser: Parser;\n public treeSitterParser: Parser; // Expose for Phase 3\n\n constructor() {\n super();\n this.parser = new Parser();\n this.parser.setLanguage(TypeScript.typescript);\n this.treeSitterParser = this.parser; // Expose parser\n }\n\n parse(filePath: string, content: string): FileAnalysis {\n const analysis = this.createEmptyAnalysis(filePath);\n\n // Ensure content is a string (not Buffer)\n const sourceCode = typeof content === \"string\" ? content : String(content);\n\n // Skip extremely large files (>500KB) to prevent memory issues\n if (sourceCode.length > 500000) {\n const lines = sourceCode.split(\"\\n\");\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n return analysis;\n }\n\n // Use TSX parser for .tsx files\n if (filePath.endsWith(\".tsx\")) {\n this.parser.setLanguage(TypeScript.tsx);\n } else {\n this.parser.setLanguage(TypeScript.typescript);\n }\n\n let tree;\n try {\n tree = this.parser.parse(sourceCode);\n } catch {\n // If parsing fails, just return the file node\n const lines = sourceCode.split(\"\\n\");\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n return analysis;\n }\n\n const lines = sourceCode.split(\"\\n\");\n\n // Create file node\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n\n // Walk the tree\n this.walkTree(tree.rootNode, filePath, analysis, fileNode.id);\n\n return analysis;\n }\n\n private walkTree(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n switch (node.type) {\n case \"import_statement\":\n this.handleImport(node, analysis);\n break;\n\n case \"export_statement\":\n this.handleExport(node, filePath, analysis, parentId);\n break;\n\n case \"function_declaration\":\n case \"arrow_function\":\n case \"function_expression\":\n this.handleFunction(node, filePath, analysis, parentId);\n break;\n\n case \"class_declaration\":\n this.handleClass(node, filePath, analysis, parentId);\n break;\n\n case \"method_definition\":\n this.handleMethod(node, filePath, analysis, parentId);\n break;\n\n case \"call_expression\":\n this.handleCall(node, filePath, analysis, parentId);\n break;\n\n case \"variable_declaration\":\n this.handleVariable(node, filePath, analysis, parentId);\n break;\n }\n\n // Recurse into children\n for (const child of node.children) {\n this.walkTree(child, filePath, analysis, parentId);\n }\n }\n\n private handleImport(node: Parser.SyntaxNode, analysis: FileAnalysis): void {\n const sourceNode = node.childForFieldName(\"source\");\n if (!sourceNode) return;\n\n const source = sourceNode.text.replace(/['\"]/g, \"\");\n const specifiers: string[] = [];\n let isDefault = false;\n let isNamespace = false;\n\n // Find import clause\n for (const child of node.children) {\n if (child.type === \"import_clause\") {\n for (const clauseChild of child.children) {\n if (clauseChild.type === \"identifier\") {\n specifiers.push(clauseChild.text);\n isDefault = true;\n } else if (clauseChild.type === \"namespace_import\") {\n isNamespace = true;\n const nameNode = clauseChild.childForFieldName(\"name\");\n if (nameNode) specifiers.push(nameNode.text);\n } else if (clauseChild.type === \"named_imports\") {\n for (const importSpec of clauseChild.children) {\n if (importSpec.type === \"import_specifier\") {\n const name = importSpec.childForFieldName(\"name\");\n if (name) specifiers.push(name.text);\n }\n }\n }\n }\n }\n }\n\n analysis.imports.push({\n source,\n specifiers,\n isDefault,\n isNamespace,\n line: node.startPosition.row + 1,\n });\n }\n\n private handleExport(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const isDefault = node.children.some((c) => c.type === \"default\");\n\n // Find what's being exported\n for (const child of node.children) {\n if (child.type === \"function_declaration\") {\n const nameNode = child.childForFieldName(\"name\");\n if (nameNode) {\n analysis.exports.push({\n name: nameNode.text,\n isDefault,\n line: node.startPosition.row + 1,\n });\n }\n this.handleFunction(child, filePath, analysis, parentId);\n } else if (child.type === \"class_declaration\") {\n const nameNode = child.childForFieldName(\"name\");\n if (nameNode) {\n analysis.exports.push({\n name: nameNode.text,\n isDefault,\n line: node.startPosition.row + 1,\n });\n }\n this.handleClass(child, filePath, analysis, parentId);\n } else if (child.type === \"identifier\") {\n analysis.exports.push({\n name: child.text,\n isDefault,\n line: node.startPosition.row + 1,\n });\n }\n }\n }\n\n private handleFunction(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n let name = \"anonymous\";\n const nameNode = node.childForFieldName(\"name\");\n if (nameNode) {\n name = nameNode.text;\n }\n\n const funcNode = this.createNode(\n \"function\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n async: node.children.some((c) => c.type === \"async\"),\n generator: node.children.some((c) => c.text === \"*\"),\n }\n );\n\n analysis.nodes.push(funcNode);\n\n // Add contains edge from parent\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, funcNode.id)\n );\n }\n\n private handleClass(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n // Extract extends information\n const extends_: string[] = [];\n for (const child of node.children) {\n if (child.type === \"class_heritage\") {\n const extendsClause = child.children.find((c) => c.type === \"extends_clause\");\n if (extendsClause) {\n const baseClass = extendsClause.children.find((c) => c.type === \"identifier\");\n if (baseClass) {\n extends_.push(baseClass.text);\n }\n }\n }\n }\n\n const classNode = this.createNode(\n \"class\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n extends: extends_,\n }\n );\n\n analysis.nodes.push(classNode);\n\n // Add contains edge\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, classNode.id)\n );\n\n // Create extends edges for each base class\n for (const baseClass of extends_) {\n analysis.edges.push(\n this.createEdge(\"extends\", classNode.id, `ref:${baseClass}`, {\n unresolvedName: baseClass,\n })\n );\n }\n\n // Process class body for methods\n const body = node.childForFieldName(\"body\");\n if (body) {\n for (const member of body.children) {\n if (member.type === \"method_definition\") {\n this.handleMethod(member, filePath, analysis, classNode.id);\n }\n }\n }\n }\n\n private handleMethod(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n // Find parent class name\n const parentNode = analysis.nodes.find((n) => n.id === parentId);\n const parentClass = parentNode?.type === \"class\" ? parentNode.name : undefined;\n\n const methodNode = this.createNode(\n \"method\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n static: node.children.some((c) => c.type === \"static\"),\n async: node.children.some((c) => c.type === \"async\"),\n parentClass,\n }\n );\n\n analysis.nodes.push(methodNode);\n\n // Add contains edge\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, methodNode.id)\n );\n }\n\n private handleCall(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const funcNode = node.childForFieldName(\"function\");\n if (!funcNode) return;\n\n let calledName = \"\";\n if (funcNode.type === \"identifier\") {\n calledName = funcNode.text;\n } else if (funcNode.type === \"member_expression\") {\n // Get the full member expression (e.g., \"console.log\")\n calledName = funcNode.text;\n }\n\n if (calledName) {\n analysis.edges.push(\n this.createEdge(\"calls\", parentId, `ref:${calledName}`, {\n unresolvedName: calledName,\n line: node.startPosition.row + 1,\n })\n );\n }\n }\n\n private handleVariable(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n for (const child of node.children) {\n if (child.type === \"variable_declarator\") {\n const nameNode = child.childForFieldName(\"name\");\n const valueNode = child.childForFieldName(\"value\");\n\n if (nameNode && nameNode.type === \"identifier\") {\n // Check if it's a function expression or arrow function\n if (\n valueNode &&\n (valueNode.type === \"arrow_function\" ||\n valueNode.type === \"function_expression\")\n ) {\n const funcNode = this.createNode(\n \"function\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n kind: node.children[0]?.text || \"const\",\n }\n );\n analysis.nodes.push(funcNode);\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, funcNode.id)\n );\n }\n }\n }\n }\n }\n}\n\nexport class JavaScriptParser extends TypeScriptParser {\n language = \"javascript\";\n extensions = [\".js\", \".jsx\", \".mjs\", \".cjs\"];\n\n constructor() {\n super();\n // Override to use JavaScript grammar\n (this as any).parser = new Parser();\n (this as any).parser.setLanguage(JavaScript);\n // Update exposed parser reference\n this.treeSitterParser = (this as any).parser;\n }\n\n parse(filePath: string, content: string): FileAnalysis {\n // Ensure content is a string\n const sourceCode = typeof content === \"string\" ? content : String(content);\n\n // Use JSX parser for .jsx files\n if (filePath.endsWith(\".jsx\")) {\n // JSX needs TSX parser\n (this as any).parser.setLanguage(TypeScript.tsx);\n } else {\n (this as any).parser.setLanguage(JavaScript);\n }\n\n // Use base implementation but mark as javascript\n const analysis = super.parse(filePath, sourceCode);\n analysis.language = \"javascript\";\n for (const node of analysis.nodes) {\n node.language = \"javascript\";\n }\n return analysis;\n }\n}\n","/**\n * Python parser using Tree-sitter\n */\n\nimport Parser from \"tree-sitter\";\nimport Python from \"tree-sitter-python\";\nimport { BaseParser } from \"./base.js\";\nimport type { FileAnalysis, GraphNode, GraphEdge, ImportInfo, ExportInfo } from \"../types.js\";\n\nexport class PythonParser extends BaseParser {\n language = \"python\";\n extensions = [\".py\"];\n\n private parser: Parser;\n public treeSitterParser: Parser; // Expose for Phase 3\n\n constructor() {\n super();\n this.parser = new Parser();\n this.parser.setLanguage(Python);\n this.treeSitterParser = this.parser; // Expose parser\n }\n\n parse(filePath: string, content: string): FileAnalysis {\n const analysis = this.createEmptyAnalysis(filePath);\n\n // Ensure content is a string (not Buffer)\n const sourceCode = typeof content === \"string\" ? content : String(content);\n\n // Skip extremely large files (>500KB) to prevent memory issues\n if (sourceCode.length > 500000) {\n const lines = sourceCode.split(\"\\n\");\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n return analysis;\n }\n\n let tree;\n try {\n // Use callback-based parsing to avoid \"Invalid argument\" errors with large files\n // This is more robust than passing the string directly\n tree = this.parser.parse((index, position) => {\n if (index >= sourceCode.length) {\n return null;\n }\n const endIndex = Math.min(index + 1024, sourceCode.length);\n return sourceCode.substring(index, endIndex);\n });\n } catch (error) {\n // If parsing fails, just return the file node\n const lines = sourceCode.split(\"\\n\");\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n return analysis;\n }\n\n const lines = sourceCode.split(\"\\n\");\n\n // Create file node\n const fileNode = this.createNode(\n \"file\",\n filePath.split(\"/\").pop() || filePath,\n filePath,\n 1,\n lines.length\n );\n analysis.nodes.push(fileNode);\n\n // Walk the tree\n this.walkTree(tree.rootNode, filePath, analysis, fileNode.id);\n\n return analysis;\n }\n\n private walkTree(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n switch (node.type) {\n case \"import_statement\":\n this.handleImport(node, analysis);\n break;\n\n case \"import_from_statement\":\n this.handleFromImport(node, analysis);\n break;\n\n case \"function_definition\":\n this.handleFunction(node, filePath, analysis, parentId);\n return; // Don't recurse into function body for top-level analysis\n\n case \"class_definition\":\n this.handleClass(node, filePath, analysis, parentId);\n return; // Don't recurse, class handler will process methods\n\n case \"call\":\n this.handleCall(node, filePath, analysis, parentId);\n break;\n }\n\n // Recurse into children\n for (const child of node.children) {\n this.walkTree(child, filePath, analysis, parentId);\n }\n }\n\n private handleImport(node: Parser.SyntaxNode, analysis: FileAnalysis): void {\n // import foo, bar, baz\n for (const child of node.children) {\n if (child.type === \"dotted_name\") {\n analysis.imports.push({\n source: child.text,\n specifiers: [child.text.split(\".\").pop() || child.text],\n isDefault: false,\n isNamespace: true,\n line: node.startPosition.row + 1,\n });\n } else if (child.type === \"aliased_import\") {\n const nameNode = child.childForFieldName(\"name\");\n const aliasNode = child.childForFieldName(\"alias\");\n if (nameNode) {\n analysis.imports.push({\n source: nameNode.text,\n specifiers: [aliasNode?.text || nameNode.text],\n isDefault: false,\n isNamespace: true,\n line: node.startPosition.row + 1,\n });\n }\n }\n }\n }\n\n private handleFromImport(node: Parser.SyntaxNode, analysis: FileAnalysis): void {\n // from foo import bar, baz\n const moduleNode = node.childForFieldName(\"module_name\");\n if (!moduleNode) return;\n\n const source = moduleNode.text;\n const specifiers: string[] = [];\n\n for (const child of node.children) {\n if (child.type === \"import_prefix\") {\n // Handle relative imports (from . import x, from .. import y)\n continue;\n }\n\n if (child.type === \"dotted_name\" && child !== moduleNode) {\n specifiers.push(child.text);\n } else if (child.type === \"aliased_import\") {\n const nameNode = child.childForFieldName(\"name\");\n if (nameNode) {\n specifiers.push(nameNode.text);\n }\n } else if (child.type === \"wildcard_import\") {\n specifiers.push(\"*\");\n }\n }\n\n if (specifiers.length === 0) {\n // Check for named imports in different structure\n for (const child of node.children) {\n if (child.type === \"import_list\" || child.type === \"import_from_specifier\") {\n for (const spec of child.children) {\n if (spec.type === \"dotted_name\" || spec.type === \"identifier\") {\n specifiers.push(spec.text);\n }\n }\n }\n }\n }\n\n analysis.imports.push({\n source,\n specifiers,\n isDefault: false,\n isNamespace: specifiers.includes(\"*\"),\n line: node.startPosition.row + 1,\n });\n }\n\n private handleFunction(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const name = nameNode.text;\n\n // Check for decorators - they are siblings within parent decorated_definition\n const decorators: string[] = [];\n const decoratorDetails: Array<{ name: string; args: string[]; kwargs?: Record<string, string> }> = [];\n\n // Check if parent is decorated_definition\n if (node.parent?.type === \"decorated_definition\") {\n // Decorators are children of decorated_definition, before the function_definition\n for (const sibling of node.parent.children) {\n if (sibling.type === \"decorator\") {\n // Find the decorator call or attribute\n const decoratorCall = sibling.children.find((c) => c.type === \"call\");\n const decoratorAttr = sibling.children.find((c) => c.type === \"attribute\" || c.type === \"identifier\");\n\n if (decoratorCall) {\n // Decorator with arguments: @router.post(\"/chat\")\n const funcName = decoratorCall.children.find((c) => c.type === \"attribute\" || c.type === \"identifier\");\n if (funcName) {\n const fullDecorator = funcName.text;\n decorators.push(fullDecorator);\n\n // Extract arguments (both positional and keyword)\n const args: string[] = [];\n const kwargs: Record<string, string> = {};\n const argList = decoratorCall.children.find((c) => c.type === \"argument_list\");\n if (argList) {\n for (const arg of argList.children) {\n if (arg.type === \"string\") {\n // Positional string argument\n const stringContent = arg.children.find((c) => c.type === \"string_content\");\n const argText = stringContent ? stringContent.text : arg.text.replace(/^[\"']|[\"']$/g, \"\");\n args.push(argText);\n } else if (arg.type === \"keyword_argument\") {\n // Keyword argument: tags=[\"chat\"]\n const keyNode = arg.childForFieldName(\"name\");\n const valueNode = arg.childForFieldName(\"value\");\n if (keyNode && valueNode) {\n const key = keyNode.text;\n let value = valueNode.text;\n // Simplify list values\n if (valueNode.type === \"list\") {\n const items: string[] = [];\n for (const child of valueNode.children) {\n if (child.type === \"string\") {\n const stringContent = child.children.find((c) => c.type === \"string_content\");\n items.push(stringContent ? stringContent.text : child.text.replace(/^[\"']|[\"']$/g, \"\"));\n }\n }\n value = items.length > 0 ? items.join(\",\") : value;\n }\n kwargs[key] = value;\n }\n } else if (arg.type === \"identifier\") {\n // Positional identifier argument\n args.push(arg.text);\n }\n }\n }\n\n decoratorDetails.push({ name: fullDecorator, args, kwargs });\n }\n } else if (decoratorAttr) {\n // Simple decorator without arguments: @property\n const fullDecorator = decoratorAttr.text;\n decorators.push(fullDecorator);\n decoratorDetails.push({ name: fullDecorator, args: [] });\n }\n }\n }\n }\n\n // Check if async\n const isAsync = node.children.some((c) => c.type === \"async\");\n\n // Extract return type hint from -> annotation\n let returnType: string | undefined;\n const returnTypeNode = node.childForFieldName(\"return_type\");\n if (returnTypeNode) {\n returnType = returnTypeNode.text;\n // Clean up the type (remove quotes, generic parameters for simple matching)\n returnType = returnType.replace(/[\"']/g, \"\").split(\"[\")[0].trim();\n }\n\n const funcNode = this.createNode(\n \"function\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n async: isAsync,\n decorators,\n decoratorDetails: JSON.stringify(decoratorDetails),\n isPrivate: name.startsWith(\"_\"),\n isDunder: name.startsWith(\"__\") && name.endsWith(\"__\"),\n returnType,\n }\n );\n\n analysis.nodes.push(funcNode);\n analysis.edges.push(this.createEdge(\"contains\", parentId, funcNode.id));\n\n // Check for FastAPI route decorators (@router.get, @router.post, etc.)\n this.detectFastAPIRoute(decoratorDetails, funcNode, analysis);\n\n // Parse function parameters for Depends() and type hints\n const parameters = node.childForFieldName(\"parameters\");\n if (parameters) {\n this.detectDependsPattern(parameters, funcNode, analysis);\n this.extractParameterTypes(parameters, funcNode.id, filePath, analysis);\n }\n\n // Parse function body for calls\n const body = node.childForFieldName(\"body\");\n if (body) {\n this.parseBodyForCalls(body, filePath, analysis, funcNode.id);\n }\n\n // If not private, consider it exported\n if (!name.startsWith(\"_\")) {\n analysis.exports.push({\n name,\n isDefault: false,\n line: node.startPosition.row + 1,\n });\n }\n }\n\n /**\n * Detect FastAPI route decorators like @router.post(\"/chat\")\n */\n private detectFastAPIRoute(\n decoratorDetails: Array<{ name: string; args: string[]; kwargs?: Record<string, string> }>,\n funcNode: GraphNode,\n analysis: FileAnalysis\n ): void {\n for (const dec of decoratorDetails) {\n // Match patterns: router.get, router.post, app.get, etc.\n const routeMatch = dec.name.match(/^(router|app)\\.(get|post|put|patch|delete|options|head)$/);\n if (routeMatch && dec.args.length > 0) {\n const method = routeMatch[2].toUpperCase();\n const path = dec.args[0]; // First argument is the path\n\n // Store as metadata in the function node\n if (!funcNode.metadata) funcNode.metadata = {};\n funcNode.metadata.httpEndpoint = {\n method,\n path,\n };\n }\n }\n }\n\n /**\n * Detect Depends() pattern in function parameters\n * Example: user: User = Depends(authenticate_user)\n */\n private detectDependsPattern(\n parameters: Parser.SyntaxNode,\n funcNode: GraphNode,\n analysis: FileAnalysis\n ): void {\n for (const param of parameters.children) {\n if (param.type === \"typed_parameter\" || param.type === \"default_parameter\") {\n // Look for default value\n const defaultValue = param.children.find((c) => c.type === \"call\");\n if (defaultValue) {\n // Check if it's a Depends() call\n const funcCall = defaultValue.childForFieldName(\"function\");\n if (funcCall && funcCall.text === \"Depends\") {\n // Extract the argument to Depends()\n const argList = defaultValue.childForFieldName(\"arguments\");\n if (argList) {\n for (const arg of argList.children) {\n if (arg.type === \"identifier\") {\n const dependencyName = arg.text;\n\n // Get parameter name\n const paramName = param.children.find(\n (c) => c.type === \"identifier\"\n )?.text;\n\n // Store in metadata\n if (!funcNode.metadata) funcNode.metadata = {};\n if (!funcNode.metadata.depends) funcNode.metadata.depends = [];\n (funcNode.metadata.depends as any[]).push({\n parameterName: paramName,\n dependencyName,\n line: param.startPosition.row + 1,\n });\n\n // Create an edge to represent this dependency\n // We'll use a special edge type that will be resolved later\n analysis.edges.push(\n this.createEdge(\"depends\", funcNode.id, `ref:${dependencyName}`, {\n unresolvedName: dependencyName,\n parameterName: paramName,\n line: param.startPosition.row + 1,\n })\n );\n }\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Extract parameter type hints and register as variable types\n * Example: def process(user: User, config: Config)\n */\n private extractParameterTypes(\n parameters: Parser.SyntaxNode,\n scopeId: string,\n filePath: string,\n analysis: FileAnalysis\n ): void {\n for (const param of parameters.children) {\n if (param.type === \"typed_parameter\") {\n // Get parameter name\n const nameNode = param.children.find((c) => c.type === \"identifier\");\n if (!nameNode) continue;\n\n const paramName = nameNode.text;\n\n // Skip self and cls\n if (paramName === \"self\" || paramName === \"cls\") continue;\n\n // Get type annotation\n const typeNode = param.children.find((c) => c.type === \"type\");\n if (!typeNode) continue;\n\n let typeName = typeNode.text;\n\n // Clean up type (remove quotes, Optional[], List[], etc.)\n typeName = typeName.replace(/[\"']/g, \"\").trim();\n\n // Extract base type from generics: Optional[User] -> User, List[Item] -> Item\n const genericMatch = typeName.match(/(?:Optional|List|Dict|Set)\\[([^\\]]+)\\]/);\n if (genericMatch) {\n typeName = genericMatch[1].trim();\n }\n\n // Store as variable type in function scope\n if (!analysis.variableTypes) {\n analysis.variableTypes = [];\n }\n\n analysis.variableTypes.push({\n variableName: paramName,\n typeName,\n scopeId,\n line: param.startPosition.row + 1,\n });\n }\n }\n }\n\n private handleClass(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const name = nameNode.text;\n\n // Check for base classes\n const bases: string[] = [];\n const argumentList = node.children.find((c) => c.type === \"argument_list\");\n if (argumentList) {\n for (const arg of argumentList.children) {\n if (arg.type === \"identifier\" || arg.type === \"attribute\") {\n bases.push(arg.text);\n }\n }\n }\n\n const classNode = this.createNode(\n \"class\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n bases,\n extends: bases, // Add extends for consistency with TypeScript\n isPrivate: name.startsWith(\"_\"),\n }\n );\n\n analysis.nodes.push(classNode);\n analysis.edges.push(this.createEdge(\"contains\", parentId, classNode.id));\n\n // Add extends edges\n for (const base of bases) {\n analysis.edges.push(\n this.createEdge(\"extends\", classNode.id, `ref:${base}`, {\n unresolvedName: base,\n })\n );\n }\n\n // Parse class body for methods\n const body = node.childForFieldName(\"body\");\n if (body) {\n for (const child of body.children) {\n if (child.type === \"function_definition\") {\n this.handleMethod(child, filePath, analysis, classNode.id);\n } else if (child.type === \"decorated_definition\") {\n // Handle decorated methods (@classmethod, @staticmethod, @property, etc.)\n const funcNode = child.children.find((c) => c.type === \"function_definition\");\n if (funcNode) {\n this.handleMethod(funcNode, filePath, analysis, classNode.id);\n }\n }\n }\n }\n\n // Consider non-private classes as exports\n if (!name.startsWith(\"_\")) {\n analysis.exports.push({\n name,\n isDefault: false,\n line: node.startPosition.row + 1,\n });\n }\n }\n\n private handleMethod(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n classId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const name = nameNode.text;\n\n // Find parent class name\n const parentNode = analysis.nodes.find((n) => n.id === classId);\n const parentClass = parentNode?.type === \"class\" ? parentNode.name : undefined;\n\n // Check for decorators - they are siblings within parent decorated_definition\n const decorators: string[] = [];\n\n // Check if parent is decorated_definition (same as for top-level functions)\n if (node.parent?.type === \"decorated_definition\") {\n for (const sibling of node.parent.children) {\n if (sibling.type === \"decorator\") {\n const decoratorAttr = sibling.children.find((c) => c.type === \"attribute\" || c.type === \"identifier\");\n if (decoratorAttr) {\n decorators.push(decoratorAttr.text);\n }\n }\n }\n }\n\n const isStatic = decorators.includes(\"staticmethod\");\n const isClassMethod = decorators.includes(\"classmethod\");\n const isProperty = decorators.includes(\"property\");\n const isAsync = node.children.some((c) => c.type === \"async\");\n\n const methodNode = this.createNode(\n \"method\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n async: isAsync,\n decorators,\n static: isStatic,\n classmethod: isClassMethod,\n property: isProperty,\n isPrivate: name.startsWith(\"_\"),\n isDunder: name.startsWith(\"__\") && name.endsWith(\"__\"),\n parentClass,\n }\n );\n\n analysis.nodes.push(methodNode);\n analysis.edges.push(this.createEdge(\"contains\", classId, methodNode.id));\n\n // Parse method body for calls\n const body = node.childForFieldName(\"body\");\n if (body) {\n this.parseBodyForCalls(body, filePath, analysis, methodNode.id);\n }\n }\n\n private handleCall(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const funcNode = node.childForFieldName(\"function\");\n if (!funcNode) return;\n\n let calledName = \"\";\n if (funcNode.type === \"identifier\") {\n calledName = funcNode.text;\n } else if (funcNode.type === \"attribute\") {\n // Get the full attribute access (e.g., \"self.method\", \"module.func\")\n calledName = funcNode.text;\n }\n\n if (calledName) {\n // Track all calls including self.method for proper resolution\n analysis.edges.push(\n this.createEdge(\"calls\", parentId, `ref:${calledName}`, {\n unresolvedName: calledName,\n line: node.startPosition.row + 1,\n })\n );\n\n // Detect database operations (MongoDB patterns)\n this.detectDatabaseOperation(calledName, node, parentId, analysis);\n }\n }\n\n /**\n * Detect database operations (MongoDB, SQL, etc.)\n * Examples: collection.find_one(), db.users.insert_one(), collection.update_many()\n */\n private detectDatabaseOperation(\n calledName: string,\n node: Parser.SyntaxNode,\n parentId: string,\n analysis: FileAnalysis\n ): void {\n // MongoDB operation patterns\n const mongoOps = [\n \"find_one\",\n \"find\",\n \"insert_one\",\n \"insert_many\",\n \"update_one\",\n \"update_many\",\n \"delete_one\",\n \"delete_many\",\n \"aggregate\",\n \"count_documents\",\n \"replace_one\",\n ];\n\n // Check if the called method is a MongoDB operation\n const parts = calledName.split(\".\");\n const operation = parts[parts.length - 1];\n\n if (mongoOps.includes(operation)) {\n // Try to extract collection name\n let collection = \"unknown\";\n if (parts.length >= 2) {\n collection = parts[parts.length - 2];\n }\n\n // Store database operation metadata\n if (!analysis.databaseOperations) {\n analysis.databaseOperations = [];\n }\n\n analysis.databaseOperations.push({\n nodeId: parentId,\n operation,\n collection,\n databaseType: \"mongodb\",\n line: node.startPosition.row + 1,\n });\n }\n }\n\n private parseBodyForCalls(\n body: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const walkForCalls = (node: Parser.SyntaxNode): void => {\n if (node.type === \"call\") {\n this.handleCall(node, filePath, analysis, parentId);\n } else if (node.type === \"import_statement\") {\n // Handle local imports inside functions\n this.handleImport(node, analysis);\n } else if (node.type === \"import_from_statement\") {\n // Handle local from imports inside functions\n this.handleFromImport(node, analysis);\n } else if (node.type === \"assignment\") {\n // Track variable assignments for type inference\n this.handleAssignment(node, filePath, analysis, parentId);\n }\n for (const child of node.children) {\n walkForCalls(child);\n }\n };\n walkForCalls(body);\n }\n\n /**\n * Handle variable assignments to track types\n * Examples:\n * user = get_user(id) # Track if get_user has type hint\n * handler = UserHandler(db) # Track: handler -> UserHandler\n * org_handler = OrgHandler.get_instance() # Track: org_handler -> OrgHandler\n */\n private handleAssignment(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n scopeId: string\n ): void {\n // Get left side (variable name)\n const leftNode = node.childForFieldName(\"left\");\n if (!leftNode || leftNode.type !== \"identifier\") return;\n\n const variableName = leftNode.text;\n\n // Get right side (value being assigned)\n const rightNode = node.childForFieldName(\"right\");\n if (!rightNode) return;\n\n let typeName: string | null = null;\n\n // Pattern 1: Direct class instantiation - handler = UserHandler(...)\n if (rightNode.type === \"call\") {\n const funcNode = rightNode.childForFieldName(\"function\");\n if (funcNode) {\n if (funcNode.type === \"identifier\") {\n // Simple: ClassName(...) or function_call()\n const funcName = funcNode.text;\n\n // Check if it's a known class (starts with capital) - instant assign\n if (funcName[0] === funcName[0].toUpperCase()) {\n typeName = funcName;\n } else {\n // It's a function call - we'll need to look up return type later\n // Store as a pending type resolution\n typeName = `@call:${funcName}`;\n }\n } else if (funcNode.type === \"attribute\") {\n // Class method: ClassName.method()\n const parts = funcNode.text.split(\".\");\n if (parts.length >= 2) {\n const className = parts[0];\n const methodName = parts[1];\n\n // If className is capitalized, assume the method returns that class type\n if (className[0] === className[0].toUpperCase()) {\n typeName = className;\n } else {\n // Store for later resolution\n typeName = `@call:${funcNode.text}`;\n }\n }\n }\n }\n }\n\n if (typeName && !analysis.variableTypes) {\n analysis.variableTypes = [];\n }\n\n if (typeName) {\n analysis.variableTypes!.push({\n variableName,\n typeName,\n scopeId,\n line: node.startPosition.row + 1,\n });\n }\n }\n}\n","/**\n * Parser registry and exports\n */\n\nexport { BaseParser, ParserRegistry, parserRegistry } from \"./base.js\";\nexport { TypeScriptParser, JavaScriptParser } from \"./typescript.js\";\nexport { PythonParser } from \"./python.js\";\n\nimport { parserRegistry } from \"./base.js\";\nimport { TypeScriptParser, JavaScriptParser } from \"./typescript.js\";\nimport { PythonParser } from \"./python.js\";\n\n// Register all parsers\nexport function registerAllParsers(): void {\n parserRegistry.register(new TypeScriptParser());\n parserRegistry.register(new JavaScriptParser());\n parserRegistry.register(new PythonParser());\n}\n\n// Auto-register on import\nregisterAllParsers();\n","/**\n * Phase 3 File Analyzer\n * Re-parses files to extract Phase 3 data (property accesses, return shapes)\n */\n\nimport Parser from \"tree-sitter\";\nimport { readFileSync } from \"fs\";\nimport { Database } from \"better-sqlite3\";\nimport { extractPropertyAccesses } from \"../analysis/property-tracker.js\";\nimport { analyzeReturnStatements } from \"../analysis/return-analyzer.js\";\nimport {\n storePropertyAccesses,\n storeReturnInfo,\n} from \"./storage-queries-phase3.js\";\nimport { parserRegistry } from \"../parsers/index.js\";\n\n/**\n * Analyze a file for Phase 3 data\n */\nexport function analyzeFileForPhase3(\n filePath: string,\n functionNodes: Array<{ id: string; name: string; startLine: number; endLine: number }>,\n db: Database\n): void {\n try {\n // Get language from extension\n const language = getLanguageFromPath(filePath);\n if (!language) return;\n\n // Get parser\n const parserInstance = parserRegistry.getByLanguage(language);\n if (!parserInstance || !parserInstance.treeSitterParser) return;\n\n // Parse file using tree-sitter\n const content = readFileSync(filePath, \"utf-8\");\n const tree = parserInstance.treeSitterParser.parse(content);\n const rootNode = tree.rootNode;\n\n // Analyze each function\n for (const func of functionNodes) {\n // Find the function AST node\n const funcNode = findNodeAtLine(rootNode, func.startLine, func.endLine);\n if (!funcNode) continue;\n\n // Extract property accesses\n const accesses = extractPropertyAccesses(funcNode, func.id, func.name, filePath);\n if (accesses.length > 0) {\n // Add file path to each access\n const accessesWithFile = accesses.map((a) => ({ ...a, filePath }));\n storePropertyAccesses(db, accessesWithFile);\n }\n\n // Analyze return statements\n const returns = analyzeReturnStatements(funcNode, func.id, func.name, filePath);\n if (returns.length > 0) {\n storeReturnInfo(db, returns);\n }\n }\n } catch (error) {\n // Silently skip files that fail Phase 3 analysis\n // Don't break the build if Phase 3 fails\n }\n}\n\n/**\n * Get language from file path\n */\nfunction getLanguageFromPath(filePath: string): string | null {\n if (filePath.endsWith(\".py\")) return \"python\";\n if (filePath.endsWith(\".js\") || filePath.endsWith(\".jsx\")) return \"javascript\";\n if (filePath.endsWith(\".ts\") || filePath.endsWith(\".tsx\")) return \"typescript\";\n return null;\n}\n\n/**\n * Find AST node at specific line range\n */\nfunction findNodeAtLine(\n node: Parser.SyntaxNode,\n startLine: number,\n endLine: number\n): Parser.SyntaxNode | null {\n // Check if this node matches the line range\n const nodeStart = node.startPosition.row + 1;\n const nodeEnd = node.endPosition.row + 1;\n\n if (nodeStart === startLine && nodeEnd === endLine) {\n return node;\n }\n\n // Search children\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child) {\n const result = findNodeAtLine(child, startLine, endLine);\n if (result) return result;\n }\n }\n\n // If exact match not found but this node contains the range, return it\n if (nodeStart <= startLine && nodeEnd >= endLine) {\n // Check if it's a function/method node\n if (\n node.type === \"function_definition\" ||\n node.type === \"function_declaration\" ||\n node.type === \"method_definition\" ||\n node.type === \"arrow_function\" ||\n node.type === \"function_expression\"\n ) {\n return node;\n }\n }\n\n return null;\n}\n","/**\n * Property Access Tracker\n * Extracts and tracks property accesses from code to detect breaking data shape changes\n */\n\nimport Parser from \"tree-sitter\";\n\nexport interface PropertyAccess {\n objectName: string; // \"user\"\n propertyPath: string[]; // [\"profile\", \"avatar\"]\n fullPath: string; // \"user.profile.avatar\"\n line: number;\n scopeId: string; // Function/method where accessed\n accessType: 'dot' | 'bracket' | 'optional';\n}\n\nexport interface PropertyAccessMap {\n [fullPath: string]: AccessLocation[];\n}\n\nexport interface AccessLocation {\n scopeId: string;\n scopeName: string;\n file: string;\n line: number;\n}\n\n/**\n * Extract all property accesses from a function's AST node\n */\nexport function extractPropertyAccesses(\n functionNode: Parser.SyntaxNode,\n scopeId: string,\n scopeName: string,\n filePath: string\n): PropertyAccess[] {\n const accesses: PropertyAccess[] = [];\n const isJS = /\\.(js|ts|jsx|tsx)$/.test(filePath);\n const isPython = /\\.py$/.test(filePath);\n\n if (isJS) {\n extractJavaScriptPropertyAccesses(functionNode, scopeId, scopeName, accesses);\n } else if (isPython) {\n extractPythonPropertyAccesses(functionNode, scopeId, scopeName, accesses);\n }\n\n return accesses;\n}\n\n/**\n * Extract property accesses from JavaScript/TypeScript code\n */\nfunction extractJavaScriptPropertyAccesses(\n node: Parser.SyntaxNode,\n scopeId: string,\n scopeName: string,\n accesses: PropertyAccess[]\n): void {\n traverseNode(node, (current) => {\n // Pattern 1: Member expression - obj.property\n if (current.type === \"member_expression\") {\n const access = parseJavaScriptMemberExpression(current, scopeId);\n if (access) {\n accesses.push(access);\n }\n }\n\n // Pattern 2: Optional chaining - obj?.property\n if (current.type === \"optional_chain\") {\n const memberExpr = current.children.find((c) => c.type === \"member_expression\");\n if (memberExpr) {\n const access = parseJavaScriptMemberExpression(memberExpr, scopeId);\n if (access) {\n access.accessType = 'optional';\n accesses.push(access);\n }\n }\n }\n\n // Pattern 3: Subscript expression - obj[\"property\"]\n if (current.type === \"subscript_expression\") {\n const access = parseJavaScriptSubscript(current, scopeId);\n if (access) {\n accesses.push(access);\n }\n }\n });\n}\n\n/**\n * Parse JavaScript member expression (obj.property.nested)\n */\nfunction parseJavaScriptMemberExpression(\n node: Parser.SyntaxNode,\n scopeId: string\n): PropertyAccess | null {\n const propertyPath: string[] = [];\n let objectName = \"\";\n let currentNode: Parser.SyntaxNode | null = node;\n\n // Walk up the member expression chain\n while (currentNode && currentNode.type === \"member_expression\") {\n // Get property name\n const propertyNode = currentNode.childForFieldName(\"property\");\n if (propertyNode) {\n propertyPath.unshift(propertyNode.text);\n }\n\n // Get object (might be another member expression)\n const objectNode = currentNode.childForFieldName(\"object\");\n if (!objectNode) break;\n\n if (objectNode.type === \"identifier\") {\n objectName = objectNode.text;\n break;\n } else if (objectNode.type === \"member_expression\") {\n currentNode = objectNode;\n } else {\n // Complex expression (call, etc.) - skip\n return null;\n }\n }\n\n // Skip if no object name or common false positives\n if (!objectName || isCommonJavaScriptObject(objectName)) {\n return null;\n }\n\n // Skip if property path is empty\n if (propertyPath.length === 0) {\n return null;\n }\n\n return {\n objectName,\n propertyPath,\n fullPath: `${objectName}.${propertyPath.join(\".\")}`,\n line: node.startPosition.row + 1,\n scopeId,\n accessType: 'dot',\n };\n}\n\n/**\n * Parse JavaScript subscript expression (obj[\"property\"])\n */\nfunction parseJavaScriptSubscript(\n node: Parser.SyntaxNode,\n scopeId: string\n): PropertyAccess | null {\n const objectNode = node.childForFieldName(\"object\");\n const indexNode = node.childForFieldName(\"index\");\n\n if (!objectNode || !indexNode) return null;\n\n // Only track static string keys, not dynamic variables\n if (indexNode.type !== \"string\") return null;\n\n const objectName = objectNode.text;\n const propertyName = indexNode.text.replace(/['\"]/g, \"\");\n\n if (isCommonJavaScriptObject(objectName)) {\n return null;\n }\n\n return {\n objectName,\n propertyPath: [propertyName],\n fullPath: `${objectName}.${propertyName}`,\n line: node.startPosition.row + 1,\n scopeId,\n accessType: 'bracket',\n };\n}\n\n/**\n * Extract property accesses from Python code\n */\nfunction extractPythonPropertyAccesses(\n node: Parser.SyntaxNode,\n scopeId: string,\n scopeName: string,\n accesses: PropertyAccess[]\n): void {\n traverseNode(node, (current) => {\n // Pattern: Attribute access - obj.property\n if (current.type === \"attribute\") {\n const access = parsePythonAttribute(current, scopeId);\n if (access) {\n accesses.push(access);\n }\n }\n\n // Pattern: Subscript - obj[\"property\"] or obj[key]\n if (current.type === \"subscript\") {\n const access = parsePythonSubscript(current, scopeId);\n if (access) {\n accesses.push(access);\n }\n }\n });\n}\n\n/**\n * Parse Python attribute access (obj.property.nested)\n */\nfunction parsePythonAttribute(\n node: Parser.SyntaxNode,\n scopeId: string\n): PropertyAccess | null {\n const propertyPath: string[] = [];\n let objectName = \"\";\n let currentNode: Parser.SyntaxNode | null = node;\n\n // Walk up the attribute chain\n while (currentNode && currentNode.type === \"attribute\") {\n // Get attribute name\n const attrNode = currentNode.childForFieldName(\"attribute\");\n if (attrNode) {\n propertyPath.unshift(attrNode.text);\n }\n\n // Get object (might be another attribute)\n const objectNode = currentNode.childForFieldName(\"object\");\n if (!objectNode) break;\n\n if (objectNode.type === \"identifier\") {\n objectName = objectNode.text;\n break;\n } else if (objectNode.type === \"attribute\") {\n currentNode = objectNode;\n } else {\n // Complex expression - skip\n return null;\n }\n }\n\n // Skip common false positives\n if (!objectName || isCommonPythonObject(objectName)) {\n return null;\n }\n\n // Skip if property path is empty\n if (propertyPath.length === 0) {\n return null;\n }\n\n return {\n objectName,\n propertyPath,\n fullPath: `${objectName}.${propertyPath.join(\".\")}`,\n line: node.startPosition.row + 1,\n scopeId,\n accessType: 'dot',\n };\n}\n\n/**\n * Parse Python subscript (obj[\"property\"])\n */\nfunction parsePythonSubscript(\n node: Parser.SyntaxNode,\n scopeId: string\n): PropertyAccess | null {\n const valueNode = node.childForFieldName(\"value\");\n\n // Find subscript children\n const subscriptChildren = node.children.filter(\n (c) => c.type === \"string\" || c.type === \"identifier\"\n );\n\n if (!valueNode || subscriptChildren.length === 0) return null;\n\n // Only track static string keys\n const keyNode = subscriptChildren.find((c) => c.type === \"string\");\n if (!keyNode) return null;\n\n const objectName = valueNode.text;\n\n // Extract string content\n const stringContent = keyNode.children.find((c) => c.type === \"string_content\");\n const propertyName = stringContent ? stringContent.text : keyNode.text.replace(/['\"]/g, \"\");\n\n if (isCommonPythonObject(objectName)) {\n return null;\n }\n\n return {\n objectName,\n propertyPath: [propertyName],\n fullPath: `${objectName}.${propertyName}`,\n line: node.startPosition.row + 1,\n scopeId,\n accessType: 'bracket',\n };\n}\n\n/**\n * Traverse AST node and apply visitor function\n */\nfunction traverseNode(\n node: Parser.SyntaxNode,\n visitor: (node: Parser.SyntaxNode) => void\n): void {\n visitor(node);\n\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child) {\n traverseNode(child, visitor);\n }\n }\n}\n\n/**\n * Check if identifier is a common JavaScript object to skip\n */\nfunction isCommonJavaScriptObject(name: string): boolean {\n const commonObjects = new Set([\n // Global objects\n 'console', 'window', 'document', 'process', 'global',\n // Common libraries\n 'Math', 'JSON', 'Date', 'Array', 'Object', 'String', 'Number',\n // Keywords\n 'this', 'super',\n // Common module patterns\n 'exports', 'module', 'require',\n ]);\n\n return commonObjects.has(name);\n}\n\n/**\n * Check if identifier is a common Python object to skip\n */\nfunction isCommonPythonObject(name: string): boolean {\n const commonObjects = new Set([\n // Keywords\n 'self', 'cls',\n // Built-in types\n 'str', 'int', 'float', 'dict', 'list', 'tuple', 'set',\n // Common modules\n 'os', 'sys', 'json', 'math', 'datetime',\n ]);\n\n return commonObjects.has(name);\n}\n\n/**\n * Build a map of property accesses grouped by full path\n */\nexport function buildAccessMap(\n accesses: PropertyAccess[],\n scopeName: string,\n file: string\n): PropertyAccessMap {\n const map: PropertyAccessMap = {};\n\n for (const access of accesses) {\n const key = access.fullPath;\n\n if (!map[key]) {\n map[key] = [];\n }\n\n map[key].push({\n scopeId: access.scopeId,\n scopeName,\n file,\n line: access.line,\n });\n }\n\n return map;\n}\n\n/**\n * Get all accesses for a specific property path\n */\nexport function getAccessesForProperty(\n propertyPath: string,\n allAccesses: PropertyAccess[]\n): PropertyAccess[] {\n return allAccesses.filter((access) => access.fullPath === propertyPath);\n}\n\n/**\n * Get all accesses on a specific object\n */\nexport function getAccessesForObject(\n objectName: string,\n allAccesses: PropertyAccess[]\n): PropertyAccess[] {\n return allAccesses.filter((access) => access.objectName === objectName);\n}\n\n/**\n * Check if a property access matches a pattern\n * E.g., matches(\"user.email\", \"user.*\") -> true\n */\nexport function matchesPattern(fullPath: string, pattern: string): boolean {\n // Convert pattern to regex\n const regexPattern = pattern\n .replace(/\\./g, \"\\\\.\") // Escape dots\n .replace(/\\*/g, \".*\"); // Wildcard\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(fullPath);\n}\n\n/**\n * Get property depth (number of nested levels)\n */\nexport function getPropertyDepth(access: PropertyAccess): number {\n return access.propertyPath.length;\n}\n\n/**\n * Get top-level property (first in path)\n */\nexport function getTopLevelProperty(access: PropertyAccess): string {\n return access.propertyPath[0];\n}\n\n/**\n * Filter accesses by depth\n */\nexport function filterByDepth(\n accesses: PropertyAccess[],\n minDepth: number,\n maxDepth?: number\n): PropertyAccess[] {\n return accesses.filter((access) => {\n const depth = getPropertyDepth(access);\n if (maxDepth !== undefined) {\n return depth >= minDepth && depth <= maxDepth;\n }\n return depth >= minDepth;\n });\n}\n","/**\n * Return Value Analyzer\n * Analyzes function return statements to track data shapes and types\n */\n\nimport Parser from \"tree-sitter\";\n\nexport interface ReturnInfo {\n functionId: string;\n functionName: string;\n returnType: string | null; // Inferred type\n objectShape: ObjectShape | null; // If returns object literal\n line: number;\n returnExpression: string; // Raw return expression\n}\n\nexport interface ObjectShape {\n properties: string[]; // [\"id\", \"name\", \"email\"]\n propertyTypes: Map<string, string>; // property -> type\n nestedShapes: Map<string, ObjectShape>; // property -> nested shape\n isArray: boolean;\n isDictionary: boolean;\n isOptional: boolean;\n}\n\n/**\n * Analyze all return statements in a function\n */\nexport function analyzeReturnStatements(\n functionNode: Parser.SyntaxNode,\n functionId: string,\n functionName: string,\n filePath: string\n): ReturnInfo[] {\n const returns: ReturnInfo[] = [];\n const isJS = /\\.(js|ts|jsx|tsx)$/.test(filePath);\n const isPython = /\\.py$/.test(filePath);\n\n if (isJS) {\n extractJavaScriptReturns(functionNode, functionId, functionName, returns);\n } else if (isPython) {\n extractPythonReturns(functionNode, functionId, functionName, returns);\n }\n\n return returns;\n}\n\n/**\n * Extract return statements from JavaScript/TypeScript\n */\nfunction extractJavaScriptReturns(\n node: Parser.SyntaxNode,\n functionId: string,\n functionName: string,\n returns: ReturnInfo[]\n): void {\n traverseNode(node, (current) => {\n if (current.type === \"return_statement\") {\n const returnNode = current.children.find(\n (c) => c.type !== \"return\" && c.type !== \";\"\n );\n\n if (returnNode) {\n const returnInfo = parseJavaScriptReturnValue(\n returnNode,\n functionId,\n functionName\n );\n if (returnInfo) {\n returns.push(returnInfo);\n }\n }\n }\n });\n}\n\n/**\n * Parse JavaScript return value\n */\nfunction parseJavaScriptReturnValue(\n returnNode: Parser.SyntaxNode,\n functionId: string,\n functionName: string\n): ReturnInfo | null {\n const line = returnNode.startPosition.row + 1;\n const returnExpression = returnNode.text;\n\n let returnType: string | null = null;\n let objectShape: ObjectShape | null = null;\n\n // Pattern 1: Object literal - return { id: 1, name: \"John\" }\n if (returnNode.type === \"object\") {\n objectShape = extractJavaScriptObjectShape(returnNode);\n returnType = \"object\";\n }\n\n // Pattern 2: Array literal - return [1, 2, 3]\n else if (returnNode.type === \"array\") {\n returnType = \"array\";\n objectShape = {\n properties: [],\n propertyTypes: new Map(),\n nestedShapes: new Map(),\n isArray: true,\n isDictionary: false,\n isOptional: false,\n };\n }\n\n // Pattern 3: New expression - return new User(...)\n else if (returnNode.type === \"new_expression\") {\n const constructorNode = returnNode.childForFieldName(\"constructor\");\n if (constructorNode) {\n returnType = constructorNode.text;\n }\n }\n\n // Pattern 4: Identifier - return user\n else if (returnNode.type === \"identifier\") {\n returnType = `@var:${returnNode.text}`; // Mark as variable reference\n }\n\n // Pattern 5: Call expression - return getUser()\n else if (returnNode.type === \"call_expression\") {\n const funcNode = returnNode.childForFieldName(\"function\");\n if (funcNode) {\n returnType = `@call:${funcNode.text}`;\n }\n }\n\n return {\n functionId,\n functionName,\n returnType,\n objectShape,\n line,\n returnExpression,\n };\n}\n\n/**\n * Extract object shape from JavaScript object literal\n */\nfunction extractJavaScriptObjectShape(objectNode: Parser.SyntaxNode): ObjectShape {\n const properties: string[] = [];\n const propertyTypes = new Map<string, string>();\n const nestedShapes = new Map<string, ObjectShape>();\n\n for (const child of objectNode.children) {\n if (child.type === \"pair\") {\n const keyNode = child.childForFieldName(\"key\");\n const valueNode = child.childForFieldName(\"value\");\n\n if (keyNode) {\n const propertyName = keyNode.text.replace(/['\"]/g, \"\");\n properties.push(propertyName);\n\n if (valueNode) {\n // Infer property type\n const propertyType = inferJavaScriptType(valueNode);\n propertyTypes.set(propertyName, propertyType);\n\n // Extract nested object shape\n if (valueNode.type === \"object\") {\n const nestedShape = extractJavaScriptObjectShape(valueNode);\n nestedShapes.set(propertyName, nestedShape);\n }\n }\n }\n }\n }\n\n return {\n properties,\n propertyTypes,\n nestedShapes,\n isArray: false,\n isDictionary: false,\n isOptional: false,\n };\n}\n\n/**\n * Infer JavaScript type from value node\n */\nfunction inferJavaScriptType(valueNode: Parser.SyntaxNode): string {\n switch (valueNode.type) {\n case \"number\":\n return \"number\";\n case \"string\":\n case \"template_string\":\n return \"string\";\n case \"true\":\n case \"false\":\n return \"boolean\";\n case \"null\":\n return \"null\";\n case \"undefined\":\n return \"undefined\";\n case \"array\":\n return \"array\";\n case \"object\":\n return \"object\";\n case \"arrow_function\":\n case \"function_expression\":\n return \"function\";\n case \"identifier\":\n return `@var:${valueNode.text}`;\n case \"call_expression\":\n return \"@call\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * Extract return statements from Python\n */\nfunction extractPythonReturns(\n node: Parser.SyntaxNode,\n functionId: string,\n functionName: string,\n returns: ReturnInfo[]\n): void {\n traverseNode(node, (current) => {\n if (current.type === \"return_statement\") {\n // Find the return value (skip 'return' keyword)\n const returnNode = current.children.find((c) => c.type !== \"return\");\n\n if (returnNode) {\n const returnInfo = parsePythonReturnValue(\n returnNode,\n functionId,\n functionName\n );\n if (returnInfo) {\n returns.push(returnInfo);\n }\n }\n }\n });\n}\n\n/**\n * Parse Python return value\n */\nfunction parsePythonReturnValue(\n returnNode: Parser.SyntaxNode,\n functionId: string,\n functionName: string\n): ReturnInfo | null {\n const line = returnNode.startPosition.row + 1;\n const returnExpression = returnNode.text;\n\n let returnType: string | null = null;\n let objectShape: ObjectShape | null = null;\n\n // Pattern 1: Dictionary literal - return {\"id\": 1, \"name\": \"John\"}\n if (returnNode.type === \"dictionary\") {\n objectShape = extractPythonDictionaryShape(returnNode);\n returnType = \"dict\";\n }\n\n // Pattern 2: List literal - return [1, 2, 3]\n else if (returnNode.type === \"list\") {\n returnType = \"list\";\n objectShape = {\n properties: [],\n propertyTypes: new Map(),\n nestedShapes: new Map(),\n isArray: true,\n isDictionary: false,\n isOptional: false,\n };\n }\n\n // Pattern 3: Call expression - return User() or get_user()\n else if (returnNode.type === \"call\") {\n const funcNode = returnNode.childForFieldName(\"function\");\n if (funcNode) {\n const funcName = funcNode.text;\n // If capitalized, likely a class instantiation\n if (funcName[0] === funcName[0].toUpperCase()) {\n returnType = funcName;\n } else {\n returnType = `@call:${funcName}`;\n }\n }\n }\n\n // Pattern 4: Identifier - return user\n else if (returnNode.type === \"identifier\") {\n returnType = `@var:${returnNode.text}`;\n }\n\n // Pattern 5: List comprehension - return [x for x in items]\n else if (returnNode.type === \"list_comprehension\") {\n returnType = \"list\";\n objectShape = {\n properties: [],\n propertyTypes: new Map(),\n nestedShapes: new Map(),\n isArray: true,\n isDictionary: false,\n isOptional: false,\n };\n }\n\n return {\n functionId,\n functionName,\n returnType,\n objectShape,\n line,\n returnExpression,\n };\n}\n\n/**\n * Extract object shape from Python dictionary literal\n */\nfunction extractPythonDictionaryShape(dictNode: Parser.SyntaxNode): ObjectShape {\n const properties: string[] = [];\n const propertyTypes = new Map<string, string>();\n const nestedShapes = new Map<string, ObjectShape>();\n\n for (const child of dictNode.children) {\n if (child.type === \"pair\") {\n const keyNode = child.children.find((c) => c.type === \"string\");\n const valueNode = child.children.find(\n (c) => c.type !== \"string\" && c.type !== \":\"\n );\n\n if (keyNode) {\n // Extract string content\n const stringContent = keyNode.children.find(\n (c) => c.type === \"string_content\"\n );\n const propertyName = stringContent\n ? stringContent.text\n : keyNode.text.replace(/['\"]/g, \"\");\n\n properties.push(propertyName);\n\n if (valueNode) {\n // Infer property type\n const propertyType = inferPythonType(valueNode);\n propertyTypes.set(propertyName, propertyType);\n\n // Extract nested dictionary shape\n if (valueNode.type === \"dictionary\") {\n const nestedShape = extractPythonDictionaryShape(valueNode);\n nestedShapes.set(propertyName, nestedShape);\n }\n }\n }\n }\n }\n\n return {\n properties,\n propertyTypes,\n nestedShapes,\n isArray: false,\n isDictionary: true,\n isOptional: false,\n };\n}\n\n/**\n * Infer Python type from value node\n */\nfunction inferPythonType(valueNode: Parser.SyntaxNode): string {\n switch (valueNode.type) {\n case \"integer\":\n case \"float\":\n return \"number\";\n case \"string\":\n return \"string\";\n case \"true\":\n case \"false\":\n return \"boolean\";\n case \"none\":\n return \"None\";\n case \"list\":\n return \"list\";\n case \"dictionary\":\n return \"dict\";\n case \"lambda\":\n return \"function\";\n case \"identifier\":\n return `@var:${valueNode.text}`;\n case \"call\":\n return \"@call\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * Traverse AST node and apply visitor function\n */\nfunction traverseNode(\n node: Parser.SyntaxNode,\n visitor: (node: Parser.SyntaxNode) => void\n): void {\n visitor(node);\n\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child) {\n traverseNode(child, visitor);\n }\n }\n}\n\n/**\n * Build a map of function returns\n */\nexport function buildReturnTypeMap(returns: ReturnInfo[]): Map<string, ReturnInfo[]> {\n const map = new Map<string, ReturnInfo[]>();\n\n for (const returnInfo of returns) {\n const key = returnInfo.functionId;\n\n if (!map.has(key)) {\n map.set(key, []);\n }\n\n map.get(key)!.push(returnInfo);\n }\n\n return map;\n}\n\n/**\n * Merge multiple object shapes into one\n * (for functions with multiple return statements)\n */\nexport function mergeObjectShapes(shapes: ObjectShape[]): ObjectShape | null {\n if (shapes.length === 0) return null;\n if (shapes.length === 1) return shapes[0];\n\n // Combine all properties from all shapes\n const allProperties = new Set<string>();\n const propertyTypes = new Map<string, string>();\n const nestedShapes = new Map<string, ObjectShape>();\n let isArray = false;\n let isDictionary = false;\n\n for (const shape of shapes) {\n for (const prop of shape.properties) {\n allProperties.add(prop);\n }\n\n // Merge property types (take first occurrence)\n for (const [prop, type] of shape.propertyTypes) {\n if (!propertyTypes.has(prop)) {\n propertyTypes.set(prop, type);\n }\n }\n\n // Merge nested shapes\n for (const [prop, nested] of shape.nestedShapes) {\n if (!nestedShapes.has(prop)) {\n nestedShapes.set(prop, nested);\n }\n }\n\n isArray = isArray || shape.isArray;\n isDictionary = isDictionary || shape.isDictionary;\n }\n\n return {\n properties: Array.from(allProperties),\n propertyTypes,\n nestedShapes,\n isArray,\n isDictionary,\n isOptional: false,\n };\n}\n\n/**\n * Check if two object shapes are compatible\n */\nexport function areShapesCompatible(\n shape1: ObjectShape,\n shape2: ObjectShape\n): boolean {\n // Check if all properties in shape1 exist in shape2\n for (const prop of shape1.properties) {\n if (!shape2.properties.includes(prop)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Find missing properties between two shapes\n */\nexport function findMissingProperties(\n oldShape: ObjectShape,\n newShape: ObjectShape\n): string[] {\n const missing: string[] = [];\n\n for (const prop of oldShape.properties) {\n if (!newShape.properties.includes(prop)) {\n missing.push(prop);\n }\n }\n\n return missing;\n}\n\n/**\n * Find added properties between two shapes\n */\nexport function findAddedProperties(\n oldShape: ObjectShape,\n newShape: ObjectShape\n): string[] {\n const added: string[] = [];\n\n for (const prop of newShape.properties) {\n if (!oldShape.properties.includes(prop)) {\n added.push(prop);\n }\n }\n\n return added;\n}\n\n/**\n * Compare two object shapes and return differences\n */\nexport interface ShapeComparison {\n removedProperties: string[];\n addedProperties: string[];\n changedTypes: Array<{\n property: string;\n oldType: string;\n newType: string;\n }>;\n isCompatible: boolean;\n}\n\nexport function compareObjectShapes(\n oldShape: ObjectShape,\n newShape: ObjectShape\n): ShapeComparison {\n const removedProperties = findMissingProperties(oldShape, newShape);\n const addedProperties = findAddedProperties(oldShape, newShape);\n const changedTypes: Array<{\n property: string;\n oldType: string;\n newType: string;\n }> = [];\n\n // Check for type changes\n for (const prop of oldShape.properties) {\n if (newShape.properties.includes(prop)) {\n const oldType = oldShape.propertyTypes.get(prop);\n const newType = newShape.propertyTypes.get(prop);\n\n if (oldType && newType && oldType !== newType) {\n changedTypes.push({\n property: prop,\n oldType,\n newType,\n });\n }\n }\n }\n\n const isCompatible =\n removedProperties.length === 0 && changedTypes.length === 0;\n\n return {\n removedProperties,\n addedProperties,\n changedTypes,\n isCompatible,\n };\n}\n\n/**\n * Get property paths for all nested properties\n * E.g., { user: { profile: { name: \"John\" } } } -> [\"user\", \"user.profile\", \"user.profile.name\"]\n */\nexport function getAllPropertyPaths(shape: ObjectShape, prefix = \"\"): string[] {\n const paths: string[] = [];\n\n for (const prop of shape.properties) {\n const fullPath = prefix ? `${prefix}.${prop}` : prop;\n paths.push(fullPath);\n\n // Add nested paths\n const nested = shape.nestedShapes.get(prop);\n if (nested) {\n paths.push(...getAllPropertyPaths(nested, fullPath));\n }\n }\n\n return paths;\n}\n","/**\n * Phase 3 Storage Query Methods\n * Database queries for data flow analysis\n */\n\nimport { Database } from \"better-sqlite3\";\nimport { PropertyAccess } from \"../analysis/property-tracker.js\";\nimport { ReturnInfo, ObjectShape } from \"../analysis/return-analyzer.js\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Store property accesses in database\n */\nexport function storePropertyAccesses(\n db: Database,\n accesses: Array<PropertyAccess & { filePath?: string }>\n): void {\n const stmt = db.prepare(`\n INSERT OR REPLACE INTO property_accesses\n (id, scope_node_id, object_name, property_path, full_path, access_type, file_path, line)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insert = db.transaction((accesses: Array<PropertyAccess & { filePath?: string }>) => {\n for (const access of accesses) {\n stmt.run(\n randomUUID(),\n access.scopeId,\n access.objectName,\n JSON.stringify(access.propertyPath),\n access.fullPath,\n access.accessType,\n access.filePath || \"\",\n access.line\n );\n }\n });\n\n insert(accesses);\n}\n\n/**\n * Get all property accesses for a function\n */\nexport function getPropertyAccesses(\n db: Database,\n scopeNodeId: string\n): PropertyAccess[] {\n const stmt = db.prepare(`\n SELECT * FROM property_accesses\n WHERE scope_node_id = ?\n `);\n\n const rows = stmt.all(scopeNodeId) as any[];\n return rows.map(rowToPropertyAccess);\n}\n\n/**\n * Get all accesses to a specific property path\n */\nexport function getAccessesByPath(\n db: Database,\n fullPath: string\n): PropertyAccess[] {\n const stmt = db.prepare(`\n SELECT * FROM property_accesses\n WHERE full_path = ?\n `);\n\n const rows = stmt.all(fullPath) as any[];\n return rows.map(rowToPropertyAccess);\n}\n\n/**\n * Store return info in database\n */\nexport function storeReturnInfo(db: Database, returns: ReturnInfo[]): void {\n const stmt = db.prepare(`\n INSERT OR REPLACE INTO return_shapes\n (id, function_id, return_type, object_shape, line, return_expression)\n VALUES (?, ?, ?, ?, ?, ?)\n `);\n\n const insert = db.transaction((returns: ReturnInfo[]) => {\n for (const ret of returns) {\n stmt.run(\n randomUUID(),\n ret.functionId,\n ret.returnType,\n ret.objectShape ? JSON.stringify(serializeObjectShape(ret.objectShape)) : null,\n ret.line,\n ret.returnExpression\n );\n }\n });\n\n insert(returns);\n}\n\n/**\n * Get return info for a function\n */\nexport function getReturnInfo(db: Database, functionId: string): ReturnInfo[] {\n const stmt = db.prepare(`\n SELECT * FROM return_shapes\n WHERE function_id = ?\n `);\n\n const rows = stmt.all(functionId) as any[];\n return rows.map(rowToReturnInfo);\n}\n\n/**\n * Get all return info (for shape change detection)\n */\nexport function getAllReturnInfo(db: Database): Map<string, ReturnInfo[]> {\n const stmt = db.prepare(`SELECT * FROM return_shapes`);\n const rows = stmt.all() as any[];\n\n const map = new Map<string, ReturnInfo[]>();\n for (const row of rows) {\n const returnInfo = rowToReturnInfo(row);\n if (!map.has(returnInfo.functionId)) {\n map.set(returnInfo.functionId, []);\n }\n map.get(returnInfo.functionId)!.push(returnInfo);\n }\n\n return map;\n}\n\n/**\n * Clear Phase 3 data (for re-indexing)\n */\nexport function clearPhase3Data(db: Database): void {\n db.exec(`DELETE FROM property_accesses`);\n db.exec(`DELETE FROM return_shapes`);\n db.exec(`DELETE FROM data_flows`);\n}\n\n// Helper functions\n\nfunction rowToPropertyAccess(row: any): PropertyAccess {\n return {\n objectName: row.object_name,\n propertyPath: JSON.parse(row.property_path),\n fullPath: row.full_path,\n line: row.line,\n scopeId: row.scope_node_id,\n accessType: row.access_type,\n };\n}\n\nfunction rowToReturnInfo(row: any): ReturnInfo {\n return {\n functionId: row.function_id,\n functionName: \"\", // Will be resolved from nodes table\n returnType: row.return_type,\n objectShape: row.object_shape ? deserializeObjectShape(JSON.parse(row.object_shape)) : null,\n line: row.line,\n returnExpression: row.return_expression,\n };\n}\n\nfunction serializeObjectShape(shape: ObjectShape): any {\n return {\n properties: shape.properties,\n propertyTypes: Array.from(shape.propertyTypes.entries()),\n nestedShapes: Array.from(shape.nestedShapes.entries()).map(([key, nested]) => [\n key,\n serializeObjectShape(nested),\n ]),\n isArray: shape.isArray,\n isDictionary: shape.isDictionary,\n isOptional: shape.isOptional,\n };\n}\n\nfunction deserializeObjectShape(data: any): ObjectShape {\n return {\n properties: data.properties,\n propertyTypes: new Map(data.propertyTypes),\n nestedShapes: new Map(\n data.nestedShapes.map(([key, nested]: [string, any]) => [\n key,\n deserializeObjectShape(nested),\n ])\n ),\n isArray: data.isArray,\n isDictionary: data.isDictionary,\n isOptional: data.isOptional,\n };\n}\n","/**\n * Core types for CodeMap\n */\n\n// ============ Graph Node Types ============\n\nexport type NodeType =\n | \"file\"\n | \"function\"\n | \"class\"\n | \"method\"\n | \"variable\"\n | \"module\"\n | \"import\";\n\nexport interface GraphNode {\n id: string;\n type: NodeType;\n name: string;\n filePath: string;\n startLine: number;\n endLine: number;\n language: string;\n metadata?: Record<string, unknown>;\n}\n\n// ============ Graph Edge Types ============\n\nexport type EdgeType =\n | \"imports\"\n | \"calls\"\n | \"extends\"\n | \"implements\"\n | \"contains\"\n | \"uses\"\n | \"exports\"\n | \"depends\";\n\nexport interface GraphEdge {\n id: string;\n type: EdgeType;\n sourceId: string;\n targetId: string;\n metadata?: Record<string, unknown>;\n}\n\n// ============ Analysis Results ============\n\nexport interface FileAnalysis {\n filePath: string;\n language: string;\n nodes: GraphNode[];\n edges: GraphEdge[];\n imports: ImportInfo[];\n exports: ExportInfo[];\n variableTypes?: VariableTypeInfo[];\n databaseOperations?: DatabaseOperationInfo[];\n}\n\nexport interface VariableTypeInfo {\n variableName: string;\n typeName: string;\n scopeId: string;\n line: number;\n}\n\nexport interface DatabaseOperationInfo {\n nodeId: string;\n operation: string;\n collection: string;\n databaseType: string;\n line: number;\n}\n\nexport interface ImportInfo {\n source: string;\n specifiers: string[];\n isDefault: boolean;\n isNamespace: boolean;\n line: number;\n}\n\nexport interface ExportInfo {\n name: string;\n isDefault: boolean;\n line: number;\n}\n\n// ============ Project Analysis ============\n\nexport interface ProjectAnalysis {\n rootPath: string;\n files: FileAnalysis[];\n totalNodes: number;\n totalEdges: number;\n languages: Record<string, number>;\n analyzedAt: string;\n parseErrors?: string[];\n}\n\n// ============ Query Results ============\n\nexport interface AffectedFile {\n filePath: string;\n reason: string;\n depth: number;\n connections: string[];\n}\n\nexport interface CallChain {\n caller: GraphNode;\n callee: GraphNode;\n filePath: string;\n line: number;\n}\n\n// ============ Skill Generation ============\n\nexport interface GeneratedSkill {\n name: string;\n description: string;\n content: string;\n filePath: string;\n}\n\nexport interface SkillConfig {\n projectName: string;\n outputDir: string;\n includeArchitecture: boolean;\n includePatterns: boolean;\n includeDependencies: boolean;\n}\n\n// ============ Configuration ============\n\nexport interface CodeMapConfig {\n rootPath: string;\n include: string[];\n exclude: string[];\n languages: string[];\n dbPath: string;\n skillsOutputDir: string;\n}\n\nexport const DEFAULT_CONFIG: Partial<CodeMapConfig> = {\n include: [\"**/*.ts\", \"**/*.tsx\", \"**/*.js\", \"**/*.jsx\", \"**/*.py\"],\n exclude: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.git/**\",\n \"**/venv/**\",\n \"**/__pycache__/**\",\n \"**/.next/**\",\n ],\n languages: [\"typescript\", \"javascript\", \"python\"],\n};\n\n// ============ MCP Types ============\n\nexport interface MCPToolResult {\n content: Array<{\n type: \"text\";\n text: string;\n }>;\n}\n\nexport interface MCPResource {\n uri: string;\n name: string;\n description: string;\n mimeType: string;\n}\n","/**\n * Impact analysis command\n * Detects changes and calculates their impact on the codebase\n */\n\nimport { resolve, join, relative } from \"path\";\nimport { FlowStorage } from \"../flow/storage.js\";\nimport { FlowBuilder } from \"../flow/builder.js\";\nimport { DEFAULT_CONFIG } from \"../types.js\";\nimport {\n isGitRepository,\n getGitChangedFiles,\n parseGitDiffForFunctions,\n getGitStatus,\n type GitChangedFunction,\n} from \"../utils/git.js\";\nimport { analyzeImports, type ImportAnalysisResult } from \"../analysis/imports.js\";\nimport {\n parseDockerCompose,\n calculateServiceBlastRadius,\n type DockerDependencyGraph,\n} from \"../analysis/docker.js\";\nimport { parseLineLevelDiff } from \"../analysis/line-diff.js\";\nimport { extractRemovedCalls } from \"../analysis/removed-calls.js\";\nimport { analyzeRemovedCallImpact, type RemovedCallImpact } from \"../analysis/removed-call-impact.js\";\nimport { analyzeDataFlowImpact, getPhase3Stats } from \"./impact-phase3.js\";\n\nexport interface ImpactResult {\n changedFiles: string[];\n changedFunctions: GitChangedFunction[];\n directCallers: Map<string, { name: string; file: string; line: number }[]>;\n affectedEndpoints: string[];\n importIssues: Map<string, ImportAnalysisResult>;\n dockerImpact?: {\n affectedServices: string[];\n entryPointFiles: string[];\n };\n removedCallImpacts: RemovedCallImpact[]; // NEW\n riskLevel: \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\";\n totalImpact: number;\n}\n\nexport interface ImpactOptions {\n path?: string;\n verbose?: boolean;\n}\n\n/**\n * Analyze impact of code changes\n */\nexport async function analyzeImpact(options: ImpactOptions = {}): Promise<ImpactResult> {\n const rootPath = resolve(options.path || \".\");\n const dbPath = join(rootPath, \".codemap\", \"graph.db\");\n const storage = new FlowStorage(dbPath);\n\n try {\n // Check if git repository\n if (isGitRepository(rootPath)) {\n return await analyzeImpactWithGit(storage, rootPath, options);\n } else {\n return await analyzeImpactWithHash(storage, rootPath, options);\n }\n } finally {\n storage.close();\n }\n}\n\n/**\n * Analyze impact using git diff (precise)\n */\nasync function analyzeImpactWithGit(\n storage: FlowStorage,\n rootPath: string,\n options: ImpactOptions\n): Promise<ImpactResult> {\n // Get git status\n const gitStatus = getGitStatus(rootPath);\n if (!gitStatus.hasChanges) {\n return {\n changedFiles: [],\n changedFunctions: [],\n directCallers: new Map(),\n affectedEndpoints: [],\n importIssues: new Map(),\n removedCallImpacts: [], // NEW\n riskLevel: \"LOW\",\n totalImpact: 0,\n };\n }\n\n // Get changed files from git\n const changedFiles = getGitChangedFiles(rootPath);\n const changedFilePaths = changedFiles.map((f) => f.path);\n\n // Parse git diff to find changed functions\n const changedFunctions = parseGitDiffForFunctions(rootPath, changedFiles);\n\n // Re-index only changed files\n const builder = new FlowBuilder(storage, {\n rootPath,\n include: changedFilePaths.map((f) => f),\n exclude: [],\n forceReindex: true,\n });\n\n await builder.build();\n\n // Calculate impact for each changed function\n const directCallers = new Map<string, { name: string; file: string; line: number }[]>();\n const affectedEndpoints: string[] = [];\n\n for (const func of changedFunctions) {\n // Find all nodes matching this function name in this file\n const nodes = storage\n .getNodesByFile(join(rootPath, func.file))\n .filter((n) => n.name === func.functionName);\n\n for (const node of nodes) {\n // Get callers\n const callers = storage.getResolvedCallersWithLocation(node.id);\n if (callers.length > 0) {\n directCallers.set(func.functionName, callers);\n }\n\n // Check if this is an HTTP endpoint\n const endpoints = storage.getHttpEndpointsByHandler(node.id);\n for (const endpoint of endpoints) {\n affectedEndpoints.push(`${endpoint.method} ${endpoint.path}`);\n }\n }\n }\n\n // NEW: Analyze imports for each changed file\n const importIssues = new Map<string, ImportAnalysisResult>();\n for (const filePath of changedFilePaths) {\n const fullPath = join(rootPath, filePath);\n const analysis = analyzeImports(fullPath);\n\n if (analysis.missing.length > 0 || analysis.unused.length > 0) {\n importIssues.set(relative(rootPath, fullPath), analysis);\n }\n }\n\n // NEW: Analyze Docker Compose dependencies\n const dockerGraph = parseDockerCompose(rootPath);\n let dockerImpact: { affectedServices: string[]; entryPointFiles: string[] } | undefined;\n\n // Check if any changed file is a Docker entry point\n const entryPointFiles: string[] = [];\n const affectedServices = new Set<string>();\n\n for (const [serviceName, entryPoint] of dockerGraph.entryPoints) {\n // Check if this entry point matches any changed file\n for (const changedFile of changedFilePaths) {\n if (changedFile.includes(entryPoint) || entryPoint.includes(changedFile)) {\n entryPointFiles.push(entryPoint);\n\n // Calculate blast radius\n const blastRadius = calculateServiceBlastRadius(dockerGraph, serviceName);\n blastRadius.forEach((s) => affectedServices.add(s));\n }\n }\n }\n\n if (affectedServices.size > 0) {\n dockerImpact = {\n affectedServices: Array.from(affectedServices),\n entryPointFiles,\n };\n }\n\n // NEW: Line-level diff analysis for removed calls\n const lineDiff = parseLineLevelDiff(rootPath);\n const removedCalls = extractRemovedCalls(lineDiff.removedLines);\n const removedCallImpacts = analyzeRemovedCallImpact(removedCalls, storage);\n\n // Calculate risk level (enhanced with import, Docker, and removed calls)\n const totalCallers = Array.from(directCallers.values()).reduce((sum, callers) => sum + callers.length, 0);\n const hasCriticalImportIssues = Array.from(importIssues.values()).some((i) => i.missing.length > 0);\n const hasDockerImpact = dockerImpact && dockerImpact.affectedServices.length > 0;\n const hasCriticalRemovedCalls = removedCallImpacts.some((i) => i.severity === \"CRITICAL\");\n const hasHighRiskRemovedCalls = removedCallImpacts.some((i) => i.severity === \"HIGH\");\n\n let riskLevel: \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\" = \"LOW\";\n\n // CRITICAL: Any CRITICAL removed call or critical import + Docker issues\n if (hasCriticalRemovedCalls || (hasCriticalImportIssues && hasDockerImpact)) {\n riskLevel = \"CRITICAL\";\n } else if (\n hasHighRiskRemovedCalls ||\n hasCriticalImportIssues ||\n (hasDockerImpact && dockerImpact!.affectedServices.length > 2)\n ) {\n riskLevel = \"HIGH\";\n } else if (totalCallers > 20 || affectedEndpoints.length > 5) {\n riskLevel = \"HIGH\";\n } else if (\n totalCallers > 10 ||\n affectedEndpoints.length > 2 ||\n hasDockerImpact ||\n removedCallImpacts.length > 0\n ) {\n riskLevel = \"MEDIUM\";\n }\n\n return {\n changedFiles: changedFilePaths,\n changedFunctions,\n directCallers,\n affectedEndpoints,\n importIssues,\n dockerImpact,\n removedCallImpacts, // NEW\n riskLevel,\n totalImpact: totalCallers + (dockerImpact?.affectedServices.length || 0) + removedCallImpacts.length,\n };\n}\n\n/**\n * Analyze impact using hash comparison (fallback)\n */\nasync function analyzeImpactWithHash(\n storage: FlowStorage,\n rootPath: string,\n options: ImpactOptions\n): Promise<ImpactResult> {\n // Get all files and their hashes before re-index\n const oldHashes = storage.getAllFileHashes();\n\n // Re-index with force\n const builder = new FlowBuilder(storage, {\n rootPath,\n include: DEFAULT_CONFIG.include!,\n exclude: DEFAULT_CONFIG.exclude!,\n forceReindex: false, // Use hash comparison\n });\n\n const result = await builder.build();\n\n // Find files that were re-indexed (hash changed)\n const changedFiles: string[] = [];\n const newHashes = storage.getAllFileHashes();\n\n for (const [filePath, newHash] of Object.entries(newHashes)) {\n const oldHash = oldHashes[filePath];\n if (!oldHash || oldHash !== newHash) {\n changedFiles.push(filePath);\n }\n }\n\n // Analyze imports for changed files\n const importIssues = new Map<string, ImportAnalysisResult>();\n for (const filePath of changedFiles) {\n const analysis = analyzeImports(filePath);\n if (analysis.missing.length > 0 || analysis.unused.length > 0) {\n importIssues.set(relative(rootPath, filePath), analysis);\n }\n }\n\n // For hash-based, we can't determine specific functions or removed calls\n // Just return file-level impact\n const hasCriticalImportIssues = Array.from(importIssues.values()).some((i) => i.missing.length > 0);\n\n return {\n changedFiles,\n changedFunctions: [],\n directCallers: new Map(),\n affectedEndpoints: [],\n importIssues,\n removedCallImpacts: [], // NEW - not available in hash mode\n riskLevel: hasCriticalImportIssues\n ? \"CRITICAL\"\n : changedFiles.length > 10\n ? \"HIGH\"\n : changedFiles.length > 5\n ? \"MEDIUM\"\n : \"LOW\",\n totalImpact: result.indexed,\n };\n}\n","/**\n * Git utilities for detecting changes\n */\n\nimport { execSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface GitChangedFile {\n path: string;\n status: \"modified\" | \"added\" | \"deleted\";\n}\n\nexport interface GitChangedFunction {\n file: string;\n functionName: string;\n lineNumber: number;\n changeType: \"added\" | \"modified\" | \"deleted\";\n}\n\n/**\n * Check if directory is a git repository\n */\nexport function isGitRepository(path: string): boolean {\n return existsSync(join(path, \".git\"));\n}\n\n/**\n * Get list of changed files from git diff\n */\nexport function getGitChangedFiles(rootPath: string): GitChangedFile[] {\n try {\n // Get changed files (both staged and unstaged)\n const output = execSync(\"git diff HEAD --name-status\", {\n cwd: rootPath,\n encoding: \"utf-8\",\n }).trim();\n\n if (!output) {\n return [];\n }\n\n const files: GitChangedFile[] = [];\n for (const line of output.split(\"\\n\")) {\n const [status, path] = line.split(\"\\t\");\n if (path) {\n files.push({\n path,\n status: status === \"A\" ? \"added\" : status === \"D\" ? \"deleted\" : \"modified\",\n });\n }\n }\n\n return files;\n } catch (error) {\n return [];\n }\n}\n\n/**\n * Parse git diff to find changed functions\n */\nexport function parseGitDiffForFunctions(rootPath: string, files: GitChangedFile[]): GitChangedFunction[] {\n const changedFunctions: GitChangedFunction[] = [];\n\n for (const file of files) {\n if (file.status === \"deleted\") {\n continue;\n }\n\n try {\n // Get detailed diff for this file\n const diff = execSync(`git diff HEAD -- \"${file.path}\"`, {\n cwd: rootPath,\n encoding: \"utf-8\",\n });\n\n // Parse diff to find function definitions\n const lines = diff.split(\"\\n\");\n let currentFunction: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Look for hunk headers with function context\n // @@ -47,6 +48,8 @@ def handle_chat():\n // @@ -120,1 +121,1 @@ async def authenticate_user(token: str):\n if (line.startsWith(\"@@\")) {\n const contextMatch = line.match(/@@.*@@\\s*(.*)/);\n if (contextMatch) {\n const context = contextMatch[1];\n\n // Python: def/async def\n const pythonMatch = context.match(/(?:async\\s+)?def\\s+(\\w+)/);\n if (pythonMatch) {\n currentFunction = pythonMatch[1];\n }\n\n // TypeScript/JavaScript: function/const/class\n const jsMatch = context.match(/(?:function|const|class)\\s+(\\w+)/);\n if (jsMatch) {\n currentFunction = jsMatch[1];\n }\n\n // Extract line number\n const lineMatch = line.match(/\\+(\\d+)/);\n const lineNumber = lineMatch ? parseInt(lineMatch[1]) : 0;\n\n if (currentFunction) {\n changedFunctions.push({\n file: file.path,\n functionName: currentFunction,\n lineNumber,\n changeType: file.status === \"added\" ? \"added\" : \"modified\",\n });\n }\n }\n }\n }\n } catch (error) {\n // Skip files with diff errors\n continue;\n }\n }\n\n return changedFunctions;\n}\n\n/**\n * Get uncommitted changes summary\n */\nexport function getGitStatus(rootPath: string): {\n hasChanges: boolean;\n modifiedFiles: number;\n stagedFiles: number;\n} {\n try {\n const statusOutput = execSync(\"git status --porcelain\", {\n cwd: rootPath,\n encoding: \"utf-8\",\n }).trim();\n\n const lines = statusOutput.split(\"\\n\").filter((l) => l.trim());\n const staged = lines.filter((l) => l[0] !== \" \" && l[0] !== \"?\").length;\n const modified = lines.length;\n\n return {\n hasChanges: modified > 0,\n modifiedFiles: modified,\n stagedFiles: staged,\n };\n } catch (error) {\n return {\n hasChanges: false,\n modifiedFiles: 0,\n stagedFiles: 0,\n };\n }\n}\n","/**\n * Import dependency analyzer\n * Detects missing/unused imports and tracks what they're used for\n * Uses regex-based parsing for fast analysis\n */\n\nimport { readFileSync } from \"fs\";\n\nexport interface ImportIssue {\n identifier: string;\n line: number;\n type: \"missing\" | \"unused\";\n usedAt?: number[]; // Line numbers where it's used (for missing imports)\n}\n\nexport interface ImportAnalysisResult {\n missing: ImportIssue[];\n unused: ImportIssue[];\n}\n\n/**\n * Check if identifier is a JavaScript/TypeScript builtin\n */\nfunction isJavaScriptBuiltin(identifier: string): boolean {\n // Common JavaScript globals and keywords\n const builtins = new Set([\n \"Object\", \"Array\", \"String\", \"Number\", \"Boolean\", \"Date\", \"RegExp\",\n \"Error\", \"TypeError\", \"SyntaxError\", \"ReferenceError\",\n \"Promise\", \"Map\", \"Set\", \"WeakMap\", \"WeakSet\",\n \"JSON\", \"Math\", \"Infinity\", \"NaN\", \"undefined\",\n \"Function\", \"Symbol\", \"Proxy\", \"Reflect\",\n \"Int8Array\", \"Uint8Array\", \"Int16Array\", \"Uint16Array\",\n \"Int32Array\", \"Uint32Array\", \"Float32Array\", \"Float64Array\",\n \"BigInt\", \"ArrayBuffer\", \"DataView\",\n \"Intl\", \"WebAssembly\", \"Buffer\", \"URL\", \"URLSearchParams\",\n \"console\", \"process\", \"global\", \"window\", \"document\",\n // Common keywords that look like types\n \"TRUE\", \"FALSE\", \"NULL\",\n ]);\n\n return builtins.has(identifier);\n}\n\n/**\n * Check if identifier is a Python builtin\n */\nfunction isPythonBuiltin(identifier: string): boolean {\n const builtins = new Set([\n \"True\", \"False\", \"None\",\n \"Exception\", \"BaseException\", \"ValueError\", \"TypeError\", \"KeyError\",\n \"AttributeError\", \"IndexError\", \"RuntimeError\", \"NotImplementedError\",\n \"Dict\", \"List\", \"Tuple\", \"Set\", \"FrozenSet\",\n \"Optional\", \"Union\", \"Any\", \"Callable\",\n ]);\n\n return builtins.has(identifier);\n}\n\n/**\n * Analyze import integrity in a JavaScript/TypeScript file\n */\nexport function analyzeJavaScriptImports(filePath: string): ImportAnalysisResult {\n const content = readFileSync(filePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n // Extract imports using regex\n const imports = new Map<string, number>(); // identifier -> line number\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Match: import X from 'Y'\n const defaultMatch = line.match(/import\\s+(\\w+)\\s+from\\s+['\"]([^'\"]+)['\"]/);\n if (defaultMatch) {\n imports.set(defaultMatch[1], i + 1);\n }\n\n // Match: import { X, Y } from 'Z'\n const namedMatch = line.match(/import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]([^'\"]+)['\"]/);\n if (namedMatch) {\n const names = namedMatch[1].split(\",\").map(n => n.trim().split(\" as \")[0].trim());\n names.forEach(name => imports.set(name, i + 1));\n }\n }\n\n // Extract used identifiers (simplified - exclude comments/strings)\n const usedIdentifiers = new Map<string, number[]>(); // identifier -> line numbers\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Skip import lines and comments\n if (line.trim().startsWith(\"import \") || line.trim().startsWith(\"//\") || line.trim().startsWith(\"*\")) {\n continue;\n }\n\n // Find all identifiers in this line\n for (const [identifier] of imports) {\n // Simple regex to find identifier usage (not perfect but good enough)\n const regex = new RegExp(`\\\\b${identifier}\\\\b`, \"g\");\n if (regex.test(line)) {\n if (!usedIdentifiers.has(identifier)) {\n usedIdentifiers.set(identifier, []);\n }\n usedIdentifiers.get(identifier)!.push(i + 1);\n }\n }\n }\n\n // Find unused imports\n const unused: ImportIssue[] = [];\n for (const [identifier, line] of imports) {\n const usage = usedIdentifiers.get(identifier);\n if (!usage || usage.length === 0) {\n unused.push({ identifier, line, type: \"unused\" });\n }\n }\n\n // Find missing imports (UNIVERSAL - detect ANY identifier used but not imported)\n const missing: ImportIssue[] = [];\n\n // First, extract locally-defined identifiers (classes, functions, const)\n const localDefinitions = new Set<string>();\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Match: class ClassName\n const classMatch = line.match(/^(?:export\\s+)?class\\s+([A-Z][a-zA-Z0-9]*)/);\n if (classMatch) {\n localDefinitions.add(classMatch[1]);\n }\n\n // Match: function functionName\n const funcMatch = line.match(/^(?:export\\s+)?(?:async\\s+)?function\\s+([A-Z][a-zA-Z0-9]*)/);\n if (funcMatch) {\n localDefinitions.add(funcMatch[1]);\n }\n\n // Match: const ConstantName =\n const constMatch = line.match(/^(?:export\\s+)?const\\s+([A-Z][a-z][a-zA-Z0-9]*)\\s*=/);\n if (constMatch) {\n localDefinitions.add(constMatch[1]);\n }\n }\n\n // Extract all capitalized identifiers that look like they should be imported\n // Patterns: CapitalizedWords, UPPERCASE_CONSTANTS\n const potentialImports = new Set<string>();\n\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i];\n\n // Skip import lines, comments\n if (line.trim().startsWith(\"import \") ||\n line.trim().startsWith(\"//\") ||\n line.trim().startsWith(\"*\") ||\n line.trim().startsWith(\"#\")) {\n continue;\n }\n\n // Remove inline comments (// and /* */)\n line = line.replace(/\\/\\/.*$/g, \"\");\n line = line.replace(/\\/\\*.*?\\*\\//g, \"\");\n\n // Remove strings and template literals to avoid false positives\n line = line.replace(/[`\"'].*?[`\"']/g, \"\");\n\n // Match identifiers that look like imported types/classes\n // Pattern: PascalCase or mixedCase (not SCREAMING_SNAKE_CASE)\n // Examples: CallToolRequestSchema, Redis, MongoClient (YES)\n // Skip: LOG_LEVEL, ECONNREFUSED, MAX_VALUE (NO - these are constants)\n // Skip: obj.Property (property access chains)\n const matches = line.matchAll(/(?<!\\.)([A-Z][a-z][a-zA-Z0-9]*)(?!\\.)/g);\n for (const match of matches) {\n const identifier = match[1];\n\n // Skip common JavaScript globals and keywords\n if (!isJavaScriptBuiltin(identifier)) {\n potentialImports.add(identifier);\n }\n }\n }\n\n // Check which potential imports are actually missing\n for (const identifier of potentialImports) {\n // Skip if it's imported OR defined locally\n if (!imports.has(identifier) && !localDefinitions.has(identifier)) {\n // Find where it's used\n const usageLines: number[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match whole word only (not part of another identifier)\n const regex = new RegExp(`\\\\b${identifier}\\\\b`);\n if (regex.test(line) && !line.trim().startsWith(\"//\")) {\n usageLines.push(i + 1);\n }\n }\n\n if (usageLines.length > 0) {\n missing.push({\n identifier,\n line: usageLines[0],\n type: \"missing\",\n usedAt: usageLines,\n });\n }\n }\n }\n\n return { missing, unused };\n}\n\n/**\n * Analyze import integrity in a Python file\n */\nexport function analyzePythonImports(filePath: string): ImportAnalysisResult {\n const content = readFileSync(filePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n // Extract imports\n const imports = new Map<string, number>(); // identifier -> line number\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Match: import X\n const importMatch = line.match(/^import\\s+(\\w+)/);\n if (importMatch) {\n imports.set(importMatch[1], i + 1);\n }\n\n // Match: from X import Y\n const fromMatch = line.match(/^from\\s+[\\w.]+\\s+import\\s+(.+)/);\n if (fromMatch) {\n const names = fromMatch[1].split(\",\").map(n => n.trim().split(\" as \")[0].trim());\n names.forEach(name => imports.set(name, i + 1));\n }\n }\n\n // Extract used identifiers\n const usedIdentifiers = new Map<string, number[]>();\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Skip import lines and comments\n if (line.trim().startsWith(\"import \") || line.trim().startsWith(\"from \") || line.trim().startsWith(\"#\")) {\n continue;\n }\n\n // Find all identifiers in this line\n for (const [identifier] of imports) {\n const regex = new RegExp(`\\\\b${identifier}\\\\b`, \"g\");\n if (regex.test(line)) {\n if (!usedIdentifiers.has(identifier)) {\n usedIdentifiers.set(identifier, []);\n }\n usedIdentifiers.get(identifier)!.push(i + 1);\n }\n }\n }\n\n // Find unused imports\n const unused: ImportIssue[] = [];\n for (const [identifier, line] of imports) {\n const usage = usedIdentifiers.get(identifier);\n if (!usage || usage.length === 0) {\n unused.push({ identifier, line, type: \"unused\" });\n }\n }\n\n // Find missing imports (UNIVERSAL - detect ANY identifier used but not imported)\n const missing: ImportIssue[] = [];\n\n // First, extract locally-defined identifiers (classes, functions)\n const localDefinitions = new Set<string>();\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Match: class ClassName\n const classMatch = line.match(/^class\\s+([A-Z][a-zA-Z0-9_]*)/);\n if (classMatch) {\n localDefinitions.add(classMatch[1]);\n }\n\n // Match: def FunctionName\n const funcMatch = line.match(/^(?:async\\s+)?def\\s+([A-Z][a-zA-Z0-9_]*)/);\n if (funcMatch) {\n localDefinitions.add(funcMatch[1]);\n }\n }\n\n // Extract all capitalized identifiers (likely classes/types)\n const potentialImports = new Set<string>();\n\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i];\n\n // Skip import lines and comments\n if (line.trim().startsWith(\"import \") ||\n line.trim().startsWith(\"from \") ||\n line.trim().startsWith(\"#\")) {\n continue;\n }\n\n // Remove inline comments\n line = line.replace(/#.*$/g, \"\");\n\n // Remove strings to avoid false positives\n line = line.replace(/[`\"'f].*?[`\"']/g, \"\");\n\n // Match capitalized identifiers (likely imported classes/types)\n // Skip property access chains\n const matches = line.matchAll(/(?<!\\.)([A-Z][a-zA-Z0-9_]*)(?!\\.)/g);\n for (const match of matches) {\n const identifier = match[1];\n\n // Skip Python builtins\n if (!isPythonBuiltin(identifier)) {\n potentialImports.add(identifier);\n }\n }\n }\n\n // Check which potential imports are actually missing\n for (const identifier of potentialImports) {\n // Skip if it's imported OR defined locally\n if (!imports.has(identifier) && !localDefinitions.has(identifier)) {\n // Find where it's used\n const usageLines: number[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const regex = new RegExp(`\\\\b${identifier}\\\\b`);\n if (regex.test(line) && !line.trim().startsWith(\"#\")) {\n usageLines.push(i + 1);\n }\n }\n\n if (usageLines.length > 0) {\n missing.push({\n identifier,\n line: usageLines[0],\n type: \"missing\",\n usedAt: usageLines,\n });\n }\n }\n }\n\n return { missing, unused };\n}\n\n/**\n * Main entry point - analyzes imports based on file type\n */\nexport function analyzeImports(filePath: string): ImportAnalysisResult {\n if (filePath.endsWith(\".py\")) {\n return analyzePythonImports(filePath);\n } else if (filePath.match(/\\.(js|jsx|ts|tsx)$/)) {\n return analyzeJavaScriptImports(filePath);\n }\n\n return { missing: [], unused: [] };\n}\n","/**\n * Docker Compose dependency analyzer\n * Parses docker-compose files and Dockerfiles to build service dependency graph\n */\n\nimport { readFileSync, existsSync } from \"fs\";\nimport { load as parseYaml } from \"js-yaml\";\nimport { join } from \"path\";\n\n/**\n * Parse Dockerfile to extract CMD or ENTRYPOINT\n */\nfunction parseDockerfile(dockerfilePath: string): string | null {\n if (!existsSync(dockerfilePath)) {\n return null;\n }\n\n const content = readFileSync(dockerfilePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n // Look for CMD or ENTRYPOINT (skip HEALTHCHECK lines)\n let inHealthCheck = false;\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Track if we're in a HEALTHCHECK block\n if (line.includes(\"HEALTHCHECK\")) {\n inHealthCheck = true;\n continue;\n }\n\n // If we were in a HEALTHCHECK and this line doesn't continue it, exit HEALTHCHECK mode\n if (inHealthCheck && !line.startsWith(\" \") && !line.startsWith(\"\\t\")) {\n inHealthCheck = false;\n }\n\n // Skip CMD lines that are part of HEALTHCHECK\n if (inHealthCheck) {\n continue;\n }\n\n // CMD [\"node\", \"server.js\"]\n if (trimmed.startsWith(\"CMD\")) {\n const match = trimmed.match(/CMD\\s+\\[([^\\]]+)\\]/);\n if (match) {\n const parts = match[1].split(\",\").map((p) => p.trim().replace(/\"/g, \"\"));\n const commandStr = parts.join(\" \");\n return extractEntryPointFromCommand(commandStr);\n }\n\n // CMD node server.js\n const shellMatch = trimmed.match(/CMD\\s+(.+)/);\n if (shellMatch) {\n return extractEntryPointFromCommand(shellMatch[1]);\n }\n }\n\n // ENTRYPOINT [\"node\", \"server.js\"]\n if (trimmed.startsWith(\"ENTRYPOINT\")) {\n const match = trimmed.match(/ENTRYPOINT\\s+\\[([^\\]]+)\\]/);\n if (match) {\n const parts = match[1].split(\",\").map((p) => p.trim().replace(/\"/g, \"\"));\n const commandStr = parts.join(\" \");\n return extractEntryPointFromCommand(commandStr);\n }\n }\n }\n\n return null;\n}\n\n/**\n * Extract entry point file from a command string\n */\nfunction extractEntryPointFromCommand(command: string | string[]): string | null {\n const commandStr = Array.isArray(command) ? command.join(\" \") : command;\n\n // Match patterns like: node server.js, python -m backend.api, uvicorn main:app\n const patterns = [\n /node\\s+([^\\s]+\\.js)/,\n /python\\s+-m\\s+([\\w.]+)/,\n /python\\s+([^\\s]+\\.py)/,\n /uvicorn\\s+([\\w:]+)/,\n /npm\\s+start/,\n ];\n\n for (const pattern of patterns) {\n const match = commandStr.match(pattern);\n if (match) {\n const entryFile = match[1];\n\n // Convert to file path\n if (entryFile.endsWith(\".js\") || entryFile.endsWith(\".py\")) {\n return entryFile;\n } else if (entryFile.includes(\":\")) {\n // uvicorn main:app -> main.py\n const file = entryFile.split(\":\")[0];\n return `${file}.py`;\n } else {\n // python -m backend.api -> backend/api.py\n const file = entryFile.replace(/\\./g, \"/\");\n return `${file}.py`;\n }\n }\n }\n\n return null;\n}\n\nexport interface DockerService {\n name: string;\n dependsOn: string[];\n volumes: string[];\n entryPoint?: string;\n command?: string;\n}\n\nexport interface DockerDependencyGraph {\n services: Map<string, DockerService>;\n entryPoints: Map<string, string>; // service name -> entry point file path\n}\n\n/**\n * Parse docker-compose.yaml and build service dependency graph\n */\nexport function parseDockerCompose(projectRoot: string): DockerDependencyGraph {\n const graph: DockerDependencyGraph = {\n services: new Map(),\n entryPoints: new Map(),\n };\n\n // Find docker-compose files\n const composeFiles = [\n join(projectRoot, \"docker-compose.yaml\"),\n join(projectRoot, \"docker-compose.yml\"),\n join(projectRoot, \"compose.yaml\"),\n join(projectRoot, \"compose.yml\"),\n ];\n\n let composeData: any = null;\n\n for (const file of composeFiles) {\n if (existsSync(file)) {\n const content = readFileSync(file, \"utf-8\");\n composeData = parseYaml(content) as any;\n break;\n }\n }\n\n if (!composeData || !composeData.services) {\n return graph;\n }\n\n // Parse each service\n for (const [serviceName, serviceConfig] of Object.entries(composeData.services)) {\n const config = serviceConfig as any;\n\n const service: DockerService = {\n name: serviceName,\n dependsOn: [],\n volumes: [],\n entryPoint: config.entrypoint,\n command: config.command,\n };\n\n // Extract depends_on\n if (config.depends_on) {\n if (Array.isArray(config.depends_on)) {\n service.dependsOn = config.depends_on;\n } else if (typeof config.depends_on === \"object\") {\n service.dependsOn = Object.keys(config.depends_on);\n }\n }\n\n // Extract volumes\n if (config.volumes && Array.isArray(config.volumes)) {\n service.volumes = config.volumes\n .filter((v: string) => typeof v === \"string\")\n .map((v: string) => v.split(\":\")[0]);\n }\n\n // Try to detect entry point file from docker-compose command\n if (config.command) {\n const entryFile = extractEntryPointFromCommand(config.command);\n if (entryFile) {\n graph.entryPoints.set(serviceName, entryFile);\n }\n }\n\n // If no command in docker-compose, check Dockerfile\n if (!graph.entryPoints.has(serviceName) && config.build) {\n const buildContext = typeof config.build === \"string\" ? config.build : config.build.context;\n if (buildContext) {\n const dockerfilePath = join(projectRoot, buildContext, \"Dockerfile\");\n const entryFile = parseDockerfile(dockerfilePath);\n if (entryFile) {\n graph.entryPoints.set(serviceName, entryFile);\n }\n }\n }\n\n graph.services.set(serviceName, service);\n }\n\n return graph;\n}\n\n/**\n * Find which services depend on a given service\n */\nexport function findDependentServices(\n graph: DockerDependencyGraph,\n serviceName: string\n): string[] {\n const dependents: string[] = [];\n\n for (const [name, service] of graph.services) {\n if (service.dependsOn.includes(serviceName)) {\n dependents.push(name);\n }\n }\n\n return dependents;\n}\n\n/**\n * Calculate blast radius for a service failure\n */\nexport function calculateServiceBlastRadius(\n graph: DockerDependencyGraph,\n serviceName: string\n): string[] {\n const affected = new Set<string>();\n const queue = [serviceName];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (affected.has(current)) continue;\n\n affected.add(current);\n\n // Find services that depend on this one\n const dependents = findDependentServices(graph, current);\n queue.push(...dependents);\n }\n\n return Array.from(affected);\n}\n","/**\n * Line-Level Diff Parser\n * Parses git diff to extract exact removed/added lines with function context\n */\n\nimport { execSync } from \"child_process\";\n\nexport interface RemovedLine {\n file: string;\n lineNumber: number;\n content: string;\n inFunction?: string; // Which function this line was in\n}\n\nexport interface AddedLine {\n file: string;\n lineNumber: number;\n content: string;\n inFunction?: string;\n}\n\nexport interface ModifiedLine {\n before: RemovedLine;\n after: AddedLine;\n}\n\nexport interface LineLevelDiff {\n removedLines: RemovedLine[];\n addedLines: AddedLine[];\n modifiedLines: ModifiedLine[];\n}\n\n/**\n * Parse git diff to extract exact line changes\n */\nexport function parseLineLevelDiff(projectRoot: string): LineLevelDiff {\n try {\n // Get unified diff from git\n const diffOutput = execSync('git diff HEAD', {\n cwd: projectRoot,\n encoding: 'utf-8',\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\n });\n\n if (!diffOutput.trim()) {\n // No changes\n return {\n removedLines: [],\n addedLines: [],\n modifiedLines: [],\n };\n }\n\n return parseDiffOutput(diffOutput);\n } catch (error) {\n // Git not available or no changes\n return {\n removedLines: [],\n addedLines: [],\n modifiedLines: [],\n };\n }\n}\n\n/**\n * Parse diff output into structured format\n */\nfunction parseDiffOutput(diffOutput: string): LineLevelDiff {\n const removedLines: RemovedLine[] = [];\n const addedLines: AddedLine[] = [];\n\n let currentFile = '';\n let currentFunction = '';\n let removedLineNumber = 0;\n let addedLineNumber = 0;\n\n const lines = diffOutput.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Track current file: diff --git a/file.js b/file.js\n if (line.startsWith('diff --git')) {\n const match = line.match(/b\\/(.*?)$/);\n if (match) {\n currentFile = match[1].trim();\n }\n continue;\n }\n\n // Track line numbers and function context: @@ -42,7 +42,6 @@ function authenticate(user)\n if (line.startsWith('@@')) {\n const match = line.match(/@@ -(\\d+),\\d+ \\+(\\d+),\\d+ @@(.*)/);\n if (match) {\n removedLineNumber = parseInt(match[1]);\n addedLineNumber = parseInt(match[2]);\n\n // Extract function name from context (if available)\n const context = match[3].trim();\n if (context) {\n currentFunction = extractFunctionName(context);\n }\n }\n continue;\n }\n\n // Skip file headers\n if (line.startsWith('---') || line.startsWith('+++') || line.startsWith('index ')) {\n continue;\n }\n\n // Extract removed lines (-)\n if (line.startsWith('-') && !line.startsWith('---')) {\n const content = line.substring(1); // Remove '-' prefix\n\n // Skip empty lines and lines that are just whitespace\n if (content.trim()) {\n removedLines.push({\n file: currentFile,\n lineNumber: removedLineNumber,\n content,\n inFunction: currentFunction || undefined,\n });\n }\n\n removedLineNumber++;\n continue;\n }\n\n // Extract added lines (+)\n if (line.startsWith('+') && !line.startsWith('+++')) {\n const content = line.substring(1); // Remove '+' prefix\n\n // Skip empty lines and lines that are just whitespace\n if (content.trim()) {\n addedLines.push({\n file: currentFile,\n lineNumber: addedLineNumber,\n content,\n inFunction: currentFunction || undefined,\n });\n }\n\n addedLineNumber++;\n continue;\n }\n\n // Context line (no change)\n if (line.startsWith(' ') || !line.startsWith('-') && !line.startsWith('+')) {\n removedLineNumber++;\n addedLineNumber++;\n }\n }\n\n // Match modified lines (line changed, not just removed/added)\n const modifiedLines = matchModifiedLines(removedLines, addedLines);\n\n return {\n removedLines,\n addedLines,\n modifiedLines,\n };\n}\n\n/**\n * Extract function name from git diff context header\n */\nfunction extractFunctionName(context: string): string {\n // Remove common prefixes\n context = context.replace(/^(function|def|class|const|let|var|async|export)\\s+/, '');\n\n // Match patterns:\n // - \"function authenticate(user)\" → \"authenticate\"\n // - \"def validate_token(token):\" → \"validate_token\"\n // - \"class UserHandler {\" → \"UserHandler\"\n // - \"const handleRequest = \" → \"handleRequest\"\n // - \"authenticate(user) {\" → \"authenticate\"\n\n const patterns = [\n /^(\\w+)\\s*\\(/, // functionName(\n /^(\\w+)\\s*=/, // functionName =\n /^(\\w+)\\s*{/, // ClassName {\n /^(\\w+)\\s*:/, // functionName:\n ];\n\n for (const pattern of patterns) {\n const match = context.match(pattern);\n if (match) {\n return match[1];\n }\n }\n\n // Fallback: return first word\n const firstWord = context.split(/\\s+/)[0];\n return firstWord || '';\n}\n\n/**\n * Match removed and added lines that are modifications of the same line\n */\nfunction matchModifiedLines(\n removedLines: RemovedLine[],\n addedLines: AddedLine[]\n): ModifiedLine[] {\n const modifiedLines: ModifiedLine[] = [];\n\n // Group by file and function\n const removedByLocation = new Map<string, RemovedLine[]>();\n const addedByLocation = new Map<string, AddedLine[]>();\n\n for (const removed of removedLines) {\n const key = `${removed.file}:${removed.inFunction || 'global'}`;\n if (!removedByLocation.has(key)) {\n removedByLocation.set(key, []);\n }\n removedByLocation.get(key)!.push(removed);\n }\n\n for (const added of addedLines) {\n const key = `${added.file}:${added.inFunction || 'global'}`;\n if (!addedByLocation.has(key)) {\n addedByLocation.set(key, []);\n }\n addedByLocation.get(key)!.push(added);\n }\n\n // Match lines in the same location (same file, same function, similar line numbers)\n for (const [location, removedLinesInLocation] of removedByLocation) {\n const addedLinesInLocation = addedByLocation.get(location) || [];\n\n for (const removed of removedLinesInLocation) {\n // Find added line within ±2 lines\n const matchingAdded = addedLinesInLocation.find(\n added => Math.abs(added.lineNumber - removed.lineNumber) <= 2\n );\n\n if (matchingAdded) {\n modifiedLines.push({\n before: removed,\n after: matchingAdded,\n });\n }\n }\n }\n\n return modifiedLines;\n}\n","/**\n * Removed Call Extractor\n * Extracts function calls from removed lines of code\n */\n\nimport type { RemovedLine } from './line-diff.js';\n\nexport interface RemovedCall {\n callee: string; // Function that was called\n removedFrom: string; // Function it was removed from\n file: string;\n lineNumber: number;\n rawContent: string; // Original line content\n}\n\n/**\n * Extract function calls from removed lines\n */\nexport function extractRemovedCalls(removedLines: RemovedLine[]): RemovedCall[] {\n const removedCalls: RemovedCall[] = [];\n\n for (const line of removedLines) {\n // Parse the line content to detect function calls\n const calls = parseLineForCalls(line.content, line.file);\n\n for (const call of calls) {\n removedCalls.push({\n callee: call.name,\n removedFrom: line.inFunction || 'unknown',\n file: line.file,\n lineNumber: line.lineNumber,\n rawContent: line.content.trim(),\n });\n }\n }\n\n return removedCalls;\n}\n\n/**\n * Parse a single line to extract function calls\n */\nfunction parseLineForCalls(\n lineContent: string,\n filePath: string\n): Array<{ name: string }> {\n const calls: Array<{ name: string }> = [];\n\n // Skip comments and strings\n if (isCommentOrString(lineContent)) {\n return calls;\n }\n\n // Remove inline comments\n lineContent = lineContent.replace(/\\/\\/.*$/g, ''); // JS comments\n lineContent = lineContent.replace(/#.*$/g, ''); // Python comments\n lineContent = lineContent.replace(/\\/\\*.*?\\*\\//g, ''); // Block comments\n\n // Remove strings to avoid false positives\n lineContent = lineContent.replace(/[\"'`].*?[\"'`]/g, '');\n\n // Detect language\n const isJS = /\\.(js|ts|jsx|tsx)$/.test(filePath);\n const isPython = /\\.py$/.test(filePath);\n\n if (isJS) {\n calls.push(...extractJavaScriptCalls(lineContent));\n }\n\n if (isPython) {\n calls.push(...extractPythonCalls(lineContent));\n }\n\n return calls;\n}\n\n/**\n * Check if line is a comment or string literal\n */\nfunction isCommentOrString(line: string): boolean {\n const trimmed = line.trim();\n\n // Comments\n if (trimmed.startsWith('//') ||\n trimmed.startsWith('/*') ||\n trimmed.startsWith('*') ||\n trimmed.startsWith('#')) {\n return true;\n }\n\n // String literals (rough check)\n const stringPrefixes = ['\"', \"'\", '`'];\n if (stringPrefixes.some(prefix => trimmed.startsWith(prefix))) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Extract function calls from JavaScript/TypeScript code\n */\nfunction extractJavaScriptCalls(lineContent: string): Array<{ name: string }> {\n const calls: Array<{ name: string }> = [];\n const seen = new Set<string>();\n\n // Pattern 1: Simple function calls - functionName(...)\n // Match: validateToken(token), process(data)\n const simplePattern = /\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*\\(/g;\n let match;\n\n while ((match = simplePattern.exec(lineContent)) !== null) {\n const functionName = match[1];\n\n // Skip keywords and common false positives\n if (!isJavaScriptKeyword(functionName) && !seen.has(functionName)) {\n calls.push({ name: functionName });\n seen.add(functionName);\n }\n }\n\n // Pattern 2: Method calls - obj.method(...)\n // Match: user.authenticate(), db.query()\n const methodPattern = /\\.([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*\\(/g;\n\n while ((match = methodPattern.exec(lineContent)) !== null) {\n const methodName = match[1];\n\n if (!isJavaScriptKeyword(methodName) && !seen.has(methodName)) {\n calls.push({ name: methodName });\n seen.add(methodName);\n }\n }\n\n // Pattern 3: Async/await calls - await functionName(...)\n const awaitPattern = /await\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*\\(/g;\n\n while ((match = awaitPattern.exec(lineContent)) !== null) {\n const functionName = match[1];\n\n if (!isJavaScriptKeyword(functionName) && !seen.has(functionName)) {\n calls.push({ name: functionName });\n seen.add(functionName);\n }\n }\n\n return calls;\n}\n\n/**\n * Extract function calls from Python code\n */\nfunction extractPythonCalls(lineContent: string): Array<{ name: string }> {\n const calls: Array<{ name: string }> = [];\n const seen = new Set<string>();\n\n // Pattern 1: Simple function calls - function_name(...)\n const simplePattern = /\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\(/g;\n let match;\n\n while ((match = simplePattern.exec(lineContent)) !== null) {\n const functionName = match[1];\n\n if (!isPythonKeyword(functionName) && !seen.has(functionName)) {\n calls.push({ name: functionName });\n seen.add(functionName);\n }\n }\n\n // Pattern 2: Method calls - obj.method(...)\n const methodPattern = /\\.([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\(/g;\n\n while ((match = methodPattern.exec(lineContent)) !== null) {\n const methodName = match[1];\n\n if (!isPythonKeyword(methodName) && !seen.has(methodName)) {\n calls.push({ name: methodName });\n seen.add(methodName);\n }\n }\n\n // Pattern 3: Async/await calls\n const awaitPattern = /await\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\(/g;\n\n while ((match = awaitPattern.exec(lineContent)) !== null) {\n const functionName = match[1];\n\n if (!isPythonKeyword(functionName) && !seen.has(functionName)) {\n calls.push({ name: functionName });\n seen.add(functionName);\n }\n }\n\n return calls;\n}\n\n/**\n * Check if identifier is a JavaScript keyword\n */\nfunction isJavaScriptKeyword(identifier: string): boolean {\n const keywords = new Set([\n // Keywords\n 'if', 'else', 'for', 'while', 'do', 'switch', 'case', 'break', 'continue',\n 'return', 'throw', 'try', 'catch', 'finally', 'new', 'typeof', 'instanceof',\n 'delete', 'void', 'async', 'await', 'yield', 'import', 'export', 'from',\n 'class', 'extends', 'super', 'this', 'static', 'const', 'let', 'var',\n 'function', 'constructor', 'get', 'set',\n\n // Common builtins to skip\n 'console', 'parseInt', 'parseFloat', 'isNaN', 'isFinite',\n 'setTimeout', 'setInterval', 'clearTimeout', 'clearInterval',\n 'require', 'module', 'exports', '__dirname', '__filename',\n ]);\n\n return keywords.has(identifier);\n}\n\n/**\n * Check if identifier is a Python keyword\n */\nfunction isPythonKeyword(identifier: string): boolean {\n const keywords = new Set([\n // Keywords\n 'if', 'elif', 'else', 'for', 'while', 'break', 'continue', 'pass',\n 'return', 'raise', 'try', 'except', 'finally', 'with', 'as', 'yield',\n 'import', 'from', 'class', 'def', 'lambda', 'global', 'nonlocal',\n 'assert', 'del', 'in', 'is', 'not', 'and', 'or', 'async', 'await',\n\n // Common builtins to skip\n 'print', 'len', 'range', 'enumerate', 'zip', 'map', 'filter',\n 'sorted', 'reversed', 'sum', 'min', 'max', 'abs', 'round',\n 'open', 'input', 'type', 'isinstance', 'hasattr', 'getattr', 'setattr',\n ]);\n\n return keywords.has(identifier);\n}\n","/**\n * Removed Call Impact Analyzer\n * Calculates the impact of removed function calls using the call graph\n */\n\nimport type { FlowStorage } from '../flow/storage.js';\nimport type { RemovedCall } from './removed-calls.js';\n\nexport interface RemovedCallImpact {\n removedCall: RemovedCall;\n\n // Direct impact\n functionNode?: {\n id: string;\n name: string;\n file: string;\n line: number;\n };\n\n // Is this function still called elsewhere?\n stillCalledBy: Array<{\n name: string;\n file: string;\n line: number;\n }>;\n\n // Propagated impact: all functions that depend on removedFrom\n impactedFunctions: Array<{\n name: string;\n file: string;\n line: number;\n reason: string;\n }>;\n\n severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';\n description: string;\n}\n\n/**\n * Security/validation keywords that trigger CRITICAL severity\n */\nconst SECURITY_KEYWORDS = [\n // Authentication & Authorization\n 'authenticate', 'authorization', 'authorize', 'login', 'logout',\n 'signin', 'signout', 'verify', 'check', 'validate', 'permission',\n 'access', 'role', 'admin', 'auth',\n\n // Input validation & sanitization\n 'sanitize', 'escape', 'clean', 'filter', 'whitelist', 'blacklist',\n 'validate', 'verification', 'check',\n\n // Security tokens & sessions\n 'token', 'session', 'cookie', 'csrf', 'xsrf', 'jwt', 'oauth',\n 'api_key', 'apikey', 'secret', 'password', 'hash', 'encrypt',\n\n // Injection prevention\n 'xss', 'sql', 'injection', 'query', 'prepared', 'statement',\n\n // Rate limiting & abuse prevention\n 'ratelimit', 'throttle', 'captcha', 'honeypot',\n];\n\n/**\n * Analyze the impact of removed function calls\n */\nexport function analyzeRemovedCallImpact(\n removedCalls: RemovedCall[],\n storage: FlowStorage\n): RemovedCallImpact[] {\n const impacts: RemovedCallImpact[] = [];\n\n for (const removedCall of removedCalls) {\n try {\n const impact = analyzeSingleRemovedCall(removedCall, storage);\n if (impact) {\n impacts.push(impact);\n }\n } catch (error) {\n // Log error but continue processing other calls\n console.error(`Error analyzing removed call ${removedCall.callee}:`, error);\n }\n }\n\n return impacts;\n}\n\n/**\n * Analyze a single removed call\n */\nfunction analyzeSingleRemovedCall(\n removedCall: RemovedCall,\n storage: FlowStorage\n): RemovedCallImpact | null {\n // Step 1: Find the function node in call graph\n const nodes = storage.searchNodesByName(removedCall.callee);\n\n if (nodes.length === 0) {\n // Function not in graph (might be external library or not indexed)\n return null;\n }\n\n const functionNode = nodes[0];\n\n // Step 2: Check if function is still called elsewhere\n const allCallers = storage.getResolvedCallers(functionNode.id);\n const stillCalledBy = allCallers\n .filter(c => c.name !== removedCall.removedFrom)\n .map(c => ({\n name: c.name,\n file: c.filePath,\n line: c.startLine,\n }));\n\n // Step 3: Find all functions that call removedFrom\n // (These are the functions that are now affected)\n const removedFromNodes = storage.searchNodesByName(removedCall.removedFrom);\n\n let impactedFunctions: Array<{\n name: string;\n file: string;\n line: number;\n reason: string;\n }> = [];\n\n if (removedFromNodes.length > 0) {\n const removedFromNode = removedFromNodes[0];\n\n // Get all functions that depend on removedFrom\n // Use BFS with depth limit to prevent explosion\n const impactedNodes = storage.getImpactedNodes(removedFromNode.id, 5);\n\n impactedFunctions = impactedNodes.map(n => ({\n name: n.name,\n file: n.filePath,\n line: n.startLine,\n reason: `Calls ${removedCall.removedFrom}() which no longer calls ${removedCall.callee}()`,\n }));\n }\n\n // Step 4: Calculate severity\n const severity = calculateSeverity(\n removedCall,\n stillCalledBy,\n impactedFunctions\n );\n\n // Step 5: Build description\n const description = buildImpactDescription(\n removedCall,\n stillCalledBy,\n impactedFunctions,\n severity\n );\n\n return {\n removedCall,\n functionNode: {\n id: functionNode.id,\n name: functionNode.name,\n file: functionNode.filePath,\n line: functionNode.startLine,\n },\n stillCalledBy,\n impactedFunctions,\n severity,\n description,\n };\n}\n\n/**\n * Calculate severity based on impact\n */\nfunction calculateSeverity(\n removedCall: RemovedCall,\n stillCalledBy: Array<{ name: string }>,\n impactedFunctions: Array<{ name: string }>\n): 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' {\n // Check if this is a security/validation function\n const isSecurityFunction = SECURITY_KEYWORDS.some(keyword =>\n removedCall.callee.toLowerCase().includes(keyword)\n );\n\n // CRITICAL: Security function removed and has significant impact\n if (isSecurityFunction && impactedFunctions.length > 5) {\n return 'CRITICAL';\n }\n\n // CRITICAL: Security function removed and now orphaned\n if (isSecurityFunction && stillCalledBy.length === 0) {\n return 'CRITICAL';\n }\n\n // HIGH: Function is now orphaned (not called anywhere)\n if (stillCalledBy.length === 0) {\n return 'HIGH';\n }\n\n // HIGH: Large impact (>20 impacted functions)\n if (impactedFunctions.length > 20) {\n return 'HIGH';\n }\n\n // MEDIUM: Moderate impact (10-20 impacted functions)\n if (impactedFunctions.length >= 10) {\n return 'MEDIUM';\n }\n\n // MEDIUM: Security function with any impact\n if (isSecurityFunction && impactedFunctions.length > 0) {\n return 'MEDIUM';\n }\n\n // LOW: Small impact (<10 impacted functions)\n return 'LOW';\n}\n\n/**\n * Build human-readable impact description\n */\nfunction buildImpactDescription(\n removedCall: RemovedCall,\n stillCalledBy: Array<{ name: string; file: string }>,\n impactedFunctions: Array<{ name: string }>,\n severity: string\n): string {\n const parts: string[] = [];\n\n // Main statement\n parts.push(\n `${removedCall.callee}() was removed from ${removedCall.removedFrom}() at line ${removedCall.lineNumber}`\n );\n\n // Orphaned warning\n if (stillCalledBy.length === 0) {\n parts.push(`⚠️ ORPHANED: ${removedCall.callee}() is no longer called anywhere in the codebase`);\n } else {\n // Still called by others\n const callerNames = stillCalledBy.slice(0, 3).map(c => c.name).join(', ');\n const moreCount = stillCalledBy.length > 3 ? ` and ${stillCalledBy.length - 3} more` : '';\n parts.push(`Still called by: ${callerNames}${moreCount}`);\n }\n\n // Impact count\n if (impactedFunctions.length > 0) {\n parts.push(\n `Impact: ${impactedFunctions.length} function${impactedFunctions.length === 1 ? '' : 's'} ` +\n `depend on ${removedCall.removedFrom}()`\n );\n }\n\n // Security warning\n if (severity === 'CRITICAL') {\n parts.push('🔴 CRITICAL: Security or validation function removed from execution path');\n }\n\n return parts.join('\\n');\n}\n"],"mappings":"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","names":["resolve","join","existsSync","readFileSync","readFileSync","methodNode","lines","fileNode","Parser","Parser","lines","fileNode","traverseNode","accesses","returns","readFileSync","resolve","join","relative","readFileSync","readFileSync","existsSync","join","execSync","resolve","join","relative","join","existsSync","readFileSync","resolve"]}
|