@dreamtree-org/graphify 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../node_modules/tsup/assets/cjs_shims.js","../../src/security.ts","../../src/graphStore.ts","../../src/query.ts","../../src/mcp/server.ts","../../src/cli/index.ts","../../src/analyze.ts","../../src/cluster.ts","../../src/export.ts","../../src/pipeline.ts","../../src/build.ts","../../src/schema.ts","../../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/report.ts","../../src/cli/commands/explain.ts","../../src/cli/commands/install.ts","../../src/cli/commands/path.ts","../../src/cli/commands/query.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\n * Security helpers — URL validation, SSRF-guarded fetch, path guards, label\n * sanitization, prompt-injection defenses. Every control listed in\n * SECURITY.md must have a corresponding function here and a unit test in\n * tests/security.test.ts. See the master prompt §5 for the full checklist.\n */\n\nimport { createHash } from 'node:crypto';\nimport * as dns from 'node:dns';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\nimport * as fs from 'node:fs';\nimport * as net from 'node:net';\nimport * as nodePath from 'node:path';\n\nconst ALLOWED_SCHEMES = new Set(['http:', 'https:']);\nconst MAX_FETCH_BYTES = 50 * 1024 * 1024;\nconst MAX_TEXT_BYTES = 10 * 1024 * 1024;\nconst MAX_LABEL_LEN = 256;\nconst MAX_REDIRECTS = 5;\nconst REQUEST_TIMEOUT_MS = 15_000;\n\n/** Hostnames that must never be reachable, regardless of what they resolve to. */\nconst BLOCKED_HOSTNAMES = new Set([\n 'metadata.google.internal',\n 'metadata.internal',\n 'metadata',\n 'metadata.azure.com',\n 'instance-data',\n 'instance-data.ec2.internal',\n]);\n\n// ---------------------------------------------------------------------------\n// IP range checks (SSRF guard core). Implemented without extra dependencies.\n// ---------------------------------------------------------------------------\n\nfunction ipv4ToInt(ip: string): number | null {\n const parts = ip.split('.');\n if (parts.length !== 4) return null;\n let result = 0;\n for (const part of parts) {\n if (!/^\\d{1,3}$/.test(part)) return null;\n const n = Number(part);\n if (n > 255) return null;\n result = (result << 8) | n;\n }\n return result >>> 0;\n}\n\nfunction ipv4InCidr(ipInt: number, cidr: string): boolean {\n const [base, prefixStr] = cidr.split('/');\n const prefix = Number(prefixStr);\n const baseInt = ipv4ToInt(base ?? '');\n if (baseInt === null) return false;\n const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n return (ipInt & mask) >>> 0 === (baseInt & mask) >>> 0;\n}\n\n/** IPv4 ranges that must never be connected to from a server-side fetch. */\nconst BLOCKED_IPV4_CIDRS = [\n '0.0.0.0/8', // \"this\" network\n '10.0.0.0/8', // private\n '100.64.0.0/10', // carrier-grade NAT (CGN)\n '127.0.0.0/8', // loopback\n '169.254.0.0/16', // link-local (covers 169.254.169.254 cloud metadata)\n '172.16.0.0/12', // private\n '192.0.0.0/24', // IETF protocol assignments\n '192.0.2.0/24', // TEST-NET-1\n '192.168.0.0/16', // private\n '198.18.0.0/15', // benchmarking\n '198.51.100.0/24', // TEST-NET-2\n '203.0.113.0/24', // TEST-NET-3\n '224.0.0.0/4', // multicast\n '240.0.0.0/4', // reserved\n '255.255.255.255/32', // broadcast\n];\n\nexport function isForbiddenIpv4(ip: string): boolean {\n const ipInt = ipv4ToInt(ip);\n if (ipInt === null) return true; // malformed -> treat as forbidden, fail closed\n return BLOCKED_IPV4_CIDRS.some((cidr) => ipv4InCidr(ipInt, cidr));\n}\n\n/** Expand a (possibly `::`-compressed) IPv6 address into 8 16-bit groups. */\nfunction expandIpv6(ip: string): number[] | null {\n const withoutZone = ip.split('%')[0] ?? '';\n const parts = withoutZone.split('::');\n if (parts.length > 2) return null;\n\n const head = parts[0] ? parts[0].split(':').filter((s) => s.length > 0) : [];\n const tail = parts.length === 2 && parts[1] ? parts[1].split(':').filter((s) => s.length > 0) : [];\n\n let missing = 0;\n if (parts.length === 2) {\n missing = 8 - head.length - tail.length;\n if (missing < 0) return null;\n } else if (head.length + tail.length !== 8) {\n return null;\n }\n\n const groupsHex = [...head, ...Array(missing).fill('0'), ...tail];\n if (groupsHex.length !== 8) return null;\n\n const groups: number[] = [];\n for (const g of groupsHex) {\n if (!/^[0-9a-fA-F]{1,4}$/.test(g)) return null;\n groups.push(parseInt(g, 16));\n }\n return groups;\n}\n\nexport function isForbiddenIpv6(ip: string): boolean {\n const lower = ip.toLowerCase();\n if (lower === '::1' || lower === '::') return true;\n\n const mapped = /^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/.exec(lower);\n if (mapped) return isForbiddenIpv4(mapped[1] as string);\n\n const groups = expandIpv6(lower);\n if (groups === null) return true; // unparsable -> fail closed\n const first = groups[0] as number;\n if ((first & 0xffc0) === 0xfe80) return true; // fe80::/10 link-local\n if ((first & 0xfe00) === 0xfc00) return true; // fc00::/7 unique local\n if ((first & 0xff00) === 0xff00) return true; // ff00::/8 multicast\n if (groups.every((g) => g === 0)) return true; // unspecified/all-zero\n return false;\n}\n\nexport function isForbiddenIp(ip: string): boolean {\n return net.isIPv6(ip) ? isForbiddenIpv6(ip) : isForbiddenIpv4(ip);\n}\n\n// ---------------------------------------------------------------------------\n// URL validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate a URL is http/https and, when the hostname is itself a literal\n * IP or a known cloud-metadata hostname, reject it synchronously. DNS-bound\n * hostnames are re-validated at connect time by safeFetch() (see below) —\n * this function alone cannot rule out DNS rebinding for a hostname that\n * currently resolves to a public IP.\n */\nexport function validateUrl(url: string): string {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new Error(`Invalid URL: ${url}`);\n }\n\n if (!ALLOWED_SCHEMES.has(parsed.protocol)) {\n throw new Error(\n `URL scheme not allowed: \"${parsed.protocol}\" (allowed: ${[...ALLOWED_SCHEMES].join(', ')})`,\n );\n }\n\n const hostname = parsed.hostname.toLowerCase();\n if (BLOCKED_HOSTNAMES.has(hostname)) {\n throw new Error(`URL targets a blocked host: ${hostname}`);\n }\n\n // WHATWG URL keeps the brackets on an IPv6 literal host (e.g. \"[::1]\") —\n // strip them before checking net.isIP()/isForbiddenIp().\n const bareHost =\n hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname;\n if (net.isIP(bareHost) && isForbiddenIp(bareHost)) {\n throw new Error(`URL targets a forbidden IP address: ${bareHost}`);\n }\n\n return parsed.toString();\n}\n\n// ---------------------------------------------------------------------------\n// safeFetch — SSRF-guarded, size-capped, redirect-revalidating fetch\n// ---------------------------------------------------------------------------\n\nexport type LookupFn = (hostname: string) => Promise<{ address: string; family: number }>;\n\n/**\n * Resolve a hostname (or pass through a literal IP) and validate the\n * result. `lookup` defaults to the real `dns.promises.lookup` — tests\n * substitute a fake to exercise the rebind guard deterministically without\n * making a real DNS query.\n */\nexport async function resolveAndValidate(\n hostname: string,\n lookup: LookupFn = dns.promises.lookup,\n): Promise<{ address: string; family: number }> {\n if (net.isIP(hostname)) {\n if (isForbiddenIp(hostname)) {\n throw new Error(`Refusing to connect to forbidden IP: ${hostname}`);\n }\n return { address: hostname, family: net.isIPv6(hostname) ? 6 : 4 };\n }\n const result = await lookup(hostname);\n if (isForbiddenIp(result.address)) {\n throw new Error(`Refusing to connect to forbidden IP: ${hostname} -> ${result.address}`);\n }\n return result;\n}\n\nexport interface RawResponse {\n statusCode: number;\n headers: http.IncomingHttpHeaders;\n body: Buffer;\n}\n\n/** Minimal shape of the `http`/`https` modules that requestOnce() needs — narrow on purpose so tests can substitute a fake transport instead of mocking network I/O. */\nexport type RequestTransport = Pick<typeof http, 'request'>;\n\n/**\n * Issue a single HTTP(S) request, connecting to `resolvedAddress` directly\n * (via a `lookup` override) rather than re-resolving DNS at connect time —\n * this is what prevents a DNS-rebind attacker from swapping the target\n * between validation and connection (TOCTOU). Streams the body and aborts\n * once it exceeds the byte cap for its declared content type.\n */\nexport function requestOnce(\n target: URL,\n resolvedAddress: string,\n resolvedFamily: number,\n transport: RequestTransport = target.protocol === 'https:' ? https : http,\n): Promise<RawResponse> {\n return new Promise((resolve, reject) => {\n const req = transport.request(\n {\n protocol: target.protocol,\n hostname: target.hostname,\n host: target.hostname,\n port: target.port || (target.protocol === 'https:' ? 443 : 80),\n path: `${target.pathname}${target.search}`,\n method: 'GET',\n timeout: REQUEST_TIMEOUT_MS,\n headers: { 'user-agent': 'graphify/0.1', accept: '*/*' },\n // Force the connection to the address we already validated — do not\n // let Node re-resolve `target.hostname` at connect time.\n lookup: (\n _hostname: string,\n options: unknown,\n callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void,\n ) => {\n callback(null, resolvedAddress, resolvedFamily);\n },\n } as http.RequestOptions,\n (res) => {\n const statusCode = res.statusCode ?? 0;\n const contentType = String(res.headers['content-type'] ?? '');\n const isTextual = /^text\\/|json|xml|html|charset=/i.test(contentType);\n const cap = isTextual ? MAX_TEXT_BYTES : MAX_FETCH_BYTES;\n\n const chunks: Buffer[] = [];\n let total = 0;\n let aborted = false;\n\n res.on('data', (chunk: Buffer) => {\n total += chunk.length;\n if (total > cap) {\n aborted = true;\n res.destroy();\n req.destroy();\n reject(new Error(`Response exceeded ${cap} byte cap (content-type: ${contentType})`));\n return;\n }\n chunks.push(chunk);\n });\n res.on('end', () => {\n if (aborted) return;\n resolve({ statusCode, headers: res.headers, body: Buffer.concat(chunks) });\n });\n res.on('error', (err) => {\n if (!aborted) reject(err);\n });\n },\n );\n\n req.on('timeout', () => {\n req.destroy(new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms`));\n });\n req.on('error', reject);\n req.end();\n });\n}\n\nexport interface SafeFetchDeps {\n /** Override DNS resolution + IP validation (default: resolveAndValidate). */\n resolve?: (hostname: string) => Promise<{ address: string; family: number }>;\n /** Override the actual request (default: requestOnce against real http/https). */\n request?: (target: URL, address: string, family: number) => Promise<RawResponse>;\n}\n\n/**\n * Fetch a URL with the SSRF guards from validateUrl() plus streaming size\n * caps (MAX_FETCH_BYTES / MAX_TEXT_BYTES) and a hard error on non-2xx\n * status. Every redirect hop is independently validated and re-resolved —\n * a redirect to a private/loopback/metadata address is rejected exactly\n * like a direct request would be.\n *\n * `deps` exists so tests can substitute the DNS/network collaborators with\n * deterministic fakes (see tests/security.test.ts) instead of mocking\n * Node's core modules or hitting real sockets — production callers should\n * never need to pass it.\n */\nexport async function safeFetch(url: string, deps: SafeFetchDeps = {}): Promise<Buffer> {\n const resolve = deps.resolve ?? resolveAndValidate;\n const doRequest = deps.request ?? requestOnce;\n\n let current = validateUrl(url);\n for (let hop = 0; hop <= MAX_REDIRECTS; hop++) {\n const target = new URL(current);\n const { address, family } = await resolve(target.hostname);\n const response = await doRequest(target, address, family);\n\n if (response.statusCode >= 300 && response.statusCode < 400) {\n const location = response.headers.location;\n if (!location) {\n throw new Error(`Redirect response (${response.statusCode}) missing Location header`);\n }\n const next = new URL(location, target).toString();\n current = validateUrl(next);\n continue;\n }\n\n if (response.statusCode < 200 || response.statusCode >= 300) {\n throw new Error(`Non-2xx response: ${response.statusCode}`);\n }\n\n return response.body;\n }\n throw new Error(`Too many redirects (> ${MAX_REDIRECTS}) while fetching ${url}`);\n}\n\n// ---------------------------------------------------------------------------\n// Path traversal guard\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve `path` and require it stays inside `base` (defaults to\n * `<cwd>/graphify-out`). `base` must already exist. Throws on traversal\n * attempts (`../`, absolute escapes, symlink-resolved escapes).\n */\nexport function validateGraphPath(path: string, base?: string): string {\n const baseDir = base ?? nodePath.join(process.cwd(), 'graphify-out');\n\n let resolvedBase: string;\n try {\n resolvedBase = fs.realpathSync(baseDir);\n } catch {\n throw new Error(`Base directory does not exist: ${baseDir}`);\n }\n\n const candidate = nodePath.isAbsolute(path) ? path : nodePath.join(resolvedBase, path);\n const resolvedCandidate = nodePath.resolve(candidate);\n\n // Resolve symlinks for whichever is the deepest existing ancestor, so a\n // symlink inside an otherwise-valid path can't escape the base dir either.\n let realCandidate = resolvedCandidate;\n try {\n realCandidate = fs.realpathSync(resolvedCandidate);\n } catch {\n // Path (or part of it) may not exist yet (e.g. a file we're about to\n // write) — fall back to the lexically-resolved path for the check.\n }\n\n const relative = nodePath.relative(resolvedBase, realCandidate);\n const escapes = relative === '..' || relative.startsWith(`..${nodePath.sep}`) || nodePath.isAbsolute(relative);\n if (escapes) {\n throw new Error(`Path escapes graphify-out/: ${path}`);\n }\n\n return realCandidate;\n}\n\n// ---------------------------------------------------------------------------\n// Label sanitization (unchanged reference implementation) + HTML escaping\n// ---------------------------------------------------------------------------\n\n/** Strip control characters, cap length. Apply to every node/edge label. */\nexport function sanitizeLabel(text: string | null | undefined): string {\n if (text == null) return '';\n // eslint-disable-next-line no-control-regex -- intentional: stripping raw control chars\n const stripped = String(text).replace(/[\\x00-\\x1f\\x7f]/g, '');\n return stripped.slice(0, MAX_LABEL_LEN);\n}\n\n/**\n * HTML-escape a string. Callers must run sanitizeLabel() first for\n * length/control-char stripping, then escapeHtml() immediately before\n * embedding into graph.html (XSS control, see SECURITY.md).\n */\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n// ---------------------------------------------------------------------------\n// Prompt-injection defenses for LLM-bound file content\n// ---------------------------------------------------------------------------\n\n/**\n * Known jailbreak / chat-template sentinels that must never reach a prompt\n * unescaped, whether they occur in source files or are forged to spoof our\n * own <untrusted_source> delimiter.\n */\nconst SENTINEL_PATTERNS: RegExp[] = [\n /<\\|im_start\\|>/gi,\n /<\\|im_end\\|>/gi,\n /<\\|system\\|>/gi,\n /\\[INST\\]/gi,\n /\\[\\/INST\\]/gi,\n /<<SYS>>/gi,\n /<<\\/SYS>>/gi,\n /<\\/untrusted_source>/gi,\n /<untrusted_source/gi,\n];\n\n/**\n * Render brackets as fullwidth lookalikes (< > [ ]) so the defanged\n * echo is human-visible but no longer byte-identical to the original\n * sentinel — a naive downstream scan for the literal delimiter/sentinel\n * text will not re-match our own \"we found one\" marker.\n */\nfunction toFullwidthBrackets(text: string): string {\n return text\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\\[/g, '[')\n .replace(/\\]/g, ']');\n}\n\n/**\n * Replace known jailbreak/chat-template sentinels with a visibly defanged\n * form — never silently stripped (silent stripping can itself be an\n * injection vector if it changes meaning unexpectedly).\n */\nfunction defangSentinels(content: string): string {\n let result = content;\n for (const pattern of SENTINEL_PATTERNS) {\n result = result.replace(pattern, (match) => `[DEFANGED:${toFullwidthBrackets(match)}]`);\n }\n return result;\n}\n\n/**\n * Wrap file content for LLM prompts in a hash-stamped untrusted-source\n * delimiter and neutralize known jailbreak/chat-template sentinels. This\n * raises the bar against prompt injection; it does not eliminate it —\n * document that plainly wherever this is referenced.\n */\nexport function wrapUntrustedSource(path: string, content: string): string {\n const sha256 = createHash('sha256').update(content, 'utf8').digest('hex');\n const safePath = escapeHtml(sanitizeLabel(path));\n const defanged = defangSentinels(content);\n return `<untrusted_source path=\"${safePath}\" sha256=\"${sha256}\">\\n${defanged}\\n</untrusted_source>`;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport Graph from 'graphology';\nimport { validateGraphPath } from './security.js';\n\n/**\n * Load a previously-exported graph.json back into a graphology Graph.\n * Always goes through security.validateGraphPath() (path-traversal guard —\n * see SECURITY.md) so a caller-supplied `outDir`/CLI arg can never make\n * this read outside the graphify-out/ directory it resolves to.\n */\nexport async function loadGraph(outDir: string = path.join(process.cwd(), 'graphify-out')): Promise<Graph> {\n const jsonPath = validateGraphPath('graph.json', outDir);\n const raw = await fs.readFile(jsonPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n return Graph.from(data as Parameters<typeof Graph.from>[0]);\n}\n","import type Graph from 'graphology';\n\n/**\n * Library-level graph queries shared by the CLI (`graphify query/path/\n * explain`) and the MCP server tools of the same name. None of this is an\n * LLM call — it's lexical node matching + graph traversal, so it works\n * fully offline and deterministically.\n */\n\nconst STOPWORDS = new Set([\n 'a', 'an', 'the', 'is', 'are', 'was', 'were', 'do', 'does', 'did', 'how',\n 'what', 'where', 'when', 'why', 'who', 'which', 'to', 'of', 'in', 'on',\n 'for', 'and', 'or', 'this', 'that', 'it', 'does', 'that\\'s',\n]);\n\nfunction tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9_.]+/)\n .filter((token) => token.length > 1 && !STOPWORDS.has(token));\n}\n\nexport interface NodeMatch {\n id: string;\n label: string;\n score: number;\n}\n\n/** Score every node by how many query tokens appear in its label or id. */\nexport function scoreNodes(graph: Graph, query: string): NodeMatch[] {\n const tokens = tokenize(query);\n const matches: NodeMatch[] = [];\n\n graph.forEachNode((id, attributes) => {\n const label = (attributes.label as string | undefined) ?? id;\n const haystack = `${label} ${id}`.toLowerCase();\n let score = 0;\n for (const token of tokens) {\n if (haystack.includes(token)) score += 1;\n }\n if (score > 0) matches.push({ id, label, score });\n });\n\n matches.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));\n return matches;\n}\n\n/**\n * Best-effort single-node resolution: the highest-scoring lexical match,\n * or null if nothing in the graph matches at all. Deliberately does *not*\n * fall back to \"the most connected node\" — path/explain name a specific\n * node by intent, and silently substituting an unrelated one would be\n * more misleading than clearly saying \"no match\".\n */\nexport function resolveNode(graph: Graph, query: string): NodeMatch | null {\n const matches = scoreNodes(graph, query);\n return matches[0] ?? null;\n}\n\nexport interface VisitedNode {\n id: string;\n label: string;\n sourceFile: string;\n sourceLocation: string;\n depth: number;\n}\n\nexport interface TraversalEdge {\n source: string;\n target: string;\n relation: string;\n confidence: string;\n}\n\nexport interface QueryResult {\n seeds: NodeMatch[];\n visited: VisitedNode[];\n edges: TraversalEdge[];\n}\n\nexport interface QueryOptions {\n dfs?: boolean;\n /** Approximate cap on how many nodes to include (a stand-in for a true token budget — see docs). */\n budget?: number;\n maxDepth?: number;\n maxSeeds?: number;\n}\n\nconst DEFAULT_MAX_DEPTH = 2;\nconst DEFAULT_MAX_SEEDS = 5;\nconst DEFAULT_BUDGET = 40;\n\n/**\n * BFS (default, broad context) or DFS (--dfs, trace a specific path)\n * traversal from the nodes whose label best matches `question`'s\n * keywords. This is lexical retrieval, not natural-language\n * understanding — it surfaces the neighborhood of the graph an agent (or\n * a human) should look at to answer the question, it does not itself\n * compose an answer.\n */\nexport function queryGraph(graph: Graph, question: string, options: QueryOptions = {}): QueryResult {\n const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;\n const maxSeeds = options.maxSeeds ?? DEFAULT_MAX_SEEDS;\n const budget = options.budget ?? DEFAULT_BUDGET;\n\n const allMatches = scoreNodes(graph, question);\n const seeds = allMatches.length > 0 ? allMatches.slice(0, maxSeeds) : [];\n\n const visited = new Map<string, number>(); // id -> depth\n const frontier: Array<{ id: string; depth: number }> = seeds.map((s) => ({ id: s.id, depth: 0 }));\n for (const seed of seeds) visited.set(seed.id, 0);\n\n while (frontier.length > 0 && visited.size < budget) {\n const current = options.dfs ? (frontier.pop() as { id: string; depth: number }) : (frontier.shift() as { id: string; depth: number });\n if (current.depth >= maxDepth) continue;\n\n const neighbors = [...graph.neighbors(current.id)].sort((a, b) => a.localeCompare(b));\n for (const neighbor of neighbors) {\n if (visited.has(neighbor) || visited.size >= budget) continue;\n visited.set(neighbor, current.depth + 1);\n frontier.push({ id: neighbor, depth: current.depth + 1 });\n }\n }\n\n const visitedNodes: VisitedNode[] = [...visited.entries()]\n .map(([id, depth]) => {\n const attrs = graph.getNodeAttributes(id);\n return {\n id,\n label: (attrs.label as string | undefined) ?? id,\n sourceFile: (attrs.sourceFile as string | undefined) ?? '',\n sourceLocation: (attrs.sourceLocation as string | undefined) ?? '',\n depth,\n };\n })\n .sort((a, b) => a.depth - b.depth || a.id.localeCompare(b.id));\n\n const edges: TraversalEdge[] = [];\n graph.forEachEdge((_edge, attrs, source, target) => {\n if (visited.has(source) && visited.has(target)) {\n edges.push({\n source,\n target,\n relation: String(attrs.relation),\n confidence: String(attrs.confidence),\n });\n }\n });\n edges.sort(\n (a, b) => a.source.localeCompare(b.source) || a.target.localeCompare(b.target) || a.relation.localeCompare(b.relation),\n );\n\n return { seeds, visited: visitedNodes, edges };\n}\n\nexport interface PathResult {\n from: NodeMatch;\n to: NodeMatch;\n found: boolean;\n path: string[];\n edges: TraversalEdge[];\n}\n\n/** Shortest path between the nodes that best match `fromQuery` and `toQuery` (undirected BFS — connectivity, not call direction). */\nexport function shortestPath(graph: Graph, fromQuery: string, toQuery: string): PathResult | null {\n const from = resolveNode(graph, fromQuery);\n const to = resolveNode(graph, toQuery);\n if (!from || !to) return null;\n\n if (from.id === to.id) {\n return { from, to, found: true, path: [from.id], edges: [] };\n }\n\n const predecessor = new Map<string, string>();\n const visited = new Set<string>([from.id]);\n const queue: string[] = [from.id];\n\n while (queue.length > 0) {\n const current = queue.shift() as string;\n if (current === to.id) break;\n const neighbors = [...graph.neighbors(current)].sort((a, b) => a.localeCompare(b));\n for (const neighbor of neighbors) {\n if (visited.has(neighbor)) continue;\n visited.add(neighbor);\n predecessor.set(neighbor, current);\n queue.push(neighbor);\n }\n }\n\n if (!visited.has(to.id)) {\n return { from, to, found: false, path: [], edges: [] };\n }\n\n const path: string[] = [to.id];\n let cursor = to.id;\n while (cursor !== from.id) {\n const prev = predecessor.get(cursor);\n if (!prev) break;\n path.unshift(prev);\n cursor = prev;\n }\n\n const edges: TraversalEdge[] = [];\n for (let i = 0; i < path.length - 1; i++) {\n const a = path[i] as string;\n const b = path[i + 1] as string;\n const key = graph.edges(a, b)[0] ?? graph.edges(b, a)[0];\n if (key) {\n const attrs = graph.getEdgeAttributes(key);\n edges.push({ source: a, target: b, relation: String(attrs.relation), confidence: String(attrs.confidence) });\n }\n }\n\n return { from, to, found: true, path, edges };\n}\n\nexport interface ExplainResult {\n id: string;\n label: string;\n sourceFile: string;\n sourceLocation: string;\n communityLabel?: string;\n outgoing: TraversalEdge[];\n incoming: TraversalEdge[];\n}\n\n/** Plain-language-ready explanation of the node that best matches `query`. */\nexport function explainNode(graph: Graph, query: string): ExplainResult | null {\n const match = resolveNode(graph, query);\n if (!match) return null;\n\n const attrs = graph.getNodeAttributes(match.id);\n const outgoing: TraversalEdge[] = [];\n const incoming: TraversalEdge[] = [];\n\n graph.forEachOutEdge(match.id, (_edge, edgeAttrs, source, target) => {\n outgoing.push({ source, target, relation: String(edgeAttrs.relation), confidence: String(edgeAttrs.confidence) });\n });\n graph.forEachInEdge(match.id, (_edge, edgeAttrs, source, target) => {\n incoming.push({ source, target, relation: String(edgeAttrs.relation), confidence: String(edgeAttrs.confidence) });\n });\n\n outgoing.sort((a, b) => a.target.localeCompare(b.target) || a.relation.localeCompare(b.relation));\n incoming.sort((a, b) => a.source.localeCompare(b.source) || a.relation.localeCompare(b.relation));\n\n return {\n id: match.id,\n label: match.label,\n sourceFile: (attrs.sourceFile as string | undefined) ?? '',\n sourceLocation: (attrs.sourceLocation as string | undefined) ?? '',\n communityLabel: attrs.communityLabel as string | undefined,\n outgoing,\n incoming,\n };\n}\n","/**\n * MCP stdio server exposing query/path/explain as tools against an existing\n * graphify-out/graph.json. Stdio only — never opens a network listener.\n * All graph file paths go through security.validateGraphPath().\n *\n * This module is a pure library: importing it has no side effects (it does\n * not read argv or start a server on import). `startServer()` is called\n * explicitly by `bin/graphify-mcp.js` (the standalone `graphify-mcp` CLI\n * entry point) and by `graphify --mcp` (see src/cli/index.ts).\n */\nimport * as path from 'node:path';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport { z } from 'zod';\nimport { loadGraph } from '../graphStore.js';\nimport { explainNode, queryGraph, shortestPath } from '../query.js';\nimport { validateGraphPath } from '../security.js';\n\nfunction textResult(text: string): { content: Array<{ type: 'text'; text: string }> } {\n return { content: [{ type: 'text', text }] };\n}\n\n/**\n * Build the McpServer instance (tools registered, nothing connected yet).\n * Split out from startServer() so tests can connect it to an in-memory\n * transport instead of real stdio (see tests/mcp/server.test.ts).\n */\nexport function createGraphifyMcpServer(outDir: string): McpServer {\n const server = new McpServer({ name: 'graphify', version: '0.1.0' });\n\n server.registerTool(\n 'query',\n {\n description:\n 'BFS (default) or DFS traversal of the graphify knowledge graph, seeded from nodes ' +\n 'whose label matches the question. Returns the matched seeds, the visited node ' +\n 'context, and the edges among them — broad context for answering a structural question.',\n inputSchema: {\n question: z.string().describe('Natural-language question or keywords to search the graph for.'),\n dfs: z.boolean().optional().describe('Use depth-first traversal instead of the default breadth-first.'),\n budget: z.number().int().positive().optional().describe('Approximate cap on how many nodes to include.'),\n },\n },\n async ({ question, dfs, budget }) => {\n const graph = await loadGraph(outDir);\n const result = queryGraph(graph, question, { dfs, budget });\n return textResult(JSON.stringify(result, null, 2));\n },\n );\n\n server.registerTool(\n 'path',\n {\n description: 'Shortest path between two named nodes in the graphify knowledge graph.',\n inputSchema: {\n from: z.string().describe('Name/label of the starting node.'),\n to: z.string().describe('Name/label of the destination node.'),\n },\n },\n async ({ from, to }) => {\n const graph = await loadGraph(outDir);\n const result = shortestPath(graph, from, to);\n if (!result) {\n return textResult(`Could not resolve \"${from}\" and/or \"${to}\" to a node in the graph.`);\n }\n return textResult(JSON.stringify(result, null, 2));\n },\n );\n\n server.registerTool(\n 'explain',\n {\n description:\n 'Plain-language-ready explanation of a single node: its source location, community, ' +\n 'and incoming/outgoing edges.',\n inputSchema: {\n node: z.string().describe('Name/label (or id) of the node to explain.'),\n },\n },\n async ({ node }) => {\n const graph = await loadGraph(outDir);\n const result = explainNode(graph, node);\n if (!result) {\n return textResult(`No node matched \"${node}\".`);\n }\n return textResult(JSON.stringify(result, null, 2));\n },\n );\n\n return server;\n}\n\n/**\n * Start the MCP server, serving `query`/`path`/`explain` tools against the\n * graph.json found in `graphPath`'s directory. `graphPath` is validated\n * (via security.validateGraphPath()) up front so a bad path fails\n * immediately with a clear error instead of the first time a client calls\n * a tool. `transport` defaults to real stdio; tests substitute an\n * in-memory transport.\n */\nexport async function startServer(graphPath: string, transport: Transport = new StdioServerTransport()): Promise<void> {\n const outDir = path.dirname(path.resolve(graphPath));\n const fileName = path.basename(graphPath);\n // Fail fast (and clearly) if the graph path escapes/doesn't exist, rather\n // than only surfacing that the first time a tool is called.\n validateGraphPath(fileName, outDir);\n\n const server = createGraphifyMcpServer(outDir);\n await server.connect(transport);\n}\n\n/** Entry point used by bin/graphify-mcp.js. */\nexport async function main(argv: string[] = process.argv): Promise<void> {\n const graphPath = argv[2] ?? path.join(process.cwd(), 'graphify-out', 'graph.json');\n await startServer(graphPath);\n}\n","#!/usr/bin/env node\nimport { execFile } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\nimport { watch as watchFiles } from 'chokidar';\nimport { Command } from 'commander';\nimport { analyze } from '../analyze.js';\nimport { cluster } from '../cluster.js';\nimport { exportGraph } from '../export.js';\nimport { loadGraph } from '../graphStore.js';\nimport { runPipeline } from '../pipeline.js';\nimport { renderReport } from '../report.js';\nimport { validateUrl } from '../security.js';\nimport { runExplain } from './commands/explain.js';\nimport { runInstall } from './commands/install.js';\nimport { runPath } from './commands/path.js';\nimport { runQuery } from './commands/query.js';\n\nconst execFileAsync = promisify(execFile);\n\ninterface DefaultCommandOptions {\n mode?: string;\n update?: boolean;\n watch?: boolean;\n clusterOnly?: boolean;\n viz: boolean; // commander negatable --no-viz -> options.viz\n svg?: boolean;\n graphml?: boolean;\n neo4j?: boolean;\n mcp?: boolean;\n leiden?: boolean;\n maxIterations?: number;\n}\n\nfunction looksLikeGitUrl(value: string): boolean {\n if (!/^https?:\\/\\//i.test(value)) return false;\n return /github\\.com|gitlab\\.com|bitbucket\\.org/i.test(value) || value.endsWith('.git');\n}\n\n/** Clone `url` into a fresh temp directory using an argv-array child_process call (never shell: true, never a shell string built from input). */\nasync function cloneRepo(url: string): Promise<string> {\n const validated = validateUrl(url);\n const dest = await fs.mkdtemp(path.join(os.tmpdir(), 'graphify-clone-'));\n await execFileAsync('git', ['clone', '--depth', '1', validated, dest]);\n return dest;\n}\n\nfunction exportOptionsFrom(options: DefaultCommandOptions) {\n return { html: options.viz, svg: options.svg, graphml: options.graphml, neo4j: options.neo4j };\n}\n\nfunction clusterOptionsFrom(options: DefaultCommandOptions) {\n return {\n algorithm: options.leiden ? ('leiden' as const) : ('louvain' as const),\n maxIterations: options.maxIterations,\n };\n}\n\nasync function runClusterOnly(root: string, options: DefaultCommandOptions): Promise<void> {\n const outDir = path.join(root, 'graphify-out');\n const graph = await loadGraph(outDir);\n cluster(graph, clusterOptionsFrom(options));\n const analysis = analyze(graph);\n const report = renderReport(graph, analysis);\n await exportGraph(graph, { outDir, ...exportOptionsFrom(options) }, report);\n console.error(`Re-clustered the existing graph (${clusterOptionsFrom(options).algorithm}).`);\n}\n\n/** Watch `root` (ignoring graphify-out/, node_modules/, .git/) and re-run `runOnce` on any change, debounced. Never resolves — the process stays alive until interrupted, matching normal watch-mode CLI behavior. */\nasync function watchAndRebuild(root: string, runOnce: () => Promise<unknown>): Promise<void> {\n const watcher = watchFiles(root, {\n ignored: (filePath: string) => /(^|[/\\\\])(node_modules|\\.git|graphify-out)([/\\\\]|$)/.test(filePath),\n ignoreInitial: true,\n });\n\n let timer: ReturnType<typeof setTimeout> | null = null;\n let running = false;\n const schedule = (): void => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n if (running) return;\n running = true;\n console.error('Change detected, rebuilding...');\n runOnce()\n .catch((error: unknown) => console.error(`graphify --watch: rebuild failed: ${(error as Error).message}`))\n .finally(() => {\n running = false;\n });\n }, 300);\n };\n\n watcher.on('add', schedule).on('change', schedule).on('unlink', schedule);\n\n await new Promise<never>(() => {\n /* keep the process alive until the user interrupts it (Ctrl+C) */\n });\n}\n\nconst program = new Command();\n\nprogram\n .name('graphify')\n .description('Turn a folder of code/docs/papers into a queryable knowledge graph.')\n .argument('[path]', 'path to scan, or a GitHub URL', '.')\n .option('--mode <mode>', 'extraction mode (deep for richer INFERRED edges — reserved, no-op in v1)')\n .option('--update', 'incremental re-extract of changed files only (not implemented in v1 — runs full pipeline)')\n .option('--watch', 'rebuild on file change')\n .option('--cluster-only', 'rerun clustering on an existing graph')\n .option('--leiden', 'use Leiden instead of Louvain for community detection (v2 — better community quality)')\n .option('--max-iterations <n>', 'Leiden only: cap on outer iterations for very large graphs', Number)\n .option('--no-viz', 'skip graph.html')\n .option('--svg', 'also export graph.svg (not implemented in v1)')\n .option('--graphml', 'also export graph.graphml (not implemented in v1)')\n .option('--neo4j', 'generate graphify-out/cypher.txt for Neo4j (not implemented in v1)')\n .option('--mcp', 'start MCP stdio server instead of running the pipeline')\n .action(async (targetArg: string, options: DefaultCommandOptions) => {\n try {\n if (options.mcp) {\n const outDir = path.resolve(targetArg === '.' ? process.cwd() : targetArg, 'graphify-out');\n const { startServer } = await import('../mcp/server.js');\n await startServer(path.join(outDir, 'graph.json'));\n return;\n }\n\n let root = targetArg;\n if (looksLikeGitUrl(targetArg)) {\n console.error(`Cloning ${targetArg} ...`);\n root = await cloneRepo(targetArg);\n }\n root = path.resolve(root);\n\n if (options.update) {\n console.error(\n '--update (incremental re-extract) is not implemented yet in v1 — running the full pipeline instead.',\n );\n }\n if (options.mode) {\n console.error(`--mode ${options.mode} is reserved for a future richer-INFERRED-edges pass — currently a no-op.`);\n }\n\n if (options.clusterOnly) {\n await runClusterOnly(root, options);\n return;\n }\n\n const runOnce = () =>\n runPipeline(root, {\n ...exportOptionsFrom(options),\n ...clusterOptionsFrom(options),\n onProgress: (m) => console.error(m),\n });\n await runOnce();\n\n if (options.watch) {\n console.error(`Watching ${root} for changes (Ctrl+C to stop) ...`);\n await watchAndRebuild(root, runOnce);\n }\n } catch (error) {\n console.error(`graphify: ${(error as Error).message}`);\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('query <question>')\n .description('BFS (default) or DFS traversal answering a question against the existing graph')\n .option('--dfs', 'depth-first traversal (trace a specific path)')\n .option('--budget <tokens>', 'cap answer at N tokens', Number)\n .action(async (question: string, options: { dfs?: boolean; budget?: number }) => {\n try {\n await runQuery(question, options);\n } catch (error) {\n console.error(`graphify query: ${(error as Error).message}`);\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('path <from> <to>')\n .description('shortest path between two named nodes')\n .action(async (from: string, to: string) => {\n try {\n await runPath(from, to);\n } catch (error) {\n console.error(`graphify path: ${(error as Error).message}`);\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('explain <node>')\n .description('plain-language explanation of a node')\n .action(async (node: string) => {\n try {\n await runExplain(node);\n } catch (error) {\n console.error(`graphify explain: ${(error as Error).message}`);\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('install')\n .description('install the skill files into the local agent(s)')\n .action(async () => {\n try {\n await runInstall();\n } catch (error) {\n console.error(`graphify install: ${(error as Error).message}`);\n process.exitCode = 1;\n }\n });\n\nprogram.parseAsync(process.argv);\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 { 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 { 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","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 { 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 * 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 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 { loadGraph } from '../../graphStore.js';\nimport { explainNode } from '../../query.js';\n\n/** Plain-language explanation of a single node. */\nexport async function runExplain(nodeName: string): Promise<void> {\n const graph = await loadGraph();\n const result = explainNode(graph, nodeName);\n\n if (!result) {\n console.log(`No node matched \"${nodeName}\".`);\n return;\n }\n\n const location = result.sourceLocation ? `:${result.sourceLocation}` : '';\n console.log(result.label);\n console.log(` location: ${result.sourceFile}${location}`);\n if (result.communityLabel) {\n console.log(` community: ${result.communityLabel}`);\n }\n\n console.log('');\n console.log(`Calls / references out (${result.outgoing.length}):`);\n if (result.outgoing.length === 0) {\n console.log(' (none)');\n } else {\n for (const edge of result.outgoing) {\n console.log(` --${edge.relation}--> ${edge.target} (${edge.confidence})`);\n }\n }\n\n console.log('');\n console.log(`Referenced by (${result.incoming.length}):`);\n if (result.incoming.length === 0) {\n console.log(' (none)');\n } else {\n for (const edge of result.incoming) {\n console.log(` ${edge.source} --${edge.relation}--> (${edge.confidence})`);\n }\n }\n}\n","import { createRequire } from 'node:module';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve this package's own root directory, whether we're running from\n * source (tests/dev), the built dist/ bundle, or installed as a real\n * dependency elsewhere. Uses Node's self-reference resolution (walking up\n * from this module's location to the nearest package.json named\n * \"@dreamtree-org/graphify\") rather than a hardcoded relative path, since\n * the number of directories between this file and the package root\n * differs between src/ and the bundled dist/ output.\n */\nfunction packageRoot(): string {\n const packageJsonPath = require.resolve('@dreamtree-org/graphify/package.json');\n return path.dirname(packageJsonPath);\n}\n\nexport interface InstallResult {\n host: string;\n path: string;\n}\n\n/**\n * Copy SKILL.md into the local agent's skill directory. Claude Code only\n * for v1 (project-local `.claude/skills/graphify/SKILL.md`) — other hosts\n * (Cursor, etc.) are a clearly-flagged follow-up, not faked with an empty\n * or copy-pasted file.\n */\nexport async function runInstall(cwd: string = process.cwd()): Promise<InstallResult[]> {\n const sourcePath = path.join(packageRoot(), 'src', 'skill', 'SKILL.md');\n const content = await fs.readFile(sourcePath, 'utf-8');\n\n const results: InstallResult[] = [];\n\n const claudeCodeDir = path.join(cwd, '.claude', 'skills', 'graphify');\n await fs.mkdir(claudeCodeDir, { recursive: true });\n const claudeCodePath = path.join(claudeCodeDir, 'SKILL.md');\n await fs.writeFile(claudeCodePath, content, 'utf-8');\n results.push({ host: 'Claude Code', path: claudeCodePath });\n\n for (const result of results) {\n console.log(`Installed graphify skill for ${result.host} -> ${result.path}`);\n }\n console.log('');\n console.log(\n 'Other hosts (Cursor, etc.) are not implemented yet by `graphify install` — see ARCHITECTURE.md.',\n );\n\n return results;\n}\n","import { loadGraph } from '../../graphStore.js';\nimport { shortestPath } from '../../query.js';\n\n/** Shortest path between two named nodes. */\nexport async function runPath(fromNode: string, toNode: string): Promise<void> {\n const graph = await loadGraph();\n const result = shortestPath(graph, fromNode, toNode);\n\n if (!result) {\n console.log(`Could not resolve \"${fromNode}\" and/or \"${toNode}\" to a node in the graph.`);\n return;\n }\n\n if (!result.found) {\n console.log(\n `No path found between \"${result.from.label}\" and \"${result.to.label}\" — they may be in ` +\n 'disconnected parts of the graph (see GRAPH_REPORT.md § Open Questions).',\n );\n return;\n }\n\n console.log(`${result.from.label} -> ${result.to.label} (${result.path.length} node(s)):`);\n console.log(` ${result.path.join(' -> ')}`);\n if (result.edges.length > 0) {\n console.log('');\n console.log('Edges along the path:');\n for (const edge of result.edges) {\n console.log(` ${edge.source} --${edge.relation}--> ${edge.target} (${edge.confidence})`);\n }\n }\n}\n","import { loadGraph } from '../../graphStore.js';\nimport { queryGraph } from '../../query.js';\n\nexport interface QueryOptions {\n dfs?: boolean;\n budget?: number;\n}\n\n/** BFS (default) or DFS traversal answering a natural-language question against the graph. */\nexport async function runQuery(question: string, options: QueryOptions = {}): Promise<void> {\n const graph = await loadGraph();\n const result = queryGraph(graph, question, { dfs: options.dfs, budget: options.budget });\n\n if (result.seeds.length === 0) {\n console.log(\n `No nodes matched \"${question}\". Try different keywords, or run \\`graphify explain <node>\\` ` +\n 'if you already know the name.',\n );\n return;\n }\n\n console.log(`Matched ${result.seeds.length} seed node(s):`);\n for (const seed of result.seeds) {\n console.log(` - ${seed.label} (${seed.id})`);\n }\n\n console.log('');\n console.log(`Context — ${result.visited.length} node(s), ${options.dfs ? 'DFS' : 'BFS'} traversal:`);\n for (const node of result.visited) {\n const location = node.sourceLocation ? `:${node.sourceLocation}` : '';\n console.log(` [depth ${node.depth}] ${node.label} — ${node.sourceFile}${location}`);\n }\n\n console.log('');\n console.log(`Edges within this context (${result.edges.length}):`);\n for (const edge of result.edges) {\n console.log(` ${edge.source} --${edge.relation}--> ${edge.target} (${edge.confidence})`);\n }\n}\n"],"mappings":"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","names":["path","relative","import_node_crypto","Graph","fs","path","import_graphology","path","path","import_zod","fs","path","Graph","leiden","louvain","fs","require","path","import_graphology","Graph","fs","path","path","fs","path","import_node_module","require","fs","fs","fs","fs","fs","path","fs","path","stripQuotes","labelOf","import_node_module","fs","path","require","watchFiles","startServer"]}