codemap-ai 3.1.1 → 3.2.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/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"],"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.1.1\");\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 // Show risk level\n console.log(chalk.blue(\"\\n Risk Assessment:\\n\"));\n const riskColor = result.riskLevel === \"HIGH\" ? chalk.red : result.riskLevel === \"MEDIUM\" ? chalk.yellow : chalk.green;\n console.log(` ${riskColor(result.riskLevel)} - ${result.totalImpact} functions affected`);\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 } 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\";\n\nexport interface ImpactResult {\n changedFiles: string[];\n changedFunctions: GitChangedFunction[];\n directCallers: Map<string, { name: string; file: string; line: number }[]>;\n affectedEndpoints: string[];\n riskLevel: \"LOW\" | \"MEDIUM\" | \"HIGH\";\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 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 // Calculate risk level\n const totalCallers = Array.from(directCallers.values()).reduce((sum, callers) => sum + callers.length, 0);\n let riskLevel: \"LOW\" | \"MEDIUM\" | \"HIGH\" = \"LOW\";\n if (totalCallers > 20 || affectedEndpoints.length > 5) {\n riskLevel = \"HIGH\";\n } else if (totalCallers > 10 || affectedEndpoints.length > 2) {\n riskLevel = \"MEDIUM\";\n }\n\n return {\n changedFiles: changedFilePaths,\n changedFunctions,\n directCallers,\n affectedEndpoints,\n riskLevel,\n totalImpact: totalCallers,\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 // For hash-based, we can't determine specific functions\n // Just return file-level impact\n return {\n changedFiles,\n changedFunctions: [],\n directCallers: new Map(),\n affectedEndpoints: [],\n riskLevel: changedFiles.length > 10 ? \"HIGH\" : changedFiles.length > 5 ? \"MEDIUM\" : \"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"],"mappings":";;;;;;;AAKA,SAAS,eAAe;AACxB,SAAS,WAAAA,UAAS,QAAAC,aAAY;AAC9B,SAAS,cAAAC,aAAY,WAAW,gBAAAC,eAAc,qBAAqB;AACnE,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,SAAS;;;ACLhB,SAAS,cAAc,gBAAgB;AACvC,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AACrB,SAAS,SAAS,UAA6B,eAAe;;;ACIvD,IAAe,aAAf,MAA4C;AAAA,EAIvC,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAIhB,eAAe,UAAkB,MAAc,MAAsB;AAC7E,WAAO,GAAG,QAAQ,IAAI,IAAI,IAAI,IAAI;AAAA,EACpC;AAAA,EAEU,iBAAyB;AACjC,WAAO,QAAQ,EAAE,KAAK,aAAa;AAAA,EACrC;AAAA,EAEU,WACR,MACA,MACA,UACA,WACA,SACA,UACW;AACX,WAAO;AAAA,MACL,IAAI,KAAK,eAAe,UAAU,MAAM,SAAS;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAEU,WACR,MACA,UACA,UACA,UACW;AACX,WAAO;AAAA,MACL,IAAI,KAAK,eAAe;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEU,oBAAoB,UAAgC;AAC5D,WAAO;AAAA,MACL;AAAA,MACA,UAAU,KAAK;AAAA,MACf,OAAO,CAAC;AAAA,MACR,OAAO,CAAC;AAAA,MACR,SAAS,CAAC;AAAA,MACV,SAAS,CAAC;AAAA,IACZ;AAAA,EACF;AACF;AAKO,IAAM,iBAAN,MAAqB;AAAA,EAClB,UAA+B,oBAAI,IAAI;AAAA,EACvC,eAAoC,oBAAI,IAAI;AAAA,EAEpD,SAAS,QAAsB;AAC7B,SAAK,QAAQ,IAAI,OAAO,UAAU,MAAM;AACxC,eAAW,OAAO,OAAO,YAAY;AACnC,WAAK,aAAa,IAAI,KAAK,MAAM;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,cAAc,UAAsC;AAClD,WAAO,KAAK,QAAQ,IAAI,QAAQ;AAAA,EAClC;AAAA,EAEA,eAAe,WAAuC;AAEpD,UAAM,MAAM,UAAU,WAAW,GAAG,IAAI,YAAY,IAAI,SAAS;AACjE,WAAO,KAAK,aAAa,IAAI,GAAG;AAAA,EAClC;AAAA,EAEA,WAAW,UAAsC;AAC/C,UAAM,MAAM,SAAS,UAAU,SAAS,YAAY,GAAG,CAAC;AACxD,WAAO,KAAK,eAAe,GAAG;AAAA,EAChC;AAAA,EAEA,yBAAmC;AACjC,WAAO,MAAM,KAAK,KAAK,aAAa,KAAK,CAAC;AAAA,EAC5C;AAAA,EAEA,wBAAkC;AAChC,WAAO,MAAM,KAAK,KAAK,QAAQ,KAAK,CAAC;AAAA,EACvC;AACF;AAEO,IAAM,iBAAiB,IAAI,eAAe;;;AC9GjD,OAAO,YAAY;AACnB,OAAO,gBAAgB;AACvB,OAAO,gBAAgB;AAIhB,IAAM,mBAAN,cAA+B,WAAW;AAAA,EAC/C,WAAW;AAAA,EACX,aAAa,CAAC,OAAO,MAAM;AAAA,EAEnB;AAAA,EAER,cAAc;AACZ,UAAM;AACN,SAAK,SAAS,IAAI,OAAO;AACzB,SAAK,OAAO,YAAY,WAAW,UAAU;AAAA,EAC/C;AAAA,EAEA,MAAM,UAAkB,SAA+B;AACrD,UAAM,WAAW,KAAK,oBAAoB,QAAQ;AAGlD,UAAM,aAAa,OAAO,YAAY,WAAW,UAAU,OAAO,OAAO;AAGzE,QAAI,WAAW,SAAS,KAAQ;AAC9B,YAAMC,SAAQ,WAAW,MAAM,IAAI;AACnC,YAAMC,YAAW,KAAK;AAAA,QACpB;AAAA,QACA,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,QAC7B;AAAA,QACA;AAAA,QACAD,OAAM;AAAA,MACR;AACA,eAAS,MAAM,KAAKC,SAAQ;AAC5B,aAAO;AAAA,IACT;AAGA,QAAI,SAAS,SAAS,MAAM,GAAG;AAC7B,WAAK,OAAO,YAAY,WAAW,GAAG;AAAA,IACxC,OAAO;AACL,WAAK,OAAO,YAAY,WAAW,UAAU;AAAA,IAC/C;AAEA,QAAI;AACJ,QAAI;AACF,aAAO,KAAK,OAAO,MAAM,UAAU;AAAA,IACrC,QAAQ;AAEN,YAAMD,SAAQ,WAAW,MAAM,IAAI;AACnC,YAAMC,YAAW,KAAK;AAAA,QACpB;AAAA,QACA,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,QAC7B;AAAA,QACA;AAAA,QACAD,OAAM;AAAA,MACR;AACA,eAAS,MAAM,KAAKC,SAAQ;AAC5B,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,WAAW,MAAM,IAAI;AAGnC,UAAM,WAAW,KAAK;AAAA,MACpB;AAAA,MACA,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,MAAM;AAAA,IACR;AACA,aAAS,MAAM,KAAK,QAAQ;AAG5B,SAAK,SAAS,KAAK,UAAU,UAAU,UAAU,SAAS,EAAE;AAE5D,WAAO;AAAA,EACT;AAAA,EAEQ,SACN,MACA,UACA,UACA,UACM;AACN,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,aAAK,aAAa,MAAM,QAAQ;AAChC;AAAA,MAEF,KAAK;AACH,aAAK,aAAa,MAAM,UAAU,UAAU,QAAQ;AACpD;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,aAAK,eAAe,MAAM,UAAU,UAAU,QAAQ;AACtD;AAAA,MAEF,KAAK;AACH,aAAK,YAAY,MAAM,UAAU,UAAU,QAAQ;AACnD;AAAA,MAEF,KAAK;AACH,aAAK,aAAa,MAAM,UAAU,UAAU,QAAQ;AACpD;AAAA,MAEF,KAAK;AACH,aAAK,WAAW,MAAM,UAAU,UAAU,QAAQ;AAClD;AAAA,MAEF,KAAK;AACH,aAAK,eAAe,MAAM,UAAU,UAAU,QAAQ;AACtD;AAAA,IACJ;AAGA,eAAW,SAAS,KAAK,UAAU;AACjC,WAAK,SAAS,OAAO,UAAU,UAAU,QAAQ;AAAA,IACnD;AAAA,EACF;AAAA,EAEQ,aAAa,MAAyB,UAA8B;AAC1E,UAAM,aAAa,KAAK,kBAAkB,QAAQ;AAClD,QAAI,CAAC,WAAY;AAEjB,UAAM,SAAS,WAAW,KAAK,QAAQ,SAAS,EAAE;AAClD,UAAM,aAAuB,CAAC;AAC9B,QAAI,YAAY;AAChB,QAAI,cAAc;AAGlB,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,MAAM,SAAS,iBAAiB;AAClC,mBAAW,eAAe,MAAM,UAAU;AACxC,cAAI,YAAY,SAAS,cAAc;AACrC,uBAAW,KAAK,YAAY,IAAI;AAChC,wBAAY;AAAA,UACd,WAAW,YAAY,SAAS,oBAAoB;AAClD,0BAAc;AACd,kBAAM,WAAW,YAAY,kBAAkB,MAAM;AACrD,gBAAI,SAAU,YAAW,KAAK,SAAS,IAAI;AAAA,UAC7C,WAAW,YAAY,SAAS,iBAAiB;AAC/C,uBAAW,cAAc,YAAY,UAAU;AAC7C,kBAAI,WAAW,SAAS,oBAAoB;AAC1C,sBAAM,OAAO,WAAW,kBAAkB,MAAM;AAChD,oBAAI,KAAM,YAAW,KAAK,KAAK,IAAI;AAAA,cACrC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,aAAS,QAAQ,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,KAAK,cAAc,MAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAEQ,aACN,MACA,UACA,UACA,UACM;AACN,UAAM,YAAY,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS;AAGhE,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,MAAM,SAAS,wBAAwB;AACzC,cAAM,WAAW,MAAM,kBAAkB,MAAM;AAC/C,YAAI,UAAU;AACZ,mBAAS,QAAQ,KAAK;AAAA,YACpB,MAAM,SAAS;AAAA,YACf;AAAA,YACA,MAAM,KAAK,cAAc,MAAM;AAAA,UACjC,CAAC;AAAA,QACH;AACA,aAAK,eAAe,OAAO,UAAU,UAAU,QAAQ;AAAA,MACzD,WAAW,MAAM,SAAS,qBAAqB;AAC7C,cAAM,WAAW,MAAM,kBAAkB,MAAM;AAC/C,YAAI,UAAU;AACZ,mBAAS,QAAQ,KAAK;AAAA,YACpB,MAAM,SAAS;AAAA,YACf;AAAA,YACA,MAAM,KAAK,cAAc,MAAM;AAAA,UACjC,CAAC;AAAA,QACH;AACA,aAAK,YAAY,OAAO,UAAU,UAAU,QAAQ;AAAA,MACtD,WAAW,MAAM,SAAS,cAAc;AACtC,iBAAS,QAAQ,KAAK;AAAA,UACpB,MAAM,MAAM;AAAA,UACZ;AAAA,UACA,MAAM,KAAK,cAAc,MAAM;AAAA,QACjC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eACN,MACA,UACA,UACA,UACM;AACN,QAAI,OAAO;AACX,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAI,UAAU;AACZ,aAAO,SAAS;AAAA,IAClB;AAEA,UAAM,WAAW,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,cAAc,MAAM;AAAA,MACzB,KAAK,YAAY,MAAM;AAAA,MACvB;AAAA,QACE,OAAO,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAAA,QACnD,WAAW,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG;AAAA,MACrD;AAAA,IACF;AAEA,aAAS,MAAM,KAAK,QAAQ;AAG5B,aAAS,MAAM;AAAA,MACb,KAAK,WAAW,YAAY,UAAU,SAAS,EAAE;AAAA,IACnD;AAAA,EACF;AAAA,EAEQ,YACN,MACA,UACA,UACA,UACM;AACN,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAI,CAAC,SAAU;AAEf,UAAM,YAAY,KAAK;AAAA,MACrB;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,KAAK,cAAc,MAAM;AAAA,MACzB,KAAK,YAAY,MAAM;AAAA,IACzB;AAEA,aAAS,MAAM,KAAK,SAAS;AAG7B,aAAS,MAAM;AAAA,MACb,KAAK,WAAW,YAAY,UAAU,UAAU,EAAE;AAAA,IACpD;AAGA,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,MAAM,SAAS,kBAAkB;AACnC,cAAM,gBAAgB,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,gBAAgB;AAC5E,YAAI,eAAe;AACjB,gBAAM,YAAY,cAAc,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY;AAC5E,cAAI,WAAW;AAEb,qBAAS,MAAM;AAAA,cACb,KAAK,WAAW,WAAW,UAAU,IAAI,OAAO,UAAU,IAAI,IAAI;AAAA,gBAChE,gBAAgB,UAAU;AAAA,cAC5B,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,OAAO,KAAK,kBAAkB,MAAM;AAC1C,QAAI,MAAM;AACR,iBAAW,UAAU,KAAK,UAAU;AAClC,YAAI,OAAO,SAAS,qBAAqB;AACvC,eAAK,aAAa,QAAQ,UAAU,UAAU,UAAU,EAAE;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,aACN,MACA,UACA,UACA,UACM;AACN,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAI,CAAC,SAAU;AAEf,UAAM,aAAa,KAAK;AAAA,MACtB;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,KAAK,cAAc,MAAM;AAAA,MACzB,KAAK,YAAY,MAAM;AAAA,MACvB;AAAA,QACE,QAAQ,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAAA,QACrD,OAAO,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAAA,MACrD;AAAA,IACF;AAEA,aAAS,MAAM,KAAK,UAAU;AAG9B,aAAS,MAAM;AAAA,MACb,KAAK,WAAW,YAAY,UAAU,WAAW,EAAE;AAAA,IACrD;AAAA,EACF;AAAA,EAEQ,WACN,MACA,UACA,UACA,UACM;AACN,UAAM,WAAW,KAAK,kBAAkB,UAAU;AAClD,QAAI,CAAC,SAAU;AAEf,QAAI,aAAa;AACjB,QAAI,SAAS,SAAS,cAAc;AAClC,mBAAa,SAAS;AAAA,IACxB,WAAW,SAAS,SAAS,qBAAqB;AAEhD,mBAAa,SAAS;AAAA,IACxB;AAEA,QAAI,YAAY;AACd,eAAS,MAAM;AAAA,QACb,KAAK,WAAW,SAAS,UAAU,OAAO,UAAU,IAAI;AAAA,UACtD,gBAAgB;AAAA,UAChB,MAAM,KAAK,cAAc,MAAM;AAAA,QACjC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eACN,MACA,UACA,UACA,UACM;AACN,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,MAAM,SAAS,uBAAuB;AACxC,cAAM,WAAW,MAAM,kBAAkB,MAAM;AAC/C,cAAM,YAAY,MAAM,kBAAkB,OAAO;AAEjD,YAAI,YAAY,SAAS,SAAS,cAAc;AAE9C,cACE,cACC,UAAU,SAAS,oBAClB,UAAU,SAAS,wBACrB;AACA,kBAAM,WAAW,KAAK;AAAA,cACpB;AAAA,cACA,SAAS;AAAA,cACT;AAAA,cACA,KAAK,cAAc,MAAM;AAAA,cACzB,KAAK,YAAY,MAAM;AAAA,cACvB;AAAA,gBACE,MAAM,KAAK,SAAS,CAAC,GAAG,QAAQ;AAAA,cAClC;AAAA,YACF;AACA,qBAAS,MAAM,KAAK,QAAQ;AAC5B,qBAAS,MAAM;AAAA,cACb,KAAK,WAAW,YAAY,UAAU,SAAS,EAAE;AAAA,YACnD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,mBAAN,cAA+B,iBAAiB;AAAA,EACrD,WAAW;AAAA,EACX,aAAa,CAAC,OAAO,QAAQ,QAAQ,MAAM;AAAA,EAE3C,cAAc;AACZ,UAAM;AAEN,IAAC,KAAa,SAAS,IAAI,OAAO;AAClC,IAAC,KAAa,OAAO,YAAY,UAAU;AAAA,EAC7C;AAAA,EAEA,MAAM,UAAkB,SAA+B;AAErD,UAAM,aAAa,OAAO,YAAY,WAAW,UAAU,OAAO,OAAO;AAGzE,QAAI,SAAS,SAAS,MAAM,GAAG;AAE7B,MAAC,KAAa,OAAO,YAAY,WAAW,GAAG;AAAA,IACjD,OAAO;AACL,MAAC,KAAa,OAAO,YAAY,UAAU;AAAA,IAC7C;AAGA,UAAM,WAAW,MAAM,MAAM,UAAU,UAAU;AACjD,aAAS,WAAW;AACpB,eAAW,QAAQ,SAAS,OAAO;AACjC,WAAK,WAAW;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AACF;;;AChaA,OAAOC,aAAY;AACnB,OAAO,YAAY;AAIZ,IAAM,eAAN,cAA2B,WAAW;AAAA,EAC3C,WAAW;AAAA,EACX,aAAa,CAAC,KAAK;AAAA,EAEX;AAAA,EAER,cAAc;AACZ,UAAM;AACN,SAAK,SAAS,IAAIC,QAAO;AACzB,SAAK,OAAO,YAAY,MAAM;AAAA,EAChC;AAAA,EAEA,MAAM,UAAkB,SAA+B;AACrD,UAAM,WAAW,KAAK,oBAAoB,QAAQ;AAGlD,UAAM,aAAa,OAAO,YAAY,WAAW,UAAU,OAAO,OAAO;AAGzE,QAAI,WAAW,SAAS,KAAQ;AAC9B,YAAMC,SAAQ,WAAW,MAAM,IAAI;AACnC,YAAMC,YAAW,KAAK;AAAA,QACpB;AAAA,QACA,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,QAC7B;AAAA,QACA;AAAA,QACAD,OAAM;AAAA,MACR;AACA,eAAS,MAAM,KAAKC,SAAQ;AAC5B,aAAO;AAAA,IACT;AAEA,QAAI;AACJ,QAAI;AAGF,aAAO,KAAK,OAAO,MAAM,CAAC,OAAO,aAAa;AAC5C,YAAI,SAAS,WAAW,QAAQ;AAC9B,iBAAO;AAAA,QACT;AACA,cAAM,WAAW,KAAK,IAAI,QAAQ,MAAM,WAAW,MAAM;AACzD,eAAO,WAAW,UAAU,OAAO,QAAQ;AAAA,MAC7C,CAAC;AAAA,IACH,SAAS,OAAO;AAEd,YAAMD,SAAQ,WAAW,MAAM,IAAI;AACnC,YAAMC,YAAW,KAAK;AAAA,QACpB;AAAA,QACA,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,QAC7B;AAAA,QACA;AAAA,QACAD,OAAM;AAAA,MACR;AACA,eAAS,MAAM,KAAKC,SAAQ;AAC5B,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,WAAW,MAAM,IAAI;AAGnC,UAAM,WAAW,KAAK;AAAA,MACpB;AAAA,MACA,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,MAAM;AAAA,IACR;AACA,aAAS,MAAM,KAAK,QAAQ;AAG5B,SAAK,SAAS,KAAK,UAAU,UAAU,UAAU,SAAS,EAAE;AAE5D,WAAO;AAAA,EACT;AAAA,EAEQ,SACN,MACA,UACA,UACA,UACM;AACN,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,aAAK,aAAa,MAAM,QAAQ;AAChC;AAAA,MAEF,KAAK;AACH,aAAK,iBAAiB,MAAM,QAAQ;AACpC;AAAA,MAEF,KAAK;AACH,aAAK,eAAe,MAAM,UAAU,UAAU,QAAQ;AACtD;AAAA;AAAA,MAEF,KAAK;AACH,aAAK,YAAY,MAAM,UAAU,UAAU,QAAQ;AACnD;AAAA;AAAA,MAEF,KAAK;AACH,aAAK,WAAW,MAAM,UAAU,UAAU,QAAQ;AAClD;AAAA,IACJ;AAGA,eAAW,SAAS,KAAK,UAAU;AACjC,WAAK,SAAS,OAAO,UAAU,UAAU,QAAQ;AAAA,IACnD;AAAA,EACF;AAAA,EAEQ,aAAa,MAAyB,UAA8B;AAE1E,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,MAAM,SAAS,eAAe;AAChC,iBAAS,QAAQ,KAAK;AAAA,UACpB,QAAQ,MAAM;AAAA,UACd,YAAY,CAAC,MAAM,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,MAAM,IAAI;AAAA,UACtD,WAAW;AAAA,UACX,aAAa;AAAA,UACb,MAAM,KAAK,cAAc,MAAM;AAAA,QACjC,CAAC;AAAA,MACH,WAAW,MAAM,SAAS,kBAAkB;AAC1C,cAAM,WAAW,MAAM,kBAAkB,MAAM;AAC/C,cAAM,YAAY,MAAM,kBAAkB,OAAO;AACjD,YAAI,UAAU;AACZ,mBAAS,QAAQ,KAAK;AAAA,YACpB,QAAQ,SAAS;AAAA,YACjB,YAAY,CAAC,WAAW,QAAQ,SAAS,IAAI;AAAA,YAC7C,WAAW;AAAA,YACX,aAAa;AAAA,YACb,MAAM,KAAK,cAAc,MAAM;AAAA,UACjC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBAAiB,MAAyB,UAA8B;AAE9E,UAAM,aAAa,KAAK,kBAAkB,aAAa;AACvD,QAAI,CAAC,WAAY;AAEjB,UAAM,SAAS,WAAW;AAC1B,UAAM,aAAuB,CAAC;AAE9B,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,MAAM,SAAS,iBAAiB;AAElC;AAAA,MACF;AAEA,UAAI,MAAM,SAAS,iBAAiB,UAAU,YAAY;AACxD,mBAAW,KAAK,MAAM,IAAI;AAAA,MAC5B,WAAW,MAAM,SAAS,kBAAkB;AAC1C,cAAM,WAAW,MAAM,kBAAkB,MAAM;AAC/C,YAAI,UAAU;AACZ,qBAAW,KAAK,SAAS,IAAI;AAAA,QAC/B;AAAA,MACF,WAAW,MAAM,SAAS,mBAAmB;AAC3C,mBAAW,KAAK,GAAG;AAAA,MACrB;AAAA,IACF;AAEA,QAAI,WAAW,WAAW,GAAG;AAE3B,iBAAW,SAAS,KAAK,UAAU;AACjC,YAAI,MAAM,SAAS,iBAAiB,MAAM,SAAS,yBAAyB;AAC1E,qBAAW,QAAQ,MAAM,UAAU;AACjC,gBAAI,KAAK,SAAS,iBAAiB,KAAK,SAAS,cAAc;AAC7D,yBAAW,KAAK,KAAK,IAAI;AAAA,YAC3B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,aAAS,QAAQ,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,aAAa,WAAW,SAAS,GAAG;AAAA,MACpC,MAAM,KAAK,cAAc,MAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAEQ,eACN,MACA,UACA,UACA,UACM;AACN,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAI,CAAC,SAAU;AAEf,UAAM,OAAO,SAAS;AAGtB,UAAM,aAAuB,CAAC;AAC9B,UAAM,mBAA6F,CAAC;AAGpG,QAAI,KAAK,QAAQ,SAAS,wBAAwB;AAEhD,iBAAW,WAAW,KAAK,OAAO,UAAU;AAC1C,YAAI,QAAQ,SAAS,aAAa;AAEhC,gBAAM,gBAAgB,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AACpE,gBAAM,gBAAgB,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,SAAS,YAAY;AAEpG,cAAI,eAAe;AAEjB,kBAAM,WAAW,cAAc,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,SAAS,YAAY;AACrG,gBAAI,UAAU;AACZ,oBAAM,gBAAgB,SAAS;AAC/B,yBAAW,KAAK,aAAa;AAG7B,oBAAM,OAAiB,CAAC;AACxB,oBAAM,SAAiC,CAAC;AACxC,oBAAM,UAAU,cAAc,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,eAAe;AAC7E,kBAAI,SAAS;AACX,2BAAW,OAAO,QAAQ,UAAU;AAClC,sBAAI,IAAI,SAAS,UAAU;AAEzB,0BAAM,gBAAgB,IAAI,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,gBAAgB;AAC1E,0BAAM,UAAU,gBAAgB,cAAc,OAAO,IAAI,KAAK,QAAQ,gBAAgB,EAAE;AACxF,yBAAK,KAAK,OAAO;AAAA,kBACnB,WAAW,IAAI,SAAS,oBAAoB;AAE1C,0BAAM,UAAU,IAAI,kBAAkB,MAAM;AAC5C,0BAAM,YAAY,IAAI,kBAAkB,OAAO;AAC/C,wBAAI,WAAW,WAAW;AACxB,4BAAM,MAAM,QAAQ;AACpB,0BAAI,QAAQ,UAAU;AAEtB,0BAAI,UAAU,SAAS,QAAQ;AAC7B,8BAAM,QAAkB,CAAC;AACzB,mCAAW,SAAS,UAAU,UAAU;AACtC,8BAAI,MAAM,SAAS,UAAU;AAC3B,kCAAM,gBAAgB,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,gBAAgB;AAC5E,kCAAM,KAAK,gBAAgB,cAAc,OAAO,MAAM,KAAK,QAAQ,gBAAgB,EAAE,CAAC;AAAA,0BACxF;AAAA,wBACF;AACA,gCAAQ,MAAM,SAAS,IAAI,MAAM,KAAK,GAAG,IAAI;AAAA,sBAC/C;AACA,6BAAO,GAAG,IAAI;AAAA,oBAChB;AAAA,kBACF,WAAW,IAAI,SAAS,cAAc;AAEpC,yBAAK,KAAK,IAAI,IAAI;AAAA,kBACpB;AAAA,gBACF;AAAA,cACF;AAEA,+BAAiB,KAAK,EAAE,MAAM,eAAe,MAAM,OAAO,CAAC;AAAA,YAC7D;AAAA,UACF,WAAW,eAAe;AAExB,kBAAM,gBAAgB,cAAc;AACpC,uBAAW,KAAK,aAAa;AAC7B,6BAAiB,KAAK,EAAE,MAAM,eAAe,MAAM,CAAC,EAAE,CAAC;AAAA,UACzD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,UAAU,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAG5D,QAAI;AACJ,UAAM,iBAAiB,KAAK,kBAAkB,aAAa;AAC3D,QAAI,gBAAgB;AAClB,mBAAa,eAAe;AAE5B,mBAAa,WAAW,QAAQ,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK;AAAA,IAClE;AAEA,UAAM,WAAW,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,cAAc,MAAM;AAAA,MACzB,KAAK,YAAY,MAAM;AAAA,MACvB;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,kBAAkB,KAAK,UAAU,gBAAgB;AAAA,QACjD,WAAW,KAAK,WAAW,GAAG;AAAA,QAC9B,UAAU,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS,IAAI;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AAEA,aAAS,MAAM,KAAK,QAAQ;AAC5B,aAAS,MAAM,KAAK,KAAK,WAAW,YAAY,UAAU,SAAS,EAAE,CAAC;AAGtE,SAAK,mBAAmB,kBAAkB,UAAU,QAAQ;AAG5D,UAAM,aAAa,KAAK,kBAAkB,YAAY;AACtD,QAAI,YAAY;AACd,WAAK,qBAAqB,YAAY,UAAU,QAAQ;AACxD,WAAK,sBAAsB,YAAY,SAAS,IAAI,UAAU,QAAQ;AAAA,IACxE;AAGA,UAAM,OAAO,KAAK,kBAAkB,MAAM;AAC1C,QAAI,MAAM;AACR,WAAK,kBAAkB,MAAM,UAAU,UAAU,SAAS,EAAE;AAAA,IAC9D;AAGA,QAAI,CAAC,KAAK,WAAW,GAAG,GAAG;AACzB,eAAS,QAAQ,KAAK;AAAA,QACpB;AAAA,QACA,WAAW;AAAA,QACX,MAAM,KAAK,cAAc,MAAM;AAAA,MACjC,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBACN,kBACA,UACA,UACM;AACN,eAAW,OAAO,kBAAkB;AAElC,YAAM,aAAa,IAAI,KAAK,MAAM,0DAA0D;AAC5F,UAAI,cAAc,IAAI,KAAK,SAAS,GAAG;AACrC,cAAM,SAAS,WAAW,CAAC,EAAE,YAAY;AACzC,cAAM,OAAO,IAAI,KAAK,CAAC;AAGvB,YAAI,CAAC,SAAS,SAAU,UAAS,WAAW,CAAC;AAC7C,iBAAS,SAAS,eAAe;AAAA,UAC/B;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qBACN,YACA,UACA,UACM;AACN,eAAW,SAAS,WAAW,UAAU;AACvC,UAAI,MAAM,SAAS,qBAAqB,MAAM,SAAS,qBAAqB;AAE1E,cAAM,eAAe,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AACjE,YAAI,cAAc;AAEhB,gBAAM,WAAW,aAAa,kBAAkB,UAAU;AAC1D,cAAI,YAAY,SAAS,SAAS,WAAW;AAE3C,kBAAM,UAAU,aAAa,kBAAkB,WAAW;AAC1D,gBAAI,SAAS;AACX,yBAAW,OAAO,QAAQ,UAAU;AAClC,oBAAI,IAAI,SAAS,cAAc;AAC7B,wBAAM,iBAAiB,IAAI;AAG3B,wBAAM,YAAY,MAAM,SAAS;AAAA,oBAC/B,CAAC,MAAM,EAAE,SAAS;AAAA,kBACpB,GAAG;AAGH,sBAAI,CAAC,SAAS,SAAU,UAAS,WAAW,CAAC;AAC7C,sBAAI,CAAC,SAAS,SAAS,QAAS,UAAS,SAAS,UAAU,CAAC;AAC7D,kBAAC,SAAS,SAAS,QAAkB,KAAK;AAAA,oBACxC,eAAe;AAAA,oBACf;AAAA,oBACA,MAAM,MAAM,cAAc,MAAM;AAAA,kBAClC,CAAC;AAID,2BAAS,MAAM;AAAA,oBACb,KAAK,WAAW,WAAW,SAAS,IAAI,OAAO,cAAc,IAAI;AAAA,sBAC/D,gBAAgB;AAAA,sBAChB,eAAe;AAAA,sBACf,MAAM,MAAM,cAAc,MAAM;AAAA,oBAClC,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,sBACN,YACA,SACA,UACA,UACM;AACN,eAAW,SAAS,WAAW,UAAU;AACvC,UAAI,MAAM,SAAS,mBAAmB;AAEpC,cAAM,WAAW,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY;AACnE,YAAI,CAAC,SAAU;AAEf,cAAM,YAAY,SAAS;AAG3B,YAAI,cAAc,UAAU,cAAc,MAAO;AAGjD,cAAM,WAAW,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAC7D,YAAI,CAAC,SAAU;AAEf,YAAI,WAAW,SAAS;AAGxB,mBAAW,SAAS,QAAQ,SAAS,EAAE,EAAE,KAAK;AAG9C,cAAM,eAAe,SAAS,MAAM,wCAAwC;AAC5E,YAAI,cAAc;AAChB,qBAAW,aAAa,CAAC,EAAE,KAAK;AAAA,QAClC;AAGA,YAAI,CAAC,SAAS,eAAe;AAC3B,mBAAS,gBAAgB,CAAC;AAAA,QAC5B;AAEA,iBAAS,cAAc,KAAK;AAAA,UAC1B,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UACA,MAAM,MAAM,cAAc,MAAM;AAAA,QAClC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,YACN,MACA,UACA,UACA,UACM;AACN,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAI,CAAC,SAAU;AAEf,UAAM,OAAO,SAAS;AAGtB,UAAM,QAAkB,CAAC;AACzB,UAAM,eAAe,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,eAAe;AACzE,QAAI,cAAc;AAChB,iBAAW,OAAO,aAAa,UAAU;AACvC,YAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,aAAa;AACzD,gBAAM,KAAK,IAAI,IAAI;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,KAAK;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,cAAc,MAAM;AAAA,MACzB,KAAK,YAAY,MAAM;AAAA,MACvB;AAAA,QACE;AAAA,QACA,WAAW,KAAK,WAAW,GAAG;AAAA,MAChC;AAAA,IACF;AAEA,aAAS,MAAM,KAAK,SAAS;AAC7B,aAAS,MAAM,KAAK,KAAK,WAAW,YAAY,UAAU,UAAU,EAAE,CAAC;AAGvE,eAAW,QAAQ,OAAO;AACxB,eAAS,MAAM;AAAA,QACb,KAAK,WAAW,WAAW,UAAU,IAAI,OAAO,IAAI,IAAI;AAAA,UACtD,gBAAgB;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,OAAO,KAAK,kBAAkB,MAAM;AAC1C,QAAI,MAAM;AACR,iBAAW,SAAS,KAAK,UAAU;AACjC,YAAI,MAAM,SAAS,uBAAuB;AACxC,eAAK,aAAa,OAAO,UAAU,UAAU,UAAU,EAAE;AAAA,QAC3D,WAAW,MAAM,SAAS,wBAAwB;AAEhD,gBAAM,WAAW,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,qBAAqB;AAC5E,cAAI,UAAU;AACZ,iBAAK,aAAa,UAAU,UAAU,UAAU,UAAU,EAAE;AAAA,UAC9D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,WAAW,GAAG,GAAG;AACzB,eAAS,QAAQ,KAAK;AAAA,QACpB;AAAA,QACA,WAAW;AAAA,QACX,MAAM,KAAK,cAAc,MAAM;AAAA,MACjC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,aACN,MACA,UACA,UACA,SACM;AACN,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAI,CAAC,SAAU;AAEf,UAAM,OAAO,SAAS;AAGtB,UAAM,aAAuB,CAAC;AAG9B,QAAI,KAAK,QAAQ,SAAS,wBAAwB;AAChD,iBAAW,WAAW,KAAK,OAAO,UAAU;AAC1C,YAAI,QAAQ,SAAS,aAAa;AAChC,gBAAM,gBAAgB,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,SAAS,YAAY;AACpG,cAAI,eAAe;AACjB,uBAAW,KAAK,cAAc,IAAI;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,WAAW,SAAS,cAAc;AACnD,UAAM,gBAAgB,WAAW,SAAS,aAAa;AACvD,UAAM,aAAa,WAAW,SAAS,UAAU;AACjD,UAAM,UAAU,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAE5D,UAAM,aAAa,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,cAAc,MAAM;AAAA,MACzB,KAAK,YAAY,MAAM;AAAA,MACvB;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,UAAU;AAAA,QACV,WAAW,KAAK,WAAW,GAAG;AAAA,QAC9B,UAAU,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS,IAAI;AAAA,MACvD;AAAA,IACF;AAEA,aAAS,MAAM,KAAK,UAAU;AAC9B,aAAS,MAAM,KAAK,KAAK,WAAW,YAAY,SAAS,WAAW,EAAE,CAAC;AAGvE,UAAM,OAAO,KAAK,kBAAkB,MAAM;AAC1C,QAAI,MAAM;AACR,WAAK,kBAAkB,MAAM,UAAU,UAAU,WAAW,EAAE;AAAA,IAChE;AAAA,EACF;AAAA,EAEQ,WACN,MACA,UACA,UACA,UACM;AACN,UAAM,WAAW,KAAK,kBAAkB,UAAU;AAClD,QAAI,CAAC,SAAU;AAEf,QAAI,aAAa;AACjB,QAAI,SAAS,SAAS,cAAc;AAClC,mBAAa,SAAS;AAAA,IACxB,WAAW,SAAS,SAAS,aAAa;AAExC,mBAAa,SAAS;AAAA,IACxB;AAEA,QAAI,YAAY;AAEd,eAAS,MAAM;AAAA,QACb,KAAK,WAAW,SAAS,UAAU,OAAO,UAAU,IAAI;AAAA,UACtD,gBAAgB;AAAA,UAChB,MAAM,KAAK,cAAc,MAAM;AAAA,QACjC,CAAC;AAAA,MACH;AAGA,WAAK,wBAAwB,YAAY,MAAM,UAAU,QAAQ;AAAA,IACnE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,wBACN,YACA,MACA,UACA,UACM;AAEN,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,QAAQ,WAAW,MAAM,GAAG;AAClC,UAAM,YAAY,MAAM,MAAM,SAAS,CAAC;AAExC,QAAI,SAAS,SAAS,SAAS,GAAG;AAEhC,UAAI,aAAa;AACjB,UAAI,MAAM,UAAU,GAAG;AACrB,qBAAa,MAAM,MAAM,SAAS,CAAC;AAAA,MACrC;AAGA,UAAI,CAAC,SAAS,oBAAoB;AAChC,iBAAS,qBAAqB,CAAC;AAAA,MACjC;AAEA,eAAS,mBAAmB,KAAK;AAAA,QAC/B,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd,MAAM,KAAK,cAAc,MAAM;AAAA,MACjC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,kBACN,MACA,UACA,UACA,UACM;AACN,UAAM,eAAe,CAAC,SAAkC;AACtD,UAAI,KAAK,SAAS,QAAQ;AACxB,aAAK,WAAW,MAAM,UAAU,UAAU,QAAQ;AAAA,MACpD,WAAW,KAAK,SAAS,oBAAoB;AAE3C,aAAK,aAAa,MAAM,QAAQ;AAAA,MAClC,WAAW,KAAK,SAAS,yBAAyB;AAEhD,aAAK,iBAAiB,MAAM,QAAQ;AAAA,MACtC,WAAW,KAAK,SAAS,cAAc;AAErC,aAAK,iBAAiB,MAAM,UAAU,UAAU,QAAQ;AAAA,MAC1D;AACA,iBAAW,SAAS,KAAK,UAAU;AACjC,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AACA,iBAAa,IAAI;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,iBACN,MACA,UACA,UACA,SACM;AAEN,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAI,CAAC,YAAY,SAAS,SAAS,aAAc;AAEjD,UAAM,eAAe,SAAS;AAG9B,UAAM,YAAY,KAAK,kBAAkB,OAAO;AAChD,QAAI,CAAC,UAAW;AAEhB,QAAI,WAA0B;AAG9B,QAAI,UAAU,SAAS,QAAQ;AAC7B,YAAM,WAAW,UAAU,kBAAkB,UAAU;AACvD,UAAI,UAAU;AACZ,YAAI,SAAS,SAAS,cAAc;AAElC,gBAAM,WAAW,SAAS;AAG1B,cAAI,SAAS,CAAC,MAAM,SAAS,CAAC,EAAE,YAAY,GAAG;AAC7C,uBAAW;AAAA,UACb,OAAO;AAGL,uBAAW,SAAS,QAAQ;AAAA,UAC9B;AAAA,QACF,WAAW,SAAS,SAAS,aAAa;AAExC,gBAAM,QAAQ,SAAS,KAAK,MAAM,GAAG;AACrC,cAAI,MAAM,UAAU,GAAG;AACrB,kBAAM,YAAY,MAAM,CAAC;AACzB,kBAAM,aAAa,MAAM,CAAC;AAG1B,gBAAI,UAAU,CAAC,MAAM,UAAU,CAAC,EAAE,YAAY,GAAG;AAC/C,yBAAW;AAAA,YACb,OAAO;AAEL,yBAAW,SAAS,SAAS,IAAI;AAAA,YACnC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,YAAY,CAAC,SAAS,eAAe;AACvC,eAAS,gBAAgB,CAAC;AAAA,IAC5B;AAEA,QAAI,UAAU;AACZ,eAAS,cAAe,KAAK;AAAA,QAC3B;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,KAAK,cAAc,MAAM;AAAA,MACjC,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACzvBO,SAAS,qBAA2B;AACzC,iBAAe,SAAS,IAAI,iBAAiB,CAAC;AAC9C,iBAAe,SAAS,IAAI,iBAAiB,CAAC;AAC9C,iBAAe,SAAS,IAAI,aAAa,CAAC;AAC5C;AAGA,mBAAmB;;;AJaZ,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,oBAAI,IAA2B;AAAA;AAAA,EAC3C,SAAmB,CAAC;AAAA,EAE5B,YAAY,SAAsB,QAAoB;AACpD,SAAK,UAAU;AACf,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,oBAAoB,UAAkC;AACpD,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,QAMH;AACD,UAAM,WAAW,QAAQ,KAAK,OAAO,QAAQ;AAG7C,SAAK,aAAa;AAAA,MAChB,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,IACf,CAAC;AAED,UAAM,WAAW,MAAM,KAAK,cAAc,QAAQ;AAClD,UAAM,eAAsD,CAAC;AAC7D,QAAI,UAAU;AAGd,eAAW,YAAY,UAAU;AAC/B,YAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,YAAM,OAAO,KAAK,YAAY,OAAO;AAErC,UAAI,CAAC,KAAK,OAAO,cAAc;AAC7B,cAAM,eAAe,KAAK,QAAQ,YAAY,QAAQ;AACtD,YAAI,iBAAiB,MAAM;AACzB;AACA;AAAA,QACF;AAAA,MACF;AAEA,mBAAa,KAAK,EAAE,MAAM,UAAU,KAAK,CAAC;AAAA,IAC5C;AAGA,QAAI,UAAU;AACd,eAAW,QAAQ,cAAc;AAC/B,WAAK,aAAa;AAAA,QAChB,OAAO;AAAA,QACP,OAAO,aAAa;AAAA,QACpB,SAAS,UAAU;AAAA,QACnB,aAAa,SAAS,UAAU,KAAK,IAAI;AAAA,MAC3C,CAAC;AAED,UAAI;AACF,cAAM,KAAK,cAAc,KAAK,MAAM,KAAK,MAAM,QAAQ;AACvD;AAAA,MACF,SAAS,OAAO;AACd,aAAK,OAAO,KAAK,GAAG,SAAS,UAAU,KAAK,IAAI,CAAC,KAAK,KAAK,EAAE;AAAA,MAC/D;AAAA,IACF;AAGA,SAAK,aAAa;AAAA,MAChB,OAAO;AAAA,MACP,OAAO,aAAa;AAAA,MACpB,SAAS,aAAa;AAAA,MACtB,aAAa;AAAA,IACf,CAAC;AAED,SAAK,gBAAgB;AAErB,UAAM,QAAQ,KAAK,QAAQ,SAAS;AAEpC,SAAK,aAAa;AAAA,MAChB,OAAO;AAAA,MACP,OAAO,aAAa;AAAA,MACpB,SAAS,aAAa;AAAA,MACtB,aAAa;AAAA,IACf,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM;AAAA,MAClB,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,UAAqC;AAC/D,UAAM,WAAqB,CAAC;AAE5B,eAAW,WAAW,KAAK,OAAO,SAAS;AACzC,YAAM,UAAU,MAAM,KAAK,SAAS;AAAA,QAClC,KAAK;AAAA,QACL,UAAU;AAAA,QACV,QAAQ,KAAK,OAAO;AAAA,QACpB,OAAO;AAAA,MACT,CAAC;AACD,eAAS,KAAK,GAAG,OAAO;AAAA,IAC1B;AAGA,UAAM,gBAAgB,oBAAI,IAAI,CAAC,OAAO,OAAO,QAAQ,OAAO,MAAM,CAAC;AACnE,UAAM,cAAc,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM;AACvD,YAAM,MAAM,QAAQ,CAAC;AACrB,UAAI,CAAC,cAAc,IAAI,GAAG,EAAG,QAAO;AAEpC,UAAI;AACF,cAAM,QAAQ,SAAS,CAAC;AACxB,YAAI,MAAM,OAAO,IAAQ,QAAO;AAAA,MAClC,QAAQ;AACN,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AAED,WAAO,YAAY,KAAK;AAAA,EAC1B;AAAA,EAEQ,YAAY,SAAyB;AAC3C,WAAO,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK,EAAE,UAAU,GAAG,EAAE;AAAA,EAC3E;AAAA,EAEA,MAAc,cAAc,UAAkB,MAAc,UAAiC;AAC3F,UAAM,WAAW,KAAK,YAAY,QAAQ;AAC1C,UAAM,UAAU,aAAa,UAAU,OAAO;AAG9C,UAAM,SAAS,eAAe,cAAc,QAAQ;AACpD,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,iCAAiC,QAAQ,EAAE;AAAA,IAC7D;AAGA,UAAM,WAAW,OAAO,MAAM,UAAU,OAAO;AAG/C,SAAK,QAAQ,eAAe,QAAQ;AAGpC,UAAM,cAA6B,CAAC;AAEpC,eAAW,QAAQ,SAAS,OAAO;AAEjC,YAAM,WAAW,KAAK,YAAY,GAAG,KAAK,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,OAAO,EAAE;AAClF,YAAM,eAAe,EAAE,GAAG,MAAM,MAAM,SAAS;AAE/C,WAAK,QAAQ,WAAW,YAAY;AAGpC,UAAI,KAAK,SAAS,cAAc,KAAK,SAAS,SAAS;AACrD,oBAAY,KAAK,IAAI,IAAI,KAAK;AAC9B,aAAK,QAAQ,eAAe,UAAU,KAAK,MAAM,KAAK,EAAE;AAAA,MAC1D;AAAA,IACF;AAGA,SAAK,UAAU,IAAI,UAAU,WAAW;AAGxC,eAAW,QAAQ,SAAS,OAAO;AACjC,WAAK,QAAQ,WAAW,IAAI;AAAA,IAC9B;AAGA,eAAW,OAAO,SAAS,SAAS;AAClC,iBAAW,QAAQ,IAAI,YAAY;AACjC,aAAK,QAAQ,eAAe,UAAU,MAAM,IAAI,QAAQ,IAAI,IAAI;AAAA,MAClE;AAAA,IACF;AAGA,QAAI,SAAS,eAAe;AAC1B,iBAAW,WAAW,SAAS,eAAe;AAC5C,aAAK,QAAQ;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAGA,QAAI,SAAS,oBAAoB;AAC/B,iBAAW,QAAQ,SAAS,oBAAoB;AAC9C,aAAK,QAAQ,wBAAwB;AAAA,UACnC,IAAI,GAAG,KAAK,MAAM,OAAO,KAAK,IAAI;AAAA,UAClC,SAAS,KAAK;AAAA,UACd,eAAe,KAAK;AAAA,UACpB,WAAW,KAAK;AAAA,UAChB,YAAY,KAAK;AAAA,UACjB,MAAM,KAAK;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AAGA,SAAK,QAAQ,WAAW,UAAU,UAAU,IAAI;AAGhD,SAAK,yBAAyB,SAAS,OAAO,QAAQ;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAyB,OAAoB,UAAwB;AAC3E,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,cAAc,KAAK,UAAU;AAE7C,cAAM,eAAe,KAAK,SAAS;AACnC,YAAI,cAAc;AAChB,gBAAM,aAAa,GAAG,aAAa,MAAM,IAAI,aAAa,IAAI;AAC9D,eAAK,QAAQ,mBAAmB;AAAA,YAC9B,IAAI;AAAA,YACJ,QAAQ,aAAa;AAAA,YACrB,MAAM,aAAa;AAAA,YACnB,iBAAiB,KAAK;AAAA,YACtB,cAAc;AAAA;AAAA,YACd,UAAU;AAAA,cACR;AAAA,cACA,cAAc,KAAK;AAAA,cACnB,MAAM,KAAK;AAAA,YACb;AAAA,UACF,CAAC;AAAA,QACH;AAGA,cAAM,UAAU,KAAK,SAAS;AAM9B,YAAI,SAAS;AACX,qBAAW,OAAO,SAAS;AACzB,kBAAM,QAAQ,GAAG,KAAK,EAAE,YAAY,IAAI,aAAa;AACrD,iBAAK,QAAQ,0BAA0B;AAAA,cACrC,IAAI;AAAA,cACJ,gBAAgB,KAAK;AAAA,cACrB,gBAAgB;AAAA;AAAA,cAChB,WAAW;AAAA,cACX,SAAS;AAAA,cACT,gBAAgB,IAAI;AAAA,cACpB,MAAM,IAAI;AAAA,cACV,iBAAiB,IAAI;AAAA,cACrB,UAAU;AAAA,gBACR;AAAA,gBACA,cAAc,KAAK;AAAA,cACrB;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAwB;AAE9B,UAAM,kBAAkB,KAAK,QAAQ,GAClC,QAAQ,kDAAkD,EAC1D,IAAI;AAQP,eAAW,QAAQ,iBAAiB;AAClC,YAAM,UAAU,KAAK,UAAU,QAAQ,QAAQ,EAAE;AACjD,YAAM,aAAa,KAAK,QAAQ,QAAQ,KAAK,SAAS;AAEtD,UAAI,CAAC,WAAY;AAGjB,YAAM,aAAa,KAAK,iBAAiB,WAAW,UAAU,SAAS,KAAK,SAAS;AAErF,UAAI,YAAY;AAEd,aAAK,QAAQ,WAAW;AAAA,UACtB,IAAI,KAAK;AAAA,UACT,MAAM,KAAK;AAAA,UACX,UAAU,KAAK;AAAA,UACf,UAAU;AAAA,UACV,UAAU,KAAK,WAAW,KAAK,MAAM,KAAK,QAAQ,IAAI;AAAA,QACxD,CAAC;AAAA,MACH;AAAA,IACF;AAGA,SAAK,6BAA6B;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKQ,+BAAqC;AAC3C,UAAM,iBAAiB,KAAK,QAAQ,6BAA6B;AAEjE,eAAW,OAAO,gBAAgB;AAChC,YAAM,aAAa,KAAK,QAAQ,QAAQ,IAAI,cAAc;AAC1D,UAAI,CAAC,WAAY;AAGjB,YAAM,aAAa,KAAK,iBAAiB,WAAW,UAAU,IAAI,eAAe;AAEjF,UAAI,YAAY;AAEd,aAAK,QAAQ,gCAAgC,IAAI,IAAI,UAAU;AAG/D,aAAK,QAAQ,WAAW;AAAA,UACtB,IAAI,GAAG,IAAI,EAAE;AAAA,UACb,MAAM;AAAA,UACN,UAAU,IAAI;AAAA,UACd,UAAU;AAAA,UACV,UAAU;AAAA,YACR,WAAW;AAAA,YACX,SAAS;AAAA,YACT,MAAM,IAAI;AAAA,UACZ;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBAAiB,gBAAwB,SAAiB,aAAqC;AAErG,QAAI,QAAQ,WAAW,UAAU,KAAK,aAAa;AACjD,YAAM,aAAa,QAAQ,QAAQ,YAAY,EAAE;AACjD,YAAM,gBAAgB,KAAK,QAAQ,mBAAmB,YAAY,WAAW;AAC7E,UAAI,eAAe;AACjB,eAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,YAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,UAAI,MAAM,WAAW,GAAG;AACtB,cAAM,CAAC,YAAY,UAAU,IAAI;AAGjC,YAAI,aAAa;AACf,gBAAM,oBAAoB,KAAK,QAAQ,sBAAsB,YAAY,YAAY,WAAW;AAChG,cAAI,mBAAmB;AACrB,mBAAO;AAAA,UACT;AAAA,QACF;AAGA,cAAM,sBAAsB,KAAK,QAAQ,mBAAmB,YAAY,YAAY,cAAc;AAClG,YAAI,qBAAqB;AACvB,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAGA,UAAM,cAAc,KAAK,QAAQ,eAAe,cAAc;AAC9D,eAAW,QAAQ,aAAa;AAC9B,UAAI,KAAK,SAAS,SAAS;AACzB,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAGA,UAAM,qBAAqB,KAAK,QAAQ,cAAc,gBAAgB,OAAO;AAC7E,QAAI,oBAAoB;AACtB,aAAO;AAAA,IACT;AAGA,UAAM,UAAU,KAAK,QAAQ,kBAAkB,OAAO;AACtD,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,QAAQ,CAAC,EAAE;AAAA,IACpB;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,YAAY,UAA0B;AAC5C,UAAM,MAAM,QAAQ,QAAQ;AAC5B,QAAI,QAAQ,MAAO,QAAO;AAC1B,QAAI,QAAQ,SAAS,QAAQ,OAAQ,QAAO;AAC5C,QAAI,QAAQ,SAAS,QAAQ,OAAQ,QAAO;AAC5C,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,UAA8B;AACjD,QAAI,KAAK,YAAY;AACnB,WAAK,WAAW,QAAQ;AAAA,IAC1B;AAAA,EACF;AACF;;;AKzSO,IAAM,iBAAyC;AAAA,EACpD,SAAS,CAAC,WAAW,YAAY,WAAW,YAAY,SAAS;AAAA,EACjE,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW,CAAC,cAAc,cAAc,QAAQ;AAClD;;;ACvJA,SAAS,WAAAC,UAAS,QAAAC,aAAY;;;ACD9B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AAiBd,SAAS,gBAAgB,MAAuB;AACrD,SAAO,WAAW,KAAK,MAAM,MAAM,CAAC;AACtC;AAKO,SAAS,mBAAmB,UAAoC;AACrE,MAAI;AAEF,UAAM,SAAS,SAAS,+BAA+B;AAAA,MACrD,KAAK;AAAA,MACL,UAAU;AAAA,IACZ,CAAC,EAAE,KAAK;AAER,QAAI,CAAC,QAAQ;AACX,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,QAA0B,CAAC;AACjC,eAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,YAAM,CAAC,QAAQ,IAAI,IAAI,KAAK,MAAM,GAAI;AACtC,UAAI,MAAM;AACR,cAAM,KAAK;AAAA,UACT;AAAA,UACA,QAAQ,WAAW,MAAM,UAAU,WAAW,MAAM,YAAY;AAAA,QAClE,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,CAAC;AAAA,EACV;AACF;AAKO,SAAS,yBAAyB,UAAkB,OAA+C;AACxG,QAAM,mBAAyC,CAAC;AAEhD,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,WAAW;AAC7B;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,OAAO,SAAS,qBAAqB,KAAK,IAAI,KAAK;AAAA,QACvD,KAAK;AAAA,QACL,UAAU;AAAA,MACZ,CAAC;AAGD,YAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,UAAI,kBAAiC;AAErC,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAM,OAAO,MAAM,CAAC;AAKpB,YAAI,KAAK,WAAW,IAAI,GAAG;AACzB,gBAAM,eAAe,KAAK,MAAM,eAAe;AAC/C,cAAI,cAAc;AAChB,kBAAM,UAAU,aAAa,CAAC;AAG9B,kBAAM,cAAc,QAAQ,MAAM,0BAA0B;AAC5D,gBAAI,aAAa;AACf,gCAAkB,YAAY,CAAC;AAAA,YACjC;AAGA,kBAAM,UAAU,QAAQ,MAAM,kCAAkC;AAChE,gBAAI,SAAS;AACX,gCAAkB,QAAQ,CAAC;AAAA,YAC7B;AAGA,kBAAM,YAAY,KAAK,MAAM,SAAS;AACtC,kBAAM,aAAa,YAAY,SAAS,UAAU,CAAC,CAAC,IAAI;AAExD,gBAAI,iBAAiB;AACnB,+BAAiB,KAAK;AAAA,gBACpB,MAAM,KAAK;AAAA,gBACX,cAAc;AAAA,gBACd;AAAA,gBACA,YAAY,KAAK,WAAW,UAAU,UAAU;AAAA,cAClD,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AAEd;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,aAAa,UAI3B;AACA,MAAI;AACF,UAAM,eAAe,SAAS,0BAA0B;AAAA,MACtD,KAAK;AAAA,MACL,UAAU;AAAA,IACZ,CAAC,EAAE,KAAK;AAER,UAAM,QAAQ,aAAa,MAAM,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC;AAC7D,UAAM,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,GAAG,EAAE;AACjE,UAAM,WAAW,MAAM;AAEvB,WAAO;AAAA,MACL,YAAY,WAAW;AAAA,MACvB,eAAe;AAAA,MACf,aAAa;AAAA,IACf;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,aAAa;AAAA,IACf;AAAA,EACF;AACF;;;AD5HA,eAAsB,cAAc,UAAyB,CAAC,GAA0B;AACtF,QAAM,WAAWC,SAAQ,QAAQ,QAAQ,GAAG;AAC5C,QAAM,SAASC,MAAK,UAAU,YAAY,UAAU;AACpD,QAAM,UAAU,IAAI,YAAY,MAAM;AAEtC,MAAI;AAEF,QAAI,gBAAgB,QAAQ,GAAG;AAC7B,aAAO,MAAM,qBAAqB,SAAS,UAAU,OAAO;AAAA,IAC9D,OAAO;AACL,aAAO,MAAM,sBAAsB,SAAS,UAAU,OAAO;AAAA,IAC/D;AAAA,EACF,UAAE;AACA,YAAQ,MAAM;AAAA,EAChB;AACF;AAKA,eAAe,qBACb,SACA,UACA,SACuB;AAEvB,QAAM,YAAY,aAAa,QAAQ;AACvC,MAAI,CAAC,UAAU,YAAY;AACzB,WAAO;AAAA,MACL,cAAc,CAAC;AAAA,MACf,kBAAkB,CAAC;AAAA,MACnB,eAAe,oBAAI,IAAI;AAAA,MACvB,mBAAmB,CAAC;AAAA,MACpB,WAAW;AAAA,MACX,aAAa;AAAA,IACf;AAAA,EACF;AAGA,QAAM,eAAe,mBAAmB,QAAQ;AAChD,QAAM,mBAAmB,aAAa,IAAI,CAAC,MAAM,EAAE,IAAI;AAGvD,QAAM,mBAAmB,yBAAyB,UAAU,YAAY;AAGxE,QAAM,UAAU,IAAI,YAAY,SAAS;AAAA,IACvC;AAAA,IACA,SAAS,iBAAiB,IAAI,CAAC,MAAM,CAAC;AAAA,IACtC,SAAS,CAAC;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AAED,QAAM,QAAQ,MAAM;AAGpB,QAAM,gBAAgB,oBAAI,IAA4D;AACtF,QAAM,oBAA8B,CAAC;AAErC,aAAW,QAAQ,kBAAkB;AAEnC,UAAM,QAAQ,QACX,eAAeA,MAAK,UAAU,KAAK,IAAI,CAAC,EACxC,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,YAAY;AAE7C,eAAW,QAAQ,OAAO;AAExB,YAAM,UAAU,QAAQ,+BAA+B,KAAK,EAAE;AAC9D,UAAI,QAAQ,SAAS,GAAG;AACtB,sBAAc,IAAI,KAAK,cAAc,OAAO;AAAA,MAC9C;AAGA,YAAM,YAAY,QAAQ,0BAA0B,KAAK,EAAE;AAC3D,iBAAW,YAAY,WAAW;AAChC,0BAAkB,KAAK,GAAG,SAAS,MAAM,IAAI,SAAS,IAAI,EAAE;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAGA,QAAM,eAAe,MAAM,KAAK,cAAc,OAAO,CAAC,EAAE,OAAO,CAAC,KAAK,YAAY,MAAM,QAAQ,QAAQ,CAAC;AACxG,MAAI,YAAuC;AAC3C,MAAI,eAAe,MAAM,kBAAkB,SAAS,GAAG;AACrD,gBAAY;AAAA,EACd,WAAW,eAAe,MAAM,kBAAkB,SAAS,GAAG;AAC5D,gBAAY;AAAA,EACd;AAEA,SAAO;AAAA,IACL,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,EACf;AACF;AAKA,eAAe,sBACb,SACA,UACA,SACuB;AAEvB,QAAM,YAAY,QAAQ,iBAAiB;AAG3C,QAAM,UAAU,IAAI,YAAY,SAAS;AAAA,IACvC;AAAA,IACA,SAAS,eAAe;AAAA,IACxB,SAAS,eAAe;AAAA,IACxB,cAAc;AAAA;AAAA,EAChB,CAAC;AAED,QAAM,SAAS,MAAM,QAAQ,MAAM;AAGnC,QAAM,eAAyB,CAAC;AAChC,QAAM,YAAY,QAAQ,iBAAiB;AAE3C,aAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,SAAS,GAAG;AAC3D,UAAM,UAAU,UAAU,QAAQ;AAClC,QAAI,CAAC,WAAW,YAAY,SAAS;AACnC,mBAAa,KAAK,QAAQ;AAAA,IAC5B;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA,kBAAkB,CAAC;AAAA,IACnB,eAAe,oBAAI,IAAI;AAAA,IACvB,mBAAmB,CAAC;AAAA,IACpB,WAAW,aAAa,SAAS,KAAK,SAAS,aAAa,SAAS,IAAI,WAAW;AAAA,IACpF,aAAa,OAAO;AAAA,EACtB;AACF;;;AP5JA,IAAM,UAAU,IAAI,QAAQ;AAK5B,SAAS,mBAAmB,aAA8B;AACxD,MAAI;AACF,UAAM,mBAAmBC,MAAK,QAAQ,GAAG,WAAW,aAAa;AAEjE,QAAI,CAACC,YAAW,gBAAgB,GAAG;AACjC,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,KAAK,MAAMC,cAAa,kBAAkB,OAAO,CAAC;AAEjE,QAAI,CAAC,OAAO,YAAY;AACtB,aAAO,aAAa,CAAC;AAAA,IACvB;AAGA,WAAO,WAAW,UAAU;AAAA,MAC1B,SAAS;AAAA,MACT,MAAM,CAAC,cAAc,cAAc,UAAU,WAAW;AAAA,IAC1D;AAEA,kBAAc,kBAAkB,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC/D,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO;AAAA,EACT;AACF;AAEA,QACG,KAAK,SAAS,EACd,YAAY,kEAAkE,EAC9E,QAAQ,OAAO;AAIlB,QACG,QAAQ,OAAO,EACf,YAAY,oCAAoC,EAChD,SAAS,UAAU,4BAA4B,GAAG,EAClD,OAAO,eAAe,wCAAwC,EAC9D,OAAO,2BAA2B,0BAA0B,EAC5D,OAAO,2BAA2B,0BAA0B,EAC5D,OAAO,OAAO,MAAc,YAAY;AACvC,QAAM,WAAWC,SAAQ,IAAI;AAC7B,QAAM,YAAYH,MAAK,UAAU,UAAU;AAE3C,UAAQ,IAAI,MAAM,KAAK,KAAK,kCAAkC,CAAC;AAC/D,UAAQ,IAAI,MAAM,KAAK,cAAc,QAAQ;AAAA,CAAI,CAAC;AAGlD,MAAI,CAACC,YAAW,SAAS,GAAG;AAC1B,cAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EAC1C;AAEA,QAAM,SAASD,MAAK,WAAW,UAAU;AACzC,QAAM,UAAU,IAAI,YAAY,MAAM;AAEtC,QAAM,UAAU,IAAI,YAAY,SAAS;AAAA,IACvC;AAAA,IACA,SAAS,QAAQ,WAAW,eAAe;AAAA,IAC3C,SAAS,QAAQ,WAAW,eAAe;AAAA,IAC3C,cAAc,QAAQ,SAAS;AAAA,EACjC,CAAC;AAED,QAAM,UAAU,IAAI,sBAAsB,EAAE,MAAM;AAElD,UAAQ,oBAAoB,CAAC,aAAa;AACxC,YAAQ,SAAS,OAAO;AAAA,MACtB,KAAK;AACH,gBAAQ,OAAO;AACf;AAAA,MACF,KAAK;AACH,gBAAQ,OAAO,YAAY,SAAS,OAAO,IAAI,SAAS,KAAK,MAAM,SAAS,WAAW;AACvF;AAAA,MACF,KAAK;AACH,gBAAQ,OAAO;AACf;AAAA,MACF,KAAK;AACH,gBAAQ,QAAQ,MAAM,MAAM,oBAAoB,CAAC;AACjD;AAAA,IACJ;AAAA,EACF,CAAC;AAED,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,MAAM;AAEnC,YAAQ,IAAI,MAAM,KAAK,gBAAgB,CAAC;AACxC,YAAQ,IAAI,KAAK,MAAM,KAAK,UAAU,CAAC,OAAO,OAAO,OAAO,QAAQ;AACpE,YAAQ,IAAI,KAAK,MAAM,KAAK,UAAU,CAAC,OAAO,OAAO,OAAO,oBAAoB;AAChF,YAAQ,IAAI,KAAK,MAAM,KAAK,WAAW,CAAC,MAAM,OAAO,QAAQ,iBAAiB;AAC9E,YAAQ,IAAI,KAAK,MAAM,KAAK,aAAa,CAAC,IAAI,OAAO,UAAU,2BAA2B;AAG1F,UAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAI,MAAM,gBAAgB,GAAG;AAC3B,cAAQ,IAAI,MAAM,KAAK;AAAA,IAAO,MAAM,KAAK,sBAAsB,CAAC,EAAE,CAAC;AACnE,cAAQ,IAAI,KAAK,MAAM,KAAK,iBAAiB,CAAC,IAAI,MAAM,aAAa,kBAAkB;AACvF,cAAQ,IAAI,KAAK,MAAM,KAAK,eAAe,CAAC,MAAM,MAAM,oBAAoB,IAAI,MAAM,qBAAqB,6BAA6B;AAAA,IAC1I;AAEA,QAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,cAAQ,IAAI,MAAM,OAAO;AAAA,YAAe,OAAO,OAAO,MAAM,eAAe,CAAC;AAC5E,iBAAW,OAAO,OAAO,OAAO,MAAM,GAAG,CAAC,GAAG;AAC3C,gBAAQ,IAAI,MAAM,KAAK,SAAS,GAAG,EAAE,CAAC;AAAA,MACxC;AACA,UAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,gBAAQ,IAAI,MAAM,KAAK,eAAe,OAAO,OAAO,SAAS,CAAC,OAAO,CAAC;AAAA,MACxE;AAAA,IACF;AAEA,UAAM,cAAc,OAAO,WAAW,OAAO,aAAa,IACtD,KAAK,MAAO,OAAO,YAAY,OAAO,WAAW,OAAO,cAAe,GAAG,IAC1E;AACJ,UAAM,iBAAiB,MAAM,wBAAwB,IACjD,KAAK,MAAO,MAAM,uBAAuB,MAAM,wBAAyB,GAAG,IAC3E;AAEJ,YAAQ,IAAI,MAAM,KAAK;AAAA,0BAA6B,WAAW,GAAG,CAAC;AACnE,QAAI,MAAM,wBAAwB,GAAG;AACnC,cAAQ,IAAI,MAAM,KAAK,iCAAiC,cAAc,GAAG,CAAC;AAAA,IAC5E;AACA,YAAQ,IAAI,MAAM,KAAK,wBAAwB,MAAM;AAAA,CAAI,CAAC;AAE1D,YAAQ,IAAI,MAAM,KAAK,eAAe,CAAC;AACvC,YAAQ,IAAI,MAAM,KAAK,sFAAiF,CAAC;AACzG,YAAQ,IAAI,MAAM,KAAK,4EAAuE,CAAC;AAAA,EACjG,SAAS,OAAO;AACd,YAAQ,KAAK,MAAM,IAAI,iBAAiB,CAAC;AACzC,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB,UAAE;AACA,YAAQ,MAAM;AAAA,EAChB;AACF,CAAC;AAIH,QACG,QAAQ,MAAM,EACd,YAAY,wCAAwC,EACpD,SAAS,UAAU,4BAA4B,GAAG,EAClD,OAAO,2BAA2B,0BAA0B,EAC5D,OAAO,2BAA2B,0BAA0B,EAC5D,OAAO,cAAc,+BAA+B,EACpD,OAAO,OAAO,MAAc,YAAY;AACvC,QAAM,WAAWG,SAAQ,IAAI;AAC7B,QAAM,YAAYH,MAAK,UAAU,UAAU;AAE3C,UAAQ,IAAI,MAAM,KAAK,KAAK,8BAA8B,CAAC;AAC3D,UAAQ,IAAI,MAAM,KAAK,cAAc,QAAQ;AAAA,CAAI,CAAC;AAGlD,MAAIC,YAAWD,MAAK,WAAW,UAAU,CAAC,KAAK,CAAC,QAAQ,OAAO;AAC7D,YAAQ,IAAI,MAAM,OAAO,4DAA4D,CAAC;AACtF;AAAA,EACF;AAGA,MAAI,CAACC,YAAW,SAAS,GAAG;AAC1B,cAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EAC1C;AAEA,QAAM,SAASD,MAAK,WAAW,UAAU;AACzC,QAAM,UAAU,IAAI,YAAY,MAAM;AAEtC,QAAM,UAAU,IAAI,YAAY,SAAS;AAAA,IACvC;AAAA,IACA,SAAS,QAAQ,WAAW,eAAe;AAAA,IAC3C,SAAS,QAAQ,WAAW,eAAe;AAAA,IAC3C,cAAc;AAAA,EAChB,CAAC;AAED,QAAM,UAAU,IAAI,sBAAsB,EAAE,MAAM;AAElD,UAAQ,oBAAoB,CAAC,aAAa;AACxC,YAAQ,SAAS,OAAO;AAAA,MACtB,KAAK;AACH,gBAAQ,OAAO;AACf;AAAA,MACF,KAAK;AACH,gBAAQ,OAAO,YAAY,SAAS,OAAO,IAAI,SAAS,KAAK,MAAM,SAAS,WAAW;AACvF;AAAA,MACF,KAAK;AACH,gBAAQ,OAAO;AACf;AAAA,MACF,KAAK;AACH,gBAAQ,QAAQ,MAAM,MAAM,oBAAoB,CAAC;AACjD;AAAA,IACJ;AAAA,EACF,CAAC;AAED,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,MAAM;AAEnC,YAAQ,IAAI,MAAM,KAAK,gBAAgB,CAAC;AACxC,YAAQ,IAAI,KAAK,MAAM,KAAK,UAAU,CAAC,OAAO,OAAO,OAAO,QAAQ;AACpE,YAAQ,IAAI,KAAK,MAAM,KAAK,WAAW,CAAC,MAAM,OAAO,QAAQ,iBAAiB;AAE9E,UAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAI,MAAM,gBAAgB,GAAG;AAC3B,cAAQ,IAAI,MAAM,KAAK;AAAA,IAAO,MAAM,KAAK,sBAAsB,CAAC,EAAE,CAAC;AACnE,cAAQ,IAAI,KAAK,MAAM,KAAK,iBAAiB,CAAC,IAAI,MAAM,aAAa,SAAS;AAAA,IAChF;AAEA,UAAM,cAAc,OAAO,WAAW,OAAO,aAAa,IACtD,KAAK,MAAO,OAAO,YAAY,OAAO,WAAW,OAAO,cAAe,GAAG,IAC1E;AAEJ,YAAQ,IAAI,MAAM,KAAK;AAAA,qBAAwB,WAAW,GAAG,CAAC;AAC9D,YAAQ,IAAI,MAAM,KAAK,eAAe,MAAM;AAAA,CAAI,CAAC;AAGjD,QAAI,CAAC,QAAQ,SAAS;AACpB,YAAM,gBAAgB,mBAAmB,QAAQ;AACjD,UAAI,eAAe;AACjB,gBAAQ,IAAI,MAAM,MAAM,iDAA4C,CAAC;AAAA,MACvE,OAAO;AACL,gBAAQ,IAAI,MAAM,OAAO,+DAA0D,CAAC;AACpF,gBAAQ,IAAI,MAAM,KAAK,yEAAyE,CAAC;AAAA,MACnG;AAAA,IACF;AAEA,YAAQ,IAAI,MAAM,KAAK,UAAU,CAAC;AAClC,YAAQ,IAAI,MAAM,KAAK,qEAAqE,CAAC;AAAA,EAC/F,SAAS,OAAO;AACd,YAAQ,KAAK,MAAM,IAAI,uBAAuB,CAAC;AAC/C,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB,UAAE;AACA,YAAQ,MAAM;AAAA,EAChB;AACF,CAAC;AAIH,QACG,QAAQ,QAAQ,EAChB,YAAY,gCAAgC,EAC5C,SAAS,UAAU,4BAA4B,GAAG,EAClD,OAAO,iBAAiB,sBAAsB,EAC9C,OAAO,OAAO,MAAc,YAAY;AACvC,QAAM,WAAWG,SAAQ,IAAI;AAC7B,QAAM,SAASH,MAAK,UAAU,YAAY,UAAU;AAEpD,UAAQ,IAAI,MAAM,KAAK,KAAK,+BAA+B,CAAC;AAE5D,MAAI,CAACC,YAAW,MAAM,GAAG;AACvB,YAAQ,IAAI,MAAM,IAAI,uDAAuD,CAAC;AAC9E,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,UAAU,IAAI,sBAAsB,EAAE,MAAM;AAElD,MAAI;AACF,UAAM,SAAS,MAAM,cAAc,EAAE,MAAM,UAAU,SAAS,QAAQ,QAAQ,CAAC;AAE/E,QAAI,OAAO,aAAa,WAAW,GAAG;AACpC,cAAQ,QAAQ,MAAM,MAAM,qBAAqB,CAAC;AAClD,cAAQ,IAAI,MAAM,KAAK,+BAA+B,CAAC;AACvD;AAAA,IACF;AAEA,YAAQ,QAAQ,MAAM,MAAM,YAAY,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAGpF,YAAQ,IAAI,MAAM,KAAK,uBAAuB,CAAC;AAC/C,eAAW,QAAQ,OAAO,aAAa,MAAM,GAAG,EAAE,GAAG;AACnD,cAAQ,IAAI,MAAM,KAAK,cAAS,IAAI,EAAE,CAAC;AAAA,IACzC;AACA,QAAI,OAAO,aAAa,SAAS,IAAI;AACnC,cAAQ,IAAI,MAAM,KAAK,eAAe,OAAO,aAAa,SAAS,EAAE,OAAO,CAAC;AAAA,IAC/E;AAGA,QAAI,OAAO,iBAAiB,SAAS,GAAG;AACtC,cAAQ,IAAI,MAAM,KAAK,0BAA0B,CAAC;AAClD,iBAAW,QAAQ,OAAO,kBAAkB;AAC1C,gBAAQ,IAAI,MAAM,KAAK,cAAS,KAAK,YAAY,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU,GAAG,CAAC;AAAA,MACxF;AAAA,IACF;AAGA,QAAI,OAAO,cAAc,OAAO,GAAG;AACjC,cAAQ,IAAI,MAAM,KAAK,wBAAwB,CAAC;AAChD,iBAAW,CAAC,UAAU,OAAO,KAAK,OAAO,cAAc,QAAQ,GAAG;AAChE,gBAAQ,IAAI,MAAM,OAAO,OAAO,QAAQ,GAAG,CAAC;AAC5C,gBAAQ,IAAI,MAAM,KAAK,SAAS,QAAQ,MAAM,iBAAiB,CAAC;AAChE,YAAI,QAAQ,SAAS;AACnB,qBAAW,UAAU,QAAQ,MAAM,GAAG,CAAC,GAAG;AACxC,oBAAQ,IAAI,MAAM,KAAK,kBAAa,OAAO,IAAI,KAAK,OAAO,IAAI,IAAI,OAAO,IAAI,GAAG,CAAC;AAAA,UACpF;AACA,cAAI,QAAQ,SAAS,GAAG;AACtB,oBAAQ,IAAI,MAAM,KAAK,mBAAmB,QAAQ,SAAS,CAAC,OAAO,CAAC;AAAA,UACtE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,kBAAkB,SAAS,GAAG;AACvC,cAAQ,IAAI,MAAM,KAAK,gCAAgC,CAAC;AACxD,iBAAW,YAAY,OAAO,mBAAmB;AAC/C,gBAAQ,IAAI,MAAM,KAAK,cAAS,QAAQ,EAAE,CAAC;AAAA,MAC7C;AAAA,IACF;AAGA,YAAQ,IAAI,MAAM,KAAK,wBAAwB,CAAC;AAChD,UAAM,YAAY,OAAO,cAAc,SAAS,MAAM,MAAM,OAAO,cAAc,WAAW,MAAM,SAAS,MAAM;AACjH,YAAQ,IAAI,OAAO,UAAU,OAAO,SAAS,CAAC,MAAM,OAAO,WAAW,qBAAqB;AAE3F,YAAQ,IAAI;AAAA,EACd,SAAS,OAAO;AACd,YAAQ,KAAK,MAAM,IAAI,wBAAwB,CAAC;AAChD,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAIH,QACG,QAAQ,SAAS,EACjB,YAAY,iCAAiC,EAC7C,SAAS,UAAU,4BAA4B,GAAG,EAClD,OAAO,2BAA2B,0BAA0B,EAC5D,OAAO,2BAA2B,0BAA0B,EAC5D,OAAO,OAAO,MAAc,YAAY;AAEvC,QAAM,eAAe,QAAQ,SAAS,KAAK,CAAC,QAAQ,IAAI,KAAK,MAAM,OAAO;AAC1E,MAAI,cAAc;AAChB,UAAM,aAAa,WAAW,CAAC,MAAM,WAAW,GAAI,QAAQ,UAAU,CAAC,aAAa,GAAG,QAAQ,OAAO,IAAI,CAAC,GAAI,GAAI,QAAQ,UAAU,CAAC,aAAa,GAAG,QAAQ,OAAO,IAAI,CAAC,CAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAAA,EACjM;AACF,CAAC;AAIH,QACG,QAAQ,YAAY,EACpB,YAAY,8CAA8C,EAC1D,OAAO,qBAAqB,qBAAqB,GAAG,EACpD,OAAO,OAAO,YAAY;AACzB,UAAQ,IAAI,uBAAuBE,SAAQ,QAAQ,IAAI;AACvD,UAAQ,IAAI,kBAAkBH,MAAKG,SAAQ,QAAQ,IAAI,GAAG,YAAY,UAAU;AAGhF,QAAM,OAAO,2BAAsB;AACrC,CAAC;AAGH,QAAQ,MAAM;","names":["resolve","join","existsSync","readFileSync","lines","fileNode","Parser","Parser","lines","fileNode","resolve","join","resolve","join","join","existsSync","readFileSync","resolve"]}
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"]}