codemap-ai 3.2.0 → 3.4.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 +1191 -31
- package/dist/cli.js.map +1 -1
- package/dist/{flow-server-UQEOUP2C.js → flow-server-4XSR5P4N.js} +2 -2
- package/dist/{flow-server-UQEOUP2C.js.map → flow-server-4XSR5P4N.js.map} +1 -1
- package/dist/index.js +424 -17
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +1 -1
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/flow/builder.ts","../src/parsers/base.ts","../src/parsers/typescript.ts","../src/parsers/python.ts","../src/parsers/index.ts","../src/types.ts"],"sourcesContent":["/**\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"],"mappings":"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","names":["lines","fileNode","Parser","Parser","lines","fileNode"]}
|
|
1
|
+
{"version":3,"sources":["../src/flow/builder.ts","../src/analysis/class-hierarchy.ts","../src/flow/enhanced-resolver.ts","../src/parsers/base.ts","../src/parsers/typescript.ts","../src/parsers/python.ts","../src/parsers/index.ts","../src/types.ts"],"sourcesContent":["/**\n * Flow Builder - Builds call graphs with resolved references\n * Core implementation for CodeMap Flow Edition\n */\n\nimport { readFileSync, statSync } from \"fs\";\nimport { createHash } from \"crypto\";\nimport { glob } from \"glob\";\nimport { resolve, relative, dirname, basename, extname } from \"path\";\nimport { FlowStorage } from \"./storage.js\";\nimport { EnhancedResolver } from \"./enhanced-resolver.js\";\nimport { parserRegistry } from \"../parsers/index.js\";\nimport type { FileAnalysis, GraphNode, GraphEdge } from \"../types.js\";\n\nexport interface FlowConfig {\n rootPath: string;\n include: string[];\n exclude: string[];\n forceReindex: boolean;\n}\n\nexport interface FlowProgress {\n phase: \"discovering\" | \"parsing\" | \"resolving\" | \"complete\";\n total: number;\n current: number;\n currentFile: string;\n}\n\nexport type ProgressCallback = (progress: FlowProgress) => void;\n\ninterface ModuleExports {\n [symbolName: string]: string; // symbol name → node ID\n}\n\nexport class FlowBuilder {\n private storage: FlowStorage;\n private config: FlowConfig;\n private onProgress?: ProgressCallback;\n private moduleMap = new Map<string, ModuleExports>(); // file path → exports\n private errors: string[] = [];\n\n constructor(storage: FlowStorage, config: FlowConfig) {\n this.storage = storage;\n this.config = config;\n }\n\n setProgressCallback(callback: ProgressCallback): void {\n this.onProgress = callback;\n }\n\n async build(): Promise<{\n indexed: number;\n skipped: number;\n resolved: number;\n unresolved: number;\n errors: string[];\n }> {\n const rootPath = resolve(this.config.rootPath);\n\n // Phase 1: Discover files\n this.emitProgress({\n phase: \"discovering\",\n total: 0,\n current: 0,\n currentFile: \"\",\n });\n\n const allFiles = await this.discoverFiles(rootPath);\n const filesToIndex: Array<{ path: string; hash: string }> = [];\n let skipped = 0;\n\n // Check which files need indexing\n for (const filePath of allFiles) {\n const content = readFileSync(filePath, \"utf-8\");\n const hash = this.hashContent(content);\n\n if (!this.config.forceReindex) {\n const existingHash = this.storage.getFileHash(filePath);\n if (existingHash === hash) {\n skipped++;\n continue;\n }\n }\n\n filesToIndex.push({ path: filePath, hash });\n }\n\n // Phase 2: Parse files and extract symbols\n let indexed = 0;\n for (const file of filesToIndex) {\n this.emitProgress({\n phase: \"parsing\",\n total: filesToIndex.length,\n current: indexed + 1,\n currentFile: relative(rootPath, file.path),\n });\n\n try {\n await this.parseAndStore(file.path, file.hash, rootPath);\n indexed++;\n } catch (error) {\n this.errors.push(`${relative(rootPath, file.path)}: ${error}`);\n }\n }\n\n // Phase 3: Resolve cross-file calls\n this.emitProgress({\n phase: \"resolving\",\n total: filesToIndex.length,\n current: filesToIndex.length,\n currentFile: \"\",\n });\n\n // First pass: Basic resolution (existing logic)\n this.resolveAllCalls();\n\n // Second pass: Enhanced resolution with type tracking\n const enhancedResolver = new EnhancedResolver(this.storage);\n enhancedResolver.buildHierarchy();\n const enhancedResolved = enhancedResolver.resolveAllCalls();\n\n // Log improvement\n if (enhancedResolved.length > 0) {\n console.log(`✨ Enhanced resolver: resolved ${enhancedResolved.length} additional calls`);\n }\n\n const stats = this.storage.getStats();\n\n this.emitProgress({\n phase: \"complete\",\n total: filesToIndex.length,\n current: filesToIndex.length,\n currentFile: \"\",\n });\n\n return {\n indexed,\n skipped,\n resolved: stats.resolvedCalls,\n unresolved: stats.unresolvedCalls,\n errors: this.errors,\n };\n }\n\n private async discoverFiles(rootPath: string): Promise<string[]> {\n const allFiles: string[] = [];\n\n for (const pattern of this.config.include) {\n const matches = await glob(pattern, {\n cwd: rootPath,\n absolute: true,\n ignore: this.config.exclude,\n nodir: true,\n });\n allFiles.push(...matches);\n }\n\n // Filter by supported extensions and size\n const supportedExts = new Set([\".py\", \".ts\", \".tsx\", \".js\", \".jsx\"]);\n const uniqueFiles = [...new Set(allFiles)].filter((f) => {\n const ext = extname(f);\n if (!supportedExts.has(ext)) return false;\n\n try {\n const stats = statSync(f);\n if (stats.size > 200000) return false; // Skip files > 200KB\n } catch {\n return false;\n }\n return true;\n });\n\n return uniqueFiles.sort();\n }\n\n private hashContent(content: string): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n }\n\n private async parseAndStore(filePath: string, hash: string, rootPath: string): Promise<void> {\n const language = this.getLanguage(filePath);\n const content = readFileSync(filePath, \"utf-8\");\n\n // Get parser for this language\n const parser = parserRegistry.getByLanguage(language);\n if (!parser) {\n throw new Error(`No parser found for language: ${language}`);\n }\n\n // Parse with tree-sitter\n const analysis = parser.parse(filePath, content);\n\n // Delete old data for this file\n this.storage.deleteFileData(filePath);\n\n // Store nodes with hashes\n const fileExports: ModuleExports = {};\n\n for (const node of analysis.nodes) {\n // Add hash to node\n const nodeHash = this.hashContent(`${node.name}:${node.startLine}:${node.endLine}`);\n const nodeWithHash = { ...node, hash: nodeHash };\n\n this.storage.insertNode(nodeWithHash);\n\n // Track exports (top-level functions and classes)\n if (node.type === \"function\" || node.type === \"class\") {\n fileExports[node.name] = node.id;\n this.storage.registerExport(filePath, node.name, node.id);\n }\n }\n\n // Store exports in module map\n this.moduleMap.set(filePath, fileExports);\n\n // Store edges (including unresolved refs)\n for (const edge of analysis.edges) {\n this.storage.insertEdge(edge);\n }\n\n // Store imports\n for (const imp of analysis.imports) {\n for (const spec of imp.specifiers) {\n this.storage.registerImport(filePath, spec, imp.source, imp.line);\n }\n }\n\n // Store variable types\n if (analysis.variableTypes) {\n for (const varType of analysis.variableTypes) {\n this.storage.registerVariableType(\n varType.variableName,\n varType.typeName,\n varType.scopeId,\n filePath,\n varType.line\n );\n }\n }\n\n // Store database operations\n if (analysis.databaseOperations) {\n for (const dbOp of analysis.databaseOperations) {\n this.storage.insertDatabaseOperation({\n id: `${dbOp.nodeId}:db:${dbOp.line}`,\n node_id: dbOp.nodeId,\n database_type: dbOp.databaseType,\n operation: dbOp.operation,\n collection: dbOp.collection,\n line: dbOp.line,\n });\n }\n }\n\n // Store file record\n this.storage.upsertFile(filePath, language, hash);\n\n // Process framework-specific patterns\n this.processFrameworkPatterns(analysis.nodes, filePath);\n }\n\n /**\n * Process framework-specific patterns (FastAPI routes, Depends, etc.)\n */\n private processFrameworkPatterns(nodes: GraphNode[], filePath: string): void {\n for (const node of nodes) {\n if (node.type === \"function\" && node.metadata) {\n // 1. Process FastAPI HTTP endpoints\n const httpEndpoint = node.metadata.httpEndpoint as { method: string; path: string } | undefined;\n if (httpEndpoint) {\n const endpointId = `${httpEndpoint.method}:${httpEndpoint.path}`;\n this.storage.insertHttpEndpoint({\n id: endpointId,\n method: httpEndpoint.method,\n path: httpEndpoint.path,\n handler_node_id: node.id,\n container_id: undefined, // Will be set when docker-compose is parsed\n metadata: {\n filePath,\n functionName: node.name,\n line: node.startLine,\n },\n });\n }\n\n // 2. Process FastAPI Depends() patterns\n const depends = node.metadata.depends as Array<{\n parameterName: string;\n dependencyName: string;\n line: number;\n }> | undefined;\n\n if (depends) {\n for (const dep of depends) {\n const depId = `${node.id}:depends:${dep.parameterName}`;\n this.storage.insertFrameworkDependency({\n id: depId,\n source_node_id: node.id,\n target_node_id: undefined, // Will be resolved later\n framework: \"fastapi\",\n pattern: \"depends\",\n parameter_name: dep.parameterName,\n line: dep.line,\n unresolved_name: dep.dependencyName,\n metadata: {\n filePath,\n functionName: node.name,\n },\n });\n }\n }\n }\n }\n }\n\n private resolveAllCalls(): void {\n // Get all unresolved edges (target_id starts with \"ref:\")\n const unresolvedEdges = this.storage.db\n .prepare(`SELECT * FROM edges WHERE target_id LIKE 'ref:%'`)\n .all() as Array<{\n id: string;\n source_id: string;\n target_id: string;\n type: string;\n metadata: string | null;\n }>;\n\n for (const edge of unresolvedEdges) {\n const refName = edge.target_id.replace(\"ref:\", \"\");\n const sourceNode = this.storage.getNode(edge.source_id);\n\n if (!sourceNode) continue;\n\n // Try to resolve the reference (pass source node ID for scope resolution)\n const resolvedId = this.resolveReference(sourceNode.filePath, refName, edge.source_id);\n\n if (resolvedId) {\n // Update edge with resolved target\n this.storage.insertEdge({\n id: edge.id,\n type: edge.type as GraphEdge[\"type\"],\n sourceId: edge.source_id,\n targetId: resolvedId,\n metadata: edge.metadata ? JSON.parse(edge.metadata) : undefined,\n });\n }\n }\n\n // Also resolve framework dependencies (FastAPI Depends)\n this.resolveFrameworkDependencies();\n }\n\n /**\n * Resolve framework dependencies (e.g., FastAPI Depends())\n */\n private resolveFrameworkDependencies(): void {\n const unresolvedDeps = this.storage.getAllUnresolvedDependencies();\n\n for (const dep of unresolvedDeps) {\n const sourceNode = this.storage.getNode(dep.source_node_id);\n if (!sourceNode) continue;\n\n // Try to resolve the dependency name to an actual node\n const resolvedId = this.resolveReference(sourceNode.filePath, dep.unresolved_name);\n\n if (resolvedId) {\n // Update the dependency with resolved target\n this.storage.updateFrameworkDependencyTarget(dep.id, resolvedId);\n\n // Also create an edge for the call graph\n this.storage.insertEdge({\n id: `${dep.id}:edge`,\n type: \"calls\",\n sourceId: dep.source_node_id,\n targetId: resolvedId,\n metadata: {\n framework: \"fastapi\",\n pattern: \"depends\",\n line: dep.line,\n },\n });\n }\n }\n }\n\n private resolveReference(sourceFilePath: string, refName: string, scopeNodeId?: string): string | null {\n // Strategy 0a: Handle super() calls\n if (refName.startsWith(\"super().\") && scopeNodeId) {\n const methodName = refName.replace(\"super().\", \"\");\n const resolvedSuper = this.storage.resolveSuperMethod(methodName, scopeNodeId);\n if (resolvedSuper) {\n return resolvedSuper;\n }\n }\n\n // Strategy 0b: Handle attribute calls (variable.method or ClassName.method)\n if (refName.includes(\".\")) {\n const parts = refName.split(\".\");\n if (parts.length === 2) {\n const [objectName, methodName] = parts;\n\n // Try variable.method resolution first (if we have scope)\n if (scopeNodeId) {\n const resolvedVarMethod = this.storage.resolveVariableMethod(objectName, methodName, scopeNodeId);\n if (resolvedVarMethod) {\n return resolvedVarMethod;\n }\n }\n\n // Fall back to ClassName.method resolution\n const resolvedClassMethod = this.storage.resolveClassMethod(objectName, methodName, sourceFilePath);\n if (resolvedClassMethod) {\n return resolvedClassMethod;\n }\n }\n }\n\n // Strategy 1: Look in the same file\n const nodesInFile = this.storage.getNodesByFile(sourceFilePath);\n for (const node of nodesInFile) {\n if (node.name === refName) {\n return node.id;\n }\n }\n\n // Strategy 2: Check imports\n const resolvedFromImport = this.storage.resolveImport(sourceFilePath, refName);\n if (resolvedFromImport) {\n return resolvedFromImport;\n }\n\n // Strategy 3: Search all nodes (fallback)\n const matches = this.storage.searchNodesByName(refName);\n if (matches.length === 1) {\n return matches[0].id;\n }\n\n return null;\n }\n\n private getLanguage(filePath: string): string {\n const ext = extname(filePath);\n if (ext === \".py\") return \"python\";\n if (ext === \".ts\" || ext === \".tsx\") return \"typescript\";\n if (ext === \".js\" || ext === \".jsx\") return \"javascript\";\n return \"unknown\";\n }\n\n private emitProgress(progress: FlowProgress): void {\n if (this.onProgress) {\n this.onProgress(progress);\n }\n }\n}\n","/**\n * Class Hierarchy Builder\n * Builds inheritance trees for improved method resolution\n */\n\nimport type { FlowNode } from \"../graph/types.js\";\n\nexport interface ClassNode {\n id: string; // Node ID\n name: string; // Class name\n file: string; // File path\n line: number; // Start line\n extends: string[]; // Parent class names\n methods: string[]; // Method names defined in this class\n}\n\nexport interface ClassHierarchy {\n classes: Map<string, ClassNode>; // class_name -> ClassNode\n children: Map<string, string[]>; // parent_name -> [child_name, ...]\n parents: Map<string, string[]>; // child_name -> [parent_name, ...]\n}\n\n/**\n * Build class hierarchy from flow nodes\n */\nexport function buildClassHierarchy(nodes: FlowNode[]): ClassHierarchy {\n const classes = new Map<string, ClassNode>();\n const children = new Map<string, string[]>();\n const parents = new Map<string, string[]>();\n\n // Step 1: Collect all class nodes\n for (const node of nodes) {\n if (node.type === \"class\") {\n const classNode: ClassNode = {\n id: node.id,\n name: node.name,\n file: node.filePath,\n line: node.startLine,\n extends: node.extends || [],\n methods: [], // Will populate in next step\n };\n\n classes.set(node.name, classNode);\n }\n }\n\n // Step 2: Find methods for each class\n for (const node of nodes) {\n if (node.type === \"method\" && node.parentClass) {\n const classNode = classes.get(node.parentClass);\n if (classNode) {\n classNode.methods.push(node.name);\n }\n }\n }\n\n // Step 3: Build parent-child relationships\n for (const [className, classNode] of classes) {\n for (const parentName of classNode.extends) {\n // Add to children map (parent -> children)\n if (!children.has(parentName)) {\n children.set(parentName, []);\n }\n children.get(parentName)!.push(className);\n\n // Add to parents map (child -> parents)\n if (!parents.has(className)) {\n parents.set(className, []);\n }\n parents.get(className)!.push(parentName);\n }\n }\n\n return {\n classes,\n children,\n parents,\n };\n}\n\n/**\n * Get all methods available for a class (including inherited)\n */\nexport function getAvailableMethods(\n className: string,\n hierarchy: ClassHierarchy\n): string[] {\n const methods = new Set<string>();\n const visited = new Set<string>();\n\n // BFS up the inheritance chain\n const queue = [className];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n // Add methods from current class\n const classNode = hierarchy.classes.get(current);\n if (classNode) {\n for (const method of classNode.methods) {\n methods.add(method);\n }\n\n // Add parent classes to queue\n const parentNames = hierarchy.parents.get(current) || [];\n for (const parent of parentNames) {\n queue.push(parent);\n }\n }\n }\n\n return Array.from(methods);\n}\n\n/**\n * Find which class defines a method (searching up inheritance chain)\n */\nexport function findMethodDefinition(\n className: string,\n methodName: string,\n hierarchy: ClassHierarchy\n): ClassNode | null {\n const visited = new Set<string>();\n const queue = [className];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n const classNode = hierarchy.classes.get(current);\n if (classNode) {\n // Check if this class defines the method\n if (classNode.methods.includes(methodName)) {\n return classNode;\n }\n\n // Search parent classes\n const parentNames = hierarchy.parents.get(current) || [];\n for (const parent of parentNames) {\n queue.push(parent);\n }\n }\n }\n\n return null;\n}\n\n/**\n * Check if a class inherits from another class\n */\nexport function inheritsFrom(\n childClass: string,\n parentClass: string,\n hierarchy: ClassHierarchy\n): boolean {\n const visited = new Set<string>();\n const queue = [childClass];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n if (current === parentClass) {\n return true;\n }\n\n // Check parents\n const parentNames = hierarchy.parents.get(current) || [];\n for (const parent of parentNames) {\n queue.push(parent);\n }\n }\n\n return false;\n}\n\n/**\n * Get all descendants of a class\n */\nexport function getDescendants(\n className: string,\n hierarchy: ClassHierarchy\n): string[] {\n const descendants: string[] = [];\n const visited = new Set<string>();\n const queue = [className];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n // Add children\n const childNames = hierarchy.children.get(current) || [];\n for (const child of childNames) {\n descendants.push(child);\n queue.push(child);\n }\n }\n\n return descendants;\n}\n\n/**\n * Get the full inheritance chain for a class\n */\nexport function getInheritanceChain(\n className: string,\n hierarchy: ClassHierarchy\n): string[] {\n const chain: string[] = [className];\n const visited = new Set<string>();\n let current = className;\n\n while (true) {\n if (visited.has(current)) {\n break;\n }\n visited.add(current);\n\n const parentNames = hierarchy.parents.get(current) || [];\n if (parentNames.length === 0) {\n break;\n }\n\n // Take first parent (for simplicity, handle multiple inheritance later)\n const parent = parentNames[0];\n chain.push(parent);\n current = parent;\n }\n\n return chain;\n}\n\n/**\n * Resolve method call on a class instance\n * Returns the class node that defines the method\n */\nexport function resolveMethodCall(\n instanceType: string,\n methodName: string,\n hierarchy: ClassHierarchy\n): ClassNode | null {\n return findMethodDefinition(instanceType, methodName, hierarchy);\n}\n\n/**\n * Get statistics about class hierarchy\n */\nexport function getHierarchyStats(hierarchy: ClassHierarchy): {\n totalClasses: number;\n classesWithParents: number;\n classesWithChildren: number;\n maxDepth: number;\n} {\n const totalClasses = hierarchy.classes.size;\n const classesWithParents = hierarchy.parents.size;\n const classesWithChildren = hierarchy.children.size;\n\n // Calculate max depth\n let maxDepth = 0;\n for (const className of hierarchy.classes.keys()) {\n const chain = getInheritanceChain(className, hierarchy);\n maxDepth = Math.max(maxDepth, chain.length);\n }\n\n return {\n totalClasses,\n classesWithParents,\n classesWithChildren,\n maxDepth,\n };\n}\n","/**\n * Enhanced Call Resolver\n * Resolves method calls using type information and class hierarchy\n */\n\nimport type { FlowStorage } from \"./storage.js\";\nimport type { GraphNode, GraphEdge } from \"../types.js\";\nimport type { VariableType } from \"../analysis/type-tracker.js\";\nimport {\n buildClassHierarchy,\n resolveMethodCall,\n type ClassHierarchy,\n} from \"../analysis/class-hierarchy.js\";\n\nexport interface ResolvedCall {\n originalEdge: GraphEdge;\n targetNode: GraphNode | null;\n confidence: \"HIGH\" | \"MEDIUM\" | \"LOW\";\n reason: string;\n}\n\n/**\n * Enhanced resolver that uses type tracking and class hierarchy\n */\nexport class EnhancedResolver {\n private hierarchy: ClassHierarchy | null = null;\n private variableTypes: Map<string, VariableType[]> = new Map();\n\n constructor(private storage: FlowStorage) {}\n\n /**\n * Build class hierarchy from all nodes in storage\n */\n buildHierarchy(): void {\n const nodes = this.getAllNodes();\n this.hierarchy = buildClassHierarchy(nodes);\n }\n\n /**\n * Load variable type information from storage\n */\n loadVariableTypes(): void {\n const stmt = this.storage.db.prepare(`\n SELECT * FROM variable_types\n `);\n\n const rows = stmt.all() as Array<{\n id: string;\n variable_name: string;\n type_name: string;\n scope_node_id: string;\n file_path: string;\n line: number;\n }>;\n\n for (const row of rows) {\n const scopeId = row.scope_node_id;\n if (!this.variableTypes.has(scopeId)) {\n this.variableTypes.set(scopeId, []);\n }\n\n this.variableTypes.get(scopeId)!.push({\n name: row.variable_name,\n type: row.type_name,\n scope: scopeId,\n line: row.line,\n });\n }\n }\n\n /**\n * Resolve all unresolved edges using type information\n */\n resolveAllCalls(): ResolvedCall[] {\n if (!this.hierarchy) {\n this.buildHierarchy();\n }\n\n this.loadVariableTypes();\n\n const resolvedCalls: ResolvedCall[] = [];\n\n // Get all unresolved edges (target starts with 'ref:')\n const stmt = this.storage.db.prepare(`\n SELECT * FROM edges\n WHERE target_id LIKE 'ref:%'\n AND type = 'calls'\n `);\n\n const edges = stmt.all() as Array<{\n id: string;\n type: string;\n source_id: string;\n target_id: string;\n metadata: string | null;\n }>;\n\n for (const edgeRow of edges) {\n const edge: GraphEdge = {\n id: edgeRow.id,\n type: edgeRow.type as GraphEdge[\"type\"],\n sourceId: edgeRow.source_id,\n targetId: edgeRow.target_id,\n metadata: edgeRow.metadata ? JSON.parse(edgeRow.metadata) : undefined,\n };\n\n const resolved = this.resolveCall(edge);\n if (resolved.targetNode) {\n resolvedCalls.push(resolved);\n\n // Update edge in database\n this.updateEdgeTarget(edge.id, resolved.targetNode.id);\n }\n }\n\n return resolvedCalls;\n }\n\n /**\n * Resolve a single call edge\n */\n resolveCall(edge: GraphEdge): ResolvedCall {\n const unresolvedName = edge.metadata?.unresolvedName as string;\n if (!unresolvedName) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"No unresolved name in metadata\",\n };\n }\n\n // Get source node (the function/method making the call)\n const sourceNode = this.storage.getNode(edge.sourceId);\n if (!sourceNode) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"Source node not found\",\n };\n }\n\n // Pattern 1: Simple function call - functionName()\n if (!unresolvedName.includes(\".\")) {\n return this.resolveSimpleCall(unresolvedName, sourceNode, edge);\n }\n\n // Pattern 2: Method call - obj.method()\n return this.resolveMethodCall(unresolvedName, sourceNode, edge);\n }\n\n /**\n * Resolve simple function call (no dot notation)\n */\n private resolveSimpleCall(\n functionName: string,\n sourceNode: GraphNode,\n edge: GraphEdge\n ): ResolvedCall {\n // Search for function in same file first\n const sameFileNodes = this.storage.getNodesByFile(sourceNode.filePath);\n const localMatch = sameFileNodes.find(\n (n) => (n.type === \"function\" || n.type === \"method\") && n.name === functionName\n );\n\n if (localMatch) {\n return {\n originalEdge: edge,\n targetNode: localMatch,\n confidence: \"HIGH\",\n reason: \"Found in same file\",\n };\n }\n\n // Search globally\n const globalMatches = this.storage.searchNodesByName(functionName);\n if (globalMatches.length === 1) {\n return {\n originalEdge: edge,\n targetNode: globalMatches[0],\n confidence: \"MEDIUM\",\n reason: \"Single global match\",\n };\n }\n\n if (globalMatches.length > 1) {\n // Multiple matches - prefer same directory\n const sourceDir = sourceNode.filePath.split(\"/\").slice(0, -1).join(\"/\");\n const sameDirMatch = globalMatches.find((n) => n.filePath.startsWith(sourceDir));\n\n if (sameDirMatch) {\n return {\n originalEdge: edge,\n targetNode: sameDirMatch,\n confidence: \"MEDIUM\",\n reason: \"Multiple matches, picked same directory\",\n };\n }\n\n return {\n originalEdge: edge,\n targetNode: globalMatches[0],\n confidence: \"LOW\",\n reason: `Multiple matches (${globalMatches.length}), picked first`,\n };\n }\n\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"No matches found\",\n };\n }\n\n /**\n * Resolve method call using type information\n * Pattern: obj.method() or self.method()\n */\n private resolveMethodCall(\n fullName: string,\n sourceNode: GraphNode,\n edge: GraphEdge\n ): ResolvedCall {\n const parts = fullName.split(\".\");\n const varName = parts[0];\n const methodName = parts.slice(1).join(\".\");\n\n // Special case: self.method() or this.method()\n if (varName === \"self\" || varName === \"this\") {\n return this.resolveSelfMethodCall(methodName, sourceNode, edge);\n }\n\n // Look up variable type in current scope\n const scopeTypes = this.variableTypes.get(sourceNode.id) || [];\n const varType = scopeTypes.find((v) => v.name === varName);\n\n if (!varType) {\n // Fallback to simple name matching\n return this.resolveSimpleCall(methodName, sourceNode, edge);\n }\n\n // Use class hierarchy to resolve method\n if (!this.hierarchy) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"Class hierarchy not built\",\n };\n }\n\n const classNode = resolveMethodCall(varType.type, methodName, this.hierarchy);\n\n if (classNode) {\n // Find the actual method node\n const methodNode = this.findMethodInClass(classNode.name, methodName);\n\n if (methodNode) {\n return {\n originalEdge: edge,\n targetNode: methodNode,\n confidence: \"HIGH\",\n reason: `Resolved via type tracking: ${varName}: ${varType.type}`,\n };\n }\n }\n\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: `Type found (${varType.type}) but method not resolved`,\n };\n }\n\n /**\n * Resolve self.method() or this.method()\n */\n private resolveSelfMethodCall(\n methodName: string,\n sourceNode: GraphNode,\n edge: GraphEdge\n ): ResolvedCall {\n // Find parent class of source method\n const parentClass = sourceNode.metadata?.parentClass as string | undefined;\n\n if (!parentClass) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"self/this call but no parent class\",\n };\n }\n\n // Search in class hierarchy\n if (!this.hierarchy) {\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: \"Class hierarchy not built\",\n };\n }\n\n const classNode = resolveMethodCall(parentClass, methodName, this.hierarchy);\n\n if (classNode) {\n const methodNode = this.findMethodInClass(classNode.name, methodName);\n\n if (methodNode) {\n return {\n originalEdge: edge,\n targetNode: methodNode,\n confidence: \"HIGH\",\n reason: `Resolved self.${methodName} in ${parentClass}`,\n };\n }\n }\n\n // Fallback: search in same file\n const sameFileNodes = this.storage.getNodesByFile(sourceNode.filePath);\n const methodNode = sameFileNodes.find(\n (n) => n.type === \"method\" && n.name === methodName\n );\n\n if (methodNode) {\n return {\n originalEdge: edge,\n targetNode: methodNode,\n confidence: \"MEDIUM\",\n reason: \"Found method in same file\",\n };\n }\n\n return {\n originalEdge: edge,\n targetNode: null,\n confidence: \"LOW\",\n reason: `Method ${methodName} not found in ${parentClass}`,\n };\n }\n\n /**\n * Find method node in a class\n */\n private findMethodInClass(className: string, methodName: string): GraphNode | null {\n const stmt = this.storage.db.prepare(`\n SELECT * FROM nodes\n WHERE type = 'method'\n AND name = ?\n AND json_extract(metadata, '$.parentClass') = ?\n `);\n\n const row = stmt.get(methodName, className) as Record<string, unknown> | undefined;\n if (!row) return null;\n\n return {\n id: row.id as string,\n type: row.type as GraphNode[\"type\"],\n name: row.name as string,\n filePath: row.file_path as string,\n startLine: row.start_line as number,\n endLine: row.end_line as number,\n language: row.language as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n };\n }\n\n /**\n * Get all nodes from storage\n */\n private getAllNodes(): GraphNode[] {\n const stmt = this.storage.db.prepare(\"SELECT * FROM nodes\");\n const rows = stmt.all() as Array<Record<string, unknown>>;\n\n return rows.map((row) => ({\n id: row.id as string,\n type: row.type as GraphNode[\"type\"],\n name: row.name as string,\n filePath: row.file_path as string,\n startLine: row.start_line as number,\n endLine: row.end_line as number,\n language: row.language as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n }));\n }\n\n /**\n * Update edge target in database\n */\n private updateEdgeTarget(edgeId: string, newTargetId: string): void {\n const stmt = this.storage.db.prepare(`\n UPDATE edges\n SET target_id = ?\n WHERE id = ?\n `);\n stmt.run(newTargetId, edgeId);\n }\n\n /**\n * Get resolution statistics\n */\n getStats(): {\n totalCalls: number;\n resolvedCalls: number;\n unresolvedCalls: number;\n resolutionRate: number;\n } {\n const totalStmt = this.storage.db.prepare(`\n SELECT COUNT(*) as count FROM edges WHERE type = 'calls'\n `);\n const totalRow = totalStmt.get() as { count: number };\n const totalCalls = totalRow.count;\n\n const resolvedStmt = this.storage.db.prepare(`\n SELECT COUNT(*) as count FROM edges\n WHERE type = 'calls' AND target_id NOT LIKE 'ref:%'\n `);\n const resolvedRow = resolvedStmt.get() as { count: number };\n const resolvedCalls = resolvedRow.count;\n\n const unresolvedCalls = totalCalls - resolvedCalls;\n const resolutionRate = totalCalls > 0 ? (resolvedCalls / totalCalls) * 100 : 0;\n\n return {\n totalCalls,\n resolvedCalls,\n unresolvedCalls,\n resolutionRate,\n };\n }\n}\n","/**\n * Base parser interface and utilities\n */\n\nimport type { FileAnalysis, GraphNode, GraphEdge, ImportInfo, ExportInfo } from \"../types.js\";\n\nexport interface Parser {\n language: string;\n extensions: string[];\n 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 // Extract extends information\n const extends_: string[] = [];\n for (const child of node.children) {\n if (child.type === \"class_heritage\") {\n const extendsClause = child.children.find((c) => c.type === \"extends_clause\");\n if (extendsClause) {\n const baseClass = extendsClause.children.find((c) => c.type === \"identifier\");\n if (baseClass) {\n extends_.push(baseClass.text);\n }\n }\n }\n }\n\n const classNode = this.createNode(\n \"class\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n extends: extends_,\n }\n );\n\n analysis.nodes.push(classNode);\n\n // Add contains edge\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, classNode.id)\n );\n\n // Create extends edges for each base class\n for (const baseClass of extends_) {\n analysis.edges.push(\n this.createEdge(\"extends\", classNode.id, `ref:${baseClass}`, {\n unresolvedName: baseClass,\n })\n );\n }\n\n // Process class body for methods\n const body = node.childForFieldName(\"body\");\n if (body) {\n for (const member of body.children) {\n if (member.type === \"method_definition\") {\n this.handleMethod(member, filePath, analysis, classNode.id);\n }\n }\n }\n }\n\n private handleMethod(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n // Find parent class name\n const parentNode = analysis.nodes.find((n) => n.id === parentId);\n const parentClass = parentNode?.type === \"class\" ? parentNode.name : undefined;\n\n const methodNode = this.createNode(\n \"method\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n static: node.children.some((c) => c.type === \"static\"),\n async: node.children.some((c) => c.type === \"async\"),\n parentClass,\n }\n );\n\n analysis.nodes.push(methodNode);\n\n // Add contains edge\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, methodNode.id)\n );\n }\n\n private handleCall(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const funcNode = node.childForFieldName(\"function\");\n if (!funcNode) return;\n\n let calledName = \"\";\n if (funcNode.type === \"identifier\") {\n calledName = funcNode.text;\n } else if (funcNode.type === \"member_expression\") {\n // Get the full member expression (e.g., \"console.log\")\n calledName = funcNode.text;\n }\n\n if (calledName) {\n analysis.edges.push(\n this.createEdge(\"calls\", parentId, `ref:${calledName}`, {\n unresolvedName: calledName,\n line: node.startPosition.row + 1,\n })\n );\n }\n }\n\n private handleVariable(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n for (const child of node.children) {\n if (child.type === \"variable_declarator\") {\n const nameNode = child.childForFieldName(\"name\");\n const valueNode = child.childForFieldName(\"value\");\n\n if (nameNode && nameNode.type === \"identifier\") {\n // Check if it's a function expression or arrow function\n if (\n valueNode &&\n (valueNode.type === \"arrow_function\" ||\n valueNode.type === \"function_expression\")\n ) {\n const funcNode = this.createNode(\n \"function\",\n nameNode.text,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n kind: node.children[0]?.text || \"const\",\n }\n );\n analysis.nodes.push(funcNode);\n analysis.edges.push(\n this.createEdge(\"contains\", parentId, funcNode.id)\n );\n }\n }\n }\n }\n }\n}\n\nexport class JavaScriptParser extends TypeScriptParser {\n language = \"javascript\";\n extensions = [\".js\", \".jsx\", \".mjs\", \".cjs\"];\n\n constructor() {\n super();\n // Override to use JavaScript grammar\n (this as any).parser = new Parser();\n (this as any).parser.setLanguage(JavaScript);\n }\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 extends: bases, // Add extends for consistency with TypeScript\n isPrivate: name.startsWith(\"_\"),\n }\n );\n\n analysis.nodes.push(classNode);\n analysis.edges.push(this.createEdge(\"contains\", parentId, classNode.id));\n\n // Add extends edges\n for (const base of bases) {\n analysis.edges.push(\n this.createEdge(\"extends\", classNode.id, `ref:${base}`, {\n unresolvedName: base,\n })\n );\n }\n\n // Parse class body for methods\n const body = node.childForFieldName(\"body\");\n if (body) {\n for (const child of body.children) {\n if (child.type === \"function_definition\") {\n this.handleMethod(child, filePath, analysis, classNode.id);\n } else if (child.type === \"decorated_definition\") {\n // Handle decorated methods (@classmethod, @staticmethod, @property, etc.)\n const funcNode = child.children.find((c) => c.type === \"function_definition\");\n if (funcNode) {\n this.handleMethod(funcNode, filePath, analysis, classNode.id);\n }\n }\n }\n }\n\n // Consider non-private classes as exports\n if (!name.startsWith(\"_\")) {\n analysis.exports.push({\n name,\n isDefault: false,\n line: node.startPosition.row + 1,\n });\n }\n }\n\n private handleMethod(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n classId: string\n ): void {\n const nameNode = node.childForFieldName(\"name\");\n if (!nameNode) return;\n\n const name = nameNode.text;\n\n // Find parent class name\n const parentNode = analysis.nodes.find((n) => n.id === classId);\n const parentClass = parentNode?.type === \"class\" ? parentNode.name : undefined;\n\n // Check for decorators - they are siblings within parent decorated_definition\n const decorators: string[] = [];\n\n // Check if parent is decorated_definition (same as for top-level functions)\n if (node.parent?.type === \"decorated_definition\") {\n for (const sibling of node.parent.children) {\n if (sibling.type === \"decorator\") {\n const decoratorAttr = sibling.children.find((c) => c.type === \"attribute\" || c.type === \"identifier\");\n if (decoratorAttr) {\n decorators.push(decoratorAttr.text);\n }\n }\n }\n }\n\n const isStatic = decorators.includes(\"staticmethod\");\n const isClassMethod = decorators.includes(\"classmethod\");\n const isProperty = decorators.includes(\"property\");\n const isAsync = node.children.some((c) => c.type === \"async\");\n\n const methodNode = this.createNode(\n \"method\",\n name,\n filePath,\n node.startPosition.row + 1,\n node.endPosition.row + 1,\n {\n async: isAsync,\n decorators,\n static: isStatic,\n classmethod: isClassMethod,\n property: isProperty,\n isPrivate: name.startsWith(\"_\"),\n isDunder: name.startsWith(\"__\") && name.endsWith(\"__\"),\n parentClass,\n }\n );\n\n analysis.nodes.push(methodNode);\n analysis.edges.push(this.createEdge(\"contains\", classId, methodNode.id));\n\n // Parse method body for calls\n const body = node.childForFieldName(\"body\");\n if (body) {\n this.parseBodyForCalls(body, filePath, analysis, methodNode.id);\n }\n }\n\n private handleCall(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const funcNode = node.childForFieldName(\"function\");\n if (!funcNode) return;\n\n let calledName = \"\";\n if (funcNode.type === \"identifier\") {\n calledName = funcNode.text;\n } else if (funcNode.type === \"attribute\") {\n // Get the full attribute access (e.g., \"self.method\", \"module.func\")\n calledName = funcNode.text;\n }\n\n if (calledName) {\n // Track all calls including self.method for proper resolution\n analysis.edges.push(\n this.createEdge(\"calls\", parentId, `ref:${calledName}`, {\n unresolvedName: calledName,\n line: node.startPosition.row + 1,\n })\n );\n\n // Detect database operations (MongoDB patterns)\n this.detectDatabaseOperation(calledName, node, parentId, analysis);\n }\n }\n\n /**\n * Detect database operations (MongoDB, SQL, etc.)\n * Examples: collection.find_one(), db.users.insert_one(), collection.update_many()\n */\n private detectDatabaseOperation(\n calledName: string,\n node: Parser.SyntaxNode,\n parentId: string,\n analysis: FileAnalysis\n ): void {\n // MongoDB operation patterns\n const mongoOps = [\n \"find_one\",\n \"find\",\n \"insert_one\",\n \"insert_many\",\n \"update_one\",\n \"update_many\",\n \"delete_one\",\n \"delete_many\",\n \"aggregate\",\n \"count_documents\",\n \"replace_one\",\n ];\n\n // Check if the called method is a MongoDB operation\n const parts = calledName.split(\".\");\n const operation = parts[parts.length - 1];\n\n if (mongoOps.includes(operation)) {\n // Try to extract collection name\n let collection = \"unknown\";\n if (parts.length >= 2) {\n collection = parts[parts.length - 2];\n }\n\n // Store database operation metadata\n if (!analysis.databaseOperations) {\n analysis.databaseOperations = [];\n }\n\n analysis.databaseOperations.push({\n nodeId: parentId,\n operation,\n collection,\n databaseType: \"mongodb\",\n line: node.startPosition.row + 1,\n });\n }\n }\n\n private parseBodyForCalls(\n body: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n parentId: string\n ): void {\n const walkForCalls = (node: Parser.SyntaxNode): void => {\n if (node.type === \"call\") {\n this.handleCall(node, filePath, analysis, parentId);\n } else if (node.type === \"import_statement\") {\n // Handle local imports inside functions\n this.handleImport(node, analysis);\n } else if (node.type === \"import_from_statement\") {\n // Handle local from imports inside functions\n this.handleFromImport(node, analysis);\n } else if (node.type === \"assignment\") {\n // Track variable assignments for type inference\n this.handleAssignment(node, filePath, analysis, parentId);\n }\n for (const child of node.children) {\n walkForCalls(child);\n }\n };\n walkForCalls(body);\n }\n\n /**\n * Handle variable assignments to track types\n * Examples:\n * user = get_user(id) # Track if get_user has type hint\n * handler = UserHandler(db) # Track: handler -> UserHandler\n * org_handler = OrgHandler.get_instance() # Track: org_handler -> OrgHandler\n */\n private handleAssignment(\n node: Parser.SyntaxNode,\n filePath: string,\n analysis: FileAnalysis,\n scopeId: string\n ): void {\n // Get left side (variable name)\n const leftNode = node.childForFieldName(\"left\");\n if (!leftNode || leftNode.type !== \"identifier\") return;\n\n const variableName = leftNode.text;\n\n // Get right side (value being assigned)\n const rightNode = node.childForFieldName(\"right\");\n if (!rightNode) return;\n\n let typeName: string | null = null;\n\n // Pattern 1: Direct class instantiation - handler = UserHandler(...)\n if (rightNode.type === \"call\") {\n const funcNode = rightNode.childForFieldName(\"function\");\n if (funcNode) {\n if (funcNode.type === \"identifier\") {\n // Simple: ClassName(...) or function_call()\n const funcName = funcNode.text;\n\n // Check if it's a known class (starts with capital) - instant assign\n if (funcName[0] === funcName[0].toUpperCase()) {\n typeName = funcName;\n } else {\n // It's a function call - we'll need to look up return type later\n // Store as a pending type resolution\n typeName = `@call:${funcName}`;\n }\n } else if (funcNode.type === \"attribute\") {\n // Class method: ClassName.method()\n const parts = funcNode.text.split(\".\");\n if (parts.length >= 2) {\n const className = parts[0];\n const methodName = parts[1];\n\n // If className is capitalized, assume the method returns that class type\n if (className[0] === className[0].toUpperCase()) {\n typeName = className;\n } else {\n // Store for later resolution\n typeName = `@call:${funcNode.text}`;\n }\n }\n }\n }\n }\n\n if (typeName && !analysis.variableTypes) {\n analysis.variableTypes = [];\n }\n\n if (typeName) {\n analysis.variableTypes!.push({\n variableName,\n typeName,\n scopeId,\n line: node.startPosition.row + 1,\n });\n }\n }\n}\n","/**\n * Parser registry and exports\n */\n\nexport { BaseParser, ParserRegistry, parserRegistry } from \"./base.js\";\nexport { TypeScriptParser, JavaScriptParser } from \"./typescript.js\";\nexport { PythonParser } from \"./python.js\";\n\nimport { parserRegistry } from \"./base.js\";\nimport { TypeScriptParser, JavaScriptParser } from \"./typescript.js\";\nimport { PythonParser } from \"./python.js\";\n\n// Register all parsers\nexport function registerAllParsers(): void {\n parserRegistry.register(new TypeScriptParser());\n parserRegistry.register(new JavaScriptParser());\n parserRegistry.register(new PythonParser());\n}\n\n// Auto-register on import\nregisterAllParsers();\n","/**\n * 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"],"mappings":";;;;;AAKA,SAAS,cAAc,gBAAgB;AACvC,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AACrB,SAAS,SAAS,UAA6B,eAAe;;;ACiBvD,SAAS,oBAAoB,OAAmC;AACrE,QAAM,UAAU,oBAAI,IAAuB;AAC3C,QAAM,WAAW,oBAAI,IAAsB;AAC3C,QAAM,UAAU,oBAAI,IAAsB;AAG1C,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,SAAS;AACzB,YAAM,YAAuB;AAAA,QAC3B,IAAI,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,SAAS,KAAK,WAAW,CAAC;AAAA,QAC1B,SAAS,CAAC;AAAA;AAAA,MACZ;AAEA,cAAQ,IAAI,KAAK,MAAM,SAAS;AAAA,IAClC;AAAA,EACF;AAGA,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,YAAY,KAAK,aAAa;AAC9C,YAAM,YAAY,QAAQ,IAAI,KAAK,WAAW;AAC9C,UAAI,WAAW;AACb,kBAAU,QAAQ,KAAK,KAAK,IAAI;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAGA,aAAW,CAAC,WAAW,SAAS,KAAK,SAAS;AAC5C,eAAW,cAAc,UAAU,SAAS;AAE1C,UAAI,CAAC,SAAS,IAAI,UAAU,GAAG;AAC7B,iBAAS,IAAI,YAAY,CAAC,CAAC;AAAA,MAC7B;AACA,eAAS,IAAI,UAAU,EAAG,KAAK,SAAS;AAGxC,UAAI,CAAC,QAAQ,IAAI,SAAS,GAAG;AAC3B,gBAAQ,IAAI,WAAW,CAAC,CAAC;AAAA,MAC3B;AACA,cAAQ,IAAI,SAAS,EAAG,KAAK,UAAU;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AA4CO,SAAS,qBACd,WACA,YACA,WACkB;AAClB,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAQ,CAAC,SAAS;AAExB,SAAO,MAAM,SAAS,GAAG;AACvB,UAAM,UAAU,MAAM,MAAM;AAE5B,QAAI,QAAQ,IAAI,OAAO,GAAG;AACxB;AAAA,IACF;AACA,YAAQ,IAAI,OAAO;AAEnB,UAAM,YAAY,UAAU,QAAQ,IAAI,OAAO;AAC/C,QAAI,WAAW;AAEb,UAAI,UAAU,QAAQ,SAAS,UAAU,GAAG;AAC1C,eAAO;AAAA,MACT;AAGA,YAAM,cAAc,UAAU,QAAQ,IAAI,OAAO,KAAK,CAAC;AACvD,iBAAW,UAAU,aAAa;AAChC,cAAM,KAAK,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAoGO,SAAS,kBACd,cACA,YACA,WACkB;AAClB,SAAO,qBAAqB,cAAc,YAAY,SAAS;AACjE;;;AC5OO,IAAM,mBAAN,MAAuB;AAAA,EAI5B,YAAoB,SAAsB;AAAtB;AAAA,EAAuB;AAAA,EAHnC,YAAmC;AAAA,EACnC,gBAA6C,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAO7D,iBAAuB;AACrB,UAAM,QAAQ,KAAK,YAAY;AAC/B,SAAK,YAAY,oBAAoB,KAAK;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA0B;AACxB,UAAM,OAAO,KAAK,QAAQ,GAAG,QAAQ;AAAA;AAAA,KAEpC;AAED,UAAM,OAAO,KAAK,IAAI;AAStB,eAAW,OAAO,MAAM;AACtB,YAAM,UAAU,IAAI;AACpB,UAAI,CAAC,KAAK,cAAc,IAAI,OAAO,GAAG;AACpC,aAAK,cAAc,IAAI,SAAS,CAAC,CAAC;AAAA,MACpC;AAEA,WAAK,cAAc,IAAI,OAAO,EAAG,KAAK;AAAA,QACpC,MAAM,IAAI;AAAA,QACV,MAAM,IAAI;AAAA,QACV,OAAO;AAAA,QACP,MAAM,IAAI;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkC;AAChC,QAAI,CAAC,KAAK,WAAW;AACnB,WAAK,eAAe;AAAA,IACtB;AAEA,SAAK,kBAAkB;AAEvB,UAAM,gBAAgC,CAAC;AAGvC,UAAM,OAAO,KAAK,QAAQ,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA,KAIpC;AAED,UAAM,QAAQ,KAAK,IAAI;AAQvB,eAAW,WAAW,OAAO;AAC3B,YAAM,OAAkB;AAAA,QACtB,IAAI,QAAQ;AAAA,QACZ,MAAM,QAAQ;AAAA,QACd,UAAU,QAAQ;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,UAAU,QAAQ,WAAW,KAAK,MAAM,QAAQ,QAAQ,IAAI;AAAA,MAC9D;AAEA,YAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAI,SAAS,YAAY;AACvB,sBAAc,KAAK,QAAQ;AAG3B,aAAK,iBAAiB,KAAK,IAAI,SAAS,WAAW,EAAE;AAAA,MACvD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,MAA+B;AACzC,UAAM,iBAAiB,KAAK,UAAU;AACtC,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,UAAM,aAAa,KAAK,QAAQ,QAAQ,KAAK,QAAQ;AACrD,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,QAAI,CAAC,eAAe,SAAS,GAAG,GAAG;AACjC,aAAO,KAAK,kBAAkB,gBAAgB,YAAY,IAAI;AAAA,IAChE;AAGA,WAAO,KAAK,kBAAkB,gBAAgB,YAAY,IAAI;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKQ,kBACN,cACA,YACA,MACc;AAEd,UAAM,gBAAgB,KAAK,QAAQ,eAAe,WAAW,QAAQ;AACrE,UAAM,aAAa,cAAc;AAAA,MAC/B,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,SAAS,aAAa,EAAE,SAAS;AAAA,IACtE;AAEA,QAAI,YAAY;AACd,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,UAAM,gBAAgB,KAAK,QAAQ,kBAAkB,YAAY;AACjE,QAAI,cAAc,WAAW,GAAG;AAC9B,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY,cAAc,CAAC;AAAA,QAC3B,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,QAAI,cAAc,SAAS,GAAG;AAE5B,YAAM,YAAY,WAAW,SAAS,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AACtE,YAAM,eAAe,cAAc,KAAK,CAAC,MAAM,EAAE,SAAS,WAAW,SAAS,CAAC;AAE/E,UAAI,cAAc;AAChB,eAAO;AAAA,UACL,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY,cAAc,CAAC;AAAA,QAC3B,YAAY;AAAA,QACZ,QAAQ,qBAAqB,cAAc,MAAM;AAAA,MACnD;AAAA,IACF;AAEA,WAAO;AAAA,MACL,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBACN,UACA,YACA,MACc;AACd,UAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,UAAM,UAAU,MAAM,CAAC;AACvB,UAAM,aAAa,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AAG1C,QAAI,YAAY,UAAU,YAAY,QAAQ;AAC5C,aAAO,KAAK,sBAAsB,YAAY,YAAY,IAAI;AAAA,IAChE;AAGA,UAAM,aAAa,KAAK,cAAc,IAAI,WAAW,EAAE,KAAK,CAAC;AAC7D,UAAM,UAAU,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAEzD,QAAI,CAAC,SAAS;AAEZ,aAAO,KAAK,kBAAkB,YAAY,YAAY,IAAI;AAAA,IAC5D;AAGA,QAAI,CAAC,KAAK,WAAW;AACnB,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,YAAY,kBAAkB,QAAQ,MAAM,YAAY,KAAK,SAAS;AAE5E,QAAI,WAAW;AAEb,YAAM,aAAa,KAAK,kBAAkB,UAAU,MAAM,UAAU;AAEpE,UAAI,YAAY;AACd,eAAO;AAAA,UACL,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,QAAQ,+BAA+B,OAAO,KAAK,QAAQ,IAAI;AAAA,QACjE;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ,eAAe,QAAQ,IAAI;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,sBACN,YACA,YACA,MACc;AAEd,UAAM,cAAc,WAAW,UAAU;AAEzC,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,WAAW;AACnB,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,YAAY,kBAAkB,aAAa,YAAY,KAAK,SAAS;AAE3E,QAAI,WAAW;AACb,YAAMA,cAAa,KAAK,kBAAkB,UAAU,MAAM,UAAU;AAEpE,UAAIA,aAAY;AACd,eAAO;AAAA,UACL,cAAc;AAAA,UACd,YAAYA;AAAA,UACZ,YAAY;AAAA,UACZ,QAAQ,iBAAiB,UAAU,OAAO,WAAW;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAGA,UAAM,gBAAgB,KAAK,QAAQ,eAAe,WAAW,QAAQ;AACrE,UAAM,aAAa,cAAc;AAAA,MAC/B,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,SAAS;AAAA,IAC3C;AAEA,QAAI,YAAY;AACd,aAAO;AAAA,QACL,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,WAAO;AAAA,MACL,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ,UAAU,UAAU,iBAAiB,WAAW;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,WAAmB,YAAsC;AACjF,UAAM,OAAO,KAAK,QAAQ,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,KAKpC;AAED,UAAM,MAAM,KAAK,IAAI,YAAY,SAAS;AAC1C,QAAI,CAAC,IAAK,QAAO;AAEjB,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,MAAM,IAAI;AAAA,MACV,MAAM,IAAI;AAAA,MACV,UAAU,IAAI;AAAA,MACd,WAAW,IAAI;AAAA,MACf,SAAS,IAAI;AAAA,MACb,UAAU,IAAI;AAAA,MACd,UAAU,IAAI,WAAW,KAAK,MAAM,IAAI,QAAkB,IAAI;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAA2B;AACjC,UAAM,OAAO,KAAK,QAAQ,GAAG,QAAQ,qBAAqB;AAC1D,UAAM,OAAO,KAAK,IAAI;AAEtB,WAAO,KAAK,IAAI,CAAC,SAAS;AAAA,MACxB,IAAI,IAAI;AAAA,MACR,MAAM,IAAI;AAAA,MACV,MAAM,IAAI;AAAA,MACV,UAAU,IAAI;AAAA,MACd,WAAW,IAAI;AAAA,MACf,SAAS,IAAI;AAAA,MACb,UAAU,IAAI;AAAA,MACd,UAAU,IAAI,WAAW,KAAK,MAAM,IAAI,QAAkB,IAAI;AAAA,IAChE,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,QAAgB,aAA2B;AAClE,UAAM,OAAO,KAAK,QAAQ,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA,KAIpC;AACD,SAAK,IAAI,aAAa,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,WAKE;AACA,UAAM,YAAY,KAAK,QAAQ,GAAG,QAAQ;AAAA;AAAA,KAEzC;AACD,UAAM,WAAW,UAAU,IAAI;AAC/B,UAAM,aAAa,SAAS;AAE5B,UAAM,eAAe,KAAK,QAAQ,GAAG,QAAQ;AAAA;AAAA;AAAA,KAG5C;AACD,UAAM,cAAc,aAAa,IAAI;AACrC,UAAM,gBAAgB,YAAY;AAElC,UAAM,kBAAkB,aAAa;AACrC,UAAM,iBAAiB,aAAa,IAAK,gBAAgB,aAAc,MAAM;AAE7E,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;ACtaO,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;AAGf,UAAM,WAAqB,CAAC;AAC5B,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;AACb,qBAAS,KAAK,UAAU,IAAI;AAAA,UAC9B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,KAAK;AAAA,MACrB;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,KAAK,cAAc,MAAM;AAAA,MACzB,KAAK,YAAY,MAAM;AAAA,MACvB;AAAA,QACE,SAAS;AAAA,MACX;AAAA,IACF;AAEA,aAAS,MAAM,KAAK,SAAS;AAG7B,aAAS,MAAM;AAAA,MACb,KAAK,WAAW,YAAY,UAAU,UAAU,EAAE;AAAA,IACpD;AAGA,eAAW,aAAa,UAAU;AAChC,eAAS,MAAM;AAAA,QACb,KAAK,WAAW,WAAW,UAAU,IAAI,OAAO,SAAS,IAAI;AAAA,UAC3D,gBAAgB;AAAA,QAClB,CAAC;AAAA,MACH;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;AAGf,UAAM,aAAa,SAAS,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AAC/D,UAAM,cAAc,YAAY,SAAS,UAAU,WAAW,OAAO;AAErE,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,QACnD;AAAA,MACF;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;;;AC7aA,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,SAAS;AAAA;AAAA,QACT,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,aAAa,SAAS,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO;AAC9D,UAAM,cAAc,YAAY,SAAS,UAAU,WAAW,OAAO;AAGrE,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,QACrD;AAAA,MACF;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;;;AC/vBO,SAAS,qBAA2B;AACzC,iBAAe,SAAS,IAAI,iBAAiB,CAAC;AAC9C,iBAAe,SAAS,IAAI,iBAAiB,CAAC;AAC9C,iBAAe,SAAS,IAAI,aAAa,CAAC;AAC5C;AAGA,mBAAmB;;;ANcZ,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;AAGD,SAAK,gBAAgB;AAGrB,UAAM,mBAAmB,IAAI,iBAAiB,KAAK,OAAO;AAC1D,qBAAiB,eAAe;AAChC,UAAM,mBAAmB,iBAAiB,gBAAgB;AAG1D,QAAI,iBAAiB,SAAS,GAAG;AAC/B,cAAQ,IAAI,sCAAiC,iBAAiB,MAAM,mBAAmB;AAAA,IACzF;AAEA,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;;;AOrTO,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;","names":["methodNode","lines","fileNode","Parser","Parser","lines","fileNode"]}
|
package/dist/mcp-server.js
CHANGED
package/dist/mcp-server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/flow-server.ts"],"sourcesContent":["/**\n * MCP Server for CodeMap Flow Edition\n * Provides 3 focused tools: impact analysis, flow tracing, and caller lookup\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { FlowStorage } from \"../flow/storage.js\";\nimport { resolve } from \"path\";\nimport { existsSync } from \"fs\";\n\n// Get config from environment\nconst DB_PATH = process.env.CODEMAP_DB_PATH || \".codemap/graph.db\";\nconst PROJECT_ROOT = process.env.CODEMAP_PROJECT_ROOT || process.cwd();\n\nlet storage: FlowStorage | null = null;\n\nfunction getStorage(): FlowStorage {\n if (!storage) {\n const dbPath = resolve(PROJECT_ROOT, DB_PATH);\n if (!existsSync(dbPath)) {\n throw new Error(`CodeMap database not found at ${dbPath}. Run 'codemap index' first.`);\n }\n storage = new FlowStorage(dbPath);\n }\n return storage;\n}\n\nconst server = new Server(\n {\n name: \"codemap-flow\",\n version: \"3.2.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n }\n);\n\n// ============ Tools ============\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"codemap_impact\",\n description: \"Analyze what would break if you change a function/class. Shows all callers and affected files with risk assessment.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: {\n type: \"string\",\n description: \"Function or class name to analyze\",\n },\n depth: {\n type: \"number\",\n description: \"How many levels deep to analyze (default: 3)\",\n default: 3,\n },\n },\n required: [\"target\"],\n },\n },\n {\n name: \"codemap_trace_flow\",\n description: \"Trace the execution flow between two functions. Shows the complete call path from source to target.\",\n inputSchema: {\n type: \"object\",\n properties: {\n from: {\n type: \"string\",\n description: \"Starting function name\",\n },\n to: {\n type: \"string\",\n description: \"Target function name\",\n },\n },\n required: [\"from\", \"to\"],\n },\n },\n {\n name: \"codemap_callers\",\n description: \"Find all functions that call a specific function. Shows where and how a function is used.\",\n inputSchema: {\n type: \"object\",\n properties: {\n function: {\n type: \"string\",\n description: \"Function name to find callers for\",\n },\n },\n required: [\"function\"],\n },\n },\n ],\n };\n});\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const db = getStorage();\n\n try {\n switch (name) {\n case \"codemap_impact\": {\n const target = args?.target as string;\n const depth = (args?.depth as number) || 3;\n\n // Find the target node(s)\n const nodes = db.searchNodesByName(target);\n\n if (nodes.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No function or class found with name \"${target}\"`,\n },\n ],\n };\n }\n\n const targetNode = nodes[0];\n\n // Get impacted nodes\n const impacted = db.getImpactedNodes(targetNode.id, depth);\n\n // Get unique files\n const affectedFiles = new Set(impacted.map((n) => n.filePath));\n\n // Assess risk\n const directCallers = db.getResolvedCallers(targetNode.id);\n let risk = \"LOW\";\n if (directCallers.length > 10) risk = \"HIGH\";\n else if (directCallers.length > 5) risk = \"MEDIUM\";\n\n const response = `# Impact Analysis: ${targetNode.name}\n\n**Location:** ${targetNode.filePath}:${targetNode.startLine}\n**Type:** ${targetNode.type}\n**Risk Level:** ${risk}\n\n## Direct Callers (${directCallers.length})\n${directCallers.slice(0, 10).map((c) => `- ${c.name} in ${c.filePath}:${c.startLine}`).join(\"\\n\")}\n${directCallers.length > 10 ? `\\n... and ${directCallers.length - 10} more` : \"\"}\n\n## Total Impact\n- **Affected functions:** ${impacted.length}\n- **Affected files:** ${affectedFiles.size}\n\n## Affected Files\n${[...affectedFiles].slice(0, 20).map((f) => `- ${f}`).join(\"\\n\")}\n${affectedFiles.size > 20 ? `\\n... and ${affectedFiles.size - 20} more` : \"\"}\n\n⚠️ **Recommendation:** ${risk === \"HIGH\" ? \"High-risk change. Review all callers before modifying.\" : risk === \"MEDIUM\" ? \"Moderate risk. Test affected files after changes.\" : \"Low risk. Changes unlikely to cause wide impact.\"}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n case \"codemap_trace_flow\": {\n const from = args?.from as string;\n const to = args?.to as string;\n\n // Find source and target nodes\n const sourceNodes = db.searchNodesByName(from);\n const targetNodes = db.searchNodesByName(to);\n\n if (sourceNodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Source function \"${from}\" not found` }],\n };\n }\n\n if (targetNodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Target function \"${to}\" not found` }],\n };\n }\n\n const sourceNode = sourceNodes[0];\n const targetNode = targetNodes[0];\n\n // Trace path\n const path = db.traceCallPath(sourceNode.id, targetNode.id);\n\n if (!path) {\n return {\n content: [\n {\n type: \"text\",\n text: `No call path found from \"${from}\" to \"${to}\". They may not be connected.`,\n },\n ],\n };\n }\n\n const response = `# Execution Flow: ${from} → ${to}\n\n${path.nodes\n .map(\n (n, i) =>\n `${i + 1}. **${n.name}**\\n File: ${n.file}:${n.line}${i < path.nodes.length - 1 ? \"\\n ↓ calls\" : \"\"}`\n )\n .join(\"\\n\\n\")}\n\n**Total steps:** ${path.nodes.length}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n case \"codemap_callers\": {\n const functionName = args?.function as string;\n\n // Find the function\n const nodes = db.searchNodesByName(functionName);\n\n if (nodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Function \"${functionName}\" not found` }],\n };\n }\n\n const targetNode = nodes[0];\n\n // Get all callers\n const callers = db.getResolvedCallers(targetNode.id);\n\n if (callers.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No callers found for \"${functionName}\". It may be unused or only called externally.`,\n },\n ],\n };\n }\n\n const response = `# Callers of ${functionName}\n\n**Function:** ${targetNode.name} (${targetNode.type})\n**Location:** ${targetNode.filePath}:${targetNode.startLine}\n**Total callers:** ${callers.length}\n\n## Who Calls This Function\n\n${callers\n .map(\n (c) => `- **${c.name}** (${c.type})\n File: ${c.filePath}:${c.startLine}`\n )\n .join(\"\\n\\n\")}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n default:\n return {\n content: [{ type: \"text\", text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: \"text\", text: `Error: ${errorMessage}` }],\n isError: true,\n };\n }\n});\n\n// Start server\nconst transport = new StdioServerTransport();\nserver.connect(transport).catch((error) => {\n console.error(\"Failed to start MCP server:\", error);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/mcp/flow-server.ts"],"sourcesContent":["/**\n * MCP Server for CodeMap Flow Edition\n * Provides 3 focused tools: impact analysis, flow tracing, and caller lookup\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { FlowStorage } from \"../flow/storage.js\";\nimport { resolve } from \"path\";\nimport { existsSync } from \"fs\";\n\n// Get config from environment\nconst DB_PATH = process.env.CODEMAP_DB_PATH || \".codemap/graph.db\";\nconst PROJECT_ROOT = process.env.CODEMAP_PROJECT_ROOT || process.cwd();\n\nlet storage: FlowStorage | null = null;\n\nfunction getStorage(): FlowStorage {\n if (!storage) {\n const dbPath = resolve(PROJECT_ROOT, DB_PATH);\n if (!existsSync(dbPath)) {\n throw new Error(`CodeMap database not found at ${dbPath}. Run 'codemap index' first.`);\n }\n storage = new FlowStorage(dbPath);\n }\n return storage;\n}\n\nconst server = new Server(\n {\n name: \"codemap-flow\",\n version: \"3.4.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n }\n);\n\n// ============ Tools ============\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"codemap_impact\",\n description: \"Analyze what would break if you change a function/class. Shows all callers and affected files with risk assessment.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: {\n type: \"string\",\n description: \"Function or class name to analyze\",\n },\n depth: {\n type: \"number\",\n description: \"How many levels deep to analyze (default: 3)\",\n default: 3,\n },\n },\n required: [\"target\"],\n },\n },\n {\n name: \"codemap_trace_flow\",\n description: \"Trace the execution flow between two functions. Shows the complete call path from source to target.\",\n inputSchema: {\n type: \"object\",\n properties: {\n from: {\n type: \"string\",\n description: \"Starting function name\",\n },\n to: {\n type: \"string\",\n description: \"Target function name\",\n },\n },\n required: [\"from\", \"to\"],\n },\n },\n {\n name: \"codemap_callers\",\n description: \"Find all functions that call a specific function. Shows where and how a function is used.\",\n inputSchema: {\n type: \"object\",\n properties: {\n function: {\n type: \"string\",\n description: \"Function name to find callers for\",\n },\n },\n required: [\"function\"],\n },\n },\n ],\n };\n});\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const db = getStorage();\n\n try {\n switch (name) {\n case \"codemap_impact\": {\n const target = args?.target as string;\n const depth = (args?.depth as number) || 3;\n\n // Find the target node(s)\n const nodes = db.searchNodesByName(target);\n\n if (nodes.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No function or class found with name \"${target}\"`,\n },\n ],\n };\n }\n\n const targetNode = nodes[0];\n\n // Get impacted nodes\n const impacted = db.getImpactedNodes(targetNode.id, depth);\n\n // Get unique files\n const affectedFiles = new Set(impacted.map((n) => n.filePath));\n\n // Assess risk\n const directCallers = db.getResolvedCallers(targetNode.id);\n let risk = \"LOW\";\n if (directCallers.length > 10) risk = \"HIGH\";\n else if (directCallers.length > 5) risk = \"MEDIUM\";\n\n const response = `# Impact Analysis: ${targetNode.name}\n\n**Location:** ${targetNode.filePath}:${targetNode.startLine}\n**Type:** ${targetNode.type}\n**Risk Level:** ${risk}\n\n## Direct Callers (${directCallers.length})\n${directCallers.slice(0, 10).map((c) => `- ${c.name} in ${c.filePath}:${c.startLine}`).join(\"\\n\")}\n${directCallers.length > 10 ? `\\n... and ${directCallers.length - 10} more` : \"\"}\n\n## Total Impact\n- **Affected functions:** ${impacted.length}\n- **Affected files:** ${affectedFiles.size}\n\n## Affected Files\n${[...affectedFiles].slice(0, 20).map((f) => `- ${f}`).join(\"\\n\")}\n${affectedFiles.size > 20 ? `\\n... and ${affectedFiles.size - 20} more` : \"\"}\n\n⚠️ **Recommendation:** ${risk === \"HIGH\" ? \"High-risk change. Review all callers before modifying.\" : risk === \"MEDIUM\" ? \"Moderate risk. Test affected files after changes.\" : \"Low risk. Changes unlikely to cause wide impact.\"}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n case \"codemap_trace_flow\": {\n const from = args?.from as string;\n const to = args?.to as string;\n\n // Find source and target nodes\n const sourceNodes = db.searchNodesByName(from);\n const targetNodes = db.searchNodesByName(to);\n\n if (sourceNodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Source function \"${from}\" not found` }],\n };\n }\n\n if (targetNodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Target function \"${to}\" not found` }],\n };\n }\n\n const sourceNode = sourceNodes[0];\n const targetNode = targetNodes[0];\n\n // Trace path\n const path = db.traceCallPath(sourceNode.id, targetNode.id);\n\n if (!path) {\n return {\n content: [\n {\n type: \"text\",\n text: `No call path found from \"${from}\" to \"${to}\". They may not be connected.`,\n },\n ],\n };\n }\n\n const response = `# Execution Flow: ${from} → ${to}\n\n${path.nodes\n .map(\n (n, i) =>\n `${i + 1}. **${n.name}**\\n File: ${n.file}:${n.line}${i < path.nodes.length - 1 ? \"\\n ↓ calls\" : \"\"}`\n )\n .join(\"\\n\\n\")}\n\n**Total steps:** ${path.nodes.length}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n case \"codemap_callers\": {\n const functionName = args?.function as string;\n\n // Find the function\n const nodes = db.searchNodesByName(functionName);\n\n if (nodes.length === 0) {\n return {\n content: [{ type: \"text\", text: `Function \"${functionName}\" not found` }],\n };\n }\n\n const targetNode = nodes[0];\n\n // Get all callers\n const callers = db.getResolvedCallers(targetNode.id);\n\n if (callers.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No callers found for \"${functionName}\". It may be unused or only called externally.`,\n },\n ],\n };\n }\n\n const response = `# Callers of ${functionName}\n\n**Function:** ${targetNode.name} (${targetNode.type})\n**Location:** ${targetNode.filePath}:${targetNode.startLine}\n**Total callers:** ${callers.length}\n\n## Who Calls This Function\n\n${callers\n .map(\n (c) => `- **${c.name}** (${c.type})\n File: ${c.filePath}:${c.startLine}`\n )\n .join(\"\\n\\n\")}\n`;\n\n return {\n content: [{ type: \"text\", text: response }],\n };\n }\n\n default:\n return {\n content: [{ type: \"text\", text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: \"text\", text: `Error: ${errorMessage}` }],\n isError: true,\n };\n }\n});\n\n// Start server\nconst transport = new StdioServerTransport();\nserver.connect(transport).catch((error) => {\n console.error(\"Failed to start MCP server:\", error);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|