@dreamtree-org/graphify 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/detect.ts","../src/extract.ts","../src/extractors/csharp.ts","../src/extractors/common.ts","../src/extractors/wasmLoader.ts","../src/extractors/go.ts","../src/extractors/java.ts","../src/extractors/python.ts","../src/extractors/ruby.ts","../src/extractors/rust.ts","../src/extractors/typescript.ts","../src/schema.ts","../src/build.ts","../src/resolve.ts","../src/cluster.ts","../src/analyze.ts","../src/report.ts","../src/export.ts","../src/extractionCache.ts","../src/pipeline.ts","../src/merge.ts","../src/memory.ts","../src/diff.ts","../src/check.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { FileCategory, FileManifest } from './types.js';\n\n/** Directories that are never worth walking into. */\nconst SKIP_DIRS = new Set([\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'out',\n 'graphify-out',\n '.next',\n '.venv',\n 'venv',\n '__pycache__',\n '.cache',\n 'coverage',\n '.turbo',\n]);\n\nconst CODE_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.mts',\n '.cts',\n '.py',\n '.go',\n '.rs',\n '.java',\n '.cs',\n '.rb',\n '.c',\n '.h',\n '.cpp',\n '.hpp',\n '.cc',\n '.php',\n '.kt',\n '.swift',\n '.scala',\n '.lua',\n '.sh',\n '.sql',\n]);\n\nconst DOCUMENT_EXTENSIONS = new Set(['.md', '.mdx', '.txt', '.rst', '.adoc', '.org', '.json', '.yaml', '.yml', '.toml']);\n\nconst PAPER_EXTENSIONS = new Set(['.pdf', '.tex', '.bib']);\n\nconst IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.bmp', '.ico']);\n\nconst VIDEO_EXTENSIONS = new Set(['.mp4', '.mov', '.avi', '.mkv', '.webm']);\n\n/**\n * Filenames or name fragments that must never be read into the graph or an\n * LLM prompt — credentials, secrets, key material. Skipped into\n * `skippedSensitive` rather than silently ignored, so a run's manifest is\n * auditable.\n */\nconst SENSITIVE_NAME_PATTERNS: RegExp[] = [\n /^\\.env(\\..*)?$/i,\n /^\\.npmrc$/i,\n /^\\.pypirc$/i,\n /credentials/i,\n /secret/i,\n /^id_rsa$/i,\n /^id_ed25519$/i,\n /\\.pem$/i,\n /\\.key$/i,\n /\\.pfx$/i,\n /\\.p12$/i,\n /^\\.aws\\//i,\n /service[-_]?account.*\\.json$/i,\n];\n\nfunction isSensitiveName(name: string): boolean {\n return SENSITIVE_NAME_PATTERNS.some((pattern) => pattern.test(name));\n}\n\nfunction categorize(ext: string): FileCategory | null {\n const lower = ext.toLowerCase();\n if (CODE_EXTENSIONS.has(lower)) return 'code';\n if (DOCUMENT_EXTENSIONS.has(lower)) return 'document';\n if (PAPER_EXTENSIONS.has(lower)) return 'paper';\n if (IMAGE_EXTENSIONS.has(lower)) return 'image';\n if (VIDEO_EXTENSIONS.has(lower)) return 'video';\n return null;\n}\n\nfunction countWords(content: string): number {\n const trimmed = content.trim();\n if (trimmed.length === 0) return 0;\n return trimmed.split(/\\s+/).length;\n}\n\n/** Decode a file's bytes as UTF-8 with a replacement strategy — never throw on invalid bytes. */\nfunction readTextSafely(filePath: string): string {\n const buf = fs.readFileSync(filePath);\n return buf.toString('utf-8');\n}\n\n/**\n * Walk `root` and categorize files into code/document/paper/image/video\n * buckets. Does not follow symlinks (security.ts §5 — symlink traversal).\n * Sensitive-looking files (.env, credentials, key material) are recorded in\n * `skippedSensitive` and excluded from every other bucket/count.\n */\nexport function collectFiles(root: string): FileManifest {\n const scanRoot = path.resolve(root);\n const stat = fs.statSync(scanRoot);\n if (!stat.isDirectory()) {\n throw new Error(`collectFiles: not a directory: ${scanRoot}`);\n }\n\n const files: Record<FileCategory, string[]> = {\n code: [],\n document: [],\n paper: [],\n image: [],\n video: [],\n };\n const skippedSensitive: string[] = [];\n let totalWords = 0;\n\n const stack: string[] = [scanRoot];\n const textCategories: Set<FileCategory> = new Set(['code', 'document', 'paper']);\n\n while (stack.length > 0) {\n const dir = stack.pop() as string;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n continue; // unreadable directory (permissions) — skip, don't crash the run\n }\n\n // Sort for deterministic traversal order.\n entries.sort((a, b) => a.name.localeCompare(b.name));\n\n for (const entry of entries) {\n if (entry.isSymbolicLink()) continue; // never follow symlinks\n\n const fullPath = path.join(dir, entry.name);\n const relPath = path.relative(scanRoot, fullPath);\n\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name) || entry.name.startsWith('.')) continue;\n stack.push(fullPath);\n continue;\n }\n\n if (!entry.isFile()) continue; // sockets, devices, fifos, etc.\n\n if (isSensitiveName(entry.name)) {\n skippedSensitive.push(relPath);\n continue;\n }\n\n const ext = path.extname(entry.name);\n const category = categorize(ext);\n if (category === null) continue; // unrecognized extension — not tracked\n\n files[category].push(relPath);\n\n if (textCategories.has(category)) {\n try {\n const content = readTextSafely(fullPath);\n totalWords += countWords(content);\n } catch {\n // Unreadable/binary-under-a-text-extension — degrade gracefully.\n }\n }\n }\n }\n\n for (const category of Object.keys(files) as FileCategory[]) {\n files[category].sort();\n }\n skippedSensitive.sort();\n\n const totalFiles = Object.values(files).reduce((sum, list) => sum + list.length, 0);\n\n return {\n scanRoot,\n files,\n totalFiles,\n totalWords,\n skippedSensitive,\n };\n}\n","import * as path from 'node:path';\nimport { extractCSharp } from './extractors/csharp.js';\nimport { extractGo } from './extractors/go.js';\nimport { extractJava } from './extractors/java.js';\nimport { extractPython } from './extractors/python.js';\nimport { extractRuby } from './extractors/ruby.js';\nimport { extractRust } from './extractors/rust.js';\nimport { extractTypeScript } from './extractors/typescript.js';\nimport type { ExtractionResult } from './types.js';\n\n/** `displayPath`, when given, is used for node ids/sourceFile instead of the read path — see extract(). */\nexport type Extractor = (path: string, displayPath?: string) => Promise<ExtractionResult>;\n\n/** File extension -> extractor module. Register new languages here. */\nexport const EXTRACTOR_REGISTRY: Record<string, Extractor> = {\n '.ts': extractTypeScript,\n '.tsx': extractTypeScript,\n '.js': extractTypeScript,\n '.jsx': extractTypeScript,\n '.mjs': extractTypeScript,\n '.cjs': extractTypeScript,\n '.mts': extractTypeScript,\n '.cts': extractTypeScript,\n '.py': extractPython,\n '.go': extractGo,\n '.rs': extractRust,\n '.java': extractJava,\n '.cs': extractCSharp,\n '.rb': extractRuby,\n};\n\n/**\n * Dispatch a single file to its language extractor. Returns an empty\n * extraction (not a thrown error) for unregistered extensions so detect's\n * file list and extract's coverage can diverge without crashing a run.\n *\n * `displayPath` decouples where the file is read from (relative to the\n * process cwd) from the path used in node ids and sourceFile attributes —\n * the pipeline passes the project-root-relative path so ids stay stable\n * and portable no matter which directory the pipeline was launched from\n * (this is what makes cross-project merging's namespacing meaningful).\n */\nexport async function extract(filePath: string, displayPath?: string): Promise<ExtractionResult> {\n const ext = path.extname(filePath);\n const extractor = EXTRACTOR_REGISTRY[ext];\n if (!extractor) {\n return { nodes: [], edges: [] };\n }\n return extractor(filePath, displayPath);\n}\n","import * as fs from 'node:fs/promises';\nimport type { Node as TSNode } from 'web-tree-sitter';\nimport type { ExtractionResult } from '../types.js';\nimport {\n ExtractionBuilder,\n descendantsOfType,\n entityId,\n externalId,\n lineOf,\n namedChildren,\n resolveModuleRef,\n toPosix,\n} from './common.js';\nimport { createParser } from './wasmLoader.js';\n\n/**\n * Structural extraction for .cs via web-tree-sitter (WASM, no native\n * compilation, no eval/exec of source content).\n *\n * Like Java, C# has no free top-level functions — methods live inside a\n * class or interface — but unlike Java, top-level types are usually\n * nested one level deeper inside a `namespace Foo { ... }` block, so pass\n * 1 flattens namespace bodies (recursively, for nested namespaces) before\n * walking classes/interfaces/methods, exactly as if their members were\n * declared at the top level.\n *\n * C#'s base-type list (`class Calculator : Base, IGreeter`) doesn't\n * distinguish a base class from an implemented interface syntactically —\n * that's only knowable from the *referenced* declaration. The one\n * compiler-enforced rule this grammar does guarantee is ordering: a base\n * class, if present, must be listed first. So the first entry becomes an\n * `inherits` edge and every subsequent entry becomes `implements` — a\n * deliberate best-effort heuristic, not a guarantee.\n *\n * Every `invocation_expression` is resolved (pass 2): a same-file\n * method/`this.Method()` call resolved against the enclosing class is\n * EXTRACTED; a call qualified by a `using Alias = Namespace.Type;`\n * binding (or an unqualified call resolved only through one) is\n * INFERRED — the \"cross-file second pass\" placeholder described in the\n * master prompt §3. It intentionally does not open and parse the\n * referenced type to confirm the target. An unresolvable callee produces\n * no edge at all.\n */\nexport async function extractCSharp(filePath: string, displayPath?: string): Promise<ExtractionResult> {\n const parser = await createParser('c_sharp');\n\n const raw = await fs.readFile(filePath);\n const content = raw.toString('utf-8'); // replacement-decoded — never throws on invalid bytes\n\n const tree = parser.parse(content);\n if (!tree) {\n throw new Error(`extractCSharp: parser produced no tree for ${filePath}`);\n }\n const root = tree.rootNode;\n\n const sourceFile = toPosix(displayPath ?? filePath);\n const builder = new ExtractionBuilder();\n const fileId = sourceFile;\n builder.addNode({ id: fileId, label: sourceFile, sourceFile, sourceLocation: 'L1' });\n\n /** Declared name (class/interface) -> our graph id. */\n const nameIndex = new Map<string, string>();\n /** tree-sitter node id -> our graph id, for every method entity we track. */\n const functionNodeMap = new Map<number, string>();\n /** tree-sitter class/interface declaration node id -> method name -> our graph id. */\n const classMethods = new Map<number, Map<string, string>>();\n /** tree-sitter method_declaration node id -> its enclosing type's node id. */\n const enclosingClassOf = new Map<number, number>();\n /** local binding name (`using Alias = ...`) -> the module it came from. */\n const importIndex = new Map<string, ReturnType<typeof resolveModuleRef>>();\n\n function addModuleNode(ref: ReturnType<typeof resolveModuleRef>): void {\n if (builder.hasNode(ref.id)) return;\n builder.addNode({\n id: ref.id,\n label: ref.label,\n sourceFile: ref.external ? '<external>' : ref.id,\n sourceLocation: 'L1',\n });\n }\n\n function resolveHeritageTarget(name: string): string {\n const resolved = nameIndex.get(name);\n if (resolved) return resolved;\n const extId = externalId(name);\n if (!builder.hasNode(extId)) {\n builder.addNode({ id: extId, label: name, sourceFile: '<external>', sourceLocation: 'L0' });\n }\n return extId;\n }\n\n function handleUsingDirective(node: TSNode): void {\n const children = namedChildren(node);\n const first = children[0];\n if (!first) return;\n\n let aliasName: string | undefined;\n let targetNode: TSNode | undefined;\n if (first.type === 'name_equals') {\n aliasName = namedChildren(first)[0]?.text;\n targetNode = children[1];\n } else {\n targetNode = first;\n }\n if (!targetNode) return;\n\n const ref = resolveModuleRef(sourceFile, targetNode.text);\n addModuleNode(ref);\n if (aliasName) importIndex.set(aliasName, ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n }\n\n function handleMethodDeclaration(typeNode: TSNode, typeId: string, typeName: string, member: TSNode): void {\n const methodName = member.childForFieldName('name')?.text ?? '(anonymous)';\n const methodId = entityId(sourceFile, `${typeName}.${methodName}`);\n builder.addNode({\n id: methodId,\n label: `method ${typeName}.${methodName}`,\n sourceFile,\n sourceLocation: lineOf(member),\n });\n builder.addEdge({ source: typeId, target: methodId, relation: 'method', confidence: 'EXTRACTED' });\n\n let methods = classMethods.get(typeNode.id);\n if (!methods) {\n methods = new Map();\n classMethods.set(typeNode.id, methods);\n }\n methods.set(methodName, methodId);\n functionNodeMap.set(member.id, methodId);\n enclosingClassOf.set(member.id, typeNode.id);\n }\n\n function handleBaseList(typeId: string, node: TSNode): void {\n const baseList = node.childForFieldName('bases');\n if (!baseList) return;\n const entries = namedChildren(baseList);\n entries.forEach((entry, index) => {\n builder.addEdge({\n source: typeId,\n target: resolveHeritageTarget(entry.text),\n relation: index === 0 ? 'inherits' : 'implements',\n confidence: 'EXTRACTED',\n });\n });\n }\n\n function handleClassDeclaration(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const classId = entityId(sourceFile, name);\n builder.addNode({ id: classId, label: `class ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: classId, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, classId);\n functionNodeMap.set(node.id, classId);\n classMethods.set(node.id, new Map());\n\n handleBaseList(classId, node);\n\n const body = node.childForFieldName('body');\n if (body) {\n for (const member of namedChildren(body)) {\n if (member.type !== 'method_declaration') continue; // constructors intentionally not tracked\n handleMethodDeclaration(node, classId, name, member);\n }\n }\n }\n\n function handleInterfaceDeclaration(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `interface ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n handleBaseList(id, node); // interface-extends-interface(s) — same shape as a class base list\n }\n\n // Pass 1: top-level declarations (usings, classes, interfaces),\n // flattening `namespace Foo { ... }` wrappers (recursively).\n function walkTopLevel(node: TSNode): void {\n for (const child of namedChildren(node)) {\n switch (child.type) {\n case 'using_directive':\n handleUsingDirective(child);\n break;\n case 'class_declaration':\n handleClassDeclaration(child);\n break;\n case 'interface_declaration':\n handleInterfaceDeclaration(child);\n break;\n case 'namespace_declaration': {\n const nsBody = child.childForFieldName('body');\n if (nsBody) walkTopLevel(nsBody);\n break;\n }\n case 'file_scoped_namespace_declaration':\n // `namespace Foo;` (C# 10+) — declarations are direct named\n // children of this node itself (no separate `body` field).\n walkTopLevel(child);\n break;\n default:\n break;\n }\n }\n }\n walkTopLevel(root);\n\n function closestTrackedCaller(node: TSNode): string {\n let current: TSNode | null = node.parent;\n while (current) {\n const tracked = functionNodeMap.get(current.id);\n if (tracked) return tracked;\n current = current.parent;\n }\n return fileId;\n }\n\n function closestEnclosingClassMethods(node: TSNode): Map<string, string> | undefined {\n let current: TSNode | null = node.parent;\n while (current) {\n if (current.type === 'method_declaration') {\n const typeNodeId = enclosingClassOf.get(current.id);\n if (typeNodeId !== undefined) return classMethods.get(typeNodeId);\n }\n current = current.parent;\n }\n return undefined;\n }\n\n // Pass 2: calls (see the function doc comment above for the\n // EXTRACTED/INFERRED policy).\n for (const call of descendantsOfType(root, ['invocation_expression'])) {\n const fn = call.childForFieldName('function');\n if (!fn) continue;\n\n let targetId: string | null = null;\n let confidence: 'EXTRACTED' | 'INFERRED' = 'EXTRACTED';\n\n if (fn.type === 'identifier') {\n const name = fn.text;\n const methodId = closestEnclosingClassMethods(call)?.get(name);\n if (methodId) {\n targetId = methodId;\n } else {\n const viaImport = importIndex.get(name);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n } else if (fn.type === 'member_access_expression') {\n const expression = fn.childForFieldName('expression');\n const name = fn.childForFieldName('name')?.text;\n if (expression && name) {\n if (expression.type === 'this_expression') {\n const methodId = closestEnclosingClassMethods(call)?.get(name);\n if (methodId) targetId = methodId;\n } else if (expression.type === 'identifier') {\n const viaImport = importIndex.get(expression.text);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n }\n }\n\n if (!targetId) continue; // unresolved callee (builtin, external value, ...) — no noisy guess\n const callerId = closestTrackedCaller(call);\n builder.addEdge({ source: callerId, target: targetId, relation: 'calls', confidence });\n }\n\n return builder.build();\n}\n","import * as path from 'node:path';\nimport type { Node as TSNode } from 'web-tree-sitter';\nimport type { ExtractionResult, GraphEdge, GraphNode } from '../types.js';\n\n/**\n * web-tree-sitter types `namedChildren`/`descendantsOfType` as\n * `(Node | null)[]` (a node slot can be null for a missing/erroneous\n * child). These two helpers give every extractor a non-null array to\n * iterate without repeating the same `.filter()` everywhere.\n */\nexport function namedChildren(node: TSNode): TSNode[] {\n return node.namedChildren.filter((c): c is TSNode => c !== null);\n}\n\nexport function descendantsOfType(node: TSNode, types: string | string[]): TSNode[] {\n return node.descendantsOfType(types).filter((c): c is TSNode => c !== null);\n}\n\n/** Normalize a path to forward slashes so ids/labels are stable across platforms. */\nexport function toPosix(p: string): string {\n return p.split(path.sep).join('/');\n}\n\n/** `tree-sitter` node shape narrowed to what id/location helpers need. */\nexport interface PositionedNode {\n startPosition: { row: number };\n}\n\n/** 1-based \"L<line>\" source location string, matching the schema example (`\"L42\"`). */\nexport function lineOf(node: PositionedNode): string {\n return `L${node.startPosition.row + 1}`;\n}\n\n/** Build a stable, file-scoped node id: unique across the whole graph once merged. */\nexport function entityId(sourceFile: string, qualifiedName: string): string {\n return `${toPosix(sourceFile)}::${qualifiedName}`;\n}\n\n/** Id for a reference we could not resolve to any declaration we saw (best-effort target). */\nexport function externalId(name: string): string {\n return `external:${name}`;\n}\n\nexport interface ModuleRef {\n id: string;\n label: string;\n /** true when the specifier is a bare package (not resolvable to an in-repo file). */\n external: boolean;\n}\n\n/**\n * Resolve an import/require specifier to a best-effort module id relative\n * to the importing file. This is intentionally lightweight (string/path\n * math only, no filesystem probing, no extension resolution) — it exists\n * so same-repo relative imports get a deterministic, file-shaped id that a\n * later cross-file pass (or a second extraction of the target file) can\n * line up against, not to fully replicate a module resolver.\n */\nexport function resolveModuleRef(sourceFile: string, specifier: string): ModuleRef {\n if (specifier.startsWith('.') || specifier.startsWith('/')) {\n const dir = path.posix.dirname(toPosix(sourceFile));\n const joined = specifier.startsWith('/') ? specifier : path.posix.join(dir, specifier);\n const normalized = path.posix.normalize(joined);\n return { id: normalized, label: specifier, external: false };\n }\n return { id: `module:${specifier}`, label: specifier, external: true };\n}\n\n/**\n * Accumulates nodes/edges for one file's ExtractionResult with node-id\n * dedup (a file can otherwise easily emit the same module/external\n * placeholder node twice — once per import, once per call resolution).\n */\nexport class ExtractionBuilder {\n private readonly nodeIds = new Set<string>();\n readonly nodes: GraphNode[] = [];\n readonly edges: GraphEdge[] = [];\n\n addNode(node: GraphNode): void {\n if (this.nodeIds.has(node.id)) return;\n this.nodeIds.add(node.id);\n this.nodes.push(node);\n }\n\n hasNode(id: string): boolean {\n return this.nodeIds.has(id);\n }\n\n addEdge(edge: GraphEdge): void {\n this.edges.push(edge);\n }\n\n build(): ExtractionResult {\n return { nodes: this.nodes, edges: this.edges };\n }\n}\n","import { createRequire } from 'node:module';\nimport { Language, Parser } from 'web-tree-sitter';\n\n/**\n * Shared web-tree-sitter bootstrapping for every language extractor.\n *\n * Pinned to web-tree-sitter@^0.25.x deliberately (not the newer 0.26.x\n * major that ships with the rest of the dependency set): 0.26 requires\n * every language grammar to carry a \"dylink.0\" WASM custom section (the\n * newer wasm dynamic-linking convention), but `tree-sitter-wasms`'s\n * prebuilt grammars still use the legacy \"dylink\" section — loading any\n * grammar under 0.26 throws `need dylink section` before a single file can\n * be parsed. 0.25.x accepts the legacy section and loads every grammar\n * `tree-sitter-wasms` ships. Revisit this pin once `tree-sitter-wasms`\n * republishes grammars built against a dylink.0-era tree-sitter-cli.\n */\n\nconst require = createRequire(import.meta.url);\n\nlet initPromise: Promise<void> | null = null;\n\nfunction ensureInitialized(): Promise<void> {\n if (!initPromise) {\n initPromise = Parser.init();\n }\n return initPromise;\n}\n\nconst languageCache = new Map<string, Promise<Language>>();\n\n/** Load (and cache) a tree-sitter-wasms grammar by its `tree-sitter-<name>.wasm` basename. */\nexport async function loadLanguage(grammarName: string): Promise<Language> {\n await ensureInitialized();\n let cached = languageCache.get(grammarName);\n if (!cached) {\n const wasmPath = require.resolve(`tree-sitter-wasms/out/tree-sitter-${grammarName}.wasm`);\n cached = Language.load(wasmPath);\n languageCache.set(grammarName, cached);\n }\n return cached;\n}\n\n/** Create a fresh Parser bound to the given grammar. Parsers are cheap and not thread-shared. */\nexport async function createParser(grammarName: string): Promise<Parser> {\n const language = await loadLanguage(grammarName);\n const parser = new Parser();\n parser.setLanguage(language);\n return parser;\n}\n","import * as fs from 'node:fs/promises';\nimport type { Node as TSNode } from 'web-tree-sitter';\nimport type { ExtractionResult } from '../types.js';\nimport {\n ExtractionBuilder,\n descendantsOfType,\n entityId,\n externalId,\n lineOf,\n namedChildren,\n resolveModuleRef,\n toPosix,\n} from './common.js';\nimport { createParser } from './wasmLoader.js';\n\n/** Strip the surrounding quotes tree-sitter keeps on an interpreted/raw string literal's text. */\nfunction stripQuotes(text: string): string {\n if (text.length >= 2) {\n const first = text[0];\n const last = text[text.length - 1];\n if ((first === '\"' || first === '`') && first === last) {\n return text.slice(1, -1);\n }\n }\n return text;\n}\n\n/** Default package qualifier Go infers from an import path when no explicit alias is given. */\nfunction defaultPackageQualifier(importPath: string): string {\n const segments = importPath.split('/');\n return segments[segments.length - 1] ?? importPath;\n}\n\n/**\n * Structural extraction for .go via web-tree-sitter (WASM, no native\n * compilation, no eval/exec of source content).\n *\n * Pattern mirrors typescript.ts, adapted to Go's shape: top-level named\n * types (struct/interface/defined types), functions, methods (declared\n * separately from their receiver type via `func (recv T) Name(...)`), and\n * imports (pass 1) -> every `call_expression` resolved against what pass 1\n * saw (pass 2). A same-file callee, or a call through the receiver\n * variable of the enclosing method onto a method of the same struct, is\n * EXTRACTED; a call through an imported package qualifier (e.g.\n * `m.Add(x, x)` where `m` is an import alias) is INFERRED — the\n * \"cross-file second pass\" placeholder described in the master prompt §3.\n * An unresolvable callee produces no edge at all.\n *\n * Go has no `extends`/`implements` clauses; struct embedding\n * (`type Calculator struct { Base }`) is the one heritage-like construct\n * Go's grammar exposes directly, so it becomes an `embeds` edge.\n */\nexport async function extractGo(filePath: string, displayPath?: string): Promise<ExtractionResult> {\n const parser = await createParser('go');\n\n const raw = await fs.readFile(filePath);\n const content = raw.toString('utf-8'); // replacement-decoded — never throws on invalid bytes\n\n const tree = parser.parse(content);\n if (!tree) {\n throw new Error(`extractGo: parser produced no tree for ${filePath}`);\n }\n const root = tree.rootNode;\n\n const sourceFile = toPosix(displayPath ?? filePath);\n const builder = new ExtractionBuilder();\n const fileId = sourceFile;\n builder.addNode({ id: fileId, label: sourceFile, sourceFile, sourceLocation: 'L1' });\n\n /** Declared name (function or named type) -> our graph id. */\n const nameIndex = new Map<string, string>();\n /** tree-sitter node id -> our graph id, for every function/method entity we track. */\n const functionNodeMap = new Map<number, string>();\n /** graph id of a named type -> method name -> our graph id. */\n const typeMethods = new Map<string, Map<string, string>>();\n /** tree-sitter method_declaration node id -> { receiver variable name, owning type's graph id }. */\n const receiverInfo = new Map<number, { varName: string; typeId: string }>();\n /** local package qualifier (import alias or inferred name) -> the module it came from. */\n const importIndex = new Map<string, ReturnType<typeof resolveModuleRef>>();\n\n function addModuleNode(ref: ReturnType<typeof resolveModuleRef>): void {\n if (builder.hasNode(ref.id)) return;\n builder.addNode({\n id: ref.id,\n label: ref.label,\n sourceFile: ref.external ? '<external>' : ref.id,\n sourceLocation: 'L1',\n });\n }\n\n function resolveTypeTarget(name: string): string {\n const resolved = nameIndex.get(name);\n if (resolved) return resolved;\n const extId = externalId(name);\n if (!builder.hasNode(extId)) {\n builder.addNode({ id: extId, label: name, sourceFile: '<external>', sourceLocation: 'L0' });\n }\n return extId;\n }\n\n function handleImportSpec(spec: TSNode): void {\n const pathNode = spec.childForFieldName('path');\n if (!pathNode) return;\n const specifier = stripQuotes(pathNode.text);\n const ref = resolveModuleRef(sourceFile, specifier);\n addModuleNode(ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n\n const aliasNode = spec.childForFieldName('name');\n const alias = aliasNode?.text;\n if (alias && alias !== '_' && alias !== '.') {\n importIndex.set(alias, ref);\n } else if (!alias) {\n importIndex.set(defaultPackageQualifier(specifier), ref);\n }\n }\n\n function handleImportDeclaration(node: TSNode): void {\n for (const child of namedChildren(node)) {\n if (child.type === 'import_spec') {\n handleImportSpec(child);\n } else if (child.type === 'import_spec_list') {\n for (const spec of namedChildren(child)) {\n if (spec.type === 'import_spec') handleImportSpec(spec);\n }\n }\n }\n }\n\n function handleFunctionDeclaration(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `function ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n functionNodeMap.set(node.id, id);\n }\n\n function handleTypeDeclaration(node: TSNode): void {\n for (const spec of namedChildren(node)) {\n if (spec.type !== 'type_spec') continue; // skip `type X = Y` aliases\n const name = spec.childForFieldName('name')?.text;\n if (!name) continue;\n const underlying = spec.childForFieldName('type');\n const kind = underlying?.type === 'struct_type' ? 'struct' : underlying?.type === 'interface_type' ? 'interface' : 'type';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `${kind} ${name}`, sourceFile, sourceLocation: lineOf(spec) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n typeMethods.set(id, new Map());\n\n if (underlying?.type === 'struct_type') {\n const fieldList = namedChildren(underlying).find((c) => c.type === 'field_declaration_list');\n if (fieldList) {\n for (const field of namedChildren(fieldList)) {\n if (field.type !== 'field_declaration') continue;\n if (field.childForFieldName('name')) continue; // named field, not embedding\n const embeddedType = namedChildren(field)[0];\n if (!embeddedType) continue;\n const base = embeddedType.type === 'pointer_type' ? namedChildren(embeddedType)[0] : embeddedType;\n if (!base) continue;\n builder.addEdge({\n source: id,\n target: resolveTypeTarget(base.text),\n relation: 'embeds',\n confidence: 'EXTRACTED',\n });\n }\n }\n }\n }\n }\n\n /** Receiver's declared type name, unwrapping a pointer receiver (`*T`). */\n function receiverTypeName(receiver: TSNode): string | null {\n const paramDecl = namedChildren(receiver)[0];\n if (!paramDecl) return null;\n let typeNode = paramDecl.childForFieldName('type');\n if (typeNode?.type === 'pointer_type') {\n typeNode = namedChildren(typeNode)[0] ?? null;\n }\n return typeNode?.type === 'type_identifier' ? typeNode.text : null;\n }\n\n function receiverVarName(receiver: TSNode): string | null {\n const paramDecl = namedChildren(receiver)[0];\n return paramDecl?.childForFieldName('name')?.text ?? null;\n }\n\n function handleMethodDeclaration(node: TSNode): void {\n const receiver = node.childForFieldName('receiver');\n const methodName = node.childForFieldName('name')?.text ?? '(anonymous)';\n if (!receiver) return;\n const typeName = receiverTypeName(receiver);\n if (!typeName) return;\n const typeId = resolveTypeTarget(typeName);\n\n const methodId = entityId(sourceFile, `${typeName}.${methodName}`);\n builder.addNode({ id: methodId, label: `method ${typeName}.${methodName}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: typeId, target: methodId, relation: 'method', confidence: 'EXTRACTED' });\n\n let methods = typeMethods.get(typeId);\n if (!methods) {\n methods = new Map();\n typeMethods.set(typeId, methods);\n }\n methods.set(methodName, methodId);\n\n functionNodeMap.set(node.id, methodId);\n const varName = receiverVarName(receiver);\n if (varName) receiverInfo.set(node.id, { varName, typeId });\n }\n\n // Pass 1: top-level declarations (imports, named types, functions, methods).\n for (const child of namedChildren(root)) {\n switch (child.type) {\n case 'import_declaration':\n handleImportDeclaration(child);\n break;\n case 'type_declaration':\n handleTypeDeclaration(child);\n break;\n case 'function_declaration':\n handleFunctionDeclaration(child);\n break;\n case 'method_declaration':\n handleMethodDeclaration(child);\n break;\n default:\n break;\n }\n }\n\n function closestTrackedCaller(node: TSNode): string {\n let current: TSNode | null = node.parent;\n while (current) {\n const tracked = functionNodeMap.get(current.id);\n if (tracked) return tracked;\n current = current.parent;\n }\n return fileId;\n }\n\n function closestEnclosingReceiver(node: TSNode): { varName: string; typeId: string } | undefined {\n let current: TSNode | null = node.parent;\n while (current) {\n if (current.type === 'method_declaration') {\n return receiverInfo.get(current.id);\n }\n current = current.parent;\n }\n return undefined;\n }\n\n // Pass 2: calls (see the function doc comment above for the\n // EXTRACTED/INFERRED policy).\n for (const call of descendantsOfType(root, ['call_expression'])) {\n const fn = call.childForFieldName('function');\n if (!fn) continue;\n\n let targetId: string | null = null;\n let confidence: 'EXTRACTED' | 'INFERRED' = 'EXTRACTED';\n\n if (fn.type === 'identifier') {\n const sameFile = nameIndex.get(fn.text);\n if (sameFile) targetId = sameFile;\n } else if (fn.type === 'selector_expression') {\n const operand = fn.childForFieldName('operand');\n const property = fn.childForFieldName('field')?.text;\n if (operand && property && operand.type === 'identifier') {\n const receiver = closestEnclosingReceiver(call);\n if (receiver && receiver.varName === operand.text) {\n const methodId = typeMethods.get(receiver.typeId)?.get(property);\n if (methodId) targetId = methodId;\n } else {\n const viaImport = importIndex.get(operand.text);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n }\n }\n\n if (!targetId) continue; // unresolved callee (builtin, external value, ...) — no noisy guess\n const callerId = closestTrackedCaller(call);\n builder.addEdge({ source: callerId, target: targetId, relation: 'calls', confidence });\n }\n\n return builder.build();\n}\n","import * as fs from 'node:fs/promises';\nimport type { Node as TSNode } from 'web-tree-sitter';\nimport type { ExtractionResult } from '../types.js';\nimport {\n ExtractionBuilder,\n descendantsOfType,\n entityId,\n externalId,\n lineOf,\n namedChildren,\n resolveModuleRef,\n toPosix,\n} from './common.js';\nimport { createParser } from './wasmLoader.js';\n\n/**\n * Structural extraction for .java via web-tree-sitter (WASM, no native\n * compilation, no eval/exec of source content).\n *\n * Java has no free top-level functions — every method lives inside a\n * class or interface — so pass 1 walks top-level class/interface\n * declarations and, for classes, their methods (an interface's methods\n * are abstract signatures with no body, so only the interface itself\n * becomes a node, mirroring typescript.ts's interface handling).\n * Constructors (`constructor_declaration`, distinct from\n * `method_declaration` in this grammar) are intentionally not tracked as\n * separate entities — same \"structural, not exhaustive\" scope as the\n * other extractors in this file.\n *\n * Every `method_invocation` is then resolved (pass 2): a same-file\n * method/`this.method()` call resolved against the enclosing class is\n * EXTRACTED; a call qualified by an imported class name (or bound via a\n * static import) is INFERRED — the \"cross-file second pass\" placeholder\n * described in the master prompt §3. It intentionally does not open and\n * parse the imported class to confirm the target. An unresolvable callee\n * produces no edge at all.\n *\n * Fully-qualified import paths (`com.example.math.MathUtils`) have no\n * clean mapping to a same-repo relative file without real classpath/\n * package-root information, so every import resolves to an external\n * module placeholder via resolveModuleRef — consistent with how the Go\n * extractor treats its (also always-absolute) import paths.\n */\nexport async function extractJava(filePath: string, displayPath?: string): Promise<ExtractionResult> {\n const parser = await createParser('java');\n\n const raw = await fs.readFile(filePath);\n const content = raw.toString('utf-8'); // replacement-decoded — never throws on invalid bytes\n\n const tree = parser.parse(content);\n if (!tree) {\n throw new Error(`extractJava: parser produced no tree for ${filePath}`);\n }\n const root = tree.rootNode;\n\n const sourceFile = toPosix(displayPath ?? filePath);\n const builder = new ExtractionBuilder();\n const fileId = sourceFile;\n builder.addNode({ id: fileId, label: sourceFile, sourceFile, sourceLocation: 'L1' });\n\n /** Declared name (class/interface) -> our graph id. */\n const nameIndex = new Map<string, string>();\n /** tree-sitter node id -> our graph id, for every method entity we track. */\n const functionNodeMap = new Map<number, string>();\n /** tree-sitter class_declaration node id -> method name -> our graph id. */\n const classMethods = new Map<number, Map<string, string>>();\n /** tree-sitter method_declaration node id -> its enclosing class's node id. */\n const enclosingClassOf = new Map<number, number>();\n /** local binding name (imported class or statically-imported member) -> the module it came from. */\n const importIndex = new Map<string, ReturnType<typeof resolveModuleRef>>();\n\n function addModuleNode(ref: ReturnType<typeof resolveModuleRef>): void {\n if (builder.hasNode(ref.id)) return;\n builder.addNode({\n id: ref.id,\n label: ref.label,\n sourceFile: ref.external ? '<external>' : ref.id,\n sourceLocation: 'L1',\n });\n }\n\n function resolveHeritageTarget(name: string): string {\n const resolved = nameIndex.get(name);\n if (resolved) return resolved;\n const extId = externalId(name);\n if (!builder.hasNode(extId)) {\n builder.addNode({ id: extId, label: name, sourceFile: '<external>', sourceLocation: 'L0' });\n }\n return extId;\n }\n\n function handleImportDeclaration(node: TSNode): void {\n // Java's grammar keeps `static`/`*` as bare tokens (no field name), so\n // we detect them structurally rather than via childForFieldName.\n const hasWildcard = namedChildren(node).some((c) => c.type === 'asterisk');\n const scoped = namedChildren(node).find((c) => c.type === 'scoped_identifier' || c.type === 'identifier');\n if (!scoped) return;\n const fullPath = scoped.text;\n const ref = resolveModuleRef(sourceFile, fullPath);\n addModuleNode(ref);\n\n if (hasWildcard) {\n // `import com.example.util.*;` — whole package, no single local binding to record.\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n return;\n }\n\n // Plain class import (`import a.b.Foo;`) and static-member import\n // (`import static a.b.Foo.bar;`) both bind their last dotted segment\n // as the local name callers use unqualified.\n const segments = fullPath.split('.');\n const localName = segments[segments.length - 1];\n if (localName) importIndex.set(localName, ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports_from', confidence: 'EXTRACTED' });\n }\n\n function handleMethodDeclaration(classNode: TSNode, classId: string, className: string, member: TSNode): void {\n const methodName = member.childForFieldName('name')?.text ?? '(anonymous)';\n const methodId = entityId(sourceFile, `${className}.${methodName}`);\n builder.addNode({\n id: methodId,\n label: `method ${className}.${methodName}`,\n sourceFile,\n sourceLocation: lineOf(member),\n });\n builder.addEdge({ source: classId, target: methodId, relation: 'method', confidence: 'EXTRACTED' });\n\n let methods = classMethods.get(classNode.id);\n if (!methods) {\n methods = new Map();\n classMethods.set(classNode.id, methods);\n }\n methods.set(methodName, methodId);\n functionNodeMap.set(member.id, methodId);\n enclosingClassOf.set(member.id, classNode.id);\n }\n\n function handleClassDeclaration(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const classId = entityId(sourceFile, name);\n builder.addNode({ id: classId, label: `class ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: classId, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, classId);\n functionNodeMap.set(node.id, classId);\n classMethods.set(node.id, new Map());\n\n const superclass = node.childForFieldName('superclass');\n if (superclass) {\n const base = namedChildren(superclass)[0];\n if (base) {\n builder.addEdge({\n source: classId,\n target: resolveHeritageTarget(base.text),\n relation: 'inherits',\n confidence: 'EXTRACTED',\n });\n }\n }\n\n const interfaces = node.childForFieldName('interfaces');\n if (interfaces) {\n const typeList = namedChildren(interfaces).find((c) => c.type === 'type_list');\n for (const iface of typeList ? namedChildren(typeList) : []) {\n builder.addEdge({\n source: classId,\n target: resolveHeritageTarget(iface.text),\n relation: 'implements',\n confidence: 'EXTRACTED',\n });\n }\n }\n\n const body = node.childForFieldName('body');\n if (body) {\n for (const member of namedChildren(body)) {\n if (member.type !== 'method_declaration') continue; // constructors intentionally not tracked\n handleMethodDeclaration(node, classId, name, member);\n }\n }\n }\n\n function handleInterfaceDeclaration(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `interface ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n\n const extendsInterfaces = namedChildren(node).find((c) => c.type === 'extends_interfaces');\n if (extendsInterfaces) {\n const typeList = namedChildren(extendsInterfaces).find((c) => c.type === 'type_list');\n for (const parent of typeList ? namedChildren(typeList) : []) {\n builder.addEdge({\n source: id,\n target: resolveHeritageTarget(parent.text),\n relation: 'inherits',\n confidence: 'EXTRACTED',\n });\n }\n }\n }\n\n // Pass 1: top-level declarations (imports, classes, interfaces).\n for (const child of namedChildren(root)) {\n switch (child.type) {\n case 'import_declaration':\n handleImportDeclaration(child);\n break;\n case 'class_declaration':\n handleClassDeclaration(child);\n break;\n case 'interface_declaration':\n handleInterfaceDeclaration(child);\n break;\n default:\n break;\n }\n }\n\n function closestTrackedCaller(node: TSNode): string {\n let current: TSNode | null = node.parent;\n while (current) {\n const tracked = functionNodeMap.get(current.id);\n if (tracked) return tracked;\n current = current.parent;\n }\n return fileId;\n }\n\n function closestEnclosingClassMethods(node: TSNode): Map<string, string> | undefined {\n let current: TSNode | null = node.parent;\n while (current) {\n if (current.type === 'method_declaration') {\n const classNodeId = enclosingClassOf.get(current.id);\n if (classNodeId !== undefined) return classMethods.get(classNodeId);\n }\n current = current.parent;\n }\n return undefined;\n }\n\n // Pass 2: calls (see the function doc comment above for the\n // EXTRACTED/INFERRED policy).\n for (const call of descendantsOfType(root, ['method_invocation'])) {\n const name = call.childForFieldName('name')?.text;\n if (!name) continue;\n const object = call.childForFieldName('object');\n\n let targetId: string | null = null;\n let confidence: 'EXTRACTED' | 'INFERRED' = 'EXTRACTED';\n\n if (!object) {\n // Unqualified call: same-file method (via the tracked caller's own\n // class) or a statically-imported member.\n const methodId = closestEnclosingClassMethods(call)?.get(name);\n if (methodId) {\n targetId = methodId;\n } else {\n const viaImport = importIndex.get(name);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n } else if (object.type === 'this') {\n const methodId = closestEnclosingClassMethods(call)?.get(name);\n if (methodId) targetId = methodId;\n } else if (object.type === 'identifier') {\n const viaImport = importIndex.get(object.text);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n\n if (!targetId) continue; // unresolved callee (builtin, external value, ...) — no noisy guess\n const callerId = closestTrackedCaller(call);\n builder.addEdge({ source: callerId, target: targetId, relation: 'calls', confidence });\n }\n\n return builder.build();\n}\n","import * as fs from 'node:fs/promises';\nimport type { Node as TSNode } from 'web-tree-sitter';\nimport type { ExtractionResult } from '../types.js';\nimport {\n ExtractionBuilder,\n descendantsOfType,\n entityId,\n externalId,\n lineOf,\n namedChildren,\n resolveModuleRef,\n toPosix,\n} from './common.js';\nimport { createParser } from './wasmLoader.js';\n\n/**\n * Structural extraction for .py via web-tree-sitter (WASM, no native\n * compilation, no eval/exec of source content).\n *\n * Pattern mirrors typescript.ts: parse -> walk the module body for\n * top-level functions/classes/imports (pass 1) -> walk every `call` node\n * and resolve its callee against what pass 1 saw (pass 2). A same-file\n * callee (or a `self.method()` call resolved against the enclosing class)\n * is EXTRACTED; a callee that only resolves through an imported local\n * binding (a directly-imported name, or a member access on an imported\n * module alias) is emitted as INFERRED — the \"cross-file second pass\"\n * placeholder described in the master prompt §3. It intentionally does not\n * open and parse the imported module to confirm the target. An\n * unresolvable callee (a builtin, a call on some arbitrary local value,\n * etc.) produces no edge at all rather than a noisy guess.\n *\n * Python has no separate interface/heritage-clause concept: every base\n * class listed in `class Foo(Base, Other):` becomes an `inherits` edge.\n */\nexport async function extractPython(filePath: string, displayPath?: string): Promise<ExtractionResult> {\n const parser = await createParser('python');\n\n const raw = await fs.readFile(filePath);\n const content = raw.toString('utf-8'); // replacement-decoded — never throws on invalid bytes\n\n const tree = parser.parse(content);\n if (!tree) {\n throw new Error(`extractPython: parser produced no tree for ${filePath}`);\n }\n const root = tree.rootNode;\n\n const sourceFile = toPosix(displayPath ?? filePath);\n const builder = new ExtractionBuilder();\n const fileId = sourceFile;\n builder.addNode({ id: fileId, label: sourceFile, sourceFile, sourceLocation: 'L1' });\n\n /** Declared name (function/class) -> our graph id. */\n const nameIndex = new Map<string, string>();\n /** tree-sitter node id -> our graph id, for every function-like entity we track. */\n const functionNodeMap = new Map<number, string>();\n /** tree-sitter class_definition node id -> method name -> our graph id. */\n const classMethods = new Map<number, Map<string, string>>();\n /** tree-sitter function_definition (method) node id -> its enclosing class's node id. */\n const enclosingClassOf = new Map<number, number>();\n /** local binding name (import) -> the module it came from. */\n const importIndex = new Map<string, ReturnType<typeof resolveModuleRef>>();\n\n function addModuleNode(ref: ReturnType<typeof resolveModuleRef>): void {\n if (builder.hasNode(ref.id)) return;\n builder.addNode({\n id: ref.id,\n label: ref.label,\n sourceFile: ref.external ? '<external>' : ref.id,\n sourceLocation: 'L1',\n });\n }\n\n function resolveHeritageTarget(name: string): string {\n const resolved = nameIndex.get(name);\n if (resolved) return resolved;\n const extId = externalId(name);\n if (!builder.hasNode(extId)) {\n builder.addNode({ id: extId, label: name, sourceFile: '<external>', sourceLocation: 'L0' });\n }\n return extId;\n }\n\n /** Unwrap a `@decorator` / `decorated_definition` wrapper to the function/class it decorates. */\n function unwrapDecorated(node: TSNode): TSNode | null {\n if (node.type !== 'decorated_definition') return node;\n return (\n namedChildren(node).find((c) => c.type === 'function_definition' || c.type === 'class_definition') ?? null\n );\n }\n\n /**\n * Convert a `relative_import` node (e.g. \".\", \".foo\", \"..foo.bar\") into a\n * relative-path-shaped specifier resolveModuleRef understands (e.g. \".\",\n * \"./foo\", \"../foo/bar\") — one leading dot means \"this package\" (`.`),\n * each additional dot means one more directory up.\n */\n function relativeSpecifier(relImport: TSNode): string {\n let dots = 0;\n for (const ch of relImport.text) {\n if (ch !== '.') break;\n dots++;\n }\n const dotted = namedChildren(relImport).find((c) => c.type === 'dotted_name');\n const up = dots - 1;\n let base = up === 0 ? '.' : Array.from({ length: up }, () => '..').join('/');\n if (dotted) {\n base = `${base}/${dotted.text.split('.').join('/')}`;\n }\n return base;\n }\n\n function moduleSpecifierOf(node: TSNode): string {\n if (node.type === 'relative_import') return relativeSpecifier(node);\n return node.text; // dotted_name, e.g. \"pkg.sub\"\n }\n\n function handleFunctionDefinition(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `function ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n functionNodeMap.set(node.id, id);\n }\n\n function handleClassDefinition(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const classId = entityId(sourceFile, name);\n builder.addNode({ id: classId, label: `class ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: classId, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, classId);\n functionNodeMap.set(node.id, classId);\n\n const superclasses = node.childForFieldName('superclasses');\n if (superclasses) {\n for (const base of namedChildren(superclasses)) {\n if (base.type !== 'identifier' && base.type !== 'attribute') continue; // skip e.g. metaclass=Meta\n builder.addEdge({\n source: classId,\n target: resolveHeritageTarget(base.text),\n relation: 'inherits',\n confidence: 'EXTRACTED',\n });\n }\n }\n\n const methods = new Map<string, string>();\n classMethods.set(node.id, methods);\n\n const body = node.childForFieldName('body');\n if (body) {\n for (const rawMember of namedChildren(body)) {\n const member = unwrapDecorated(rawMember);\n if (!member || member.type !== 'function_definition') continue;\n const methodName = member.childForFieldName('name')?.text ?? '(anonymous)';\n const methodId = entityId(sourceFile, `${name}.${methodName}`);\n builder.addNode({\n id: methodId,\n label: `method ${name}.${methodName}`,\n sourceFile,\n sourceLocation: lineOf(member),\n });\n builder.addEdge({ source: classId, target: methodId, relation: 'method', confidence: 'EXTRACTED' });\n methods.set(methodName, methodId);\n functionNodeMap.set(member.id, methodId);\n enclosingClassOf.set(member.id, node.id);\n }\n }\n }\n\n function handleImportStatement(node: TSNode): void {\n // `import a, b.c as d` — every item is a top-level named child, either\n // `dotted_name` (bare module) or `aliased_import` (module `as` alias).\n for (const item of namedChildren(node)) {\n if (item.type === 'dotted_name') {\n const ref = resolveModuleRef(sourceFile, item.text);\n addModuleNode(ref);\n const bindingName = namedChildren(item)[0]?.text ?? item.text; // `import pkg.sub` binds `pkg`\n importIndex.set(bindingName, ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n } else if (item.type === 'aliased_import') {\n const dotted = item.childForFieldName('name');\n const alias = item.childForFieldName('alias')?.text;\n if (!dotted || !alias) continue;\n const ref = resolveModuleRef(sourceFile, dotted.text);\n addModuleNode(ref);\n importIndex.set(alias, ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n }\n }\n }\n\n function handleImportFromStatement(node: TSNode): void {\n const moduleNode = node.childForFieldName('module_name');\n if (!moduleNode) return;\n const ref = resolveModuleRef(sourceFile, moduleSpecifierOf(moduleNode));\n addModuleNode(ref);\n\n let sawItem = false;\n for (const child of namedChildren(node)) {\n if (child.id === moduleNode.id) continue;\n if (child.type === 'dotted_name') {\n sawItem = true;\n importIndex.set(child.text, ref);\n } else if (child.type === 'aliased_import') {\n sawItem = true;\n const alias = child.childForFieldName('alias')?.text;\n const name = child.childForFieldName('name')?.text;\n if (alias) importIndex.set(alias, ref);\n else if (name) importIndex.set(name, ref);\n } else if (child.type === 'wildcard_import') {\n sawItem = true;\n }\n }\n if (sawItem) {\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports_from', confidence: 'EXTRACTED' });\n }\n }\n\n // Pass 1: top-level declarations (functions, classes, imports),\n // unwrapping `@decorator` wrappers where present.\n for (const rawChild of namedChildren(root)) {\n if (rawChild.type === 'import_statement') {\n handleImportStatement(rawChild);\n continue;\n }\n if (rawChild.type === 'import_from_statement') {\n handleImportFromStatement(rawChild);\n continue;\n }\n\n const effective = unwrapDecorated(rawChild);\n if (!effective) continue;\n\n switch (effective.type) {\n case 'function_definition':\n handleFunctionDefinition(effective);\n break;\n case 'class_definition':\n handleClassDefinition(effective);\n break;\n default:\n break;\n }\n }\n\n function closestTrackedCaller(node: TSNode): string {\n let current: TSNode | null = node.parent;\n while (current) {\n const tracked = functionNodeMap.get(current.id);\n if (tracked) return tracked;\n current = current.parent;\n }\n return fileId;\n }\n\n function closestEnclosingClassMethods(node: TSNode): Map<string, string> | undefined {\n let current: TSNode | null = node.parent;\n while (current) {\n if (current.type === 'function_definition') {\n const classNodeId = enclosingClassOf.get(current.id);\n if (classNodeId !== undefined) return classMethods.get(classNodeId);\n }\n current = current.parent;\n }\n return undefined;\n }\n\n // Pass 2: calls (see the function doc comment above for the\n // EXTRACTED/INFERRED policy).\n for (const call of descendantsOfType(root, ['call'])) {\n const fn = call.childForFieldName('function');\n if (!fn) continue;\n\n let targetId: string | null = null;\n let confidence: 'EXTRACTED' | 'INFERRED' = 'EXTRACTED';\n\n if (fn.type === 'identifier') {\n const name = fn.text;\n const sameFile = nameIndex.get(name);\n if (sameFile) {\n targetId = sameFile;\n } else {\n const viaImport = importIndex.get(name);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n } else if (fn.type === 'attribute') {\n const object = fn.childForFieldName('object');\n const property = fn.childForFieldName('attribute')?.text;\n if (object && property) {\n if (object.type === 'identifier' && object.text === 'self') {\n const methodId = closestEnclosingClassMethods(call)?.get(property);\n if (methodId) targetId = methodId;\n } else if (object.type === 'identifier') {\n const viaImport = importIndex.get(object.text);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n }\n }\n\n if (!targetId) continue; // unresolved callee (builtin, external value, ...) — no noisy guess\n const callerId = closestTrackedCaller(call);\n builder.addEdge({ source: callerId, target: targetId, relation: 'calls', confidence });\n }\n\n return builder.build();\n}\n","import * as fs from 'node:fs/promises';\nimport type { Node as TSNode } from 'web-tree-sitter';\nimport type { ExtractionResult } from '../types.js';\nimport {\n ExtractionBuilder,\n descendantsOfType,\n entityId,\n externalId,\n lineOf,\n namedChildren,\n resolveModuleRef,\n toPosix,\n} from './common.js';\nimport { createParser } from './wasmLoader.js';\n\n/**\n * Best-effort conversion of a required path's last segment into the\n * CamelCase constant name Ruby convention says it defines (`require_relative\n * './math'` -> `Math`, `require 'active_support/core_ext'` -> `CoreExt`).\n * Ruby's `require`/`require_relative` bind no local alias at all (unlike\n * every other language here), so this is the one available heuristic for\n * giving later `Constant.method(...)` calls something to resolve against —\n * it is a naming-convention guess, not a confirmed binding.\n */\nfunction conventionalConstantName(specifier: string): string {\n const lastSegment = specifier.split('/').filter(Boolean).pop() ?? specifier;\n return lastSegment\n .split('_')\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n}\n\n/** Text of a `string` node's `string_content` child (already unquoted), or '' for an empty literal. */\nfunction stringLiteralContent(node: TSNode): string | null {\n if (node.type !== 'string') return null;\n const content = namedChildren(node).find((c) => c.type === 'string_content');\n return content ? content.text : '';\n}\n\n/**\n * Structural extraction for .rb via web-tree-sitter (WASM, no native\n * compilation, no eval/exec of source content).\n *\n * Pattern mirrors typescript.ts, adapted to Ruby's shape: top-level\n * classes/modules and free `method`s (pass 1) -> every `call` node walked\n * once to special-case `require`/`require_relative` into import edges (Ruby\n * has no dedicated import AST node — these are plain method calls, per the\n * master prompt), then a second walk resolves the rest as method calls\n * (pass 2). A same-file callee — including an implicit- or explicit-`self`\n * call resolved against the enclosing class/module — is EXTRACTED; a call\n * through a `Constant.method(...)` receiver that only resolves via the\n * conventional-constant-name heuristic above is INFERRED. An unresolvable\n * callee produces no edge at all.\n *\n * Known, deliberate scope limit: a bare, paren-less, argument-less\n * identifier (`helper_top` with no parens or `()`) is genuinely ambiguous\n * with a local-variable reference at the grammar level — tree-sitter-ruby\n * itself represents it as a plain `identifier`, not a `call` — so this\n * extractor (like a human reading the AST alone) cannot tell them apart\n * and does not attempt to. Only calls that surface as an actual `call`\n * node (parens, and/or arguments, and/or an explicit receiver) are\n * resolved.\n *\n * `include`/`extend`/`prepend` (Ruby's mixin mechanism) become `mixes_in`\n * edges; `class Foo < Bar` becomes `inherits`. Ruby has no `implements`\n * equivalent.\n */\nexport async function extractRuby(filePath: string, displayPath?: string): Promise<ExtractionResult> {\n const parser = await createParser('ruby');\n\n const raw = await fs.readFile(filePath);\n const content = raw.toString('utf-8'); // replacement-decoded — never throws on invalid bytes\n\n const tree = parser.parse(content);\n if (!tree) {\n throw new Error(`extractRuby: parser produced no tree for ${filePath}`);\n }\n const root = tree.rootNode;\n\n const sourceFile = toPosix(displayPath ?? filePath);\n const builder = new ExtractionBuilder();\n const fileId = sourceFile;\n builder.addNode({ id: fileId, label: sourceFile, sourceFile, sourceLocation: 'L1' });\n\n /** Declared name (top-level function/class/module) -> our graph id. */\n const nameIndex = new Map<string, string>();\n /** tree-sitter node id -> our graph id, for every function/method entity we track. */\n const functionNodeMap = new Map<number, string>();\n /** graph id of a class/module -> method name -> our graph id. */\n const typeMethods = new Map<string, Map<string, string>>();\n /** tree-sitter method node id -> its enclosing class/module's graph id. */\n const enclosingTypeOf = new Map<number, string>();\n /** conventional constant name (derived from a require path) -> the module it came from. */\n const importIndex = new Map<string, ReturnType<typeof resolveModuleRef>>();\n\n function addModuleNode(ref: ReturnType<typeof resolveModuleRef>): void {\n if (builder.hasNode(ref.id)) return;\n builder.addNode({\n id: ref.id,\n label: ref.label,\n sourceFile: ref.external ? '<external>' : ref.id,\n sourceLocation: 'L1',\n });\n }\n\n function resolveHeritageTarget(name: string): string {\n const resolved = nameIndex.get(name);\n if (resolved) return resolved;\n const extId = externalId(name);\n if (!builder.hasNode(extId)) {\n builder.addNode({ id: extId, label: name, sourceFile: '<external>', sourceLocation: 'L0' });\n }\n return extId;\n }\n\n function handleTopLevelMethod(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `function ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n functionNodeMap.set(node.id, id);\n }\n\n function handleClassOrModule(node: TSNode, kind: 'class' | 'module'): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `${kind} ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n typeMethods.set(id, new Map());\n\n if (kind === 'class') {\n const superclass = node.childForFieldName('superclass');\n const base = superclass ? namedChildren(superclass)[0] : undefined;\n if (base) {\n builder.addEdge({\n source: id,\n target: resolveHeritageTarget(base.text),\n relation: 'inherits',\n confidence: 'EXTRACTED',\n });\n }\n }\n\n const body = node.childForFieldName('body');\n if (!body) return;\n const methods = typeMethods.get(id);\n for (const member of namedChildren(body)) {\n if (member.type === 'method') {\n const methodName = member.childForFieldName('name')?.text ?? '(anonymous)';\n const methodId = entityId(sourceFile, `${name}.${methodName}`);\n builder.addNode({\n id: methodId,\n label: `method ${name}.${methodName}`,\n sourceFile,\n sourceLocation: lineOf(member),\n });\n builder.addEdge({ source: id, target: methodId, relation: 'method', confidence: 'EXTRACTED' });\n methods?.set(methodName, methodId);\n functionNodeMap.set(member.id, methodId);\n enclosingTypeOf.set(member.id, id);\n } else if (member.type === 'call') {\n const methodField = member.childForFieldName('method')?.text;\n if (methodField !== 'include' && methodField !== 'extend' && methodField !== 'prepend') continue;\n const args = member.childForFieldName('arguments');\n for (const arg of args ? namedChildren(args) : []) {\n if (arg.type !== 'constant' && arg.type !== 'scoped_constant') continue;\n builder.addEdge({\n source: id,\n target: resolveHeritageTarget(arg.text),\n relation: 'mixes_in',\n confidence: 'EXTRACTED',\n });\n }\n }\n }\n }\n\n // Pass 1: top-level declarations (free methods, classes, modules).\n for (const child of namedChildren(root)) {\n switch (child.type) {\n case 'method':\n handleTopLevelMethod(child);\n break;\n case 'class':\n handleClassOrModule(child, 'class');\n break;\n case 'module':\n handleClassOrModule(child, 'module');\n break;\n default:\n break;\n }\n }\n\n function closestTrackedCaller(node: TSNode): string {\n let current: TSNode | null = node.parent;\n while (current) {\n const tracked = functionNodeMap.get(current.id);\n if (tracked) return tracked;\n current = current.parent;\n }\n return fileId;\n }\n\n function closestEnclosingTypeMethods(node: TSNode): Map<string, string> | undefined {\n let current: TSNode | null = node.parent;\n while (current) {\n if (current.type === 'method') {\n const typeId = enclosingTypeOf.get(current.id);\n if (typeId !== undefined) return typeMethods.get(typeId);\n }\n current = current.parent;\n }\n return undefined;\n }\n\n const allCalls = descendantsOfType(root, ['call']);\n\n // Pass 2a: `require`/`require_relative` — plain method calls in Ruby's\n // grammar, special-cased into import edges instead of `calls` edges.\n const requireCallIds = new Set<number>();\n for (const call of allCalls) {\n const methodName = call.childForFieldName('method')?.text;\n if (methodName !== 'require' && methodName !== 'require_relative') continue;\n const args = call.childForFieldName('arguments');\n const soleArg = args ? namedChildren(args) : [];\n if (soleArg.length !== 1) continue;\n const literal = stringLiteralContent(soleArg[0] as TSNode);\n if (literal === null) continue;\n\n requireCallIds.add(call.id);\n const ref = resolveModuleRef(sourceFile, literal);\n addModuleNode(ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n importIndex.set(conventionalConstantName(literal), ref);\n }\n\n // Pass 2b: every other call (see the function doc comment above for the\n // EXTRACTED/INFERRED policy).\n for (const call of allCalls) {\n if (requireCallIds.has(call.id)) continue;\n const methodName = call.childForFieldName('method')?.text;\n if (!methodName) continue;\n const receiver = call.childForFieldName('receiver');\n\n let targetId: string | null = null;\n let confidence: 'EXTRACTED' | 'INFERRED' = 'EXTRACTED';\n\n if (!receiver) {\n const viaEnclosingType = closestEnclosingTypeMethods(call)?.get(methodName);\n if (viaEnclosingType) {\n targetId = viaEnclosingType;\n } else {\n const sameFile = nameIndex.get(methodName);\n if (sameFile) targetId = sameFile;\n }\n } else if (receiver.type === 'self') {\n const methodId = closestEnclosingTypeMethods(call)?.get(methodName);\n if (methodId) targetId = methodId;\n } else if (receiver.type === 'constant' || receiver.type === 'scoped_constant') {\n const sameFileTypeId = nameIndex.get(receiver.text);\n const methodId = sameFileTypeId ? typeMethods.get(sameFileTypeId)?.get(methodName) : undefined;\n if (methodId) {\n targetId = methodId;\n } else {\n const viaImport = importIndex.get(receiver.text);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n }\n\n if (!targetId) continue; // unresolved callee (builtin, local var, ...) — no noisy guess\n const callerId = closestTrackedCaller(call);\n builder.addEdge({ source: callerId, target: targetId, relation: 'calls', confidence });\n }\n\n return builder.build();\n}\n","import * as fs from 'node:fs/promises';\nimport type { Node as TSNode } from 'web-tree-sitter';\nimport type { ExtractionResult } from '../types.js';\nimport {\n ExtractionBuilder,\n descendantsOfType,\n entityId,\n externalId,\n lineOf,\n namedChildren,\n resolveModuleRef,\n toPosix,\n} from './common.js';\nimport { createParser } from './wasmLoader.js';\n\n/**\n * Convert a Rust `use` path's `::`-joined segments into the relative-path\n * shape resolveModuleRef() understands: `crate`/`self` map to \"this\n * directory\" (`.`), each leading `super` walks up one directory, and\n * anything else (an external crate, `std`, ...) is left `::`-joined so\n * resolveModuleRef treats it as an external module specifier.\n */\nfunction convertUsePath(segments: string[]): string {\n const first = segments[0];\n if (first === 'crate' || first === 'self') {\n const rest = segments.slice(1);\n return rest.length ? `./${rest.join('/')}` : '.';\n }\n if (first === 'super') {\n let i = 0;\n while (segments[i] === 'super') i++;\n const ups = Array.from({ length: i }, () => '..').join('/');\n const rest = segments.slice(i);\n return rest.length ? `${ups}/${rest.join('/')}` : ups;\n }\n return segments.join('::');\n}\n\n/**\n * Structural extraction for .rs via web-tree-sitter (WASM, no native\n * compilation, no eval/exec of source content).\n *\n * Pattern mirrors typescript.ts, adapted to Rust's shape: top-level\n * structs/traits and free functions come from pass 1, but methods are\n * declared separately in `impl` blocks (inherent `impl Type { ... }` or\n * trait `impl Trait for Type { ... }`), so those are walked as their own\n * step and attached to whichever struct/trait `name` they target. Every\n * call_expression is then resolved (pass 2): a same-file callee, or a\n * `self.method()` call resolved against the enclosing impl block's type,\n * is EXTRACTED; a callee that only resolves through a `use`-imported local\n * binding (an imported item, or a module alias via `use ... as`) is\n * INFERRED — the \"cross-file second pass\" placeholder described in the\n * master prompt §3. It intentionally does not open and parse the\n * imported module to confirm the target. An unresolvable callee produces\n * no edge at all.\n *\n * `impl Trait for Type` is Rust's one heritage-like construct exposed\n * directly in the grammar, so it becomes an `implements` edge from `Type`\n * to `Trait`.\n */\nexport async function extractRust(filePath: string, displayPath?: string): Promise<ExtractionResult> {\n const parser = await createParser('rust');\n\n const raw = await fs.readFile(filePath);\n const content = raw.toString('utf-8'); // replacement-decoded — never throws on invalid bytes\n\n const tree = parser.parse(content);\n if (!tree) {\n throw new Error(`extractRust: parser produced no tree for ${filePath}`);\n }\n const root = tree.rootNode;\n\n const sourceFile = toPosix(displayPath ?? filePath);\n const builder = new ExtractionBuilder();\n const fileId = sourceFile;\n builder.addNode({ id: fileId, label: sourceFile, sourceFile, sourceLocation: 'L1' });\n\n /** Declared name (function/struct/trait) -> our graph id. */\n const nameIndex = new Map<string, string>();\n /** tree-sitter node id -> our graph id, for every function/method entity we track. */\n const functionNodeMap = new Map<number, string>();\n /** graph id of a struct/trait -> method name -> our graph id. */\n const typeMethods = new Map<string, Map<string, string>>();\n /** tree-sitter function_item (method) node id -> the owning impl block's type graph id. */\n const enclosingTypeOf = new Map<number, string>();\n /** local binding name (`use` item/alias) -> the module it came from. */\n const importIndex = new Map<string, ReturnType<typeof resolveModuleRef>>();\n\n function addModuleNode(ref: ReturnType<typeof resolveModuleRef>): void {\n if (builder.hasNode(ref.id)) return;\n builder.addNode({\n id: ref.id,\n label: ref.label,\n sourceFile: ref.external ? '<external>' : ref.id,\n sourceLocation: 'L1',\n });\n }\n\n function resolveTypeTarget(name: string): string {\n const resolved = nameIndex.get(name);\n if (resolved) return resolved;\n const extId = externalId(name);\n if (!builder.hasNode(extId)) {\n builder.addNode({ id: extId, label: name, sourceFile: '<external>', sourceLocation: 'L0' });\n }\n return extId;\n }\n\n function processUseArgument(node: TSNode): void {\n switch (node.type) {\n case 'identifier': {\n // `use foo;` — whole-module import, single segment.\n const ref = resolveModuleRef(sourceFile, convertUsePath([node.text]));\n addModuleNode(ref);\n importIndex.set(node.text, ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n break;\n }\n case 'scoped_identifier': {\n // `use std::fmt;` — single named item `fmt` from module `std`.\n const pathNode = node.childForFieldName('path');\n const nameNode = node.childForFieldName('name');\n if (!pathNode || !nameNode) break;\n const ref = resolveModuleRef(sourceFile, convertUsePath(pathNode.text.split('::')));\n addModuleNode(ref);\n importIndex.set(nameNode.text, ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports_from', confidence: 'EXTRACTED' });\n break;\n }\n case 'use_as_clause': {\n // `use crate::math as m;` — whole module aliased to `m`.\n const pathNode = node.childForFieldName('path');\n const aliasNode = node.childForFieldName('alias');\n if (!pathNode || !aliasNode) break;\n const ref = resolveModuleRef(sourceFile, convertUsePath(pathNode.text.split('::')));\n addModuleNode(ref);\n importIndex.set(aliasNode.text, ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n break;\n }\n case 'scoped_use_list': {\n // `use crate::math::{add, multiply};` — named items from a module.\n const pathNode = node.childForFieldName('path');\n const listNode = node.childForFieldName('list');\n if (!listNode) break;\n const prefixSegments = pathNode ? pathNode.text.split('::') : [];\n const ref = resolveModuleRef(sourceFile, convertUsePath(prefixSegments));\n addModuleNode(ref);\n let sawItem = false;\n for (const item of namedChildren(listNode)) {\n sawItem = true;\n if (item.type === 'identifier') {\n importIndex.set(item.text, ref);\n } else if (item.type === 'use_as_clause') {\n const alias = item.childForFieldName('alias')?.text;\n if (alias) importIndex.set(alias, ref);\n }\n // nested scoped_identifier / use_wildcard / `self` items: edge is\n // still emitted below, just no simple local binding to record.\n }\n if (sawItem) {\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports_from', confidence: 'EXTRACTED' });\n }\n break;\n }\n default:\n break; // `use foo::*;` (use_wildcard) or other rare forms — no clean binding to model\n }\n }\n\n function handleStructItem(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `struct ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n typeMethods.set(id, new Map());\n }\n\n function handleTraitItem(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `trait ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n }\n\n function handleFunctionItem(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `function ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n functionNodeMap.set(node.id, id);\n }\n\n function handleImplItem(node: TSNode): void {\n const typeName = node.childForFieldName('type')?.text;\n if (!typeName) return;\n const typeId = resolveTypeTarget(typeName);\n\n const traitName = node.childForFieldName('trait')?.text;\n if (traitName) {\n builder.addEdge({\n source: typeId,\n target: resolveTypeTarget(traitName),\n relation: 'implements',\n confidence: 'EXTRACTED',\n });\n }\n\n let methods = typeMethods.get(typeId);\n if (!methods) {\n methods = new Map();\n typeMethods.set(typeId, methods);\n }\n\n const body = node.childForFieldName('body');\n if (!body) return;\n for (const member of namedChildren(body)) {\n if (member.type !== 'function_item') continue;\n const methodName = member.childForFieldName('name')?.text ?? '(anonymous)';\n const methodId = entityId(sourceFile, `${typeName}.${methodName}`);\n builder.addNode({\n id: methodId,\n label: `method ${typeName}.${methodName}`,\n sourceFile,\n sourceLocation: lineOf(member),\n });\n builder.addEdge({ source: typeId, target: methodId, relation: 'method', confidence: 'EXTRACTED' });\n methods.set(methodName, methodId);\n functionNodeMap.set(member.id, methodId);\n enclosingTypeOf.set(member.id, typeId);\n }\n }\n\n // Pass 1: top-level declarations (imports, structs, traits, free\n // functions). Impl blocks are handled in their own pass below so every\n // struct/trait name is already registered before methods attach to it.\n const implNodes: TSNode[] = [];\n for (const child of namedChildren(root)) {\n switch (child.type) {\n case 'use_declaration': {\n const arg = child.childForFieldName('argument');\n if (arg) processUseArgument(arg);\n break;\n }\n case 'struct_item':\n handleStructItem(child);\n break;\n case 'trait_item':\n handleTraitItem(child);\n break;\n case 'function_item':\n handleFunctionItem(child);\n break;\n case 'impl_item':\n implNodes.push(child);\n break;\n default:\n break;\n }\n }\n for (const impl of implNodes) handleImplItem(impl);\n\n function closestTrackedCaller(node: TSNode): string {\n let current: TSNode | null = node.parent;\n while (current) {\n const tracked = functionNodeMap.get(current.id);\n if (tracked) return tracked;\n current = current.parent;\n }\n return fileId;\n }\n\n function closestEnclosingTypeMethods(node: TSNode): Map<string, string> | undefined {\n let current: TSNode | null = node.parent;\n while (current) {\n if (current.type === 'function_item') {\n const typeId = enclosingTypeOf.get(current.id);\n if (typeId !== undefined) return typeMethods.get(typeId);\n }\n current = current.parent;\n }\n return undefined;\n }\n\n // Pass 2: calls (see the function doc comment above for the\n // EXTRACTED/INFERRED policy).\n for (const call of descendantsOfType(root, ['call_expression'])) {\n const fn = call.childForFieldName('function');\n if (!fn) continue;\n\n let targetId: string | null = null;\n let confidence: 'EXTRACTED' | 'INFERRED' = 'EXTRACTED';\n\n if (fn.type === 'identifier') {\n const name = fn.text;\n const sameFile = nameIndex.get(name);\n if (sameFile) {\n targetId = sameFile;\n } else {\n const viaImport = importIndex.get(name);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n } else if (fn.type === 'field_expression') {\n const value = fn.childForFieldName('value');\n const field = fn.childForFieldName('field')?.text;\n if (value && field) {\n if (value.type === 'self') {\n const methodId = closestEnclosingTypeMethods(call)?.get(field);\n if (methodId) targetId = methodId;\n }\n }\n } else if (fn.type === 'scoped_identifier') {\n // `m::add(1, 2)` — call through a `use ... as m` module alias.\n const path = fn.childForFieldName('path')?.text;\n const name = fn.childForFieldName('name')?.text;\n if (path && name) {\n const viaImport = importIndex.get(path);\n if (viaImport) {\n targetId = viaImport.id;\n confidence = 'INFERRED';\n }\n }\n }\n\n if (!targetId) continue; // unresolved callee (builtin, external value, ...) — no noisy guess\n const callerId = closestTrackedCaller(call);\n builder.addEdge({ source: callerId, target: targetId, relation: 'calls', confidence });\n }\n\n return builder.build();\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Node as TSNode } from 'web-tree-sitter';\nimport type { ExtractionResult } from '../types.js';\nimport {\n ExtractionBuilder,\n descendantsOfType,\n entityId,\n externalId,\n lineOf,\n namedChildren,\n resolveModuleRef,\n toPosix,\n} from './common.js';\nimport { createParser } from './wasmLoader.js';\n\nfunction grammarForExtension(ext: string): 'typescript' | 'tsx' | 'javascript' {\n const lower = ext.toLowerCase();\n if (lower === '.tsx') return 'tsx';\n if (lower === '.jsx') return 'javascript';\n if (lower === '.ts' || lower === '.mts' || lower === '.cts') return 'typescript';\n return 'javascript'; // .js / .mjs / .cjs\n}\n\n/** Strip the surrounding quotes tree-sitter keeps on a `string` node's text. */\nfunction stripQuotes(text: string): string {\n if (text.length >= 2) {\n const first = text[0];\n const last = text[text.length - 1];\n if ((first === '\"' || first === \"'\" || first === '`') && first === last) {\n return text.slice(1, -1);\n }\n }\n return text;\n}\n\n/** The sole string-literal argument of a call, if that's exactly what it has (used for `require('x')` / `import('x')`). */\nfunction firstStringArgument(call: TSNode): string | null {\n const args = call.childForFieldName('arguments');\n if (!args) return null;\n const first = namedChildren(args)[0];\n if (!first || first.type !== 'string') return null;\n return stripQuotes(first.text);\n}\n\n/**\n * Structural extraction for .ts/.tsx/.js/.jsx via web-tree-sitter (WASM,\n * no native compilation, no eval/exec of source content).\n *\n * Pattern: parse -> walk the AST for top-level functions/classes/\n * interfaces/const-bound functions/imports/re-exports (pass 1) -> walk all\n * `call_expression`s and resolve each callee against what pass 1 saw\n * (pass 2). A same-file callee is EXTRACTED; a callee that resolves only\n * through an imported local binding (e.g. calling a function you imported,\n * or a member on a namespace import) is emitted as INFERRED — this is the\n * \"cross-file second pass\" placeholder described in the master prompt §3.\n * It intentionally does not open and parse the imported file to confirm\n * the target; a real multi-file resolver is future work (see\n * ARCHITECTURE.md). An unresolvable callee (a builtin, a call on some\n * arbitrary local value, etc.) produces no edge at all rather than a noisy\n * guess.\n */\nexport async function extractTypeScript(filePath: string, displayPath?: string): Promise<ExtractionResult> {\n const ext = path.extname(filePath);\n const grammar = grammarForExtension(ext);\n const parser = await createParser(grammar);\n\n const raw = await fs.readFile(filePath);\n const content = raw.toString('utf-8'); // replacement-decoded — never throws on invalid bytes\n\n const tree = parser.parse(content);\n if (!tree) {\n throw new Error(`extractTypeScript: parser produced no tree for ${filePath}`);\n }\n const root = tree.rootNode;\n\n const sourceFile = toPosix(displayPath ?? filePath);\n const builder = new ExtractionBuilder();\n const fileId = sourceFile;\n builder.addNode({ id: fileId, label: sourceFile, sourceFile, sourceLocation: 'L1' });\n\n /** Declared name (function/class/interface/top-level const) -> our graph id. */\n const nameIndex = new Map<string, string>();\n /** tree-sitter node id -> our graph id, for every function-like entity we track. */\n const functionNodeMap = new Map<number, string>();\n /** tree-sitter class_declaration node id -> method name -> our graph id. */\n const classMethods = new Map<number, Map<string, string>>();\n /** tree-sitter method_definition node id -> its enclosing class's node id. */\n const enclosingClassOf = new Map<number, number>();\n\n interface ImportBinding {\n ref: ReturnType<typeof resolveModuleRef>;\n /** The name as declared in the *source* module — undefined for namespace/default/require-whole\n * bindings, where the local name tells us nothing about what the target file actually calls it. */\n importedName?: string;\n kind: 'named' | 'namespace' | 'default';\n }\n /** local binding name (import, or CommonJS require()) -> where it came from. */\n const importIndex = new Map<string, ImportBinding>();\n\n function addModuleNode(ref: ReturnType<typeof resolveModuleRef>): void {\n if (builder.hasNode(ref.id)) return;\n builder.addNode({\n id: ref.id,\n label: ref.label,\n sourceFile: ref.external ? '<external>' : ref.id,\n sourceLocation: 'L1',\n });\n }\n\n /**\n * Resolve an import/require binding to the most specific target id we can\n * reasonably guess without opening the target file: a named import of a\n * same-repo module points at that module's *own* entityId for the name it\n * was declared under there (not the local alias here) — the same\n * deterministic id scheme means this will actually line up with the real\n * node once that file is extracted too. A namespace/require-whole binding\n * used via member access (`ns.foo()`) does the same with the accessed\n * property name. Anything else (default import, external package, bare\n * namespace call) falls back to the module node itself.\n */\n function importTargetId(binding: ImportBinding, property?: string): string {\n if (!binding.ref.external) {\n if (binding.kind === 'named' && binding.importedName) {\n return entityId(binding.ref.id, binding.importedName);\n }\n if (binding.kind === 'namespace' && property) {\n return entityId(binding.ref.id, property);\n }\n }\n return binding.ref.id;\n }\n\n function resolveHeritageTarget(name: string): string {\n const resolved = nameIndex.get(name);\n if (resolved) return resolved;\n const extId = externalId(name);\n if (!builder.hasNode(extId)) {\n builder.addNode({ id: extId, label: name, sourceFile: '<external>', sourceLocation: 'L0' });\n }\n return extId;\n }\n\n function handleFunctionDeclaration(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `function ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n functionNodeMap.set(node.id, id);\n }\n\n /** `const foo = require('bar')` / `const { a, b: c } = require('bar')` — register bindings only; pass 2 emits the actual `imports` edge when it walks this same call_expression. */\n function registerRequireBinding(nameNode: TSNode, ref: ReturnType<typeof resolveModuleRef>): void {\n if (nameNode.type === 'identifier') {\n importIndex.set(nameNode.text, { ref, kind: 'namespace' });\n return;\n }\n if (nameNode.type === 'object_pattern') {\n for (const prop of namedChildren(nameNode)) {\n if (prop.type === 'shorthand_property_identifier_pattern') {\n importIndex.set(prop.text, { ref, importedName: prop.text, kind: 'named' });\n } else if (prop.type === 'pair_pattern') {\n const key = prop.childForFieldName('key')?.text;\n const value = prop.childForFieldName('value')?.text;\n if (key && value) importIndex.set(value, { ref, importedName: key, kind: 'named' });\n }\n }\n }\n }\n\n function handleTopLevelVariableFunctions(node: TSNode): void {\n for (const declarator of namedChildren(node)) {\n if (declarator.type !== 'variable_declarator') continue;\n const value = declarator.childForFieldName('value');\n if (!value) continue;\n\n if (value.type === 'arrow_function' || value.type === 'function_expression') {\n const name = declarator.childForFieldName('name')?.text;\n if (!name) continue;\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `function ${name}`, sourceFile, sourceLocation: lineOf(declarator) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n functionNodeMap.set(value.id, id);\n continue;\n }\n\n if (value.type === 'call_expression') {\n const callee = value.childForFieldName('function');\n const specifier = callee?.type === 'identifier' && callee.text === 'require' ? firstStringArgument(value) : null;\n if (specifier) {\n const nameNode = declarator.childForFieldName('name');\n if (nameNode) {\n const ref = resolveModuleRef(sourceFile, specifier);\n addModuleNode(ref);\n registerRequireBinding(nameNode, ref);\n }\n }\n }\n }\n }\n\n function handleInterfaceDeclaration(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const id = entityId(sourceFile, name);\n builder.addNode({ id, label: `interface ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: id, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, id);\n }\n\n function handleClassDeclaration(node: TSNode): void {\n const name = node.childForFieldName('name')?.text ?? '(anonymous)';\n const classId = entityId(sourceFile, name);\n builder.addNode({ id: classId, label: `class ${name}`, sourceFile, sourceLocation: lineOf(node) });\n builder.addEdge({ source: fileId, target: classId, relation: 'contains', confidence: 'EXTRACTED' });\n nameIndex.set(name, classId);\n functionNodeMap.set(node.id, classId);\n\n const heritage = namedChildren(node).find((c) => c.type === 'class_heritage');\n if (heritage) {\n for (const clause of namedChildren(heritage)) {\n if (clause.type === 'extends_clause') {\n const base = clause.childForFieldName('value')?.text;\n if (base) {\n builder.addEdge({\n source: classId,\n target: resolveHeritageTarget(base),\n relation: 'inherits',\n confidence: 'EXTRACTED',\n });\n }\n } else if (clause.type === 'implements_clause') {\n for (const iface of namedChildren(clause)) {\n builder.addEdge({\n source: classId,\n target: resolveHeritageTarget(iface.text),\n relation: 'implements',\n confidence: 'EXTRACTED',\n });\n }\n }\n }\n }\n\n const methods = new Map<string, string>();\n classMethods.set(node.id, methods);\n\n const body = node.childForFieldName('body');\n if (body) {\n for (const member of namedChildren(body)) {\n if (member.type !== 'method_definition') continue;\n const methodName = member.childForFieldName('name')?.text ?? '(anonymous)';\n const methodId = entityId(sourceFile, `${name}.${methodName}`);\n builder.addNode({\n id: methodId,\n label: `method ${name}.${methodName}`,\n sourceFile,\n sourceLocation: lineOf(member),\n });\n builder.addEdge({ source: classId, target: methodId, relation: 'method', confidence: 'EXTRACTED' });\n methods.set(methodName, methodId);\n functionNodeMap.set(member.id, methodId);\n enclosingClassOf.set(member.id, node.id);\n }\n }\n }\n\n function handleImport(node: TSNode): void {\n const sourceNode = node.childForFieldName('source');\n if (!sourceNode) return;\n const ref = resolveModuleRef(sourceFile, stripQuotes(sourceNode.text));\n addModuleNode(ref);\n\n const clause = namedChildren(node).find((c) => c.type === 'import_clause');\n if (!clause) return; // side-effect-only import, e.g. `import './setup.js'`\n\n let sawNamed = false;\n let sawWhole = false;\n\n for (const child of namedChildren(clause)) {\n if (child.type === 'named_imports') {\n sawNamed = true;\n for (const specifierNode of namedChildren(child)) {\n const importedName = specifierNode.childForFieldName('name')?.text;\n const localName = specifierNode.childForFieldName('alias')?.text ?? importedName;\n if (localName) importIndex.set(localName, { ref, importedName, kind: 'named' });\n }\n } else if (child.type === 'namespace_import') {\n sawWhole = true;\n const localName = namedChildren(child)[0]?.text;\n if (localName) importIndex.set(localName, { ref, kind: 'namespace' });\n } else if (child.type === 'identifier') {\n sawWhole = true;\n importIndex.set(child.text, { ref, kind: 'default' });\n }\n }\n\n if (sawNamed) {\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports_from', confidence: 'EXTRACTED' });\n }\n if (sawWhole) {\n builder.addEdge({ source: fileId, target: ref.id, relation: 'imports', confidence: 'EXTRACTED' });\n }\n }\n\n function handleReExport(node: TSNode): void {\n const sourceNode = node.childForFieldName('source');\n if (!sourceNode) return;\n const ref = resolveModuleRef(sourceFile, stripQuotes(sourceNode.text));\n addModuleNode(ref);\n builder.addEdge({ source: fileId, target: ref.id, relation: 're_exports', confidence: 'EXTRACTED' });\n }\n\n function unwrapExport(node: TSNode): TSNode | null {\n if (node.type !== 'export_statement') return node;\n return node.childForFieldName('declaration');\n }\n\n // Pass 1: top-level declarations (functions, classes, interfaces,\n // const-bound functions, imports, re-exports).\n for (const child of namedChildren(root)) {\n if (child.type === 'import_statement') {\n handleImport(child);\n continue;\n }\n if (child.type === 'export_statement' && child.childForFieldName('source')) {\n handleReExport(child);\n continue;\n }\n\n const effective = unwrapExport(child);\n if (!effective) continue;\n\n switch (effective.type) {\n case 'function_declaration':\n case 'generator_function_declaration':\n handleFunctionDeclaration(effective);\n break;\n case 'class_declaration':\n handleClassDeclaration(effective);\n break;\n case 'interface_declaration':\n handleInterfaceDeclaration(effective);\n break;\n case 'lexical_declaration':\n case 'variable_declaration':\n handleTopLevelVariableFunctions(effective);\n break;\n default:\n break;\n }\n }\n\n function closestTrackedCaller(node: TSNode): string {\n let current: TSNode | null = node.parent;\n while (current) {\n const tracked = functionNodeMap.get(current.id);\n if (tracked) return tracked;\n current = current.parent;\n }\n return fileId;\n }\n\n function closestEnclosingClassMethods(node: TSNode): Map<string, string> | undefined {\n let current: TSNode | null = node.parent;\n while (current) {\n if (current.type === 'method_definition') {\n const classNodeId = enclosingClassOf.get(current.id);\n if (classNodeId !== undefined) return classMethods.get(classNodeId);\n }\n current = current.parent;\n }\n return undefined;\n }\n\n // Pass 2: calls (see the function doc comment above for the\n // EXTRACTED/INFERRED policy).\n for (const call of descendantsOfType(root, ['call_expression'])) {\n const fn = call.childForFieldName('function');\n if (!fn) continue;\n\n // CommonJS `require('x')` and dynamic `import('x')` are import\n // expressions wearing a call's clothing — treat them as `imports`\n // edges (module-level, EXTRACTED) rather than `calls`, wherever in the\n // tree they occur (module scope, or lazily inside a function).\n if ((fn.type === 'identifier' && fn.text === 'require') || fn.type === 'import') {\n const specifier = firstStringArgument(call);\n if (specifier) {\n const ref = resolveModuleRef(sourceFile, specifier);\n addModuleNode(ref);\n builder.addEdge({\n source: closestTrackedCaller(call),\n target: ref.id,\n relation: 'imports',\n confidence: 'EXTRACTED',\n });\n continue;\n }\n }\n\n let targetId: string | null = null;\n let confidence: 'EXTRACTED' | 'INFERRED' = 'EXTRACTED';\n\n if (fn.type === 'identifier') {\n const name = fn.text;\n const sameFile = nameIndex.get(name);\n if (sameFile) {\n targetId = sameFile;\n } else {\n const binding = importIndex.get(name);\n if (binding) {\n targetId = importTargetId(binding);\n confidence = 'INFERRED';\n }\n }\n } else if (fn.type === 'member_expression') {\n const object = fn.childForFieldName('object');\n const property = fn.childForFieldName('property')?.text;\n if (object && property) {\n if (object.type === 'this') {\n const methodId = closestEnclosingClassMethods(call)?.get(property);\n if (methodId) targetId = methodId;\n } else if (object.type === 'identifier') {\n const binding = importIndex.get(object.text);\n if (binding) {\n targetId = importTargetId(binding, property);\n confidence = 'INFERRED';\n }\n }\n }\n }\n\n if (!targetId) continue; // unresolved callee (builtin, external value, ...) — no noisy guess\n const callerId = closestTrackedCaller(call);\n builder.addEdge({ source: callerId, target: targetId, relation: 'calls', confidence });\n }\n\n return builder.build();\n}\n","import { z } from 'zod';\nimport type { ExtractionResult } from './types.js';\n\n/**\n * Runtime schema for ExtractionResult (see types.ts + master prompt §2).\n * Every extractor's output is validated against this before buildGraph()\n * merges it — a malformed extractor must fail loudly, never silently\n * corrupt the graph.\n */\nexport const ConfidenceSchema = z.enum(['EXTRACTED', 'INFERRED', 'AMBIGUOUS']);\n\nexport const RelationSchema = z.enum([\n 'calls',\n 'imports',\n 'imports_from',\n 'inherits',\n 'implements',\n 'mixes_in',\n 'embeds',\n 'references',\n 'contains',\n 'method',\n 're_exports',\n]);\n\nexport const GraphNodeSchema = z.object({\n id: z.string().min(1, 'node id must be non-empty'),\n label: z.string(),\n sourceFile: z.string(),\n sourceLocation: z.string(),\n});\n\nexport const GraphEdgeSchema = z.object({\n source: z.string().min(1, 'edge source must be non-empty'),\n target: z.string().min(1, 'edge target must be non-empty'),\n relation: RelationSchema,\n confidence: ConfidenceSchema,\n});\n\nexport const ExtractionResultSchema = z.object({\n nodes: z.array(GraphNodeSchema),\n edges: z.array(GraphEdgeSchema),\n});\n\nexport interface ExtractionValidationIssue {\n path: Array<string | number>;\n message: string;\n}\n\n/** Thrown by validateExtraction() on schema mismatch. Carries the raw zod issues. */\nexport class ExtractionValidationError extends Error {\n readonly issues: ExtractionValidationIssue[];\n\n constructor(message: string, issues: ExtractionValidationIssue[]) {\n super(message);\n this.name = 'ExtractionValidationError';\n this.issues = issues;\n }\n}\n\n/**\n * Validate an unknown value (typically an extractor's return value) against\n * the ExtractionResult schema. Throws ExtractionValidationError with a clear,\n * human-readable message on mismatch instead of letting malformed data reach\n * buildGraph().\n */\nexport function validateExtraction(value: unknown, context?: string): ExtractionResult {\n const result = ExtractionResultSchema.safeParse(value);\n if (!result.success) {\n const label = context ? ` (${context})` : '';\n const issues: ExtractionValidationIssue[] = result.error.issues.map((issue) => ({\n path: issue.path as Array<string | number>,\n message: issue.message,\n }));\n const details = issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ');\n throw new ExtractionValidationError(`Invalid ExtractionResult${label}: ${details}`, issues);\n }\n return result.data;\n}\n","import Graph from 'graphology';\nimport { validateExtraction } from './schema.js';\nimport type { Confidence, ExtractionResult } from './types.js';\n\nconst CONFIDENCE_RANK: Record<Confidence, number> = { EXTRACTED: 3, INFERRED: 2, AMBIGUOUS: 1 };\n\nfunction strongerConfidence(a: Confidence, b: Confidence): Confidence {\n return CONFIDENCE_RANK[a] >= CONFIDENCE_RANK[b] ? a : b;\n}\n\nfunction ensureNode(graph: Graph, id: string): void {\n if (graph.hasNode(id)) return;\n // An edge endpoint that never appeared in any extraction's `nodes` array —\n // shouldn't happen with a well-behaved extractor, but auto-vivify a\n // minimal placeholder rather than let addEdge throw and abort the merge.\n graph.addNode(id, { label: id, sourceFile: '<unknown>', sourceLocation: 'L0' });\n}\n\n/**\n * Merge per-file extraction results into one graphology graph.\n *\n * Every extraction is validated against the ExtractionResult schema before\n * anything is added to the graph — a single malformed extraction throws\n * (via validateExtraction()/ExtractionValidationError) before any node from\n * *any* extraction is merged, so a bad extractor can never silently\n * corrupt a graph that also contains good data.\n *\n * Nodes and edges are sorted before being added so the resulting graph (and\n * the graph.json ultimately exported from it) is deterministic regardless\n * of the order files were extracted in. Duplicate edges — same\n * source/target/relation, e.g. two different call sites resolving to the\n * same callee — are merged into a single edge, keeping the strongest\n * confidence seen (EXTRACTED > INFERRED > AMBIGUOUS) rather than being\n * counted as parallel edges (the schema has no call-count/weight field, so\n * \"A calls B\" is either true or it isn't). Multiple distinct relations\n * between the same pair (e.g. a file both `imports` and `imports_from` the\n * same module) are kept as separate edges.\n */\nexport function buildGraph(extractions: ExtractionResult[]): Graph {\n const graph = new Graph({ type: 'directed', multi: true, allowSelfLoops: true });\n\n const validated = extractions.map((extraction, index) =>\n validateExtraction(extraction, `extraction #${index}`),\n );\n\n const allNodes = validated.flatMap((extraction) => extraction.nodes);\n const allEdges = validated.flatMap((extraction) => extraction.edges);\n\n const sortedNodes = [...allNodes].sort((a, b) => a.id.localeCompare(b.id));\n for (const node of sortedNodes) {\n if (graph.hasNode(node.id)) continue;\n graph.addNode(node.id, {\n label: node.label,\n sourceFile: node.sourceFile,\n sourceLocation: node.sourceLocation,\n });\n }\n\n const sortedEdges = [...allEdges].sort(\n (a, b) =>\n a.source.localeCompare(b.source) ||\n a.target.localeCompare(b.target) ||\n a.relation.localeCompare(b.relation),\n );\n\n for (const edge of sortedEdges) {\n ensureNode(graph, edge.source);\n ensureNode(graph, edge.target);\n\n const key = `${edge.source}|${edge.relation}|${edge.target}`;\n if (graph.hasEdge(key)) {\n const existing = graph.getEdgeAttribute(key, 'confidence') as Confidence;\n graph.setEdgeAttribute(key, 'confidence', strongerConfidence(existing, edge.confidence));\n continue;\n }\n graph.addEdgeWithKey(key, edge.source, edge.target, {\n relation: edge.relation,\n confidence: edge.confidence,\n });\n }\n\n return graph;\n}\n","import type { ExtractionResult } from './types.js';\n\n/**\n * Cross-file reference resolution — the pass the per-file extractors can't\n * do alone. An extractor guesses an import target's id from the specifier\n * text (`import { scoreNodes } from './query.js'` → `src/query.js::scoreNodes`)\n * without opening the target file, so in a TypeScript repo the guess carries\n * the wrong extension (`.js` vs the real `src/query.ts`), and extensionless\n * or directory imports (`'./utils'` → `src/utils`) miss entirely. Once every\n * file is extracted we know the full set of real node ids, so guessed ids\n * that don't exist can be re-pointed at the single real node they were\n * clearly aiming for — turning phantom auto-vivified endpoints into edges\n * that reach the actual definition (this is what makes `graphify affected`\n * see cross-file callers).\n *\n * Deliberately conservative: a guess is only re-pointed when exactly ONE\n * real candidate matches; anything ambiguous or unknown is left alone\n * (buildGraph auto-vivifies it as before). Edge confidence is untouched —\n * the call target is still inferred, it just lands on a real node now.\n */\n\nconst CODE_EXTENSIONS = [\n '.ts', '.tsx', '.mts', '.cts',\n '.js', '.jsx', '.mjs', '.cjs',\n '.py', '.go', '.rs', '.java', '.cs', '.rb',\n];\n\n/** Ids that name things outside the extracted file set — never remap candidates. */\nfunction isOpaque(id: string): boolean {\n return id.startsWith('module:') || id.startsWith('external:') || id.startsWith('db:');\n}\n\nfunction stripKnownExtension(p: string): string | null {\n for (const ext of CODE_EXTENSIONS) {\n if (p.endsWith(ext)) return p.slice(0, -ext.length);\n }\n return null;\n}\n\n/** All the real file paths a guessed path could have meant: other extensions on the same stem, or the directory's index file. */\nfunction candidatePaths(guessed: string): string[] {\n const stem = stripKnownExtension(guessed) ?? guessed;\n const candidates: string[] = [];\n for (const ext of CODE_EXTENSIONS) candidates.push(`${stem}${ext}`);\n for (const ext of CODE_EXTENSIONS) candidates.push(`${guessed}/index${ext}`);\n if (stem !== guessed) {\n for (const ext of CODE_EXTENSIONS) candidates.push(`${stem}/index${ext}`);\n }\n return candidates.filter((c) => c !== guessed);\n}\n\n/** The unique real id `guessed` could resolve to, or null when unknown/ambiguous. */\nfunction uniqueMatch(guessed: string, candidates: string[], realIds: ReadonlySet<string>): string | null {\n const matches = new Set<string>();\n for (const candidate of candidates) {\n if (realIds.has(candidate)) matches.add(candidate);\n }\n if (matches.size !== 1) return null;\n return [...matches][0] as string;\n}\n\nexport interface ResolveStats {\n /** Edge endpoints re-pointed from a guessed id to a real node id. */\n resolvedEndpoints: number;\n /** Placeholder module nodes dropped because the real file node replaced them. */\n droppedPlaceholders: number;\n}\n\n/**\n * Mutates `extractions` in place: re-points guessed edge endpoints at real\n * node ids and drops the placeholder module nodes those guesses created.\n */\nexport function resolveCrossFileReferences(extractions: ExtractionResult[]): ResolveStats {\n const realIds = new Set<string>();\n const realFiles = new Set<string>();\n for (const extraction of extractions) {\n for (const node of extraction.nodes) realIds.add(node.id);\n for (const node of extraction.nodes) {\n const sep = node.id.indexOf('::');\n if (sep > 0) realFiles.add(node.id.slice(0, sep));\n }\n for (const edge of extraction.edges) {\n if (edge.relation === 'contains') realFiles.add(edge.source);\n }\n }\n\n const remap = new Map<string, string>();\n\n const resolveId = (id: string): string | null => {\n if (isOpaque(id)) return null;\n const cached = remap.get(id);\n if (cached !== undefined) return cached;\n\n const sep = id.indexOf('::');\n let resolved: string | null;\n if (sep > 0) {\n // Guessed entity: only ever a phantom (extractors never create nodes\n // for these), so an existing id needs no fixing.\n if (realIds.has(id)) return null;\n const guessedPath = id.slice(0, sep);\n const name = id.slice(sep);\n const candidates = candidatePaths(guessedPath).map((p) => `${p}${name}`);\n resolved = uniqueMatch(id, candidates, realIds);\n } else {\n // Guessed module/file: the extractor DID add a placeholder node for\n // it, so it is in realIds — what matters is whether it's a really\n // extracted file. Check against realFiles, and remap only onto real\n // files so a file reference never lands on some non-file node.\n if (realFiles.has(id)) return null;\n resolved = uniqueMatch(id, candidatePaths(id), realFiles);\n }\n if (resolved !== null) remap.set(id, resolved);\n return resolved;\n };\n\n let resolvedEndpoints = 0;\n for (const extraction of extractions) {\n for (const edge of extraction.edges) {\n const source = resolveId(edge.source);\n if (source !== null) {\n edge.source = source;\n resolvedEndpoints++;\n }\n const target = resolveId(edge.target);\n if (target !== null) {\n edge.target = target;\n resolvedEndpoints++;\n }\n }\n }\n\n // Placeholder module nodes (added by extractors for guessed same-repo\n // imports) whose id was remapped now duplicate the real file node — drop\n // them so they don't linger as isolated near-duplicates.\n let droppedPlaceholders = 0;\n for (const extraction of extractions) {\n const before = extraction.nodes.length;\n extraction.nodes = extraction.nodes.filter((node) => !remap.has(node.id));\n droppedPlaceholders += before - extraction.nodes.length;\n }\n\n return { resolvedEndpoints, droppedPlaceholders };\n}\n","import { createHash } from 'node:crypto';\nimport Graph from 'graphology';\n// A pure-JS, graphology-native Leiden implementation — extracted from the\n// upstream graphology monorepo's own (never separately published)\n// src/communities-leiden, repackaged with an optional `maxIterations` cap.\n// No native compilation (no .node bindings) — same \"no native\n// compilation\" constraint as the rest of this package. See v2 notes below.\nimport leiden from '@aflsolutions/graphology-communities-leiden';\nimport louvain from 'graphology-communities-louvain';\n\n/** Fixed seed so repeated runs on the same graph explore ties identically. */\nconst FIXED_SEED = 0x5eed_1234;\n\n/** mulberry32 — small, dependency-free, deterministic PRNG. */\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return function next(): number {\n a = (a + 0x6d2b79f5) | 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\ninterface EdgeEntry {\n key: string;\n source: string;\n target: string;\n attributes: Record<string, unknown>;\n}\n\n/**\n * Build a copy of `graph` with nodes and edges (re-)inserted in sorted\n * order, so the clustering algorithm's own internal iteration — and\n * therefore its tie-breaking — is fed a canonical order regardless of how\n * the input graph happened to be constructed (master prompt §4: \"sort\n * nodes/edges before feeding the algorithm\").\n */\nfunction sortedWorkingCopy(graph: Graph): Graph {\n const copy = new Graph({ type: graph.type, multi: graph.multi, allowSelfLoops: graph.allowSelfLoops });\n\n const nodeIds = graph.nodes().sort((a, b) => a.localeCompare(b));\n for (const id of nodeIds) {\n copy.addNode(id, { ...graph.getNodeAttributes(id) });\n }\n\n const edgeEntries: EdgeEntry[] = [];\n graph.forEachEdge((edge, attributes, source, target) => {\n edgeEntries.push({ key: edge, source, target, attributes });\n });\n edgeEntries.sort(\n (a, b) =>\n a.source.localeCompare(b.source) ||\n a.target.localeCompare(b.target) ||\n String(a.attributes.relation).localeCompare(String(b.attributes.relation)),\n );\n for (const entry of edgeEntries) {\n copy.addEdgeWithKey(entry.key, entry.source, entry.target, { ...entry.attributes });\n }\n\n return copy;\n}\n\nexport type ClusterAlgorithm = 'louvain' | 'leiden';\n\nexport interface ClusterOptions {\n /**\n * `louvain` (default, v1 behavior, unchanged) or `leiden` (v2: better\n * community quality / guaranteed well-connectedness, via\n * `@aflsolutions/graphology-communities-leiden` — see master prompt's\n * v2 upgrade ideas, \"Real Leiden clustering\"). Both run deterministically\n * against a sorted working copy with the same fixed-seed PRNG.\n */\n algorithm?: ClusterAlgorithm;\n /**\n * Leiden-only: hard cap on outer iterations, for very large graphs where\n * full convergence is expensive and the last iterations buy little\n * additional modularity. Ignored for `algorithm: 'louvain'`.\n */\n maxIterations?: number;\n}\n\n/**\n * @aflsolutions/graphology-communities-leiden (like upstream graphology's\n * own Leiden) only implements the undirected case — it throws on a graph\n * whose edges are all directed. Community detection is inherently an\n * undirected-connectivity notion anyway (classic Louvain/Leiden\n * modularity is defined over undirected graphs), so we run Leiden against\n * an undirected copy and copy the resulting `community` assignment back\n * onto `working` by node id.\n */\nfunction toUndirectedCopy(graph: Graph): Graph {\n const copy = new Graph({ type: 'undirected', multi: true, allowSelfLoops: graph.allowSelfLoops });\n graph.forEachNode((nodeId, attributes) => copy.addNode(nodeId, { ...attributes }));\n graph.forEachEdge((edgeKey, attributes, source, target) => {\n copy.addEdgeWithKey(edgeKey, source, target, { ...attributes });\n });\n return copy;\n}\n\nfunction runAlgorithm(working: Graph, options: ClusterOptions): void {\n const rng = mulberry32(FIXED_SEED);\n if (options.algorithm === 'leiden') {\n const undirected = toUndirectedCopy(working);\n leiden.assign(undirected, { rng, maxIterations: options.maxIterations ?? 0 });\n undirected.forEachNode((nodeId, attributes) => {\n working.setNodeAttribute(nodeId, 'community', attributes.community);\n });\n return;\n }\n louvain.assign(working, { rng });\n}\n\n/**\n * Community detection — Louvain by default (v1, unchanged), or Leiden\n * (v2, `{ algorithm: 'leiden' }`) for better-quality, guaranteed\n * well-connected communities on the same graph. Deterministic: runs\n * against a sorted working copy with a fixed RNG seed, then copies the\n * resulting `community` assignment back onto the original graph by node id\n * (so `cluster()` still mutates and returns the graph instance it was\n * given). Labels each community after its highest-degree (\"hub\") member;\n * no LLM required for a usable baseline. Also stamps a `communityHash`\n * (sha256 of the community's sorted member ids) so `--cluster-only` can\n * tell which communities actually changed vs. merely being relabeled with\n * a different arbitrary index next run.\n */\nexport function cluster(graph: Graph, options: ClusterOptions = {}): Graph {\n if (graph.order === 0) return graph;\n\n const working = sortedWorkingCopy(graph);\n runAlgorithm(working, options);\n\n // Highest-degree member per community, computed on the sorted copy so\n // ties break on node id deterministically.\n const hubs = new Map<number, { id: string; degree: number }>();\n working.forEachNode((nodeId) => {\n const community = working.getNodeAttribute(nodeId, 'community') as number;\n const degree = working.degree(nodeId);\n const current = hubs.get(community);\n if (!current || degree > current.degree) {\n hubs.set(community, { id: nodeId, degree });\n }\n });\n\n const membersByCommunity = new Map<number, string[]>();\n working.forEachNode((nodeId) => {\n const community = working.getNodeAttribute(nodeId, 'community') as number;\n const list = membersByCommunity.get(community);\n if (list) list.push(nodeId);\n else membersByCommunity.set(community, [nodeId]);\n });\n\n const labelByCommunity = new Map<number, string>();\n const hashByCommunity = new Map<number, string>();\n for (const [community, members] of membersByCommunity) {\n members.sort((a, b) => a.localeCompare(b));\n hashByCommunity.set(community, createHash('sha256').update(members.join('\\n')).digest('hex'));\n\n const hub = hubs.get(community);\n const hubLabel = hub ? (working.getNodeAttribute(hub.id, 'label') as string) : undefined;\n labelByCommunity.set(community, hubLabel && hubLabel.length > 0 ? hubLabel : `community-${community}`);\n }\n\n working.forEachNode((nodeId) => {\n const community = working.getNodeAttribute(nodeId, 'community') as number;\n graph.mergeNodeAttributes(nodeId, {\n community,\n communityLabel: labelByCommunity.get(community),\n communityHash: hashByCommunity.get(community),\n });\n });\n\n return graph;\n}\n","import type Graph from 'graphology';\nimport type { Analysis, Confidence } from './types.js';\n\n/** A node needs at least this many total connections to ever be a \"god node\", regardless of graph size. */\nconst ABSOLUTE_DEGREE_FLOOR = 10;\n/** ...and needs to be at least this many times the graph's mean degree. */\nconst MEAN_DEGREE_MULTIPLIER = 3;\n/** Cap how many items of a given kind get spelled out in a single message. */\nconst MAX_LISTED = 10;\n\nfunction truncatedList(items: string[]): string {\n const shown = items.slice(0, MAX_LISTED).join(', ');\n return items.length > MAX_LISTED ? `${shown}, ...` : shown;\n}\n\n/** Connected components treating the (directed) graph as undirected — reachability via any edge direction. */\nfunction connectedComponents(graph: Graph): string[][] {\n const visited = new Set<string>();\n const components: string[][] = [];\n const sortedNodes = [...graph.nodes()].sort((a, b) => a.localeCompare(b));\n\n for (const start of sortedNodes) {\n if (visited.has(start)) continue;\n const component: string[] = [];\n const queue: string[] = [start];\n visited.add(start);\n\n while (queue.length > 0) {\n const current = queue.shift() as string;\n component.push(current);\n const neighbors = [...graph.neighbors(current)].sort((a, b) => a.localeCompare(b));\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n visited.add(neighbor);\n queue.push(neighbor);\n }\n }\n }\n\n component.sort((a, b) => a.localeCompare(b));\n components.push(component);\n }\n\n components.sort((a, b) => b.length - a.length || (a[0] ?? '').localeCompare(b[0] ?? ''));\n return components;\n}\n\nfunction labelOf(graph: Graph, id: string): string {\n return (graph.getNodeAttribute(id, 'label') as string | undefined) ?? id;\n}\n\n/**\n * Surface god-nodes (excessive fan-in/out), structural surprises (self\n * references, AMBIGUOUS edges), and open questions (isolated nodes,\n * disconnected components) for a human to review in GRAPH_REPORT.md.\n */\nexport function analyze(graph: Graph): Analysis {\n const godNodes: string[] = [];\n const surprises: string[] = [];\n const openQuestions: string[] = [];\n\n if (graph.order === 0) {\n openQuestions.push(\n 'The graph is empty — no nodes were extracted. Check detect()/extract() coverage for this codebase.',\n );\n return { godNodes, surprises, openQuestions };\n }\n\n const degreeEntries = [...graph.nodes()]\n .map((id) => ({ id, degree: graph.degree(id) }))\n .sort((a, b) => a.id.localeCompare(b.id));\n const meanDegree = degreeEntries.reduce((sum, e) => sum + e.degree, 0) / degreeEntries.length;\n const threshold = Math.max(ABSOLUTE_DEGREE_FLOOR, meanDegree * MEAN_DEGREE_MULTIPLIER);\n\n for (const { id, degree } of degreeEntries) {\n if (degree > 0 && degree >= threshold) {\n godNodes.push(id);\n surprises.push(\n `${labelOf(graph, id)} has ${degree} connections (fan-in + fan-out) — well above the graph ` +\n `average of ${meanDegree.toFixed(1)}. Likely a god node / hotspot worth reviewing for ` +\n 'excessive coupling.',\n );\n }\n }\n\n graph.forEachEdge((_edge, attributes, source, target) => {\n if (source === target) {\n surprises.push(`${labelOf(graph, source)} has a self-referential \"${String(attributes.relation)}\" edge.`);\n }\n });\n\n const ambiguousEdges: string[] = [];\n graph.forEachEdge((_edge, attributes, source, target) => {\n if ((attributes.confidence as Confidence) === 'AMBIGUOUS') {\n ambiguousEdges.push(\n `${labelOf(graph, source)} --${String(attributes.relation)}--> ${labelOf(graph, target)}`,\n );\n }\n });\n if (ambiguousEdges.length > 0) {\n ambiguousEdges.sort((a, b) => a.localeCompare(b));\n openQuestions.push(\n `${ambiguousEdges.length} edge(s) are marked AMBIGUOUS and need human review: ` +\n truncatedList(ambiguousEdges),\n );\n }\n\n const isolated = degreeEntries.filter((e) => e.degree === 0).map((e) => e.id);\n if (isolated.length > 0) {\n openQuestions.push(\n `${isolated.length} node(s) have no incoming or outgoing edges (${truncatedList(isolated)}) — ` +\n 'dead code, an entry point, or a gap in extraction?',\n );\n }\n\n const components = connectedComponents(graph);\n if (components.length > 1) {\n const largest = components[0] as string[];\n openQuestions.push(\n `The graph has ${components.length} disconnected components — the largest has ${largest.length} ` +\n 'node(s). Confirm this reflects real module boundaries rather than missed cross-file edges.',\n );\n }\n\n return { godNodes, surprises, openQuestions };\n}\n","import type Graph from 'graphology';\nimport type { Analysis } from './types.js';\n\nfunction labelOf(graph: Graph, id: string): string {\n return (graph.getNodeAttribute(id, 'label') as string | undefined) ?? id;\n}\n\nfunction bulletList(items: string[]): string {\n if (items.length === 0) return '_None found._';\n return items.map((item) => `- ${item}`).join('\\n');\n}\n\ninterface CommunitySummary {\n label: string;\n members: string[];\n}\n\nfunction summarizeCommunities(graph: Graph): CommunitySummary[] {\n const byCommunity = new Map<number, CommunitySummary>();\n graph.forEachNode((nodeId, attributes) => {\n const community = attributes.community as number | undefined;\n if (community === undefined) return;\n const label = (attributes.communityLabel as string | undefined) ?? `community-${community}`;\n const existing = byCommunity.get(community);\n if (existing) {\n existing.members.push(nodeId);\n } else {\n byCommunity.set(community, { label, members: [nodeId] });\n }\n });\n\n const summaries = [...byCommunity.values()];\n for (const summary of summaries) {\n summary.members.sort((a, b) => a.localeCompare(b));\n }\n summaries.sort((a, b) => b.members.length - a.members.length || a.label.localeCompare(b.label));\n return summaries;\n}\n\n/**\n * Render the plain-language GRAPH_REPORT.md content: a short summary,\n * community breakdown, god nodes, structural surprises, and open\n * questions — everything a human (or an agent) needs to sanity-check a\n * freshly built graph before trusting it.\n */\nexport function renderReport(graph: Graph, analysis: Analysis, now: Date = new Date()): string {\n const generatedAt = now.toISOString();\n const communities = summarizeCommunities(graph);\n\n const lines: string[] = [];\n lines.push('# Graph Report');\n lines.push('');\n lines.push(`Generated: ${generatedAt}`);\n lines.push('');\n lines.push('## Summary');\n lines.push('');\n lines.push(`- **Nodes:** ${graph.order}`);\n lines.push(`- **Edges:** ${graph.size}`);\n lines.push(`- **Communities:** ${communities.length}`);\n lines.push(`- **God nodes:** ${analysis.godNodes.length}`);\n lines.push('');\n\n lines.push('## Communities');\n lines.push('');\n if (communities.length === 0) {\n lines.push('_No communities detected (graph may be empty, or cluster() has not run yet)._');\n } else {\n for (const community of communities) {\n lines.push(`### ${community.label} (${community.members.length} member(s))`);\n lines.push('');\n const shown = community.members.slice(0, 25).map((id) => labelOf(graph, id));\n lines.push(bulletList(shown));\n if (community.members.length > 25) {\n lines.push(`- ...and ${community.members.length - 25} more`);\n }\n lines.push('');\n }\n }\n\n lines.push('## God Nodes');\n lines.push('');\n lines.push(\n 'Nodes with unusually high fan-in + fan-out relative to the rest of this graph — often a sign of a ' +\n 'shared utility, a bottleneck, or a module that has taken on too many responsibilities.',\n );\n lines.push('');\n lines.push(bulletList(analysis.godNodes.map((id) => labelOf(graph, id))));\n lines.push('');\n\n lines.push('## Structural Surprises');\n lines.push('');\n lines.push(bulletList(analysis.surprises));\n lines.push('');\n\n lines.push('## Open Questions');\n lines.push('');\n lines.push(bulletList(analysis.openQuestions));\n lines.push('');\n\n return lines.join('\\n');\n}\n","import { createRequire } from 'node:module';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type Graph from 'graphology';\nimport { escapeHtml, sanitizeLabel, validateGraphPath } from './security.js';\nimport type { ExportOptions } from './types.js';\n\nconst require = createRequire(import.meta.url);\n\n/** Locate the bundled, self-contained vis-network assets (no CDN, works fully offline). */\nfunction resolveVisNetworkAssets(): { jsPath: string; cssPath: string } {\n const packageJsonPath = require.resolve('vis-network/package.json');\n const root = path.dirname(packageJsonPath);\n return {\n jsPath: path.join(root, 'standalone', 'umd', 'vis-network.min.js'),\n cssPath: path.join(root, 'styles', 'vis-network.min.css'),\n };\n}\n\n/** A small, deterministic categorical palette, cycled by community index. */\nconst COMMUNITY_PALETTE = [\n '#4e79a7',\n '#f28e2b',\n '#e15759',\n '#76b7b2',\n '#59a14f',\n '#edc948',\n '#b07aa1',\n '#ff9da7',\n '#9c755f',\n '#bab0ac',\n];\n\nfunction colorForCommunity(community: number | undefined): string {\n if (community === undefined) return '#8ab4f8';\n const index = ((community % COMMUNITY_PALETTE.length) + COMMUNITY_PALETTE.length) % COMMUNITY_PALETTE.length;\n return COMMUNITY_PALETTE[index] as string;\n}\n\n/**\n * Embedding untrusted-derived strings (node labels ultimately come from\n * source file content) inside an inline <script> tag has one extra XSS\n * vector JSON.stringify() alone doesn't cover: a literal `</script>`\n * substring in the JSON text would close our script tag early and let the\n * rest be parsed as raw HTML. Escape the forward slash so that can't happen.\n */\nfunction safeInlineJson(value: unknown): string {\n return JSON.stringify(value, null, 2).replace(/<\\/(script)/gi, '<\\\\/$1');\n}\n\nfunction buildVisNodesAndEdges(graph: Graph): { nodes: unknown[]; edges: unknown[] } {\n const nodes = graph.nodes().map((id) => {\n const attributes = graph.getNodeAttributes(id);\n const rawLabel = (attributes.label as string | undefined) ?? id;\n const label = escapeHtml(sanitizeLabel(rawLabel));\n const sourceFile = escapeHtml(sanitizeLabel((attributes.sourceFile as string | undefined) ?? ''));\n const sourceLocation = escapeHtml(sanitizeLabel((attributes.sourceLocation as string | undefined) ?? ''));\n const communityLabel = escapeHtml(sanitizeLabel((attributes.communityLabel as string | undefined) ?? ''));\n return {\n id,\n label,\n title: `${label}\\n${sourceFile}${sourceLocation ? `:${sourceLocation}` : ''}${\n communityLabel ? `\\ncommunity: ${communityLabel}` : ''\n }`,\n color: colorForCommunity(attributes.community as number | undefined),\n };\n });\n\n const edges: unknown[] = [];\n graph.forEachEdge((edgeKey, attributes, source, target) => {\n const relation = escapeHtml(sanitizeLabel(String(attributes.relation ?? '')));\n const confidence = escapeHtml(sanitizeLabel(String(attributes.confidence ?? '')));\n edges.push({\n id: edgeKey,\n from: source,\n to: target,\n label: relation,\n title: `${relation} (${confidence})`,\n dashes: confidence === 'INFERRED' || confidence === 'AMBIGUOUS',\n arrows: 'to',\n });\n });\n\n return { nodes, edges };\n}\n\nasync function renderHtml(graph: Graph): Promise<string> {\n const { jsPath, cssPath } = resolveVisNetworkAssets();\n const [visJs, visCss] = await Promise.all([\n fs.readFile(jsPath, 'utf-8'),\n fs.readFile(cssPath, 'utf-8'),\n ]);\n\n const { nodes, edges } = buildVisNodesAndEdges(graph);\n const dataJson = safeInlineJson({ nodes, edges });\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>graphify — graph.html</title>\n<style>\n html, body { margin: 0; padding: 0; height: 100%; font-family: system-ui, sans-serif; }\n #graph { width: 100%; height: 100vh; }\n ${visCss}\n</style>\n</head>\n<body>\n<div id=\"graph\"></div>\n<script>\n${visJs}\n</script>\n<script>\n(function () {\n var data = ${dataJson};\n var nodes = new vis.DataSet(data.nodes);\n var edges = new vis.DataSet(data.edges);\n var container = document.getElementById('graph');\n var network = new vis.Network(container, { nodes: nodes, edges: edges }, {\n nodes: { shape: 'dot', size: 12, font: { size: 14 } },\n edges: { smooth: { type: 'continuous' }, font: { size: 10, align: 'middle' } },\n physics: { stabilization: true },\n interaction: { hover: true, tooltipDelay: 150 },\n });\n window.__graphifyNetwork = network;\n})();\n</script>\n</body>\n</html>\n`;\n}\n\n/**\n * Write graph.json (graphology's node-link serialization, GraphRAG-ready)\n * and, per options, graph.html (vis-network, bundled inline — no CDN, works\n * fully offline) and GRAPH_REPORT.md. Every label/title embedded in\n * graph.html is passed through security.sanitizeLabel() + escapeHtml()\n * first (XSS control, see SECURITY.md).\n *\n * Obsidian vault / .graphml / Neo4j cypher export are NOT implemented in\n * v1 — if requested, exportGraph logs a clear warning and skips them\n * rather than silently doing nothing or faking output.\n */\nexport async function exportGraph(graph: Graph, options: ExportOptions, report?: string): Promise<void> {\n const outDir = path.resolve(options.outDir);\n await fs.mkdir(outDir, { recursive: true });\n\n const jsonPath = validateGraphPath('graph.json', outDir);\n await fs.writeFile(jsonPath, JSON.stringify(graph.toJSON(), null, 2), 'utf-8');\n\n if (options.html !== false) {\n const htmlPath = validateGraphPath('graph.html', outDir);\n await fs.writeFile(htmlPath, await renderHtml(graph), 'utf-8');\n }\n\n if (report !== undefined) {\n const reportPath = validateGraphPath('GRAPH_REPORT.md', outDir);\n await fs.writeFile(reportPath, report, 'utf-8');\n }\n\n const notImplemented: string[] = [];\n if (options.svg) notImplemented.push('--svg');\n if (options.graphml) notImplemented.push('--graphml');\n if (options.neo4j) notImplemented.push('--neo4j');\n if (options.obsidian) notImplemented.push('--obsidian');\n for (const flag of notImplemented) {\n console.warn(`graphify: ${flag} export is not implemented yet in v1 — skipping.`);\n }\n}\n","import { createHash } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { ExtractionResult } from './types.js';\n\n/**\n * Per-file extraction cache — what makes `--update` (and every rebuild\n * behind a git hook or --watch) incremental. Entries are keyed by a hash of\n * the file's CONTENT plus its root-relative path: content because that's\n * what extraction depends on, path because node ids embed it. A stale entry\n * for content that changed simply never matches again; the whole directory\n * can always be deleted safely.\n */\n\nexport class ExtractionCache {\n private readonly dir: string;\n\n constructor(outDir: string) {\n this.dir = path.join(outDir, 'cache');\n }\n\n key(relFile: string, content: Buffer | string): string {\n return createHash('sha256').update(relFile).update('\u0000').update(content).digest('hex');\n }\n\n async get(key: string): Promise<ExtractionResult | null> {\n try {\n const raw = await fs.readFile(path.join(this.dir, `${key}.json`), 'utf-8');\n const parsed = JSON.parse(raw) as ExtractionResult;\n if (!Array.isArray(parsed.nodes) || !Array.isArray(parsed.edges)) return null;\n return parsed;\n } catch {\n return null;\n }\n }\n\n async put(key: string, extraction: ExtractionResult): Promise<void> {\n await fs.mkdir(this.dir, { recursive: true });\n await fs.writeFile(path.join(this.dir, `${key}.json`), JSON.stringify(extraction), 'utf-8');\n }\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type Graph from 'graphology';\nimport { analyze } from './analyze.js';\nimport { buildGraph } from './build.js';\nimport { ExtractionCache } from './extractionCache.js';\nimport { cluster, type ClusterAlgorithm } from './cluster.js';\nimport { collectFiles } from './detect.js';\nimport { extract } from './extract.js';\nimport { exportGraph } from './export.js';\nimport { renderReport } from './report.js';\nimport { resolveCrossFileReferences } from './resolve.js';\nimport type { Analysis, ExtractionResult, FileManifest } from './types.js';\n\nexport interface PipelineOptions {\n /** Where to write graph.json/graph.html/GRAPH_REPORT.md. Defaults to `<root>/graphify-out`. */\n outDir?: string;\n html?: boolean;\n svg?: boolean;\n graphml?: boolean;\n neo4j?: boolean;\n obsidian?: boolean;\n /** `louvain` (default, v1) or `leiden` (v2 — better community quality, see cluster.ts). */\n algorithm?: ClusterAlgorithm;\n /** Leiden-only: cap on outer iterations for very large graphs. */\n maxIterations?: number;\n /**\n * Pre-computed extractions from non-filesystem sources (e.g. a MySQL\n * schema via extractMysql()) merged into the same graph as the code.\n */\n extraExtractions?: ExtractionResult[];\n /**\n * Incremental mode: reuse cached per-file extractions (keyed by content\n * hash) and re-parse only changed files. The cache is warmed on every\n * run either way — `update` only controls whether it's read.\n */\n update?: boolean;\n /** Called with a short progress message after each stage (e.g. for CLI stderr output). */\n onProgress?: (message: string) => void;\n}\n\nexport interface PipelineResult {\n manifest: FileManifest;\n graph: Graph;\n analysis: Analysis;\n report: string;\n}\n\n/**\n * The full `detect -> extract -> build -> cluster -> analyze -> report ->\n * export` pipeline as a single library call — the CLI's default command is\n * a thin wrapper over this. Every extension registered in\n * EXTRACTOR_REGISTRY (see extract.ts) is run; files with no registered\n * extractor are skipped (not an error — see extract()'s doc comment).\n */\nexport async function runPipeline(root: string, options: PipelineOptions = {}): Promise<PipelineResult> {\n const progress = options.onProgress ?? (() => {});\n const resolvedRoot = path.resolve(root);\n\n progress(`Scanning ${resolvedRoot} ...`);\n const manifest = collectFiles(resolvedRoot);\n progress(\n `Found ${manifest.totalFiles} file(s) (${manifest.files.code.length} code, ` +\n `${manifest.skippedSensitive.length} skipped as sensitive).`,\n );\n\n const outDir = options.outDir ?? path.join(resolvedRoot, 'graphify-out');\n const cache = new ExtractionCache(outDir);\n\n progress('Extracting...');\n const extractions: ExtractionResult[] = [];\n let cacheHits = 0;\n for (const relFile of manifest.files.code.sort((a, b) => a.localeCompare(b))) {\n // Read path: relative to CWD so fs reads inside the extractor resolve\n // correctly. Display path (second arg): relative to the scan root, so\n // node ids/sourceFile are stable and portable no matter where the\n // pipeline was launched from — required for cross-project merging.\n const filePath = path.relative(process.cwd(), path.join(resolvedRoot, relFile)) || relFile;\n try {\n const key = cache.key(relFile, await fs.readFile(path.join(resolvedRoot, relFile)));\n let extraction = options.update ? await cache.get(key) : null;\n if (extraction) {\n cacheHits++;\n } else {\n extraction = await extract(filePath, relFile);\n // Cache BEFORE the resolution pass mutates edges — entries must stay pristine.\n await cache.put(key, extraction);\n }\n extractions.push(extraction);\n } catch (error) {\n progress(` extraction failed for ${relFile}: ${(error as Error).message}`);\n throw error;\n }\n }\n if (options.update) {\n progress(` cache: ${cacheHits} hit(s), ${extractions.length - cacheHits} re-extracted.`);\n }\n\n if (options.extraExtractions && options.extraExtractions.length > 0) {\n extractions.push(...options.extraExtractions);\n }\n\n progress('Resolving cross-file references...');\n const resolveStats = resolveCrossFileReferences(extractions);\n if (resolveStats.resolvedEndpoints > 0) {\n progress(\n ` re-pointed ${resolveStats.resolvedEndpoints} guessed reference(s) at real nodes ` +\n `(${resolveStats.droppedPlaceholders} placeholder node(s) dropped).`,\n );\n }\n\n progress('Building graph...');\n const graph = buildGraph(extractions);\n\n progress(`Clustering (${options.algorithm ?? 'louvain'})...`);\n cluster(graph, { algorithm: options.algorithm, maxIterations: options.maxIterations });\n\n progress('Analyzing...');\n const analysis = analyze(graph);\n\n progress('Rendering report...');\n const report = renderReport(graph, analysis);\n\n progress(`Exporting to ${outDir} ...`);\n await exportGraph(\n graph,\n {\n outDir,\n html: options.html,\n svg: options.svg,\n graphml: options.graphml,\n neo4j: options.neo4j,\n obsidian: options.obsidian,\n },\n report,\n );\n\n progress('Done.');\n return { manifest, graph, analysis, report };\n}\n","import Graph from 'graphology';\nimport type { Confidence } from './types.js';\n\n/**\n * Cross-project graph merging — combine several already-built graphs (one\n * per repo/project) into a single queryable global graph.\n *\n * Node ids inside one project are relative-path-based (`src/a.ts::foo`), so\n * two projects' ids would collide. Every node id and sourceFile is therefore\n * prefixed with `<project>/` — EXCEPT `module:*` (bare package imports) and\n * `external:*` (unresolved reference targets) nodes, which deliberately stay\n * unprefixed and shared: two repos importing the same package meet at the\n * same node, so cross-repo bridges emerge in the merged graph instead of\n * each repo floating as a disconnected island.\n */\n\nexport interface MergeEntry {\n /** Project name used as the id/sourceFile namespace prefix. */\n name: string;\n graph: Graph;\n}\n\nconst CONFIDENCE_RANK: Record<Confidence, number> = { EXTRACTED: 3, INFERRED: 2, AMBIGUOUS: 1 };\n\nfunction strongerConfidence(a: Confidence, b: Confidence): Confidence {\n return CONFIDENCE_RANK[a] >= CONFIDENCE_RANK[b] ? a : b;\n}\n\nfunction isShared(id: string): boolean {\n // `external:` = unresolved reference targets, `module:` = bare package\n // imports (see extractors/common.ts) — both name things outside any one\n // project, so they stay unprefixed and shared across the merge.\n return id.startsWith('external:') || id.startsWith('module:');\n}\n\nfunction namespaced(project: string, id: string): string {\n return isShared(id) ? id : `${project}/${id}`;\n}\n\n/**\n * Merge the entries into one directed graph, applying the same\n * deterministic-ordering and duplicate-edge rules as buildGraph(): entries\n * are processed in name order, duplicate edges (possible via shared\n * external nodes) keep the strongest confidence, and every node carries a\n * `project` attribute (shared external nodes get `project: '(shared)'`\n * once more than one project touches them).\n */\nexport function mergeGraphs(entries: MergeEntry[]): Graph {\n const names = entries.map((e) => e.name);\n const duplicate = names.find((name, i) => names.indexOf(name) !== i);\n if (duplicate !== undefined) {\n throw new Error(`Duplicate project name in merge: \"${duplicate}\" — every entry needs a unique name.`);\n }\n\n const merged = new Graph({ type: 'directed', multi: true, allowSelfLoops: true });\n const sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));\n\n for (const { name, graph } of sorted) {\n const nodeIds = [...graph.nodes()].sort((a, b) => a.localeCompare(b));\n for (const id of nodeIds) {\n const attrs = graph.getNodeAttributes(id);\n const newId = namespaced(name, id);\n\n if (merged.hasNode(newId)) {\n // Only shared external nodes can collide across projects.\n merged.setNodeAttribute(newId, 'project', '(shared)');\n continue;\n }\n\n const sourceFile = (attrs.sourceFile as string | undefined) ?? '';\n merged.addNode(newId, {\n label: (attrs.label as string | undefined) ?? id,\n sourceFile: isShared(id) || sourceFile === '' ? sourceFile : `${name}/${sourceFile}`,\n sourceLocation: (attrs.sourceLocation as string | undefined) ?? '',\n project: name,\n });\n }\n\n const edgeKeys = [...graph.edges()].sort((a, b) => a.localeCompare(b));\n for (const edgeKey of edgeKeys) {\n const attrs = graph.getEdgeAttributes(edgeKey);\n const source = namespaced(name, graph.source(edgeKey));\n const target = namespaced(name, graph.target(edgeKey));\n const relation = String(attrs.relation);\n const confidence = attrs.confidence as Confidence;\n\n const key = `${source}|${relation}|${target}`;\n if (merged.hasEdge(key)) {\n const existing = merged.getEdgeAttribute(key, 'confidence') as Confidence;\n merged.setEdgeAttribute(key, 'confidence', strongerConfidence(existing, confidence));\n continue;\n }\n merged.addEdgeWithKey(key, source, target, { relation, confidence });\n }\n }\n\n return merged;\n}\n","import { createHash } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * The graph feedback loop — `graphify save-result` logs which graph nodes\n * actually helped answer a question (or led nowhere), and `graphify\n * reflect` aggregates those logs into a recency-weighted LESSONS.md an\n * agent can read at session start. This is what turns the graph from a\n * static map into one that learns which landmarks matter.\n */\n\nexport type ResultOutcome = 'useful' | 'dead_end' | 'corrected';\nexport type ResultType = 'query' | 'path' | 'explain' | 'affected';\n\nexport interface SavedResult {\n question: string;\n answer: string;\n type: ResultType;\n outcome: ResultOutcome;\n /** Node ids/labels cited in the answer. */\n nodes: string[];\n /** What the right answer was — pairs with outcome 'corrected'. */\n correction?: string;\n savedAt: string; // ISO timestamp\n}\n\nconst OUTCOMES: ReadonlySet<string> = new Set(['useful', 'dead_end', 'corrected']);\nconst TYPES: ReadonlySet<string> = new Set(['query', 'path', 'explain', 'affected']);\n\nexport function validateResult(value: Omit<SavedResult, 'savedAt'>): void {\n if (!value.question) throw new Error('save-result requires --question');\n if (!value.answer) throw new Error('save-result requires --answer');\n if (!OUTCOMES.has(value.outcome)) {\n throw new Error(`--outcome must be one of: useful, dead_end, corrected (got \"${value.outcome}\")`);\n }\n if (!TYPES.has(value.type)) {\n throw new Error(`--type must be one of: query, path, explain, affected (got \"${value.type}\")`);\n }\n if (value.outcome === 'corrected' && !value.correction) {\n throw new Error('--outcome corrected requires --correction with what the right answer was');\n }\n}\n\n/** Append one result to `<memoryDir>/result-<stamp>-<hash>.json`. Returns the file path. */\nexport async function saveResult(\n entry: Omit<SavedResult, 'savedAt'>,\n memoryDir: string,\n now: Date = new Date(),\n): Promise<string> {\n validateResult(entry);\n await fs.mkdir(memoryDir, { recursive: true });\n\n const saved: SavedResult = { ...entry, savedAt: now.toISOString() };\n const hash = createHash('sha256').update(JSON.stringify(saved)).digest('hex').slice(0, 8);\n const stamp = saved.savedAt.replace(/[:.]/g, '-');\n const filePath = path.join(memoryDir, `result-${stamp}-${hash}.json`);\n await fs.writeFile(filePath, JSON.stringify(saved, null, 2), 'utf-8');\n return filePath;\n}\n\nexport interface ReflectOptions {\n /** A result's weight halves every this many days (default 30). */\n halfLifeDays?: number;\n /** Injectable clock for deterministic tests. */\n now?: Date;\n /** Only list nodes cited usefully at least this many distinct times (default 2). */\n minCorroboration?: number;\n}\n\ninterface NodeSignal {\n useful: number;\n deadEnd: number;\n usefulCount: number;\n deadEndCount: number;\n}\n\n/** Read every result JSON under `memoryDir` (missing dir = no results). */\nexport async function loadResults(memoryDir: string): Promise<SavedResult[]> {\n let files: string[];\n try {\n files = (await fs.readdir(memoryDir)).filter((f) => f.startsWith('result-') && f.endsWith('.json'));\n } catch {\n return [];\n }\n\n const results: SavedResult[] = [];\n for (const file of files.sort((a, b) => a.localeCompare(b))) {\n try {\n const parsed = JSON.parse(await fs.readFile(path.join(memoryDir, file), 'utf-8')) as SavedResult;\n if (parsed.question && parsed.savedAt) results.push(parsed);\n } catch {\n // one corrupt file must not sink the reflection\n }\n }\n return results;\n}\n\n/** Aggregate saved results into a LESSONS.md string. Deterministic given results + options.now. */\nexport function renderLessons(results: SavedResult[], options: ReflectOptions = {}): string {\n const halfLife = options.halfLifeDays ?? 30;\n const now = options.now ?? new Date();\n const minCorroboration = options.minCorroboration ?? 2;\n\n const weightOf = (savedAt: string): number => {\n const ageDays = Math.max(0, (now.getTime() - new Date(savedAt).getTime()) / 86_400_000);\n return Math.pow(0.5, ageDays / halfLife);\n };\n\n const signals = new Map<string, NodeSignal>();\n const corrections: Array<{ question: string; correction: string; savedAt: string }> = [];\n\n for (const result of results) {\n const weight = weightOf(result.savedAt);\n for (const node of result.nodes ?? []) {\n const signal = signals.get(node) ?? { useful: 0, deadEnd: 0, usefulCount: 0, deadEndCount: 0 };\n if (result.outcome === 'useful') {\n signal.useful += weight;\n signal.usefulCount++;\n } else if (result.outcome === 'dead_end') {\n signal.deadEnd += weight;\n signal.deadEndCount++;\n }\n signals.set(node, signal);\n }\n if (result.outcome === 'corrected' && result.correction) {\n corrections.push({ question: result.question, correction: result.correction, savedAt: result.savedAt });\n }\n }\n\n const byScore = (kind: 'useful' | 'deadEnd') =>\n [...signals.entries()]\n .filter(([, s]) => (kind === 'useful' ? s.usefulCount >= minCorroboration : s.deadEndCount > 0))\n .sort((a, b) => b[1][kind] - a[1][kind] || a[0].localeCompare(b[0]))\n .slice(0, 10);\n\n const lines: string[] = [\n '# Graph lessons',\n '',\n `_Aggregated from ${results.length} saved result(s); signal half-life ${halfLife} day(s)._`,\n '',\n '## Nodes that keep answering',\n '',\n ];\n\n const useful = byScore('useful');\n if (useful.length === 0) {\n lines.push(`(none yet with >= ${minCorroboration} corroborating results — keep saving results)`);\n } else {\n for (const [node, s] of useful) {\n lines.push(`- **${node}** — score ${s.useful.toFixed(2)} across ${s.usefulCount} useful result(s)`);\n }\n }\n\n lines.push('', '## Dead ends', '');\n const deadEnds = byScore('deadEnd');\n if (deadEnds.length === 0) {\n lines.push('(none recorded)');\n } else {\n for (const [node, s] of deadEnds) {\n lines.push(`- **${node}** — score ${s.deadEnd.toFixed(2)} across ${s.deadEndCount} dead-end result(s)`);\n }\n }\n\n lines.push('', '## Corrections', '');\n if (corrections.length === 0) {\n lines.push('(none recorded)');\n } else {\n corrections.sort((a, b) => b.savedAt.localeCompare(a.savedAt));\n for (const c of corrections.slice(0, 20)) {\n lines.push(`- (${c.savedAt.slice(0, 10)}) Q: ${c.question}`);\n lines.push(` Right answer: ${c.correction}`);\n }\n }\n\n lines.push('');\n return lines.join('\\n');\n}\n","import { execFile } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\nimport type Graph from 'graphology';\nimport { buildGraph } from './build.js';\nimport { collectFiles } from './detect.js';\nimport { extract } from './extract.js';\nimport { affectedBy } from './impact.js';\nimport { resolveCrossFileReferences } from './resolve.js';\nimport { testsForNode } from './testmap.js';\nimport type { ExtractionResult } from './types.js';\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * `graphify review` — semantic graph diff between two git revisions.\n * Full structural extraction is sub-second, so instead of parsing text\n * diffs we build the graph at both revs and diff the graphs: which symbols\n * appeared, disappeared, or got rewired — each with its blast radius and\n * the test files worth running. One command answers both \"what changed\n * since I was last here\" and \"review this PR structurally\".\n */\n\nexport interface ChangedSymbol {\n id: string;\n label: string;\n sourceFile: string;\n /** Everything that depends on this symbol (computed in the graph where it exists). */\n blastRadius: number;\n /** Test files reachable from it. */\n tests: string[];\n}\n\nexport interface RewiredSymbol extends ChangedSymbol {\n gainedEdges: string[];\n lostEdges: string[];\n}\n\nexport interface GraphDiff {\n base: string;\n head: string;\n added: ChangedSymbol[];\n removed: ChangedSymbol[];\n rewired: RewiredSymbol[];\n}\n\n/** Extract a graph from a directory without exporting anything. */\nexport async function graphForDirectory(root: string): Promise<Graph> {\n const manifest = collectFiles(root);\n const extractions: ExtractionResult[] = [];\n for (const relFile of manifest.files.code.sort((a, b) => a.localeCompare(b))) {\n extractions.push(await extract(path.join(root, relFile), relFile));\n }\n resolveCrossFileReferences(extractions);\n return buildGraph(extractions);\n}\n\n/** `git archive <rev> | tar -x` into a fresh temp dir — tracked files only, no worktree pollution. */\nasync function checkoutRev(repoRoot: string, rev: string): Promise<string> {\n const dest = await fs.mkdtemp(path.join(os.tmpdir(), `graphify-review-${rev.replace(/[^a-zA-Z0-9]/g, '_')}-`));\n const { stdout } = await execFileAsync(\n 'git',\n ['-C', repoRoot, 'archive', '--format=tar', rev],\n { encoding: 'buffer', maxBuffer: 512 * 1024 * 1024 },\n );\n await new Promise<void>((resolve, reject) => {\n const tar = execFile('tar', ['-x', '-C', dest], (error) => (error ? reject(error) : resolve()));\n tar.stdin?.end(stdout);\n });\n return dest;\n}\n\n/** Signature of a node's edge set, for rewire detection. */\nfunction edgeSignature(graph: Graph, id: string): Set<string> {\n const signature = new Set<string>();\n graph.forEachOutEdge(id, (_e, attrs, _s, target) => signature.add(`-> ${String(attrs.relation)} ${target}`));\n graph.forEachInEdge(id, (_e, attrs, source) => signature.add(`<- ${String(attrs.relation)} ${source}`));\n return signature;\n}\n\nfunction describeSymbol(graph: Graph, id: string): ChangedSymbol {\n const attrs = graph.getNodeAttributes(id);\n const impact = affectedBy(graph, id, { maxDepth: 3 });\n const tests = testsForNode(graph, id);\n return {\n id,\n label: (attrs.label as string | undefined) ?? id,\n sourceFile: (attrs.sourceFile as string | undefined) ?? '',\n blastRadius: impact?.affected.length ?? 0,\n tests: tests?.testFiles.map((t) => t.file) ?? [],\n };\n}\n\n/** Entity nodes only — file add/removes are visible from the entities inside them, and file nodes double-count. */\nfunction entityIds(graph: Graph): Set<string> {\n const ids = new Set<string>();\n graph.forEachNode((id) => {\n if (id.includes('::')) ids.add(id);\n });\n return ids;\n}\n\nexport function diffGraphs(baseGraph: Graph, headGraph: Graph, base: string, head: string): GraphDiff {\n const baseIds = entityIds(baseGraph);\n const headIds = entityIds(headGraph);\n\n const added: ChangedSymbol[] = [];\n const removed: ChangedSymbol[] = [];\n const rewired: RewiredSymbol[] = [];\n\n for (const id of [...headIds].sort((a, b) => a.localeCompare(b))) {\n if (!baseIds.has(id)) {\n added.push(describeSymbol(headGraph, id));\n continue;\n }\n const before = edgeSignature(baseGraph, id);\n const after = edgeSignature(headGraph, id);\n const gained = [...after].filter((e) => !before.has(e)).sort((a, b) => a.localeCompare(b));\n const lost = [...before].filter((e) => !after.has(e)).sort((a, b) => a.localeCompare(b));\n if (gained.length > 0 || lost.length > 0) {\n rewired.push({ ...describeSymbol(headGraph, id), gainedEdges: gained, lostEdges: lost });\n }\n }\n\n for (const id of [...baseIds].sort((a, b) => a.localeCompare(b))) {\n if (!headIds.has(id)) removed.push(describeSymbol(baseGraph, id));\n }\n\n return { base, head, added, removed, rewired };\n}\n\n/** Diff two revisions of the repo at `repoRoot`. `head` defaults to the working head via a second archive of HEAD. */\nexport async function reviewRevisions(repoRoot: string, base: string, head = 'HEAD'): Promise<GraphDiff> {\n const [baseDir, headDir] = await Promise.all([checkoutRev(repoRoot, base), checkoutRev(repoRoot, head)]);\n try {\n const [baseGraph, headGraph] = [await graphForDirectory(baseDir), await graphForDirectory(headDir)];\n return diffGraphs(baseGraph, headGraph, base, head);\n } finally {\n await Promise.all([\n fs.rm(baseDir, { recursive: true, force: true }),\n fs.rm(headDir, { recursive: true, force: true }),\n ]);\n }\n}\n\nexport function renderReview(diff: GraphDiff): string {\n const lines: string[] = [\n `# Structural review: ${diff.base}..${diff.head}`,\n '',\n `${diff.added.length} symbol(s) added, ${diff.removed.length} removed, ${diff.rewired.length} rewired.`,\n '',\n ];\n\n const section = (title: string, symbols: ChangedSymbol[]): void => {\n lines.push(`## ${title} (${symbols.length})`, '');\n if (symbols.length === 0) {\n lines.push('(none)', '');\n return;\n }\n for (const s of symbols) {\n const tests = s.tests.length > 0 ? ` | tests: ${s.tests.join(', ')}` : ' | tests: none found';\n lines.push(`- **${s.label}** (${s.sourceFile}) — blast radius ${s.blastRadius}${tests}`);\n const r = s as RewiredSymbol;\n if (r.gainedEdges) {\n for (const e of r.gainedEdges.slice(0, 5)) lines.push(` - gained: ${e}`);\n for (const e of r.lostEdges.slice(0, 5)) lines.push(` - lost: ${e}`);\n }\n }\n lines.push('');\n };\n\n section('Removed — check every caller', diff.removed);\n section('Rewired — dependencies changed', diff.rewired);\n section('Added', diff.added);\n\n const allTests = new Set<string>();\n for (const s of [...diff.removed, ...diff.rewired, ...diff.added]) {\n for (const t of s.tests) allTests.add(t);\n }\n lines.push(`## Suggested test run (${allTests.size} file(s))`, '');\n for (const t of [...allTests].sort((a, b) => a.localeCompare(b))) lines.push(`- ${t}`);\n lines.push('');\n\n return lines.join('\\n');\n}\n","import type Graph from 'graphology';\n\n/**\n * `graphify check` — architecture guardrails. Declarative dependency rules\n * checked against the graph's edges, with CI-friendly results: an agent (or\n * a pipeline) can verify an edit didn't violate the architecture before it\n * lands. Cross-language, because the graph already is.\n */\n\nexport interface DependencyRule {\n /** Short rule name shown in violations. */\n name: string;\n /** Glob over the depending file (edge source's sourceFile). */\n from: string;\n /** Globs the dependency target's file must NOT match. */\n disallow: string[];\n /** Optional human explanation echoed with violations. */\n reason?: string;\n}\n\nexport interface RulesConfig {\n rules: DependencyRule[];\n}\n\nexport interface Violation {\n rule: string;\n reason?: string;\n fromFile: string;\n fromNode: string;\n toFile: string;\n toNode: string;\n relation: string;\n}\n\n/** Relations that constitute a dependency for rule purposes. */\nconst DEPENDENCY_RELATIONS = new Set([\n 'calls', 'imports', 'imports_from', 'inherits', 'implements', 'mixes_in', 'embeds', 're_exports',\n]);\n\n/**\n * Minimal glob: `**` crosses directories, `*` stays within one segment.\n * Anchored on both ends. Enough for path rules without a dependency.\n */\nexport function globToRegExp(glob: string): RegExp {\n const escaped = glob.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = escaped.replace(/\\*\\*|\\*|\\?/g, (token) =>\n token === '**' ? '.*' : token === '*' ? '[^/]*' : '[^/]',\n );\n return new RegExp(`^${pattern}$`);\n}\n\nexport function validateRules(value: unknown): RulesConfig {\n const config = value as RulesConfig;\n if (!config || !Array.isArray(config.rules)) {\n throw new Error('Rules file must be JSON of shape { \"rules\": [{ \"name\", \"from\", \"disallow\": [...] }] }');\n }\n for (const rule of config.rules) {\n if (!rule.name || typeof rule.from !== 'string' || !Array.isArray(rule.disallow)) {\n throw new Error(`Malformed rule \"${rule.name ?? '(unnamed)'}\" — need name, from, and disallow[].`);\n }\n }\n return config;\n}\n\n/** Check every dependency edge in the graph against the rules. Deterministic ordering. */\nexport function checkRules(graph: Graph, config: RulesConfig): Violation[] {\n const compiled = config.rules.map((rule) => ({\n rule,\n from: globToRegExp(rule.from),\n disallow: rule.disallow.map(globToRegExp),\n }));\n\n const violations: Violation[] = [];\n graph.forEachEdge((_edge, attrs, source, target) => {\n const relation = String(attrs.relation);\n if (!DEPENDENCY_RELATIONS.has(relation)) return;\n\n const fromFile = (graph.getNodeAttribute(source, 'sourceFile') as string | undefined) ?? '';\n const toFile = (graph.getNodeAttribute(target, 'sourceFile') as string | undefined) ?? '';\n if (!fromFile || !toFile || fromFile === toFile) return;\n\n for (const { rule, from, disallow } of compiled) {\n if (!from.test(fromFile)) continue;\n if (disallow.some((d) => d.test(toFile))) {\n violations.push({\n rule: rule.name,\n reason: rule.reason,\n fromFile,\n fromNode: source,\n toFile,\n toNode: target,\n relation,\n });\n }\n }\n });\n\n violations.sort(\n (a, b) =>\n a.rule.localeCompare(b.rule) ||\n a.fromFile.localeCompare(b.fromFile) ||\n a.toFile.localeCompare(b.toFile) ||\n a.fromNode.localeCompare(b.fromNode),\n );\n return violations;\n}\n"],"mappings":"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","names":["path","fs","path","require","fs","fs","fs","fs","fs","path","fs","path","stripQuotes","CODE_EXTENSIONS","sep","Graph","labelOf","createRequire","fs","path","require","createRequire","createHash","fs","path","fs","path","Graph","CONFIDENCE_RANK","strongerConfidence","createHash","fs","path","fs","path","resolve"]}