@dreamtree-org/graphify 1.0.0 → 1.1.1

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/cluster.ts","../src/analyze.ts","../src/report.ts","../src/export.ts","../src/pipeline.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\nexport type Extractor = (path: 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 */\nexport async function extract(filePath: 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);\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): 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(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): 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(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): 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(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): 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(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): 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(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): 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(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): 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(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 { 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 * as path from 'node:path';\nimport type Graph from 'graphology';\nimport { analyze } from './analyze.js';\nimport { buildGraph } from './build.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 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 /** 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 progress('Extracting...');\n const extractions: ExtractionResult[] = [];\n for (const relFile of manifest.files.code.sort((a, b) => a.localeCompare(b))) {\n // Relative to CWD (not necessarily to `resolvedRoot`) so fs reads inside\n // the extractor resolve correctly, while still keeping sourceFile short\n // and human-readable rather than a fully absolute path.\n const filePath = path.relative(process.cwd(), path.join(resolvedRoot, relFile)) || relFile;\n try {\n const extraction = await extract(filePath);\n extractions.push(extraction);\n } catch (error) {\n progress(` extraction failed for ${relFile}: ${(error as Error).message}`);\n throw error;\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 const outDir = options.outDir ?? path.join(resolvedRoot, 'graphify-out');\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"],"mappings":"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","names":["path","fs","path","require","fs","fs","fs","fs","fs","path","fs","path","stripQuotes","Graph","labelOf","createRequire","fs","path","require","createRequire","path"]}