archtracker-mcp 0.4.0 → 0.4.2

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/bin.js ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/bin.ts
4
+ var CLI_COMMANDS = ["init", "analyze", "check", "context", "serve", "ci-setup", "help"];
5
+ var CLI_FLAGS = ["--help", "-h", "--version", "-V"];
6
+ var args = process.argv.slice(2);
7
+ var hasCommand = args.some((arg) => CLI_COMMANDS.includes(arg));
8
+ var hasFlag = args.some((arg) => CLI_FLAGS.includes(arg));
9
+ if (hasCommand || hasFlag) {
10
+ await import("./cli/index.js");
11
+ } else {
12
+ await import("./mcp/index.js");
13
+ }
14
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bin.ts"],"sourcesContent":["/**\n * Smart entry point for `archtracker-mcp` binary.\n *\n * - If CLI subcommands are detected (serve, analyze, init, etc.) → run CLI\n * - Otherwise → start MCP server on stdio\n *\n * This allows both:\n * npx archtracker-mcp → MCP server\n * npx archtracker-mcp serve --target src → Web viewer (CLI mode)\n * npx archtracker-mcp analyze --target src → Analysis report (CLI mode)\n */\n\nconst CLI_COMMANDS = [\"init\", \"analyze\", \"check\", \"context\", \"serve\", \"ci-setup\", \"help\"];\nconst CLI_FLAGS = [\"--help\", \"-h\", \"--version\", \"-V\"];\n\nconst args = process.argv.slice(2);\nconst hasCommand = args.some((arg) => CLI_COMMANDS.includes(arg));\nconst hasFlag = args.some((arg) => CLI_FLAGS.includes(arg));\n\nif (hasCommand || hasFlag) {\n await import(\"./cli/index.js\");\n} else {\n await import(\"./mcp/index.js\");\n}\n"],"mappings":";;;AAYA,IAAM,eAAe,CAAC,QAAQ,WAAW,SAAS,WAAW,SAAS,YAAY,MAAM;AACxF,IAAM,YAAY,CAAC,UAAU,MAAM,aAAa,IAAI;AAEpD,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,aAAa,KAAK,KAAK,CAAC,QAAQ,aAAa,SAAS,GAAG,CAAC;AAChE,IAAM,UAAU,KAAK,KAAK,CAAC,QAAQ,UAAU,SAAS,GAAG,CAAC;AAE1D,IAAI,cAAc,SAAS;AACzB,QAAM,OAAO,gBAAgB;AAC/B,OAAO;AACL,QAAM,OAAO,gBAAgB;AAC/B;","names":[]}
package/dist/mcp/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env node
2
+
1
3
  // src/mcp/index.ts
2
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/index.ts","../../src/analyzer/analyze.ts","../../src/analyzer/engines/regex-engine.ts","../../src/analyzer/engines/cycle.ts","../../src/analyzer/engines/strip-comments.ts","../../src/analyzer/engines/detect.ts","../../src/analyzer/engines/languages.ts","../../src/analyzer/engines/types.ts","../../src/i18n/index.ts","../../src/analyzer/search.ts","../../src/analyzer/report.ts","../../src/storage/snapshot.ts","../../src/types/schema.ts","../../src/storage/diff.ts","../../src/utils/path-guard.ts","../../src/utils/version.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport {\n analyzeProject,\n AnalyzerError,\n searchByPath,\n findAffectedFiles,\n findCriticalFiles,\n findOrphanFiles,\n formatAnalysisReport,\n} from \"../analyzer/index.js\";\nimport {\n saveSnapshot,\n loadSnapshot,\n computeDiff,\n formatDiffReport,\n StorageError,\n} from \"../storage/index.js\";\nimport type { ArchContext } from \"../types/schema.js\";\nimport { validatePath, PathTraversalError } from \"../utils/path-guard.js\";\nimport { t } from \"../i18n/index.js\";\nimport { VERSION } from \"../utils/version.js\";\nimport { LANGUAGE_IDS } from \"../analyzer/engines/types.js\";\n\nconst server = new McpServer({\n name: \"archtracker\",\n version: VERSION,\n});\n\n/** Zod enum for language parameter — derived from LANGUAGE_IDS */\nconst languageEnum = z.enum(LANGUAGE_IDS);\n\n/** Human-readable language list for tool descriptions */\nconst LANG_DISPLAY: Record<string, string> = {\n javascript: \"JS/TS\", \"c-cpp\": \"C/C++\", \"c-sharp\": \"C#\",\n};\nconst languageList = LANGUAGE_IDS\n .map((id) => LANG_DISPLAY[id] ?? id.charAt(0).toUpperCase() + id.slice(1))\n .join(\", \");\n\n// ─── Tool 1: generate_map ───────────────────────────────────────\n\nserver.tool(\n \"generate_map\",\n `Analyze dependency graph of a directory and return file import/export structure as JSON. Supports ${languageList}.`,\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path (default: src)\"),\n exclude: z\n .array(z.string())\n .optional()\n .describe(\"Array of regex patterns to exclude (e.g. ['test', 'mock'])\"),\n maxDepth: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe(\"Max analysis depth (0 = unlimited)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, exclude, maxDepth, language }) => {\n try {\n validatePath(targetDir);\n const graph = await analyzeProject(targetDir, { exclude, maxDepth, language });\n\n const summary = [\n t(\"mcp.analyzeComplete\", { files: graph.totalFiles, edges: graph.totalEdges }),\n graph.circularDependencies.length > 0\n ? t(\"mcp.circularFound\", { count: graph.circularDependencies.length })\n : t(\"mcp.circularNone\"),\n ].join(\"\\n\");\n\n return {\n content: [\n { type: \"text\" as const, text: summary },\n { type: \"text\" as const, text: JSON.stringify(graph, null, 2) },\n ],\n };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 2: analyze_existing_architecture ──────────────────────\n\nserver.tool(\n \"analyze_existing_architecture\",\n `Comprehensive architecture analysis for existing projects. Shows critical components, circular dependencies, orphan files, coupling hotspots, and directory breakdown. Supports ${LANGUAGE_IDS.length} languages.`,\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path (default: src)\"),\n exclude: z\n .array(z.string())\n .optional()\n .describe(\"Array of regex patterns to exclude\"),\n topN: z\n .number()\n .int()\n .min(1)\n .max(50)\n .optional()\n .describe(\"Number of top items to show in each section (default: 10)\"),\n saveSnapshot: z\n .boolean()\n .optional()\n .describe(\"Also save a snapshot after analysis (default: false)\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root (needed only when saveSnapshot is true)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, exclude, topN, saveSnapshot: doSave, projectRoot, language }) => {\n try {\n validatePath(targetDir);\n const graph = await analyzeProject(targetDir, { exclude, language });\n const report = formatAnalysisReport(graph, { topN: topN ?? 10 });\n\n const content: { type: \"text\"; text: string }[] = [\n { type: \"text\" as const, text: report },\n ];\n\n if (doSave) {\n validatePath(projectRoot);\n await saveSnapshot(projectRoot, graph);\n content.push({ type: \"text\" as const, text: t(\"analyze.snapshotSaved\") });\n }\n\n return { content };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 3: save_architecture_snapshot ─────────────────────────\n\nserver.tool(\n \"save_architecture_snapshot\",\n \"Save the current dependency graph as a snapshot to .archtracker/snapshot.json\",\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root (where .archtracker is placed)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, projectRoot, language }) => {\n try {\n validatePath(targetDir);\n validatePath(projectRoot);\n const graph = await analyzeProject(targetDir, { language });\n const snapshot = await saveSnapshot(projectRoot, graph);\n\n // Top 5 most-depended-on files\n const keyComponents = Object.values(graph.files)\n .sort((a, b) => b.dependents.length - a.dependents.length)\n .slice(0, 5)\n .map((f) => ` ${t(\"cli.dependedBy\", { path: f.path, count: f.dependents.length })}`);\n\n const report = [\n t(\"mcp.snapshotSaved\"),\n t(\"cli.timestamp\", { ts: snapshot.timestamp }),\n t(\"cli.fileCount\", { count: graph.totalFiles }),\n t(\"cli.edgeCount\", { count: graph.totalEdges }),\n \"\",\n t(\"cli.keyComponents\"),\n ...keyComponents,\n ].join(\"\\n\");\n\n return { content: [{ type: \"text\" as const, text: report }] };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 3: check_architecture_diff ────────────────────────────\n\nserver.tool(\n \"check_architecture_diff\",\n \"Compare saved snapshot with current code dependencies and warn about files that may need updates\",\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root (where .archtracker is placed)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, projectRoot, language }) => {\n try {\n validatePath(targetDir);\n validatePath(projectRoot);\n const existingSnapshot = await loadSnapshot(projectRoot);\n\n if (!existingSnapshot) {\n // Auto-generate initial snapshot\n const graph = await analyzeProject(targetDir, { language });\n await saveSnapshot(projectRoot, graph);\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n t(\"mcp.autoInit\"),\n t(\"cli.fileCount\", { count: graph.totalFiles }) + \", \" + t(\"cli.edgeCount\", { count: graph.totalEdges }),\n t(\"mcp.nextCheckEnabled\"),\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n const currentGraph = await analyzeProject(targetDir, { language });\n const diff = computeDiff(existingSnapshot.graph, currentGraph);\n const report = formatDiffReport(diff);\n\n return { content: [{ type: \"text\" as const, text: report }] };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 4: get_current_context ────────────────────────────────\n\nserver.tool(\n \"get_current_context\",\n \"Get current valid file paths and architecture summary for AI session initialization\",\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, projectRoot, language }) => {\n try {\n let snapshot = await loadSnapshot(projectRoot);\n\n // Auto-generate if no snapshot exists\n if (!snapshot) {\n const graph = await analyzeProject(targetDir, { language });\n snapshot = await saveSnapshot(projectRoot, graph);\n }\n\n const graph = snapshot.graph;\n\n // Build key components list (sorted by dependent count)\n const keyComponents = Object.values(graph.files)\n .filter((f) => f.dependents.length > 0 || f.dependencies.length > 0)\n .sort((a, b) => b.dependents.length - a.dependents.length)\n .slice(0, 20)\n .map((f) => ({\n path: f.path,\n dependentCount: f.dependents.length,\n dependencyCount: f.dependencies.length,\n }));\n\n const validPaths = Object.keys(graph.files).sort();\n\n const summary = [\n t(\"cli.project\", { path: graph.rootDir }),\n t(\"cli.fileCount\", { count: graph.totalFiles }),\n t(\"cli.edgeCount\", { count: graph.totalEdges }),\n t(\"cli.circularCount\", { count: graph.circularDependencies.length }),\n t(\"cli.snapshot\", { ts: snapshot.timestamp }),\n \"\",\n t(\"cli.keyComponents\"),\n ...keyComponents.map(\n (c) =>\n ` ${t(\"cli.dependedBy\", { path: c.path, count: c.dependentCount })}`,\n ),\n ].join(\"\\n\");\n\n const context: ArchContext = {\n validPaths,\n summary,\n snapshotExists: true,\n snapshotTimestamp: snapshot.timestamp,\n keyComponents,\n };\n\n return {\n content: [\n { type: \"text\" as const, text: summary },\n {\n type: \"text\" as const,\n text: JSON.stringify(context, null, 2),\n },\n ],\n };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 5: search_architecture ────────────────────────────────\n\nserver.tool(\n \"search_architecture\",\n \"Search architecture: file path search, impact analysis, critical component detection, orphan file detection\",\n {\n query: z\n .string()\n .optional()\n .describe(\"Search query (required for path/affected modes, not needed for critical/orphans)\"),\n mode: z\n .enum([\"path\", \"affected\", \"critical\", \"orphans\"])\n .default(\"path\")\n .describe(\n \"Search mode: path=search by path, affected=change impact, critical=key files, orphans=isolated files\",\n ),\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root\"),\n limit: z\n .number()\n .int()\n .min(1)\n .max(50)\n .optional()\n .describe(\"Max results (default: 10)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ query, mode, targetDir, projectRoot, limit, language }) => {\n try {\n validatePath(targetDir);\n validatePath(projectRoot);\n // Use existing snapshot or generate fresh\n let snapshot = await loadSnapshot(projectRoot);\n if (!snapshot) {\n const graph = await analyzeProject(targetDir, { language });\n snapshot = await saveSnapshot(projectRoot, graph);\n }\n\n const graph = snapshot.graph;\n const maxResults = limit ?? 10;\n let results;\n\n // Validate query is provided for modes that require it\n if ((mode === \"path\" || mode === \"affected\") && !query) {\n return {\n content: [{ type: \"text\" as const, text: t(\"mcp.queryRequired\", { mode }) }],\n isError: true,\n };\n }\n\n switch (mode) {\n case \"path\":\n results = searchByPath(graph, query!);\n break;\n case \"affected\":\n results = findAffectedFiles(graph, query!);\n break;\n case \"critical\":\n results = findCriticalFiles(graph, maxResults);\n break;\n case \"orphans\":\n results = findOrphanFiles(graph);\n break;\n }\n\n if (results.length === 0) {\n return {\n content: [\n { type: \"text\" as const, text: t(\"search.noResults\", { query: query ?? \"\", mode }) },\n ],\n };\n }\n\n const lines = [\n t(\"search.results\", { count: results.length, mode }),\n \"\",\n ...results.slice(0, maxResults).map((r) => {\n return [\n ` ${r.file}`,\n ` ${r.matchReason}`,\n ` deps: ${r.dependencyCount} -> [${r.dependencies.slice(0, 5).join(\", \")}${r.dependencies.length > 5 ? \"...\" : \"\"}]`,\n ` dependents: ${r.dependentCount} <- [${r.dependents.slice(0, 5).join(\", \")}${r.dependents.length > 5 ? \"...\" : \"\"}]`,\n ].join(\"\\n\");\n }),\n ];\n\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Error handling helper ──────────────────────────────────────\n\nfunction errorResponse(error: unknown) {\n let message: string;\n\n if (error instanceof PathTraversalError) {\n message = t(\"error.pathTraversal\", { message: error.message });\n } else if (error instanceof AnalyzerError) {\n message = t(\"error.analyzer\", { message: error.message });\n } else if (error instanceof StorageError) {\n message = t(\"error.storage\", { message: error.message });\n } else if (error instanceof Error) {\n message = t(\"error.generic\", { message: error.message });\n } else {\n message = t(\"error.unexpected\", { message: String(error) });\n }\n\n return {\n content: [{ type: \"text\" as const, text: message }],\n isError: true,\n };\n}\n\n// ─── Server startup ─────────────────────────────────────────────\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"[archtracker] MCP server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"[archtracker] Fatal error:\", error);\n process.exit(1);\n});\n","import { resolve } from \"node:path\";\nimport { stat } from \"node:fs/promises\";\nimport type { DependencyGraph } from \"../types/schema.js\";\nimport { RegexEngine } from \"./engines/regex-engine.js\";\nimport { detectLanguage } from \"./engines/detect.js\";\nimport { getLanguageConfig } from \"./engines/languages.js\";\nimport type { LanguageId } from \"./engines/types.js\";\n\n/** Options for the dependency analyzer */\nexport interface AnalyzeOptions {\n /** Regex patterns to exclude from analysis (e.g. [\"node_modules\", \"\\\\.test\\\\.ts$\"]) */\n exclude?: string[];\n /** Maximum recursion depth (0 = unlimited) */\n maxDepth?: number;\n /** Target language (auto-detected if omitted) */\n language?: LanguageId;\n}\n\n/**\n * Analyze project dependencies using regex-based import extraction.\n * Supports all 13 languages. Language is auto-detected if not specified.\n */\nexport async function analyzeProject(\n rootDir: string,\n options: AnalyzeOptions = {},\n): Promise<DependencyGraph> {\n const absRootDir = resolve(rootDir);\n\n // Validate directory exists\n try {\n const s = await stat(absRootDir);\n if (!s.isDirectory()) {\n throw new AnalyzerError(`Not a directory: ${absRootDir}`);\n }\n } catch (error) {\n if (error instanceof AnalyzerError) throw error;\n throw new AnalyzerError(`Directory not found: ${absRootDir}`, { cause: error });\n }\n\n const language = options.language ?? (await detectLanguage(absRootDir));\n\n try {\n const config = getLanguageConfig(language);\n if (!config) {\n throw new AnalyzerError(`No analyzer config for language: ${language}`);\n }\n\n return await new RegexEngine(config).analyze(absRootDir, options);\n } catch (error) {\n if (error instanceof AnalyzerError) throw error;\n const message = error instanceof Error ? error.message : String(error);\n throw new AnalyzerError(message, { cause: error });\n }\n}\n\n/** Custom error class for analyzer failures */\nexport class AnalyzerError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AnalyzerError\";\n }\n}\n","import { readdir, readFile, stat } from \"node:fs/promises\";\nimport { join, relative, resolve } from \"node:path\";\nimport type {\n DependencyGraph,\n DependencyEdge,\n FileNode,\n} from \"../../types/schema.js\";\nimport type { AnalyzerEngine, LanguageConfig } from \"./types.js\";\nimport { detectCycles } from \"./cycle.js\";\nimport { stripComments } from \"./strip-comments.js\";\n\nexport class RegexEngine implements AnalyzerEngine {\n constructor(private config: LanguageConfig) {}\n\n async analyze(\n rootDir: string,\n options: { exclude?: string[]; maxDepth?: number } = {},\n ): Promise<DependencyGraph> {\n const absRootDir = resolve(rootDir);\n const excludePatterns = [\n ...(this.config.defaultExclude ?? []),\n ...(options.exclude ?? []),\n \"\\\\.archtracker\",\n ].map((p) => new RegExp(p));\n\n // 1. Collect all matching files\n const projectFiles = await this.collectFiles(\n absRootDir,\n absRootDir,\n excludePatterns,\n options.maxDepth ?? 0,\n );\n\n const projectFileSet = new Set(projectFiles);\n\n // 2. Extract imports and resolve edges\n const files: Record<string, FileNode> = {};\n const edges: DependencyEdge[] = [];\n const edgeSet = new Set<string>(); // \"source\\0target\" for dedup\n\n // Initialize all file nodes\n for (const filePath of projectFiles) {\n const relPath = relative(absRootDir, filePath);\n files[relPath] = {\n path: relPath,\n exists: true,\n dependencies: [],\n dependents: [],\n };\n }\n\n // Process each file for imports\n for (const filePath of projectFiles) {\n const relSource = relative(absRootDir, filePath);\n let content: string;\n try {\n content = await readFile(filePath, \"utf-8\");\n } catch {\n if (files[relSource]) files[relSource].exists = false;\n continue;\n }\n\n const stripped = stripComments(content, this.config.commentStyle);\n const imports = this.extractImports(stripped);\n for (const importPath of imports) {\n const resolved = this.config.resolveImport(\n importPath,\n filePath,\n absRootDir,\n projectFileSet,\n );\n if (!resolved) continue;\n\n const relTarget = relative(absRootDir, resolved);\n if (!files[relTarget]) continue; // skip external\n if (relSource === relTarget) continue; // skip self-import\n\n const edgeKey = `${relSource}\\0${relTarget}`;\n if (edgeSet.has(edgeKey)) continue; // deduplicate\n edgeSet.add(edgeKey);\n\n edges.push({\n source: relSource,\n target: relTarget,\n type: \"static\",\n });\n\n files[relSource].dependencies.push(relTarget);\n files[relTarget].dependents.push(relSource);\n }\n }\n\n // 3. Detect cycles\n const circularDependencies = detectCycles(edges);\n\n return {\n rootDir: absRootDir,\n files,\n edges,\n circularDependencies,\n totalFiles: Object.keys(files).length,\n totalEdges: edges.length,\n };\n }\n\n private extractImports(content: string): string[] {\n // Use custom extractor if defined (e.g., Rust grouped use)\n if (this.config.extractImports) {\n return this.config.extractImports(content);\n }\n\n const imports: string[] = [];\n for (const pattern of this.config.importPatterns) {\n // Reset regex state, ensuring 'g' flag is present to prevent infinite loops\n const flags = pattern.regex.flags.includes('g') ? pattern.regex.flags : pattern.regex.flags + 'g';\n const regex = new RegExp(pattern.regex.source, flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(content)) !== null) {\n // Use the first capturing group as the import path\n if (match[1]) {\n imports.push(match[1]);\n }\n }\n }\n return imports;\n }\n\n private async collectFiles(\n dir: string,\n absRootDir: string,\n excludePatterns: RegExp[],\n maxDepth: number,\n currentDepth: number = 0,\n ): Promise<string[]> {\n if (maxDepth > 0 && currentDepth >= maxDepth) return [];\n\n const results: string[] = [];\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relPath = relative(absRootDir, fullPath);\n\n // Check excludes against the entry name and relative path\n if (\n excludePatterns.some(\n (p) => p.test(entry.name) || p.test(relPath) || p.test(fullPath),\n )\n ) {\n continue;\n }\n\n if (entry.isDirectory()) {\n if (entry.name.startsWith(\".\")) continue;\n const sub = await this.collectFiles(\n fullPath,\n absRootDir,\n excludePatterns,\n maxDepth,\n currentDepth + 1,\n );\n results.push(...sub);\n } else if (entry.isFile()) {\n const dotIdx = entry.name.lastIndexOf(\".\");\n if (dotIdx > 0) {\n const ext = entry.name.slice(dotIdx);\n if (this.config.extensions.includes(ext)) {\n results.push(fullPath);\n }\n }\n }\n }\n\n return results;\n }\n}\n","import type { DependencyEdge, CircularDependency } from \"../../types/schema.js\";\n\nexport function detectCycles(edges: DependencyEdge[]): CircularDependency[] {\n const adj = new Map<string, string[]>();\n for (const edge of edges) {\n if (!adj.has(edge.source)) adj.set(edge.source, []);\n adj.get(edge.source)!.push(edge.target);\n }\n\n const visited = new Set<string>();\n const inStack = new Set<string>();\n const cycles: CircularDependency[] = [];\n const cycleKeys = new Set<string>();\n\n function dfs(node: string, path: string[]): void {\n if (inStack.has(node)) {\n const cycleStart = path.indexOf(node);\n if (cycleStart !== -1) {\n const cycle = path.slice(cycleStart);\n const key = [...cycle].sort().join(\"\\u2192\");\n if (!cycleKeys.has(key)) {\n cycleKeys.add(key);\n cycles.push({ cycle });\n }\n }\n return;\n }\n if (visited.has(node)) return;\n\n visited.add(node);\n inStack.add(node);\n path.push(node);\n\n for (const neighbor of adj.get(node) ?? []) {\n dfs(neighbor, path);\n }\n\n path.pop();\n inStack.delete(node);\n }\n\n for (const node of adj.keys()) {\n if (!visited.has(node)) {\n dfs(node, []);\n }\n }\n\n return cycles;\n}\n","import type { CommentStyle } from \"./types.js\";\n\n/**\n * Strip comments and string literals from source code.\n * Replaces them with whitespace to preserve line numbers and positions.\n */\nexport function stripComments(content: string, style: CommentStyle): string {\n switch (style) {\n case \"c-style\":\n return stripCStyle(content);\n case \"hash\":\n return stripHash(content);\n case \"python\":\n return stripPython(content);\n case \"ruby\":\n return stripRuby(content);\n case \"php\":\n return stripPhp(content);\n default: {\n const _exhaustive: never = style;\n throw new Error(`Unknown comment style: ${_exhaustive}`);\n }\n }\n}\n\n/**\n * C-style comments: // line comments and /* block comments *\\/\n * Used by: Rust, Go, Java, C/C++, Swift, Kotlin\n * Also strips string literals (\"...\" and '...' for char literals)\n * Handles Rust raw strings: r\"...\", r#\"...\"#, r##\"...\"## etc.\n */\nfunction stripCStyle(content: string): string {\n let result = \"\";\n let i = 0;\n while (i < content.length) {\n // Rust raw strings: r\"...\", r#\"...\"#, r##\"...\"##, etc.\n if (content[i] === \"r\" && i + 1 < content.length) {\n let hashes = 0;\n let j = i + 1;\n while (j < content.length && content[j] === \"#\") {\n hashes++;\n j++;\n }\n if (j < content.length && content[j] === '\"') {\n // This is a raw string: r\"...\", r#\"...\"#, etc.\n // Replace entire raw string content with spaces\n // Replace r, hashes, and opening quote with spaces\n for (let k = i; k <= j; k++) {\n result += \" \";\n }\n i = j + 1; // move past opening quote\n // Scan for closing pattern\n while (i < content.length) {\n if (content[i] === '\"') {\n // Check if followed by correct number of hashes\n let matchHashes = 0;\n let m = i + 1;\n while (m < content.length && content[m] === \"#\" && matchHashes < hashes) {\n matchHashes++;\n m++;\n }\n if (matchHashes === hashes) {\n // Found the closing delimiter\n for (let k = i; k < m; k++) {\n result += \" \";\n }\n i = m;\n break;\n }\n }\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n continue;\n }\n // Not a raw string, fall through to normal character handling\n }\n\n // Single-line comment\n if (content[i] === \"/\" && content[i + 1] === \"/\") {\n // Skip to end of line, preserve newline\n while (i < content.length && content[i] !== \"\\n\") {\n result += \" \";\n i++;\n }\n }\n // Block comment\n else if (content[i] === \"/\" && content[i + 1] === \"*\") {\n result += \" \";\n i++; // /\n result += \" \";\n i++; // *\n while (i < content.length) {\n if (content[i] === \"*\" && content[i + 1] === \"/\") {\n result += \" \";\n i++;\n result += \" \";\n i++;\n break;\n }\n // Preserve newlines for line-number accuracy\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n }\n // Double-quoted string\n else if (content[i] === '\"') {\n result += content[i]; // keep the quote\n i++;\n while (i < content.length && content[i] !== '\"') {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i]; // backslash\n i++;\n result += content[i]; // escaped char\n i++;\n } else if (content[i] === \"\\n\") {\n result += \"\\n\";\n i++;\n } else {\n result += content[i];\n i++;\n }\n }\n if (i < content.length) {\n result += content[i]; // closing quote\n i++;\n }\n }\n // Single-quoted char literal (e.g. '/', '\\'', '\\\\', '\\n')\n else if (content[i] === \"'\") {\n result += content[i]; // opening quote\n i++;\n while (i < content.length && content[i] !== \"'\") {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i]; // backslash\n i++;\n result += content[i]; // escaped char\n i++;\n } else {\n result += content[i];\n i++;\n }\n }\n if (i < content.length) {\n result += content[i]; // closing quote\n i++;\n }\n }\n // Raw/backtick string (Go)\n else if (content[i] === \"`\") {\n result += \" \"; // replace backtick string content\n i++;\n while (i < content.length && content[i] !== \"`\") {\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n if (i < content.length) {\n result += \" \";\n i++;\n }\n }\n // Normal character\n else {\n result += content[i];\n i++;\n }\n }\n return result;\n}\n\n/**\n * Hash-style comments: # line comments\n * Used by: (standalone, though mostly via python/ruby)\n */\nfunction stripHash(content: string): string {\n let result = \"\";\n let i = 0;\n while (i < content.length) {\n if (content[i] === \"#\") {\n while (i < content.length && content[i] !== \"\\n\") {\n result += \" \";\n i++;\n }\n } else if (content[i] === '\"') {\n result += content[i];\n i++;\n while (i < content.length && content[i] !== '\"') {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else {\n result += content[i++];\n }\n }\n if (i < content.length) { result += content[i]; i++; }\n } else if (content[i] === \"'\") {\n result += content[i];\n i++;\n while (i < content.length && content[i] !== \"'\") {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else {\n result += content[i++];\n }\n }\n if (i < content.length) { result += content[i]; i++; }\n } else {\n result += content[i];\n i++;\n }\n }\n return result;\n}\n\n/**\n * Python comments: # line comments + triple-quoted strings (\"\"\" and ''')\n * Handles string prefixes: r, b, f, rb, fr, br (case-insensitive)\n * For raw strings (r prefix), backslash is NOT treated as escape.\n */\nfunction stripPython(content: string): string {\n let result = \"\";\n let i = 0;\n while (i < content.length) {\n // Check for string prefix (r, b, f, rb, fr, br) before quotes\n let prefixLen = 0;\n let isRaw = false;\n if (i < content.length) {\n const c0 = content[i];\n const c1 = i + 1 < content.length ? content[i + 1] : \"\";\n const c2 = i + 2 < content.length ? content[i + 2] : \"\";\n // Two-char prefixes: rb, br, fr, rf\n if (\n (c0 === \"r\" || c0 === \"R\" || c0 === \"b\" || c0 === \"B\" || c0 === \"f\" || c0 === \"F\") &&\n (c1 === \"r\" || c1 === \"R\" || c1 === \"b\" || c1 === \"B\" || c1 === \"f\" || c1 === \"F\") &&\n (c2 === '\"' || c2 === \"'\")\n ) {\n // Validate it's a real two-char prefix (rb, br, fr, rf)\n const pair = (c0 + c1).toLowerCase();\n if (pair === \"rb\" || pair === \"br\" || pair === \"fr\" || pair === \"rf\") {\n prefixLen = 2;\n isRaw = pair.includes(\"r\");\n }\n }\n // Single-char prefix: r, b, f\n if (\n prefixLen === 0 &&\n (c0 === \"r\" || c0 === \"R\" || c0 === \"b\" || c0 === \"B\" || c0 === \"f\" || c0 === \"F\") &&\n (c1 === '\"' || c1 === \"'\")\n ) {\n prefixLen = 1;\n isRaw = c0 === \"r\" || c0 === \"R\";\n }\n }\n\n const quoteStart = i + prefixLen;\n\n // Triple-quoted strings (with or without prefix)\n if (\n quoteStart + 2 < content.length &&\n (content[quoteStart] === '\"' || content[quoteStart] === \"'\") &&\n content[quoteStart + 1] === content[quoteStart] &&\n content[quoteStart + 2] === content[quoteStart]\n ) {\n const quote = content[quoteStart];\n // Output prefix chars\n for (let k = 0; k < prefixLen; k++) {\n result += \" \";\n }\n // Replace triple-quoted content with spaces\n result += \" \";\n i = quoteStart + 3;\n while (i < content.length) {\n if (content[i] === quote && content[i + 1] === quote && content[i + 2] === quote) {\n result += \" \";\n i += 3;\n break;\n }\n if (!isRaw && content[i] === \"\\\\\" && i + 1 < content.length) {\n result += \" \";\n i++;\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n } else {\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n }\n }\n // Hash comment\n else if (prefixLen === 0 && content[i] === \"#\") {\n while (i < content.length && content[i] !== \"\\n\") {\n result += \" \";\n i++;\n }\n }\n // Single/double quoted strings (non-triple), with or without prefix\n else if (\n quoteStart < content.length &&\n (content[quoteStart] === '\"' || content[quoteStart] === \"'\") &&\n (prefixLen > 0 || content[i] === '\"' || content[i] === \"'\")\n ) {\n const quote = content[quoteStart];\n // Output prefix\n for (let k = i; k < quoteStart; k++) {\n result += content[k];\n }\n result += content[quoteStart]; // opening quote\n i = quoteStart + 1;\n while (i < content.length && content[i] !== quote) {\n if (!isRaw && content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else if (content[i] === \"\\n\") {\n result += \"\\n\";\n i++;\n break; // unterminated string\n } else {\n result += content[i++];\n }\n }\n if (i < content.length && content[i] === quote) { result += content[i]; i++; }\n }\n else {\n result += content[i];\n i++;\n }\n }\n return result;\n}\n\n/**\n * Ruby comments: # line comments + =begin/=end block comments\n * Handles string interpolation #{} inside double-quoted strings.\n */\nfunction stripRuby(content: string): string {\n const lines = content.split(\"\\n\");\n const result: string[] = [];\n let inBlock = false;\n\n for (const line of lines) {\n if (!inBlock && /^=begin(\\s|$)/.test(line)) {\n inBlock = true;\n result.push(\" \".repeat(line.length));\n continue;\n }\n if (inBlock) {\n if (/^=end(\\s|$)/.test(line)) {\n inBlock = false;\n }\n result.push(\" \".repeat(line.length));\n continue;\n }\n\n // Process line for # comments (respecting strings)\n let processed = \"\";\n let i = 0;\n while (i < line.length) {\n if (line[i] === \"#\") {\n // Outside of any string, this is a comment\n processed += \" \".repeat(line.length - i);\n break;\n } else if (line[i] === '\"') {\n processed += line[i]; i++;\n processed = scanRubyDoubleQuotedString(line, i, processed);\n i = (scanRubyDoubleQuotedStringIndex(line, i));\n } else if (line[i] === \"'\") {\n processed += line[i]; i++;\n while (i < line.length && line[i] !== \"'\") {\n if (line[i] === \"\\\\\" && i + 1 < line.length) {\n processed += line[i++];\n processed += line[i++];\n } else {\n processed += line[i++];\n }\n }\n if (i < line.length) { processed += line[i]; i++; }\n } else {\n processed += line[i]; i++;\n }\n }\n result.push(processed);\n }\n\n return result.join(\"\\n\");\n}\n\n/**\n * Scans a Ruby double-quoted string body starting at position i (after the opening \"),\n * handling #{} interpolation. Returns the resulting processed string content appended to `processed`.\n */\nfunction scanRubyDoubleQuotedString(line: string, startI: number, processed: string): string {\n let i = startI;\n while (i < line.length && line[i] !== '\"') {\n if (line[i] === \"\\\\\" && i + 1 < line.length) {\n processed += line[i++];\n processed += line[i++];\n } else if (line[i] === \"#\" && i + 1 < line.length && line[i + 1] === \"{\") {\n // String interpolation: #{...}\n processed += line[i++]; // #\n processed += line[i++]; // {\n let depth = 1;\n while (i < line.length && depth > 0) {\n if (line[i] === \"{\") {\n depth++;\n processed += line[i++];\n } else if (line[i] === \"}\") {\n depth--;\n processed += line[i++];\n } else if (line[i] === \"\\\\\" && i + 1 < line.length) {\n processed += line[i++];\n processed += line[i++];\n } else {\n processed += line[i++];\n }\n }\n } else {\n processed += line[i++];\n }\n }\n if (i < line.length) { processed += line[i]; /* closing \" */ }\n return processed;\n}\n\n/**\n * Returns the index after scanning a Ruby double-quoted string body starting at startI.\n */\nfunction scanRubyDoubleQuotedStringIndex(line: string, startI: number): number {\n let i = startI;\n while (i < line.length && line[i] !== '\"') {\n if (line[i] === \"\\\\\" && i + 1 < line.length) {\n i += 2;\n } else if (line[i] === \"#\" && i + 1 < line.length && line[i + 1] === \"{\") {\n i += 2; // skip #{\n let depth = 1;\n while (i < line.length && depth > 0) {\n if (line[i] === \"{\") {\n depth++;\n i++;\n } else if (line[i] === \"}\") {\n depth--;\n i++;\n } else if (line[i] === \"\\\\\" && i + 1 < line.length) {\n i += 2;\n } else {\n i++;\n }\n }\n } else {\n i++;\n }\n }\n if (i < line.length) { i++; /* skip closing \" */ }\n return i;\n}\n\n/**\n * PHP comments: // line, /* block *\\/, and # line\n * Also handles heredoc (<<<IDENTIFIER) and nowdoc (<<<'IDENTIFIER').\n */\nfunction stripPhp(content: string): string {\n let result = \"\";\n let i = 0;\n while (i < content.length) {\n // Heredoc / Nowdoc: <<<IDENTIFIER or <<<'IDENTIFIER'\n if (content[i] === \"<\" && content[i + 1] === \"<\" && content[i + 2] === \"<\") {\n const heredocStart = i;\n let j = i + 3;\n let isNowdoc = false;\n // Skip optional whitespace after <<<\n // Check for nowdoc (single-quoted identifier)\n if (j < content.length && content[j] === \"'\") {\n isNowdoc = true;\n j++; // skip opening '\n }\n // Read identifier\n const identStart = j;\n while (j < content.length && /[A-Za-z0-9_]/.test(content[j])) {\n j++;\n }\n const identifier = content.slice(identStart, j);\n if (identifier.length > 0) {\n // For nowdoc, skip the closing '\n if (isNowdoc && j < content.length && content[j] === \"'\") {\n j++;\n }\n // Check for optional semicolon and newline (or just newline) to validate this is heredoc syntax\n // We need at least a newline after the identifier line\n let validHeredoc = false;\n let lineEnd = j;\n // There might be a semicolon and/or other chars before newline, but typically just newline\n if (lineEnd < content.length && content[lineEnd] === \"\\n\") {\n validHeredoc = true;\n }\n if (validHeredoc) {\n // Output the heredoc opening line as-is (<<<IDENTIFIER or <<<'IDENTIFIER')\n for (let k = heredocStart; k <= lineEnd; k++) {\n if (content[k] === \"\\n\") {\n result += \"\\n\";\n } else {\n result += content[k];\n }\n }\n i = lineEnd + 1; // move past the newline\n // Now scan for the closing identifier on its own line\n // The closing identifier may optionally be followed by ; and must be at end of line\n let found = false;\n while (i < content.length && !found) {\n // Check if current line starts with the identifier\n const lineStart = i;\n // Read the current line\n let lineEndIdx = i;\n while (lineEndIdx < content.length && content[lineEndIdx] !== \"\\n\") {\n lineEndIdx++;\n }\n const currentLine = content.slice(lineStart, lineEndIdx);\n // PHP 7.3+ allows indented heredoc closing, but we check trimmed\n const trimmedLine = currentLine.trimStart();\n if (\n trimmedLine === identifier ||\n trimmedLine === identifier + \";\" ||\n trimmedLine === identifier + \",\" ||\n trimmedLine === identifier + \");\" ||\n trimmedLine === identifier + \")\" ||\n trimmedLine.startsWith(identifier + \";\") ||\n trimmedLine === identifier\n ) {\n // This is the closing line - output it as-is\n for (let k = lineStart; k < lineEndIdx; k++) {\n result += content[k];\n }\n i = lineEndIdx;\n if (i < content.length && content[i] === \"\\n\") {\n result += \"\\n\";\n i++;\n }\n found = true;\n } else {\n // Body line: replace content with spaces, preserve newlines\n for (let k = lineStart; k < lineEndIdx; k++) {\n result += \" \";\n }\n i = lineEndIdx;\n if (i < content.length && content[i] === \"\\n\") {\n result += \"\\n\";\n i++;\n }\n }\n }\n continue;\n }\n }\n // If not a valid heredoc, just output the < and continue\n result += content[i];\n i++;\n continue;\n }\n\n // Single-line comments (// or #)\n if ((content[i] === \"/\" && content[i + 1] === \"/\") || content[i] === \"#\") {\n while (i < content.length && content[i] !== \"\\n\") {\n result += \" \";\n i++;\n }\n }\n // Block comments\n else if (content[i] === \"/\" && content[i + 1] === \"*\") {\n result += \" \"; i++;\n result += \" \"; i++;\n while (i < content.length) {\n if (content[i] === \"*\" && content[i + 1] === \"/\") {\n result += \" \"; i++;\n result += \" \"; i++;\n break;\n }\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n }\n // Double-quoted string\n else if (content[i] === '\"') {\n result += content[i]; i++;\n while (i < content.length && content[i] !== '\"') {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else {\n result += content[i++];\n }\n }\n if (i < content.length) { result += content[i]; i++; }\n }\n // Single-quoted string\n else if (content[i] === \"'\") {\n result += content[i]; i++;\n while (i < content.length && content[i] !== \"'\") {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else {\n result += content[i++];\n }\n }\n if (i < content.length) { result += content[i]; i++; }\n }\n else {\n result += content[i]; i++;\n }\n }\n return result;\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { LanguageId } from \"./types.js\";\n\n/** Marker files that identify a project's primary language */\nconst MARKERS: Array<{ file: string; language: LanguageId }> = [\n { file: \"Cargo.toml\", language: \"rust\" },\n { file: \"go.mod\", language: \"go\" },\n { file: \"pyproject.toml\", language: \"python\" },\n { file: \"setup.py\", language: \"python\" },\n { file: \"requirements.txt\", language: \"python\" },\n { file: \"Pipfile\", language: \"python\" },\n { file: \"pom.xml\", language: \"java\" },\n { file: \"build.gradle\", language: \"java\" },\n { file: \"build.gradle.kts\", language: \"kotlin\" },\n { file: \"build.sbt\", language: \"scala\" },\n { file: \"build.sc\", language: \"scala\" },\n { file: \"Package.swift\", language: \"swift\" },\n { file: \"Gemfile\", language: \"ruby\" },\n { file: \"composer.json\", language: \"php\" },\n { file: \"pubspec.yaml\", language: \"dart\" },\n { file: \"CMakeLists.txt\", language: \"c-cpp\" },\n { file: \"Makefile\", language: \"c-cpp\" },\n { file: \"package.json\", language: \"javascript\" },\n { file: \"tsconfig.json\", language: \"javascript\" },\n];\n\n/** Extension-based markers for languages without fixed-name marker files */\nconst EXT_MARKERS: Array<[string, LanguageId]> = [\n [\".sln\", \"c-sharp\"],\n [\".csproj\", \"c-sharp\"],\n];\n\n/** Extension-to-language mapping for fallback detection */\nconst EXT_MAP: Record<string, LanguageId> = {\n \".ts\": \"javascript\",\n \".tsx\": \"javascript\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".rs\": \"rust\",\n \".go\": \"go\",\n \".java\": \"java\",\n \".c\": \"c-cpp\",\n \".cpp\": \"c-cpp\",\n \".cc\": \"c-cpp\",\n \".cxx\": \"c-cpp\",\n \".h\": \"c-cpp\",\n \".hpp\": \"c-cpp\",\n \".rb\": \"ruby\",\n \".php\": \"php\",\n \".swift\": \"swift\",\n \".kt\": \"kotlin\",\n \".kts\": \"kotlin\",\n \".cs\": \"c-sharp\",\n \".dart\": \"dart\",\n \".scala\": \"scala\",\n \".sc\": \"scala\",\n};\n\n/**\n * Auto-detect the primary language of a project directory.\n * 1. Check for marker files (Cargo.toml, go.mod, etc.)\n * 2. Fallback: count file extensions in the top-level directory\n */\nexport async function detectLanguage(rootDir: string): Promise<LanguageId> {\n // Phase 1: marker files\n for (const marker of MARKERS) {\n try {\n const s = await stat(join(rootDir, marker.file));\n if (s.isFile() || s.isDirectory()) {\n return marker.language;\n }\n } catch {\n // file doesn't exist, continue\n }\n }\n\n // Phase 1.5: extension-based markers (e.g. *.sln, *.csproj for C#)\n try {\n const topEntries = await readdir(rootDir, { withFileTypes: true });\n for (const entry of topEntries) {\n if (!entry.isFile()) continue;\n for (const [ext, lang] of EXT_MARKERS) {\n if (entry.name.endsWith(ext)) return lang;\n }\n }\n } catch {\n // ignore\n }\n\n // Phase 2: extension frequency (shallow scan)\n const counts = new Map<LanguageId, number>();\n try {\n await scanExtensions(rootDir, counts, 2, 0);\n } catch {\n // if scan fails, default to JS\n }\n\n if (counts.size > 0) {\n let maxLang: LanguageId = \"javascript\";\n let maxCount = 0;\n for (const [lang, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxLang = lang;\n }\n }\n return maxLang;\n }\n\n return \"javascript\";\n}\n\nasync function scanExtensions(\n dir: string,\n counts: Map<LanguageId, number>,\n maxDepth: number,\n currentDepth: number,\n): Promise<void> {\n if (currentDepth >= maxDepth) return;\n\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n\n if (entry.isDirectory() && currentDepth < maxDepth - 1) {\n await scanExtensions(\n join(dir, entry.name),\n counts,\n maxDepth,\n currentDepth + 1,\n );\n } else if (entry.isFile()) {\n const dotIdx = entry.name.lastIndexOf(\".\");\n if (dotIdx > 0) {\n const ext = entry.name.slice(dotIdx);\n const lang = EXT_MAP[ext];\n if (lang) {\n counts.set(lang, (counts.get(lang) ?? 0) + 1);\n }\n }\n }\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { join, dirname, resolve } from \"node:path\";\nimport { LANGUAGE_IDS } from \"./types.js\";\nimport type { LanguageConfig, LanguageId } from \"./types.js\";\n\n// ─── Python ──────────────────────────────────────────\nconst python: LanguageConfig = {\n id: \"python\",\n extensions: [\".py\"],\n commentStyle: \"python\",\n importPatterns: [\n // from package.module import something\n { regex: /^from\\s+(\\.[\\w.]*|\\w[\\w.]*)\\s+import\\b/gm },\n // import package.module (handled by extractImports for multi-module case)\n ],\n // Bug #1 fix: custom extractImports to handle `import a, b, c`\n extractImports(content: string): string[] {\n const imports: string[] = [];\n\n // from package.module import something\n const fromRegex = /^from\\s+(\\.[\\w.]*|\\w[\\w.]*)\\s+import\\b/gm;\n let match: RegExpExecArray | null;\n while ((match = fromRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n // import a, b, c — captures all comma-separated modules\n const importRegex = /^import\\s+([\\w.]+(?:\\s*,\\s*[\\w.]+)*)/gm;\n while ((match = importRegex.exec(content)) !== null) {\n const modules = match[1].split(\",\");\n for (const mod of modules) {\n const trimmed = mod.trim();\n if (trimmed) imports.push(trimmed);\n }\n }\n\n return imports;\n },\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Relative imports (starts with .)\n if (importPath.startsWith(\".\")) {\n const dots = importPath.match(/^\\.+/)?.[0].length ?? 1;\n let base = dirname(sourceFile);\n for (let i = 1; i < dots; i++) base = dirname(base);\n const rest = importPath.slice(dots).replace(/\\./g, \"/\");\n return tryPythonResolve(join(base, rest), projectFiles);\n }\n // Absolute imports\n const parts = importPath.replace(/\\./g, \"/\");\n return tryPythonResolve(join(rootDir, parts), projectFiles);\n },\n defaultExclude: [\"__pycache__\", \"\\\\.venv\", \"venv\", \"\\\\.egg-info\", \"dist\", \"build\"],\n};\n\nfunction tryPythonResolve(base: string, projectFiles: Set<string>): string | null {\n // Try as module file\n if (projectFiles.has(base + \".py\")) return base + \".py\";\n // Try as package __init__.py\n if (projectFiles.has(join(base, \"__init__.py\"))) return join(base, \"__init__.py\");\n return null;\n}\n\n// ─── Rust ────────────────────────────────────────────\nconst rust: LanguageConfig = {\n id: \"rust\",\n extensions: [\".rs\"],\n commentStyle: \"c-style\",\n importPatterns: [], // handled by extractImports\n extractImports(content: string): string[] {\n const imports: string[] = [];\n\n // mod declarations: mod child;\n const modRegex = /\\bmod\\s+(\\w+)\\s*;/gm;\n let match: RegExpExecArray | null;\n while ((match = modRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n // use crate::... (simple and grouped)\n const useRegex = /\\buse\\s+crate::([\\s\\S]*?);/gm;\n while ((match = useRegex.exec(content)) !== null) {\n const body = match[1].trim();\n extractRustUsePaths(body, \"\", imports);\n }\n\n // Bug #2 fix: use super::... imports\n const useSuperRegex = /\\buse\\s+super::([\\s\\S]*?);/gm;\n while ((match = useSuperRegex.exec(content)) !== null) {\n const body = match[1].trim();\n extractRustUsePaths(body, \"\", imports, \"super\");\n }\n\n // Bug #2 fix: use self::... imports\n const useSelfRegex = /\\buse\\s+self::([\\s\\S]*?);/gm;\n while ((match = useSelfRegex.exec(content)) !== null) {\n const body = match[1].trim();\n extractRustUsePaths(body, \"\", imports, \"self\");\n }\n\n return imports;\n },\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n const srcDir = join(rootDir, \"src\");\n\n if (!importPath.includes(\"::\")) {\n // mod declaration: look for child module\n const parentDir = dirname(sourceFile);\n const asFile = join(parentDir, importPath + \".rs\");\n if (projectFiles.has(asFile)) return asFile;\n const asDir = join(parentDir, importPath, \"mod.rs\");\n if (projectFiles.has(asDir)) return asDir;\n return null;\n }\n\n // Bug #3 fix: use super::x::y — resolve from parent directory of source file\n if (importPath.startsWith(\"super::\")) {\n const parentDir = dirname(dirname(sourceFile));\n const segments = importPath.slice(\"super::\".length).split(\"::\");\n for (let i = segments.length; i > 0; i--) {\n const path = segments.slice(0, i).join(\"/\");\n const asFile = join(parentDir, path + \".rs\");\n if (projectFiles.has(asFile)) return asFile;\n const asDir = join(parentDir, path, \"mod.rs\");\n if (projectFiles.has(asDir)) return asDir;\n }\n return null;\n }\n\n // Bug #4 fix: use self::x::y — resolve from same directory as source file\n if (importPath.startsWith(\"self::\")) {\n const selfDir = dirname(sourceFile);\n const segments = importPath.slice(\"self::\".length).split(\"::\");\n for (let i = segments.length; i > 0; i--) {\n const path = segments.slice(0, i).join(\"/\");\n const asFile = join(selfDir, path + \".rs\");\n if (projectFiles.has(asFile)) return asFile;\n const asDir = join(selfDir, path, \"mod.rs\");\n if (projectFiles.has(asDir)) return asDir;\n }\n return null;\n }\n\n // use crate::x::y — resolve from src/\n const segments = importPath.split(\"::\");\n // Try progressively shorter prefixes as directory/file\n for (let i = segments.length; i > 0; i--) {\n const path = segments.slice(0, i).join(\"/\");\n const asFile = join(srcDir, path + \".rs\");\n if (projectFiles.has(asFile)) return asFile;\n const asDir = join(srcDir, path, \"mod.rs\");\n if (projectFiles.has(asDir)) return asDir;\n }\n return null;\n },\n defaultExclude: [\"target\"],\n};\n\n/**\n * Recursively extract Rust use paths, handling grouped imports.\n * e.g. \"foo::{bar, baz::qux}\" → [\"foo::bar\", \"foo::baz::qux\"]\n * e.g. \"foo::bar\" → [\"foo::bar\"]\n * The optional rootPrefix parameter prepends \"super\" or \"self\" to all paths.\n */\nfunction extractRustUsePaths(body: string, prefix: string, results: string[], rootPrefix?: string): void {\n const trimmed = body.trim();\n\n // Check for grouped import: path::{...}\n const braceStart = trimmed.indexOf(\"{\");\n if (braceStart === -1) {\n // Simple path like \"foo::bar::Baz\" or just \"foo\"\n let path = prefix ? `${prefix}::${trimmed}` : trimmed;\n if (rootPrefix) {\n path = `${rootPrefix}::${path}`;\n }\n // Remove trailing items after last :: that aren't module names\n // Keep the full path — resolver handles progressively shorter prefixes\n if (path && !path.includes(\"{\")) {\n results.push(path);\n }\n return;\n }\n\n // Extract the prefix before the brace\n let pathPrefix = trimmed.slice(0, braceStart).trim();\n if (pathPrefix.endsWith(\"::\")) {\n pathPrefix = pathPrefix.slice(0, -2);\n }\n const fullPrefix = prefix ? `${prefix}::${pathPrefix}` : pathPrefix;\n\n // Find matching closing brace\n let depth = 0;\n let braceEnd = -1;\n for (let i = braceStart; i < trimmed.length; i++) {\n if (trimmed[i] === \"{\") depth++;\n else if (trimmed[i] === \"}\") {\n depth--;\n if (depth === 0) { braceEnd = i; break; }\n }\n }\n if (braceEnd === -1) return;\n\n // Split the brace content by commas (respecting nested braces)\n const inner = trimmed.slice(braceStart + 1, braceEnd).trim();\n const items = splitByTopLevelComma(inner);\n\n for (const item of items) {\n const cleaned = item.trim();\n if (cleaned === \"self\") {\n const selfPath = rootPrefix ? `${rootPrefix}::${fullPrefix}` : fullPrefix;\n results.push(selfPath);\n } else if (cleaned) {\n extractRustUsePaths(cleaned, fullPrefix, results, rootPrefix);\n }\n }\n}\n\n/** Split string by commas, respecting nested braces */\nfunction splitByTopLevelComma(s: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < s.length; i++) {\n if (s[i] === \"{\") depth++;\n else if (s[i] === \"}\") depth--;\n else if (s[i] === \",\" && depth === 0) {\n parts.push(s.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(s.slice(start));\n return parts;\n}\n\n// ─── Go ──────────────────────────────────────────────\nconst go: LanguageConfig = {\n id: \"go\",\n extensions: [\".go\"],\n commentStyle: \"c-style\",\n importPatterns: [], // handled by extractImports\n extractImports(content: string): string[] {\n const imports: string[] = [];\n\n // Single import: import \"path\" or import alias \"path\"\n const singleRegex = /\\bimport\\s+(?:\\w+\\s+)?\"([^\"]+)\"/gm;\n let match: RegExpExecArray | null;\n while ((match = singleRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n // Import block: import ( ... )\n const blockRegex = /\\bimport\\s*\\(([^)]*)\\)/gms;\n while ((match = blockRegex.exec(content)) !== null) {\n const block = match[1];\n const entryRegex = /(?:\\w+\\s+)?\"([^\"]+)\"/g;\n let entry: RegExpExecArray | null;\n while ((entry = entryRegex.exec(block)) !== null) {\n imports.push(entry[1]);\n }\n }\n\n return imports;\n },\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n // Only resolve project-internal imports\n // Read go.mod module path to strip prefix\n const modPrefix = goModulePrefix(rootDir);\n if (!modPrefix || !importPath.startsWith(modPrefix)) return null;\n\n const relPath = importPath.slice(modPrefix.length + 1); // +1 for /\n // Go packages are directories; find any .go file in the directory\n const pkgDir = join(rootDir, relPath);\n for (const f of projectFiles) {\n if (f.startsWith(pkgDir + \"/\") && f.endsWith(\".go\")) return f;\n }\n return null;\n },\n defaultExclude: [\"vendor\"],\n};\n\n// Bug #11: goModCache is a per-process cache of go.mod module prefixes, keyed by rootDir.\n// It is intentionally never cleared because the module path for a given rootDir does not\n// change during the lifetime of a single process. If a long-running process needs to pick\n// up go.mod changes, restart the process.\nconst goModCache = new Map<string, string | null>();\nfunction goModulePrefix(rootDir: string): string | null {\n if (goModCache.has(rootDir)) return goModCache.get(rootDir)!;\n try {\n const content = readFileSync(join(rootDir, \"go.mod\"), \"utf-8\");\n const match = content.match(/^module\\s+(.+)$/m);\n const prefix = match ? match[1].trim() : null;\n goModCache.set(rootDir, prefix);\n return prefix;\n } catch {\n goModCache.set(rootDir, null);\n return null;\n }\n}\n\n// ─── Java ────────────────────────────────────────────\nconst java: LanguageConfig = {\n id: \"java\",\n extensions: [\".java\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // Bug #5 fix: import com.example.ClassName; and import com.example.*; (wildcard)\n // Bug #6: static imports also captured here\n { regex: /^import\\s+(?:static\\s+)?([\\w.*]+);/gm },\n ],\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n // Bug #5 fix: wildcard imports — can't resolve to a single file, return null\n if (importPath.endsWith(\".*\")) {\n return null;\n }\n\n // Bug #6 fix: static imports — try progressively shorter paths\n // e.g. com.example.Class.method → try com/example/Class/method.java,\n // then com/example/Class.java, then com/example.java, etc.\n const segments = importPath.split(\".\");\n for (let i = segments.length; i > 0; i--) {\n const filePath = segments.slice(0, i).join(\"/\") + \".java\";\n for (const srcRoot of [\"\", \"src/main/java/\", \"src/\", \"app/src/main/java/\"]) {\n const full = join(rootDir, srcRoot, filePath);\n if (projectFiles.has(full)) return full;\n }\n }\n return null;\n },\n defaultExclude: [\"build\", \"target\", \"\\\\.gradle\", \"\\\\.idea\"],\n};\n\n// ─── C/C++ ───────────────────────────────────────────\nconst cCpp: LanguageConfig = {\n id: \"c-cpp\",\n extensions: [\".c\", \".cpp\", \".cc\", \".cxx\", \".h\", \".hpp\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // #include \"file.h\" (skip <system> includes)\n { regex: /^#include\\s+\"([^\"]+)\"/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Resolve relative to source file first\n const fromSource = resolve(dirname(sourceFile), importPath);\n if (projectFiles.has(fromSource)) return fromSource;\n // Then relative to root\n const fromRoot = join(rootDir, importPath);\n if (projectFiles.has(fromRoot)) return fromRoot;\n // Try common include dirs\n for (const incDir of [\"include\", \"src\"]) {\n const full = join(rootDir, incDir, importPath);\n if (projectFiles.has(full)) return full;\n }\n return null;\n },\n defaultExclude: [\"build\", \"cmake-build\", \"\\\\.o$\", \"\\\\.obj$\"],\n};\n\n// ─── Ruby ────────────────────────────────────────────\nconst ruby: LanguageConfig = {\n id: \"ruby\",\n extensions: [\".rb\"],\n commentStyle: \"ruby\",\n importPatterns: [\n // require_relative 'path'\n { regex: /\\brequire_relative\\s+['\"]([^'\"]+)['\"]/gm },\n // require 'path' (for project-internal requires)\n { regex: /\\brequire\\s+['\"]([^'\"]+)['\"]/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n const withExt = importPath.endsWith(\".rb\") ? importPath : importPath + \".rb\";\n // require_relative: relative to source\n const fromSource = resolve(dirname(sourceFile), withExt);\n if (projectFiles.has(fromSource)) return fromSource;\n // require: relative to root or lib/\n const fromRoot = join(rootDir, withExt);\n if (projectFiles.has(fromRoot)) return fromRoot;\n const fromLib = join(rootDir, \"lib\", withExt);\n if (projectFiles.has(fromLib)) return fromLib;\n return null;\n },\n defaultExclude: [\"vendor\", \"\\\\.bundle\"],\n};\n\n// ─── PHP ─────────────────────────────────────────────\nconst php: LanguageConfig = {\n id: \"php\",\n extensions: [\".php\"],\n commentStyle: \"php\",\n importPatterns: [\n // require/include/require_once/include_once 'path'\n { regex: /\\b(?:require|include)(?:_once)?\\s+['\"]([^'\"]+)['\"]/gm },\n // Bug #9 fix: use Namespace\\Class — skip `function` and `const` keywords\n { regex: /^use\\s+(?:function\\s+|const\\s+)?([\\w\\\\]+)/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Direct file path\n if (importPath.includes(\"/\") || importPath.endsWith(\".php\")) {\n const withExt = importPath.endsWith(\".php\") ? importPath : importPath + \".php\";\n const fromSource = resolve(dirname(sourceFile), withExt);\n if (projectFiles.has(fromSource)) return fromSource;\n const fromRoot = join(rootDir, withExt);\n if (projectFiles.has(fromRoot)) return fromRoot;\n return null;\n }\n // PSR-4: Namespace\\Class → Namespace/Class.php\n const filePath = importPath.replace(/\\\\/g, \"/\") + \".php\";\n const fromRoot = join(rootDir, filePath);\n if (projectFiles.has(fromRoot)) return fromRoot;\n const fromSrc = join(rootDir, \"src\", filePath);\n if (projectFiles.has(fromSrc)) return fromSrc;\n return null;\n },\n defaultExclude: [\"vendor\"],\n};\n\n// ─── Swift ───────────────────────────────────────────\nconst swift: LanguageConfig = {\n id: \"swift\",\n extensions: [\".swift\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // Bug #10 fix: import ModuleName and @testable import ModuleName\n { regex: /^(?:@testable\\s+)?import\\s+(?:class\\s+|struct\\s+|enum\\s+|protocol\\s+|func\\s+|var\\s+|let\\s+|typealias\\s+)?(\\w+)/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Cross-module: import Module → find Sources/Module/*.swift\n const spmDir = join(rootDir, \"Sources\", importPath);\n // Return the first .swift file in the target module directory\n for (const f of projectFiles) {\n if (f.startsWith(spmDir + \"/\") && f.endsWith(\".swift\")) return f;\n }\n return null;\n },\n defaultExclude: [\"\\\\.build\", \"DerivedData\"],\n};\n\n// ─── Kotlin ──────────────────────────────────────────\nconst kotlin: LanguageConfig = {\n id: \"kotlin\",\n extensions: [\".kt\", \".kts\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // Bug #7/#8 fix: import com.example.ClassName and import com.example.*\n { regex: /^import\\s+([\\w.*]+)/gm },\n ],\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n // Bug #8 fix: wildcard imports — can't resolve to a single file, return null\n if (importPath.endsWith(\".*\")) {\n return null;\n }\n\n // Bug #7 fix: strip trailing dot if present (from previous regex issues)\n let cleanPath = importPath;\n if (cleanPath.endsWith(\".\")) {\n cleanPath = cleanPath.slice(0, -1);\n }\n\n // Convert com.example.Class to com/example/Class.kt\n const filePath = cleanPath.replace(/\\./g, \"/\");\n for (const ext of [\".kt\", \".kts\"]) {\n for (const srcRoot of [\n \"\",\n \"src/main/kotlin/\",\n \"src/main/java/\",\n \"src/\",\n \"app/src/main/kotlin/\",\n \"app/src/main/java/\",\n ]) {\n const full = join(rootDir, srcRoot, filePath + ext);\n if (projectFiles.has(full)) return full;\n }\n }\n return null;\n },\n defaultExclude: [\"build\", \"\\\\.gradle\", \"\\\\.idea\"],\n};\n\n// ─── C# ──────────────────────────────────────────────\nconst cSharp: LanguageConfig = {\n id: \"c-sharp\",\n extensions: [\".cs\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // using Namespace; and using Namespace.SubNamespace;\n // using static Namespace.Class;\n // Skip: using Alias = Namespace.Class; (captured but resolved same way)\n { regex: /^using\\s+(?:static\\s+)?([\\w.]+)\\s*;/gm },\n ],\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n const segments = importPath.split(\".\");\n\n // 1. Try as direct file path (progressively shorter, like Java static imports)\n for (let i = segments.length; i > 0; i--) {\n const filePath = segments.slice(0, i).join(\"/\") + \".cs\";\n for (const srcRoot of [\"\", \"src/\", \"lib/\"]) {\n const full = join(rootDir, srcRoot, filePath);\n if (projectFiles.has(full)) return full;\n }\n }\n\n // 2. C# using = namespace import; try as directory, find first .cs file\n // Strip leading segments progressively (handles root namespace prefix)\n for (let start = 0; start < segments.length; start++) {\n const dirPath = segments.slice(start).join(\"/\");\n for (const srcRoot of [\"\", \"src/\", \"lib/\"]) {\n const prefix = join(rootDir, srcRoot, dirPath) + \"/\";\n for (const f of projectFiles) {\n if (f.startsWith(prefix) && f.endsWith(\".cs\")) return f;\n }\n }\n }\n\n return null;\n },\n defaultExclude: [\"bin\", \"obj\", \"\\\\.vs\", \"packages\", \"TestResults\"],\n};\n\n// ─── Dart ────────────────────────────────────────────\nconst dart: LanguageConfig = {\n id: \"dart\",\n extensions: [\".dart\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // import 'package:pkg/file.dart'; or import 'relative/path.dart';\n { regex: /^import\\s+['\"]([^'\"]+)['\"]/gm },\n // export 'file.dart'; (re-exports create dependencies too)\n { regex: /^export\\s+['\"]([^'\"]+)['\"]/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Skip dart: stdlib imports\n if (importPath.startsWith(\"dart:\")) return null;\n\n // package: imports — resolve own package to lib/\n if (importPath.startsWith(\"package:\")) {\n const ownPackage = dartPackageName(rootDir);\n if (!ownPackage) return null;\n const prefix = `package:${ownPackage}/`;\n if (!importPath.startsWith(prefix)) return null; // external package\n const relPath = importPath.slice(prefix.length);\n const full = join(rootDir, \"lib\", relPath);\n if (projectFiles.has(full)) return full;\n return null;\n }\n\n // Relative imports\n const resolved = resolve(dirname(sourceFile), importPath);\n if (projectFiles.has(resolved)) return resolved;\n return null;\n },\n defaultExclude: [\"\\\\.dart_tool\", \"build\", \"\\\\.packages\"],\n};\n\nconst dartPackageCache = new Map<string, string | null>();\nfunction dartPackageName(rootDir: string): string | null {\n if (dartPackageCache.has(rootDir)) return dartPackageCache.get(rootDir)!;\n try {\n const content = readFileSync(join(rootDir, \"pubspec.yaml\"), \"utf-8\");\n const match = content.match(/^name:\\s*(\\S+)/m);\n const name = match ? match[1] : null;\n dartPackageCache.set(rootDir, name);\n return name;\n } catch {\n dartPackageCache.set(rootDir, null);\n return null;\n }\n}\n\n// ─── Scala ───────────────────────────────────────────\nconst scala: LanguageConfig = {\n id: \"scala\",\n extensions: [\".scala\", \".sc\"],\n commentStyle: \"c-style\",\n importPatterns: [], // handled by extractImports for grouped syntax\n extractImports(content: string): string[] {\n const imports: string[] = [];\n // import pkg.Class\n // import pkg.{A, B, C}\n // import pkg._ (wildcard)\n const importRegex = /\\bimport\\s+([\\w.]+(?:\\.\\{[^}]+\\}|\\.\\w+|\\._))/gm;\n let match: RegExpExecArray | null;\n while ((match = importRegex.exec(content)) !== null) {\n const full = match[1];\n // Check for grouped imports: import pkg.{A, B}\n const braceMatch = full.match(/^([\\w.]+)\\.\\{([^}]+)\\}$/);\n if (braceMatch) {\n const prefix = braceMatch[1];\n const items = braceMatch[2].split(\",\");\n for (const item of items) {\n const trimmed = item.trim().split(/\\s+/)[0]; // handle \"A => B\" rename\n if (trimmed === \"_\") continue; // wildcard in group\n imports.push(`${prefix}.${trimmed}`);\n }\n } else if (full.endsWith(\"._\")) {\n // Wildcard import — skip\n continue;\n } else {\n imports.push(full);\n }\n }\n return imports;\n },\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n const segments = importPath.split(\".\");\n // Try progressively shorter paths\n for (let i = segments.length; i > 0; i--) {\n const filePath = segments.slice(0, i).join(\"/\");\n for (const ext of [\".scala\", \".sc\"]) {\n for (const srcRoot of [\"\", \"src/main/scala/\", \"src/\", \"app/\"]) {\n const full = join(rootDir, srcRoot, filePath + ext);\n if (projectFiles.has(full)) return full;\n }\n }\n }\n return null;\n },\n defaultExclude: [\"target\", \"\\\\.bsp\", \"\\\\.metals\", \"\\\\.bloop\"],\n};\n\n// ─── JavaScript / TypeScript ──────────────────────────\nconst javascript: LanguageConfig = {\n id: \"javascript\",\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // ES6: import [type] [stuff from] \"path\"\n { regex: /import\\s+(?:type\\s+)?(?:[\\w*{}\\s,]+\\s+from\\s+)?[\"']([^\"']+)[\"']/g },\n // Dynamic: import(\"path\")\n { regex: /\\bimport\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g },\n // Re-export: export [type] { stuff } from \"path\" / export * from \"path\"\n { regex: /export\\s+(?:type\\s+)?(?:\\{[^}]*\\}|\\*(?:\\s+as\\s+\\w+)?)\\s+from\\s+[\"']([^\"']+)[\"']/g },\n // CommonJS: require(\"path\")\n { regex: /\\brequire\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Skip external modules: node:, @scope/pkg, bare specifiers without ./ or ../\n if (importPath.startsWith(\"node:\")) return null;\n if (!importPath.startsWith(\".\")) return null;\n\n // Resolve relative to source file\n const resolved = resolve(dirname(sourceFile), importPath);\n\n // 1. Exact match (e.g., \"./foo.js\" where foo.js actually exists)\n if (projectFiles.has(resolved)) return resolved;\n\n // 2. ESM convention: .js → .ts / .tsx (TypeScript emits .js in import paths)\n if (resolved.endsWith(\".js\")) {\n const tsPath = resolved.slice(0, -3) + \".ts\";\n if (projectFiles.has(tsPath)) return tsPath;\n const tsxPath = resolved.slice(0, -3) + \".tsx\";\n if (projectFiles.has(tsxPath)) return tsxPath;\n }\n if (resolved.endsWith(\".jsx\")) {\n const tsxPath = resolved.slice(0, -4) + \".tsx\";\n if (projectFiles.has(tsxPath)) return tsxPath;\n }\n\n // 3. Try adding extensions\n for (const ext of [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"]) {\n if (projectFiles.has(resolved + ext)) return resolved + ext;\n }\n\n // 4. Try as directory with index file\n for (const idx of [\"/index.ts\", \"/index.tsx\", \"/index.js\", \"/index.jsx\"]) {\n if (projectFiles.has(resolved + idx)) return resolved + idx;\n }\n\n return null;\n },\n defaultExclude: [\"node_modules\", \"\\\\.d\\\\.ts$\", \"dist\", \"build\", \"coverage\"],\n};\n\n// ─── Registry ────────────────────────────────────────\nconst LANGUAGE_CONFIGS: Record<LanguageId, LanguageConfig | null> = {\n javascript,\n python,\n rust,\n go,\n java,\n \"c-cpp\": cCpp,\n \"c-sharp\": cSharp,\n ruby,\n php,\n swift,\n kotlin,\n dart,\n scala,\n};\n\nexport function getLanguageConfig(id: LanguageId): LanguageConfig | null {\n return LANGUAGE_CONFIGS[id] ?? null;\n}\n\nexport function getAllLanguageIds(): LanguageId[] {\n return [...LANGUAGE_IDS];\n}\n","import type { DependencyGraph } from \"../../types/schema.js\";\n\n/** Single source of truth for supported language IDs */\nexport const LANGUAGE_IDS = [\n \"javascript\",\n \"python\",\n \"rust\",\n \"go\",\n \"java\",\n \"c-cpp\",\n \"c-sharp\",\n \"ruby\",\n \"php\",\n \"swift\",\n \"kotlin\",\n \"dart\",\n \"scala\",\n] as const;\n\nexport type LanguageId = (typeof LANGUAGE_IDS)[number];\n\nexport interface AnalyzerEngine {\n analyze(\n rootDir: string,\n options: { exclude?: string[]; maxDepth?: number },\n ): Promise<DependencyGraph>;\n}\n\nexport interface ImportPattern {\n regex: RegExp;\n}\n\nexport type ImportResolver = (\n importPath: string,\n sourceFile: string,\n rootDir: string,\n projectFiles: Set<string>,\n) => string | null;\n\nexport type CommentStyle =\n | \"c-style\" // // and /* */\n | \"hash\" // #\n | \"python\" // # and \"\"\" / '''\n | \"ruby\" // # and =begin/=end\n | \"php\"; // //, /* */, and #\n\nexport interface LanguageConfig {\n id: LanguageId;\n extensions: string[];\n importPatterns: ImportPattern[];\n resolveImport: ImportResolver;\n commentStyle: CommentStyle;\n defaultExclude?: string[];\n /** Custom import extractor for languages with complex syntax (e.g. Rust grouped use) */\n extractImports?: (content: string) => string[];\n}\n","export type Locale = \"en\" | \"ja\";\n\nlet currentLocale: Locale = detectLocale();\n\n/** Get the current locale */\nexport function getLocale(): Locale {\n return currentLocale;\n}\n\n/** Set the locale explicitly */\nexport function setLocale(locale: Locale): void {\n currentLocale = locale;\n}\n\n/** Auto-detect locale from LANG/LC_ALL environment variable */\nfunction detectLocale(): Locale {\n const env = process.env.LC_ALL || process.env.LANG || \"\";\n if (env.startsWith(\"ja\")) return \"ja\";\n return \"en\";\n}\n\n/** Get a translated message by key */\nexport function t(key: string, vars?: Record<string, string | number>): string {\n const messages = currentLocale === \"ja\" ? ja : en;\n let msg = (messages as Record<string, string>)[key] ?? (en as Record<string, string>)[key] ?? key;\n\n if (vars) {\n for (const [k, v] of Object.entries(vars)) {\n msg = msg.replaceAll(`{${k}}`, String(v));\n }\n }\n return msg;\n}\n\n// ─── Message catalogs ───────────────────────────────────────────\n\nconst en = {\n // Analyzer\n \"analyzer.failed\": \"dependency-cruiser failed: {message}\",\n \"analyzer.exitCode\": \"Analysis finished with error code {code}\",\n\n // Storage\n \"storage.parseFailed\": \"Failed to parse snapshot.json. File may be corrupted: {path}\",\n \"storage.readFailed\": \"Failed to read snapshot.json: {path}\",\n \"storage.invalidSchema\": \"snapshot.json schema is invalid. Please regenerate with `archtracker init`:\\n{issues}\",\n \"storage.versionMismatch\": \"snapshot.json version ({version}) is incompatible with current schema ({expected}). Regenerate with `archtracker init`.\",\n\n // Path guard\n \"pathGuard.traversal\": \"Path points outside project root: \\\"{input}\\\" → \\\"{resolved}\\\" (allowed: \\\"{boundary}\\\")\",\n\n // Diff report\n \"diff.title\": \"# Architecture Change Report\\n\",\n \"diff.noChanges\": \"No changes — snapshot matches current code.\\n\",\n \"diff.added\": \"## Added Files ({count})\",\n \"diff.removed\": \"## Removed Files ({count})\",\n \"diff.modified\": \"## Modified Dependencies ({count})\",\n \"diff.affected\": \"## Files Requiring Review ({count})\",\n \"diff.reasonRemoved\": \"Dependency \\\"{file}\\\" was removed\",\n \"diff.reasonModified\": \"Dependency \\\"{file}\\\" had its dependencies changed\",\n \"diff.reasonAdded\": \"New dependency \\\"{file}\\\" was added\",\n\n // Search\n \"search.pathMatch\": \"Path matches \\\"{pattern}\\\"\",\n \"search.affected\": \"May be affected by changes to \\\"{file}\\\" (via: {via})\",\n \"search.critical\": \"{count} files depend on this component\",\n \"search.orphan\": \"Orphan file (no dependencies, no dependents)\",\n \"search.noResults\": \"No results: \\\"{query}\\\" (mode: {mode})\",\n \"search.results\": \"Results: {count} (mode: {mode})\",\n\n // CLI\n \"cli.analyzing\": \"Analyzing...\",\n \"cli.snapshotSaved\": \"Snapshot saved\",\n \"cli.timestamp\": \" Timestamp: {ts}\",\n \"cli.fileCount\": \" Files: {count}\",\n \"cli.edgeCount\": \" Edges: {count}\",\n \"cli.circularCount\": \" Circular deps: {count}\",\n \"cli.keyComponents\": \"\\nKey components:\",\n \"cli.dependedBy\": \"{path} ({count} dependents)\",\n \"cli.noSnapshot\": \"No snapshot found. Run `archtracker init` first.\",\n \"cli.ciFailed\": \"\\nCI check failed: {count} file(s) require review\",\n \"cli.autoGenerating\": \"No snapshot found, auto-generating...\",\n \"cli.project\": \"Project: {path}\",\n \"cli.validPaths\": \"\\nValid file paths:\",\n \"cli.snapshot\": \"Snapshot: {ts}\",\n\n // MCP\n \"mcp.analyzeComplete\": \"Analysis complete: {files} files, {edges} edges\",\n \"mcp.circularFound\": \"Circular deps: {count} found\",\n \"mcp.circularNone\": \"Circular deps: none\",\n \"mcp.snapshotSaved\": \"Snapshot saved\",\n \"mcp.autoInit\": \"No snapshot existed. Initial snapshot auto-generated.\",\n \"mcp.nextCheckEnabled\": \"Diff checking will be active from the next run.\",\n \"mcp.queryRequired\": \"\\\"{mode}\\\" mode requires the query parameter\",\n\n // Analyze report\n \"analyze.title\": \"# Architecture Analysis Report\\n\",\n \"analyze.overview\": \"## Overview\",\n \"analyze.totalFiles\": \" Total files: {count}\",\n \"analyze.totalEdges\": \" Total edges: {count}\",\n \"analyze.totalCircular\": \" Circular dependencies: {count}\",\n \"analyze.criticalTitle\": \"\\n## Critical Components (Top {count})\",\n \"analyze.criticalItem\": \" {path} ({count} dependents)\",\n \"analyze.circularTitle\": \"\\n## Circular Dependencies ({count})\",\n \"analyze.circularItem\": \" {files}\",\n \"analyze.orphanTitle\": \"\\n## Orphan Files ({count})\",\n \"analyze.couplingTitle\": \"\\n## High Coupling (Top {count} by import count)\",\n \"analyze.couplingItem\": \" {path} ({count} imports)\",\n \"analyze.layerTitle\": \"\\n## Directory Breakdown\",\n \"analyze.layerItem\": \" {dir}/ — {count} files\",\n \"analyze.noIssues\": \"\\nNo architectural issues detected.\",\n \"analyze.snapshotSaved\": \"\\nSnapshot saved alongside analysis.\",\n\n // CI\n \"ci.generated\": \"GitHub Actions workflow generated: {path}\",\n\n // Web viewer\n \"web.starting\": \"Starting architecture viewer...\",\n \"web.listening\": \"Architecture graph available at: http://localhost:{port}\",\n \"web.stop\": \"Press Ctrl+C to stop\",\n \"web.watching\": \"Watching {dir}/ for changes...\",\n \"web.reloading\": \"File change detected, reloading...\",\n \"web.reloaded\": \"Graph reloaded\",\n\n // Errors\n \"error.analyzer\": \"[Analysis Error] {message}\",\n \"error.storage\": \"[Storage Error] {message}\",\n \"error.pathTraversal\": \"[Security Error] {message}\",\n \"error.generic\": \"[Error] {message}\",\n \"error.unexpected\": \"[Error] Unexpected error: {message}\",\n \"error.cli.analyzer\": \"Analysis error: {message}\",\n \"error.cli.storage\": \"Storage error: {message}\",\n \"error.cli.generic\": \"Error: {message}\",\n \"error.cli.unexpected\": \"Unexpected error: {message}\",\n} as const;\n\nconst ja = {\n // Analyzer\n \"analyzer.failed\": \"dependency-cruiser の実行に失敗しました: {message}\",\n \"analyzer.exitCode\": \"解析がエラーコード {code} で終了しました\",\n\n // Storage\n \"storage.parseFailed\": \"snapshot.json のパースに失敗しました。ファイルが破損している可能性があります: {path}\",\n \"storage.readFailed\": \"snapshot.json の読み取りに失敗しました: {path}\",\n \"storage.invalidSchema\": \"snapshot.json のスキーマが不正です。archtracker init で再生成してください:\\n{issues}\",\n \"storage.versionMismatch\": \"snapshot.json のバージョン ({version}) が現在のスキーマ ({expected}) と互換性がありません。archtracker init で再生成してください。\",\n\n // Path guard\n \"pathGuard.traversal\": \"パスがプロジェクトルートの外部を指しています: \\\"{input}\\\" → \\\"{resolved}\\\" (許可範囲: \\\"{boundary}\\\")\",\n\n // Diff report\n \"diff.title\": \"# アーキテクチャ変更レポート\\n\",\n \"diff.noChanges\": \"変更なし — スナップショットと現在のコードは一致しています。\\n\",\n \"diff.added\": \"## 追加されたファイル ({count}件)\",\n \"diff.removed\": \"## 削除されたファイル ({count}件)\",\n \"diff.modified\": \"## 依存関係が変更されたファイル ({count}件)\",\n \"diff.affected\": \"## 確認が必要なファイル ({count}件)\",\n \"diff.reasonRemoved\": \"依存先 \\\"{file}\\\" が削除されました\",\n \"diff.reasonModified\": \"依存先 \\\"{file}\\\" の依存関係が変更されました\",\n \"diff.reasonAdded\": \"新しい依存先 \\\"{file}\\\" が追加されました\",\n\n // Search\n \"search.pathMatch\": \"パスが \\\"{pattern}\\\" にマッチ\",\n \"search.affected\": \"\\\"{file}\\\" の変更により影響を受ける可能性(経由: {via})\",\n \"search.critical\": \"{count}件のファイルが依存する重要コンポーネント\",\n \"search.orphan\": \"孤立ファイル(依存なし・被依存なし)\",\n \"search.noResults\": \"検索結果なし: \\\"{query}\\\" (モード: {mode})\",\n \"search.results\": \"検索結果: {count}件 (モード: {mode})\",\n\n // CLI\n \"cli.analyzing\": \"解析中...\",\n \"cli.snapshotSaved\": \"スナップショットを保存しました\",\n \"cli.timestamp\": \" タイムスタンプ: {ts}\",\n \"cli.fileCount\": \" ファイル数: {count}\",\n \"cli.edgeCount\": \" エッジ数: {count}\",\n \"cli.circularCount\": \" 循環参照: {count}件\",\n \"cli.keyComponents\": \"\\n主要コンポーネント:\",\n \"cli.dependedBy\": \"{path} ({count}件が依存)\",\n \"cli.noSnapshot\": \"スナップショットが見つかりません。`archtracker init` を先に実行してください。\",\n \"cli.ciFailed\": \"\\nCI チェック失敗: {count}件の要確認ファイルがあります\",\n \"cli.autoGenerating\": \"スナップショットが無いため自動生成します...\",\n \"cli.project\": \"プロジェクト: {path}\",\n \"cli.validPaths\": \"\\n有効なファイルパス:\",\n \"cli.snapshot\": \"スナップショット: {ts}\",\n\n // MCP\n \"mcp.analyzeComplete\": \"解析完了: {files}ファイル, {edges}エッジ\",\n \"mcp.circularFound\": \"循環参照: {count}件検出\",\n \"mcp.circularNone\": \"循環参照: なし\",\n \"mcp.snapshotSaved\": \"スナップショットを保存しました\",\n \"mcp.autoInit\": \"スナップショットが存在しなかったため、初期スナップショットを自動生成しました。\",\n \"mcp.nextCheckEnabled\": \"次回の実行時から差分チェックが有効になります。\",\n \"mcp.queryRequired\": \"\\\"{mode}\\\" モードでは query パラメータが必須です\",\n\n // Analyze report\n \"analyze.title\": \"# アーキテクチャ分析レポート\\n\",\n \"analyze.overview\": \"## 概要\",\n \"analyze.totalFiles\": \" 総ファイル数: {count}\",\n \"analyze.totalEdges\": \" 総エッジ数: {count}\",\n \"analyze.totalCircular\": \" 循環参照: {count}件\",\n \"analyze.criticalTitle\": \"\\n## 重要コンポーネント (上位{count}件)\",\n \"analyze.criticalItem\": \" {path} ({count}件が依存)\",\n \"analyze.circularTitle\": \"\\n## 循環参照 ({count}件)\",\n \"analyze.circularItem\": \" {files}\",\n \"analyze.orphanTitle\": \"\\n## 孤立ファイル ({count}件)\",\n \"analyze.couplingTitle\": \"\\n## 高結合ファイル (import数 上位{count}件)\",\n \"analyze.couplingItem\": \" {path} ({count}件をimport)\",\n \"analyze.layerTitle\": \"\\n## ディレクトリ構成\",\n \"analyze.layerItem\": \" {dir}/ — {count}ファイル\",\n \"analyze.noIssues\": \"\\nアーキテクチャ上の問題は検出されませんでした。\",\n \"analyze.snapshotSaved\": \"\\n分析と同時にスナップショットを保存しました。\",\n\n // CI\n \"ci.generated\": \"GitHub Actions ワークフローを生成しました: {path}\",\n\n // Web viewer\n \"web.starting\": \"アーキテクチャビューアーを起動中...\",\n \"web.listening\": \"アーキテクチャグラフ: http://localhost:{port}\",\n \"web.stop\": \"Ctrl+C で停止\",\n \"web.watching\": \"{dir}/ を監視中...\",\n \"web.reloading\": \"ファイル変更を検出、リロード中...\",\n \"web.reloaded\": \"グラフを更新しました\",\n\n // Errors\n \"error.analyzer\": \"[解析エラー] {message}\",\n \"error.storage\": \"[ストレージエラー] {message}\",\n \"error.pathTraversal\": \"[セキュリティエラー] {message}\",\n \"error.generic\": \"[エラー] {message}\",\n \"error.unexpected\": \"[エラー] 予期しないエラーが発生しました: {message}\",\n \"error.cli.analyzer\": \"解析エラー: {message}\",\n \"error.cli.storage\": \"ストレージエラー: {message}\",\n \"error.cli.generic\": \"エラー: {message}\",\n \"error.cli.unexpected\": \"予期しないエラー: {message}\",\n} as const;\n","import type { DependencyGraph, FileNode } from \"../types/schema.js\";\nimport { t } from \"../i18n/index.js\";\n\n/** Search result for architecture queries */\nexport interface SearchResult {\n file: string;\n dependents: string[];\n dependencies: string[];\n dependentCount: number;\n dependencyCount: number;\n matchReason: string;\n}\n\n/**\n * Search the dependency graph by file path pattern.\n * Pattern is treated as a literal substring (escaped to prevent ReDoS).\n */\nexport function searchByPath(\n graph: DependencyGraph,\n pattern: string,\n): SearchResult[] {\n const escaped = pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regex = new RegExp(escaped, \"i\");\n return Object.values(graph.files)\n .filter((f) => regex.test(f.path))\n .map((f) => toSearchResult(f, t(\"search.pathMatch\", { pattern })));\n}\n\n/**\n * Find all files that would be affected if a given file changes.\n * Traverses the dependent chain recursively (reverse dependency tree).\n */\nexport function findAffectedFiles(\n graph: DependencyGraph,\n filePath: string,\n maxDepth: number = 10,\n): SearchResult[] {\n const node = findNode(graph, filePath);\n if (!node) return [];\n\n const visited = new Set<string>();\n const results: SearchResult[] = [];\n\n function traverse(current: FileNode, depth: number, via: string) {\n if (depth > maxDepth || visited.has(current.path)) return;\n visited.add(current.path);\n\n if (current.path !== node!.path) {\n results.push(\n toSearchResult(\n current,\n t(\"search.affected\", { file: filePath, via }),\n ),\n );\n }\n\n for (const depPath of current.dependents) {\n const depNode = graph.files[depPath];\n if (depNode) {\n traverse(depNode, depth + 1, current.path);\n }\n }\n }\n\n traverse(node, 0, filePath);\n return results;\n}\n\n/**\n * Find the most critical files in the project.\n * Ranked by dependent count (files that many other files depend on).\n */\nexport function findCriticalFiles(\n graph: DependencyGraph,\n limit: number = 10,\n): SearchResult[] {\n return Object.values(graph.files)\n .filter((f) => f.dependents.length > 0)\n .sort((a, b) => b.dependents.length - a.dependents.length)\n .slice(0, limit)\n .map((f) =>\n toSearchResult(f, t(\"search.critical\", { count: f.dependents.length })),\n );\n}\n\n/**\n * Find orphan files (no dependencies and no dependents).\n */\nexport function findOrphanFiles(graph: DependencyGraph): SearchResult[] {\n return Object.values(graph.files)\n .filter((f) => f.dependents.length === 0 && f.dependencies.length === 0)\n .map((f) => toSearchResult(f, t(\"search.orphan\")));\n}\n\n/** Find a node by exact or partial path match */\nfunction findNode(\n graph: DependencyGraph,\n filePath: string,\n): FileNode | undefined {\n // Exact match\n if (graph.files[filePath]) return graph.files[filePath];\n\n // Partial match (find first file ending with the pattern)\n const key = Object.keys(graph.files).find(\n (k) => k.endsWith(filePath) || k.includes(filePath),\n );\n return key ? graph.files[key] : undefined;\n}\n\nfunction toSearchResult(node: FileNode, matchReason: string): SearchResult {\n return {\n file: node.path,\n dependents: node.dependents,\n dependencies: node.dependencies,\n dependentCount: node.dependents.length,\n dependencyCount: node.dependencies.length,\n matchReason,\n };\n}\n","import type { DependencyGraph } from \"../types/schema.js\";\nimport { t } from \"../i18n/index.js\";\n\n/**\n * Generate a comprehensive architecture analysis report.\n *\n * Designed for onboarding into existing projects — provides\n * a full overview of dependencies, critical components, circular\n * references, orphan files, coupling hotspots, and directory breakdown.\n */\nexport function formatAnalysisReport(\n graph: DependencyGraph,\n options: { topN?: number } = {},\n): string {\n const topN = options.topN ?? 10;\n const lines: string[] = [];\n const files = Object.values(graph.files);\n\n // ─── Overview ────────────────────────────────────────────\n lines.push(t(\"analyze.title\"));\n lines.push(t(\"analyze.overview\"));\n lines.push(t(\"analyze.totalFiles\", { count: graph.totalFiles }));\n lines.push(t(\"analyze.totalEdges\", { count: graph.totalEdges }));\n lines.push(t(\"analyze.totalCircular\", { count: graph.circularDependencies.length }));\n\n // ─── Critical Components ─────────────────────────────────\n const critical = files\n .filter((f) => f.dependents.length > 0)\n .sort((a, b) => b.dependents.length - a.dependents.length)\n .slice(0, topN);\n\n if (critical.length > 0) {\n lines.push(t(\"analyze.criticalTitle\", { count: critical.length }));\n for (const f of critical) {\n lines.push(t(\"analyze.criticalItem\", { path: f.path, count: f.dependents.length }));\n }\n }\n\n // ─── Circular Dependencies ──────────────────────────────\n if (graph.circularDependencies.length > 0) {\n lines.push(t(\"analyze.circularTitle\", { count: graph.circularDependencies.length }));\n for (const c of graph.circularDependencies) {\n lines.push(t(\"analyze.circularItem\", { files: c.cycle.join(\" → \") }));\n }\n }\n\n // ─── High Coupling (most imports) ───────────────────────\n const highCoupling = files\n .filter((f) => f.dependencies.length > 0)\n .sort((a, b) => b.dependencies.length - a.dependencies.length)\n .slice(0, topN);\n\n if (highCoupling.length > 0) {\n lines.push(t(\"analyze.couplingTitle\", { count: highCoupling.length }));\n for (const f of highCoupling) {\n lines.push(t(\"analyze.couplingItem\", { path: f.path, count: f.dependencies.length }));\n }\n }\n\n // ─── Orphan Files ───────────────────────────────────────\n const orphans = files.filter(\n (f) => f.dependents.length === 0 && f.dependencies.length === 0,\n );\n\n if (orphans.length > 0) {\n lines.push(t(\"analyze.orphanTitle\", { count: orphans.length }));\n for (const f of orphans) {\n lines.push(` ${f.path}`);\n }\n }\n\n // ─── Directory Breakdown ────────────────────────────────\n const dirCounts = new Map<string, number>();\n for (const f of files) {\n const dir = f.path.includes(\"/\") ? f.path.substring(0, f.path.lastIndexOf(\"/\")) : \".\";\n dirCounts.set(dir, (dirCounts.get(dir) ?? 0) + 1);\n }\n\n if (dirCounts.size > 1) {\n lines.push(t(\"analyze.layerTitle\"));\n const sorted = [...dirCounts.entries()].sort((a, b) => b[1] - a[1]);\n for (const [dir, count] of sorted) {\n lines.push(t(\"analyze.layerItem\", { dir, count }));\n }\n }\n\n // ─── Summary ────────────────────────────────────────────\n if (graph.circularDependencies.length === 0 && orphans.length === 0) {\n lines.push(t(\"analyze.noIssues\"));\n }\n\n return lines.join(\"\\n\");\n}\n","import { mkdir, writeFile, readFile, access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport type { ArchSnapshot } from \"../types/schema.js\";\nimport { SCHEMA_VERSION } from \"../types/schema.js\";\nimport type { DependencyGraph } from \"../types/schema.js\";\nimport { t } from \"../i18n/index.js\";\n\nconst ARCHTRACKER_DIR = \".archtracker\";\nconst SNAPSHOT_FILE = \"snapshot.json\";\n\n/** Zod schema for runtime validation of loaded snapshots */\nconst FileNodeSchema = z.object({\n path: z.string(),\n exists: z.boolean(),\n dependencies: z.array(z.string()),\n dependents: z.array(z.string()),\n});\n\nconst DependencyGraphSchema = z.object({\n rootDir: z.string(),\n files: z.record(z.string(), FileNodeSchema),\n edges: z.array(z.object({\n source: z.string(),\n target: z.string(),\n type: z.enum([\"static\", \"dynamic\", \"type-only\"]),\n })),\n circularDependencies: z.array(z.object({ cycle: z.array(z.string()) })),\n totalFiles: z.number(),\n totalEdges: z.number(),\n});\n\nconst SnapshotSchema = z.object({\n version: z.literal(SCHEMA_VERSION),\n timestamp: z.string(),\n rootDir: z.string(),\n graph: DependencyGraphSchema,\n});\n\n/**\n * Save a dependency graph as a versioned snapshot.\n *\n * Creates .archtracker/ directory if it doesn't exist.\n * Writes snapshot.json with schema version and timestamp.\n */\nexport async function saveSnapshot(\n projectRoot: string,\n graph: DependencyGraph,\n): Promise<ArchSnapshot> {\n const dirPath = join(projectRoot, ARCHTRACKER_DIR);\n const filePath = join(dirPath, SNAPSHOT_FILE);\n\n const snapshot: ArchSnapshot = {\n version: SCHEMA_VERSION,\n timestamp: new Date().toISOString(),\n rootDir: graph.rootDir,\n graph,\n };\n\n await mkdir(dirPath, { recursive: true });\n await writeFile(filePath, JSON.stringify(snapshot, null, 2), \"utf-8\");\n\n return snapshot;\n}\n\n/**\n * Load the most recent snapshot from .archtracker/snapshot.json.\n *\n * Returns null if no snapshot exists.\n * Validates schema structure with Zod for data integrity.\n */\nexport async function loadSnapshot(\n projectRoot: string,\n): Promise<ArchSnapshot | null> {\n const filePath = join(projectRoot, ARCHTRACKER_DIR, SNAPSHOT_FILE);\n\n // Read file directly — no TOCTOU race with access() check\n let raw: string;\n try {\n raw = await readFile(filePath, \"utf-8\");\n } catch (error: unknown) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n return null;\n }\n throw new StorageError(\n t(\"storage.readFailed\", { path: filePath }),\n { cause: error },\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new StorageError(\n t(\"storage.parseFailed\", { path: filePath }),\n );\n }\n\n // Validate structure with Zod\n const result = SnapshotSchema.safeParse(parsed);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` ${i.path.join(\".\")}: ${i.message}`)\n .slice(0, 5)\n .join(\"\\n\");\n throw new StorageError(\n t(\"storage.invalidSchema\", { issues }),\n );\n }\n\n return result.data as ArchSnapshot;\n}\n\n/** Check if .archtracker directory exists */\nexport async function hasArchtrackerDir(\n projectRoot: string,\n): Promise<boolean> {\n try {\n await access(join(projectRoot, ARCHTRACKER_DIR));\n return true;\n } catch {\n return false;\n }\n}\n\n/** Custom error class for storage failures */\nexport class StorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"StorageError\";\n }\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n","/**\n * ArchTracker core schema definitions.\n * Snapshot format is versioned for backward compatibility.\n */\n\nexport const SCHEMA_VERSION = \"1.0\" as const;\n\n/** A single dependency edge: source imports target */\nexport interface DependencyEdge {\n source: string;\n target: string;\n type: \"static\" | \"dynamic\" | \"type-only\";\n}\n\n/** A file node in the architecture graph */\nexport interface FileNode {\n path: string;\n exists: boolean;\n dependencies: string[];\n dependents: string[];\n}\n\n/** A detected circular dependency */\nexport interface CircularDependency {\n cycle: string[];\n}\n\n/** The full dependency graph */\nexport interface DependencyGraph {\n rootDir: string;\n files: Record<string, FileNode>;\n edges: DependencyEdge[];\n circularDependencies: CircularDependency[];\n totalFiles: number;\n totalEdges: number;\n}\n\n/** Persisted snapshot with schema version */\nexport interface ArchSnapshot {\n version: typeof SCHEMA_VERSION;\n timestamp: string;\n rootDir: string;\n graph: DependencyGraph;\n}\n\n/** Diff result between two snapshots */\nexport interface ArchDiff {\n added: string[];\n removed: string[];\n modified: string[];\n affectedDependents: Array<{\n file: string;\n reason: string;\n dependsOn: string;\n }>;\n}\n\n/** Context summary for AI session initialization */\nexport interface ArchContext {\n validPaths: string[];\n summary: string;\n snapshotExists: boolean;\n snapshotTimestamp?: string;\n keyComponents: Array<{\n path: string;\n dependentCount: number;\n dependencyCount: number;\n }>;\n}\n","import type { ArchDiff, DependencyGraph } from \"../types/schema.js\";\nimport { t } from \"../i18n/index.js\";\n\n/**\n * Compute the diff between an old and new dependency graph.\n *\n * Identifies:\n * - Added files (new in the codebase)\n * - Removed files (deleted from the codebase)\n * - Modified files (dependencies changed)\n * - Affected dependents (files that depend on changed/removed files and may need updates)\n */\nexport function computeDiff(\n oldGraph: DependencyGraph,\n newGraph: DependencyGraph,\n): ArchDiff {\n const oldFiles = new Set(Object.keys(oldGraph.files));\n const newFiles = new Set(Object.keys(newGraph.files));\n\n // Files that exist in new but not in old\n const added = [...newFiles].filter((f) => !oldFiles.has(f));\n\n // Files that existed in old but not in new\n const removed = [...oldFiles].filter((f) => !newFiles.has(f));\n\n // Files that exist in both but have different dependency sets\n const modified: string[] = [];\n for (const file of newFiles) {\n if (!oldFiles.has(file)) continue;\n\n const oldDeps = oldGraph.files[file].dependencies.slice().sort();\n const newDeps = newGraph.files[file].dependencies.slice().sort();\n\n if (!arraysEqual(oldDeps, newDeps)) {\n modified.push(file);\n }\n }\n\n // Find all files that depend on changed/removed files\n const removedSet = new Set(removed);\n const changedFiles = new Set([...removed, ...modified]);\n const affectedDependents: ArchDiff[\"affectedDependents\"] = [];\n const seenAffected = new Set<string>();\n\n for (const changedFile of changedFiles) {\n // Look up dependents in the NEW graph (for modified files)\n // and in the OLD graph (for removed files)\n const graph = removedSet.has(changedFile) ? oldGraph : newGraph;\n const node = graph.files[changedFile];\n if (!node) continue;\n\n for (const dependent of node.dependents) {\n const key = `${dependent}→${changedFile}`;\n if (seenAffected.has(key)) continue;\n seenAffected.add(key);\n\n const reason = removedSet.has(changedFile)\n ? t(\"diff.reasonRemoved\", { file: changedFile })\n : t(\"diff.reasonModified\", { file: changedFile });\n\n affectedDependents.push({\n file: dependent,\n reason,\n dependsOn: changedFile,\n });\n }\n }\n\n // Also check for files that depend on added files\n // (new dependencies that might need verification)\n for (const addedFile of added) {\n const node = newGraph.files[addedFile];\n if (!node) continue;\n\n for (const dependent of node.dependents) {\n const key = `${dependent}→${addedFile}`;\n if (seenAffected.has(key)) continue;\n seenAffected.add(key);\n\n affectedDependents.push({\n file: dependent,\n reason: t(\"diff.reasonAdded\", { file: addedFile }),\n dependsOn: addedFile,\n });\n }\n }\n\n return { added, removed, modified, affectedDependents };\n}\n\n/** Generate a human-readable report from an ArchDiff */\nexport function formatDiffReport(diff: ArchDiff): string {\n const lines: string[] = [];\n\n lines.push(t(\"diff.title\"));\n\n if (diff.added.length === 0 && diff.removed.length === 0 && diff.modified.length === 0) {\n lines.push(t(\"diff.noChanges\"));\n return lines.join(\"\\n\");\n }\n\n if (diff.added.length > 0) {\n lines.push(t(\"diff.added\", { count: diff.added.length }));\n for (const f of diff.added) {\n lines.push(` + ${f}`);\n }\n lines.push(\"\");\n }\n\n if (diff.removed.length > 0) {\n lines.push(t(\"diff.removed\", { count: diff.removed.length }));\n for (const f of diff.removed) {\n lines.push(` - ${f}`);\n }\n lines.push(\"\");\n }\n\n if (diff.modified.length > 0) {\n lines.push(t(\"diff.modified\", { count: diff.modified.length }));\n for (const f of diff.modified) {\n lines.push(` ~ ${f}`);\n }\n lines.push(\"\");\n }\n\n if (diff.affectedDependents.length > 0) {\n lines.push(t(\"diff.affected\", { count: diff.affectedDependents.length }));\n for (const a of diff.affectedDependents) {\n lines.push(` ! ${a.file}`);\n lines.push(` ${a.reason}`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n","import { resolve } from \"node:path\";\nimport { t } from \"../i18n/index.js\";\n\n/**\n * Validate that a path resolves within the allowed boundary (CWD by default).\n * Prevents path traversal attacks via ../../../etc/passwd style inputs.\n */\nexport function validatePath(\n inputPath: string,\n boundary?: string,\n): string {\n const resolved = resolve(inputPath);\n const root = boundary ? resolve(boundary) : process.cwd();\n\n if (!resolved.startsWith(root)) {\n throw new PathTraversalError(\n t(\"pathGuard.traversal\", { input: inputPath, resolved, boundary: root }),\n );\n }\n return resolved;\n}\n\nexport class PathTraversalError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PathTraversalError\";\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/** Read version from package.json at build/runtime — single source of truth */\nfunction loadVersion(): string {\n // Walk up from this file to find package.json\n let dir = dirname(fileURLToPath(import.meta.url));\n for (let i = 0; i < 5; i++) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, \"package.json\"), \"utf-8\"));\n return pkg.version;\n } catch {\n dir = dirname(dir);\n }\n }\n return \"0.0.0\";\n}\n\nexport const VERSION = loadVersion();\n"],"mappings":"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","names":["z","resolve","stat","readdir","stat","join","join","resolve","join","segments","resolve","fromRoot","resolve","stat","readFile","join","join","readFile","resolve","resolve","readFileSync","join","dirname","z","graph"]}
1
+ {"version":3,"sources":["../../src/mcp/index.ts","../../src/analyzer/analyze.ts","../../src/analyzer/engines/regex-engine.ts","../../src/analyzer/engines/cycle.ts","../../src/analyzer/engines/strip-comments.ts","../../src/analyzer/engines/detect.ts","../../src/analyzer/engines/languages.ts","../../src/analyzer/engines/types.ts","../../src/i18n/index.ts","../../src/analyzer/search.ts","../../src/analyzer/report.ts","../../src/storage/snapshot.ts","../../src/types/schema.ts","../../src/storage/diff.ts","../../src/utils/path-guard.ts","../../src/utils/version.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport {\n analyzeProject,\n AnalyzerError,\n searchByPath,\n findAffectedFiles,\n findCriticalFiles,\n findOrphanFiles,\n formatAnalysisReport,\n} from \"../analyzer/index.js\";\nimport {\n saveSnapshot,\n loadSnapshot,\n computeDiff,\n formatDiffReport,\n StorageError,\n} from \"../storage/index.js\";\nimport type { ArchContext } from \"../types/schema.js\";\nimport { validatePath, PathTraversalError } from \"../utils/path-guard.js\";\nimport { t } from \"../i18n/index.js\";\nimport { VERSION } from \"../utils/version.js\";\nimport { LANGUAGE_IDS } from \"../analyzer/engines/types.js\";\n\nconst server = new McpServer({\n name: \"archtracker\",\n version: VERSION,\n});\n\n/** Zod enum for language parameter — derived from LANGUAGE_IDS */\nconst languageEnum = z.enum(LANGUAGE_IDS);\n\n/** Human-readable language list for tool descriptions */\nconst LANG_DISPLAY: Record<string, string> = {\n javascript: \"JS/TS\", \"c-cpp\": \"C/C++\", \"c-sharp\": \"C#\",\n};\nconst languageList = LANGUAGE_IDS\n .map((id) => LANG_DISPLAY[id] ?? id.charAt(0).toUpperCase() + id.slice(1))\n .join(\", \");\n\n// ─── Tool 1: generate_map ───────────────────────────────────────\n\nserver.tool(\n \"generate_map\",\n `Analyze dependency graph of a directory and return file import/export structure as JSON. Supports ${languageList}.`,\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path (default: src)\"),\n exclude: z\n .array(z.string())\n .optional()\n .describe(\"Array of regex patterns to exclude (e.g. ['test', 'mock'])\"),\n maxDepth: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe(\"Max analysis depth (0 = unlimited)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, exclude, maxDepth, language }) => {\n try {\n validatePath(targetDir);\n const graph = await analyzeProject(targetDir, { exclude, maxDepth, language });\n\n const summary = [\n t(\"mcp.analyzeComplete\", { files: graph.totalFiles, edges: graph.totalEdges }),\n graph.circularDependencies.length > 0\n ? t(\"mcp.circularFound\", { count: graph.circularDependencies.length })\n : t(\"mcp.circularNone\"),\n ].join(\"\\n\");\n\n return {\n content: [\n { type: \"text\" as const, text: summary },\n { type: \"text\" as const, text: JSON.stringify(graph, null, 2) },\n ],\n };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 2: analyze_existing_architecture ──────────────────────\n\nserver.tool(\n \"analyze_existing_architecture\",\n `Comprehensive architecture analysis for existing projects. Shows critical components, circular dependencies, orphan files, coupling hotspots, and directory breakdown. Supports ${LANGUAGE_IDS.length} languages.`,\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path (default: src)\"),\n exclude: z\n .array(z.string())\n .optional()\n .describe(\"Array of regex patterns to exclude\"),\n topN: z\n .number()\n .int()\n .min(1)\n .max(50)\n .optional()\n .describe(\"Number of top items to show in each section (default: 10)\"),\n saveSnapshot: z\n .boolean()\n .optional()\n .describe(\"Also save a snapshot after analysis (default: false)\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root (needed only when saveSnapshot is true)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, exclude, topN, saveSnapshot: doSave, projectRoot, language }) => {\n try {\n validatePath(targetDir);\n const graph = await analyzeProject(targetDir, { exclude, language });\n const report = formatAnalysisReport(graph, { topN: topN ?? 10 });\n\n const content: { type: \"text\"; text: string }[] = [\n { type: \"text\" as const, text: report },\n ];\n\n if (doSave) {\n validatePath(projectRoot);\n await saveSnapshot(projectRoot, graph);\n content.push({ type: \"text\" as const, text: t(\"analyze.snapshotSaved\") });\n }\n\n return { content };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 3: save_architecture_snapshot ─────────────────────────\n\nserver.tool(\n \"save_architecture_snapshot\",\n \"Save the current dependency graph as a snapshot to .archtracker/snapshot.json\",\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root (where .archtracker is placed)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, projectRoot, language }) => {\n try {\n validatePath(targetDir);\n validatePath(projectRoot);\n const graph = await analyzeProject(targetDir, { language });\n const snapshot = await saveSnapshot(projectRoot, graph);\n\n // Top 5 most-depended-on files\n const keyComponents = Object.values(graph.files)\n .sort((a, b) => b.dependents.length - a.dependents.length)\n .slice(0, 5)\n .map((f) => ` ${t(\"cli.dependedBy\", { path: f.path, count: f.dependents.length })}`);\n\n const report = [\n t(\"mcp.snapshotSaved\"),\n t(\"cli.timestamp\", { ts: snapshot.timestamp }),\n t(\"cli.fileCount\", { count: graph.totalFiles }),\n t(\"cli.edgeCount\", { count: graph.totalEdges }),\n \"\",\n t(\"cli.keyComponents\"),\n ...keyComponents,\n ].join(\"\\n\");\n\n return { content: [{ type: \"text\" as const, text: report }] };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 3: check_architecture_diff ────────────────────────────\n\nserver.tool(\n \"check_architecture_diff\",\n \"Compare saved snapshot with current code dependencies and warn about files that may need updates\",\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root (where .archtracker is placed)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, projectRoot, language }) => {\n try {\n validatePath(targetDir);\n validatePath(projectRoot);\n const existingSnapshot = await loadSnapshot(projectRoot);\n\n if (!existingSnapshot) {\n // Auto-generate initial snapshot\n const graph = await analyzeProject(targetDir, { language });\n await saveSnapshot(projectRoot, graph);\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n t(\"mcp.autoInit\"),\n t(\"cli.fileCount\", { count: graph.totalFiles }) + \", \" + t(\"cli.edgeCount\", { count: graph.totalEdges }),\n t(\"mcp.nextCheckEnabled\"),\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n const currentGraph = await analyzeProject(targetDir, { language });\n const diff = computeDiff(existingSnapshot.graph, currentGraph);\n const report = formatDiffReport(diff);\n\n return { content: [{ type: \"text\" as const, text: report }] };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 4: get_current_context ────────────────────────────────\n\nserver.tool(\n \"get_current_context\",\n \"Get current valid file paths and architecture summary for AI session initialization\",\n {\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ targetDir, projectRoot, language }) => {\n try {\n let snapshot = await loadSnapshot(projectRoot);\n\n // Auto-generate if no snapshot exists\n if (!snapshot) {\n const graph = await analyzeProject(targetDir, { language });\n snapshot = await saveSnapshot(projectRoot, graph);\n }\n\n const graph = snapshot.graph;\n\n // Build key components list (sorted by dependent count)\n const keyComponents = Object.values(graph.files)\n .filter((f) => f.dependents.length > 0 || f.dependencies.length > 0)\n .sort((a, b) => b.dependents.length - a.dependents.length)\n .slice(0, 20)\n .map((f) => ({\n path: f.path,\n dependentCount: f.dependents.length,\n dependencyCount: f.dependencies.length,\n }));\n\n const validPaths = Object.keys(graph.files).sort();\n\n const summary = [\n t(\"cli.project\", { path: graph.rootDir }),\n t(\"cli.fileCount\", { count: graph.totalFiles }),\n t(\"cli.edgeCount\", { count: graph.totalEdges }),\n t(\"cli.circularCount\", { count: graph.circularDependencies.length }),\n t(\"cli.snapshot\", { ts: snapshot.timestamp }),\n \"\",\n t(\"cli.keyComponents\"),\n ...keyComponents.map(\n (c) =>\n ` ${t(\"cli.dependedBy\", { path: c.path, count: c.dependentCount })}`,\n ),\n ].join(\"\\n\");\n\n const context: ArchContext = {\n validPaths,\n summary,\n snapshotExists: true,\n snapshotTimestamp: snapshot.timestamp,\n keyComponents,\n };\n\n return {\n content: [\n { type: \"text\" as const, text: summary },\n {\n type: \"text\" as const,\n text: JSON.stringify(context, null, 2),\n },\n ],\n };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Tool 5: search_architecture ────────────────────────────────\n\nserver.tool(\n \"search_architecture\",\n \"Search architecture: file path search, impact analysis, critical component detection, orphan file detection\",\n {\n query: z\n .string()\n .optional()\n .describe(\"Search query (required for path/affected modes, not needed for critical/orphans)\"),\n mode: z\n .enum([\"path\", \"affected\", \"critical\", \"orphans\"])\n .default(\"path\")\n .describe(\n \"Search mode: path=search by path, affected=change impact, critical=key files, orphans=isolated files\",\n ),\n targetDir: z\n .string()\n .default(\"src\")\n .describe(\"Target directory path\"),\n projectRoot: z\n .string()\n .default(\".\")\n .describe(\"Project root\"),\n limit: z\n .number()\n .int()\n .min(1)\n .max(50)\n .optional()\n .describe(\"Max results (default: 10)\"),\n language: languageEnum\n .optional()\n .describe(\"Target language (auto-detected if omitted)\"),\n },\n async ({ query, mode, targetDir, projectRoot, limit, language }) => {\n try {\n validatePath(targetDir);\n validatePath(projectRoot);\n // Use existing snapshot or generate fresh\n let snapshot = await loadSnapshot(projectRoot);\n if (!snapshot) {\n const graph = await analyzeProject(targetDir, { language });\n snapshot = await saveSnapshot(projectRoot, graph);\n }\n\n const graph = snapshot.graph;\n const maxResults = limit ?? 10;\n let results;\n\n // Validate query is provided for modes that require it\n if ((mode === \"path\" || mode === \"affected\") && !query) {\n return {\n content: [{ type: \"text\" as const, text: t(\"mcp.queryRequired\", { mode }) }],\n isError: true,\n };\n }\n\n switch (mode) {\n case \"path\":\n results = searchByPath(graph, query!);\n break;\n case \"affected\":\n results = findAffectedFiles(graph, query!);\n break;\n case \"critical\":\n results = findCriticalFiles(graph, maxResults);\n break;\n case \"orphans\":\n results = findOrphanFiles(graph);\n break;\n }\n\n if (results.length === 0) {\n return {\n content: [\n { type: \"text\" as const, text: t(\"search.noResults\", { query: query ?? \"\", mode }) },\n ],\n };\n }\n\n const lines = [\n t(\"search.results\", { count: results.length, mode }),\n \"\",\n ...results.slice(0, maxResults).map((r) => {\n return [\n ` ${r.file}`,\n ` ${r.matchReason}`,\n ` deps: ${r.dependencyCount} -> [${r.dependencies.slice(0, 5).join(\", \")}${r.dependencies.length > 5 ? \"...\" : \"\"}]`,\n ` dependents: ${r.dependentCount} <- [${r.dependents.slice(0, 5).join(\", \")}${r.dependents.length > 5 ? \"...\" : \"\"}]`,\n ].join(\"\\n\");\n }),\n ];\n\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n } catch (error) {\n return errorResponse(error);\n }\n },\n);\n\n// ─── Error handling helper ──────────────────────────────────────\n\nfunction errorResponse(error: unknown) {\n let message: string;\n\n if (error instanceof PathTraversalError) {\n message = t(\"error.pathTraversal\", { message: error.message });\n } else if (error instanceof AnalyzerError) {\n message = t(\"error.analyzer\", { message: error.message });\n } else if (error instanceof StorageError) {\n message = t(\"error.storage\", { message: error.message });\n } else if (error instanceof Error) {\n message = t(\"error.generic\", { message: error.message });\n } else {\n message = t(\"error.unexpected\", { message: String(error) });\n }\n\n return {\n content: [{ type: \"text\" as const, text: message }],\n isError: true,\n };\n}\n\n// ─── Server startup ─────────────────────────────────────────────\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"[archtracker] MCP server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"[archtracker] Fatal error:\", error);\n process.exit(1);\n});\n","import { resolve } from \"node:path\";\nimport { stat } from \"node:fs/promises\";\nimport type { DependencyGraph } from \"../types/schema.js\";\nimport { RegexEngine } from \"./engines/regex-engine.js\";\nimport { detectLanguage } from \"./engines/detect.js\";\nimport { getLanguageConfig } from \"./engines/languages.js\";\nimport type { LanguageId } from \"./engines/types.js\";\n\n/** Options for the dependency analyzer */\nexport interface AnalyzeOptions {\n /** Regex patterns to exclude from analysis (e.g. [\"node_modules\", \"\\\\.test\\\\.ts$\"]) */\n exclude?: string[];\n /** Maximum recursion depth (0 = unlimited) */\n maxDepth?: number;\n /** Target language (auto-detected if omitted) */\n language?: LanguageId;\n}\n\n/**\n * Analyze project dependencies using regex-based import extraction.\n * Supports all 13 languages. Language is auto-detected if not specified.\n */\nexport async function analyzeProject(\n rootDir: string,\n options: AnalyzeOptions = {},\n): Promise<DependencyGraph> {\n const absRootDir = resolve(rootDir);\n\n // Validate directory exists\n try {\n const s = await stat(absRootDir);\n if (!s.isDirectory()) {\n throw new AnalyzerError(`Not a directory: ${absRootDir}`);\n }\n } catch (error) {\n if (error instanceof AnalyzerError) throw error;\n throw new AnalyzerError(`Directory not found: ${absRootDir}`, { cause: error });\n }\n\n const language = options.language ?? (await detectLanguage(absRootDir));\n\n try {\n const config = getLanguageConfig(language);\n if (!config) {\n throw new AnalyzerError(`No analyzer config for language: ${language}`);\n }\n\n return await new RegexEngine(config).analyze(absRootDir, options);\n } catch (error) {\n if (error instanceof AnalyzerError) throw error;\n const message = error instanceof Error ? error.message : String(error);\n throw new AnalyzerError(message, { cause: error });\n }\n}\n\n/** Custom error class for analyzer failures */\nexport class AnalyzerError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"AnalyzerError\";\n }\n}\n","import { readdir, readFile, stat } from \"node:fs/promises\";\nimport { join, relative, resolve } from \"node:path\";\nimport type {\n DependencyGraph,\n DependencyEdge,\n FileNode,\n} from \"../../types/schema.js\";\nimport type { AnalyzerEngine, LanguageConfig } from \"./types.js\";\nimport { detectCycles } from \"./cycle.js\";\nimport { stripComments } from \"./strip-comments.js\";\n\nexport class RegexEngine implements AnalyzerEngine {\n constructor(private config: LanguageConfig) {}\n\n async analyze(\n rootDir: string,\n options: { exclude?: string[]; maxDepth?: number } = {},\n ): Promise<DependencyGraph> {\n const absRootDir = resolve(rootDir);\n const excludePatterns = [\n ...(this.config.defaultExclude ?? []),\n ...(options.exclude ?? []),\n \"\\\\.archtracker\",\n ].map((p) => new RegExp(p));\n\n // 1. Collect all matching files\n const projectFiles = await this.collectFiles(\n absRootDir,\n absRootDir,\n excludePatterns,\n options.maxDepth ?? 0,\n );\n\n const projectFileSet = new Set(projectFiles);\n\n // 2. Extract imports and resolve edges\n const files: Record<string, FileNode> = {};\n const edges: DependencyEdge[] = [];\n const edgeSet = new Set<string>(); // \"source\\0target\" for dedup\n\n // Initialize all file nodes\n for (const filePath of projectFiles) {\n const relPath = relative(absRootDir, filePath);\n files[relPath] = {\n path: relPath,\n exists: true,\n dependencies: [],\n dependents: [],\n };\n }\n\n // Process each file for imports\n for (const filePath of projectFiles) {\n const relSource = relative(absRootDir, filePath);\n let content: string;\n try {\n content = await readFile(filePath, \"utf-8\");\n } catch {\n if (files[relSource]) files[relSource].exists = false;\n continue;\n }\n\n const stripped = stripComments(content, this.config.commentStyle);\n const imports = this.extractImports(stripped);\n for (const importPath of imports) {\n const resolved = this.config.resolveImport(\n importPath,\n filePath,\n absRootDir,\n projectFileSet,\n );\n if (!resolved) continue;\n\n const relTarget = relative(absRootDir, resolved);\n if (!files[relTarget]) continue; // skip external\n if (relSource === relTarget) continue; // skip self-import\n\n const edgeKey = `${relSource}\\0${relTarget}`;\n if (edgeSet.has(edgeKey)) continue; // deduplicate\n edgeSet.add(edgeKey);\n\n edges.push({\n source: relSource,\n target: relTarget,\n type: \"static\",\n });\n\n files[relSource].dependencies.push(relTarget);\n files[relTarget].dependents.push(relSource);\n }\n }\n\n // 3. Detect cycles\n const circularDependencies = detectCycles(edges);\n\n return {\n rootDir: absRootDir,\n files,\n edges,\n circularDependencies,\n totalFiles: Object.keys(files).length,\n totalEdges: edges.length,\n };\n }\n\n private extractImports(content: string): string[] {\n // Use custom extractor if defined (e.g., Rust grouped use)\n if (this.config.extractImports) {\n return this.config.extractImports(content);\n }\n\n const imports: string[] = [];\n for (const pattern of this.config.importPatterns) {\n // Reset regex state, ensuring 'g' flag is present to prevent infinite loops\n const flags = pattern.regex.flags.includes('g') ? pattern.regex.flags : pattern.regex.flags + 'g';\n const regex = new RegExp(pattern.regex.source, flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(content)) !== null) {\n // Use the first capturing group as the import path\n if (match[1]) {\n imports.push(match[1]);\n }\n }\n }\n return imports;\n }\n\n private async collectFiles(\n dir: string,\n absRootDir: string,\n excludePatterns: RegExp[],\n maxDepth: number,\n currentDepth: number = 0,\n ): Promise<string[]> {\n if (maxDepth > 0 && currentDepth >= maxDepth) return [];\n\n const results: string[] = [];\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relPath = relative(absRootDir, fullPath);\n\n // Check excludes against the entry name and relative path\n if (\n excludePatterns.some(\n (p) => p.test(entry.name) || p.test(relPath) || p.test(fullPath),\n )\n ) {\n continue;\n }\n\n if (entry.isDirectory()) {\n if (entry.name.startsWith(\".\")) continue;\n const sub = await this.collectFiles(\n fullPath,\n absRootDir,\n excludePatterns,\n maxDepth,\n currentDepth + 1,\n );\n results.push(...sub);\n } else if (entry.isFile()) {\n const dotIdx = entry.name.lastIndexOf(\".\");\n if (dotIdx > 0) {\n const ext = entry.name.slice(dotIdx);\n if (this.config.extensions.includes(ext)) {\n results.push(fullPath);\n }\n }\n }\n }\n\n return results;\n }\n}\n","import type { DependencyEdge, CircularDependency } from \"../../types/schema.js\";\n\nexport function detectCycles(edges: DependencyEdge[]): CircularDependency[] {\n const adj = new Map<string, string[]>();\n for (const edge of edges) {\n if (!adj.has(edge.source)) adj.set(edge.source, []);\n adj.get(edge.source)!.push(edge.target);\n }\n\n const visited = new Set<string>();\n const inStack = new Set<string>();\n const cycles: CircularDependency[] = [];\n const cycleKeys = new Set<string>();\n\n function dfs(node: string, path: string[]): void {\n if (inStack.has(node)) {\n const cycleStart = path.indexOf(node);\n if (cycleStart !== -1) {\n const cycle = path.slice(cycleStart);\n const key = [...cycle].sort().join(\"\\u2192\");\n if (!cycleKeys.has(key)) {\n cycleKeys.add(key);\n cycles.push({ cycle });\n }\n }\n return;\n }\n if (visited.has(node)) return;\n\n visited.add(node);\n inStack.add(node);\n path.push(node);\n\n for (const neighbor of adj.get(node) ?? []) {\n dfs(neighbor, path);\n }\n\n path.pop();\n inStack.delete(node);\n }\n\n for (const node of adj.keys()) {\n if (!visited.has(node)) {\n dfs(node, []);\n }\n }\n\n return cycles;\n}\n","import type { CommentStyle } from \"./types.js\";\n\n/**\n * Strip comments and string literals from source code.\n * Replaces them with whitespace to preserve line numbers and positions.\n */\nexport function stripComments(content: string, style: CommentStyle): string {\n switch (style) {\n case \"c-style\":\n return stripCStyle(content);\n case \"hash\":\n return stripHash(content);\n case \"python\":\n return stripPython(content);\n case \"ruby\":\n return stripRuby(content);\n case \"php\":\n return stripPhp(content);\n default: {\n const _exhaustive: never = style;\n throw new Error(`Unknown comment style: ${_exhaustive}`);\n }\n }\n}\n\n/**\n * C-style comments: // line comments and /* block comments *\\/\n * Used by: Rust, Go, Java, C/C++, Swift, Kotlin\n * Also strips string literals (\"...\" and '...' for char literals)\n * Handles Rust raw strings: r\"...\", r#\"...\"#, r##\"...\"## etc.\n */\nfunction stripCStyle(content: string): string {\n let result = \"\";\n let i = 0;\n while (i < content.length) {\n // Rust raw strings: r\"...\", r#\"...\"#, r##\"...\"##, etc.\n if (content[i] === \"r\" && i + 1 < content.length) {\n let hashes = 0;\n let j = i + 1;\n while (j < content.length && content[j] === \"#\") {\n hashes++;\n j++;\n }\n if (j < content.length && content[j] === '\"') {\n // This is a raw string: r\"...\", r#\"...\"#, etc.\n // Replace entire raw string content with spaces\n // Replace r, hashes, and opening quote with spaces\n for (let k = i; k <= j; k++) {\n result += \" \";\n }\n i = j + 1; // move past opening quote\n // Scan for closing pattern\n while (i < content.length) {\n if (content[i] === '\"') {\n // Check if followed by correct number of hashes\n let matchHashes = 0;\n let m = i + 1;\n while (m < content.length && content[m] === \"#\" && matchHashes < hashes) {\n matchHashes++;\n m++;\n }\n if (matchHashes === hashes) {\n // Found the closing delimiter\n for (let k = i; k < m; k++) {\n result += \" \";\n }\n i = m;\n break;\n }\n }\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n continue;\n }\n // Not a raw string, fall through to normal character handling\n }\n\n // Single-line comment\n if (content[i] === \"/\" && content[i + 1] === \"/\") {\n // Skip to end of line, preserve newline\n while (i < content.length && content[i] !== \"\\n\") {\n result += \" \";\n i++;\n }\n }\n // Block comment\n else if (content[i] === \"/\" && content[i + 1] === \"*\") {\n result += \" \";\n i++; // /\n result += \" \";\n i++; // *\n while (i < content.length) {\n if (content[i] === \"*\" && content[i + 1] === \"/\") {\n result += \" \";\n i++;\n result += \" \";\n i++;\n break;\n }\n // Preserve newlines for line-number accuracy\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n }\n // Double-quoted string\n else if (content[i] === '\"') {\n result += content[i]; // keep the quote\n i++;\n while (i < content.length && content[i] !== '\"') {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i]; // backslash\n i++;\n result += content[i]; // escaped char\n i++;\n } else if (content[i] === \"\\n\") {\n result += \"\\n\";\n i++;\n } else {\n result += content[i];\n i++;\n }\n }\n if (i < content.length) {\n result += content[i]; // closing quote\n i++;\n }\n }\n // Single-quoted char literal (e.g. '/', '\\'', '\\\\', '\\n')\n else if (content[i] === \"'\") {\n result += content[i]; // opening quote\n i++;\n while (i < content.length && content[i] !== \"'\") {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i]; // backslash\n i++;\n result += content[i]; // escaped char\n i++;\n } else {\n result += content[i];\n i++;\n }\n }\n if (i < content.length) {\n result += content[i]; // closing quote\n i++;\n }\n }\n // Raw/backtick string (Go)\n else if (content[i] === \"`\") {\n result += \" \"; // replace backtick string content\n i++;\n while (i < content.length && content[i] !== \"`\") {\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n if (i < content.length) {\n result += \" \";\n i++;\n }\n }\n // Normal character\n else {\n result += content[i];\n i++;\n }\n }\n return result;\n}\n\n/**\n * Hash-style comments: # line comments\n * Used by: (standalone, though mostly via python/ruby)\n */\nfunction stripHash(content: string): string {\n let result = \"\";\n let i = 0;\n while (i < content.length) {\n if (content[i] === \"#\") {\n while (i < content.length && content[i] !== \"\\n\") {\n result += \" \";\n i++;\n }\n } else if (content[i] === '\"') {\n result += content[i];\n i++;\n while (i < content.length && content[i] !== '\"') {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else {\n result += content[i++];\n }\n }\n if (i < content.length) { result += content[i]; i++; }\n } else if (content[i] === \"'\") {\n result += content[i];\n i++;\n while (i < content.length && content[i] !== \"'\") {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else {\n result += content[i++];\n }\n }\n if (i < content.length) { result += content[i]; i++; }\n } else {\n result += content[i];\n i++;\n }\n }\n return result;\n}\n\n/**\n * Python comments: # line comments + triple-quoted strings (\"\"\" and ''')\n * Handles string prefixes: r, b, f, rb, fr, br (case-insensitive)\n * For raw strings (r prefix), backslash is NOT treated as escape.\n */\nfunction stripPython(content: string): string {\n let result = \"\";\n let i = 0;\n while (i < content.length) {\n // Check for string prefix (r, b, f, rb, fr, br) before quotes\n let prefixLen = 0;\n let isRaw = false;\n if (i < content.length) {\n const c0 = content[i];\n const c1 = i + 1 < content.length ? content[i + 1] : \"\";\n const c2 = i + 2 < content.length ? content[i + 2] : \"\";\n // Two-char prefixes: rb, br, fr, rf\n if (\n (c0 === \"r\" || c0 === \"R\" || c0 === \"b\" || c0 === \"B\" || c0 === \"f\" || c0 === \"F\") &&\n (c1 === \"r\" || c1 === \"R\" || c1 === \"b\" || c1 === \"B\" || c1 === \"f\" || c1 === \"F\") &&\n (c2 === '\"' || c2 === \"'\")\n ) {\n // Validate it's a real two-char prefix (rb, br, fr, rf)\n const pair = (c0 + c1).toLowerCase();\n if (pair === \"rb\" || pair === \"br\" || pair === \"fr\" || pair === \"rf\") {\n prefixLen = 2;\n isRaw = pair.includes(\"r\");\n }\n }\n // Single-char prefix: r, b, f\n if (\n prefixLen === 0 &&\n (c0 === \"r\" || c0 === \"R\" || c0 === \"b\" || c0 === \"B\" || c0 === \"f\" || c0 === \"F\") &&\n (c1 === '\"' || c1 === \"'\")\n ) {\n prefixLen = 1;\n isRaw = c0 === \"r\" || c0 === \"R\";\n }\n }\n\n const quoteStart = i + prefixLen;\n\n // Triple-quoted strings (with or without prefix)\n if (\n quoteStart + 2 < content.length &&\n (content[quoteStart] === '\"' || content[quoteStart] === \"'\") &&\n content[quoteStart + 1] === content[quoteStart] &&\n content[quoteStart + 2] === content[quoteStart]\n ) {\n const quote = content[quoteStart];\n // Output prefix chars\n for (let k = 0; k < prefixLen; k++) {\n result += \" \";\n }\n // Replace triple-quoted content with spaces\n result += \" \";\n i = quoteStart + 3;\n while (i < content.length) {\n if (content[i] === quote && content[i + 1] === quote && content[i + 2] === quote) {\n result += \" \";\n i += 3;\n break;\n }\n if (!isRaw && content[i] === \"\\\\\" && i + 1 < content.length) {\n result += \" \";\n i++;\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n } else {\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n }\n }\n // Hash comment\n else if (prefixLen === 0 && content[i] === \"#\") {\n while (i < content.length && content[i] !== \"\\n\") {\n result += \" \";\n i++;\n }\n }\n // Single/double quoted strings (non-triple), with or without prefix\n else if (\n quoteStart < content.length &&\n (content[quoteStart] === '\"' || content[quoteStart] === \"'\") &&\n (prefixLen > 0 || content[i] === '\"' || content[i] === \"'\")\n ) {\n const quote = content[quoteStart];\n // Output prefix\n for (let k = i; k < quoteStart; k++) {\n result += content[k];\n }\n result += content[quoteStart]; // opening quote\n i = quoteStart + 1;\n while (i < content.length && content[i] !== quote) {\n if (!isRaw && content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else if (content[i] === \"\\n\") {\n result += \"\\n\";\n i++;\n break; // unterminated string\n } else {\n result += content[i++];\n }\n }\n if (i < content.length && content[i] === quote) { result += content[i]; i++; }\n }\n else {\n result += content[i];\n i++;\n }\n }\n return result;\n}\n\n/**\n * Ruby comments: # line comments + =begin/=end block comments\n * Handles string interpolation #{} inside double-quoted strings.\n */\nfunction stripRuby(content: string): string {\n const lines = content.split(\"\\n\");\n const result: string[] = [];\n let inBlock = false;\n\n for (const line of lines) {\n if (!inBlock && /^=begin(\\s|$)/.test(line)) {\n inBlock = true;\n result.push(\" \".repeat(line.length));\n continue;\n }\n if (inBlock) {\n if (/^=end(\\s|$)/.test(line)) {\n inBlock = false;\n }\n result.push(\" \".repeat(line.length));\n continue;\n }\n\n // Process line for # comments (respecting strings)\n let processed = \"\";\n let i = 0;\n while (i < line.length) {\n if (line[i] === \"#\") {\n // Outside of any string, this is a comment\n processed += \" \".repeat(line.length - i);\n break;\n } else if (line[i] === '\"') {\n processed += line[i]; i++;\n processed = scanRubyDoubleQuotedString(line, i, processed);\n i = (scanRubyDoubleQuotedStringIndex(line, i));\n } else if (line[i] === \"'\") {\n processed += line[i]; i++;\n while (i < line.length && line[i] !== \"'\") {\n if (line[i] === \"\\\\\" && i + 1 < line.length) {\n processed += line[i++];\n processed += line[i++];\n } else {\n processed += line[i++];\n }\n }\n if (i < line.length) { processed += line[i]; i++; }\n } else {\n processed += line[i]; i++;\n }\n }\n result.push(processed);\n }\n\n return result.join(\"\\n\");\n}\n\n/**\n * Scans a Ruby double-quoted string body starting at position i (after the opening \"),\n * handling #{} interpolation. Returns the resulting processed string content appended to `processed`.\n */\nfunction scanRubyDoubleQuotedString(line: string, startI: number, processed: string): string {\n let i = startI;\n while (i < line.length && line[i] !== '\"') {\n if (line[i] === \"\\\\\" && i + 1 < line.length) {\n processed += line[i++];\n processed += line[i++];\n } else if (line[i] === \"#\" && i + 1 < line.length && line[i + 1] === \"{\") {\n // String interpolation: #{...}\n processed += line[i++]; // #\n processed += line[i++]; // {\n let depth = 1;\n while (i < line.length && depth > 0) {\n if (line[i] === \"{\") {\n depth++;\n processed += line[i++];\n } else if (line[i] === \"}\") {\n depth--;\n processed += line[i++];\n } else if (line[i] === \"\\\\\" && i + 1 < line.length) {\n processed += line[i++];\n processed += line[i++];\n } else {\n processed += line[i++];\n }\n }\n } else {\n processed += line[i++];\n }\n }\n if (i < line.length) { processed += line[i]; /* closing \" */ }\n return processed;\n}\n\n/**\n * Returns the index after scanning a Ruby double-quoted string body starting at startI.\n */\nfunction scanRubyDoubleQuotedStringIndex(line: string, startI: number): number {\n let i = startI;\n while (i < line.length && line[i] !== '\"') {\n if (line[i] === \"\\\\\" && i + 1 < line.length) {\n i += 2;\n } else if (line[i] === \"#\" && i + 1 < line.length && line[i + 1] === \"{\") {\n i += 2; // skip #{\n let depth = 1;\n while (i < line.length && depth > 0) {\n if (line[i] === \"{\") {\n depth++;\n i++;\n } else if (line[i] === \"}\") {\n depth--;\n i++;\n } else if (line[i] === \"\\\\\" && i + 1 < line.length) {\n i += 2;\n } else {\n i++;\n }\n }\n } else {\n i++;\n }\n }\n if (i < line.length) { i++; /* skip closing \" */ }\n return i;\n}\n\n/**\n * PHP comments: // line, /* block *\\/, and # line\n * Also handles heredoc (<<<IDENTIFIER) and nowdoc (<<<'IDENTIFIER').\n */\nfunction stripPhp(content: string): string {\n let result = \"\";\n let i = 0;\n while (i < content.length) {\n // Heredoc / Nowdoc: <<<IDENTIFIER or <<<'IDENTIFIER'\n if (content[i] === \"<\" && content[i + 1] === \"<\" && content[i + 2] === \"<\") {\n const heredocStart = i;\n let j = i + 3;\n let isNowdoc = false;\n // Skip optional whitespace after <<<\n // Check for nowdoc (single-quoted identifier)\n if (j < content.length && content[j] === \"'\") {\n isNowdoc = true;\n j++; // skip opening '\n }\n // Read identifier\n const identStart = j;\n while (j < content.length && /[A-Za-z0-9_]/.test(content[j])) {\n j++;\n }\n const identifier = content.slice(identStart, j);\n if (identifier.length > 0) {\n // For nowdoc, skip the closing '\n if (isNowdoc && j < content.length && content[j] === \"'\") {\n j++;\n }\n // Check for optional semicolon and newline (or just newline) to validate this is heredoc syntax\n // We need at least a newline after the identifier line\n let validHeredoc = false;\n let lineEnd = j;\n // There might be a semicolon and/or other chars before newline, but typically just newline\n if (lineEnd < content.length && content[lineEnd] === \"\\n\") {\n validHeredoc = true;\n }\n if (validHeredoc) {\n // Output the heredoc opening line as-is (<<<IDENTIFIER or <<<'IDENTIFIER')\n for (let k = heredocStart; k <= lineEnd; k++) {\n if (content[k] === \"\\n\") {\n result += \"\\n\";\n } else {\n result += content[k];\n }\n }\n i = lineEnd + 1; // move past the newline\n // Now scan for the closing identifier on its own line\n // The closing identifier may optionally be followed by ; and must be at end of line\n let found = false;\n while (i < content.length && !found) {\n // Check if current line starts with the identifier\n const lineStart = i;\n // Read the current line\n let lineEndIdx = i;\n while (lineEndIdx < content.length && content[lineEndIdx] !== \"\\n\") {\n lineEndIdx++;\n }\n const currentLine = content.slice(lineStart, lineEndIdx);\n // PHP 7.3+ allows indented heredoc closing, but we check trimmed\n const trimmedLine = currentLine.trimStart();\n if (\n trimmedLine === identifier ||\n trimmedLine === identifier + \";\" ||\n trimmedLine === identifier + \",\" ||\n trimmedLine === identifier + \");\" ||\n trimmedLine === identifier + \")\" ||\n trimmedLine.startsWith(identifier + \";\") ||\n trimmedLine === identifier\n ) {\n // This is the closing line - output it as-is\n for (let k = lineStart; k < lineEndIdx; k++) {\n result += content[k];\n }\n i = lineEndIdx;\n if (i < content.length && content[i] === \"\\n\") {\n result += \"\\n\";\n i++;\n }\n found = true;\n } else {\n // Body line: replace content with spaces, preserve newlines\n for (let k = lineStart; k < lineEndIdx; k++) {\n result += \" \";\n }\n i = lineEndIdx;\n if (i < content.length && content[i] === \"\\n\") {\n result += \"\\n\";\n i++;\n }\n }\n }\n continue;\n }\n }\n // If not a valid heredoc, just output the < and continue\n result += content[i];\n i++;\n continue;\n }\n\n // Single-line comments (// or #)\n if ((content[i] === \"/\" && content[i + 1] === \"/\") || content[i] === \"#\") {\n while (i < content.length && content[i] !== \"\\n\") {\n result += \" \";\n i++;\n }\n }\n // Block comments\n else if (content[i] === \"/\" && content[i + 1] === \"*\") {\n result += \" \"; i++;\n result += \" \"; i++;\n while (i < content.length) {\n if (content[i] === \"*\" && content[i + 1] === \"/\") {\n result += \" \"; i++;\n result += \" \"; i++;\n break;\n }\n result += content[i] === \"\\n\" ? \"\\n\" : \" \";\n i++;\n }\n }\n // Double-quoted string\n else if (content[i] === '\"') {\n result += content[i]; i++;\n while (i < content.length && content[i] !== '\"') {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else {\n result += content[i++];\n }\n }\n if (i < content.length) { result += content[i]; i++; }\n }\n // Single-quoted string\n else if (content[i] === \"'\") {\n result += content[i]; i++;\n while (i < content.length && content[i] !== \"'\") {\n if (content[i] === \"\\\\\" && i + 1 < content.length) {\n result += content[i++];\n result += content[i++];\n } else {\n result += content[i++];\n }\n }\n if (i < content.length) { result += content[i]; i++; }\n }\n else {\n result += content[i]; i++;\n }\n }\n return result;\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { LanguageId } from \"./types.js\";\n\n/** Marker files that identify a project's primary language */\nconst MARKERS: Array<{ file: string; language: LanguageId }> = [\n { file: \"Cargo.toml\", language: \"rust\" },\n { file: \"go.mod\", language: \"go\" },\n { file: \"pyproject.toml\", language: \"python\" },\n { file: \"setup.py\", language: \"python\" },\n { file: \"requirements.txt\", language: \"python\" },\n { file: \"Pipfile\", language: \"python\" },\n { file: \"pom.xml\", language: \"java\" },\n { file: \"build.gradle\", language: \"java\" },\n { file: \"build.gradle.kts\", language: \"kotlin\" },\n { file: \"build.sbt\", language: \"scala\" },\n { file: \"build.sc\", language: \"scala\" },\n { file: \"Package.swift\", language: \"swift\" },\n { file: \"Gemfile\", language: \"ruby\" },\n { file: \"composer.json\", language: \"php\" },\n { file: \"pubspec.yaml\", language: \"dart\" },\n { file: \"CMakeLists.txt\", language: \"c-cpp\" },\n { file: \"Makefile\", language: \"c-cpp\" },\n { file: \"package.json\", language: \"javascript\" },\n { file: \"tsconfig.json\", language: \"javascript\" },\n];\n\n/** Extension-based markers for languages without fixed-name marker files */\nconst EXT_MARKERS: Array<[string, LanguageId]> = [\n [\".sln\", \"c-sharp\"],\n [\".csproj\", \"c-sharp\"],\n];\n\n/** Extension-to-language mapping for fallback detection */\nconst EXT_MAP: Record<string, LanguageId> = {\n \".ts\": \"javascript\",\n \".tsx\": \"javascript\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".rs\": \"rust\",\n \".go\": \"go\",\n \".java\": \"java\",\n \".c\": \"c-cpp\",\n \".cpp\": \"c-cpp\",\n \".cc\": \"c-cpp\",\n \".cxx\": \"c-cpp\",\n \".h\": \"c-cpp\",\n \".hpp\": \"c-cpp\",\n \".rb\": \"ruby\",\n \".php\": \"php\",\n \".swift\": \"swift\",\n \".kt\": \"kotlin\",\n \".kts\": \"kotlin\",\n \".cs\": \"c-sharp\",\n \".dart\": \"dart\",\n \".scala\": \"scala\",\n \".sc\": \"scala\",\n};\n\n/**\n * Auto-detect the primary language of a project directory.\n * 1. Check for marker files (Cargo.toml, go.mod, etc.)\n * 2. Fallback: count file extensions in the top-level directory\n */\nexport async function detectLanguage(rootDir: string): Promise<LanguageId> {\n // Phase 1: marker files\n for (const marker of MARKERS) {\n try {\n const s = await stat(join(rootDir, marker.file));\n if (s.isFile() || s.isDirectory()) {\n return marker.language;\n }\n } catch {\n // file doesn't exist, continue\n }\n }\n\n // Phase 1.5: extension-based markers (e.g. *.sln, *.csproj for C#)\n try {\n const topEntries = await readdir(rootDir, { withFileTypes: true });\n for (const entry of topEntries) {\n if (!entry.isFile()) continue;\n for (const [ext, lang] of EXT_MARKERS) {\n if (entry.name.endsWith(ext)) return lang;\n }\n }\n } catch {\n // ignore\n }\n\n // Phase 2: extension frequency (shallow scan)\n const counts = new Map<LanguageId, number>();\n try {\n await scanExtensions(rootDir, counts, 2, 0);\n } catch {\n // if scan fails, default to JS\n }\n\n if (counts.size > 0) {\n let maxLang: LanguageId = \"javascript\";\n let maxCount = 0;\n for (const [lang, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxLang = lang;\n }\n }\n return maxLang;\n }\n\n return \"javascript\";\n}\n\nasync function scanExtensions(\n dir: string,\n counts: Map<LanguageId, number>,\n maxDepth: number,\n currentDepth: number,\n): Promise<void> {\n if (currentDepth >= maxDepth) return;\n\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n\n if (entry.isDirectory() && currentDepth < maxDepth - 1) {\n await scanExtensions(\n join(dir, entry.name),\n counts,\n maxDepth,\n currentDepth + 1,\n );\n } else if (entry.isFile()) {\n const dotIdx = entry.name.lastIndexOf(\".\");\n if (dotIdx > 0) {\n const ext = entry.name.slice(dotIdx);\n const lang = EXT_MAP[ext];\n if (lang) {\n counts.set(lang, (counts.get(lang) ?? 0) + 1);\n }\n }\n }\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { join, dirname, resolve } from \"node:path\";\nimport { LANGUAGE_IDS } from \"./types.js\";\nimport type { LanguageConfig, LanguageId } from \"./types.js\";\n\n// ─── Python ──────────────────────────────────────────\nconst python: LanguageConfig = {\n id: \"python\",\n extensions: [\".py\"],\n commentStyle: \"python\",\n importPatterns: [\n // from package.module import something\n { regex: /^from\\s+(\\.[\\w.]*|\\w[\\w.]*)\\s+import\\b/gm },\n // import package.module (handled by extractImports for multi-module case)\n ],\n // Bug #1 fix: custom extractImports to handle `import a, b, c`\n extractImports(content: string): string[] {\n const imports: string[] = [];\n\n // from package.module import something\n const fromRegex = /^from\\s+(\\.[\\w.]*|\\w[\\w.]*)\\s+import\\b/gm;\n let match: RegExpExecArray | null;\n while ((match = fromRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n // import a, b, c — captures all comma-separated modules\n const importRegex = /^import\\s+([\\w.]+(?:\\s*,\\s*[\\w.]+)*)/gm;\n while ((match = importRegex.exec(content)) !== null) {\n const modules = match[1].split(\",\");\n for (const mod of modules) {\n const trimmed = mod.trim();\n if (trimmed) imports.push(trimmed);\n }\n }\n\n return imports;\n },\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Relative imports (starts with .)\n if (importPath.startsWith(\".\")) {\n const dots = importPath.match(/^\\.+/)?.[0].length ?? 1;\n let base = dirname(sourceFile);\n for (let i = 1; i < dots; i++) base = dirname(base);\n const rest = importPath.slice(dots).replace(/\\./g, \"/\");\n return tryPythonResolve(join(base, rest), projectFiles);\n }\n // Absolute imports\n const parts = importPath.replace(/\\./g, \"/\");\n return tryPythonResolve(join(rootDir, parts), projectFiles);\n },\n defaultExclude: [\"__pycache__\", \"\\\\.venv\", \"venv\", \"\\\\.egg-info\", \"dist\", \"build\"],\n};\n\nfunction tryPythonResolve(base: string, projectFiles: Set<string>): string | null {\n // Try as module file\n if (projectFiles.has(base + \".py\")) return base + \".py\";\n // Try as package __init__.py\n if (projectFiles.has(join(base, \"__init__.py\"))) return join(base, \"__init__.py\");\n return null;\n}\n\n// ─── Rust ────────────────────────────────────────────\nconst rust: LanguageConfig = {\n id: \"rust\",\n extensions: [\".rs\"],\n commentStyle: \"c-style\",\n importPatterns: [], // handled by extractImports\n extractImports(content: string): string[] {\n const imports: string[] = [];\n\n // mod declarations: mod child;\n const modRegex = /\\bmod\\s+(\\w+)\\s*;/gm;\n let match: RegExpExecArray | null;\n while ((match = modRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n // use crate::... (simple and grouped)\n const useRegex = /\\buse\\s+crate::([\\s\\S]*?);/gm;\n while ((match = useRegex.exec(content)) !== null) {\n const body = match[1].trim();\n extractRustUsePaths(body, \"\", imports);\n }\n\n // Bug #2 fix: use super::... imports\n const useSuperRegex = /\\buse\\s+super::([\\s\\S]*?);/gm;\n while ((match = useSuperRegex.exec(content)) !== null) {\n const body = match[1].trim();\n extractRustUsePaths(body, \"\", imports, \"super\");\n }\n\n // Bug #2 fix: use self::... imports\n const useSelfRegex = /\\buse\\s+self::([\\s\\S]*?);/gm;\n while ((match = useSelfRegex.exec(content)) !== null) {\n const body = match[1].trim();\n extractRustUsePaths(body, \"\", imports, \"self\");\n }\n\n return imports;\n },\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n const srcDir = join(rootDir, \"src\");\n\n if (!importPath.includes(\"::\")) {\n // mod declaration: look for child module\n const parentDir = dirname(sourceFile);\n const asFile = join(parentDir, importPath + \".rs\");\n if (projectFiles.has(asFile)) return asFile;\n const asDir = join(parentDir, importPath, \"mod.rs\");\n if (projectFiles.has(asDir)) return asDir;\n return null;\n }\n\n // Bug #3 fix: use super::x::y — resolve from parent directory of source file\n if (importPath.startsWith(\"super::\")) {\n const parentDir = dirname(dirname(sourceFile));\n const segments = importPath.slice(\"super::\".length).split(\"::\");\n for (let i = segments.length; i > 0; i--) {\n const path = segments.slice(0, i).join(\"/\");\n const asFile = join(parentDir, path + \".rs\");\n if (projectFiles.has(asFile)) return asFile;\n const asDir = join(parentDir, path, \"mod.rs\");\n if (projectFiles.has(asDir)) return asDir;\n }\n return null;\n }\n\n // Bug #4 fix: use self::x::y — resolve from same directory as source file\n if (importPath.startsWith(\"self::\")) {\n const selfDir = dirname(sourceFile);\n const segments = importPath.slice(\"self::\".length).split(\"::\");\n for (let i = segments.length; i > 0; i--) {\n const path = segments.slice(0, i).join(\"/\");\n const asFile = join(selfDir, path + \".rs\");\n if (projectFiles.has(asFile)) return asFile;\n const asDir = join(selfDir, path, \"mod.rs\");\n if (projectFiles.has(asDir)) return asDir;\n }\n return null;\n }\n\n // use crate::x::y — resolve from src/\n const segments = importPath.split(\"::\");\n // Try progressively shorter prefixes as directory/file\n for (let i = segments.length; i > 0; i--) {\n const path = segments.slice(0, i).join(\"/\");\n const asFile = join(srcDir, path + \".rs\");\n if (projectFiles.has(asFile)) return asFile;\n const asDir = join(srcDir, path, \"mod.rs\");\n if (projectFiles.has(asDir)) return asDir;\n }\n return null;\n },\n defaultExclude: [\"target\"],\n};\n\n/**\n * Recursively extract Rust use paths, handling grouped imports.\n * e.g. \"foo::{bar, baz::qux}\" → [\"foo::bar\", \"foo::baz::qux\"]\n * e.g. \"foo::bar\" → [\"foo::bar\"]\n * The optional rootPrefix parameter prepends \"super\" or \"self\" to all paths.\n */\nfunction extractRustUsePaths(body: string, prefix: string, results: string[], rootPrefix?: string): void {\n const trimmed = body.trim();\n\n // Check for grouped import: path::{...}\n const braceStart = trimmed.indexOf(\"{\");\n if (braceStart === -1) {\n // Simple path like \"foo::bar::Baz\" or just \"foo\"\n let path = prefix ? `${prefix}::${trimmed}` : trimmed;\n if (rootPrefix) {\n path = `${rootPrefix}::${path}`;\n }\n // Remove trailing items after last :: that aren't module names\n // Keep the full path — resolver handles progressively shorter prefixes\n if (path && !path.includes(\"{\")) {\n results.push(path);\n }\n return;\n }\n\n // Extract the prefix before the brace\n let pathPrefix = trimmed.slice(0, braceStart).trim();\n if (pathPrefix.endsWith(\"::\")) {\n pathPrefix = pathPrefix.slice(0, -2);\n }\n const fullPrefix = prefix ? `${prefix}::${pathPrefix}` : pathPrefix;\n\n // Find matching closing brace\n let depth = 0;\n let braceEnd = -1;\n for (let i = braceStart; i < trimmed.length; i++) {\n if (trimmed[i] === \"{\") depth++;\n else if (trimmed[i] === \"}\") {\n depth--;\n if (depth === 0) { braceEnd = i; break; }\n }\n }\n if (braceEnd === -1) return;\n\n // Split the brace content by commas (respecting nested braces)\n const inner = trimmed.slice(braceStart + 1, braceEnd).trim();\n const items = splitByTopLevelComma(inner);\n\n for (const item of items) {\n const cleaned = item.trim();\n if (cleaned === \"self\") {\n const selfPath = rootPrefix ? `${rootPrefix}::${fullPrefix}` : fullPrefix;\n results.push(selfPath);\n } else if (cleaned) {\n extractRustUsePaths(cleaned, fullPrefix, results, rootPrefix);\n }\n }\n}\n\n/** Split string by commas, respecting nested braces */\nfunction splitByTopLevelComma(s: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < s.length; i++) {\n if (s[i] === \"{\") depth++;\n else if (s[i] === \"}\") depth--;\n else if (s[i] === \",\" && depth === 0) {\n parts.push(s.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(s.slice(start));\n return parts;\n}\n\n// ─── Go ──────────────────────────────────────────────\nconst go: LanguageConfig = {\n id: \"go\",\n extensions: [\".go\"],\n commentStyle: \"c-style\",\n importPatterns: [], // handled by extractImports\n extractImports(content: string): string[] {\n const imports: string[] = [];\n\n // Single import: import \"path\" or import alias \"path\"\n const singleRegex = /\\bimport\\s+(?:\\w+\\s+)?\"([^\"]+)\"/gm;\n let match: RegExpExecArray | null;\n while ((match = singleRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n // Import block: import ( ... )\n const blockRegex = /\\bimport\\s*\\(([^)]*)\\)/gms;\n while ((match = blockRegex.exec(content)) !== null) {\n const block = match[1];\n const entryRegex = /(?:\\w+\\s+)?\"([^\"]+)\"/g;\n let entry: RegExpExecArray | null;\n while ((entry = entryRegex.exec(block)) !== null) {\n imports.push(entry[1]);\n }\n }\n\n return imports;\n },\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n // Only resolve project-internal imports\n // Read go.mod module path to strip prefix\n const modPrefix = goModulePrefix(rootDir);\n if (!modPrefix || !importPath.startsWith(modPrefix)) return null;\n\n const relPath = importPath.slice(modPrefix.length + 1); // +1 for /\n // Go packages are directories; find any .go file in the directory\n const pkgDir = join(rootDir, relPath);\n for (const f of projectFiles) {\n if (f.startsWith(pkgDir + \"/\") && f.endsWith(\".go\")) return f;\n }\n return null;\n },\n defaultExclude: [\"vendor\"],\n};\n\n// Bug #11: goModCache is a per-process cache of go.mod module prefixes, keyed by rootDir.\n// It is intentionally never cleared because the module path for a given rootDir does not\n// change during the lifetime of a single process. If a long-running process needs to pick\n// up go.mod changes, restart the process.\nconst goModCache = new Map<string, string | null>();\nfunction goModulePrefix(rootDir: string): string | null {\n if (goModCache.has(rootDir)) return goModCache.get(rootDir)!;\n try {\n const content = readFileSync(join(rootDir, \"go.mod\"), \"utf-8\");\n const match = content.match(/^module\\s+(.+)$/m);\n const prefix = match ? match[1].trim() : null;\n goModCache.set(rootDir, prefix);\n return prefix;\n } catch {\n goModCache.set(rootDir, null);\n return null;\n }\n}\n\n// ─── Java ────────────────────────────────────────────\nconst java: LanguageConfig = {\n id: \"java\",\n extensions: [\".java\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // Bug #5 fix: import com.example.ClassName; and import com.example.*; (wildcard)\n // Bug #6: static imports also captured here\n { regex: /^import\\s+(?:static\\s+)?([\\w.*]+);/gm },\n ],\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n // Bug #5 fix: wildcard imports — can't resolve to a single file, return null\n if (importPath.endsWith(\".*\")) {\n return null;\n }\n\n // Bug #6 fix: static imports — try progressively shorter paths\n // e.g. com.example.Class.method → try com/example/Class/method.java,\n // then com/example/Class.java, then com/example.java, etc.\n const segments = importPath.split(\".\");\n for (let i = segments.length; i > 0; i--) {\n const filePath = segments.slice(0, i).join(\"/\") + \".java\";\n for (const srcRoot of [\"\", \"src/main/java/\", \"src/\", \"app/src/main/java/\"]) {\n const full = join(rootDir, srcRoot, filePath);\n if (projectFiles.has(full)) return full;\n }\n }\n return null;\n },\n defaultExclude: [\"build\", \"target\", \"\\\\.gradle\", \"\\\\.idea\"],\n};\n\n// ─── C/C++ ───────────────────────────────────────────\nconst cCpp: LanguageConfig = {\n id: \"c-cpp\",\n extensions: [\".c\", \".cpp\", \".cc\", \".cxx\", \".h\", \".hpp\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // #include \"file.h\" (skip <system> includes)\n { regex: /^#include\\s+\"([^\"]+)\"/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Resolve relative to source file first\n const fromSource = resolve(dirname(sourceFile), importPath);\n if (projectFiles.has(fromSource)) return fromSource;\n // Then relative to root\n const fromRoot = join(rootDir, importPath);\n if (projectFiles.has(fromRoot)) return fromRoot;\n // Try common include dirs\n for (const incDir of [\"include\", \"src\"]) {\n const full = join(rootDir, incDir, importPath);\n if (projectFiles.has(full)) return full;\n }\n return null;\n },\n defaultExclude: [\"build\", \"cmake-build\", \"\\\\.o$\", \"\\\\.obj$\"],\n};\n\n// ─── Ruby ────────────────────────────────────────────\nconst ruby: LanguageConfig = {\n id: \"ruby\",\n extensions: [\".rb\"],\n commentStyle: \"ruby\",\n importPatterns: [\n // require_relative 'path'\n { regex: /\\brequire_relative\\s+['\"]([^'\"]+)['\"]/gm },\n // require 'path' (for project-internal requires)\n { regex: /\\brequire\\s+['\"]([^'\"]+)['\"]/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n const withExt = importPath.endsWith(\".rb\") ? importPath : importPath + \".rb\";\n // require_relative: relative to source\n const fromSource = resolve(dirname(sourceFile), withExt);\n if (projectFiles.has(fromSource)) return fromSource;\n // require: relative to root or lib/\n const fromRoot = join(rootDir, withExt);\n if (projectFiles.has(fromRoot)) return fromRoot;\n const fromLib = join(rootDir, \"lib\", withExt);\n if (projectFiles.has(fromLib)) return fromLib;\n return null;\n },\n defaultExclude: [\"vendor\", \"\\\\.bundle\"],\n};\n\n// ─── PHP ─────────────────────────────────────────────\nconst php: LanguageConfig = {\n id: \"php\",\n extensions: [\".php\"],\n commentStyle: \"php\",\n importPatterns: [\n // require/include/require_once/include_once 'path'\n { regex: /\\b(?:require|include)(?:_once)?\\s+['\"]([^'\"]+)['\"]/gm },\n // Bug #9 fix: use Namespace\\Class — skip `function` and `const` keywords\n { regex: /^use\\s+(?:function\\s+|const\\s+)?([\\w\\\\]+)/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Direct file path\n if (importPath.includes(\"/\") || importPath.endsWith(\".php\")) {\n const withExt = importPath.endsWith(\".php\") ? importPath : importPath + \".php\";\n const fromSource = resolve(dirname(sourceFile), withExt);\n if (projectFiles.has(fromSource)) return fromSource;\n const fromRoot = join(rootDir, withExt);\n if (projectFiles.has(fromRoot)) return fromRoot;\n return null;\n }\n // PSR-4: Namespace\\Class → Namespace/Class.php\n const filePath = importPath.replace(/\\\\/g, \"/\") + \".php\";\n const fromRoot = join(rootDir, filePath);\n if (projectFiles.has(fromRoot)) return fromRoot;\n const fromSrc = join(rootDir, \"src\", filePath);\n if (projectFiles.has(fromSrc)) return fromSrc;\n return null;\n },\n defaultExclude: [\"vendor\"],\n};\n\n// ─── Swift ───────────────────────────────────────────\nconst swift: LanguageConfig = {\n id: \"swift\",\n extensions: [\".swift\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // Bug #10 fix: import ModuleName and @testable import ModuleName\n { regex: /^(?:@testable\\s+)?import\\s+(?:class\\s+|struct\\s+|enum\\s+|protocol\\s+|func\\s+|var\\s+|let\\s+|typealias\\s+)?(\\w+)/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Cross-module: import Module → find Sources/Module/*.swift\n const spmDir = join(rootDir, \"Sources\", importPath);\n // Return the first .swift file in the target module directory\n for (const f of projectFiles) {\n if (f.startsWith(spmDir + \"/\") && f.endsWith(\".swift\")) return f;\n }\n return null;\n },\n defaultExclude: [\"\\\\.build\", \"DerivedData\"],\n};\n\n// ─── Kotlin ──────────────────────────────────────────\nconst kotlin: LanguageConfig = {\n id: \"kotlin\",\n extensions: [\".kt\", \".kts\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // Bug #7/#8 fix: import com.example.ClassName and import com.example.*\n { regex: /^import\\s+([\\w.*]+)/gm },\n ],\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n // Bug #8 fix: wildcard imports — can't resolve to a single file, return null\n if (importPath.endsWith(\".*\")) {\n return null;\n }\n\n // Bug #7 fix: strip trailing dot if present (from previous regex issues)\n let cleanPath = importPath;\n if (cleanPath.endsWith(\".\")) {\n cleanPath = cleanPath.slice(0, -1);\n }\n\n // Convert com.example.Class to com/example/Class.kt\n const filePath = cleanPath.replace(/\\./g, \"/\");\n for (const ext of [\".kt\", \".kts\"]) {\n for (const srcRoot of [\n \"\",\n \"src/main/kotlin/\",\n \"src/main/java/\",\n \"src/\",\n \"app/src/main/kotlin/\",\n \"app/src/main/java/\",\n ]) {\n const full = join(rootDir, srcRoot, filePath + ext);\n if (projectFiles.has(full)) return full;\n }\n }\n return null;\n },\n defaultExclude: [\"build\", \"\\\\.gradle\", \"\\\\.idea\"],\n};\n\n// ─── C# ──────────────────────────────────────────────\nconst cSharp: LanguageConfig = {\n id: \"c-sharp\",\n extensions: [\".cs\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // using Namespace; and using Namespace.SubNamespace;\n // using static Namespace.Class;\n // Skip: using Alias = Namespace.Class; (captured but resolved same way)\n { regex: /^using\\s+(?:static\\s+)?([\\w.]+)\\s*;/gm },\n ],\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n const segments = importPath.split(\".\");\n\n // 1. Try as direct file path (progressively shorter, like Java static imports)\n for (let i = segments.length; i > 0; i--) {\n const filePath = segments.slice(0, i).join(\"/\") + \".cs\";\n for (const srcRoot of [\"\", \"src/\", \"lib/\"]) {\n const full = join(rootDir, srcRoot, filePath);\n if (projectFiles.has(full)) return full;\n }\n }\n\n // 2. C# using = namespace import; try as directory, find first .cs file\n // Strip leading segments progressively (handles root namespace prefix)\n for (let start = 0; start < segments.length; start++) {\n const dirPath = segments.slice(start).join(\"/\");\n for (const srcRoot of [\"\", \"src/\", \"lib/\"]) {\n const prefix = join(rootDir, srcRoot, dirPath) + \"/\";\n for (const f of projectFiles) {\n if (f.startsWith(prefix) && f.endsWith(\".cs\")) return f;\n }\n }\n }\n\n return null;\n },\n defaultExclude: [\"bin\", \"obj\", \"\\\\.vs\", \"packages\", \"TestResults\"],\n};\n\n// ─── Dart ────────────────────────────────────────────\nconst dart: LanguageConfig = {\n id: \"dart\",\n extensions: [\".dart\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // import 'package:pkg/file.dart'; or import 'relative/path.dart';\n { regex: /^import\\s+['\"]([^'\"]+)['\"]/gm },\n // export 'file.dart'; (re-exports create dependencies too)\n { regex: /^export\\s+['\"]([^'\"]+)['\"]/gm },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Skip dart: stdlib imports\n if (importPath.startsWith(\"dart:\")) return null;\n\n // package: imports — resolve own package to lib/\n if (importPath.startsWith(\"package:\")) {\n const ownPackage = dartPackageName(rootDir);\n if (!ownPackage) return null;\n const prefix = `package:${ownPackage}/`;\n if (!importPath.startsWith(prefix)) return null; // external package\n const relPath = importPath.slice(prefix.length);\n const full = join(rootDir, \"lib\", relPath);\n if (projectFiles.has(full)) return full;\n return null;\n }\n\n // Relative imports\n const resolved = resolve(dirname(sourceFile), importPath);\n if (projectFiles.has(resolved)) return resolved;\n return null;\n },\n defaultExclude: [\"\\\\.dart_tool\", \"build\", \"\\\\.packages\"],\n};\n\nconst dartPackageCache = new Map<string, string | null>();\nfunction dartPackageName(rootDir: string): string | null {\n if (dartPackageCache.has(rootDir)) return dartPackageCache.get(rootDir)!;\n try {\n const content = readFileSync(join(rootDir, \"pubspec.yaml\"), \"utf-8\");\n const match = content.match(/^name:\\s*(\\S+)/m);\n const name = match ? match[1] : null;\n dartPackageCache.set(rootDir, name);\n return name;\n } catch {\n dartPackageCache.set(rootDir, null);\n return null;\n }\n}\n\n// ─── Scala ───────────────────────────────────────────\nconst scala: LanguageConfig = {\n id: \"scala\",\n extensions: [\".scala\", \".sc\"],\n commentStyle: \"c-style\",\n importPatterns: [], // handled by extractImports for grouped syntax\n extractImports(content: string): string[] {\n const imports: string[] = [];\n // import pkg.Class\n // import pkg.{A, B, C}\n // import pkg._ (wildcard)\n const importRegex = /\\bimport\\s+([\\w.]+(?:\\.\\{[^}]+\\}|\\.\\w+|\\._))/gm;\n let match: RegExpExecArray | null;\n while ((match = importRegex.exec(content)) !== null) {\n const full = match[1];\n // Check for grouped imports: import pkg.{A, B}\n const braceMatch = full.match(/^([\\w.]+)\\.\\{([^}]+)\\}$/);\n if (braceMatch) {\n const prefix = braceMatch[1];\n const items = braceMatch[2].split(\",\");\n for (const item of items) {\n const trimmed = item.trim().split(/\\s+/)[0]; // handle \"A => B\" rename\n if (trimmed === \"_\") continue; // wildcard in group\n imports.push(`${prefix}.${trimmed}`);\n }\n } else if (full.endsWith(\"._\")) {\n // Wildcard import — skip\n continue;\n } else {\n imports.push(full);\n }\n }\n return imports;\n },\n resolveImport(importPath, _sourceFile, rootDir, projectFiles) {\n const segments = importPath.split(\".\");\n // Try progressively shorter paths\n for (let i = segments.length; i > 0; i--) {\n const filePath = segments.slice(0, i).join(\"/\");\n for (const ext of [\".scala\", \".sc\"]) {\n for (const srcRoot of [\"\", \"src/main/scala/\", \"src/\", \"app/\"]) {\n const full = join(rootDir, srcRoot, filePath + ext);\n if (projectFiles.has(full)) return full;\n }\n }\n }\n return null;\n },\n defaultExclude: [\"target\", \"\\\\.bsp\", \"\\\\.metals\", \"\\\\.bloop\"],\n};\n\n// ─── JavaScript / TypeScript ──────────────────────────\nconst javascript: LanguageConfig = {\n id: \"javascript\",\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"],\n commentStyle: \"c-style\",\n importPatterns: [\n // ES6: import [type] [stuff from] \"path\"\n { regex: /import\\s+(?:type\\s+)?(?:[\\w*{}\\s,]+\\s+from\\s+)?[\"']([^\"']+)[\"']/g },\n // Dynamic: import(\"path\")\n { regex: /\\bimport\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g },\n // Re-export: export [type] { stuff } from \"path\" / export * from \"path\"\n { regex: /export\\s+(?:type\\s+)?(?:\\{[^}]*\\}|\\*(?:\\s+as\\s+\\w+)?)\\s+from\\s+[\"']([^\"']+)[\"']/g },\n // CommonJS: require(\"path\")\n { regex: /\\brequire\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g },\n ],\n resolveImport(importPath, sourceFile, rootDir, projectFiles) {\n // Skip external modules: node:, @scope/pkg, bare specifiers without ./ or ../\n if (importPath.startsWith(\"node:\")) return null;\n if (!importPath.startsWith(\".\")) return null;\n\n // Resolve relative to source file\n const resolved = resolve(dirname(sourceFile), importPath);\n\n // 1. Exact match (e.g., \"./foo.js\" where foo.js actually exists)\n if (projectFiles.has(resolved)) return resolved;\n\n // 2. ESM convention: .js → .ts / .tsx (TypeScript emits .js in import paths)\n if (resolved.endsWith(\".js\")) {\n const tsPath = resolved.slice(0, -3) + \".ts\";\n if (projectFiles.has(tsPath)) return tsPath;\n const tsxPath = resolved.slice(0, -3) + \".tsx\";\n if (projectFiles.has(tsxPath)) return tsxPath;\n }\n if (resolved.endsWith(\".jsx\")) {\n const tsxPath = resolved.slice(0, -4) + \".tsx\";\n if (projectFiles.has(tsxPath)) return tsxPath;\n }\n\n // 3. Try adding extensions\n for (const ext of [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"]) {\n if (projectFiles.has(resolved + ext)) return resolved + ext;\n }\n\n // 4. Try as directory with index file\n for (const idx of [\"/index.ts\", \"/index.tsx\", \"/index.js\", \"/index.jsx\"]) {\n if (projectFiles.has(resolved + idx)) return resolved + idx;\n }\n\n return null;\n },\n defaultExclude: [\"node_modules\", \"\\\\.d\\\\.ts$\", \"dist\", \"build\", \"coverage\"],\n};\n\n// ─── Registry ────────────────────────────────────────\nconst LANGUAGE_CONFIGS: Record<LanguageId, LanguageConfig | null> = {\n javascript,\n python,\n rust,\n go,\n java,\n \"c-cpp\": cCpp,\n \"c-sharp\": cSharp,\n ruby,\n php,\n swift,\n kotlin,\n dart,\n scala,\n};\n\nexport function getLanguageConfig(id: LanguageId): LanguageConfig | null {\n return LANGUAGE_CONFIGS[id] ?? null;\n}\n\nexport function getAllLanguageIds(): LanguageId[] {\n return [...LANGUAGE_IDS];\n}\n","import type { DependencyGraph } from \"../../types/schema.js\";\n\n/** Single source of truth for supported language IDs */\nexport const LANGUAGE_IDS = [\n \"javascript\",\n \"python\",\n \"rust\",\n \"go\",\n \"java\",\n \"c-cpp\",\n \"c-sharp\",\n \"ruby\",\n \"php\",\n \"swift\",\n \"kotlin\",\n \"dart\",\n \"scala\",\n] as const;\n\nexport type LanguageId = (typeof LANGUAGE_IDS)[number];\n\nexport interface AnalyzerEngine {\n analyze(\n rootDir: string,\n options: { exclude?: string[]; maxDepth?: number },\n ): Promise<DependencyGraph>;\n}\n\nexport interface ImportPattern {\n regex: RegExp;\n}\n\nexport type ImportResolver = (\n importPath: string,\n sourceFile: string,\n rootDir: string,\n projectFiles: Set<string>,\n) => string | null;\n\nexport type CommentStyle =\n | \"c-style\" // // and /* */\n | \"hash\" // #\n | \"python\" // # and \"\"\" / '''\n | \"ruby\" // # and =begin/=end\n | \"php\"; // //, /* */, and #\n\nexport interface LanguageConfig {\n id: LanguageId;\n extensions: string[];\n importPatterns: ImportPattern[];\n resolveImport: ImportResolver;\n commentStyle: CommentStyle;\n defaultExclude?: string[];\n /** Custom import extractor for languages with complex syntax (e.g. Rust grouped use) */\n extractImports?: (content: string) => string[];\n}\n","export type Locale = \"en\" | \"ja\";\n\nlet currentLocale: Locale = detectLocale();\n\n/** Get the current locale */\nexport function getLocale(): Locale {\n return currentLocale;\n}\n\n/** Set the locale explicitly */\nexport function setLocale(locale: Locale): void {\n currentLocale = locale;\n}\n\n/** Auto-detect locale from LANG/LC_ALL environment variable */\nfunction detectLocale(): Locale {\n const env = process.env.LC_ALL || process.env.LANG || \"\";\n if (env.startsWith(\"ja\")) return \"ja\";\n return \"en\";\n}\n\n/** Get a translated message by key */\nexport function t(key: string, vars?: Record<string, string | number>): string {\n const messages = currentLocale === \"ja\" ? ja : en;\n let msg = (messages as Record<string, string>)[key] ?? (en as Record<string, string>)[key] ?? key;\n\n if (vars) {\n for (const [k, v] of Object.entries(vars)) {\n msg = msg.replaceAll(`{${k}}`, String(v));\n }\n }\n return msg;\n}\n\n// ─── Message catalogs ───────────────────────────────────────────\n\nconst en = {\n // Analyzer\n \"analyzer.failed\": \"dependency-cruiser failed: {message}\",\n \"analyzer.exitCode\": \"Analysis finished with error code {code}\",\n\n // Storage\n \"storage.parseFailed\": \"Failed to parse snapshot.json. File may be corrupted: {path}\",\n \"storage.readFailed\": \"Failed to read snapshot.json: {path}\",\n \"storage.invalidSchema\": \"snapshot.json schema is invalid. Please regenerate with `archtracker init`:\\n{issues}\",\n \"storage.versionMismatch\": \"snapshot.json version ({version}) is incompatible with current schema ({expected}). Regenerate with `archtracker init`.\",\n\n // Path guard\n \"pathGuard.traversal\": \"Path points outside project root: \\\"{input}\\\" → \\\"{resolved}\\\" (allowed: \\\"{boundary}\\\")\",\n\n // Diff report\n \"diff.title\": \"# Architecture Change Report\\n\",\n \"diff.noChanges\": \"No changes — snapshot matches current code.\\n\",\n \"diff.added\": \"## Added Files ({count})\",\n \"diff.removed\": \"## Removed Files ({count})\",\n \"diff.modified\": \"## Modified Dependencies ({count})\",\n \"diff.affected\": \"## Files Requiring Review ({count})\",\n \"diff.reasonRemoved\": \"Dependency \\\"{file}\\\" was removed\",\n \"diff.reasonModified\": \"Dependency \\\"{file}\\\" had its dependencies changed\",\n \"diff.reasonAdded\": \"New dependency \\\"{file}\\\" was added\",\n\n // Search\n \"search.pathMatch\": \"Path matches \\\"{pattern}\\\"\",\n \"search.affected\": \"May be affected by changes to \\\"{file}\\\" (via: {via})\",\n \"search.critical\": \"{count} files depend on this component\",\n \"search.orphan\": \"Orphan file (no dependencies, no dependents)\",\n \"search.noResults\": \"No results: \\\"{query}\\\" (mode: {mode})\",\n \"search.results\": \"Results: {count} (mode: {mode})\",\n\n // CLI\n \"cli.analyzing\": \"Analyzing...\",\n \"cli.snapshotSaved\": \"Snapshot saved\",\n \"cli.timestamp\": \" Timestamp: {ts}\",\n \"cli.fileCount\": \" Files: {count}\",\n \"cli.edgeCount\": \" Edges: {count}\",\n \"cli.circularCount\": \" Circular deps: {count}\",\n \"cli.keyComponents\": \"\\nKey components:\",\n \"cli.dependedBy\": \"{path} ({count} dependents)\",\n \"cli.noSnapshot\": \"No snapshot found. Run `archtracker init` first.\",\n \"cli.ciFailed\": \"\\nCI check failed: {count} file(s) require review\",\n \"cli.autoGenerating\": \"No snapshot found, auto-generating...\",\n \"cli.project\": \"Project: {path}\",\n \"cli.validPaths\": \"\\nValid file paths:\",\n \"cli.snapshot\": \"Snapshot: {ts}\",\n\n // MCP\n \"mcp.analyzeComplete\": \"Analysis complete: {files} files, {edges} edges\",\n \"mcp.circularFound\": \"Circular deps: {count} found\",\n \"mcp.circularNone\": \"Circular deps: none\",\n \"mcp.snapshotSaved\": \"Snapshot saved\",\n \"mcp.autoInit\": \"No snapshot existed. Initial snapshot auto-generated.\",\n \"mcp.nextCheckEnabled\": \"Diff checking will be active from the next run.\",\n \"mcp.queryRequired\": \"\\\"{mode}\\\" mode requires the query parameter\",\n\n // Analyze report\n \"analyze.title\": \"# Architecture Analysis Report\\n\",\n \"analyze.overview\": \"## Overview\",\n \"analyze.totalFiles\": \" Total files: {count}\",\n \"analyze.totalEdges\": \" Total edges: {count}\",\n \"analyze.totalCircular\": \" Circular dependencies: {count}\",\n \"analyze.criticalTitle\": \"\\n## Critical Components (Top {count})\",\n \"analyze.criticalItem\": \" {path} ({count} dependents)\",\n \"analyze.circularTitle\": \"\\n## Circular Dependencies ({count})\",\n \"analyze.circularItem\": \" {files}\",\n \"analyze.orphanTitle\": \"\\n## Orphan Files ({count})\",\n \"analyze.couplingTitle\": \"\\n## High Coupling (Top {count} by import count)\",\n \"analyze.couplingItem\": \" {path} ({count} imports)\",\n \"analyze.layerTitle\": \"\\n## Directory Breakdown\",\n \"analyze.layerItem\": \" {dir}/ — {count} files\",\n \"analyze.noIssues\": \"\\nNo architectural issues detected.\",\n \"analyze.snapshotSaved\": \"\\nSnapshot saved alongside analysis.\",\n\n // CI\n \"ci.generated\": \"GitHub Actions workflow generated: {path}\",\n\n // Web viewer\n \"web.starting\": \"Starting architecture viewer...\",\n \"web.listening\": \"Architecture graph available at: http://localhost:{port}\",\n \"web.stop\": \"Press Ctrl+C to stop\",\n \"web.watching\": \"Watching {dir}/ for changes...\",\n \"web.reloading\": \"File change detected, reloading...\",\n \"web.reloaded\": \"Graph reloaded\",\n\n // Errors\n \"error.analyzer\": \"[Analysis Error] {message}\",\n \"error.storage\": \"[Storage Error] {message}\",\n \"error.pathTraversal\": \"[Security Error] {message}\",\n \"error.generic\": \"[Error] {message}\",\n \"error.unexpected\": \"[Error] Unexpected error: {message}\",\n \"error.cli.analyzer\": \"Analysis error: {message}\",\n \"error.cli.storage\": \"Storage error: {message}\",\n \"error.cli.generic\": \"Error: {message}\",\n \"error.cli.unexpected\": \"Unexpected error: {message}\",\n} as const;\n\nconst ja = {\n // Analyzer\n \"analyzer.failed\": \"dependency-cruiser の実行に失敗しました: {message}\",\n \"analyzer.exitCode\": \"解析がエラーコード {code} で終了しました\",\n\n // Storage\n \"storage.parseFailed\": \"snapshot.json のパースに失敗しました。ファイルが破損している可能性があります: {path}\",\n \"storage.readFailed\": \"snapshot.json の読み取りに失敗しました: {path}\",\n \"storage.invalidSchema\": \"snapshot.json のスキーマが不正です。archtracker init で再生成してください:\\n{issues}\",\n \"storage.versionMismatch\": \"snapshot.json のバージョン ({version}) が現在のスキーマ ({expected}) と互換性がありません。archtracker init で再生成してください。\",\n\n // Path guard\n \"pathGuard.traversal\": \"パスがプロジェクトルートの外部を指しています: \\\"{input}\\\" → \\\"{resolved}\\\" (許可範囲: \\\"{boundary}\\\")\",\n\n // Diff report\n \"diff.title\": \"# アーキテクチャ変更レポート\\n\",\n \"diff.noChanges\": \"変更なし — スナップショットと現在のコードは一致しています。\\n\",\n \"diff.added\": \"## 追加されたファイル ({count}件)\",\n \"diff.removed\": \"## 削除されたファイル ({count}件)\",\n \"diff.modified\": \"## 依存関係が変更されたファイル ({count}件)\",\n \"diff.affected\": \"## 確認が必要なファイル ({count}件)\",\n \"diff.reasonRemoved\": \"依存先 \\\"{file}\\\" が削除されました\",\n \"diff.reasonModified\": \"依存先 \\\"{file}\\\" の依存関係が変更されました\",\n \"diff.reasonAdded\": \"新しい依存先 \\\"{file}\\\" が追加されました\",\n\n // Search\n \"search.pathMatch\": \"パスが \\\"{pattern}\\\" にマッチ\",\n \"search.affected\": \"\\\"{file}\\\" の変更により影響を受ける可能性(経由: {via})\",\n \"search.critical\": \"{count}件のファイルが依存する重要コンポーネント\",\n \"search.orphan\": \"孤立ファイル(依存なし・被依存なし)\",\n \"search.noResults\": \"検索結果なし: \\\"{query}\\\" (モード: {mode})\",\n \"search.results\": \"検索結果: {count}件 (モード: {mode})\",\n\n // CLI\n \"cli.analyzing\": \"解析中...\",\n \"cli.snapshotSaved\": \"スナップショットを保存しました\",\n \"cli.timestamp\": \" タイムスタンプ: {ts}\",\n \"cli.fileCount\": \" ファイル数: {count}\",\n \"cli.edgeCount\": \" エッジ数: {count}\",\n \"cli.circularCount\": \" 循環参照: {count}件\",\n \"cli.keyComponents\": \"\\n主要コンポーネント:\",\n \"cli.dependedBy\": \"{path} ({count}件が依存)\",\n \"cli.noSnapshot\": \"スナップショットが見つかりません。`archtracker init` を先に実行してください。\",\n \"cli.ciFailed\": \"\\nCI チェック失敗: {count}件の要確認ファイルがあります\",\n \"cli.autoGenerating\": \"スナップショットが無いため自動生成します...\",\n \"cli.project\": \"プロジェクト: {path}\",\n \"cli.validPaths\": \"\\n有効なファイルパス:\",\n \"cli.snapshot\": \"スナップショット: {ts}\",\n\n // MCP\n \"mcp.analyzeComplete\": \"解析完了: {files}ファイル, {edges}エッジ\",\n \"mcp.circularFound\": \"循環参照: {count}件検出\",\n \"mcp.circularNone\": \"循環参照: なし\",\n \"mcp.snapshotSaved\": \"スナップショットを保存しました\",\n \"mcp.autoInit\": \"スナップショットが存在しなかったため、初期スナップショットを自動生成しました。\",\n \"mcp.nextCheckEnabled\": \"次回の実行時から差分チェックが有効になります。\",\n \"mcp.queryRequired\": \"\\\"{mode}\\\" モードでは query パラメータが必須です\",\n\n // Analyze report\n \"analyze.title\": \"# アーキテクチャ分析レポート\\n\",\n \"analyze.overview\": \"## 概要\",\n \"analyze.totalFiles\": \" 総ファイル数: {count}\",\n \"analyze.totalEdges\": \" 総エッジ数: {count}\",\n \"analyze.totalCircular\": \" 循環参照: {count}件\",\n \"analyze.criticalTitle\": \"\\n## 重要コンポーネント (上位{count}件)\",\n \"analyze.criticalItem\": \" {path} ({count}件が依存)\",\n \"analyze.circularTitle\": \"\\n## 循環参照 ({count}件)\",\n \"analyze.circularItem\": \" {files}\",\n \"analyze.orphanTitle\": \"\\n## 孤立ファイル ({count}件)\",\n \"analyze.couplingTitle\": \"\\n## 高結合ファイル (import数 上位{count}件)\",\n \"analyze.couplingItem\": \" {path} ({count}件をimport)\",\n \"analyze.layerTitle\": \"\\n## ディレクトリ構成\",\n \"analyze.layerItem\": \" {dir}/ — {count}ファイル\",\n \"analyze.noIssues\": \"\\nアーキテクチャ上の問題は検出されませんでした。\",\n \"analyze.snapshotSaved\": \"\\n分析と同時にスナップショットを保存しました。\",\n\n // CI\n \"ci.generated\": \"GitHub Actions ワークフローを生成しました: {path}\",\n\n // Web viewer\n \"web.starting\": \"アーキテクチャビューアーを起動中...\",\n \"web.listening\": \"アーキテクチャグラフ: http://localhost:{port}\",\n \"web.stop\": \"Ctrl+C で停止\",\n \"web.watching\": \"{dir}/ を監視中...\",\n \"web.reloading\": \"ファイル変更を検出、リロード中...\",\n \"web.reloaded\": \"グラフを更新しました\",\n\n // Errors\n \"error.analyzer\": \"[解析エラー] {message}\",\n \"error.storage\": \"[ストレージエラー] {message}\",\n \"error.pathTraversal\": \"[セキュリティエラー] {message}\",\n \"error.generic\": \"[エラー] {message}\",\n \"error.unexpected\": \"[エラー] 予期しないエラーが発生しました: {message}\",\n \"error.cli.analyzer\": \"解析エラー: {message}\",\n \"error.cli.storage\": \"ストレージエラー: {message}\",\n \"error.cli.generic\": \"エラー: {message}\",\n \"error.cli.unexpected\": \"予期しないエラー: {message}\",\n} as const;\n","import type { DependencyGraph, FileNode } from \"../types/schema.js\";\nimport { t } from \"../i18n/index.js\";\n\n/** Search result for architecture queries */\nexport interface SearchResult {\n file: string;\n dependents: string[];\n dependencies: string[];\n dependentCount: number;\n dependencyCount: number;\n matchReason: string;\n}\n\n/**\n * Search the dependency graph by file path pattern.\n * Pattern is treated as a literal substring (escaped to prevent ReDoS).\n */\nexport function searchByPath(\n graph: DependencyGraph,\n pattern: string,\n): SearchResult[] {\n const escaped = pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regex = new RegExp(escaped, \"i\");\n return Object.values(graph.files)\n .filter((f) => regex.test(f.path))\n .map((f) => toSearchResult(f, t(\"search.pathMatch\", { pattern })));\n}\n\n/**\n * Find all files that would be affected if a given file changes.\n * Traverses the dependent chain recursively (reverse dependency tree).\n */\nexport function findAffectedFiles(\n graph: DependencyGraph,\n filePath: string,\n maxDepth: number = 10,\n): SearchResult[] {\n const node = findNode(graph, filePath);\n if (!node) return [];\n\n const visited = new Set<string>();\n const results: SearchResult[] = [];\n\n function traverse(current: FileNode, depth: number, via: string) {\n if (depth > maxDepth || visited.has(current.path)) return;\n visited.add(current.path);\n\n if (current.path !== node!.path) {\n results.push(\n toSearchResult(\n current,\n t(\"search.affected\", { file: filePath, via }),\n ),\n );\n }\n\n for (const depPath of current.dependents) {\n const depNode = graph.files[depPath];\n if (depNode) {\n traverse(depNode, depth + 1, current.path);\n }\n }\n }\n\n traverse(node, 0, filePath);\n return results;\n}\n\n/**\n * Find the most critical files in the project.\n * Ranked by dependent count (files that many other files depend on).\n */\nexport function findCriticalFiles(\n graph: DependencyGraph,\n limit: number = 10,\n): SearchResult[] {\n return Object.values(graph.files)\n .filter((f) => f.dependents.length > 0)\n .sort((a, b) => b.dependents.length - a.dependents.length)\n .slice(0, limit)\n .map((f) =>\n toSearchResult(f, t(\"search.critical\", { count: f.dependents.length })),\n );\n}\n\n/**\n * Find orphan files (no dependencies and no dependents).\n */\nexport function findOrphanFiles(graph: DependencyGraph): SearchResult[] {\n return Object.values(graph.files)\n .filter((f) => f.dependents.length === 0 && f.dependencies.length === 0)\n .map((f) => toSearchResult(f, t(\"search.orphan\")));\n}\n\n/** Find a node by exact or partial path match */\nfunction findNode(\n graph: DependencyGraph,\n filePath: string,\n): FileNode | undefined {\n // Exact match\n if (graph.files[filePath]) return graph.files[filePath];\n\n // Partial match (find first file ending with the pattern)\n const key = Object.keys(graph.files).find(\n (k) => k.endsWith(filePath) || k.includes(filePath),\n );\n return key ? graph.files[key] : undefined;\n}\n\nfunction toSearchResult(node: FileNode, matchReason: string): SearchResult {\n return {\n file: node.path,\n dependents: node.dependents,\n dependencies: node.dependencies,\n dependentCount: node.dependents.length,\n dependencyCount: node.dependencies.length,\n matchReason,\n };\n}\n","import type { DependencyGraph } from \"../types/schema.js\";\nimport { t } from \"../i18n/index.js\";\n\n/**\n * Generate a comprehensive architecture analysis report.\n *\n * Designed for onboarding into existing projects — provides\n * a full overview of dependencies, critical components, circular\n * references, orphan files, coupling hotspots, and directory breakdown.\n */\nexport function formatAnalysisReport(\n graph: DependencyGraph,\n options: { topN?: number } = {},\n): string {\n const topN = options.topN ?? 10;\n const lines: string[] = [];\n const files = Object.values(graph.files);\n\n // ─── Overview ────────────────────────────────────────────\n lines.push(t(\"analyze.title\"));\n lines.push(t(\"analyze.overview\"));\n lines.push(t(\"analyze.totalFiles\", { count: graph.totalFiles }));\n lines.push(t(\"analyze.totalEdges\", { count: graph.totalEdges }));\n lines.push(t(\"analyze.totalCircular\", { count: graph.circularDependencies.length }));\n\n // ─── Critical Components ─────────────────────────────────\n const critical = files\n .filter((f) => f.dependents.length > 0)\n .sort((a, b) => b.dependents.length - a.dependents.length)\n .slice(0, topN);\n\n if (critical.length > 0) {\n lines.push(t(\"analyze.criticalTitle\", { count: critical.length }));\n for (const f of critical) {\n lines.push(t(\"analyze.criticalItem\", { path: f.path, count: f.dependents.length }));\n }\n }\n\n // ─── Circular Dependencies ──────────────────────────────\n if (graph.circularDependencies.length > 0) {\n lines.push(t(\"analyze.circularTitle\", { count: graph.circularDependencies.length }));\n for (const c of graph.circularDependencies) {\n lines.push(t(\"analyze.circularItem\", { files: c.cycle.join(\" → \") }));\n }\n }\n\n // ─── High Coupling (most imports) ───────────────────────\n const highCoupling = files\n .filter((f) => f.dependencies.length > 0)\n .sort((a, b) => b.dependencies.length - a.dependencies.length)\n .slice(0, topN);\n\n if (highCoupling.length > 0) {\n lines.push(t(\"analyze.couplingTitle\", { count: highCoupling.length }));\n for (const f of highCoupling) {\n lines.push(t(\"analyze.couplingItem\", { path: f.path, count: f.dependencies.length }));\n }\n }\n\n // ─── Orphan Files ───────────────────────────────────────\n const orphans = files.filter(\n (f) => f.dependents.length === 0 && f.dependencies.length === 0,\n );\n\n if (orphans.length > 0) {\n lines.push(t(\"analyze.orphanTitle\", { count: orphans.length }));\n for (const f of orphans) {\n lines.push(` ${f.path}`);\n }\n }\n\n // ─── Directory Breakdown ────────────────────────────────\n const dirCounts = new Map<string, number>();\n for (const f of files) {\n const dir = f.path.includes(\"/\") ? f.path.substring(0, f.path.lastIndexOf(\"/\")) : \".\";\n dirCounts.set(dir, (dirCounts.get(dir) ?? 0) + 1);\n }\n\n if (dirCounts.size > 1) {\n lines.push(t(\"analyze.layerTitle\"));\n const sorted = [...dirCounts.entries()].sort((a, b) => b[1] - a[1]);\n for (const [dir, count] of sorted) {\n lines.push(t(\"analyze.layerItem\", { dir, count }));\n }\n }\n\n // ─── Summary ────────────────────────────────────────────\n if (graph.circularDependencies.length === 0 && orphans.length === 0) {\n lines.push(t(\"analyze.noIssues\"));\n }\n\n return lines.join(\"\\n\");\n}\n","import { mkdir, writeFile, readFile, access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport type { ArchSnapshot } from \"../types/schema.js\";\nimport { SCHEMA_VERSION } from \"../types/schema.js\";\nimport type { DependencyGraph } from \"../types/schema.js\";\nimport { t } from \"../i18n/index.js\";\n\nconst ARCHTRACKER_DIR = \".archtracker\";\nconst SNAPSHOT_FILE = \"snapshot.json\";\n\n/** Zod schema for runtime validation of loaded snapshots */\nconst FileNodeSchema = z.object({\n path: z.string(),\n exists: z.boolean(),\n dependencies: z.array(z.string()),\n dependents: z.array(z.string()),\n});\n\nconst DependencyGraphSchema = z.object({\n rootDir: z.string(),\n files: z.record(z.string(), FileNodeSchema),\n edges: z.array(z.object({\n source: z.string(),\n target: z.string(),\n type: z.enum([\"static\", \"dynamic\", \"type-only\"]),\n })),\n circularDependencies: z.array(z.object({ cycle: z.array(z.string()) })),\n totalFiles: z.number(),\n totalEdges: z.number(),\n});\n\nconst SnapshotSchema = z.object({\n version: z.literal(SCHEMA_VERSION),\n timestamp: z.string(),\n rootDir: z.string(),\n graph: DependencyGraphSchema,\n});\n\n/**\n * Save a dependency graph as a versioned snapshot.\n *\n * Creates .archtracker/ directory if it doesn't exist.\n * Writes snapshot.json with schema version and timestamp.\n */\nexport async function saveSnapshot(\n projectRoot: string,\n graph: DependencyGraph,\n): Promise<ArchSnapshot> {\n const dirPath = join(projectRoot, ARCHTRACKER_DIR);\n const filePath = join(dirPath, SNAPSHOT_FILE);\n\n const snapshot: ArchSnapshot = {\n version: SCHEMA_VERSION,\n timestamp: new Date().toISOString(),\n rootDir: graph.rootDir,\n graph,\n };\n\n await mkdir(dirPath, { recursive: true });\n await writeFile(filePath, JSON.stringify(snapshot, null, 2), \"utf-8\");\n\n return snapshot;\n}\n\n/**\n * Load the most recent snapshot from .archtracker/snapshot.json.\n *\n * Returns null if no snapshot exists.\n * Validates schema structure with Zod for data integrity.\n */\nexport async function loadSnapshot(\n projectRoot: string,\n): Promise<ArchSnapshot | null> {\n const filePath = join(projectRoot, ARCHTRACKER_DIR, SNAPSHOT_FILE);\n\n // Read file directly — no TOCTOU race with access() check\n let raw: string;\n try {\n raw = await readFile(filePath, \"utf-8\");\n } catch (error: unknown) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n return null;\n }\n throw new StorageError(\n t(\"storage.readFailed\", { path: filePath }),\n { cause: error },\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new StorageError(\n t(\"storage.parseFailed\", { path: filePath }),\n );\n }\n\n // Validate structure with Zod\n const result = SnapshotSchema.safeParse(parsed);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` ${i.path.join(\".\")}: ${i.message}`)\n .slice(0, 5)\n .join(\"\\n\");\n throw new StorageError(\n t(\"storage.invalidSchema\", { issues }),\n );\n }\n\n return result.data as ArchSnapshot;\n}\n\n/** Check if .archtracker directory exists */\nexport async function hasArchtrackerDir(\n projectRoot: string,\n): Promise<boolean> {\n try {\n await access(join(projectRoot, ARCHTRACKER_DIR));\n return true;\n } catch {\n return false;\n }\n}\n\n/** Custom error class for storage failures */\nexport class StorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"StorageError\";\n }\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n","/**\n * ArchTracker core schema definitions.\n * Snapshot format is versioned for backward compatibility.\n */\n\nexport const SCHEMA_VERSION = \"1.0\" as const;\n\n/** A single dependency edge: source imports target */\nexport interface DependencyEdge {\n source: string;\n target: string;\n type: \"static\" | \"dynamic\" | \"type-only\";\n}\n\n/** A file node in the architecture graph */\nexport interface FileNode {\n path: string;\n exists: boolean;\n dependencies: string[];\n dependents: string[];\n}\n\n/** A detected circular dependency */\nexport interface CircularDependency {\n cycle: string[];\n}\n\n/** The full dependency graph */\nexport interface DependencyGraph {\n rootDir: string;\n files: Record<string, FileNode>;\n edges: DependencyEdge[];\n circularDependencies: CircularDependency[];\n totalFiles: number;\n totalEdges: number;\n}\n\n/** Persisted snapshot with schema version */\nexport interface ArchSnapshot {\n version: typeof SCHEMA_VERSION;\n timestamp: string;\n rootDir: string;\n graph: DependencyGraph;\n}\n\n/** Diff result between two snapshots */\nexport interface ArchDiff {\n added: string[];\n removed: string[];\n modified: string[];\n affectedDependents: Array<{\n file: string;\n reason: string;\n dependsOn: string;\n }>;\n}\n\n/** Context summary for AI session initialization */\nexport interface ArchContext {\n validPaths: string[];\n summary: string;\n snapshotExists: boolean;\n snapshotTimestamp?: string;\n keyComponents: Array<{\n path: string;\n dependentCount: number;\n dependencyCount: number;\n }>;\n}\n","import type { ArchDiff, DependencyGraph } from \"../types/schema.js\";\nimport { t } from \"../i18n/index.js\";\n\n/**\n * Compute the diff between an old and new dependency graph.\n *\n * Identifies:\n * - Added files (new in the codebase)\n * - Removed files (deleted from the codebase)\n * - Modified files (dependencies changed)\n * - Affected dependents (files that depend on changed/removed files and may need updates)\n */\nexport function computeDiff(\n oldGraph: DependencyGraph,\n newGraph: DependencyGraph,\n): ArchDiff {\n const oldFiles = new Set(Object.keys(oldGraph.files));\n const newFiles = new Set(Object.keys(newGraph.files));\n\n // Files that exist in new but not in old\n const added = [...newFiles].filter((f) => !oldFiles.has(f));\n\n // Files that existed in old but not in new\n const removed = [...oldFiles].filter((f) => !newFiles.has(f));\n\n // Files that exist in both but have different dependency sets\n const modified: string[] = [];\n for (const file of newFiles) {\n if (!oldFiles.has(file)) continue;\n\n const oldDeps = oldGraph.files[file].dependencies.slice().sort();\n const newDeps = newGraph.files[file].dependencies.slice().sort();\n\n if (!arraysEqual(oldDeps, newDeps)) {\n modified.push(file);\n }\n }\n\n // Find all files that depend on changed/removed files\n const removedSet = new Set(removed);\n const changedFiles = new Set([...removed, ...modified]);\n const affectedDependents: ArchDiff[\"affectedDependents\"] = [];\n const seenAffected = new Set<string>();\n\n for (const changedFile of changedFiles) {\n // Look up dependents in the NEW graph (for modified files)\n // and in the OLD graph (for removed files)\n const graph = removedSet.has(changedFile) ? oldGraph : newGraph;\n const node = graph.files[changedFile];\n if (!node) continue;\n\n for (const dependent of node.dependents) {\n const key = `${dependent}→${changedFile}`;\n if (seenAffected.has(key)) continue;\n seenAffected.add(key);\n\n const reason = removedSet.has(changedFile)\n ? t(\"diff.reasonRemoved\", { file: changedFile })\n : t(\"diff.reasonModified\", { file: changedFile });\n\n affectedDependents.push({\n file: dependent,\n reason,\n dependsOn: changedFile,\n });\n }\n }\n\n // Also check for files that depend on added files\n // (new dependencies that might need verification)\n for (const addedFile of added) {\n const node = newGraph.files[addedFile];\n if (!node) continue;\n\n for (const dependent of node.dependents) {\n const key = `${dependent}→${addedFile}`;\n if (seenAffected.has(key)) continue;\n seenAffected.add(key);\n\n affectedDependents.push({\n file: dependent,\n reason: t(\"diff.reasonAdded\", { file: addedFile }),\n dependsOn: addedFile,\n });\n }\n }\n\n return { added, removed, modified, affectedDependents };\n}\n\n/** Generate a human-readable report from an ArchDiff */\nexport function formatDiffReport(diff: ArchDiff): string {\n const lines: string[] = [];\n\n lines.push(t(\"diff.title\"));\n\n if (diff.added.length === 0 && diff.removed.length === 0 && diff.modified.length === 0) {\n lines.push(t(\"diff.noChanges\"));\n return lines.join(\"\\n\");\n }\n\n if (diff.added.length > 0) {\n lines.push(t(\"diff.added\", { count: diff.added.length }));\n for (const f of diff.added) {\n lines.push(` + ${f}`);\n }\n lines.push(\"\");\n }\n\n if (diff.removed.length > 0) {\n lines.push(t(\"diff.removed\", { count: diff.removed.length }));\n for (const f of diff.removed) {\n lines.push(` - ${f}`);\n }\n lines.push(\"\");\n }\n\n if (diff.modified.length > 0) {\n lines.push(t(\"diff.modified\", { count: diff.modified.length }));\n for (const f of diff.modified) {\n lines.push(` ~ ${f}`);\n }\n lines.push(\"\");\n }\n\n if (diff.affectedDependents.length > 0) {\n lines.push(t(\"diff.affected\", { count: diff.affectedDependents.length }));\n for (const a of diff.affectedDependents) {\n lines.push(` ! ${a.file}`);\n lines.push(` ${a.reason}`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n","import { resolve } from \"node:path\";\nimport { t } from \"../i18n/index.js\";\n\n/**\n * Validate that a path resolves within the allowed boundary (CWD by default).\n * Prevents path traversal attacks via ../../../etc/passwd style inputs.\n */\nexport function validatePath(\n inputPath: string,\n boundary?: string,\n): string {\n const resolved = resolve(inputPath);\n const root = boundary ? resolve(boundary) : process.cwd();\n\n if (!resolved.startsWith(root)) {\n throw new PathTraversalError(\n t(\"pathGuard.traversal\", { input: inputPath, resolved, boundary: root }),\n );\n }\n return resolved;\n}\n\nexport class PathTraversalError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PathTraversalError\";\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/** Read version from package.json at build/runtime — single source of truth */\nfunction loadVersion(): string {\n // Walk up from this file to find package.json\n let dir = dirname(fileURLToPath(import.meta.url));\n for (let i = 0; i < 5; i++) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, \"package.json\"), \"utf-8\"));\n return pkg.version;\n } catch {\n dir = dirname(dir);\n }\n }\n return \"0.0.0\";\n}\n\nexport const VERSION = loadVersion();\n"],"mappings":"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","names":["z","resolve","stat","readdir","stat","join","join","resolve","join","segments","resolve","fromRoot","resolve","stat","readFile","join","join","readFile","resolve","resolve","readFileSync","join","dirname","z","graph"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archtracker-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Architecture & Dependency Tracker — MCP server + CLI + interactive web viewer for AI-driven development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,7 +15,8 @@
15
15
  }
16
16
  },
17
17
  "bin": {
18
- "archtracker": "dist/cli/index.js"
18
+ "archtracker": "dist/cli/index.js",
19
+ "archtracker-mcp": "dist/bin.js"
19
20
  },
20
21
  "files": [
21
22
  "dist",