dsh-code-index 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +55 -6
- package/README.zh.md +35 -6
- package/dist/client.js +76 -20
- package/dist/client.js.map +1 -1
- package/dist/index.js +802 -107
- package/dist/index.js.map +1 -1
- package/package.json +8 -5
- package/scripts/release-smoke.mjs +67 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/buildIndex.ts","../src/extract.ts","../src/scan.ts","../src/store.ts","../src/types.ts","../src/repomap.ts","../src/refgraph.ts","../src/search.ts","../src/health.ts","../src/git-diff.ts","../src/change-context.ts","../src/tools.ts","../src/config.ts","../src/settings.ts","../src/index.ts"],"sourcesContent":["/** Build a RepoIndex for a workspace: scan -> extract -> persist. */\n\nimport { readFile, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport { extractAll, languageForFile } from './extract.js'\nimport { scanRepo, DEFAULT_EXCLUDED_DIRS } from './scan.js'\nimport {\n cacheKeyForRoot,\n defaultCachePath,\n legacyCachePath,\n loadIndex,\n saveIndex,\n} from './store.js'\nimport type { IndexOptions, IndexedFile, RepoIndex, SymbolInfo } from './types.js'\nimport { REPO_INDEX_SCHEMA_VERSION } from './types.js'\n\n/**\n * Full build: scan + extract every supported file. Existing per-file\n * extraction is reused when `previous` holds an identical mtime for the\n * same rel path (incremental refresh), so touched files alone re-parse.\n */\nexport async function buildIndex(\n root: string,\n options: IndexOptions = {},\n previous: RepoIndex | null = null,\n): Promise<RepoIndex> {\n const scanned = await scanRepo(root, options)\n\n // Index stale/current state from the previous run by rel path.\n const prevByPath = new Map((previous?.files ?? []).map((f) => [f.path, f]))\n const prevMtime = new Map((previous?.files ?? []).map((f) => [f.path, f.mtimeMs]))\n\n const files: IndexedFile[] = []\n const BATCH = 8\n for (let i = 0; i < scanned.length; i += BATCH) {\n const batch = scanned.slice(i, i + BATCH)\n const rows = await Promise.all(\n batch.map(async (f) => {\n const lang = languageForFile(f.abs)\n if (!lang) return null\n if (prevMtime.get(f.rel) === f.mtimeMs) {\n const cached = prevByPath.get(f.rel)!\n return {\n ...cached,\n mtimeMs: f.mtimeMs,\n symbols: cached.symbols.map((symbol) => ({ ...symbol, file: f.rel })),\n }\n }\n let code: string\n try {\n code = await readFile(f.abs, 'utf8')\n } catch {\n return null\n }\n const { symbols, imports, importDetails, calls } = await extractAll(code, lang, f.rel)\n // Backfill the repo-relative path: the extractor is file-agnostic and\n // leaves SymbolInfo.file empty, but search/render depend on it.\n return {\n path: f.rel,\n lang,\n mtimeMs: f.mtimeMs,\n symbols: symbols.map((s) => ({ ...s, file: f.rel })),\n imports,\n importDetails,\n calls,\n } satisfies IndexedFile\n }),\n )\n for (const f of rows) {\n if (f) files.push(f)\n }\n }\n\n return {\n schemaVersion: REPO_INDEX_SCHEMA_VERSION,\n root,\n generatedAt: Date.now(),\n files,\n excludedDirs: [...DEFAULT_EXCLUDED_DIRS, ...(options.excludeDirs ?? [])],\n }\n}\n\n/** Convenience wrapper: evolve an on-disk cache if `root` exists. */\nexport async function buildIndexWithCache(\n root: string,\n options: IndexOptions = {},\n cacheDir?: string,\n): Promise<RepoIndex> {\n const cachePath = defaultCachePath(root, cacheDir)\n let prev = await loadIndex(cachePath)\n let loadedLegacy = false\n if (!prev) {\n const oldPath = legacyCachePath(root, cacheDir)\n if (oldPath !== cachePath) {\n prev = await loadIndex(oldPath)\n loadedLegacy = prev !== null\n }\n }\n const reusable = prev && cacheKeyForRoot(prev.root) === cacheKeyForRoot(root) ? prev : null\n const fresh = await buildIndex(root, options, reusable)\n if (prev && indexesEqual(prev, fresh)) {\n if (loadedLegacy) await saveIndex(cachePath, fresh)\n return loadedLegacy ? fresh : prev\n }\n await saveIndex(cachePath, fresh)\n return fresh\n}\n\nfunction indexesEqual(left: RepoIndex, right: RepoIndex): boolean {\n if (left.schemaVersion !== right.schemaVersion) return false\n if (cacheKeyForRoot(left.root) !== cacheKeyForRoot(right.root)) return false\n if (left.files.length !== right.files.length) return false\n if (left.excludedDirs.length !== right.excludedDirs.length) return false\n if (left.excludedDirs.some((value, index) => value !== right.excludedDirs[index])) return false\n\n return left.files.every((file, fileIndex) => {\n const other = right.files[fileIndex]\n if (!other || file.path !== other.path || file.lang !== other.lang || file.mtimeMs !== other.mtimeMs) {\n return false\n }\n if (file.symbols.length !== other.symbols.length) return false\n if (!callsEqual(file.calls, other.calls)) return false\n if (!importsEqual(file.importDetails, other.importDetails)) return false\n return file.symbols.every((symbol, symbolIndex) => {\n const candidate = other.symbols[symbolIndex]\n return candidate !== undefined\n && symbol.id === candidate.id\n && symbol.name === candidate.name\n && symbol.kind === candidate.kind\n && symbol.file === candidate.file\n && symbol.line === candidate.line\n && symbol.endLine === candidate.endLine\n && symbol.exported === candidate.exported\n && symbol.signature === candidate.signature\n && symbol.ordinal === candidate.ordinal\n && scopesEqual(symbol.scope, candidate.scope)\n })\n })\n}\n\nfunction scopesEqual(left: SymbolInfo['scope'], right: SymbolInfo['scope']): boolean {\n if (left.length !== right.length) return false\n return left.every((part, index) => {\n const other = right[index]\n return other !== undefined\n && part.kind === other.kind\n && part.name === other.name\n && part.ordinal === other.ordinal\n })\n}\n\nfunction importsEqual(\n left: IndexedFile['importDetails'],\n right: IndexedFile['importDetails'],\n): boolean {\n const a = left ?? []\n const b = right ?? []\n if (a.length !== b.length) return false\n return a.every((info, index) => {\n const other = b[index]\n if (\n !other ||\n info.specifier !== other.specifier ||\n info.line !== other.line ||\n info.kind !== other.kind ||\n info.bindings.length !== other.bindings.length\n ) {\n return false\n }\n return info.bindings.every((binding, bindingIndex) => {\n const candidate = other.bindings[bindingIndex]\n return candidate !== undefined\n && binding.imported === candidate.imported\n && binding.local === candidate.local\n && binding.kind === candidate.kind\n })\n })\n}\n\n/**\n * Calls are compared so a cache written before call-graph support is treated as\n * stale and re-persisted, instead of silently shadowing the richer fresh index.\n */\nfunction callsEqual(left: IndexedFile['calls'], right: IndexedFile['calls']): boolean {\n const a = left ?? []\n const b = right ?? []\n if (a.length !== b.length) return false\n return a.every((call, index) => {\n const other = b[index]\n return other !== undefined\n && call.name === other.name\n && call.line === other.line\n && call.from === other.from\n && call.fromId === other.fromId\n && call.qualifier === other.qualifier\n })\n}\n\n/**\n * Locate the git repo root for a path by walking up to the nearest `.git`\n * directory. Bounded walk (max `maxLevels` levels); returns `null` when no\n * repo marker is found — callers must NOT index an untagged directory\n * (the fs root is the classic footgun: indexing `C:\\` by accident).\n */\nexport async function findRepoRoot(startDir: string, maxLevels = 12): Promise<string | null> {\n let dir = path.resolve(startDir)\n for (let level = 0; level < maxLevels; level++) {\n try {\n // stat() accepts BOTH a `.git` directory (normal repos) and a `.git`\n // file (worktrees / submodules) — readFile only handled the file form.\n await stat(path.join(dir, '.git'))\n return dir\n } catch {\n // not a repo here — keep walking\n }\n const parent = path.dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n return null\n}\n","/**\n * tree-sitter symbol extraction.\n *\n * Parses a source text with a per-language grammar (web-tree-sitter WASM,\n * static grammars from tree-sitter-wasms) and returns flat SymbolInfo rows.\n *\n * NOTE on the dependency pin: web-tree-sitter must stay at ^0.20.x — newer\n * releases expect dylinked grammar wasm, while tree-sitter-wasms ships\n * static builds. Verified working pair: web-tree-sitter@0.20.8 + tree-sitter-wasms@0.1.13.\n */\n\nimport { readFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport { type Node, Language, Parser, Query } from 'web-tree-sitter'\nimport type {\n CallInfo,\n ImportBinding,\n ImportInfo,\n ScopeKind,\n SymbolInfo,\n SymbolKind,\n SymbolScopePart,\n} from './types.js'\n\nconst require = createRequire(import.meta.url)\n// web-tree-sitter ≥0.25 is ESM with named exports; 0.20.x was CJS\n// `export = Parser`. tsup externalizes the dep, so the import shape must\n// match the published ESM entry.\n\nexport type LanguageId =\n | 'typescript'\n | 'javascript'\n | 'python'\n | 'go'\n | 'rust'\n | 'java'\n | 'cpp'\n | 'c'\n\nconst WASM_DIR = path.dirname(require.resolve('tree-sitter-wasms/out/tree-sitter-typescript.wasm'))\n\nconst GRAMMAR_NAMES: Record<LanguageId, string> = {\n typescript: 'tree-sitter-typescript',\n javascript: 'tree-sitter-javascript',\n python: 'tree-sitter-python',\n go: 'tree-sitter-go',\n rust: 'tree-sitter-rust',\n java: 'tree-sitter-java',\n cpp: 'tree-sitter-cpp',\n c: 'tree-sitter-c',\n}\n\nconst EXT_TO_LANG: Record<string, LanguageId> = {\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.mts': 'typescript',\n '.cts': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n '.py': 'python',\n '.pyi': 'python',\n '.go': 'go',\n '.rs': 'rust',\n '.java': 'java',\n '.cpp': 'cpp',\n '.cc': 'cpp',\n '.cxx': 'cpp',\n '.c++': 'cpp',\n '.hpp': 'cpp',\n '.hxx': 'cpp',\n '.hh': 'cpp',\n '.h': 'cpp',\n '.ipp': 'cpp',\n '.tpp': 'cpp',\n '.inl': 'cpp',\n '.c': 'c',\n}\n\nexport function languageForFile(filePath: string): LanguageId | null {\n const ext = path.extname(filePath).toLowerCase()\n return EXT_TO_LANG[ext] ?? null\n}\n\n/** Kind of a capture per query. */\ntype CaptureDef = { kind: SymbolKind; exported?: boolean }\n\n// Query definitions per language. Captures bind to the DECLARATION node\n// (capture OUTSIDE the pattern: `(function_declaration) @function` — the\n// 0.20 query parser rejects a capture sitting directly after the node type\n// inside the parens). Names/signatures/export come from node fields.\nconst QUERIES: Record<LanguageId, string> = {\n typescript: `\n (function_declaration) @function\n (generator_function_declaration) @function\n (method_definition) @method\n (class_declaration) @class\n (interface_declaration) @interface\n (type_alias_declaration) @type\n (enum_declaration) @enum\n (variable_declarator) @variable\n (public_field_definition) @field\n (abstract_class_declaration) @class\n `,\n // JS shares the same query surface; type-related patterns simply never match.\n javascript: `\n (function_declaration) @function\n (generator_function_declaration) @function\n (method_definition) @method\n (class_declaration) @class\n (variable_declarator) @variable\n `,\n python: `\n (function_definition) @function\n (class_definition) @class\n `,\n go: `\n (function_declaration) @function\n (method_declaration) @method\n (type_spec) @type\n `,\n rust: `\n (function_item) @function\n (function_signature_item) @method\n (struct_item) @class\n (enum_item) @enum\n (trait_item) @interface\n `,\n java: `\n (class_declaration) @class\n (interface_declaration) @interface\n (enum_declaration) @enum\n (method_declaration) @method\n (constructor_declaration) @method\n `,\n // C++ grammar (superset of C — also serves .h headers). function names\n // live inside the declarator chain, so patterns stay broad and names,\n // kinds and signatures are resolved in code (cppNameOf / kindFor /\n // signatureFor). Top-level `declaration` covers prototypes, constructors\n // and globals; field_declaration covers class-body members.\n cpp: `\n (function_definition) @function\n (class_specifier body: (_)) @class\n (struct_specifier body: (_)) @class\n (enum_specifier body: (_)) @enum\n (type_definition) @type\n (alias_declaration) @type\n (namespace_definition) @module\n (field_declaration) @field\n (declaration) @variable\n `,\n // Plain C: same core nodes minus C++-only namespace/alias forms.\n c: `\n (function_definition) @function\n (struct_specifier body: (_)) @class\n (enum_specifier body: (_)) @enum\n (type_definition) @type\n (field_declaration) @field\n (declaration) @variable\n `,\n}\n\nconst CAPTURE_KINDS: Record<string, CaptureDef> = {\n function: { kind: 'function' },\n method: { kind: 'method' },\n class: { kind: 'class' },\n interface: { kind: 'interface' },\n type: { kind: 'type' },\n enum: { kind: 'enum' },\n variable: { kind: 'variable' },\n field: { kind: 'field' },\n module: { kind: 'module' },\n}\n\n// Import statements per language. Whole statements are captured; the module\n// specifier is read from node fields in code (string quoting, dotted vs\n// relative vs URL-style syntax differ per grammar). CommonJS require() is out\n// of scope — the ES import surface covers the modern plugin ecosystem.\nconst IMPORT_QUERIES: Record<LanguageId, string> = {\n typescript: `\n (import_statement) @import\n (export_statement) @reexport\n `,\n javascript: `\n (import_statement) @import\n (export_statement) @reexport\n `,\n python: `\n (import_from_statement) @import\n (import_statement) @import\n `,\n go: `\n (import_spec) @import\n `,\n rust: `\n (use_declaration) @use\n `,\n java: `\n (import_declaration) @import\n `,\n // C/C++: #include \"local.hpp\" — quoted form resolves in-repo; <system>\n // captures too but yields null and is dropped by the extractor.\n cpp: `\n (preproc_include) @import\n `,\n c: `\n (preproc_include) @import\n `,\n}\n\n// Call expressions per language. Each capture binds the CALLEE name node, so\n// the extractor can build a function-level call graph (see enclosingCallable).\n// Member/selector calls capture the property/field tail, which is what a\n// definition lookup matches; `new X()` is a construction call.\nconst CALL_QUERIES: Record<LanguageId, string> = {\n typescript: `\n (call_expression function: (identifier) @call)\n (call_expression function: (member_expression property: (property_identifier) @call))\n (new_expression constructor: (identifier) @call)\n `,\n javascript: `\n (call_expression function: (identifier) @call)\n (call_expression function: (member_expression property: (property_identifier) @call))\n (new_expression constructor: (identifier) @call)\n `,\n python: `\n (call function: (identifier) @call)\n (call function: (attribute attribute: (identifier) @call))\n `,\n go: `\n (call_expression function: (identifier) @call)\n (call_expression function: (selector_expression field: (field_identifier) @call))\n `,\n rust: `\n (call_expression function: (identifier) @call)\n (call_expression function: (field_expression field: (field_identifier) @call))\n (call_expression function: (scoped_identifier name: (identifier) @call))\n `,\n java: `\n (method_invocation name: (identifier) @call)\n (object_creation_expression type: (type_identifier) @call)\n `,\n cpp: `\n (call_expression function: (identifier) @call)\n (call_expression function: (field_expression field: (field_identifier) @call))\n (call_expression function: (qualified_identifier name: (identifier) @call))\n `,\n c: `\n (call_expression function: (identifier) @call)\n (call_expression function: (field_expression field: (field_identifier) @call))\n `,\n}\n\n// Ancestor node types that own a call body, per language. Walking up from a\n// call site to the nearest one yields the function whose callees they are.\nconst CALLABLE_NODES: Record<LanguageId, Set<string>> = {\n typescript: new Set([\n 'function_declaration',\n 'generator_function_declaration',\n 'method_definition',\n 'function_expression',\n 'arrow_function',\n ]),\n javascript: new Set([\n 'function_declaration',\n 'generator_function_declaration',\n 'method_definition',\n 'function_expression',\n 'arrow_function',\n ]),\n python: new Set(['function_definition']),\n go: new Set(['function_declaration', 'method_declaration', 'func_literal']),\n rust: new Set(['function_item', 'function_signature_item']),\n java: new Set(['method_declaration', 'constructor_declaration']),\n cpp: new Set(['function_definition', 'lambda_expression']),\n c: new Set(['function_definition']),\n}\n\nlet parserPromise: Promise<Parser> | null = null\n\nasync function getParser(): Promise<Parser> {\n if (!parserPromise) {\n parserPromise = (async () => {\n const wasm = path.join(path.dirname(require.resolve('web-tree-sitter')), 'tree-sitter.wasm')\n await Parser.init({ locateFile: () => wasm })\n const p = new Parser()\n return p\n })()\n }\n return parserPromise\n}\n\nconst languageCache = new Map<LanguageId, Promise<Language>>()\n\nfunction getLanguage(id: LanguageId): Promise<Language> {\n let entry = languageCache.get(id)\n if (!entry) {\n entry = getParser().then(async () => {\n const grammarPath = path.join(WASM_DIR, `${GRAMMAR_NAMES[id]}.wasm`)\n const bytes = await readFile(grammarPath)\n const lang = await Language.load(bytes)\n // Precompile queries per language to catch authoring errors early.\n // (0.25 deprecates lang.query(); use the Query constructor.)\n new Query(lang, QUERIES[id]).delete()\n new Query(lang, IMPORT_QUERIES[id]).delete()\n new Query(lang, CALL_QUERIES[id]).delete()\n return lang\n })\n languageCache.set(id, entry)\n }\n return entry\n}\n\n/**\n * Extract symbols and raw import specifiers from source text of the given\n * language, from a single parse. Returns rows ordered by file line. Never\n * throws for parse errors — a failed parse yields empty lists (the caller\n * logs and continues).\n */\n/** RFC 3986-strict component encoding for symbol ids (encodes `! ' ( ) * ~`). */\nexport function encodeSymbolComponent(value: string): string {\n return encodeURIComponent(value).replace(\n /[!'()*~]/g,\n (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`,\n )\n}\n\n/** A captured declaration retained until stable ids can be assigned. */\nexport interface SymbolDraft {\n symbol: Omit<SymbolInfo, 'id' | 'scope' | 'ordinal' | 'file'>\n node: Node\n}\n\nexport interface ExtractedFile {\n symbols: SymbolInfo[]\n /** Derived compatibility view of {@link importDetails} specifiers. */\n imports: string[]\n /** Structured import/include/use sites with name bindings. */\n importDetails: ImportInfo[]\n /** Call sites, ordered by line: callee name + enclosing function. */\n calls: CallInfo[]\n}\n\nexport async function extractAll(\n code: string,\n id: LanguageId,\n file = '',\n): Promise<ExtractedFile> {\n const lang = await getLanguage(id)\n const parser = await getParser()\n parser.setLanguage(lang)\n const tree = parser.parse(code)\n if (!tree) throw new Error(`tree-sitter parse returned null for a ${id} source`)\n try {\n const drafts: SymbolDraft[] = []\n const symbolQuery = new Query(lang, QUERIES[id])\n try {\n const captures = symbolQuery.captures(tree.rootNode)\n for (const cap of captures) {\n const def = CAPTURE_KINDS[cap.name]\n if (!def) continue\n const node = cap.node\n // tree-sitter queries match at any depth; without this check the\n // variable_declarator pattern would also capture function-body\n // locals — pure index noise.\n if (def.kind === 'variable' && !isModuleLevelVariable(id, node)) continue\n const name = nameOf(id, node)\n if (!name) continue\n drafts.push({\n symbol: {\n name,\n kind: kindFor(id, node, def.kind),\n line: node.startPosition.row + 1,\n endLine: node.endPosition.row + 1,\n exported: isExported(id, node),\n signature: signatureFor(id, node),\n },\n node,\n })\n }\n } finally {\n symbolQuery.delete()\n }\n\n const dedupedDrafts = dedupeDrafts(drafts)\n const symbols = assignSymbolIds(file, dedupedDrafts, id)\n const symbolByNodeId = new Map<number, SymbolInfo>()\n dedupedDrafts.forEach((draft, index) => symbolByNodeId.set(draft.node.id, symbols[index]))\n\n const importDetails: ImportInfo[] = []\n const importQuery = new Query(lang, IMPORT_QUERIES[id])\n try {\n for (const cap of importQuery.captures(tree.rootNode)) {\n for (const info of importInfoFor(id, cap.node)) importDetails.push(info)\n }\n } finally {\n importQuery.delete()\n }\n const imports = importDetails.map((info) => info.specifier)\n\n const calls: CallInfo[] = []\n const callQuery = new Query(lang, CALL_QUERIES[id])\n try {\n const seen = new Set<string>()\n for (const cap of callQuery.captures(tree.rootNode)) {\n const name = cap.node.text.trim()\n if (!name) continue\n const line = cap.node.startPosition.row + 1\n const callable = enclosingCallableNode(id, cap.node)\n const from = callable ? callableNameOf(id, callable) : ''\n const fromId = callable ? nearestDraftId(callable, symbolByNodeId) : null\n const key = `${from}|${name}|${line}`\n if (seen.has(key)) continue\n seen.add(key)\n calls.push({ name, line, from, fromId, qualifier: qualifierOf(cap.node) })\n }\n } finally {\n callQuery.delete()\n }\n calls.sort((a, b) => a.line - b.line || a.name.localeCompare(b.name))\n\n symbols.sort(\n (a, b) =>\n a.line - b.line ||\n a.endLine - b.endLine ||\n a.kind.localeCompare(b.kind) ||\n a.name.localeCompare(b.name),\n )\n return { symbols, imports, importDetails, calls }\n } finally {\n tree.delete()\n }\n}\n\n/**\n * Drop duplicate captures of the *same* AST node only. Keying by\n * `kind|name|line` would also collapse two distinct same-named declarations\n * sharing a line (`class A { run() {} } class B { run() {} }`); identity\n * keeps them so `assignOrdinals` can separate them by source order.\n */\nfunction dedupeDrafts(drafts: SymbolDraft[]): SymbolDraft[] {\n const sorted = [...drafts].sort(\n (a, b) => a.symbol.line - b.symbol.line || a.node.startIndex - b.node.startIndex,\n )\n const seen = new Set<number>()\n const out: SymbolDraft[] = []\n for (const draft of sorted) {\n if (seen.has(draft.node.id)) continue\n seen.add(draft.node.id)\n out.push(draft)\n }\n return out\n}\n\n/** One scope owner descriptor produced by a language-specific helper. */\ninterface OwnerDesc {\n kind: ScopeKind\n name: string\n}\n\n/** A scope node: a captured declaration or a synthetic owner, by index. */\ninterface ScopeEntry {\n kind: ScopeKind\n name: string\n startIndex: number\n endIndex: number\n /** Index of the parent entry; -1 = module root. */\n parent: number\n ordinal: number\n scopeKey: string\n /** Draft index for captured declarations; -1 for synthetic owners. */\n draftIndex: number\n}\n\nconst MATCHABLE_OWNER_KINDS: ReadonlySet<ScopeKind> = new Set([\n 'class',\n 'interface',\n 'trait',\n 'module',\n 'namespace',\n 'impl',\n])\n\n/** Map a captured symbol kind onto the scope vocabulary used in symbol ids. */\nfunction scopeKindOf(language: LanguageId, kind: SymbolKind): ScopeKind {\n switch (kind) {\n case 'class':\n return 'class'\n case 'interface':\n return language === 'rust' ? 'trait' : 'interface'\n case 'function':\n return 'function'\n case 'method':\n return 'method'\n case 'module':\n return language === 'cpp' ? 'namespace' : 'module'\n default:\n return 'owner'\n }\n}\n\nfunction segmentOf(entry: ScopeEntry): string {\n return `${entry.kind}:${encodeSymbolComponent(entry.name)}@${entry.ordinal}`\n}\n\n/**\n * Assign stable qualified ids, owner scopes and sibling ordinals to captured\n * declarations. Ordinals are 1-based within a `(parent scope, kind, name)`\n * group, ordered by source position, so ids survive blank-line/comment/body\n * edits but not reordering or inserting an earlier duplicate.\n */\nexport function assignSymbolIds(\n file: string,\n drafts: readonly SymbolDraft[],\n language: LanguageId,\n): SymbolInfo[] {\n const entries: ScopeEntry[] = drafts.map((draft, index) => ({\n kind: scopeKindOf(language, draft.symbol.kind),\n name: draft.symbol.name,\n startIndex: draft.node.startIndex,\n endIndex: draft.node.endIndex,\n parent: -1,\n ordinal: 1,\n scopeKey: '',\n draftIndex: index,\n }))\n const entryByNodeId = new Map<number, number>()\n drafts.forEach((draft, index) => entryByNodeId.set(draft.node.id, index))\n const entriesByName = new Map<string, number[]>()\n entries.forEach((entry, index) => {\n const list = entriesByName.get(entry.name)\n if (list) list.push(index)\n else entriesByName.set(entry.name, [index])\n })\n\n const syntheticByKey = new Map<string, number>()\n\n const resolveOwner = (desc: OwnerDesc, parent: number, selfIndex: number): number => {\n const matches = entriesByName.get(desc.name)\n // Only an owner already scoped under the same parent may absorb this\n // segment — a global name match would attach `b::Widget::draw` to the\n // first `Widget` in the file. `owner` is a wildcard kind: the qualified\n // segment does not know whether it names a class or a namespace.\n const typed = matches?.find((index) => {\n if (index === selfIndex) return false\n const entry = entries[index]!\n if (!MATCHABLE_OWNER_KINDS.has(entry.kind)) return false\n if (entry.parent !== parent) return false\n return desc.kind === 'owner' || entry.kind === desc.kind\n })\n if (typed !== undefined) return typed\n const key = `${parent}\\u0000${desc.kind}\\u0000${desc.name}`\n const existing = syntheticByKey.get(key)\n if (existing !== undefined) return existing\n const index = entries.length\n entries.push({\n kind: desc.kind,\n name: desc.name,\n startIndex: Number.MAX_SAFE_INTEGER,\n endIndex: Number.MAX_SAFE_INTEGER,\n parent,\n ordinal: 1,\n scopeKey: '',\n draftIndex: -1,\n })\n syntheticByKey.set(key, index)\n return index\n }\n\n drafts.forEach((draft, index) => {\n let parent = -1\n for (let node = draft.node.parent; node; node = node.parent) {\n const owner = entryByNodeId.get(node.id)\n if (owner !== undefined) {\n parent = owner\n break\n }\n }\n for (const desc of ownerScopeOf(language, draft.node)) {\n parent = resolveOwner(desc, parent, index)\n }\n entries[index]!.parent = parent\n })\n\n assignOrdinals(entries)\n\n return drafts.map((draft, index) => {\n const entry = entries[index]!\n const chain: ScopeEntry[] = []\n for (let node: ScopeEntry | undefined = entries[entry.parent]; node; node = entries[node.parent]) {\n chain.push(node)\n }\n chain.reverse()\n const scope: SymbolScopePart[] = chain.map((node) => ({\n kind: node.kind,\n name: node.name,\n ordinal: node.ordinal,\n }))\n const segments = [...chain.map(segmentOf), segmentOf(entry)]\n return {\n ...draft.symbol,\n file,\n id: `sym:v1:${encodeSymbolComponent(file)}#${segments.join('/')}`,\n scope,\n ordinal: entry.ordinal,\n }\n })\n}\n\n/** BFS by depth so a parent's scopeKey is known before its children group. */\nfunction assignOrdinals(entries: ScopeEntry[]): void {\n const depthCache = new Map<number, number>()\n const depthOf = (index: number): number => {\n const cached = depthCache.get(index)\n if (cached !== undefined) return cached\n const parent = entries[index]!.parent\n const value = parent >= 0 ? depthOf(parent) + 1 : 0\n depthCache.set(index, value)\n return value\n }\n\n const byDepth = new Map<number, number[]>()\n let maxDepth = 0\n for (let index = 0; index < entries.length; index++) {\n const depth = depthOf(index)\n maxDepth = Math.max(maxDepth, depth)\n const list = byDepth.get(depth)\n if (list) list.push(index)\n else byDepth.set(depth, [index])\n }\n\n for (let depth = 0; depth <= maxDepth; depth++) {\n const groups = new Map<string, number[]>()\n for (const index of byDepth.get(depth) ?? []) {\n const entry = entries[index]!\n const parentKey = entry.parent >= 0 ? entries[entry.parent]!.scopeKey : ''\n const key = `${parentKey}\\u0000${entry.kind}\\u0000${entry.name}`\n const list = groups.get(key)\n if (list) list.push(index)\n else groups.set(key, [index])\n }\n for (const group of groups.values()) {\n group.sort((a, b) => {\n const left = entries[a]!\n const right = entries[b]!\n return (\n left.startIndex - right.startIndex ||\n left.endIndex - right.endIndex ||\n left.kind.localeCompare(right.kind) ||\n left.name.localeCompare(right.name)\n )\n })\n group.forEach((index, position) => {\n const entry = entries[index]!\n entry.ordinal = position + 1\n const segment = segmentOf(entry)\n entry.scopeKey =\n entry.parent >= 0 ? `${entries[entry.parent]!.scopeKey}/${segment}` : segment\n })\n }\n }\n}\n\n/** Owners not represented by lexical ancestry (receiver/impl/qualified names). */\nfunction ownerScopeOf(language: LanguageId, node: Node): OwnerDesc[] {\n if (language === 'go') return goReceiverOwners(node)\n if (language === 'rust') return rustImplOwners(node)\n if (language === 'cpp' || language === 'c') return cppQualifiedOwners(node)\n return []\n}\n\nfunction goReceiverOwners(node: Node): OwnerDesc[] {\n if (node.type !== 'method_declaration') return []\n const receiver = node.childForFieldName('receiver')\n const type = receiver ? findDescendant(receiver, 'type_identifier') : null\n return type ? [{ kind: 'class', name: type.text.trim() }] : []\n}\n\nfunction rustImplOwners(node: Node): OwnerDesc[] {\n if (node.type !== 'function_item' && node.type !== 'function_signature_item') return []\n let impl: Node | null = null\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (parent.type === 'impl_item') {\n impl = parent\n break\n }\n if (parent.type === 'trait_item' || CALLABLE_NODES.rust.has(parent.type)) return []\n }\n if (!impl) return []\n const type = impl.childForFieldName('type')\n const targetName = type ? findDescendant(type, 'type_identifier')?.text.trim() : undefined\n const traitName = impl.childForFieldName('trait')?.text.trim()\n // Keep the impl as its own scope segment: distinct trait impls for one type\n // are separate scopes. Carry `Trait for Type` so `impl A for Config` and\n // `impl B for Config` do not collide; a bare type name covers inherent impls.\n const name = targetName && traitName ? `${traitName} for ${targetName}` : (targetName ?? traitName)\n return name ? [{ kind: 'impl', name }] : []\n}\n\nfunction cppQualifiedOwners(node: Node): OwnerDesc[] {\n const declarator = cppDeclaratorQid(node)\n if (!declarator) return []\n return cppQualifiedSegments(declarator)\n .slice(0, -1)\n .map((name) => ({ kind: 'owner' as ScopeKind, name }))\n}\n\n/** Descend the C/C++ declarator chain to an out-of-class `Scope::name` form. */\nfunction cppDeclaratorQid(node: Node): Node | null {\n let current = node.childForFieldName?.('declarator')\n while (current) {\n if (current.type === 'qualified_identifier') return current\n if (!current.type.includes('declarator')) return null\n current = current.childForFieldName?.('declarator') ?? current.namedChildren[0] ?? null\n }\n return null\n}\n\n/** Flatten a (right-nested) C++ qualified identifier, outermost name first. */\nfunction cppQualifiedSegments(qualified: Node): string[] {\n const scope = qualified.childForFieldName('scope')\n const name = qualified.childForFieldName('name')\n const head = scope ? [scope.text.trim()] : []\n const tail =\n name?.type === 'qualified_identifier'\n ? cppQualifiedSegments(name)\n : [name?.text.trim() ?? '']\n return [...head, ...tail].filter(Boolean)\n}\n\nfunction findDescendant(node: Node, type: string): Node | null {\n if (node.type === type) return node\n for (const child of node.namedChildren) {\n if (!child) continue\n const nested = findDescendant(child, type)\n if (nested) return nested\n }\n return null\n}\n\nfunction nearestDraftId(node: Node, symbols: Map<number, SymbolInfo>): string | null {\n for (let current: Node | null = node; current; current = current.parent) {\n const symbol = symbols.get(current.id)\n if (symbol) return symbol.id\n }\n return null\n}\n\n/** Symbols only — see extractAll for the combined parse. */\nexport async function extractSymbols(code: string, id: LanguageId): Promise<SymbolInfo[]> {\n return (await extractAll(code, id)).symbols\n}\n\n/** The declared name of a declaration node — language-aware dispatch. */\nfunction nameOf(id: LanguageId, node: Node): string {\n if (id === 'cpp' || id === 'c') return cppNameOf(node)\n const field = node.childForFieldName?.('name')\n if (field) return field.text.trim()\n // e.g. an anonymous default export — skip those.\n return ''\n}\n\n/**\n * C/C++ declaration names hide in the declarator chain:\n * - function_definition → declarator:function_declarator → identifier |\n * qualified_identifier (A::b) | field_identifier (in-class method)\n * - class/struct/enum specifiers and alias_declaration carry `name`\n * - type_definition → declarator:type_identifier\n * Returns '' for anonymous declarations (skipped upstream).\n */\nfunction cppNameOf(node: Node): string {\n const nameField = node.childForFieldName?.('name')\n if (nameField) return nameField.text.trim()\n if (node.type === 'type_definition') {\n return node.childForFieldName?.('declarator')?.text.trim() ?? ''\n }\n let declarator = node.childForFieldName?.('declarator')\n if (declarator?.type === 'init_declarator') {\n declarator = declarator.childForFieldName?.('declarator')\n }\n if (declarator) {\n let current: Node | null = declarator\n while (current) {\n if (\n current.type === 'function_declarator' ||\n current.type === 'pointer_declarator' ||\n current.type === 'array_declarator' ||\n current.type === 'reference_declarator' ||\n current.type === 'parenthesized_declarator' ||\n current.type === 'init_declarator'\n ) {\n current = current.childForFieldName?.('declarator') ?? current.namedChildren[0] ?? null\n continue\n }\n if (current.type === 'qualified_identifier') {\n // app::inner::Widget::draw — the bare name is the deepest segment.\n return cppQualifiedSegments(current).at(-1) ?? ''\n }\n if (\n current.type === 'identifier' ||\n current.type === 'field_identifier' ||\n current.type === 'type_identifier'\n ) {\n return current.text.trim()\n }\n break\n }\n }\n return ''\n}\n\n/**\n * The nearest enclosing function/method node of a call site; module level\n * returns null. Anonymous function forms (arrow / function expression) are\n * owned by the variable they are assigned to (see {@link callableNameOf} and\n * {@link nearestDraftId}).\n */\nfunction enclosingCallableNode(id: LanguageId, node: Node): Node | null {\n const callable = CALLABLE_NODES[id]\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (callable.has(parent.type)) return parent\n }\n return null\n}\n\n/** Name of the function/method owning a callable node; '' when anonymous. */\nfunction callableNameOf(id: LanguageId, callable: Node): string {\n const named = nameOf(id, callable)\n if (named) return named\n const declaration = callable.parent\n if (declaration?.type === 'variable_declarator') {\n return declaration.childForFieldName?.('name')?.text.trim() ?? ''\n }\n return ''\n}\n\n/** Receiver/namespace text of a qualified call (`ns.foo()` -> \"ns\"), else null. */\nfunction qualifierOf(node: Node): string | null {\n const parent = node.parent\n if (!parent) return null\n let receiver: Node | null | undefined\n switch (parent.type) {\n case 'member_expression':\n case 'method_invocation':\n case 'attribute':\n receiver = parent.childForFieldName('object')\n break\n case 'selector_expression':\n receiver = parent.childForFieldName('operand')\n break\n case 'field_expression':\n receiver = parent.childForFieldName('value') ?? parent.childForFieldName('argument')\n break\n case 'qualified_identifier':\n case 'scoped_identifier':\n receiver = parent.childForFieldName('scope') ?? parent.childForFieldName('path')\n break\n default:\n return null\n }\n const text = receiver?.text.replace(/\\s+/g, ' ').trim()\n return text ? text : null\n}\n\n/** Structured import sites for a captured import/include/use statement. */\nfunction importInfoFor(id: LanguageId, node: Node): ImportInfo[] {\n const line = node.startPosition.row + 1\n switch (node.type) {\n case 'import_statement':\n return id === 'python' ? pythonModuleImports(node, line) : tsJsImports(node, line)\n case 'export_statement':\n return tsJsReexport(node, line)\n case 'import_from_statement':\n return pythonFromImport(node, line)\n case 'import_spec':\n return goImport(node, line)\n case 'use_declaration':\n return rustUse(node, line)\n case 'import_declaration':\n return javaImport(node, line)\n case 'preproc_include': {\n const specifier = stripQuotes(node.childForFieldName('path')?.text)\n return specifier ? [{ specifier, line, kind: 'include', bindings: [] }] : []\n }\n default:\n return []\n }\n}\n\nfunction tsJsImports(node: Node, line: number): ImportInfo[] {\n const specifier = stripQuotes(node.childForFieldName('source')?.text)\n if (!specifier) return []\n return [{ specifier, line, kind: 'import', bindings: importClauseBindings(node) }]\n}\n\nfunction importClauseBindings(node: Node): ImportBinding[] {\n const bindings: ImportBinding[] = []\n const clause = node.namedChildren.find((child) => child?.type === 'import_clause')\n if (!clause) return bindings\n for (const child of clause.namedChildren) {\n if (!child) continue\n if (child.type === 'identifier') {\n bindings.push({ imported: 'default', local: child.text.trim(), kind: 'default' })\n } else if (child.type === 'namespace_import') {\n const local = child.namedChildren.find((c) => c?.type === 'identifier')?.text.trim()\n if (local) bindings.push({ imported: '*', local, kind: 'namespace' })\n } else if (child.type === 'named_imports') {\n for (const spec of child.namedChildren) {\n if (spec?.type !== 'import_specifier') continue\n const imported = spec.childForFieldName('name')?.text.trim()\n if (!imported) continue\n const alias = spec.childForFieldName('alias')?.text.trim()\n bindings.push({ imported, local: alias ?? imported, kind: 'named' })\n }\n }\n }\n return bindings\n}\n\nfunction tsJsReexport(node: Node, line: number): ImportInfo[] {\n const specifier = stripQuotes(node.childForFieldName('source')?.text)\n if (!specifier) return []\n const bindings: ImportBinding[] = []\n const clause = node.namedChildren.find((child) => child?.type === 'export_clause')\n for (const spec of clause?.namedChildren ?? []) {\n if (spec?.type !== 'export_specifier') continue\n const imported = spec.childForFieldName('name')?.text.trim()\n if (!imported) continue\n const alias = spec.childForFieldName('alias')?.text.trim()\n bindings.push({ imported, local: alias ?? imported, kind: 'named' })\n }\n const namespaceExport = node.namedChildren.find((child) => child?.type === 'namespace_export')\n const local = namespaceExport?.namedChildren.find((c) => c?.type === 'identifier')?.text.trim()\n if (local) bindings.push({ imported: '*', local, kind: 'namespace' })\n return [{ specifier, line, kind: 'reexport', bindings }]\n}\n\nfunction pythonModuleImports(node: Node, line: number): ImportInfo[] {\n const out: ImportInfo[] = []\n for (const nameNode of node.childrenForFieldName('name')) {\n if (!nameNode) continue\n if (nameNode.type === 'aliased_import') {\n const moduleName = nameNode.childForFieldName('name')?.text.trim()\n const specifier = dottedToPath(moduleName)\n if (!specifier) continue\n const alias = nameNode.childForFieldName('alias')?.text.trim()\n out.push({\n specifier,\n line,\n kind: 'import',\n bindings: [\n { imported: moduleName ?? null, local: alias ?? moduleName ?? '', kind: 'namespace' },\n ],\n })\n } else if (nameNode.type === 'dotted_name') {\n const moduleName = nameNode.text.trim()\n const specifier = dottedToPath(moduleName)\n if (!specifier) continue\n out.push({\n specifier,\n line,\n kind: 'import',\n bindings: [{ imported: null, local: moduleName.split('.')[0] ?? moduleName, kind: 'package' }],\n })\n }\n }\n return out\n}\n\nfunction pythonFromImport(node: Node, line: number): ImportInfo[] {\n const raw = node.childForFieldName('module_name')?.text\n if (raw == null) return []\n const specifier = raw.startsWith('.') ? pythonRelative(raw) : dottedToPath(raw)\n if (!specifier) return []\n const moduleNode = node.childForFieldName('module_name')\n const bindings: ImportBinding[] = []\n for (const nameNode of node.namedChildren) {\n if (!nameNode || nameNode.id === moduleNode?.id) continue\n if (nameNode.type === 'aliased_import') {\n const imported = nameNode.childForFieldName('name')?.text.trim()\n if (!imported) continue\n const alias = nameNode.childForFieldName('alias')?.text.trim()\n bindings.push({ imported, local: alias ?? lastDotSegment(imported), kind: 'named' })\n } else if (nameNode.type === 'dotted_name') {\n const imported = nameNode.text.trim()\n bindings.push({ imported, local: lastDotSegment(imported), kind: 'named' })\n } else if (nameNode.type === 'wildcard_import') {\n bindings.push({ imported: '*', local: '*', kind: 'glob' })\n }\n }\n return [{ specifier, line, kind: 'import', bindings }]\n}\n\nfunction goImport(node: Node, line: number): ImportInfo[] {\n const specifier = stripQuotes(node.childForFieldName('path')?.text)\n if (!specifier) return []\n const nameNode = node.childForFieldName('name')\n let binding: ImportBinding\n if (!nameNode) {\n binding = { imported: null, local: lastSlashSegment(specifier), kind: 'package' }\n } else if (nameNode.type === 'dot') {\n binding = { imported: '*', local: '.', kind: 'glob' }\n } else {\n binding = { imported: null, local: nameNode.text.trim(), kind: 'package' }\n }\n return [{ specifier, line, kind: 'import', bindings: [binding] }]\n}\n\nfunction rustUse(node: Node, line: number): ImportInfo[] {\n const argument = node.childForFieldName('argument')\n if (!argument) return []\n const base = argument.type === 'use_as_clause' ? argument.childForFieldName('path') : argument\n const specifier = rustUsePath(base?.text ?? argument.text)\n if (!specifier) return []\n return [{ specifier, line, kind: 'use', bindings: rustBindings(argument) }]\n}\n\nfunction rustBindings(node: Node): ImportBinding[] {\n switch (node.type) {\n case 'scoped_identifier': {\n const imported = node.childForFieldName('name')?.text.trim()\n return imported ? [{ imported, local: imported, kind: 'named' }] : []\n }\n case 'identifier': {\n const name = node.text.trim()\n return name ? [{ imported: name, local: name, kind: 'named' }] : []\n }\n case 'use_as_clause': {\n const path = node.childForFieldName('path')\n const alias = node.childForFieldName('alias')?.text.trim()\n const imported = path ? rustLeafName(path) : null\n return imported && alias ? [{ imported, local: alias, kind: 'named' }] : []\n }\n case 'scoped_use_list': {\n const bindings: ImportBinding[] = []\n for (const item of node.childForFieldName('list')?.namedChildren ?? []) {\n if (item) bindings.push(...rustBindings(item))\n }\n return bindings\n }\n case 'use_wildcard':\n return [{ imported: '*', local: '*', kind: 'glob' }]\n default:\n return []\n }\n}\n\nfunction rustLeafName(node: Node): string | null {\n if (node.type === 'identifier') return node.text.trim()\n return node.childForFieldName('name')?.text.trim() ?? null\n}\n\nfunction javaImport(node: Node, line: number): ImportInfo[] {\n const path = node.namedChildren.find((child) => child?.type === 'scoped_identifier')\n const specifier = dottedToPath(path?.text)\n if (!specifier) return []\n const wildcard = node.namedChildren.some((child) => child?.type === 'asterisk')\n if (wildcard) {\n return [\n { specifier, line, kind: 'import', bindings: [{ imported: '*', local: '*', kind: 'glob' }] },\n ]\n }\n const imported = path?.childForFieldName('name')?.text.trim() ?? lastSlashSegment(specifier)\n const isStatic = /^import\\s+static\\b/.test(node.text)\n return [\n {\n specifier,\n line,\n kind: 'import',\n bindings: [{ imported, local: imported, kind: isStatic ? 'static' : 'named' }],\n },\n ]\n}\n\nfunction lastDotSegment(value: string): string {\n return value.split('.').pop() ?? value\n}\n\nfunction lastSlashSegment(value: string): string {\n return value.split('/').pop() ?? value\n}\n\n/**\n * Rust use paths: 'crate::a::b' is root-relative, 'super::x' is parent-module\n * ('../x'), 'self::x' is current ('./x'); everything else (std, external\n * crates) stays root-relative and simply won't resolve in-repo. Use-lists\n * ('a::b::{c,d}') contribute their base path.\n */\nfunction rustUsePath(text: string | undefined | null): string | null {\n if (!text) return null\n const base = text.split('{')[0].trim()\n if (!base) return null\n const parts = base.split('::').filter(Boolean)\n if (parts[0] === 'crate') parts.shift()\n return parts.map((p) => (p === 'super' ? '..' : p === 'self' ? '.' : p)).join('/')\n}\n\nfunction stripQuotes(text: string | undefined | null): string | null {\n if (text == null || text.length < 2) return null\n const first = text[0]\n const last = text[text.length - 1]\n if ((first === \"'\" && last === \"'\") || (first === '\"' && last === '\"')) {\n return text.slice(1, -1)\n }\n return null\n}\n\n/** 'os.path' → 'os/path' — dotted module path to repo-relative-ish path. */\nfunction dottedToPath(text: string | undefined | null): string | null {\n if (!text) return null\n return text.trim().replace(/\\./g, '/')\n}\n\n/** '.utils' → './utils', '..pkg.mod' → '../pkg/mod' — python relative import. */\nfunction pythonRelative(raw: string): string {\n const dots = raw.match(/^\\.+/)?.[0].length ?? 0\n const rest = raw.slice(dots).replace(/\\./g, '/')\n const prefix = dots === 1 ? './' : '../'.repeat(dots - 1)\n return prefix + rest\n}\n\n/** Best-effort declaration signature: `name` + parameter list, if any. */\nfunction signatureFor(id: LanguageId, node: Node): string {\n const sig = rawSignature(id, node)\n return sig.length > 80 ? `${sig.slice(0, 77)}...` : sig\n}\n\nfunction rawSignature(id: LanguageId, node: Node): string {\n const name = nameOf(id, node)\n // Field first (go method_declaration has both a receiver and a parameters\n // parameter_list — the field picks the right one), type fallback otherwise.\n const params =\n node.childForFieldName?.('parameters') ??\n node.namedChildren.find(\n (c) =>\n c?.type === 'formal_parameters' ||\n c?.type === 'method_parameters' ||\n c?.type === 'parameters' ||\n c?.type === 'parameter_list',\n )\n if (params) {\n return `${name}${collapseSpace(params.text)}`\n }\n if (id === 'cpp' || id === 'c') {\n // C/C++: the parameter list hides inside the declarator chain.\n let current = node.childForFieldName?.('declarator')\n while (current) {\n if (current.type === 'function_declarator') {\n const list = current.childForFieldName?.('parameters')\n return list ? `${name}${collapseSpace(list.text)}` : name\n }\n current = current.childForFieldName?.('declarator') ?? current.namedChildren[0] ?? null\n if (current && !current.type.includes('declarator') && current.type !== 'identifier' && current.type !== 'qualified_identifier' && current.type !== 'field_identifier') break\n }\n }\n const first = node.namedChildren[0]\n return first ? collapseSpace(first.text) : name\n}\n\n/**\n * Signatures must stay one line: repo-map rows are budgeted per line, and a\n * multi-line parameter list would both wrap the format and burn chars.\n */\nfunction collapseSpace(text: string): string {\n return text\n .replace(/\\s+/g, ' ')\n .replace(/\\( /g, '(')\n .replace(/ \\)/g, ')')\n .replace(/ ,/g, ',')\n .replace(/,\\)/g, ')')\n .trim()\n}\n\n/**\n * A variable is indexable only at module level: its declaration must sit\n * directly inside the program (or the export_statement wrapping it). Anything\n * deeper — function bodies, blocks, for-of heads — is a local with no\n * navigation value.\n */\nfunction isModuleLevelVariable(id: LanguageId, node: Node): boolean {\n if (id === 'cpp' || id === 'c') {\n // A (field_)declaration is indexable at namespace/file scope or in a\n // class body — anything inside a function body is a local.\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (parent.type === 'function_definition' || parent.type === 'compound_statement') return false\n if (parent.type === 'translation_unit' || parent.type === 'declaration_list' || parent.type === 'field_declaration_list') return true\n }\n return false\n }\n const declaration = node.parent // variable_declaration | lexical_declaration\n const container = declaration?.parent // program | export_statement | …\n return container?.type === 'program' || container?.type === 'export_statement'\n}\n\n/**\n * A symbol is exported when walking up from it reaches an export_statement\n * before any function or class body — only module-level declarations count.\n * A method inside `export class` must NOT inherit the class's export, and a\n * function nested inside an exported function is not exported either.\n */\nfunction isExported(id: LanguageId, node: Node): boolean {\n if (id === 'python') {\n // Python has no export syntax: a def/class directly under the module is\n // importable, anything nested (methods, inner functions) is not a\n // module-level symbol.\n return node.parent?.type === 'module'\n }\n if (id === 'go') {\n // Go exports by capitalisation, not by keyword.\n const name = nameOf(id, node)\n return !!name && /^[A-Z]/.test(name)\n }\n if (id === 'rust') {\n // `pub` = exported; `pub(crate)` & friends are crate-local, not public.\n return node.namedChildren.some(\n (c) => c?.type === 'visibility_modifier' && c.text === 'pub',\n )\n }\n if (id === 'java') {\n // Interface members are implicitly public.\n if (node.parent?.type === 'interface_body') return true\n return node.namedChildren.some((c) => c?.type === 'modifiers' && /\\bpublic\\b/.test(c?.text ?? ''))\n }\n if (id === 'cpp' || id === 'c') {\n return cppIsExported(node)\n }\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (parent.type === 'export_statement') return true\n if (parent.type === 'statement_block' || parent.type === 'class_body') return false\n if (parent.type === 'program') return false\n }\n return false\n}\n\n/**\n * C/C++ export semantics:\n * - anything under `public:` in a class body is exported; `private:`/\n * `protected:` sections are not\n * - top-level declarations are exported unless marked `static`\n * (internal-linkage). C has no access sections; C++ namespaces stay\n * transparent — a symbol under namespace X is still module-level.\n */\nfunction cppIsExported(node: Node): boolean {\n const isStatic = node.namedChildren.some(\n (c) => c?.type === 'storage_class_specifier' && c.text === 'static',\n )\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (parent.type === 'field_declaration_list') {\n const body = parent\n // Struct members default to public, class members to private (C++ rule).\n const structKind = body.parent?.type === 'struct_specifier' ? 'struct' : 'class'\n let current: string | null = structKind === 'struct' ? 'public' : 'private'\n for (let up: Node | null = node; up && up.id !== body.id; up = up.parent) {\n const next = up.parent\n if (next?.type === 'field_declaration_list') {\n const siblingIndex = next.namedChildren.findIndex((c) => c?.id === up.id)\n const accessBefore = next.namedChildren\n .slice(0, siblingIndex)\n .filter((c) => c?.type === 'access_specifier')\n if (accessBefore.length > 0) {\n current = accessBefore.at(-1)!.text.replace(':', '').trim()\n }\n }\n }\n return current === 'public' && !isStatic\n }\n if (parent.type === 'translation_unit') return !isStatic\n }\n return !isStatic\n}\n\n/**\n * Language quirks the query syntax can't express:\n * - python: no distinct method node — a def directly in a class body is one\n * - go: a type_spec is a class (struct) or interface by its type child\n * - rust: function_item directly in an impl body is a method\n */\nfunction kindFor(id: LanguageId, node: Node, kind: SymbolKind): SymbolKind {\n if (id === 'python' && kind === 'function') {\n const inClassBody = node.parent?.type === 'block' && node.parent?.parent?.type === 'class_definition'\n if (inClassBody) return 'method'\n }\n if (id === 'go' && node.type === 'type_spec') {\n const type = node.childForFieldName('type')?.type\n if (type === 'struct_type') return 'class'\n if (type === 'interface_type') return 'interface'\n return 'type'\n }\n if (id === 'rust' && node.type === 'function_item') {\n const inImpl = node.parent?.type === 'declaration_list' && node.parent?.parent?.type === 'impl_item'\n if (inImpl) return 'method'\n }\n if ((id === 'cpp' || id === 'c') && (kind === 'variable' || kind === 'field')) {\n // A declaration whose declarator chain holds a function_declarator is a\n // function prototype/definition — not a data member or global.\n let current = node.childForFieldName?.('declarator')\n while (current) {\n if (current.type === 'function_declarator') {\n return node.parent?.type === 'field_declaration_list' ? 'method' : 'function'\n }\n current = current.childForFieldName?.('declarator') ?? current.namedChildren[0] ?? null\n }\n return node.type === 'field_declaration' ? 'field' : 'variable'\n }\n if ((id === 'cpp' || id === 'c') && node.type === 'function_definition') {\n // A function defined directly in a class/struct body is a method.\n if (node.parent?.type === 'field_declaration_list') return 'method'\n }\n return kind\n}\n\n/** Compile a symbol query for a code sample (used by tests). */\nexport async function parseFileToSymbols(\n filePath: string,\n repoRoot: string,\n code?: string,\n): Promise<SymbolInfo[]> {\n const lang = languageForFile(filePath)\n if (!lang) return []\n const text = code ?? (await readFile(filePath, 'utf8'))\n const rel = path.relative(repoRoot, filePath).split(path.sep).join('/')\n const { symbols } = await extractAll(text, lang, rel)\n return symbols\n}","/** Workspace file discovery with dir exclusions and mtime tracking. */\n\nimport { readdir, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport type { IndexOptions } from './types.js'\n\nexport const DEFAULT_EXCLUDED_DIRS = [\n 'node_modules',\n '.git',\n '.idea',\n '.vscode',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.next',\n '.nuxt',\n '.cache',\n 'target',\n 'vendor',\n '.dsh-code-index',\n]\n\n/** Language-agnostic source extensions we index. */\nexport const SUPPORTED_EXTS = new Set([\n '.ts',\n '.tsx',\n '.mts',\n '.cts',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.py',\n '.pyi',\n '.go',\n '.rs',\n '.java',\n '.cpp',\n '.cc',\n '.cxx',\n '.c++',\n '.hpp',\n '.hxx',\n '.hh',\n '.h',\n '.ipp',\n '.tpp',\n '.inl',\n '.c',\n])\n\nexport interface ScannedFile {\n /** Absolute path on disk. */\n abs: string\n /** Repo-relative path (forward-slash). */\n rel: string\n mtimeMs: number\n}\n\n/**\n * Recursively walk `root` and return indexed files, skipping excluded dir\n * components at any depth. Uses readdir with `withFileTypes` so we never\n * stat every entry; mtime comes from a targeted stat per candidate file.\n */\nexport async function scanRepo(\n root: string,\n options: IndexOptions = {},\n): Promise<ScannedFile[]> {\n const excluded = new Set([...DEFAULT_EXCLUDED_DIRS, ...(options.excludeDirs ?? [])])\n const results: ScannedFile[] = []\n const queue: Array<[string, string]> = [[root, '']] // [absDir, relDir]\n\n while (queue.length) {\n const [absDir, relDir] = queue.pop()!\n let entries\n try {\n entries = await readdir(absDir, { withFileTypes: true })\n } catch {\n continue // unreadable dir: skip into the void\n }\n for (const entry of entries) {\n const abs = path.join(absDir, entry.name)\n const rel = relDir ? `${relDir}/${entry.name}` : entry.name\n if (entry.isDirectory()) {\n if (excluded.has(entry.name)) continue\n queue.push([abs, rel])\n } else if (entry.isFile() && SUPPORTED_EXTS.has(path.extname(entry.name).toLowerCase())) {\n try {\n const st = await stat(abs)\n results.push({ abs, rel, mtimeMs: st.mtimeMs })\n } catch {\n // race: file deleted mid-scan — ignore\n }\n }\n }\n }\n\n results.sort((a, b) => a.rel.localeCompare(b.rel))\n return results\n}","/** On-disk JSON cache for RepoIndex, keyed by repo root. */\n\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { createHash, randomUUID } from 'node:crypto'\nimport { REPO_INDEX_SCHEMA_VERSION, type RepoIndex } from './types.js'\n\nexport const CACHE_DIR_NAME = '.dsh-code-index'\n\n/** Stable root identity for cache hashing, including Windows case aliases. */\nexport function cacheKeyForRoot(root: string): string {\n const resolved = path.resolve(root)\n return process.platform === 'win32' ? resolved.toLowerCase() : resolved\n}\n\n/** Default cache location: `<repoRoot>/.dsh-code-index/index.json`. */\nexport function defaultCachePath(root: string, cacheDir?: string): string {\n const dir = cacheDir ?? path.join(root, CACHE_DIR_NAME)\n const hash = createHash('sha1').update(cacheKeyForRoot(root)).digest('hex').slice(0, 12)\n return path.join(dir, `${hash}.json`)\n}\n\n/** Cache filename used before Windows root casing was canonicalized. */\nexport function legacyCachePath(root: string, cacheDir?: string): string {\n const dir = cacheDir ?? path.join(root, CACHE_DIR_NAME)\n const hash = createHash('sha1').update(root).digest('hex').slice(0, 12)\n return path.join(dir, `${hash}.json`)\n}\n\nexport async function loadIndex(cachePath: string): Promise<RepoIndex | null> {\n try {\n const raw = await readFile(cachePath, 'utf8')\n const parsed = JSON.parse(raw) as RepoIndex\n if (!parsed || typeof parsed.root !== 'string' || !Array.isArray(parsed.files)) return null\n // Reject caches from an older layout instead of partially healing graph\n // data — the build path reconstructs them at the same path.\n if (parsed.schemaVersion !== REPO_INDEX_SCHEMA_VERSION) return null\n return healSymbolFiles(parsed)\n } catch {\n return null // missing or corrupt cache == no cache\n }\n}\n\n/**\n * Self-heal caches written before the per-symbol file backfill (the\n * \"SymbolInfo.file is always set\" invariant). Empty `file` fields are derived\n * from the containing IndexedFile path on load, so any consumer of loadIndex\n * sees consistent rows — and the next save persists the healed form.\n */\nexport function healSymbolFiles(index: RepoIndex): RepoIndex {\n for (const file of index.files) {\n for (const symbol of file.symbols) {\n if (!symbol.file) symbol.file = file.path\n }\n }\n return index\n}\n\nexport async function saveIndex(cachePath: string, index: RepoIndex): Promise<void> {\n await mkdir(path.dirname(cachePath), { recursive: true })\n const temporaryPath = `${cachePath}.${process.pid}.${randomUUID()}.tmp`\n try {\n await writeFile(temporaryPath, JSON.stringify(index, null, 2), { encoding: 'utf8', flag: 'wx' })\n await rename(temporaryPath, cachePath)\n } finally {\n await rm(temporaryPath, { force: true })\n }\n}\n","/** Shared data model for dsh-code-index. */\n\n/** On-disk cache layout version. Bump when persisted graph/symbol shapes change. */\nexport const REPO_INDEX_SCHEMA_VERSION = 2 as const\n\nexport type SymbolKind =\n | 'function'\n | 'method'\n | 'class'\n | 'interface'\n | 'type'\n | 'enum'\n | 'variable'\n | 'field'\n | 'import'\n | 'module'\n\n/** Stable, file-qualified symbol identity: `sym:v1:<file>#<scope>/<segment>`. */\nexport type SymbolId = string\n\n/** Vocabulary for one scope segment in a qualified symbol id. */\nexport type ScopeKind =\n | 'module'\n | 'namespace'\n | 'class'\n | 'interface'\n | 'trait'\n | 'impl'\n | 'function'\n | 'method'\n | 'owner'\n\nexport interface SymbolScopePart {\n kind: ScopeKind\n name: string\n /** 1-based among sibling scope owners with the same kind and name. */\n ordinal: number\n}\n\nexport interface SymbolInfo {\n /** Stable qualified id; unique within a RepoIndex. */\n id: SymbolId\n /** Symbol name (identifier / type id / member name). */\n name: string\n kind: SymbolKind\n /** Repo-relative path of the containing file, always forward-slash. */\n file: string\n /** 1-based start line. */\n line: number\n /** 1-based end line (inclusive). */\n endLine: number\n /** True when the symbol is exported at module level (export .. / export default). */\n exported: boolean\n /** Short human-readable signature, e.g. `greet(name: string)` — empty when n/a. */\n signature: string\n /** Owners only; excludes the symbol itself. Empty at module level. */\n scope: SymbolScopePart[]\n /** 1-based among symbols with the same scope, kind, and name. */\n ordinal: number\n}\n\n/** One name bound by an import statement, with its local alias. */\nexport interface ImportBinding {\n /** Imported name: \"foo\" | \"default\" | \"*\" | null (namespace/package). */\n imported: string | null\n /** Name visible in this file (alias when renamed). */\n local: string\n kind: 'named' | 'default' | 'namespace' | 'package' | 'static' | 'glob'\n}\n\n/** Structured form of one import/include/use site. */\nexport interface ImportInfo {\n specifier: string\n line: number\n kind: 'import' | 'reexport' | 'include' | 'use'\n bindings: ImportBinding[]\n}\n\n/** One call site: callee name, line, and enclosing function ('' = module level). */\nexport interface CallInfo {\n /** Callee name as written (identifier, member/property, or qualified tail). */\n name: string\n /** 1-based line of the call expression. */\n line: number\n /** Enclosing function/method name, or '' for a module-level call. */\n from: string\n /** Structural owner from AST containment; null at module level. */\n fromId: SymbolId | null\n /** Receiver/namespace text when available: `ns.foo()` -> \"ns\"; bare -> null. */\n qualifier: string | null\n}\n\nexport interface IndexedFile {\n /** Repo-relative path (forward-slash). */\n path: string\n lang: string\n /** fs mtime of the source file at index time (milliseconds). */\n mtimeMs: number\n symbols: SymbolInfo[]\n /** Derived compatibility view of {@link importDetails} specifiers. */\n imports?: string[]\n /** Structured import/include/use sites with their name bindings. */\n importDetails?: ImportInfo[]\n /** Call sites found in this file (callee + line + enclosing function).\n * Optional because caches written before call-graph support lack it. */\n calls?: CallInfo[]\n}\n\nexport interface RepoIndex {\n /** Persisted layout version; see {@link REPO_INDEX_SCHEMA_VERSION}. */\n schemaVersion: typeof REPO_INDEX_SCHEMA_VERSION\n /** Absolute source root this index describes. */\n root: string\n /** Unix ms when the index was generated. */\n generatedAt: number\n files: IndexedFile[]\n excludedDirs: string[]\n}\n\nexport function symbolCount(index: RepoIndex): number {\n return index.files.reduce((n, f) => n + f.symbols.length, 0)\n}\n\n/** Optional config consumed by the index build pipeline. */\nexport interface IndexOptions {\n /** Extra directories to exclude, appended to the defaults. */\n excludeDirs?: string[]\n /** Minimum mtime delta (ms) that forces a re-extract in refresh mode. */\n staleToleranceMs?: number\n}","/**\n * Bounded, ranked repo map generation — the \"aider-style\" overview the model\n * can turn to before browsing files. Pure logic, no IO.\n */\n\nimport path from 'node:path'\nimport { SUPPORTED_EXTS } from './scan.js'\nimport type { IndexedFile, RepoIndex, SymbolKind } from './types.js'\n\n/** Higher-weight symbols pull their file up the map. */\nexport const KIND_WEIGHT: Record<SymbolKind, number> = {\n class: 1.0,\n interface: 1.0,\n type: 0.8,\n function: 0.8,\n method: 0.7,\n enum: 0.9,\n variable: 0.25,\n field: 0.2,\n import: 0.05,\n module: 0.3,\n}\n\nexport interface RepoMapOptions {\n /** Max files to include (default 24). */\n topFiles?: number\n /** Max symbols per file (default 18). */\n symbolsPerFile?: number\n /** Hard cap on rendered characters (default 3200). */\n maxChars?: number\n}\n\nexport interface RepoMapEntry {\n path: string\n score: number\n symbols: Array<{ name: string; kind: SymbolKind; line: number; signature: string }>\n}\n\n/**\n * Paths that look like tests. A map led by test files reads as noise: tests\n * reference an API, they rarely explain it — and symbol density actively\n * favours them (many small functions), so they need an explicit damper.\n */\nconst TEST_PATH_RE =\n /(^|\\/)(tests?|__tests__)(\\/|$)|\\.(?:spec|test)\\.[cm]?[jt]sx?$|(^|\\/)(?:test_[^/]+\\.py|[^/]+_test\\.(?:py|go))$/\n\n/** Density-aware file score: weighted symbols minus bloat; test paths damped. */\nexport function scoreFile(file: IndexedFile): number {\n let score = 0\n for (const sym of file.symbols) {\n score += KIND_WEIGHT[sym.kind] ?? 0.3\n if (sym.exported) score += 0.3\n }\n score /= 1 + file.symbols.length * 0.04\n if (TEST_PATH_RE.test(file.path)) score *= 0.2\n return score\n}\n\n/** Rank files, take the top slice, cap per-file symbols. */\nexport function rankRepoMap(index: RepoIndex, options: RepoMapOptions = {}): RepoMapEntry[] {\n const topFiles = options.topFiles ?? 24\n const perFile = options.symbolsPerFile ?? 18\n const density = new Map<string, number>()\n for (const f of index.files) {\n if (f.symbols.length > 0) density.set(f.path, scoreFile(f))\n }\n const centrality = referencePageRank(index.files, density)\n const ranked = index.files\n .filter((f) => f.symbols.length > 0)\n .map((f) => ({\n file: f,\n score: (density.get(f.path) ?? 0) + REF_WEIGHT * (centrality.get(f.path) ?? 0),\n }))\n .sort((a, b) => b.score - a.score || a.file.path.localeCompare(b.file.path))\n .slice(0, topFiles)\n\n return ranked.map(({ file, score }) => ({\n path: file.path,\n score,\n symbols: file.symbols.slice(0, perFile).map((s) => ({\n name: s.name,\n kind: s.kind,\n line: s.line,\n signature: s.signature,\n })),\n }))\n}\n\n/** How much one unit of reference centrality is worth in map score. */\nconst REF_WEIGHT = 0.5\n\n/**\n * Count in-repo references: how many OTHER indexed files import each file.\n * Self-imports don't count; each (importer, target) pair counts once.\n */\nexport function countReferences(files: IndexedFile[]): Map<string, number> {\n const fileSet = new Set(files.map((f) => f.path))\n const counts = new Map<string, number>()\n for (const file of files) {\n const targets = new Set<string>()\n for (const spec of file.imports ?? []) {\n const target = resolveImport(spec, file.path, fileSet)\n if (target && target !== file.path) targets.add(target)\n }\n for (const target of targets) {\n counts.set(target, (counts.get(target) ?? 0) + 1)\n }\n }\n return counts\n}\n\n/** PageRank damping — the standard 0.85. */\nconst DAMPING = 0.85\n/** Stop the power iteration once total rank movement drops below this. */\nconst CONVERGENCE_TOL = 1e-6\n/** Hard cap; convergence on repo-sized graphs needs ~20-40. */\nconst MAX_ITERATIONS = 100\n\n/**\n * Personalized PageRank over the import graph: nodes are files, an edge\n * A → B means A imports B, so rank flows toward heavily-imported hubs — and\n * a hub that other hubs themselves import accumulates more than a merely\n * popular leaf, which flat in-degree counting cannot see.\n *\n * Teleport uses each file's density share instead of a uniform vector, so\n * sparsely-linked repos keep their 0.2.x ordering (with no edges the fixed\n * point IS the normalized density vector). Returns L1-normalized importance\n * mass per file.\n */\nfunction referencePageRank(files: IndexedFile[], density: Map<string, number>): Map<string, number> {\n const nodes = files.filter((f) => density.has(f.path)).map((f) => f.path)\n const n = nodes.length\n if (n === 0) return new Map()\n if (n === 1) return new Map([[nodes[0]!, 1]])\n\n const totalDensity = nodes.reduce((sum, p) => sum + (density.get(p) ?? 0), 0)\n const teleport = nodes.map((p) => (density.get(p) ?? 0) / totalDensity)\n\n const fileSet = new Set(nodes)\n const out = new Map<string, Set<string>>()\n for (const file of files) {\n if (!fileSet.has(file.path)) continue\n const targets = out.get(file.path) ?? new Set<string>()\n for (const spec of file.imports ?? []) {\n const target = resolveImport(spec, file.path, fileSet)\n if (target && target !== file.path) targets.add(target)\n }\n out.set(file.path, targets)\n }\n\n const incoming = new Map<string, Array<[fromIdx: number, weight: number]>>()\n for (const [from, targets] of out) {\n if (targets.size === 0) continue\n const weight = 1 / targets.size\n const fromIdx = nodes.indexOf(from)\n for (const target of targets) {\n const list = incoming.get(target) ?? []\n list.push([fromIdx, weight])\n incoming.set(target, list)\n }\n }\n\n let rank = teleport.slice()\n for (let iter = 0; iter < MAX_ITERATIONS; iter++) {\n let danglingMass = 0\n for (let i = 0; i < n; i++) {\n if (!out.get(nodes[i]!)?.size) danglingMass += rank[i]!\n }\n const next = new Array<number>(n)\n let delta = 0\n for (let i = 0; i < n; i++) {\n let flow = 0\n for (const [fromIdx, weight] of incoming.get(nodes[i]!) ?? []) {\n flow += rank[fromIdx]! * weight\n }\n next[i] = (1 - DAMPING) * teleport[i]! + DAMPING * (flow + danglingMass * teleport[i]!)\n delta += Math.abs(next[i]! - rank[i]!)\n }\n rank = next\n if (delta < CONVERGENCE_TOL) break\n }\n\n const result = new Map<string, number>()\n for (let i = 0; i < n; i++) result.set(nodes[i]!, rank[i]!)\n return result\n}\n\n/** Outcome of {@link resolveImportDetailed}: the target plus how it matched. */\nexport interface ImportResolution {\n target: string | null\n /**\n * True when only the nested-segment suffix fallback matched (Go module paths,\n * Java packages). Callers that must not over-claim can use this to keep a\n * fuzzy match weaker; the NodeNext `.js`/`.jsx`/`.mjs`/`.cjs` → TS-source\n * substitution at skip 0 is a direct hit, not a fallback.\n */\n suffixSkipped: boolean\n}\n\n/**\n * Resolve a raw import specifier against the indexed file set, reporting both\n * the repo-relative target and whether the nested-segment suffix fallback was\n * needed. Relative specifiers resolve against the importing file; absolute\n * ones against the repo root — the suffix fallback lets Go module paths and\n * Java package names match their in-repo location without reading go.mod /\n * package-info.\n */\nexport function resolveImportDetailed(\n spec: string,\n fromPath: string,\n fileSet: Set<string>,\n): ImportResolution {\n if (!spec) return { target: null, suffixSkipped: false }\n if (spec.startsWith('./') || spec.startsWith('../')) {\n const base = path.posix.normalize(path.posix.join(path.posix.dirname(fromPath), spec))\n return { target: candidateFor(base, fileSet), suffixSkipped: false }\n }\n const segments = spec.split('/').filter(Boolean)\n for (let skip = 0; skip < segments.length; skip++) {\n const hit = candidateFor(segments.slice(skip).join('/'), fileSet)\n if (hit) return { target: hit, suffixSkipped: skip > 0 }\n }\n return { target: null, suffixSkipped: false }\n}\n\n/** Thin wrapper over {@link resolveImportDetailed} returning just the target. */\nexport function resolveImport(spec: string, fromPath: string, fileSet: Set<string>): string | null {\n return resolveImportDetailed(spec, fromPath, fileSet).target\n}\n\n/** Extension and index-file candidates for a specifier base path. */\nfunction candidateFor(base: string, fileSet: Set<string>): string | null {\n // Bare path first: C/C++ includes already carry their extension\n // (\"net/socket.hpp\"), and matching the exact file beats guessing.\n if (fileSet.has(base)) return base\n for (const ext of SUPPORTED_EXTS) {\n if (fileSet.has(`${base}${ext}`)) return `${base}${ext}`\n }\n // TS 5 / NodeNext ESM: a local import is written with the *emitted* extension\n // ('./util.js') while the source on disk is './util.ts'. Map the JS family\n // back to its TypeScript source before falling through to directory indexes.\n const aliased = tsSourceForJsSpecifier(base, fileSet)\n if (aliased) return aliased\n for (const ext of SUPPORTED_EXTS) {\n if (fileSet.has(`${base}/index${ext}`)) return `${base}/index${ext}`\n if (fileSet.has(`${base}/__init__${ext}`)) return `${base}/__init__${ext}`\n }\n return null\n}\n\n/** Resolve a JS-extension specifier ('.js/.jsx/.mjs/.cjs') to on-disk TS source. */\nfunction tsSourceForJsSpecifier(base: string, fileSet: Set<string>): string | null {\n const match = /\\.(js|jsx|mjs|cjs)$/.exec(base)\n if (!match) return null\n const stem = base.slice(0, base.length - match[0].length)\n const candidates =\n match[1] === 'jsx'\n ? ['.tsx', '.ts']\n : match[1] === 'mjs'\n ? ['.mts', '.ts']\n : match[1] === 'cjs'\n ? ['.cts', '.ts']\n : ['.ts', '.tsx']\n for (const ext of candidates) {\n if (fileSet.has(`${stem}${ext}`)) return `${stem}${ext}`\n }\n return null\n}\n\n/** Render the ranked map as markdown, hard-truncated to maxChars. */\nexport function renderRepoMap(entries: RepoMapEntry[], options: RepoMapOptions = {}): string {\n const maxChars = options.maxChars ?? 3200\n const lines: string[] = ['# repo map']\n let totalSymbols = 0\n for (const e of entries) {\n totalSymbols += e.symbols.length\n lines.push(`## ${e.path} (${e.symbols.length})`)\n for (const s of e.symbols) {\n const label = s.signature || s.name\n lines.push(` ${s.kind} ${label} :${s.line}`)\n }\n }\n let text = lines.join('\\n')\n if (text.length > maxChars) {\n text = `${text.slice(0, maxChars)}\\n… truncated`\n }\n return totalSymbols > 0 ? text : ''\n}","/** Function-level call graph built from the cached index — pure, no IO. */\n\nimport { resolveImport, resolveImportDetailed } from './repomap.js'\nimport type {\n CallInfo,\n ImportBinding,\n IndexedFile,\n RepoIndex,\n SymbolId,\n SymbolInfo,\n} from './types.js'\n\n/** name -> definitions; several when same-named symbols live in different files. */\nexport function buildSymbolTable(index: RepoIndex): Map<string, SymbolInfo[]> {\n const table = new Map<string, SymbolInfo[]>()\n for (const file of index.files) {\n for (const symbol of file.symbols) {\n const list = table.get(symbol.name)\n if (list) list.push(symbol)\n else table.set(symbol.name, [symbol])\n }\n }\n for (const list of table.values()) {\n list.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line)\n }\n return table\n}\n\n/** One call site that invokes the queried symbol. */\nexport interface CallerHit {\n file: string\n line: number\n from: string\n}\n\n/** One distinct symbol the queried function calls, with its first call line. */\nexport interface CalleeHit {\n name: string\n line: number\n /** In-repo definitions matched by the callee name. */\n targets: SymbolInfo[]\n}\n\nexport interface SymbolRefs {\n /** Definitions of the queried symbol (empty when only call sites exist). */\n defs: SymbolInfo[]\n callers: CallerHit[]\n callees: CalleeHit[]\n}\n\n/** How many call sites reference each name — used to rank search hits. */\nexport function callerCounts(index: RepoIndex): Map<string, number> {\n const counts = new Map<string, number>()\n for (const file of index.files) {\n for (const call of file.calls ?? []) {\n counts.set(call.name, (counts.get(call.name) ?? 0) + 1)\n }\n }\n return counts\n}\n\n/**\n * Resolve one symbol to its callers (call sites invoking it anywhere) and its\n * callees (calls made inside the definition, attributed by the extracted\n * enclosing-function name). Name-based, so it is a best-effort view: like-named\n * symbols are reported as candidates rather than guessed apart.\n */\nexport function symbolRefs(index: RepoIndex, symbol: string, limit = 200): SymbolRefs {\n const table = buildSymbolTable(index)\n const defs = table.get(symbol) ?? []\n\n const callers: CallerHit[] = []\n const calleeFirstLine = new Map<string, number>()\n for (const file of index.files) {\n for (const call of file.calls ?? []) {\n if (call.name === symbol) {\n callers.push({ file: file.path, line: call.line, from: call.from })\n }\n if (call.from === symbol && !calleeFirstLine.has(call.name)) {\n calleeFirstLine.set(call.name, call.line)\n }\n }\n }\n\n callers.sort(\n (a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.from.localeCompare(b.from),\n )\n\n const callees: CalleeHit[] = [...calleeFirstLine.entries()]\n .map(([name, line]) => ({ name, line, targets: table.get(name) ?? [] }))\n .sort((a, b) => a.line - b.line || a.name.localeCompare(b.name))\n\n return {\n defs,\n callers: callers.slice(0, limit),\n callees: callees.slice(0, limit),\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Provenance-labeled reference graph (design §2) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * How sure the graph is about one resolved edge. Deliberately coarse: the\n * index has no type checker, so `exact` only ever means \"one structurally\n * unambiguous target under this index's model\".\n */\nexport type ResolutionLabel = 'exact' | 'import-scoped' | 'name-only'\n\n/** Which resolution tier produced an edge — the *why* behind its label. */\nexport type ResolutionProvenance =\n | 'structural-owner'\n | 'local-unique'\n | 'explicit-import-binding'\n | 'namespace-import'\n | 'resolved-import-module'\n | 'global-name'\n\n/** One resolved call edge; one row per candidate target. */\nexport interface ReferenceEdge {\n /** Call's structural owner, or null for a module-level call. */\n sourceId: SymbolId | null\n targetId: SymbolId\n callSite: { file: string; line: number }\n /** Callee name as written at the call site. */\n name: string\n provenance: ResolutionProvenance\n resolution: ResolutionLabel\n /** Total candidates produced at this tier (may exceed the emitted edges). */\n candidateCount: number\n}\n\n/** Adjacency views over the same edge set, plus ownerless call sites. */\nexport interface ReferenceGraph {\n symbolsById: Map<SymbolId, SymbolInfo>\n /** sourceId -> edges it emits. */\n outgoing: Map<SymbolId, ReferenceEdge[]>\n /** targetId -> edges that point at it (including module-level calls). */\n incoming: Map<SymbolId, ReferenceEdge[]>\n /** Edges whose call site has no structural owner. */\n moduleLevelEdges: ReferenceEdge[]\n}\n\nexport interface ReferenceGraphOptions {\n /** Max candidate targets emitted per call site (default 8). */\n maxCandidatesPerCall?: number\n}\n\nconst DEFAULT_MAX_CANDIDATES = 8\n\n/**\n * Build the provenance-labeled reference graph for an index. Pure: reads the\n * cached index only. Existing `code_refs` helpers above keep their name-based\n * behavior; this graph is the precise-by-provenance successor.\n */\nexport function buildReferenceGraph(\n index: RepoIndex,\n options: ReferenceGraphOptions = {},\n): ReferenceGraph {\n const maxCandidates = options.maxCandidatesPerCall ?? DEFAULT_MAX_CANDIDATES\n const symbolsById = new Map<SymbolId, SymbolInfo>()\n const symbolsByFile = new Map<string, SymbolInfo[]>()\n for (const file of index.files) {\n for (const symbol of file.symbols) symbolsById.set(symbol.id, symbol)\n symbolsByFile.set(file.path, file.symbols)\n }\n const symbolsByName = buildSymbolTable(index)\n const fileSet = new Set(index.files.map((file) => file.path))\n\n const outgoing = new Map<SymbolId, ReferenceEdge[]>()\n const incoming = new Map<SymbolId, ReferenceEdge[]>()\n const moduleLevelEdges: ReferenceEdge[] = []\n\n for (const file of index.files) {\n for (const call of file.calls ?? []) {\n const edges = resolveCallTargetsFor(\n fileSet,\n file,\n call,\n symbolsByName,\n symbolsByFile,\n maxCandidates,\n )\n if (edges.length === 0) continue\n if (call.fromId) {\n appendEdges(outgoing, call.fromId, edges)\n } else {\n moduleLevelEdges.push(...edges)\n }\n for (const edge of edges) appendEdges(incoming, edge.targetId, [edge])\n }\n }\n\n return { symbolsById, outgoing, incoming, moduleLevelEdges }\n}\n\n/**\n * Resolve one call site to zero or more target edges, stopping at the first\n * non-empty resolution tier (see §2 of the design):\n *\n * 1. provably-owned local candidate (recursion / directly-owned declaration)\n * 2. explicit imported binding (incl. an honest default-binding path)\n * 3. qualifier matched to a namespace/package import\n * 4. names declared in resolved imported modules\n * 5. repo-wide name candidates\n */\nexport function resolveCallTargets(\n index: RepoIndex,\n file: IndexedFile,\n call: CallInfo,\n symbolsByName: Map<string, SymbolInfo[]>,\n maxCandidates = DEFAULT_MAX_CANDIDATES,\n): ReferenceEdge[] {\n const fileSet = new Set(index.files.map((f) => f.path))\n const symbolsByFile = new Map(index.files.map((f) => [f.path, f.symbols]))\n return resolveCallTargetsFor(fileSet, file, call, symbolsByName, symbolsByFile, maxCandidates)\n}\n\nfunction resolveCallTargetsFor(\n fileSet: Set<string>,\n file: IndexedFile,\n call: CallInfo,\n symbolsByName: Map<string, SymbolInfo[]>,\n symbolsByFile: Map<string, SymbolInfo[]>,\n maxCandidates: number,\n): ReferenceEdge[] {\n const named = symbolsByName.get(call.name) ?? []\n const qualified = call.qualifier !== null\n // Re-exports do not bind names in this module; only genuine imports can\n // target a call (§2 — re-export chains cannot claim exact).\n const imports = (file.importDetails ?? []).filter((info) => info.kind !== 'reexport')\n\n // Bare calls only: a qualified call names a member of its receiver, so a\n // same-named local or import binding must not capture it.\n if (!qualified) {\n // Tier 1 — a same-file symbol whose scope encloses this call site. `exact`\n // needs provable ownership: a parameter or local the index cannot see may\n // shadow any other name, including a module-level sibling.\n const locals = named.filter((s) => s.file === file.path && lexicallyVisible(s, call))\n if (locals.length > 0) {\n const unique = locals.length === 1\n const owned = unique && isStructuralOwner(call, locals[0]!)\n const provenance: ResolutionProvenance =\n owned && call.fromId !== null ? 'structural-owner' : 'local-unique'\n return toEdges(locals, call, file.path, provenance, owned ? 'exact' : 'name-only', maxCandidates)\n }\n\n // Tier 2 — explicit imported binding (`import { foo } from './x'`).\n const bound: SymbolInfo[] = []\n let directBinding = true\n let defaultBinding = false\n for (const info of imports) {\n for (const binding of info.bindings) {\n if (binding.local !== call.name) continue\n const isDefault = binding.kind === 'default' || binding.imported === 'default'\n if (!isDefault && !isExplicitBinding(binding)) continue\n const resolved = resolveImportDetailed(info.specifier, file.path, fileSet)\n const target = resolved.target\n if (!target) continue\n if (resolved.suffixSkipped) directBinding = false\n if (isDefault) {\n // `import x from './m'` binds a default export the index cannot name;\n // an alias match against the module's symbols is the only honest\n // target, else the module's exported set — and never `exact`.\n defaultBinding = true\n const moduleSymbols = symbolsByFile.get(target) ?? []\n const nameMatches = moduleSymbols.filter((s) => s.name === binding.local)\n bound.push(\n ...(nameMatches.length > 0 ? nameMatches : moduleSymbols.filter((s) => s.exported)),\n )\n continue\n }\n if (!isExplicitBinding(binding)) continue\n for (const def of symbolsByName.get(binding.imported) ?? []) {\n if (def.file === target) bound.push(def)\n }\n }\n }\n if (bound.length > 0) {\n const label: ResolutionLabel =\n bound.length === 1 && directBinding && !defaultBinding ? 'exact' : 'import-scoped'\n return toEdges(bound, call, file.path, 'explicit-import-binding', label, maxCandidates)\n }\n\n // Tier 4 — the name exists in a module this file imports, binding or not.\n const resolvedModules = new Set<string>()\n for (const info of imports) {\n const target = resolveImport(info.specifier, file.path, fileSet)\n if (target && target !== file.path) resolvedModules.add(target)\n }\n const imported = named.filter((s) => resolvedModules.has(s.file))\n if (imported.length > 0) {\n return toEdges(\n imported,\n call,\n file.path,\n 'resolved-import-module',\n 'import-scoped',\n maxCandidates,\n )\n }\n }\n\n // Tier 3 — `ns.foo()` where `ns` is a namespace/package import. A qualifier\n // must be an actual namespace/package binding; only a record that carries no\n // binding at all (e.g. a C/C++ include) may infer it from the path segment,\n // and even then it never elevates above `import-scoped`.\n if (qualified) {\n const qualifier = call.qualifier!\n const modules = new Set<string>()\n for (const info of imports) {\n const namespaceBound = info.bindings.some(\n (b) => (b.kind === 'namespace' || b.kind === 'package') && b.local === qualifier,\n )\n if (!namespaceBound) {\n if (info.bindings.length > 0) continue\n if (specifierLastSegment(info.specifier) !== qualifier) continue\n }\n const target = resolveImport(info.specifier, file.path, fileSet)\n if (target && target !== file.path) modules.add(target)\n }\n const qualifiedTargets = named.filter((s) => modules.has(s.file))\n if (qualifiedTargets.length > 0) {\n return toEdges(\n qualifiedTargets,\n call,\n file.path,\n 'namespace-import',\n 'import-scoped',\n maxCandidates,\n )\n }\n }\n\n // Tier 5 — repo-wide name match, no import evidence.\n if (named.length > 0) {\n return toEdges(named, call, file.path, 'global-name', 'name-only', maxCandidates)\n }\n return []\n}\n\n/** Materialize one edge per candidate, capped — `candidateCount` stays truthful. */\nfunction toEdges(\n candidates: SymbolInfo[],\n call: CallInfo,\n filePath: string,\n provenance: ResolutionProvenance,\n resolution: ResolutionLabel,\n maxCandidates: number,\n): ReferenceEdge[] {\n const unique = dedupeSymbols(candidates)\n const count = unique.length\n const cap = maxCandidates > 0 ? Math.floor(maxCandidates) : 0\n return unique.slice(0, cap).map((target) => ({\n sourceId: call.fromId,\n targetId: target.id,\n callSite: { file: filePath, line: call.line },\n name: call.name,\n provenance,\n resolution,\n candidateCount: count,\n }))\n}\n\nfunction appendEdges(\n map: Map<SymbolId, ReferenceEdge[]>,\n key: SymbolId,\n edges: ReferenceEdge[],\n): void {\n const list = map.get(key)\n if (list) list.push(...edges)\n else map.set(key, [...edges])\n}\n\nfunction dedupeSymbols(candidates: SymbolInfo[]): SymbolInfo[] {\n const sorted = [...candidates].sort(compareSymbols)\n const out: SymbolInfo[] = []\n const seen = new Set<SymbolId>()\n for (const symbol of sorted) {\n if (seen.has(symbol.id)) continue\n seen.add(symbol.id)\n out.push(symbol)\n }\n return out\n}\n\nfunction compareSymbols(a: SymbolInfo, b: SymbolInfo): number {\n return (\n a.file.localeCompare(b.file) ||\n a.line - b.line ||\n a.kind.localeCompare(b.kind) ||\n a.name.localeCompare(b.name) ||\n a.id.localeCompare(b.id)\n )\n}\n\n/**\n * A candidate is lexically visible at the call when its *containing* scope is\n * an ancestor of the call's structural owner (or of the module, for a\n * module-level call). The symbol-id path encodes the scope chain, so this is a\n * prefix test rather than a re-parse.\n */\nfunction lexicallyVisible(candidate: SymbolInfo, call: CallInfo): boolean {\n if (call.fromId) {\n const ownerPath = pathAfterHash(call.fromId)\n const scopePath = containerPath(candidate.id)\n if (scopePath === '') return true\n return ownerPath === scopePath || ownerPath.startsWith(`${scopePath}/`)\n }\n if (candidate.scope.length === 0) return true\n return candidate.line <= call.line && call.line <= candidate.endLine\n}\n\n/**\n * True when the target's containment structurally proves ownership: a\n * module-level target called from module scope (no callable can shadow it),\n * the call's own owner (recursion), or a declaration directly inside the\n * call's owner. A module-level symbol called from *inside* a callable is not\n * proof — an unseen parameter or local may shadow it.\n */\nfunction isStructuralOwner(call: CallInfo, target: SymbolInfo): boolean {\n if (!call.fromId) return containerPath(target.id) === ''\n if (target.id === call.fromId) return true\n return containerPath(target.id) === pathAfterHash(call.fromId)\n}\n\n/** Scope-chain portion of a symbol id (the part between `#` and the last `/`). */\nfunction pathAfterHash(id: SymbolId): string {\n const hash = id.indexOf('#')\n return hash >= 0 ? id.slice(hash + 1) : id\n}\n\nfunction containerPath(id: SymbolId): string {\n const full = pathAfterHash(id)\n const slash = full.lastIndexOf('/')\n return slash >= 0 ? full.slice(0, slash) : ''\n}\n\n/** A binding that names one concrete imported symbol (not a namespace/glob). */\nfunction isExplicitBinding(\n binding: ImportBinding,\n): binding is ImportBinding & { imported: string } {\n return binding.imported != null && binding.imported !== '*' && binding.imported !== 'default'\n}\n\n/** Last path-like segment of a specifier, extension stripped. */\nfunction specifierLastSegment(specifier: string): string {\n const clean = specifier.split(/[?#]/)[0] ?? specifier\n const segment = clean.split('/').filter(Boolean).pop() ?? clean\n return segment.replace(/\\.[A-Za-z0-9]+$/, '')\n}\n","/** Pure search / filter logic over a RepoIndex — unit-testable, no IO. */\n\nimport type { RepoIndex, SymbolInfo, SymbolKind } from './types.js'\nimport { callerCounts } from './refgraph.js'\n\nexport interface SymbolFilter {\n query?: string\n file?: string\n kind?: SymbolKind\n exportedOnly?: boolean\n}\n\nexport interface RankedHit extends SymbolInfo {\n /** 0..1 relevance. 1 = exact name match; lower = fuzzier. */\n score: number\n}\n\nfunction matchScore(name: string, query: string): number {\n const q = query.toLowerCase()\n const n = name.toLowerCase()\n if (n === q) return 1\n if (n.startsWith(q)) return 0.8\n if (n.includes(q)) return 0.5\n if (q.length >= 3 && isSubsequence(q, n)) return 0.3\n return 0\n}\n\n/**\n * Every query char appears in the name, in order — 'cfgldr' finds\n * 'configLoader'. Gated to 3+ chars so short queries don't match everything.\n */\nfunction isSubsequence(query: string, name: string): boolean {\n let i = 0\n for (const ch of name) {\n if (ch === query[i]) i++\n if (i === query.length) return true\n }\n return false\n}\n\n/** Filter symbols by file/kind/export, then score by name against query (if any). */\nexport function searchSymbols(\n index: RepoIndex,\n filter: SymbolFilter,\n limit = 50,\n): RankedHit[] {\n const q = (filter.query ?? '').trim()\n const filePat = filter.file?.trim().toLowerCase()\n const hits: RankedHit[] = []\n\n for (const file of index.files) {\n if (filePat && !file.path.toLowerCase().includes(filePat)) continue\n for (const sym of file.symbols) {\n if (filter.kind && sym.kind !== filter.kind) continue\n if (filter.exportedOnly && !sym.exported) continue\n const score = q ? matchScore(sym.name, q) : 0.4\n if (q && score === 0) continue\n hits.push({ ...sym, score })\n }\n }\n\n // Export boost, then relevance, then call fan-in, then stable name order.\n const refs = callerCounts(index)\n hits.sort((a, b) => {\n const ab =\n Number(b.exported) - Number(a.exported) ||\n b.score - a.score ||\n (refs.get(b.name) ?? 0) - (refs.get(a.name) ?? 0) ||\n a.name.localeCompare(b.name) ||\n a.file.localeCompare(b.file)\n return ab\n })\n return hits.slice(0, limit)\n}\n\n/** Neat one-line rendering of a hit for terminal/chat output. */\nexport function renderHit(hit: RankedHit): string {\n const exportMark = hit.exported ? 'export ' : ''\n const sig = hit.signature || hit.name\n const score = hit.score < 1 ? ` [${hit.score.toFixed(2)}]` : ''\n return `${exportMark}${hit.kind} ${sig}${score} — ${hit.file}:${hit.line}`\n}","/** Import-graph health checks: circular dependencies and orphan modules. */\n\nimport { resolveImport } from './repomap.js'\nimport type { RepoIndex } from './types.js'\n\nexport interface ModuleGraph {\n nodes: string[]\n edges: Map<string, Set<string>>\n}\n\n/** Nodes are indexed files; an edge A -> B means A imports B (self-edges dropped). */\nexport function buildModuleGraph(index: RepoIndex): ModuleGraph {\n const nodes = index.files.map((file) => file.path).sort((a, b) => a.localeCompare(b))\n const fileSet = new Set(nodes)\n const edges = new Map<string, Set<string>>()\n for (const file of index.files) {\n const targets = new Set<string>()\n for (const spec of file.imports ?? []) {\n const target = resolveImport(spec, file.path, fileSet)\n if (target && target !== file.path) targets.add(target)\n }\n edges.set(file.path, targets)\n }\n return { nodes, edges }\n}\n\n/** Tarjan strongly-connected components of size > 1 — i.e. import cycles. */\nexport function findCycles(index: RepoIndex): string[][] {\n const { nodes, edges } = buildModuleGraph(index)\n const discovery = new Map<string, number>()\n const low = new Map<string, number>()\n const onStack = new Set<string>()\n const stack: string[] = []\n const components: string[][] = []\n let counter = 0\n\n const visit = (node: string): void => {\n discovery.set(node, counter)\n low.set(node, counter)\n counter++\n stack.push(node)\n onStack.add(node)\n\n for (const next of edges.get(node) ?? []) {\n if (!discovery.has(next)) {\n visit(next)\n low.set(node, Math.min(low.get(node)!, low.get(next)!))\n } else if (onStack.has(next)) {\n low.set(node, Math.min(low.get(node)!, discovery.get(next)!))\n }\n }\n\n if (low.get(node) === discovery.get(node)) {\n const component: string[] = []\n for (;;) {\n const member = stack.pop()!\n onStack.delete(member)\n component.push(member)\n if (member === node) break\n }\n if (component.length > 1) components.push(component.sort())\n }\n }\n\n for (const node of nodes) {\n if (!discovery.has(node)) visit(node)\n }\n components.sort((a, b) => a[0]!.localeCompare(b[0]!))\n return components\n}\n\nconst ENTRY_RE =\n /(^|\\/)(index|main|cli|app|server|mod|lib|__init__)\\.[A-Za-z0-9]+$|(^|\\/)(bin|cmd|scripts)\\/|\\.config\\.[A-Za-z0-9]+$/\nconst TEST_RE =\n /(^|\\/)(tests?|__tests__)(\\/|$)|\\.(?:spec|test)\\.[cm]?[jt]sx?$|(^|\\/)(?:test_[^/]+\\.py|[^/]+_test\\.(?:py|go))$/\n\n/**\n * Symbol-bearing files that neither import nor are imported by any other file,\n * excluding conventional entry points and tests (which are legitimately\n * unreferenced). A cheap, low-false-positive stand-in for dead-code detection.\n */\nexport function findOrphanModules(index: RepoIndex): string[] {\n const { nodes, edges } = buildModuleGraph(index)\n const incoming = new Map<string, number>()\n for (const targets of edges.values()) {\n for (const target of targets) incoming.set(target, (incoming.get(target) ?? 0) + 1)\n }\n const withSymbols = new Set(\n index.files.filter((file) => file.symbols.length > 0).map((file) => file.path),\n )\n return nodes.filter(\n (path) =>\n withSymbols.has(path) &&\n (incoming.get(path) ?? 0) === 0 &&\n (edges.get(path)?.size ?? 0) === 0 &&\n !ENTRY_RE.test(path) &&\n !TEST_RE.test(path),\n )\n}\n","/**\n * Unified-diff parsing and a thin `git` adapter.\n *\n * `parseUnifiedDiff` is pure (no IO) so it is unit-testable in isolation; the\n * two readers shell out to `git` exclusively through `execFile` with an argv\n * array — a ref or path is never interpolated into a shell string.\n */\n\nimport { execFile } from 'node:child_process'\nimport { readFile } from 'node:fs/promises'\nimport path from 'node:path'\n\n/** One `@@` hunk header; a missing count means 1 (git omits `,1`). */\nexport interface DiffHunk {\n oldStart: number\n oldLines: number\n newStart: number\n newLines: number\n}\n\n/** One file's entry in a unified diff. */\nexport interface FileChange {\n /** Repo-relative path on the base side, or null for an added file. */\n oldPath: string | null\n /** Repo-relative path on the current side, or null for a deleted file. */\n newPath: string | null\n status: 'added' | 'modified' | 'deleted' | 'renamed'\n hunks: DiffHunk[]\n}\n\nconst HUNK_RE = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/\nconst HEADER_PATH_PREFIX_RE = /^[ab]\\//\n/** Git can emit large diffs; keep a generous but bounded capture buffer. */\nconst MAX_BUFFER = 64 * 1024 * 1024\n\ninterface Draft {\n oldPath: string | null\n newPath: string | null\n /** Fallback paths from the `diff --git` line, overridden by later records. */\n gitOldPath: string | null\n gitNewPath: string | null\n /** Set when `---`/`+++` was seen, so an explicit /dev/null is not re-filled. */\n sawOldHeader: boolean\n sawNewHeader: boolean\n renameFrom: string | null\n renameTo: string | null\n newFile: boolean\n deletedFile: boolean\n hunks: DiffHunk[]\n /** Once a hunk starts, `---`/`+++` lines are content, not file headers. */\n sawHunk: boolean\n}\n\nfunction newDraft(): Draft {\n return {\n oldPath: null,\n newPath: null,\n gitOldPath: null,\n gitNewPath: null,\n sawOldHeader: false,\n sawNewHeader: false,\n renameFrom: null,\n renameTo: null,\n newFile: false,\n deletedFile: false,\n hunks: [],\n sawHunk: false,\n }\n}\n\n/**\n * Parse `git diff` / `diff -u` output into per-file changes. Handles\n * `diff --git`, `new file mode`, `deleted file mode`, `rename from/to`,\n * `---`/`+++` (including `/dev/null`), and `@@` headers with omitted counts.\n */\nexport function parseUnifiedDiff(text: string): FileChange[] {\n const changes: FileChange[] = []\n let draft: Draft | null = null\n\n for (const line of text.split('\\n')) {\n if (line.startsWith('diff --git ')) {\n if (draft) changes.push(finalize(draft))\n draft = newDraft()\n const [rawOld, rawNew] = splitDiffGitPaths(line.slice('diff --git '.length))\n draft.gitOldPath = rawOld === null ? null : parseHeaderPath(rawOld)\n draft.gitNewPath = rawNew === null ? null : parseHeaderPath(rawNew)\n continue\n }\n\n if (!draft) {\n // Bare unified diff without a `diff --git` preamble: start on the first\n // recognized file line and ignore anything before it.\n if (!isFileLine(line)) continue\n draft = newDraft()\n }\n\n if (line.startsWith('new file mode ')) {\n draft.newFile = true\n } else if (line.startsWith('deleted file mode ')) {\n draft.deletedFile = true\n } else if (line.startsWith('rename from ')) {\n draft.renameFrom = parseRawPath(line.slice('rename from '.length))\n } else if (line.startsWith('rename to ')) {\n draft.renameTo = parseRawPath(line.slice('rename to '.length))\n } else if (!draft.sawHunk && line.startsWith('--- ')) {\n draft.oldPath = parseHeaderPath(line.slice(4))\n draft.sawOldHeader = true\n } else if (!draft.sawHunk && line.startsWith('+++ ')) {\n draft.newPath = parseHeaderPath(line.slice(4))\n draft.sawNewHeader = true\n } else if (line.startsWith('@@ ')) {\n const hunk = parseHunk(line)\n if (hunk) {\n draft.hunks.push(hunk)\n draft.sawHunk = true\n }\n }\n }\n\n if (draft) changes.push(finalize(draft))\n return changes\n}\n\nfunction isFileLine(line: string): boolean {\n return (\n line.startsWith('--- ') ||\n line.startsWith('+++ ') ||\n line.startsWith('@@ ') ||\n line.startsWith('new file mode ') ||\n line.startsWith('deleted file mode ') ||\n line.startsWith('rename from ') ||\n line.startsWith('rename to ')\n )\n}\n\nfunction finalize(draft: Draft): FileChange {\n let oldPath = draft.renameFrom ?? (draft.sawOldHeader ? draft.oldPath : draft.gitOldPath)\n let newPath = draft.renameTo ?? (draft.sawNewHeader ? draft.newPath : draft.gitNewPath)\n if (draft.newFile) oldPath = null\n if (draft.deletedFile) newPath = null\n let status: FileChange['status'] = 'modified'\n if (draft.newFile || (oldPath === null && newPath !== null && draft.renameFrom === null)) {\n status = 'added'\n } else if (\n draft.deletedFile ||\n (newPath === null && oldPath !== null && draft.renameTo === null)\n ) {\n status = 'deleted'\n } else if (draft.renameFrom !== null || draft.renameTo !== null) {\n status = 'renamed'\n }\n return { oldPath, newPath, status, hunks: draft.hunks }\n}\n\n/**\n * Extract the two repo paths from a `diff --git` body, honoring git's C-style\n * quoting; the tokens keep their `a/`/`b/` prefix for {@link parseHeaderPath}.\n */\nfunction splitDiffGitPaths(rest: string): [string | null, string | null] {\n const tokens: string[] = []\n let index = 0\n while (index < rest.length && tokens.length < 2) {\n while (index < rest.length && rest[index] === ' ') index++\n if (index >= rest.length) break\n const start = index\n if (rest[index] === '\"') {\n index++\n while (index < rest.length) {\n if (rest[index] === '\\\\') index += 2\n else if (rest[index] === '\"') {\n index++\n break\n } else index++\n }\n } else {\n while (index < rest.length && rest[index] !== ' ') index++\n }\n tokens.push(rest.slice(start, index))\n }\n return [tokens[0] ?? null, tokens[1] ?? null]\n}\n\nfunction parseHunk(line: string): DiffHunk | null {\n const match = HUNK_RE.exec(line)\n if (!match) return null\n const oldCount = match[2] as string | undefined\n const newCount = match[4] as string | undefined\n return {\n oldStart: Number(match[1]),\n oldLines: oldCount === undefined ? 1 : Number(oldCount),\n newStart: Number(match[3]),\n newLines: newCount === undefined ? 1 : Number(newCount),\n }\n}\n\n/** `--- a/x` / `+++ b/x` / `--- /dev/null`, tolerating a trailing timestamp. */\nfunction parseHeaderPath(raw: string): string | null {\n let value = raw\n const tab = value.indexOf('\\t')\n if (tab >= 0) value = value.slice(0, tab)\n value = value.trim()\n if (value === '/dev/null') return null\n if (value.startsWith('\"')) value = unquoteGitPath(value)\n value = value.replace(HEADER_PATH_PREFIX_RE, '')\n return value.length > 0 ? value : null\n}\n\n/** `rename from/to` paths are repo-relative with no `a/`/`b/` prefix. */\nfunction parseRawPath(raw: string): string | null {\n let value = raw.trim()\n if (value.startsWith('\"')) value = unquoteGitPath(value)\n return value.length > 0 ? value : null\n}\n\n/** Decode git's C-style quoted path (octal escapes reassembled as UTF-8 bytes). */\nfunction unquoteGitPath(value: string): string {\n const inner = value.slice(1, -1)\n const bytes: number[] = []\n for (let i = 0; i < inner.length; i++) {\n const ch = inner[i]!\n if (ch !== '\\\\') {\n bytes.push(...Buffer.from(ch, 'utf8'))\n continue\n }\n i++\n const esc: string | undefined = inner[i]\n if (esc === undefined) break\n if (esc >= '0' && esc <= '7') {\n let octal = esc\n let next: string | undefined = inner[i + 1]\n while (octal.length < 3 && next !== undefined && next >= '0' && next <= '7') {\n octal += next\n i++\n next = inner[i + 1]\n }\n bytes.push(parseInt(octal, 8))\n continue\n }\n switch (esc) {\n case 'n':\n bytes.push(0x0a)\n break\n case 't':\n bytes.push(0x09)\n break\n case 'r':\n bytes.push(0x0d)\n break\n case 'f':\n bytes.push(0x0c)\n break\n case 'v':\n bytes.push(0x0b)\n break\n case 'b':\n bytes.push(0x08)\n break\n case 'a':\n bytes.push(0x07)\n break\n case '\"':\n bytes.push(0x22)\n break\n case '\\\\':\n bytes.push(0x5c)\n break\n default:\n bytes.push(...Buffer.from(esc, 'utf8'))\n }\n }\n return Buffer.from(bytes).toString('utf8')\n}\n\n/** Reject a ref that git would parse as an option rather than a revision. */\nfunction requireSafeRef(ref: string, label: string): void {\n if (ref.length === 0) throw new Error(`${label} must not be empty`)\n if (ref.startsWith('-')) throw new Error(`${label} must not start with '-': ${ref}`)\n}\n\nfunction runGit(args: readonly string[], cwd: string): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile('git', args, { cwd, encoding: 'utf8', maxBuffer: MAX_BUFFER }, (error, stdout) => {\n if (error) reject(error)\n else resolve(stdout)\n })\n })\n}\n\n/**\n * Working-tree diff against `baseRef`, rename-aware and hunk-minimal.\n * Excludes untracked files (git semantics) — callers should say so.\n */\nexport async function readWorkingTreeDiff(root: string, baseRef: string): Promise<string> {\n requireSafeRef(baseRef, 'baseRef')\n const tracked = await runGit(\n ['diff', '--no-ext-diff', '--find-renames', '--unified=0', baseRef, '--', '.'],\n root,\n )\n const untracked = await runGit(['ls-files', '--others', '--exclude-standard', '-z', '--'], root)\n const changes = parseUnifiedDiff(tracked)\n const untrackedFiles: Array<{ path: string; content: string; lines: number }> = []\n for (const rawPath of untracked.split('\\0')) {\n if (rawPath.length === 0) continue\n const normalized = rawPath.replace(/\\\\/g, '/')\n // The index cache is intentionally local state, even when the host repo\n // has no .gitignore yet. It must not appear as a source change.\n if (normalized === '.dsh-code-index' || normalized.startsWith('.dsh-code-index/')) continue\n try {\n const content = await readFile(path.resolve(root, normalized), 'utf8')\n const lines = content.length === 0 ? 0 : content.split(/\\r?\\n/).length - (content.endsWith('\\n') ? 1 : 0)\n untrackedFiles.push({ path: normalized, content, lines })\n } catch {\n // A file can disappear between ls-files and readFile. Git would also\n // omit that race, so leave it out rather than failing the whole diff.\n }\n }\n\n // Git cannot detect an unstaged rename because its destination is still\n // untracked. Pair exact-content deleted/base files with untracked files so\n // the change-context layer receives the same rename signal as a staged diff.\n const paired = new Set<string>()\n for (const change of changes) {\n if (change.status !== 'deleted' || change.oldPath === null) continue\n let oldContent: string\n try {\n oldContent = await runGit(['show', `${baseRef}:${change.oldPath}`], root)\n } catch {\n continue\n }\n const match = untrackedFiles.find((file) => !paired.has(file.path) && file.content === oldContent)\n if (!match) continue\n change.newPath = match.path\n change.status = 'renamed'\n change.hunks = []\n paired.add(match.path)\n }\n\n for (const file of untrackedFiles) {\n if (paired.has(file.path)) continue\n changes.push({\n oldPath: null,\n newPath: file.path,\n status: 'added',\n hunks: file.lines > 0 ? [{ oldStart: 0, oldLines: 0, newStart: 1, newLines: file.lines }] : [],\n })\n }\n return renderNormalizedDiff(changes)\n}\n\n/** Re-render only the structural part consumed by parseUnifiedDiff. */\nfunction renderNormalizedDiff(changes: readonly FileChange[]): string {\n return changes\n .map((change) => {\n const oldPath = change.oldPath ?? change.newPath!\n const newPath = change.newPath ?? change.oldPath!\n const lines = [`diff --git ${diffToken(`a/${oldPath}`)} ${diffToken(`b/${newPath}`)}`]\n if (change.status === 'added') lines.push('new file mode 100644')\n if (change.status === 'deleted') lines.push('deleted file mode 100644')\n if (change.status === 'renamed') {\n lines.push('similarity index 100%', `rename from ${diffToken(change.oldPath!)}`, `rename to ${diffToken(change.newPath!)}`)\n } else {\n lines.push(`--- ${change.oldPath === null ? '/dev/null' : diffToken(`a/${change.oldPath}`)}`)\n lines.push(`+++ ${change.newPath === null ? '/dev/null' : diffToken(`b/${change.newPath}`)}`)\n }\n for (const hunk of change.hunks) {\n const oldCount = hunk.oldLines === 1 ? '' : `,${hunk.oldLines}`\n const newCount = hunk.newLines === 1 ? '' : `,${hunk.newLines}`\n lines.push(`@@ -${hunk.oldStart}${oldCount} +${hunk.newStart}${newCount} @@`)\n }\n return `${lines.join('\\n')}\\n`\n })\n .join('')\n}\n\nfunction diffToken(value: string): string {\n return /[\\s\"]/.test(value) ? `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"` : value\n}\n\n/** Read one repo-relative file at a ref; null when the path/ref is absent. */\nexport async function readGitFileAtRef(\n root: string,\n ref: string,\n repoRelativePath: string,\n): Promise<string | null> {\n requireSafeRef(ref, 'ref')\n try {\n return await runGit(['show', `${ref}:${repoRelativePath}`], root)\n } catch {\n return null\n }\n}\n","/**\n * Change-aware context (design §3): map a git/working-tree diff (or an explicit\n * file/symbol selection) onto indexed symbols, then walk the provenance-labeled\n * reference graph to surface callers, import dependents, transitive impact,\n * entry-point paths, and likely affected tests.\n *\n * Every relation keeps the reference graph's honest label (`exact` /\n * `import-scoped` / `name-only`); a diff hunk intersecting a symbol's declared\n * line range is the only thing treated as `exact`.\n */\n\nimport path from 'node:path'\nimport { buildReferenceGraph, type ResolutionLabel, type ResolutionProvenance } from './refgraph.js'\nimport { buildModuleGraph } from './health.js'\nimport { resolveImport } from './repomap.js'\nimport { extractAll, languageForFile } from './extract.js'\nimport {\n parseUnifiedDiff,\n readGitFileAtRef,\n readWorkingTreeDiff,\n type FileChange,\n} from './git-diff.js'\nimport type { IndexedFile, RepoIndex, SymbolId, SymbolInfo, SymbolKind } from './types.js'\n\n/* -------------------------------------------------------------------------- */\n/* Types (design §3) */\n/* -------------------------------------------------------------------------- */\n\nexport type ChangeKind = 'added' | 'modified' | 'deleted' | 'renamed'\n\nexport interface ChangedSymbol {\n symbol: SymbolInfo\n change: ChangeKind\n side: 'current' | 'base'\n /** A hunk range intersecting the declaration is structural, not inferred. */\n resolution: 'exact'\n}\n\nexport interface UnmappedChange {\n file: string\n side: 'current' | 'base'\n ranges: Array<{ startLine: number; endLine: number }>\n reason: 'outside-symbol' | 'base-content-unavailable'\n}\n\nexport interface ImpactHop {\n fromId: SymbolId | null\n toId: SymbolId\n callSite: { file: string; line: number }\n resolution: ResolutionLabel\n reason: ResolutionProvenance\n}\n\nexport interface ImpactRow {\n symbol: SymbolInfo\n depth: number\n via: ImpactHop\n resolution: ResolutionLabel\n}\n\nexport interface SymbolPath {\n entry: SymbolInfo\n changed: SymbolInfo\n hops: ImpactHop[]\n resolution: ResolutionLabel\n}\n\nexport interface ImportDependent {\n file: string\n changedFile: string\n specifier: string\n resolution: 'import-scoped'\n}\n\nexport interface AffectedTest {\n file: string\n resolution: ResolutionLabel\n reason:\n | 'changed-test'\n | 'imports-changed-file'\n | 'imports-impact-file'\n | 'references-symbol-name'\n | 'path-convention'\n distance?: number\n}\n\nexport interface ChangeContextResult {\n root: string\n source: 'git' | 'diff' | 'files' | 'symbols'\n baseRef?: string\n changed: ChangedSymbol[]\n unmapped: UnmappedChange[]\n directCallers: ImpactRow[]\n importDependents: ImportDependent[]\n paths: SymbolPath[]\n impact: ImpactRow[]\n tests: AffectedTest[]\n warnings: string[]\n truncated: {\n callers: boolean\n dependents: boolean\n paths: boolean\n impact: boolean\n tests: boolean\n }\n}\n\nexport interface CodeChangeContextArgs {\n repoRoot?: string\n diff?: string\n baseRef?: string\n files?: string[]\n symbols?: SymbolId[]\n maxDepth?: number\n maxImpact?: number\n maxPaths?: number\n maxTests?: number\n}\n\nexport interface ChangeContextOptions {\n maxDepth?: number\n maxImpact?: number\n maxPaths?: number\n maxTests?: number\n}\n\n/** Normalized input: exactly one selection mode. */\nexport type ChangeContextInput =\n | { kind: 'git'; root: string; baseRef: string }\n | { kind: 'diff'; root: string; text: string; baseRef?: string }\n | { kind: 'files'; files: string[] }\n | { kind: 'symbols'; symbolIds: SymbolId[] }\n\nconst LABEL_STRENGTH: Record<ResolutionLabel, number> = {\n exact: 3,\n 'import-scoped': 2,\n 'name-only': 1,\n}\n\nconst ENTRY_KINDS = new Set<SymbolKind>(['function', 'method', 'class'])\nconst ENTRY_FILE_RE = /(^|\\/)(main|index|cli|server|app)\\.[^./]+$/\nconst TEST_RE =\n /(^|\\/)(tests?|__tests__)(\\/|$)|\\.(?:spec|test)\\.[cm]?[jt]sx?$|(^|\\/)(?:test_[^/]+\\.py|[^/]+_test\\.(?:py|go))$/\n\n/** Validate flat tool args and normalize them into one input mode. */\nexport function changeContextInputFromArgs(\n args: Pick<CodeChangeContextArgs, 'diff' | 'baseRef' | 'files' | 'symbols'>,\n root: string,\n): ChangeContextInput {\n const hasDiff = typeof args.diff === 'string' && args.diff.trim().length > 0\n const hasFiles = Array.isArray(args.files) && args.files.length > 0\n const hasSymbols = Array.isArray(args.symbols) && args.symbols.length > 0\n if ([hasDiff, hasFiles, hasSymbols].filter(Boolean).length > 1) {\n throw new Error('pass only one of diff, files, symbols')\n }\n const suppliedBaseRef =\n typeof args.baseRef === 'string' && args.baseRef.length > 0 ? args.baseRef : undefined\n if (hasDiff) {\n return suppliedBaseRef === undefined\n ? { kind: 'diff', root, text: args.diff! }\n : { kind: 'diff', root, text: args.diff!, baseRef: suppliedBaseRef }\n }\n if (hasFiles) return { kind: 'files', files: args.files!.map(requireSafePath) }\n if (hasSymbols) return { kind: 'symbols', symbolIds: [...args.symbols!] }\n return { kind: 'git', root, baseRef: suppliedBaseRef ?? 'HEAD' }\n}\n\nfunction requireSafePath(raw: string): string {\n const value = raw.replace(/\\\\/g, '/').trim()\n if (value.length === 0) throw new Error('file path must not be empty')\n if (value.startsWith('/') || /^[A-Za-z]:\\//.test(value)) {\n throw new Error(`absolute file path not allowed: ${raw}`)\n }\n if (/(^|\\/)\\.\\.(\\/|$)/.test(value)) throw new Error(`path must stay inside the repo: ${raw}`)\n return value.replace(/^\\.\\//, '')\n}\n\nfunction clamp(value: number | undefined, lo: number, hi: number, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback\n return Math.min(hi, Math.max(lo, Math.floor(value)))\n}\n\nfunction weakest(labels: readonly ResolutionLabel[]): ResolutionLabel {\n let out: ResolutionLabel = 'exact'\n for (const label of labels) {\n if (LABEL_STRENGTH[label] < LABEL_STRENGTH[out]) out = label\n }\n return out\n}\n\nfunction symbolLabel(symbol: SymbolInfo): string {\n return `${symbol.kind} ${symbol.signature || symbol.name}`\n}\n\n/* -------------------------------------------------------------------------- */\n/* Pipeline */\n/* -------------------------------------------------------------------------- */\n\nexport async function buildChangeContext(\n index: RepoIndex,\n input: ChangeContextInput,\n options: ChangeContextOptions = {},\n): Promise<ChangeContextResult> {\n const maxDepth = clamp(options.maxDepth, 1, 6, 3)\n const maxImpact = clamp(options.maxImpact, 1, 200, 40)\n const maxPaths = clamp(options.maxPaths, 1, 50, 10)\n const maxTests = clamp(options.maxTests, 1, 100, 20)\n\n const graph = buildReferenceGraph(index)\n const moduleGraph = buildModuleGraph(index)\n const filesByPath = new Map(index.files.map((file) => [file.path, file]))\n const fileSet = new Set(filesByPath.keys())\n const incomingCount = new Map<SymbolId, number>()\n for (const [id, edges] of graph.incoming) incomingCount.set(id, edges.length)\n\n const warnings: string[] = []\n const changedByKey = new Map<string, ChangedSymbol>()\n const unmapped: UnmappedChange[] = []\n const changedFiles = new Set<string>()\n\n const commandRoot = input.kind === 'git' || input.kind === 'diff' ? input.root : index.root\n if (path.resolve(commandRoot) !== path.resolve(index.root)) {\n warnings.push(\n `command root ${path.resolve(commandRoot)} differs from indexed root ${index.root}; using the cached index`,\n )\n }\n\n const addChanged = (\n symbol: SymbolInfo,\n change: ChangeKind,\n side: ChangedSymbol['side'],\n ): void => {\n const key = `${side}:${symbol.id}`\n if (!changedByKey.has(key)) changedByKey.set(key, { symbol, change, side, resolution: 'exact' })\n }\n\n const addUnmapped = (\n file: string,\n side: UnmappedChange['side'],\n ranges: Array<{ startLine: number; endLine: number }>,\n reason: UnmappedChange['reason'],\n ): void => {\n if (ranges.length > 0) unmapped.push({ file, side, ranges, reason })\n }\n\n let baseRef: string | undefined\n\n if (input.kind === 'files') {\n for (const filePath of input.files) {\n const file = filesByPath.get(filePath)\n if (!file) {\n warnings.push(`file not in index: ${filePath}`)\n continue\n }\n changedFiles.add(file.path)\n for (const symbol of file.symbols) addChanged(symbol, 'modified', 'current')\n if (file.symbols.length === 0) warnings.push(`no indexed symbols in changed file: ${filePath}`)\n }\n } else if (input.kind === 'symbols') {\n for (const id of input.symbolIds) {\n const symbol = graph.symbolsById.get(id)\n if (!symbol) {\n warnings.push(`symbol not in index: ${id}`)\n continue\n }\n changedFiles.add(symbol.file)\n addChanged(symbol, 'modified', 'current')\n }\n } else {\n let text: string\n if (input.kind === 'git') {\n baseRef = input.baseRef\n text = await readWorkingTreeDiff(input.root, input.baseRef)\n } else {\n text = input.text\n baseRef = input.baseRef\n }\n\n const changes = parseUnifiedDiff(text).map((change) => ({\n ...change,\n oldPath: change.oldPath === null ? null : requireSafePath(change.oldPath),\n newPath: change.newPath === null ? null : requireSafePath(change.newPath),\n }))\n if (changes.length === 0) warnings.push('no changes found in the diff')\n\n const baseSymbolsCache = new Map<string, Promise<SymbolInfo[] | null>>()\n const readBaseSymbols = (filePath: string): Promise<SymbolInfo[] | null> => {\n const cached = baseSymbolsCache.get(filePath)\n if (cached) return cached\n const pending = (async (): Promise<SymbolInfo[] | null> => {\n if (baseRef === undefined) return null\n const content = await readGitFileAtRef(commandRoot, baseRef, filePath)\n if (content === null) return null\n const lang = languageForFile(filePath)\n if (!lang) return null\n const extracted = await extractAll(content, lang, filePath)\n return extracted.symbols\n })()\n baseSymbolsCache.set(filePath, pending)\n return pending\n }\n\n const symbolsByPath = new Map(index.files.map((file) => [file.path, file.symbols]))\n await mapDiffChanges(\n changes,\n symbolsByPath,\n addChanged,\n addUnmapped,\n changedFiles,\n readBaseSymbols,\n warnings,\n )\n }\n\n const changedSymbols = [...changedByKey.values()].sort(compareChanged)\n\n // Direct callers: incoming edges of each changed symbol.\n const callerById = new Map<SymbolId, ImpactRow>()\n for (const changed of changedSymbols) {\n for (const edge of graph.incoming.get(changed.symbol.id) ?? []) {\n if (edge.sourceId === null) continue\n const caller = graph.symbolsById.get(edge.sourceId)\n if (!caller) continue\n const row: ImpactRow = {\n symbol: caller,\n depth: 1,\n via: hopOf(edge),\n resolution: edge.resolution,\n }\n const existing = callerById.get(caller.id)\n if (!existing || LABEL_STRENGTH[row.resolution] > LABEL_STRENGTH[existing.resolution]) {\n callerById.set(caller.id, row)\n }\n }\n }\n const allCallers = [...callerById.values()].sort(compareBySymbol)\n\n // Transitive impact (depth >= 2), bounded by maxDepth.\n const changedIds = new Set(changedSymbols.map((changed) => changed.symbol.id))\n const impactById = new Map<SymbolId, ImpactRow>()\n {\n const depthById = new Map<SymbolId, number>()\n const strengthById = new Map<SymbolId, ResolutionLabel>()\n for (const id of changedIds) {\n depthById.set(id, 0)\n strengthById.set(id, 'exact')\n }\n let frontier = [...changedIds]\n for (let depth = 0; depth < maxDepth; depth++) {\n const next: SymbolId[] = []\n for (const id of frontier) {\n const pathStrength = strengthById.get(id) ?? 'exact'\n for (const edge of graph.incoming.get(id) ?? []) {\n if (edge.sourceId === null || changedIds.has(edge.sourceId)) continue\n const caller = graph.symbolsById.get(edge.sourceId)\n if (!caller) continue\n const cumulative = weakest([pathStrength, edge.resolution])\n const row: ImpactRow = {\n symbol: caller,\n depth: depth + 1,\n via: hopOf(edge),\n resolution: cumulative,\n }\n const seen = depthById.get(edge.sourceId)\n if (seen === undefined) {\n depthById.set(edge.sourceId, depth + 1)\n strengthById.set(edge.sourceId, cumulative)\n next.push(edge.sourceId)\n if (depth + 1 >= 2) impactById.set(edge.sourceId, row)\n } else if (seen === depth + 1) {\n const previous = strengthById.get(edge.sourceId) ?? 'exact'\n if (LABEL_STRENGTH[cumulative] > LABEL_STRENGTH[previous]) {\n strengthById.set(edge.sourceId, cumulative)\n if (depth + 1 >= 2) impactById.set(edge.sourceId, row)\n }\n }\n }\n }\n frontier = next\n }\n }\n const allImpact = [...impactById.values()].sort(compareByDepthThenSymbol)\n\n // Shortest reverse-call paths from entry points to each changed symbol.\n const allPaths: SymbolPath[] = []\n const pathKey = new Set<string>()\n for (const changed of changedSymbols) {\n for (const found of pathsToEntryPoints(changed.symbol, graph, incomingCount, maxDepth)) {\n const key = `${found.entry.id}\\u0000${found.changed.id}`\n if (pathKey.has(key)) continue\n pathKey.add(key)\n allPaths.push(found)\n }\n }\n allPaths.sort(comparePaths)\n\n // Import dependents: reverse module-graph edges of each changed file.\n const importDependents = collectImportDependents(index, moduleGraph, fileSet, changedFiles)\n\n // Likely affected tests.\n const allTests = collectAffectedTests(\n index,\n moduleGraph,\n changedFiles,\n changedSymbols,\n [...allCallers, ...allImpact],\n )\n\n const truncated = {\n callers: allCallers.length > maxImpact,\n dependents: importDependents.length > maxImpact,\n paths: allPaths.length > maxPaths,\n impact: allImpact.length > maxImpact,\n tests: allTests.length > maxTests,\n }\n\n return {\n root: index.root,\n source: input.kind,\n ...(baseRef !== undefined ? { baseRef } : {}),\n changed: changedSymbols,\n unmapped: unmapped.sort(compareUnmapped),\n directCallers: allCallers.slice(0, maxImpact),\n importDependents: importDependents.slice(0, maxImpact),\n paths: allPaths.slice(0, maxPaths),\n impact: allImpact.slice(0, maxImpact),\n tests: allTests.slice(0, maxTests),\n warnings,\n truncated,\n }\n}\n\nfunction hopOf(edge: {\n sourceId: SymbolId | null\n targetId: SymbolId\n callSite: { file: string; line: number }\n resolution: ResolutionLabel\n provenance: ResolutionProvenance\n}): ImpactHop {\n return {\n fromId: edge.sourceId,\n toId: edge.targetId,\n callSite: edge.callSite,\n resolution: edge.resolution,\n reason: edge.provenance,\n }\n}\n\nasync function mapDiffChanges(\n changes: readonly FileChange[],\n symbolsByPath: Map<string, SymbolInfo[]>,\n addChanged: (symbol: SymbolInfo, change: ChangeKind, side: ChangedSymbol['side']) => void,\n addUnmapped: (\n file: string,\n side: UnmappedChange['side'],\n ranges: Array<{ startLine: number; endLine: number }>,\n reason: UnmappedChange['reason'],\n ) => void,\n changedFiles: Set<string>,\n readBaseSymbols: (filePath: string) => Promise<SymbolInfo[] | null>,\n warnings: string[],\n): Promise<void> {\n for (const change of changes) {\n const { oldPath, newPath, hunks } = change\n if (newPath) changedFiles.add(newPath)\n if (oldPath) changedFiles.add(oldPath)\n\n // Current side: hunk ranges that touch the new file.\n const currentSymbols =\n newPath !== null && change.status !== 'deleted' ? symbolsByPath.get(newPath) : undefined\n if (newPath !== null && change.status !== 'deleted') {\n const currentRanges = hunks\n .filter((hunk) => hunk.newLines > 0)\n .map((hunk) => ({\n startLine: hunk.newStart,\n endLine: hunk.newStart + Math.max(hunk.newLines, 1) - 1,\n }))\n if (currentRanges.length > 0 && currentSymbols) {\n for (const range of currentRanges) {\n for (const symbol of currentSymbols) {\n if (intersects(symbol, range)) addChanged(symbol, change.status, 'current')\n }\n }\n const missed = currentRanges.filter(\n (range) => !currentSymbols.some((symbol) => intersects(symbol, range)),\n )\n addUnmapped(newPath, 'current', missed, 'outside-symbol')\n } else if (currentRanges.length > 0) {\n // Changed file is absent from the cached index.\n addUnmapped(newPath, 'current', currentRanges, 'outside-symbol')\n }\n\n // A pure rename has no hunks, but it is still a structural change. Map\n // both sides so callers can see the old identity and the current file's\n // identity instead of receiving an empty context with only a warning.\n if (change.status === 'renamed' && hunks.length === 0) {\n for (const symbol of currentSymbols ?? []) addChanged(symbol, 'renamed', 'current')\n if (oldPath !== null) {\n const oldSymbols = await readBaseSymbols(oldPath)\n if (oldSymbols === null) {\n warnings.push(`rename baseline unavailable: ${oldPath}`)\n } else {\n for (const symbol of oldSymbols) addChanged(symbol, 'renamed', 'base')\n }\n }\n }\n }\n\n // Base side: deletion-only hunks (newLines === 0) are mapped against the\n // transiently extracted old file; the baseline is never persisted.\n const deletionHunks = hunks.filter((hunk) => hunk.newLines === 0)\n if (deletionHunks.length > 0 && oldPath !== null) {\n const oldRanges = deletionHunks.map((hunk) => ({\n startLine: hunk.oldStart,\n endLine: hunk.oldStart + Math.max(hunk.oldLines, 1) - 1,\n }))\n const oldSymbols = await readBaseSymbols(oldPath)\n if (oldSymbols === null) {\n addUnmapped(oldPath, 'base', oldRanges, 'base-content-unavailable')\n } else {\n const baseChange: ChangeKind = change.status === 'deleted' ? 'deleted' : 'modified'\n for (const range of oldRanges) {\n for (const symbol of oldSymbols) {\n if (intersects(symbol, range)) addChanged(symbol, baseChange, 'base')\n }\n }\n const missed = oldRanges.filter(\n (range) => !oldSymbols.some((symbol) => intersects(symbol, range)),\n )\n addUnmapped(oldPath, 'base', missed, 'outside-symbol')\n }\n }\n\n if (change.status === 'renamed' && hunks.length === 0) {\n warnings.push(`renamed with no content change: ${oldPath} -> ${newPath}`)\n }\n }\n}\n\nfunction intersects(symbol: SymbolInfo, range: { startLine: number; endLine: number }): boolean {\n return symbol.line <= range.endLine && symbol.endLine >= range.startLine\n}\n\n/**\n * BFS over incoming (caller) edges from `changed`; the first time an entry\n * point is reached is a shortest path. Bounded by `maxDepth` so path search\n * and transitive impact cover the same horizon.\n */\nfunction pathsToEntryPoints(\n changed: SymbolInfo,\n graph: ReturnType<typeof buildReferenceGraph>,\n incomingCount: Map<SymbolId, number>,\n maxDepth: number,\n): SymbolPath[] {\n const isEntry = (symbol: SymbolInfo): boolean => {\n if (ENTRY_FILE_RE.test(symbol.file)) return true\n if (!symbol.exported) return false\n if (symbol.kind === 'variable') {\n return symbol.scope.length === 0 || (incomingCount.get(symbol.id) ?? 0) === 0\n }\n if (ENTRY_KINDS.has(symbol.kind)) return true\n return (incomingCount.get(symbol.id) ?? 0) === 0\n }\n\n const found: SymbolPath[] = []\n const depthById = new Map<SymbolId, number>([[changed.id, 0]])\n const strengthById = new Map<SymbolId, ResolutionLabel>([[changed.id, 'exact']])\n const nextEdge = new Map<SymbolId, ImpactHop>()\n const entryIds = new Set<SymbolId>()\n const queue: SymbolId[] = [changed.id]\n\n while (queue.length > 0) {\n const node = queue.shift()!\n const nodeDepth = depthById.get(node) ?? 0\n if (nodeDepth >= maxDepth) continue\n const nodeStrength = strengthById.get(node) ?? 'exact'\n for (const edge of graph.incoming.get(node) ?? []) {\n if (edge.sourceId === null) continue\n const candidateDepth = nodeDepth + 1\n const cumulative = weakest([nodeStrength, edge.resolution])\n const existingDepth = depthById.get(edge.sourceId)\n if (existingDepth === undefined) {\n depthById.set(edge.sourceId, candidateDepth)\n strengthById.set(edge.sourceId, cumulative)\n nextEdge.set(edge.sourceId, hopOf(edge))\n queue.push(edge.sourceId)\n } else if (existingDepth === candidateDepth) {\n const existingStrength = strengthById.get(edge.sourceId) ?? 'exact'\n if (LABEL_STRENGTH[cumulative] > LABEL_STRENGTH[existingStrength]) {\n strengthById.set(edge.sourceId, cumulative)\n nextEdge.set(edge.sourceId, hopOf(edge))\n queue.push(edge.sourceId)\n }\n }\n const entry = graph.symbolsById.get(edge.sourceId)\n if (entry && isEntry(entry)) entryIds.add(edge.sourceId)\n }\n }\n\n for (const entryId of entryIds) {\n const entry = graph.symbolsById.get(entryId)\n if (!entry) continue\n const hops: ImpactHop[] = []\n let cursor = entryId\n const guard = new Set<SymbolId>()\n while (cursor !== changed.id && !guard.has(cursor)) {\n guard.add(cursor)\n const hop = nextEdge.get(cursor)\n if (!hop) break\n hops.push(hop)\n cursor = hop.toId\n }\n if (cursor === changed.id && hops.length > 0) {\n found.push({\n entry,\n changed,\n hops,\n resolution: weakest(hops.map((hop) => hop.resolution)),\n })\n }\n }\n return found\n}\n\nfunction collectImportDependents(\n index: RepoIndex,\n moduleGraph: ReturnType<typeof buildModuleGraph>,\n fileSet: Set<string>,\n changedFiles: Set<string>,\n): ImportDependent[] {\n const filesByPath = new Map(index.files.map((file) => [file.path, file]))\n const reverse = new Map<string, Set<string>>()\n for (const [from, targets] of moduleGraph.edges) {\n for (const target of targets) {\n const importers = reverse.get(target) ?? new Set<string>()\n importers.add(from)\n reverse.set(target, importers)\n }\n }\n\n // Deleted/renamed-away files are absent from the module graph, so resolve\n // every file's imports against a set that still contains those paths — one\n // pass total, not one pass per changed file.\n const augmented = new Set([...fileSet, ...changedFiles])\n let reverseImports: Map<string, Set<string>> | null = null\n const reverseImportIndex = (): Map<string, Set<string>> => {\n if (reverseImports) return reverseImports\n const map = new Map<string, Set<string>>()\n for (const file of index.files) {\n for (const info of file.importDetails ?? []) {\n const target = resolveImport(info.specifier, file.path, augmented)\n if (target === null) continue\n const importers = map.get(target) ?? new Set<string>()\n importers.add(file.path)\n map.set(target, importers)\n }\n }\n reverseImports = map\n return map\n }\n\n const dependents: ImportDependent[] = []\n const seen = new Set<string>()\n for (const changedFile of [...changedFiles].sort((a, b) => a.localeCompare(b))) {\n const importers = new Set(reverse.get(changedFile) ?? [])\n let resolutionSet = fileSet\n if (!fileSet.has(changedFile)) {\n resolutionSet = augmented\n for (const importerPath of reverseImportIndex().get(changedFile) ?? []) {\n importers.add(importerPath)\n }\n }\n for (const importerPath of [...importers].sort((a, b) => a.localeCompare(b))) {\n const importer = filesByPath.get(importerPath)\n if (!importer) continue\n const specifier = specifierFor(importer, changedFile, resolutionSet)\n if (specifier === null) continue\n const key = `${importerPath}\\u0000${changedFile}\\u0000${specifier}`\n if (seen.has(key)) continue\n seen.add(key)\n dependents.push({\n file: importerPath,\n changedFile,\n specifier,\n resolution: 'import-scoped',\n })\n }\n }\n return dependents.sort(\n (a, b) =>\n a.file.localeCompare(b.file) ||\n a.changedFile.localeCompare(b.changedFile) ||\n a.specifier.localeCompare(b.specifier),\n )\n}\n\nfunction specifierFor(file: IndexedFile, target: string, fileSet: Set<string>): string | null {\n for (const info of file.importDetails ?? []) {\n if (resolveImport(info.specifier, file.path, fileSet) === target) return info.specifier\n }\n for (const spec of file.imports ?? []) {\n if (resolveImport(spec, file.path, fileSet) === target) return spec\n }\n return null\n}\n\nconst TEST_RANK: Record<AffectedTest['reason'], number> = {\n 'changed-test': 0,\n 'imports-changed-file': 1,\n 'imports-impact-file': 2,\n 'references-symbol-name': 3,\n 'path-convention': 4,\n}\n\nfunction collectAffectedTests(\n index: RepoIndex,\n moduleGraph: ReturnType<typeof buildModuleGraph>,\n changedFiles: Set<string>,\n changedSymbols: readonly ChangedSymbol[],\n impactRows: readonly ImpactRow[],\n): AffectedTest[] {\n const changedNames = new Set(changedSymbols.map((changed) => changed.symbol.name))\n const impactFileDepth = new Map<string, number>()\n for (const row of impactRows) {\n const previous = impactFileDepth.get(row.symbol.file)\n if (previous === undefined || row.depth < previous) {\n impactFileDepth.set(row.symbol.file, row.depth)\n }\n }\n const changedStems = new Set([...changedFiles].map(pathStem))\n\n const tests: AffectedTest[] = []\n for (const file of index.files) {\n if (!TEST_RE.test(file.path)) continue\n const imports = moduleGraph.edges.get(file.path) ?? new Set<string>()\n\n if (changedFiles.has(file.path)) {\n tests.push({ file: file.path, resolution: 'exact', reason: 'changed-test', distance: 0 })\n continue\n }\n\n const changedImport = [...imports].find(\n (target) => changedFiles.has(target) && target !== file.path,\n )\n if (changedImport !== undefined) {\n tests.push({\n file: file.path,\n resolution: 'import-scoped',\n reason: 'imports-changed-file',\n distance: 1,\n })\n continue\n }\n\n const impactImports = [...imports]\n .filter((target) => impactFileDepth.has(target))\n .sort((a, b) => (impactFileDepth.get(a) ?? 0) - (impactFileDepth.get(b) ?? 0))\n if (impactImports.length > 0) {\n tests.push({\n file: file.path,\n resolution: 'import-scoped',\n reason: 'imports-impact-file',\n distance: impactFileDepth.get(impactImports[0]!) ?? 2,\n })\n continue\n }\n\n if ((file.calls ?? []).some((call) => changedNames.has(call.name))) {\n tests.push({\n file: file.path,\n resolution: 'name-only',\n reason: 'references-symbol-name',\n distance: 1,\n })\n continue\n }\n\n if (changedStems.has(pathStem(file.path))) {\n tests.push({ file: file.path, resolution: 'name-only', reason: 'path-convention' })\n }\n }\n\n return tests.sort(\n (a, b) =>\n TEST_RANK[a.reason] - TEST_RANK[b.reason] ||\n (a.distance ?? Number.MAX_SAFE_INTEGER) - (b.distance ?? Number.MAX_SAFE_INTEGER) ||\n a.file.localeCompare(b.file),\n )\n}\n\n/** Basename stem with test markers removed (`a/foo.test.ts` -> `foo`). */\nfunction pathStem(filePath: string): string {\n const base = filePath.split('/').pop() ?? filePath\n return base\n .replace(/\\.[A-Za-z0-9]+$/, '')\n .replace(/\\.(?:test|spec)$/, '')\n .replace(/^test_/, '')\n .replace(/_test$/, '')\n}\n\nfunction compareChanged(a: ChangedSymbol, b: ChangedSymbol): number {\n return (\n a.side.localeCompare(b.side) ||\n a.symbol.file.localeCompare(b.symbol.file) ||\n a.symbol.line - b.symbol.line ||\n a.symbol.id.localeCompare(b.symbol.id)\n )\n}\n\nfunction compareBySymbol(a: ImpactRow, b: ImpactRow): number {\n return (\n a.symbol.file.localeCompare(b.symbol.file) ||\n a.symbol.line - b.symbol.line ||\n a.symbol.id.localeCompare(b.symbol.id)\n )\n}\n\nfunction compareByDepthThenSymbol(a: ImpactRow, b: ImpactRow): number {\n return (\n a.depth - b.depth ||\n LABEL_STRENGTH[b.resolution] - LABEL_STRENGTH[a.resolution] ||\n compareBySymbol(a, b)\n )\n}\n\nfunction comparePaths(a: SymbolPath, b: SymbolPath): number {\n return (\n a.entry.file.localeCompare(b.entry.file) ||\n a.entry.line - b.entry.line ||\n a.changed.file.localeCompare(b.changed.file) ||\n a.changed.line - b.changed.line ||\n a.entry.id.localeCompare(b.entry.id)\n )\n}\n\nfunction compareUnmapped(a: UnmappedChange, b: UnmappedChange): number {\n return a.file.localeCompare(b.file) || a.side.localeCompare(b.side)\n}\n\n/* -------------------------------------------------------------------------- */\n/* Renderer */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Render the result as fixed skeleton sections. Section headers and warnings\n * are always kept; rows are trimmed to the final character cap, which then\n * appends an explicit truncation line.\n */\nexport function renderChangeContext(result: ChangeContextResult, maxChars = 12_000): string {\n const sections: Array<{ title: string; rows: string[] }> = [\n {\n title: 'CHANGED',\n rows: result.changed.map(\n (changed) =>\n `${changed.change} ${changed.side === 'base' ? 'base ' : ''}${symbolLabel(changed.symbol)} ${changed.symbol.file}:${changed.symbol.line} [${changed.resolution}]`,\n ),\n },\n {\n title: 'DIRECT CALLERS',\n rows: result.directCallers.map(\n (row) =>\n `${symbolLabel(row.symbol)} ${row.symbol.file}:${row.symbol.line} (called at ${row.via.callSite.file}:${row.via.callSite.line}) [${row.resolution}]`,\n ),\n },\n {\n title: 'IMPORT DEPENDENTS',\n rows: result.importDependents.map(\n (dependent) =>\n `${dependent.file} imports ${dependent.changedFile} ('${dependent.specifier}') [${dependent.resolution}]`,\n ),\n },\n {\n title: 'SHORTEST PATHS TO ENTRY POINTS',\n rows: result.paths.map(\n (symbolPath) =>\n `${symbolPath.entry.file}:${symbolPath.entry.line} ${symbolLabel(symbolPath.entry)} → ${symbolPath.changed.file}:${symbolPath.changed.line} ${symbolLabel(symbolPath.changed)} (${symbolPath.hops.length} hop(s)) [${symbolPath.resolution}]`,\n ),\n },\n {\n title: 'TRANSITIVE IMPACT',\n rows: result.impact.map(\n (row) =>\n `depth ${row.depth}: ${symbolLabel(row.symbol)} ${row.symbol.file}:${row.symbol.line} (reached via ${row.via.callSite.file}:${row.via.callSite.line}) [${row.resolution}]`,\n ),\n },\n {\n title: 'LIKELY AFFECTED TESTS',\n rows: result.tests.map(\n (test) =>\n `${test.file} (${test.reason}${test.distance !== undefined ? `, distance ${test.distance}` : ''}) [${test.resolution}]`,\n ),\n },\n {\n title: 'UNMAPPED',\n rows: result.unmapped.map(\n (entry) =>\n `${entry.file} ${entry.side} lines ${entry.ranges.map((range) => `${range.startLine}-${range.endLine}`).join(', ')} (${entry.reason})`,\n ),\n },\n ]\n\n const summary = `change context — source: ${result.source}${\n result.baseRef !== undefined ? ` (base ${result.baseRef})` : ''\n }: ${result.changed.length} changed symbol(s)`\n const warningLines = result.warnings.map((warning) => `- ${warning}`)\n\n const render = (kept: readonly number[]): string => {\n const lines: string[] = [summary]\n sections.forEach((section, index) => {\n if (section.rows.length === 0) {\n lines.push(`${section.title}: (none)`)\n return\n }\n lines.push(`${section.title}:`)\n const take = kept[index] ?? 0\n for (let row = 0; row < take; row++) lines.push(` ${section.rows[row]}`)\n if (take < section.rows.length) lines.push(` … (${section.rows.length - take} more)`)\n })\n lines.push('WARNINGS:')\n if (warningLines.length === 0) lines.push(' (none)')\n else for (const warning of warningLines) lines.push(` ${warning}`)\n return lines.join('\\n')\n }\n\n const flattened: Array<{ section: number; text: string }> = []\n sections.forEach((section, index) => {\n section.rows.forEach((text) => flattened.push({ section: index, text }))\n })\n\n const countsFor = (count: number): number[] => {\n const kept = sections.map(() => 0)\n for (let index = 0; index < count; index++) kept[flattened[index]!.section]!++\n return kept\n }\n\n const total = flattened.length\n const full = render(sections.map((section) => section.rows.length))\n if (full.length <= maxChars) return full\n\n const truncationNote =\n '\\n… truncated rows to fit the character cap (raise maxChars or narrow the change)'\n const headerOnly = render(countsFor(0))\n if (headerOnly.length > maxChars) {\n throw new Error(\n `maxChars ${maxChars} is below the renderer minimum ${headerOnly.length} (section headers and warnings cannot be kept)`,\n )\n }\n if (headerOnly.length + truncationNote.length > maxChars) return headerOnly\n\n const fits = (count: number): boolean =>\n render(countsFor(count)).length + truncationNote.length <= maxChars\n\n let lo = 0\n let hi = total\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n if (fits(mid)) lo = mid\n else hi = mid - 1\n }\n\n let out = render(countsFor(lo))\n if (lo < total) out += truncationNote\n return out\n}\n","/** Model-visible tools: code_index, code_symbols, code_search. */\n\nimport { defineTool, type JsonValue } from '@deepseek-ai/dsh-tools'\nimport path from 'node:path'\nimport { buildIndexWithCache, findRepoRoot } from './buildIndex.js'\nimport { renderHit, searchSymbols } from './search.js'\nimport { rankRepoMap, renderRepoMap } from './repomap.js'\nimport { symbolRefs } from './refgraph.js'\nimport { findCycles, findOrphanModules } from './health.js'\nimport {\n buildChangeContext,\n changeContextInputFromArgs,\n renderChangeContext,\n} from './change-context.js'\nimport { getConfig, indexOptions } from './config.js'\nimport { cacheKeyForRoot } from './store.js'\nimport type { RepoIndex } from './types.js'\n\n/** Minimal structural types for the harness surfaces we touch. */\ninterface ToolCwdContext {\n agent?: {\n session?: { header?: { cwd?: string } }\n }\n}\ntype ToolRunExec = ToolCwdContext & { signal?: AbortSignal }\n\ninterface TextBlock {\n type: 'text'\n text: string\n}\n\nexport interface IndexCache {\n get(root: string, force?: boolean): Promise<RepoIndex>\n invalidate(): void\n}\n\n/** Retain completed indexes briefly while still coalescing concurrent refreshes. */\nexport function createIndexCache(\n load: (root: string) => Promise<RepoIndex>,\n ttlMs = 60_000,\n now: () => number = Date.now,\n): IndexCache {\n interface CompletedEntry {\n index: RepoIndex\n at: number\n epoch: number\n }\n interface LoadEntry {\n promise: Promise<RepoIndex>\n epoch: number\n }\n\n const completed = new Map<string, CompletedEntry>()\n const inFlight = new Map<string, LoadEntry>()\n let epoch = 0\n\n function startLoad(key: string, root: string, previous?: Promise<RepoIndex>): Promise<RepoIndex> {\n const loadEpoch = epoch\n const begin = previous\n ? previous.catch(() => undefined).then(() => load(root))\n : load(root)\n const promise = begin\n .then((index) => {\n if (loadEpoch === epoch) {\n completed.delete(key)\n completed.set(key, { index, at: now(), epoch: loadEpoch })\n while (completed.size > 16) completed.delete(completed.keys().next().value!)\n }\n return index\n })\n .finally(() => {\n if (inFlight.get(key)?.promise === promise) inFlight.delete(key)\n })\n inFlight.set(key, { promise, epoch: loadEpoch })\n return promise\n }\n\n return {\n get(root, force = false) {\n const resolvedRoot = path.resolve(root)\n const key = cacheKeyForRoot(resolvedRoot)\n const running = inFlight.get(key)\n if (running) {\n if (running.epoch === epoch && !force) return running.promise\n return startLoad(key, resolvedRoot, running.promise)\n }\n\n if (!force) {\n const cached = completed.get(key)\n if (cached && cached.epoch === epoch && now() - cached.at < ttlMs) {\n completed.delete(key)\n completed.set(key, cached)\n return Promise.resolve(cached.index)\n }\n if (cached) completed.delete(key)\n } else {\n completed.delete(key)\n }\n return startLoad(key, resolvedRoot)\n },\n invalidate() {\n epoch++\n completed.clear()\n },\n }\n}\n\nconst indexCache = createIndexCache((root) => buildIndexWithCache(root, indexOptions()))\n\nexport function getIndex(root: string, force = false): Promise<RepoIndex> {\n return indexCache.get(root, force)\n}\n\nexport function invalidateIndexCache(): void {\n indexCache.invalidate()\n}\n\nasync function resolveRoot(arg: string | undefined, exec: ToolRunExec): Promise<string> {\n const cwd = exec.agent?.session?.header?.cwd\n const base = arg ?? cwd ?? process.cwd()\n const root = await findRepoRoot(base)\n if (!root) throw new Error(`no git repository found from ${path.resolve(base)}`)\n return root\n}\n\n/** Group hit rows into the search card's matches shape for UI replay. */\nfunction hitsToSearchMeta(hits: JsonValue[]): JsonValue {\n const byFile = new Map<string, Array<{ lineNumber: number; line: string }>>()\n for (const raw of hits) {\n const hit = raw as unknown as {\n file?: string\n line?: number\n kind?: string\n name?: string\n signature?: string\n }\n if (!hit.file || typeof hit.line !== 'number') continue\n const label = `${hit.kind ?? ''} ${hit.signature || hit.name || ''}`.trim()\n const list = byFile.get(hit.file) ?? []\n list.push({ lineNumber: hit.line, line: label })\n byFile.set(hit.file, list)\n }\n return {\n shape: 'matches',\n files: [...byFile.entries()].map(([path, matches]) => ({ path, matches })),\n truncated: false,\n total: hits.length,\n }\n}\n\n/** Narrow persisted presentation metadata back into a completed search card. */\nfunction searchCardFromMeta(meta: JsonValue | undefined):\n | {\n card: 'search'\n shape: 'matches'\n files: Array<{ path: string; matches: Array<{ lineNumber: number; line: string }> }>\n truncated: boolean\n total: number\n }\n | undefined {\n if (!meta || typeof meta !== 'object' || Array.isArray(meta)) return undefined\n const record = meta as Record<string, JsonValue>\n if (record.shape !== 'matches' || !Array.isArray(record.files)) return undefined\n const files = record.files.filter(\n (entry): entry is { path: string; matches: Array<{ lineNumber: number; line: string }> } =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry),\n )\n return {\n card: 'search',\n shape: 'matches',\n files,\n truncated: record.truncated === true,\n total: typeof record.total === 'number' ? record.total : 0,\n }\n}\n\nexport const tools = [\n defineTool({\n name: 'code_index',\n description:\n 'Manage the code index: status or (re)build it for the current workspace. Auto-builds the first time it is queried. Returns file/symbol counts and the index location.',\n parameters: {\n action: {\n type: 'string',\n enum: ['status', 'build'],\n description: '\"status\" (default) reports without forcing a rebuild; \"build\" forces a fresh scan.',\n },\n repoRoot: {\n type: 'string',\n description:\n 'Optional absolute repo path. Defaults to the workspace root of the current session.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n async execute(args: { action?: string; repoRoot?: string }, exec: ToolRunExec): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root, args.action === 'build')\n const total = index.files.reduce((n, f) => n + f.symbols.length, 0)\n const langs = new Set(index.files.map((f) => f.lang))\n return [\n `repo: ${root}`,\n `files indexed: ${index.files.length}`,\n `symbols: ${total}`,\n `languages: ${[...langs].join(', ')}`,\n index.files.length === 0 ? 'no supported files found' : 'index up to date',\n ].join('\\n')\n } catch (error) {\n return `code_index: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_symbols',\n description:\n 'List symbols (functions, classes, interfaces, types, methods, variables) in the current repo. Filter by name substring, file path substring, or symbol kind. Results are exported-first, alphabetically ordered.',\n parameters: {\n query: {\n type: 'string',\n description: 'Substring of the symbol name to match (case-insensitive). Omit to list all.',\n },\n file: {\n type: 'string',\n description: 'Substring of the repo-relative file path to match, e.g. \"src/core\".',\n },\n kind: {\n type: 'string',\n enum: ['function', 'method', 'class', 'interface', 'type', 'enum', 'variable', 'field'],\n description: 'Only return symbols of this kind.',\n },\n exportedOnly: {\n type: 'boolean',\n description: 'Only exported (module-level public) symbols.',\n },\n limit: {\n type: 'number',\n description: 'Max rows (default 50).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'array' },\n render: (_args, value: JsonValue[]): TextBlock[] =>\n value.map((v) => ({\n type: 'text' as const,\n text: renderHit(v as unknown as Parameters<typeof renderHit>[0]),\n })),\n presentationMeta: (_args, value) => hitsToSearchMeta(value),\n },\n presentCall: (args) => ({\n card: 'generic',\n title: args.kind ? `List ${args.kind} symbols` : 'List symbols',\n kind: 'search',\n rawInput: { query: args.query, file: args.file, kind: args.kind },\n }),\n presentResult: (_args, result) => searchCardFromMeta(result.meta),\n async execute(\n args: {\n query?: string\n file?: string\n kind?: 'function' | 'method' | 'class' | 'interface' | 'type' | 'enum' | 'variable' | 'field'\n exportedOnly?: boolean\n limit?: number\n repoRoot?: string\n },\n exec: ToolRunExec,\n ): Promise<JsonValue[]> {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const hits = searchSymbols(\n index,\n { query: args.query, file: args.file, kind: args.kind, exportedOnly: args.exportedOnly },\n args.limit ?? 50,\n )\n return hits as unknown as JsonValue[]\n },\n }),\n\n defineTool({\n name: 'code_search',\n description:\n 'Ranked symbol search over the repo index: exact > prefix > substring name matches, exported symbols first. Results carry a relevance score and file:line, so the model can locate definitions quickly.',\n parameters: {\n query: {\n type: 'string',\n required: true,\n description: 'Symbol name (or fragment) to find.',\n },\n limit: {\n type: 'number',\n description: 'Max hits (default 20).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'array' },\n render: (_args, value: JsonValue[]): TextBlock[] =>\n value.map((v) => ({\n type: 'text' as const,\n text: renderHit(v as unknown as Parameters<typeof renderHit>[0]),\n })),\n presentationMeta: (_args, value) => hitsToSearchMeta(value),\n },\n presentCall: (args) => ({\n card: 'generic',\n title: `Search \"${args.query}\"`,\n kind: 'search',\n rawInput: { query: args.query },\n }),\n presentResult: (_args, result) => searchCardFromMeta(result.meta),\n async execute(\n args: { query: string; limit?: number; repoRoot?: string },\n exec: ToolRunExec,\n ): Promise<JsonValue[]> {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const hits = searchSymbols(index, { query: args.query }, args.limit ?? 20)\n return hits as unknown as JsonValue[]\n },\n }),\n\n defineTool({\n name: 'code_map',\n description:\n 'Return a bounded, ranked map of the current repo (top files by symbol density, with their key symbols and lines). The model can call this once per session to build an internal model of the codebase before browsing files.',\n parameters: {\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n async execute(args: { repoRoot?: string }, exec: ToolRunExec): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const cfg = getConfig()\n const map = renderRepoMap(\n rankRepoMap(index, { topFiles: cfg.mapTopFiles }),\n { maxChars: cfg.mapMaxChars },\n )\n if (!map) return 'no indexable symbols found in this repo'\n return map\n } catch (error) {\n return `code_index: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_refs',\n description:\n 'Trace a symbol through the call graph: who calls it (callers) and what it calls (callees), resolved to in-repo definitions with file:line. Complements code_search — search finds a definition, code_refs shows how it is used. Resolution is name-based, so like-named symbols are reported as candidate definitions.',\n parameters: {\n symbol: {\n type: 'string',\n required: true,\n description: 'Symbol name to trace (case-sensitive).',\n },\n direction: {\n type: 'string',\n enum: ['callers', 'callees', 'both'],\n description: 'Which side of the call graph to return (default \"both\").',\n },\n limit: {\n type: 'number',\n description: 'Max rows per side (default 50).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n presentCall: (args) => ({\n card: 'generic',\n title: `Refs ${args.symbol}`,\n kind: 'search',\n rawInput: { symbol: args.symbol, direction: args.direction },\n }),\n async execute(\n args: { symbol: string; direction?: string; limit?: number; repoRoot?: string },\n exec: ToolRunExec,\n ): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const refs = symbolRefs(index, args.symbol, args.limit ?? 50)\n const direction = args.direction ?? 'both'\n const lines: string[] = []\n\n if (refs.defs.length > 0) {\n lines.push('definitions:')\n for (const def of refs.defs) {\n lines.push(` ${def.kind} ${def.signature || def.name} — ${def.file}:${def.line}`)\n }\n } else {\n lines.push(`no definition of \"${args.symbol}\" in this repo`)\n }\n\n if (direction === 'callers' || direction === 'both') {\n lines.push('', `callers (${refs.callers.length}):`)\n if (refs.callers.length === 0) lines.push(' (none)')\n for (const caller of refs.callers) {\n lines.push(` ${caller.file}:${caller.line}${caller.from ? ` in ${caller.from}` : ''}`)\n }\n }\n\n if (direction === 'callees' || direction === 'both') {\n lines.push('', `callees (${refs.callees.length}):`)\n if (refs.callees.length === 0) lines.push(' (none)')\n for (const callee of refs.callees) {\n const target = callee.targets[0]\n lines.push(\n ` ${callee.name} :${callee.line}${target ? ` → ${target.file}:${target.line}` : ' (external)'}`,\n )\n }\n }\n\n return lines.join('\\n')\n } catch (error) {\n return `code_refs: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_change_context',\n description:\n 'Return the smallest change-aware context for the current diff: changed symbols, direct callers, import dependents, shortest paths to entry points, transitive impact, and likely affected tests. Every relation is labeled exact / import-scoped / name-only, so confidence is explicit. Select the change with an explicit diff, a list of files, a list of symbol ids, or (default) the working tree against baseRef.',\n parameters: {\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n diff: {\n type: 'string',\n description: 'Caller-supplied unified diff text; when present no git command runs.',\n },\n baseRef: {\n type: 'string',\n description: 'Git ref to diff against (default \"HEAD\"); also the baseline read for deletions.',\n },\n files: {\n type: 'array',\n items: { type: 'string' },\n description: 'Repo-relative files to treat as wholly changed (mutually exclusive with diff/symbols).',\n },\n symbols: {\n type: 'array',\n items: { type: 'string' },\n description: 'SymbolInfo ids to treat as changed (mutually exclusive with diff/files).',\n },\n maxDepth: {\n type: 'number',\n description: 'Transitive caller depth, 1..6 (default 3).',\n },\n maxImpact: {\n type: 'number',\n description: 'Max direct-caller / impact / dependent rows, 1..200 (default 40).',\n },\n maxPaths: {\n type: 'number',\n description: 'Max entry-point paths, 1..50 (default 10).',\n },\n maxTests: {\n type: 'number',\n description: 'Max affected-test rows, 1..100 (default 20).',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n presentCall: (args) => ({\n card: 'generic',\n title: 'Change context',\n kind: 'search',\n rawInput: {\n baseRef: args.baseRef,\n files: args.files,\n symbols: args.symbols,\n diff: args.diff !== undefined ? '(inline diff)' : undefined,\n },\n }),\n async execute(\n args: {\n repoRoot?: string\n diff?: string\n baseRef?: string\n files?: string[]\n symbols?: string[]\n maxDepth?: number\n maxImpact?: number\n maxPaths?: number\n maxTests?: number\n },\n exec: ToolRunExec,\n ): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const input = changeContextInputFromArgs(args, root)\n const result = await buildChangeContext(index, input, {\n maxDepth: args.maxDepth,\n maxImpact: args.maxImpact,\n maxPaths: args.maxPaths,\n maxTests: args.maxTests,\n })\n return renderChangeContext(result)\n } catch (error) {\n return `code_change_context: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_health',\n description:\n 'Report structural health from the import graph: circular dependencies (import cycles) and orphan modules (symbol-bearing files that nothing imports and that import nothing, excluding entry points and tests).',\n parameters: {\n limit: {\n type: 'number',\n description: 'Max cycles and orphan rows to list (default 50).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n presentCall: () => ({ card: 'generic', title: 'Code health', kind: 'read' }),\n async execute(args: { limit?: number; repoRoot?: string }, exec: ToolRunExec): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const limit = args.limit ?? 50\n const cycles = findCycles(index)\n const orphans = findOrphanModules(index)\n\n const lines = [`repo health — ${index.files.length} files`]\n lines.push('', `circular dependencies (${cycles.length}):`)\n if (cycles.length === 0) lines.push(' (none)')\n for (const cycle of cycles.slice(0, limit)) lines.push(` ${cycle.join(' → ')}`)\n\n lines.push('', `orphan modules (${orphans.length}):`)\n if (orphans.length === 0) lines.push(' (none)')\n for (const orphan of orphans.slice(0, limit)) lines.push(` ${orphan}`)\n\n return lines.join('\\n')\n } catch (error) {\n return `code_health: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n]\n","/** Plugin configuration: merged once at apply time, read wherever needed. */\n\nimport type { IndexOptions } from './types.js'\n\nexport interface PluginConfig {\n /** Extra directories to exclude from indexing (appended to defaults). */\n excludeDirs?: string[]\n /** Max files in the ranked repo map (code_map / auto section). */\n mapTopFiles?: number\n /** Hard char cap for rendered maps. */\n mapMaxChars?: number\n /** Refresh interval for the auto-injected map (ms, min 1000). */\n mapTtlMs?: number\n /** Set false to disable the auto-injected system section. */\n autoInject?: boolean\n /** Register the code_health tool (circles / orphans). Off by default. */\n codeHealth?: boolean\n}\n\ninterface EffectiveConfig {\n excludeDirs: string[]\n mapTopFiles: number\n mapMaxChars: number\n mapTtlMs: number\n autoInject: boolean\n codeHealth: boolean\n}\n\nconst DEFAULTS: EffectiveConfig = {\n excludeDirs: [],\n mapTopFiles: 24,\n mapMaxChars: 3200,\n mapTtlMs: 60_000,\n autoInject: true,\n codeHealth: false,\n}\n\nconst state: { current: EffectiveConfig } = { current: { ...DEFAULTS } }\n\n/** Merge a plugin-provided partial config over the defaults (idempotent). */\nexport function applyConfig(partial?: PluginConfig): void {\n state.current = {\n ...DEFAULTS,\n ...(partial ?? {}),\n excludeDirs: [...DEFAULTS.excludeDirs, ...(partial?.excludeDirs ?? [])],\n }\n // Coerce obviously wrong inputs.\n if (!Number.isFinite(state.current.mapTopFiles) || state.current.mapTopFiles < 1) {\n state.current.mapTopFiles = DEFAULTS.mapTopFiles\n }\n if (!Number.isFinite(state.current.mapMaxChars) || state.current.mapMaxChars < 200) {\n state.current.mapMaxChars = DEFAULTS.mapMaxChars\n }\n if (!Number.isFinite(state.current.mapTtlMs) || state.current.mapTtlMs < 1_000) {\n state.current.mapTtlMs = DEFAULTS.mapTtlMs\n }\n}\n\nexport function getConfig(): Readonly<EffectiveConfig> {\n return state.current\n}\n\n/** Map the effective config onto the index pipeline options. */\nexport function indexOptions(): IndexOptions {\n return { excludeDirs: state.current.excludeDirs }\n}","/** Host-side settings namespace for the plugin's user-editable config. */\n\nimport Schema from '@deepseek-ai/schemastery'\nimport type { PluginConfig } from './config.js'\nexport const SETTINGS_NAMESPACE = 'code-index'\n\nexport const settingsSchema = Schema.object({\n excludeDirs: Schema.array(Schema.string()).default([]),\n mapTopFiles: Schema.number().default(24),\n mapMaxChars: Schema.number().default(3200),\n mapTtlMs: Schema.number().default(60_000),\n autoInject: Schema.boolean().default(true),\n codeHealth: Schema.boolean().default(false),\n})\n\ninterface SettingsScopeLike<T> {\n get(): T\n watch(callback: (next: T, prev: T) => void | Promise<void>): () => void\n}\n\ninterface SettingsServiceLike {\n register<T>(ns: string, schema: unknown, options?: { base?: Partial<T> }): SettingsScopeLike<T>\n}\n\n/**\n * Register the `code-index` settings namespace when a settings provider is\n * mounted, and mirror every resolved change into the plugin's live config.\n * Absent provider = the composed config stands, exactly as before.\n */\nexport function registerSettings(\n getService: (name: string) => unknown,\n pluginConfig: PluginConfig | undefined,\n onResolved: (config: PluginConfig) => void,\n): void {\n const service = getService('settings') as SettingsServiceLike | undefined\n if (!service) return\n const scope = service.register<PluginConfig>(SETTINGS_NAMESPACE, settingsSchema, {\n base: pluginConfig ?? {},\n })\n onResolved(scope.get())\n scope.watch((next) => {\n onResolved(next)\n })\n}\n","/**\n * dsh-code-index — DeepSeek Harness bundle entry.\n *\n * Registers model-visible tools (code_index / code_symbols / code_search /\n * code_map / code_refs / code_change_context) plus an opt-in code_health\n * (config.codeHealth) backed by a tree-sitter symbol + call-graph index,\n * and injects a bounded auto-updating repo map for the default workspace\n * into the system prompt.\n */\n\ntype Disposer = void | (() => void)\n\n/** Minimal structural Context; the real @deepseek-ai/cordis type is a\n * runtime dependency we intentionally do not import in the bundle entry. */\ninterface MinimalContext {\n effect(fn: () => Disposer): void\n tools: { register(t: unknown): () => void }\n get?(name: string): unknown\n inject?(deps: string[], run: (ctx: MinimalContext) => void): unknown\n systemPrompt: {\n section(section: {\n name: string\n order: number\n text: string | ((context: unknown) => string)\n }): () => void\n }\n}\n\nexport const name = 'dsh-code-index'\n\n// Public API surface (consumable by other bundles / tests).\nexport { buildIndex, buildIndexWithCache, findRepoRoot } from './buildIndex.js'\nexport { extractSymbols, extractAll, languageForFile, parseFileToSymbols } from './extract.js'\nexport { scanRepo, DEFAULT_EXCLUDED_DIRS, SUPPORTED_EXTS } from './scan.js'\nexport { loadIndex, saveIndex, defaultCachePath, CACHE_DIR_NAME } from './store.js'\nexport { symbolCount } from './types.js'\nexport type { RepoIndex, IndexedFile, SymbolInfo, SymbolKind, IndexOptions } from './types.js'\nexport { searchSymbols, renderHit } from './search.js'\nexport { rankRepoMap, renderRepoMap, scoreFile } from './repomap.js'\nexport { symbolRefs, buildSymbolTable, callerCounts } from './refgraph.js'\nexport { findCycles, findOrphanModules, buildModuleGraph } from './health.js'\nexport { parseUnifiedDiff, readWorkingTreeDiff, readGitFileAtRef } from './git-diff.js'\nexport type { DiffHunk, FileChange } from './git-diff.js'\nexport {\n buildChangeContext,\n changeContextInputFromArgs,\n renderChangeContext,\n} from './change-context.js'\nexport type {\n CodeChangeContextArgs,\n ChangeContextInput,\n ChangeContextOptions,\n ChangeKind,\n ChangedSymbol,\n UnmappedChange,\n ImpactHop,\n ImpactRow,\n SymbolPath,\n ImportDependent,\n AffectedTest,\n ChangeContextResult,\n} from './change-context.js'\nexport { tools } from './tools.js'\n\nimport { getIndex, invalidateIndexCache, tools } from './tools.js'\nimport { findRepoRoot } from './buildIndex.js'\nimport { rankRepoMap, renderRepoMap } from './repomap.js'\nimport { symbolCount } from './types.js'\nimport { applyConfig, getConfig, type PluginConfig } from './config.js'\nimport { registerSettings } from './settings.js'\n\nexport const inject = ['tools', 'systemPrompt'] as const\n\nexport function apply(ctx: MinimalContext, pluginConfig?: PluginConfig) {\n applyConfig(pluginConfig)\n invalidateIndexCache()\n ctx.effect(() => {\n const disposers: Array<() => void> = []\n console.log('[dsh-code-index] plugin loaded')\n\n // User-editable settings resolve over the composed plugin row; when a\n // settings provider is mounted, every committed change reconfigures live.\n // The provider initializes asynchronously, so wait for the service rather\n // than reading it once at load (which can precede its availability).\n if (ctx.inject) {\n ctx.inject(['settings'], (settingsCtx) => {\n registerSettings(\n (name) => settingsCtx.get!(name),\n pluginConfig,\n (resolved) => applyConfig(resolved),\n )\n })\n }\n\n for (const tool of tools) {\n if (tool.name === 'code_health' && !getConfig().codeHealth) continue\n disposers.push(ctx.tools.register(tool))\n console.log(`[dsh-code-index] registered tool: ${tool.name}`)\n }\n\n // Auto-inject a bounded repo map for the DEFAULT workspace (the dsh\n // launch directory, per the harness docs). Multi-workspace web sessions\n // should rely on the `code_map` tool, which resolves the per-session cwd.\n let cached: { root: string; at: number; text: string } | null = null\n\n async function warmMap(): Promise<void> {\n const now = Date.now()\n const cfg = getConfig()\n try {\n const root = await findRepoRoot(process.cwd())\n if (!root) {\n cached = { root: '', at: now, text: '' }\n return\n }\n const index = await getIndex(root)\n const text = renderRepoMap(\n rankRepoMap(index, { topFiles: cfg.mapTopFiles }),\n { maxChars: cfg.mapMaxChars },\n )\n const stats = symbolCount(index)\n cached = {\n root: index.root,\n at: Date.now(),\n text: text ? `${text}\\n\\n(summary: ${index.files.length} files, ${stats} symbols)` : '',\n }\n } catch {\n cached = { root: '', at: now, text: '' } // never let injection fail the boot\n }\n }\n\n // Warm eagerly at load so the first assembly already has the map.\n void warmMap()\n\n if (getConfig().autoInject) {\n disposers.push(ctx.systemPrompt.section({\n name: 'code-index:repo-map',\n order: 60, // before tool guidance (100–199), after persona (0)\n text: () => {\n const now = Date.now()\n if (cached && now - cached.at < getConfig().mapTtlMs) return cached.text\n void warmMap()\n return cached?.text ?? ''\n },\n }))\n }\n\n return () => {\n const errors: unknown[] = []\n for (const dispose of disposers.reverse()) {\n try {\n dispose()\n } catch (error) {\n errors.push(error)\n }\n }\n console.log('[dsh-code-index] plugin unloaded')\n if (errors.length > 0) throw new AggregateError(errors, 'failed to unload dsh-code-index')\n }\n })\n}\n"],"mappings":"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","names":["readFile","stat","path","require","name","index","path","path","readFile","path","path","readFile","readFile","path","stat","path","path","name","name","path","readFile","path","path","TEST_RE","path","path","path","name"]}
|
|
1
|
+
{"version":3,"sources":["../src/buildIndex.ts","../src/extract.ts","../src/scan.ts","../src/store.ts","../src/types.ts","../src/repomap.ts","../src/refgraph.ts","../src/search.ts","../src/health.ts","../src/git-diff.ts","../src/change-context.ts","../src/context.ts","../src/tools.ts","../src/config.ts","../src/repo-context.ts","../src/settings.ts","../src/index.ts"],"sourcesContent":["/** Build a RepoIndex for a workspace: scan -> extract -> persist. */\n\nimport { readFile, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport { extractAll, languageForFile } from './extract.js'\nimport { scanRepo, DEFAULT_EXCLUDED_DIRS } from './scan.js'\nimport {\n cacheKeyForRoot,\n defaultCachePath,\n legacyCachePath,\n loadIndex,\n saveIndex,\n} from './store.js'\nimport type { IndexOptions, IndexedFile, RepoIndex, SymbolInfo } from './types.js'\nimport { REPO_INDEX_SCHEMA_VERSION } from './types.js'\n\n/**\n * Full build: scan + extract every supported file. Existing per-file\n * extraction is reused when `previous` holds an identical mtime for the\n * same rel path (incremental refresh), so touched files alone re-parse.\n */\nexport async function buildIndex(\n root: string,\n options: IndexOptions = {},\n previous: RepoIndex | null = null,\n forcePaths: ReadonlySet<string> = new Set(),\n): Promise<RepoIndex> {\n const scanned = await scanRepo(root, options)\n\n // Index stale/current state from the previous run by rel path.\n const prevByPath = new Map((previous?.files ?? []).map((f) => [f.path, f]))\n const prevMtime = new Map((previous?.files ?? []).map((f) => [f.path, f.mtimeMs]))\n\n const files: IndexedFile[] = []\n const BATCH = 8\n for (let i = 0; i < scanned.length; i += BATCH) {\n const batch = scanned.slice(i, i + BATCH)\n const rows = await Promise.all(\n batch.map(async (f) => {\n const lang = languageForFile(f.abs)\n if (!lang) return null\n if (prevMtime.get(f.rel) === f.mtimeMs && !forcePaths.has(f.rel) && !forcePaths.has('*')) {\n const cached = prevByPath.get(f.rel)!\n return {\n ...cached,\n mtimeMs: f.mtimeMs,\n symbols: cached.symbols.map((symbol) => ({ ...symbol, file: f.rel })),\n }\n }\n let code: string\n try {\n code = await readFile(f.abs, 'utf8')\n } catch {\n return null\n }\n const { symbols, imports, importDetails, calls } = await extractAll(code, lang, f.rel)\n // Backfill the repo-relative path: the extractor is file-agnostic and\n // leaves SymbolInfo.file empty, but search/render depend on it.\n return {\n path: f.rel,\n lang,\n mtimeMs: f.mtimeMs,\n symbols: symbols.map((s) => ({ ...s, file: f.rel })),\n imports,\n importDetails,\n calls,\n } satisfies IndexedFile\n }),\n )\n for (const f of rows) {\n if (f) files.push(f)\n }\n }\n\n return {\n schemaVersion: REPO_INDEX_SCHEMA_VERSION,\n root,\n generatedAt: Date.now(),\n files,\n excludedDirs: [...DEFAULT_EXCLUDED_DIRS, ...(options.excludeDirs ?? [])],\n }\n}\n\n/** Convenience wrapper: evolve an on-disk cache if `root` exists. */\nexport async function buildIndexWithCache(\n root: string,\n options: IndexOptions = {},\n cacheDir?: string,\n forcePaths: ReadonlySet<string> = new Set(),\n): Promise<RepoIndex> {\n const cachePath = defaultCachePath(root, cacheDir)\n let prev = await loadIndex(cachePath)\n let loadedLegacy = false\n if (!prev) {\n const oldPath = legacyCachePath(root, cacheDir)\n if (oldPath !== cachePath) {\n prev = await loadIndex(oldPath)\n loadedLegacy = prev !== null\n }\n }\n const reusable = prev && cacheKeyForRoot(prev.root) === cacheKeyForRoot(root) ? prev : null\n const fresh = await buildIndex(root, options, reusable, forcePaths)\n if (prev && indexesEqual(prev, fresh)) {\n if (loadedLegacy) await saveIndex(cachePath, fresh)\n return loadedLegacy ? fresh : prev\n }\n await saveIndex(cachePath, fresh)\n return fresh\n}\n\nfunction indexesEqual(left: RepoIndex, right: RepoIndex): boolean {\n if (left.schemaVersion !== right.schemaVersion) return false\n if (cacheKeyForRoot(left.root) !== cacheKeyForRoot(right.root)) return false\n if (left.files.length !== right.files.length) return false\n if (left.excludedDirs.length !== right.excludedDirs.length) return false\n if (left.excludedDirs.some((value, index) => value !== right.excludedDirs[index])) return false\n\n return left.files.every((file, fileIndex) => {\n const other = right.files[fileIndex]\n if (!other || file.path !== other.path || file.lang !== other.lang || file.mtimeMs !== other.mtimeMs) {\n return false\n }\n if (file.symbols.length !== other.symbols.length) return false\n if (!callsEqual(file.calls, other.calls)) return false\n if (!importsEqual(file.importDetails, other.importDetails)) return false\n return file.symbols.every((symbol, symbolIndex) => {\n const candidate = other.symbols[symbolIndex]\n return candidate !== undefined\n && symbol.id === candidate.id\n && symbol.name === candidate.name\n && symbol.kind === candidate.kind\n && symbol.file === candidate.file\n && symbol.line === candidate.line\n && symbol.endLine === candidate.endLine\n && symbol.exported === candidate.exported\n && symbol.signature === candidate.signature\n && symbol.ordinal === candidate.ordinal\n && scopesEqual(symbol.scope, candidate.scope)\n })\n })\n}\n\nfunction scopesEqual(left: SymbolInfo['scope'], right: SymbolInfo['scope']): boolean {\n if (left.length !== right.length) return false\n return left.every((part, index) => {\n const other = right[index]\n return other !== undefined\n && part.kind === other.kind\n && part.name === other.name\n && part.ordinal === other.ordinal\n })\n}\n\nfunction importsEqual(\n left: IndexedFile['importDetails'],\n right: IndexedFile['importDetails'],\n): boolean {\n const a = left ?? []\n const b = right ?? []\n if (a.length !== b.length) return false\n return a.every((info, index) => {\n const other = b[index]\n if (\n !other ||\n info.specifier !== other.specifier ||\n info.line !== other.line ||\n info.kind !== other.kind ||\n info.bindings.length !== other.bindings.length\n ) {\n return false\n }\n return info.bindings.every((binding, bindingIndex) => {\n const candidate = other.bindings[bindingIndex]\n return candidate !== undefined\n && binding.imported === candidate.imported\n && binding.local === candidate.local\n && binding.kind === candidate.kind\n })\n })\n}\n\n/**\n * Calls are compared so a cache written before call-graph support is treated as\n * stale and re-persisted, instead of silently shadowing the richer fresh index.\n */\nfunction callsEqual(left: IndexedFile['calls'], right: IndexedFile['calls']): boolean {\n const a = left ?? []\n const b = right ?? []\n if (a.length !== b.length) return false\n return a.every((call, index) => {\n const other = b[index]\n return other !== undefined\n && call.name === other.name\n && call.line === other.line\n && call.from === other.from\n && call.fromId === other.fromId\n && call.qualifier === other.qualifier\n })\n}\n\n/**\n * Locate the git repo root for a path by walking up to the nearest `.git`\n * directory. Bounded walk (max `maxLevels` levels); returns `null` when no\n * repo marker is found — callers must NOT index an untagged directory\n * (the fs root is the classic footgun: indexing `C:\\` by accident).\n */\nexport async function findRepoRoot(startDir: string, maxLevels = 12): Promise<string | null> {\n let dir = path.resolve(startDir)\n for (let level = 0; level < maxLevels; level++) {\n try {\n // stat() accepts BOTH a `.git` directory (normal repos) and a `.git`\n // file (worktrees / submodules) — readFile only handled the file form.\n await stat(path.join(dir, '.git'))\n return dir\n } catch {\n // not a repo here — keep walking\n }\n const parent = path.dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n return null\n}\n","/**\n * tree-sitter symbol extraction.\n *\n * Parses a source text with a per-language grammar (web-tree-sitter WASM,\n * static grammars from tree-sitter-wasms) and returns flat SymbolInfo rows.\n *\n * NOTE on the dependency pin: web-tree-sitter must stay at ^0.20.x — newer\n * releases expect dylinked grammar wasm, while tree-sitter-wasms ships\n * static builds. Verified working pair: web-tree-sitter@0.20.8 + tree-sitter-wasms@0.1.13.\n */\n\nimport { readFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport { type Node, Language, Parser, Query } from 'web-tree-sitter'\nimport type {\n CallInfo,\n ImportBinding,\n ImportInfo,\n ScopeKind,\n SymbolInfo,\n SymbolKind,\n SymbolScopePart,\n} from './types.js'\n\nconst require = createRequire(import.meta.url)\n// web-tree-sitter ≥0.25 is ESM with named exports; 0.20.x was CJS\n// `export = Parser`. tsup externalizes the dep, so the import shape must\n// match the published ESM entry.\n\nexport type LanguageId =\n | 'typescript'\n | 'javascript'\n | 'python'\n | 'go'\n | 'rust'\n | 'java'\n | 'cpp'\n | 'c'\n\nconst WASM_DIR = path.dirname(require.resolve('tree-sitter-wasms/out/tree-sitter-typescript.wasm'))\n\nconst GRAMMAR_NAMES: Record<LanguageId, string> = {\n typescript: 'tree-sitter-typescript',\n javascript: 'tree-sitter-javascript',\n python: 'tree-sitter-python',\n go: 'tree-sitter-go',\n rust: 'tree-sitter-rust',\n java: 'tree-sitter-java',\n cpp: 'tree-sitter-cpp',\n c: 'tree-sitter-c',\n}\n\nconst EXT_TO_LANG: Record<string, LanguageId> = {\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.mts': 'typescript',\n '.cts': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n '.py': 'python',\n '.pyi': 'python',\n '.go': 'go',\n '.rs': 'rust',\n '.java': 'java',\n '.cpp': 'cpp',\n '.cc': 'cpp',\n '.cxx': 'cpp',\n '.c++': 'cpp',\n '.hpp': 'cpp',\n '.hxx': 'cpp',\n '.hh': 'cpp',\n '.h': 'cpp',\n '.ipp': 'cpp',\n '.tpp': 'cpp',\n '.inl': 'cpp',\n '.c': 'c',\n}\n\nexport function languageForFile(filePath: string): LanguageId | null {\n const ext = path.extname(filePath).toLowerCase()\n return EXT_TO_LANG[ext] ?? null\n}\n\n/** Kind of a capture per query. */\ntype CaptureDef = { kind: SymbolKind; exported?: boolean }\n\n// Query definitions per language. Captures bind to the DECLARATION node\n// (capture OUTSIDE the pattern: `(function_declaration) @function` — the\n// 0.20 query parser rejects a capture sitting directly after the node type\n// inside the parens). Names/signatures/export come from node fields.\nconst QUERIES: Record<LanguageId, string> = {\n typescript: `\n (function_declaration) @function\n (generator_function_declaration) @function\n (method_definition) @method\n (class_declaration) @class\n (interface_declaration) @interface\n (type_alias_declaration) @type\n (enum_declaration) @enum\n (variable_declarator) @variable\n (public_field_definition) @field\n (abstract_class_declaration) @class\n `,\n // JS shares the same query surface; type-related patterns simply never match.\n javascript: `\n (function_declaration) @function\n (generator_function_declaration) @function\n (method_definition) @method\n (class_declaration) @class\n (variable_declarator) @variable\n `,\n python: `\n (function_definition) @function\n (class_definition) @class\n `,\n go: `\n (function_declaration) @function\n (method_declaration) @method\n (type_spec) @type\n `,\n rust: `\n (function_item) @function\n (function_signature_item) @method\n (struct_item) @class\n (enum_item) @enum\n (trait_item) @interface\n `,\n java: `\n (class_declaration) @class\n (interface_declaration) @interface\n (enum_declaration) @enum\n (method_declaration) @method\n (constructor_declaration) @method\n `,\n // C++ grammar (superset of C — also serves .h headers). function names\n // live inside the declarator chain, so patterns stay broad and names,\n // kinds and signatures are resolved in code (cppNameOf / kindFor /\n // signatureFor). Top-level `declaration` covers prototypes, constructors\n // and globals; field_declaration covers class-body members.\n cpp: `\n (function_definition) @function\n (class_specifier body: (_)) @class\n (struct_specifier body: (_)) @class\n (enum_specifier body: (_)) @enum\n (type_definition) @type\n (alias_declaration) @type\n (namespace_definition) @module\n (field_declaration) @field\n (declaration) @variable\n `,\n // Plain C: same core nodes minus C++-only namespace/alias forms.\n c: `\n (function_definition) @function\n (struct_specifier body: (_)) @class\n (enum_specifier body: (_)) @enum\n (type_definition) @type\n (field_declaration) @field\n (declaration) @variable\n `,\n}\n\nconst CAPTURE_KINDS: Record<string, CaptureDef> = {\n function: { kind: 'function' },\n method: { kind: 'method' },\n class: { kind: 'class' },\n interface: { kind: 'interface' },\n type: { kind: 'type' },\n enum: { kind: 'enum' },\n variable: { kind: 'variable' },\n field: { kind: 'field' },\n module: { kind: 'module' },\n}\n\n// Import statements per language. Whole statements are captured; the module\n// specifier is read from node fields in code (string quoting, dotted vs\n// relative vs URL-style syntax differ per grammar). CommonJS require() is out\n// of scope — the ES import surface covers the modern plugin ecosystem.\nconst IMPORT_QUERIES: Record<LanguageId, string> = {\n typescript: `\n (import_statement) @import\n (export_statement) @reexport\n `,\n javascript: `\n (import_statement) @import\n (export_statement) @reexport\n `,\n python: `\n (import_from_statement) @import\n (import_statement) @import\n `,\n go: `\n (import_spec) @import\n `,\n rust: `\n (use_declaration) @use\n `,\n java: `\n (import_declaration) @import\n `,\n // C/C++: #include \"local.hpp\" — quoted form resolves in-repo; <system>\n // captures too but yields null and is dropped by the extractor.\n cpp: `\n (preproc_include) @import\n `,\n c: `\n (preproc_include) @import\n `,\n}\n\n// Call expressions per language. Each capture binds the CALLEE name node, so\n// the extractor can build a function-level call graph (see enclosingCallable).\n// Member/selector calls capture the property/field tail, which is what a\n// definition lookup matches; `new X()` is a construction call.\nconst CALL_QUERIES: Record<LanguageId, string> = {\n typescript: `\n (call_expression function: (identifier) @call)\n (call_expression function: (member_expression property: (property_identifier) @call))\n (new_expression constructor: (identifier) @call)\n `,\n javascript: `\n (call_expression function: (identifier) @call)\n (call_expression function: (member_expression property: (property_identifier) @call))\n (new_expression constructor: (identifier) @call)\n `,\n python: `\n (call function: (identifier) @call)\n (call function: (attribute attribute: (identifier) @call))\n `,\n go: `\n (call_expression function: (identifier) @call)\n (call_expression function: (selector_expression field: (field_identifier) @call))\n `,\n rust: `\n (call_expression function: (identifier) @call)\n (call_expression function: (field_expression field: (field_identifier) @call))\n (call_expression function: (scoped_identifier name: (identifier) @call))\n `,\n java: `\n (method_invocation name: (identifier) @call)\n (object_creation_expression type: (type_identifier) @call)\n `,\n cpp: `\n (call_expression function: (identifier) @call)\n (call_expression function: (field_expression field: (field_identifier) @call))\n (call_expression function: (qualified_identifier name: (identifier) @call))\n `,\n c: `\n (call_expression function: (identifier) @call)\n (call_expression function: (field_expression field: (field_identifier) @call))\n `,\n}\n\n// Ancestor node types that own a call body, per language. Walking up from a\n// call site to the nearest one yields the function whose callees they are.\nconst CALLABLE_NODES: Record<LanguageId, Set<string>> = {\n typescript: new Set([\n 'function_declaration',\n 'generator_function_declaration',\n 'method_definition',\n 'function_expression',\n 'arrow_function',\n ]),\n javascript: new Set([\n 'function_declaration',\n 'generator_function_declaration',\n 'method_definition',\n 'function_expression',\n 'arrow_function',\n ]),\n python: new Set(['function_definition']),\n go: new Set(['function_declaration', 'method_declaration', 'func_literal']),\n rust: new Set(['function_item', 'function_signature_item']),\n java: new Set(['method_declaration', 'constructor_declaration']),\n cpp: new Set(['function_definition', 'lambda_expression']),\n c: new Set(['function_definition']),\n}\n\nlet parserPromise: Promise<Parser> | null = null\n\nasync function getParser(): Promise<Parser> {\n if (!parserPromise) {\n parserPromise = (async () => {\n const wasm = path.join(path.dirname(require.resolve('web-tree-sitter')), 'tree-sitter.wasm')\n await Parser.init({ locateFile: () => wasm })\n const p = new Parser()\n return p\n })()\n }\n return parserPromise\n}\n\nconst languageCache = new Map<LanguageId, Promise<Language>>()\n\nfunction getLanguage(id: LanguageId): Promise<Language> {\n let entry = languageCache.get(id)\n if (!entry) {\n entry = getParser().then(async () => {\n const grammarPath = path.join(WASM_DIR, `${GRAMMAR_NAMES[id]}.wasm`)\n const bytes = await readFile(grammarPath)\n const lang = await Language.load(bytes)\n // Precompile queries per language to catch authoring errors early.\n // (0.25 deprecates lang.query(); use the Query constructor.)\n new Query(lang, QUERIES[id]).delete()\n new Query(lang, IMPORT_QUERIES[id]).delete()\n new Query(lang, CALL_QUERIES[id]).delete()\n return lang\n })\n languageCache.set(id, entry)\n }\n return entry\n}\n\n/**\n * Extract symbols and raw import specifiers from source text of the given\n * language, from a single parse. Returns rows ordered by file line. Never\n * throws for parse errors — a failed parse yields empty lists (the caller\n * logs and continues).\n */\n/** RFC 3986-strict component encoding for symbol ids (encodes `! ' ( ) * ~`). */\nexport function encodeSymbolComponent(value: string): string {\n return encodeURIComponent(value).replace(\n /[!'()*~]/g,\n (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`,\n )\n}\n\n/** A captured declaration retained until stable ids can be assigned. */\nexport interface SymbolDraft {\n symbol: Omit<SymbolInfo, 'id' | 'scope' | 'ordinal' | 'file'>\n node: Node\n}\n\nexport interface ExtractedFile {\n symbols: SymbolInfo[]\n /** Derived compatibility view of {@link importDetails} specifiers. */\n imports: string[]\n /** Structured import/include/use sites with name bindings. */\n importDetails: ImportInfo[]\n /** Call sites, ordered by line: callee name + enclosing function. */\n calls: CallInfo[]\n}\n\nexport async function extractAll(\n code: string,\n id: LanguageId,\n file = '',\n): Promise<ExtractedFile> {\n const lang = await getLanguage(id)\n const parser = await getParser()\n parser.setLanguage(lang)\n const tree = parser.parse(code)\n if (!tree) throw new Error(`tree-sitter parse returned null for a ${id} source`)\n try {\n const drafts: SymbolDraft[] = []\n const symbolQuery = new Query(lang, QUERIES[id])\n try {\n const captures = symbolQuery.captures(tree.rootNode)\n for (const cap of captures) {\n const def = CAPTURE_KINDS[cap.name]\n if (!def) continue\n const node = cap.node\n // tree-sitter queries match at any depth; without this check the\n // variable_declarator pattern would also capture function-body\n // locals — pure index noise.\n if (def.kind === 'variable' && !isModuleLevelVariable(id, node)) continue\n const name = nameOf(id, node)\n if (!name) continue\n drafts.push({\n symbol: {\n name,\n kind: kindFor(id, node, def.kind),\n line: node.startPosition.row + 1,\n endLine: node.endPosition.row + 1,\n exported: isExported(id, node),\n signature: signatureFor(id, node),\n },\n node,\n })\n }\n } finally {\n symbolQuery.delete()\n }\n\n const dedupedDrafts = dedupeDrafts(drafts)\n const symbols = assignSymbolIds(file, dedupedDrafts, id)\n const symbolByNodeId = new Map<number, SymbolInfo>()\n dedupedDrafts.forEach((draft, index) => symbolByNodeId.set(draft.node.id, symbols[index]))\n\n const importDetails: ImportInfo[] = []\n const importQuery = new Query(lang, IMPORT_QUERIES[id])\n try {\n for (const cap of importQuery.captures(tree.rootNode)) {\n for (const info of importInfoFor(id, cap.node)) importDetails.push(info)\n }\n } finally {\n importQuery.delete()\n }\n const imports = importDetails.map((info) => info.specifier)\n\n const calls: CallInfo[] = []\n const callQuery = new Query(lang, CALL_QUERIES[id])\n try {\n const seen = new Set<string>()\n for (const cap of callQuery.captures(tree.rootNode)) {\n const name = cap.node.text.trim()\n if (!name) continue\n const line = cap.node.startPosition.row + 1\n const callable = enclosingCallableNode(id, cap.node)\n const from = callable ? callableNameOf(id, callable) : ''\n const fromId = callable ? nearestDraftId(callable, symbolByNodeId) : null\n const key = `${from}|${name}|${line}`\n if (seen.has(key)) continue\n seen.add(key)\n calls.push({ name, line, from, fromId, qualifier: qualifierOf(cap.node) })\n }\n } finally {\n callQuery.delete()\n }\n calls.sort((a, b) => a.line - b.line || a.name.localeCompare(b.name))\n\n symbols.sort(\n (a, b) =>\n a.line - b.line ||\n a.endLine - b.endLine ||\n a.kind.localeCompare(b.kind) ||\n a.name.localeCompare(b.name),\n )\n return { symbols, imports, importDetails, calls }\n } finally {\n tree.delete()\n }\n}\n\n/**\n * Drop duplicate captures of the *same* AST node only. Keying by\n * `kind|name|line` would also collapse two distinct same-named declarations\n * sharing a line (`class A { run() {} } class B { run() {} }`); identity\n * keeps them so `assignOrdinals` can separate them by source order.\n */\nfunction dedupeDrafts(drafts: SymbolDraft[]): SymbolDraft[] {\n const sorted = [...drafts].sort(\n (a, b) => a.symbol.line - b.symbol.line || a.node.startIndex - b.node.startIndex,\n )\n const seen = new Set<number>()\n const out: SymbolDraft[] = []\n for (const draft of sorted) {\n if (seen.has(draft.node.id)) continue\n seen.add(draft.node.id)\n out.push(draft)\n }\n return out\n}\n\n/** One scope owner descriptor produced by a language-specific helper. */\ninterface OwnerDesc {\n kind: ScopeKind\n name: string\n}\n\n/** A scope node: a captured declaration or a synthetic owner, by index. */\ninterface ScopeEntry {\n kind: ScopeKind\n name: string\n startIndex: number\n endIndex: number\n /** Index of the parent entry; -1 = module root. */\n parent: number\n ordinal: number\n scopeKey: string\n /** Draft index for captured declarations; -1 for synthetic owners. */\n draftIndex: number\n}\n\nconst MATCHABLE_OWNER_KINDS: ReadonlySet<ScopeKind> = new Set([\n 'class',\n 'interface',\n 'trait',\n 'module',\n 'namespace',\n 'impl',\n])\n\n/** Map a captured symbol kind onto the scope vocabulary used in symbol ids. */\nfunction scopeKindOf(language: LanguageId, kind: SymbolKind): ScopeKind {\n switch (kind) {\n case 'class':\n return 'class'\n case 'interface':\n return language === 'rust' ? 'trait' : 'interface'\n case 'function':\n return 'function'\n case 'method':\n return 'method'\n case 'module':\n return language === 'cpp' ? 'namespace' : 'module'\n default:\n return 'owner'\n }\n}\n\nfunction segmentOf(entry: ScopeEntry): string {\n return `${entry.kind}:${encodeSymbolComponent(entry.name)}@${entry.ordinal}`\n}\n\n/**\n * Assign stable qualified ids, owner scopes and sibling ordinals to captured\n * declarations. Ordinals are 1-based within a `(parent scope, kind, name)`\n * group, ordered by source position, so ids survive blank-line/comment/body\n * edits but not reordering or inserting an earlier duplicate.\n */\nexport function assignSymbolIds(\n file: string,\n drafts: readonly SymbolDraft[],\n language: LanguageId,\n): SymbolInfo[] {\n const entries: ScopeEntry[] = drafts.map((draft, index) => ({\n kind: scopeKindOf(language, draft.symbol.kind),\n name: draft.symbol.name,\n startIndex: draft.node.startIndex,\n endIndex: draft.node.endIndex,\n parent: -1,\n ordinal: 1,\n scopeKey: '',\n draftIndex: index,\n }))\n const entryByNodeId = new Map<number, number>()\n drafts.forEach((draft, index) => entryByNodeId.set(draft.node.id, index))\n const entriesByName = new Map<string, number[]>()\n entries.forEach((entry, index) => {\n const list = entriesByName.get(entry.name)\n if (list) list.push(index)\n else entriesByName.set(entry.name, [index])\n })\n\n const syntheticByKey = new Map<string, number>()\n\n const resolveOwner = (desc: OwnerDesc, parent: number, selfIndex: number): number => {\n const matches = entriesByName.get(desc.name)\n // Only an owner already scoped under the same parent may absorb this\n // segment — a global name match would attach `b::Widget::draw` to the\n // first `Widget` in the file. `owner` is a wildcard kind: the qualified\n // segment does not know whether it names a class or a namespace.\n const typed = matches?.find((index) => {\n if (index === selfIndex) return false\n const entry = entries[index]!\n if (!MATCHABLE_OWNER_KINDS.has(entry.kind)) return false\n if (entry.parent !== parent) return false\n return desc.kind === 'owner' || entry.kind === desc.kind\n })\n if (typed !== undefined) return typed\n const key = `${parent}\\u0000${desc.kind}\\u0000${desc.name}`\n const existing = syntheticByKey.get(key)\n if (existing !== undefined) return existing\n const index = entries.length\n entries.push({\n kind: desc.kind,\n name: desc.name,\n startIndex: Number.MAX_SAFE_INTEGER,\n endIndex: Number.MAX_SAFE_INTEGER,\n parent,\n ordinal: 1,\n scopeKey: '',\n draftIndex: -1,\n })\n syntheticByKey.set(key, index)\n return index\n }\n\n drafts.forEach((draft, index) => {\n let parent = -1\n for (let node = draft.node.parent; node; node = node.parent) {\n const owner = entryByNodeId.get(node.id)\n if (owner !== undefined) {\n parent = owner\n break\n }\n }\n for (const desc of ownerScopeOf(language, draft.node)) {\n parent = resolveOwner(desc, parent, index)\n }\n entries[index]!.parent = parent\n })\n\n assignOrdinals(entries)\n\n return drafts.map((draft, index) => {\n const entry = entries[index]!\n const chain: ScopeEntry[] = []\n for (let node: ScopeEntry | undefined = entries[entry.parent]; node; node = entries[node.parent]) {\n chain.push(node)\n }\n chain.reverse()\n const scope: SymbolScopePart[] = chain.map((node) => ({\n kind: node.kind,\n name: node.name,\n ordinal: node.ordinal,\n }))\n const segments = [...chain.map(segmentOf), segmentOf(entry)]\n return {\n ...draft.symbol,\n file,\n id: `sym:v1:${encodeSymbolComponent(file)}#${segments.join('/')}`,\n scope,\n ordinal: entry.ordinal,\n }\n })\n}\n\n/** BFS by depth so a parent's scopeKey is known before its children group. */\nfunction assignOrdinals(entries: ScopeEntry[]): void {\n const depthCache = new Map<number, number>()\n const depthOf = (index: number): number => {\n const cached = depthCache.get(index)\n if (cached !== undefined) return cached\n const parent = entries[index]!.parent\n const value = parent >= 0 ? depthOf(parent) + 1 : 0\n depthCache.set(index, value)\n return value\n }\n\n const byDepth = new Map<number, number[]>()\n let maxDepth = 0\n for (let index = 0; index < entries.length; index++) {\n const depth = depthOf(index)\n maxDepth = Math.max(maxDepth, depth)\n const list = byDepth.get(depth)\n if (list) list.push(index)\n else byDepth.set(depth, [index])\n }\n\n for (let depth = 0; depth <= maxDepth; depth++) {\n const groups = new Map<string, number[]>()\n for (const index of byDepth.get(depth) ?? []) {\n const entry = entries[index]!\n const parentKey = entry.parent >= 0 ? entries[entry.parent]!.scopeKey : ''\n const key = `${parentKey}\\u0000${entry.kind}\\u0000${entry.name}`\n const list = groups.get(key)\n if (list) list.push(index)\n else groups.set(key, [index])\n }\n for (const group of groups.values()) {\n group.sort((a, b) => {\n const left = entries[a]!\n const right = entries[b]!\n return (\n left.startIndex - right.startIndex ||\n left.endIndex - right.endIndex ||\n left.kind.localeCompare(right.kind) ||\n left.name.localeCompare(right.name)\n )\n })\n group.forEach((index, position) => {\n const entry = entries[index]!\n entry.ordinal = position + 1\n const segment = segmentOf(entry)\n entry.scopeKey =\n entry.parent >= 0 ? `${entries[entry.parent]!.scopeKey}/${segment}` : segment\n })\n }\n }\n}\n\n/** Owners not represented by lexical ancestry (receiver/impl/qualified names). */\nfunction ownerScopeOf(language: LanguageId, node: Node): OwnerDesc[] {\n if (language === 'go') return goReceiverOwners(node)\n if (language === 'rust') return rustImplOwners(node)\n if (language === 'cpp' || language === 'c') return cppQualifiedOwners(node)\n return []\n}\n\nfunction goReceiverOwners(node: Node): OwnerDesc[] {\n if (node.type !== 'method_declaration') return []\n const receiver = node.childForFieldName('receiver')\n const type = receiver ? findDescendant(receiver, 'type_identifier') : null\n return type ? [{ kind: 'class', name: type.text.trim() }] : []\n}\n\nfunction rustImplOwners(node: Node): OwnerDesc[] {\n if (node.type !== 'function_item' && node.type !== 'function_signature_item') return []\n let impl: Node | null = null\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (parent.type === 'impl_item') {\n impl = parent\n break\n }\n if (parent.type === 'trait_item' || CALLABLE_NODES.rust.has(parent.type)) return []\n }\n if (!impl) return []\n const type = impl.childForFieldName('type')\n const targetName = type ? findDescendant(type, 'type_identifier')?.text.trim() : undefined\n const traitName = impl.childForFieldName('trait')?.text.trim()\n // Keep the impl as its own scope segment: distinct trait impls for one type\n // are separate scopes. Carry `Trait for Type` so `impl A for Config` and\n // `impl B for Config` do not collide; a bare type name covers inherent impls.\n const name = targetName && traitName ? `${traitName} for ${targetName}` : (targetName ?? traitName)\n return name ? [{ kind: 'impl', name }] : []\n}\n\nfunction cppQualifiedOwners(node: Node): OwnerDesc[] {\n const declarator = cppDeclaratorQid(node)\n if (!declarator) return []\n return cppQualifiedSegments(declarator)\n .slice(0, -1)\n .map((name) => ({ kind: 'owner' as ScopeKind, name }))\n}\n\n/** Descend the C/C++ declarator chain to an out-of-class `Scope::name` form. */\nfunction cppDeclaratorQid(node: Node): Node | null {\n let current = node.childForFieldName?.('declarator')\n while (current) {\n if (current.type === 'qualified_identifier') return current\n if (!current.type.includes('declarator')) return null\n current = current.childForFieldName?.('declarator') ?? current.namedChildren[0] ?? null\n }\n return null\n}\n\n/** Flatten a (right-nested) C++ qualified identifier, outermost name first. */\nfunction cppQualifiedSegments(qualified: Node): string[] {\n const scope = qualified.childForFieldName('scope')\n const name = qualified.childForFieldName('name')\n const head = scope ? [scope.text.trim()] : []\n const tail =\n name?.type === 'qualified_identifier'\n ? cppQualifiedSegments(name)\n : [name?.text.trim() ?? '']\n return [...head, ...tail].filter(Boolean)\n}\n\nfunction findDescendant(node: Node, type: string): Node | null {\n if (node.type === type) return node\n for (const child of node.namedChildren) {\n if (!child) continue\n const nested = findDescendant(child, type)\n if (nested) return nested\n }\n return null\n}\n\nfunction nearestDraftId(node: Node, symbols: Map<number, SymbolInfo>): string | null {\n for (let current: Node | null = node; current; current = current.parent) {\n const symbol = symbols.get(current.id)\n if (symbol) return symbol.id\n }\n return null\n}\n\n/** Symbols only — see extractAll for the combined parse. */\nexport async function extractSymbols(code: string, id: LanguageId): Promise<SymbolInfo[]> {\n return (await extractAll(code, id)).symbols\n}\n\n/** The declared name of a declaration node — language-aware dispatch. */\nfunction nameOf(id: LanguageId, node: Node): string {\n if (id === 'cpp' || id === 'c') return cppNameOf(node)\n const field = node.childForFieldName?.('name')\n if (field) return field.text.trim()\n // e.g. an anonymous default export — skip those.\n return ''\n}\n\n/**\n * C/C++ declaration names hide in the declarator chain:\n * - function_definition → declarator:function_declarator → identifier |\n * qualified_identifier (A::b) | field_identifier (in-class method)\n * - class/struct/enum specifiers and alias_declaration carry `name`\n * - type_definition → declarator:type_identifier\n * Returns '' for anonymous declarations (skipped upstream).\n */\nfunction cppNameOf(node: Node): string {\n const nameField = node.childForFieldName?.('name')\n if (nameField) return nameField.text.trim()\n if (node.type === 'type_definition') {\n return node.childForFieldName?.('declarator')?.text.trim() ?? ''\n }\n let declarator = node.childForFieldName?.('declarator')\n if (declarator?.type === 'init_declarator') {\n declarator = declarator.childForFieldName?.('declarator')\n }\n if (declarator) {\n let current: Node | null = declarator\n while (current) {\n if (\n current.type === 'function_declarator' ||\n current.type === 'pointer_declarator' ||\n current.type === 'array_declarator' ||\n current.type === 'reference_declarator' ||\n current.type === 'parenthesized_declarator' ||\n current.type === 'init_declarator'\n ) {\n current = current.childForFieldName?.('declarator') ?? current.namedChildren[0] ?? null\n continue\n }\n if (current.type === 'qualified_identifier') {\n // app::inner::Widget::draw — the bare name is the deepest segment.\n return cppQualifiedSegments(current).at(-1) ?? ''\n }\n if (\n current.type === 'identifier' ||\n current.type === 'field_identifier' ||\n current.type === 'type_identifier'\n ) {\n return current.text.trim()\n }\n break\n }\n }\n return ''\n}\n\n/**\n * The nearest enclosing function/method node of a call site; module level\n * returns null. Anonymous function forms (arrow / function expression) are\n * owned by the variable they are assigned to (see {@link callableNameOf} and\n * {@link nearestDraftId}).\n */\nfunction enclosingCallableNode(id: LanguageId, node: Node): Node | null {\n const callable = CALLABLE_NODES[id]\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (callable.has(parent.type)) return parent\n }\n return null\n}\n\n/** Name of the function/method owning a callable node; '' when anonymous. */\nfunction callableNameOf(id: LanguageId, callable: Node): string {\n const named = nameOf(id, callable)\n if (named) return named\n const declaration = callable.parent\n if (declaration?.type === 'variable_declarator') {\n return declaration.childForFieldName?.('name')?.text.trim() ?? ''\n }\n return ''\n}\n\n/** Receiver/namespace text of a qualified call (`ns.foo()` -> \"ns\"), else null. */\nfunction qualifierOf(node: Node): string | null {\n const parent = node.parent\n if (!parent) return null\n let receiver: Node | null | undefined\n switch (parent.type) {\n case 'member_expression':\n case 'method_invocation':\n case 'attribute':\n receiver = parent.childForFieldName('object')\n break\n case 'selector_expression':\n receiver = parent.childForFieldName('operand')\n break\n case 'field_expression':\n receiver = parent.childForFieldName('value') ?? parent.childForFieldName('argument')\n break\n case 'qualified_identifier':\n case 'scoped_identifier':\n receiver = parent.childForFieldName('scope') ?? parent.childForFieldName('path')\n break\n default:\n return null\n }\n const text = receiver?.text.replace(/\\s+/g, ' ').trim()\n return text ? text : null\n}\n\n/** Structured import sites for a captured import/include/use statement. */\nfunction importInfoFor(id: LanguageId, node: Node): ImportInfo[] {\n const line = node.startPosition.row + 1\n switch (node.type) {\n case 'import_statement':\n return id === 'python' ? pythonModuleImports(node, line) : tsJsImports(node, line)\n case 'export_statement':\n return tsJsReexport(node, line)\n case 'import_from_statement':\n return pythonFromImport(node, line)\n case 'import_spec':\n return goImport(node, line)\n case 'use_declaration':\n return rustUse(node, line)\n case 'import_declaration':\n return javaImport(node, line)\n case 'preproc_include': {\n const specifier = stripQuotes(node.childForFieldName('path')?.text)\n return specifier ? [{ specifier, line, kind: 'include', bindings: [] }] : []\n }\n default:\n return []\n }\n}\n\nfunction tsJsImports(node: Node, line: number): ImportInfo[] {\n const specifier = stripQuotes(node.childForFieldName('source')?.text)\n if (!specifier) return []\n return [{ specifier, line, kind: 'import', bindings: importClauseBindings(node) }]\n}\n\nfunction importClauseBindings(node: Node): ImportBinding[] {\n const bindings: ImportBinding[] = []\n const clause = node.namedChildren.find((child) => child?.type === 'import_clause')\n if (!clause) return bindings\n for (const child of clause.namedChildren) {\n if (!child) continue\n if (child.type === 'identifier') {\n bindings.push({ imported: 'default', local: child.text.trim(), kind: 'default' })\n } else if (child.type === 'namespace_import') {\n const local = child.namedChildren.find((c) => c?.type === 'identifier')?.text.trim()\n if (local) bindings.push({ imported: '*', local, kind: 'namespace' })\n } else if (child.type === 'named_imports') {\n for (const spec of child.namedChildren) {\n if (spec?.type !== 'import_specifier') continue\n const imported = spec.childForFieldName('name')?.text.trim()\n if (!imported) continue\n const alias = spec.childForFieldName('alias')?.text.trim()\n bindings.push({ imported, local: alias ?? imported, kind: 'named' })\n }\n }\n }\n return bindings\n}\n\nfunction tsJsReexport(node: Node, line: number): ImportInfo[] {\n const specifier = stripQuotes(node.childForFieldName('source')?.text)\n if (!specifier) return []\n const bindings: ImportBinding[] = []\n const clause = node.namedChildren.find((child) => child?.type === 'export_clause')\n for (const spec of clause?.namedChildren ?? []) {\n if (spec?.type !== 'export_specifier') continue\n const imported = spec.childForFieldName('name')?.text.trim()\n if (!imported) continue\n const alias = spec.childForFieldName('alias')?.text.trim()\n bindings.push({ imported, local: alias ?? imported, kind: 'named' })\n }\n const namespaceExport = node.namedChildren.find((child) => child?.type === 'namespace_export')\n const local = namespaceExport?.namedChildren.find((c) => c?.type === 'identifier')?.text.trim()\n if (local) bindings.push({ imported: '*', local, kind: 'namespace' })\n return [{ specifier, line, kind: 'reexport', bindings }]\n}\n\nfunction pythonModuleImports(node: Node, line: number): ImportInfo[] {\n const out: ImportInfo[] = []\n for (const nameNode of node.childrenForFieldName('name')) {\n if (!nameNode) continue\n if (nameNode.type === 'aliased_import') {\n const moduleName = nameNode.childForFieldName('name')?.text.trim()\n const specifier = dottedToPath(moduleName)\n if (!specifier) continue\n const alias = nameNode.childForFieldName('alias')?.text.trim()\n out.push({\n specifier,\n line,\n kind: 'import',\n bindings: [\n { imported: moduleName ?? null, local: alias ?? moduleName ?? '', kind: 'namespace' },\n ],\n })\n } else if (nameNode.type === 'dotted_name') {\n const moduleName = nameNode.text.trim()\n const specifier = dottedToPath(moduleName)\n if (!specifier) continue\n out.push({\n specifier,\n line,\n kind: 'import',\n bindings: [{ imported: null, local: moduleName.split('.')[0] ?? moduleName, kind: 'package' }],\n })\n }\n }\n return out\n}\n\nfunction pythonFromImport(node: Node, line: number): ImportInfo[] {\n const raw = node.childForFieldName('module_name')?.text\n if (raw == null) return []\n const specifier = raw.startsWith('.') ? pythonRelative(raw) : dottedToPath(raw)\n if (!specifier) return []\n const moduleNode = node.childForFieldName('module_name')\n const bindings: ImportBinding[] = []\n for (const nameNode of node.namedChildren) {\n if (!nameNode || nameNode.id === moduleNode?.id) continue\n if (nameNode.type === 'aliased_import') {\n const imported = nameNode.childForFieldName('name')?.text.trim()\n if (!imported) continue\n const alias = nameNode.childForFieldName('alias')?.text.trim()\n bindings.push({ imported, local: alias ?? lastDotSegment(imported), kind: 'named' })\n } else if (nameNode.type === 'dotted_name') {\n const imported = nameNode.text.trim()\n bindings.push({ imported, local: lastDotSegment(imported), kind: 'named' })\n } else if (nameNode.type === 'wildcard_import') {\n bindings.push({ imported: '*', local: '*', kind: 'glob' })\n }\n }\n return [{ specifier, line, kind: 'import', bindings }]\n}\n\nfunction goImport(node: Node, line: number): ImportInfo[] {\n const specifier = stripQuotes(node.childForFieldName('path')?.text)\n if (!specifier) return []\n const nameNode = node.childForFieldName('name')\n let binding: ImportBinding\n if (!nameNode) {\n binding = { imported: null, local: lastSlashSegment(specifier), kind: 'package' }\n } else if (nameNode.type === 'dot') {\n binding = { imported: '*', local: '.', kind: 'glob' }\n } else {\n binding = { imported: null, local: nameNode.text.trim(), kind: 'package' }\n }\n return [{ specifier, line, kind: 'import', bindings: [binding] }]\n}\n\nfunction rustUse(node: Node, line: number): ImportInfo[] {\n const argument = node.childForFieldName('argument')\n if (!argument) return []\n const base = argument.type === 'use_as_clause' ? argument.childForFieldName('path') : argument\n const specifier = rustUsePath(base?.text ?? argument.text)\n if (!specifier) return []\n return [{ specifier, line, kind: 'use', bindings: rustBindings(argument) }]\n}\n\nfunction rustBindings(node: Node): ImportBinding[] {\n switch (node.type) {\n case 'scoped_identifier': {\n const imported = node.childForFieldName('name')?.text.trim()\n return imported ? [{ imported, local: imported, kind: 'named' }] : []\n }\n case 'identifier': {\n const name = node.text.trim()\n return name ? [{ imported: name, local: name, kind: 'named' }] : []\n }\n case 'use_as_clause': {\n const path = node.childForFieldName('path')\n const alias = node.childForFieldName('alias')?.text.trim()\n const imported = path ? rustLeafName(path) : null\n return imported && alias ? [{ imported, local: alias, kind: 'named' }] : []\n }\n case 'scoped_use_list': {\n const bindings: ImportBinding[] = []\n for (const item of node.childForFieldName('list')?.namedChildren ?? []) {\n if (item) bindings.push(...rustBindings(item))\n }\n return bindings\n }\n case 'use_wildcard':\n return [{ imported: '*', local: '*', kind: 'glob' }]\n default:\n return []\n }\n}\n\nfunction rustLeafName(node: Node): string | null {\n if (node.type === 'identifier') return node.text.trim()\n return node.childForFieldName('name')?.text.trim() ?? null\n}\n\nfunction javaImport(node: Node, line: number): ImportInfo[] {\n const path = node.namedChildren.find((child) => child?.type === 'scoped_identifier')\n const specifier = dottedToPath(path?.text)\n if (!specifier) return []\n const wildcard = node.namedChildren.some((child) => child?.type === 'asterisk')\n if (wildcard) {\n return [\n { specifier, line, kind: 'import', bindings: [{ imported: '*', local: '*', kind: 'glob' }] },\n ]\n }\n const imported = path?.childForFieldName('name')?.text.trim() ?? lastSlashSegment(specifier)\n const isStatic = /^import\\s+static\\b/.test(node.text)\n return [\n {\n specifier,\n line,\n kind: 'import',\n bindings: [{ imported, local: imported, kind: isStatic ? 'static' : 'named' }],\n },\n ]\n}\n\nfunction lastDotSegment(value: string): string {\n return value.split('.').pop() ?? value\n}\n\nfunction lastSlashSegment(value: string): string {\n return value.split('/').pop() ?? value\n}\n\n/**\n * Rust use paths: 'crate::a::b' is root-relative, 'super::x' is parent-module\n * ('../x'), 'self::x' is current ('./x'); everything else (std, external\n * crates) stays root-relative and simply won't resolve in-repo. Use-lists\n * ('a::b::{c,d}') contribute their base path.\n */\nfunction rustUsePath(text: string | undefined | null): string | null {\n if (!text) return null\n const base = text.split('{')[0].trim()\n if (!base) return null\n const parts = base.split('::').filter(Boolean)\n if (parts[0] === 'crate') parts.shift()\n return parts.map((p) => (p === 'super' ? '..' : p === 'self' ? '.' : p)).join('/')\n}\n\nfunction stripQuotes(text: string | undefined | null): string | null {\n if (text == null || text.length < 2) return null\n const first = text[0]\n const last = text[text.length - 1]\n if ((first === \"'\" && last === \"'\") || (first === '\"' && last === '\"')) {\n return text.slice(1, -1)\n }\n return null\n}\n\n/** 'os.path' → 'os/path' — dotted module path to repo-relative-ish path. */\nfunction dottedToPath(text: string | undefined | null): string | null {\n if (!text) return null\n return text.trim().replace(/\\./g, '/')\n}\n\n/** '.utils' → './utils', '..pkg.mod' → '../pkg/mod' — python relative import. */\nfunction pythonRelative(raw: string): string {\n const dots = raw.match(/^\\.+/)?.[0].length ?? 0\n const rest = raw.slice(dots).replace(/\\./g, '/')\n const prefix = dots === 1 ? './' : '../'.repeat(dots - 1)\n return prefix + rest\n}\n\n/** Best-effort declaration signature: `name` + parameter list, if any. */\nfunction signatureFor(id: LanguageId, node: Node): string {\n const sig = rawSignature(id, node)\n return sig.length > 80 ? `${sig.slice(0, 77)}...` : sig\n}\n\nfunction rawSignature(id: LanguageId, node: Node): string {\n const name = nameOf(id, node)\n // Field first (go method_declaration has both a receiver and a parameters\n // parameter_list — the field picks the right one), type fallback otherwise.\n const params =\n node.childForFieldName?.('parameters') ??\n node.namedChildren.find(\n (c) =>\n c?.type === 'formal_parameters' ||\n c?.type === 'method_parameters' ||\n c?.type === 'parameters' ||\n c?.type === 'parameter_list',\n )\n if (params) {\n return `${name}${collapseSpace(params.text)}`\n }\n if (id === 'cpp' || id === 'c') {\n // C/C++: the parameter list hides inside the declarator chain.\n let current = node.childForFieldName?.('declarator')\n while (current) {\n if (current.type === 'function_declarator') {\n const list = current.childForFieldName?.('parameters')\n return list ? `${name}${collapseSpace(list.text)}` : name\n }\n current = current.childForFieldName?.('declarator') ?? current.namedChildren[0] ?? null\n if (current && !current.type.includes('declarator') && current.type !== 'identifier' && current.type !== 'qualified_identifier' && current.type !== 'field_identifier') break\n }\n }\n const first = node.namedChildren[0]\n return first ? collapseSpace(first.text) : name\n}\n\n/**\n * Signatures must stay one line: repo-map rows are budgeted per line, and a\n * multi-line parameter list would both wrap the format and burn chars.\n */\nfunction collapseSpace(text: string): string {\n return text\n .replace(/\\s+/g, ' ')\n .replace(/\\( /g, '(')\n .replace(/ \\)/g, ')')\n .replace(/ ,/g, ',')\n .replace(/,\\)/g, ')')\n .trim()\n}\n\n/**\n * A variable is indexable only at module level: its declaration must sit\n * directly inside the program (or the export_statement wrapping it). Anything\n * deeper — function bodies, blocks, for-of heads — is a local with no\n * navigation value.\n */\nfunction isModuleLevelVariable(id: LanguageId, node: Node): boolean {\n if (id === 'cpp' || id === 'c') {\n // A (field_)declaration is indexable at namespace/file scope or in a\n // class body — anything inside a function body is a local.\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (parent.type === 'function_definition' || parent.type === 'compound_statement') return false\n if (parent.type === 'translation_unit' || parent.type === 'declaration_list' || parent.type === 'field_declaration_list') return true\n }\n return false\n }\n const declaration = node.parent // variable_declaration | lexical_declaration\n const container = declaration?.parent // program | export_statement | …\n return container?.type === 'program' || container?.type === 'export_statement'\n}\n\n/**\n * A symbol is exported when walking up from it reaches an export_statement\n * before any function or class body — only module-level declarations count.\n * A method inside `export class` must NOT inherit the class's export, and a\n * function nested inside an exported function is not exported either.\n */\nfunction isExported(id: LanguageId, node: Node): boolean {\n if (id === 'python') {\n // Python has no export syntax: a def/class directly under the module is\n // importable, anything nested (methods, inner functions) is not a\n // module-level symbol.\n return node.parent?.type === 'module'\n }\n if (id === 'go') {\n // Go exports by capitalisation, not by keyword.\n const name = nameOf(id, node)\n return !!name && /^[A-Z]/.test(name)\n }\n if (id === 'rust') {\n // `pub` = exported; `pub(crate)` & friends are crate-local, not public.\n return node.namedChildren.some(\n (c) => c?.type === 'visibility_modifier' && c.text === 'pub',\n )\n }\n if (id === 'java') {\n // Interface members are implicitly public.\n if (node.parent?.type === 'interface_body') return true\n return node.namedChildren.some((c) => c?.type === 'modifiers' && /\\bpublic\\b/.test(c?.text ?? ''))\n }\n if (id === 'cpp' || id === 'c') {\n return cppIsExported(node)\n }\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (parent.type === 'export_statement') return true\n if (parent.type === 'statement_block' || parent.type === 'class_body') return false\n if (parent.type === 'program') return false\n }\n return false\n}\n\n/**\n * C/C++ export semantics:\n * - anything under `public:` in a class body is exported; `private:`/\n * `protected:` sections are not\n * - top-level declarations are exported unless marked `static`\n * (internal-linkage). C has no access sections; C++ namespaces stay\n * transparent — a symbol under namespace X is still module-level.\n */\nfunction cppIsExported(node: Node): boolean {\n const isStatic = node.namedChildren.some(\n (c) => c?.type === 'storage_class_specifier' && c.text === 'static',\n )\n for (let parent = node.parent; parent; parent = parent.parent) {\n if (parent.type === 'field_declaration_list') {\n const body = parent\n // Struct members default to public, class members to private (C++ rule).\n const structKind = body.parent?.type === 'struct_specifier' ? 'struct' : 'class'\n let current: string | null = structKind === 'struct' ? 'public' : 'private'\n for (let up: Node | null = node; up && up.id !== body.id; up = up.parent) {\n const next = up.parent\n if (next?.type === 'field_declaration_list') {\n const siblingIndex = next.namedChildren.findIndex((c) => c?.id === up.id)\n const accessBefore = next.namedChildren\n .slice(0, siblingIndex)\n .filter((c) => c?.type === 'access_specifier')\n if (accessBefore.length > 0) {\n current = accessBefore.at(-1)!.text.replace(':', '').trim()\n }\n }\n }\n return current === 'public' && !isStatic\n }\n if (parent.type === 'translation_unit') return !isStatic\n }\n return !isStatic\n}\n\n/**\n * Language quirks the query syntax can't express:\n * - python: no distinct method node — a def directly in a class body is one\n * - go: a type_spec is a class (struct) or interface by its type child\n * - rust: function_item directly in an impl body is a method\n */\nfunction kindFor(id: LanguageId, node: Node, kind: SymbolKind): SymbolKind {\n if (id === 'python' && kind === 'function') {\n const inClassBody = node.parent?.type === 'block' && node.parent?.parent?.type === 'class_definition'\n if (inClassBody) return 'method'\n }\n if (id === 'go' && node.type === 'type_spec') {\n const type = node.childForFieldName('type')?.type\n if (type === 'struct_type') return 'class'\n if (type === 'interface_type') return 'interface'\n return 'type'\n }\n if (id === 'rust' && node.type === 'function_item') {\n const inImpl = node.parent?.type === 'declaration_list' && node.parent?.parent?.type === 'impl_item'\n if (inImpl) return 'method'\n }\n if ((id === 'cpp' || id === 'c') && (kind === 'variable' || kind === 'field')) {\n // A declaration whose declarator chain holds a function_declarator is a\n // function prototype/definition — not a data member or global.\n let current = node.childForFieldName?.('declarator')\n while (current) {\n if (current.type === 'function_declarator') {\n return node.parent?.type === 'field_declaration_list' ? 'method' : 'function'\n }\n current = current.childForFieldName?.('declarator') ?? current.namedChildren[0] ?? null\n }\n return node.type === 'field_declaration' ? 'field' : 'variable'\n }\n if ((id === 'cpp' || id === 'c') && node.type === 'function_definition') {\n // A function defined directly in a class/struct body is a method.\n if (node.parent?.type === 'field_declaration_list') return 'method'\n }\n return kind\n}\n\n/** Compile a symbol query for a code sample (used by tests). */\nexport async function parseFileToSymbols(\n filePath: string,\n repoRoot: string,\n code?: string,\n): Promise<SymbolInfo[]> {\n const lang = languageForFile(filePath)\n if (!lang) return []\n const text = code ?? (await readFile(filePath, 'utf8'))\n const rel = path.relative(repoRoot, filePath).split(path.sep).join('/')\n const { symbols } = await extractAll(text, lang, rel)\n return symbols\n}","/** Workspace file discovery with dir exclusions and mtime tracking. */\n\nimport { readFile, readdir, stat } from 'node:fs/promises'\nimport { readFileSync, statSync } from 'node:fs'\nimport path from 'node:path'\nimport ignore from 'ignore'\nimport type { IndexOptions } from './types.js'\n\nexport const DEFAULT_EXCLUDED_DIRS = [\n 'node_modules',\n '.git',\n '.idea',\n '.vscode',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.next',\n '.nuxt',\n '.cache',\n 'target',\n 'vendor',\n '.dsh-code-index',\n]\n\n/** Language-agnostic source extensions we index. */\nexport const SUPPORTED_EXTS = new Set([\n '.ts',\n '.tsx',\n '.mts',\n '.cts',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.py',\n '.pyi',\n '.go',\n '.rs',\n '.java',\n '.cpp',\n '.cc',\n '.cxx',\n '.c++',\n '.hpp',\n '.hxx',\n '.hh',\n '.h',\n '.ipp',\n '.tpp',\n '.inl',\n '.c',\n])\n\nexport type GitIgnoreMatcherCache = Map<string, {\n mtimeMs: number\n size: number\n matcher: ReturnType<typeof ignore>\n}>\n\n/** Check root and nested Git ignore rules for a repo-relative path. */\nexport function isGitIgnoredPath(\n root: string,\n relativePath: string,\n cache: GitIgnoreMatcherCache = new Map(),\n): boolean {\n const rel = relativePath.replace(/\\\\/g, '/').replace(/^\\.\\//, '')\n if (!rel) return false\n const parentParts = rel.split('/').slice(0, -1)\n for (let depth = 0; depth <= parentParts.length; depth += 1) {\n const base = parentParts.slice(0, depth).join('/')\n const ignoreFile = path.join(root, base, '.gitignore')\n let fileStat\n try {\n fileStat = statSync(ignoreFile)\n } catch {\n continue\n }\n const previous = cache.get(ignoreFile)\n let matcher = previous?.matcher\n if (!previous || previous.mtimeMs !== fileStat.mtimeMs || previous.size !== fileStat.size) {\n try {\n matcher = ignore().add(readFileSync(ignoreFile, 'utf8'))\n cache.set(ignoreFile, { mtimeMs: fileStat.mtimeMs, size: fileStat.size, matcher })\n } catch {\n cache.delete(ignoreFile)\n continue\n }\n }\n const scoped = base ? path.posix.relative(base, rel) : rel\n if (matcher?.ignores(scoped)) return true\n }\n return false\n}\n\nexport interface ScannedFile {\n /** Absolute path on disk. */\n abs: string\n /** Repo-relative path (forward-slash). */\n rel: string\n mtimeMs: number\n}\n\n/**\n * Recursively walk `root` and return indexed files, skipping excluded dir\n * components at any depth. Uses readdir with `withFileTypes` so we never\n * stat every entry; mtime comes from a targeted stat per candidate file.\n */\nexport async function scanRepo(\n root: string,\n options: IndexOptions = {},\n): Promise<ScannedFile[]> {\n const excluded = new Set([...DEFAULT_EXCLUDED_DIRS, ...(options.excludeDirs ?? [])])\n const results: ScannedFile[] = []\n type IgnoreLayer = { base: string; matcher: ReturnType<typeof ignore> }\n const queue: Array<[string, string, IgnoreLayer[]]> = [[root, '', []]] // [absDir, relDir, inherited ignore files]\n\n while (queue.length) {\n const [absDir, relDir, inherited] = queue.pop()!\n let layers = inherited\n try {\n const rules = await readFile(path.join(absDir, '.gitignore'), 'utf8')\n layers = [...inherited, { base: relDir, matcher: ignore().add(rules) }]\n } catch {\n // Missing or unreadable ignore file does not prevent indexing.\n }\n const ignoredByGit = (relativePath: string): boolean => layers.some(({ base, matcher }) => {\n const scoped = base ? path.posix.relative(base, relativePath) : relativePath\n return scoped !== '..' && !scoped.startsWith('../') && matcher.ignores(scoped)\n })\n let entries\n try {\n entries = await readdir(absDir, { withFileTypes: true })\n } catch {\n continue // unreadable dir: skip into the void\n }\n for (const entry of entries) {\n const abs = path.join(absDir, entry.name)\n const rel = relDir ? `${relDir}/${entry.name}` : entry.name\n if (entry.isDirectory()) {\n if (excluded.has(entry.name)) continue\n if (!ignoredByGit(rel)) queue.push([abs, rel, layers])\n } else if (entry.isFile() && !ignoredByGit(rel) && SUPPORTED_EXTS.has(path.extname(entry.name).toLowerCase())) {\n try {\n const st = await stat(abs)\n results.push({ abs, rel, mtimeMs: st.mtimeMs })\n } catch {\n // race: file deleted mid-scan — ignore\n }\n }\n }\n }\n\n results.sort((a, b) => a.rel.localeCompare(b.rel))\n return results\n}\n","/** On-disk JSON cache for RepoIndex, keyed by repo root. */\n\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { createHash, randomUUID } from 'node:crypto'\nimport { REPO_INDEX_SCHEMA_VERSION, type RepoIndex } from './types.js'\n\nexport const CACHE_DIR_NAME = '.dsh-code-index'\n\n/** Stable root identity for cache hashing, including Windows case aliases. */\nexport function cacheKeyForRoot(root: string): string {\n const resolved = path.resolve(root)\n return process.platform === 'win32' ? resolved.toLowerCase() : resolved\n}\n\n/** Default cache location: `<repoRoot>/.dsh-code-index/index.json`. */\nexport function defaultCachePath(root: string, cacheDir?: string): string {\n const dir = cacheDir ?? path.join(root, CACHE_DIR_NAME)\n const hash = createHash('sha1').update(cacheKeyForRoot(root)).digest('hex').slice(0, 12)\n return path.join(dir, `${hash}.json`)\n}\n\n/** Cache filename used before Windows root casing was canonicalized. */\nexport function legacyCachePath(root: string, cacheDir?: string): string {\n const dir = cacheDir ?? path.join(root, CACHE_DIR_NAME)\n const hash = createHash('sha1').update(root).digest('hex').slice(0, 12)\n return path.join(dir, `${hash}.json`)\n}\n\nexport async function loadIndex(cachePath: string): Promise<RepoIndex | null> {\n try {\n const raw = await readFile(cachePath, 'utf8')\n const parsed = JSON.parse(raw) as RepoIndex\n if (!parsed || typeof parsed.root !== 'string' || !Array.isArray(parsed.files)) return null\n // Reject caches from an older layout instead of partially healing graph\n // data — the build path reconstructs them at the same path.\n if (parsed.schemaVersion !== REPO_INDEX_SCHEMA_VERSION) return null\n return healSymbolFiles(parsed)\n } catch {\n return null // missing or corrupt cache == no cache\n }\n}\n\n/**\n * Self-heal caches written before the per-symbol file backfill (the\n * \"SymbolInfo.file is always set\" invariant). Empty `file` fields are derived\n * from the containing IndexedFile path on load, so any consumer of loadIndex\n * sees consistent rows — and the next save persists the healed form.\n */\nexport function healSymbolFiles(index: RepoIndex): RepoIndex {\n for (const file of index.files) {\n for (const symbol of file.symbols) {\n if (!symbol.file) symbol.file = file.path\n }\n }\n return index\n}\n\nexport async function saveIndex(cachePath: string, index: RepoIndex): Promise<void> {\n await mkdir(path.dirname(cachePath), { recursive: true })\n const temporaryPath = `${cachePath}.${process.pid}.${randomUUID()}.tmp`\n try {\n await writeFile(temporaryPath, JSON.stringify(index, null, 2), { encoding: 'utf8', flag: 'wx' })\n await rename(temporaryPath, cachePath)\n } finally {\n await rm(temporaryPath, { force: true })\n }\n}\n","/** Shared data model for dsh-code-index. */\n\n/** On-disk cache layout version. Bump when persisted graph/symbol shapes change. */\nexport const REPO_INDEX_SCHEMA_VERSION = 2 as const\n\nexport type SymbolKind =\n | 'function'\n | 'method'\n | 'class'\n | 'interface'\n | 'type'\n | 'enum'\n | 'variable'\n | 'field'\n | 'import'\n | 'module'\n\n/** Stable, file-qualified symbol identity: `sym:v1:<file>#<scope>/<segment>`. */\nexport type SymbolId = string\n\n/** Vocabulary for one scope segment in a qualified symbol id. */\nexport type ScopeKind =\n | 'module'\n | 'namespace'\n | 'class'\n | 'interface'\n | 'trait'\n | 'impl'\n | 'function'\n | 'method'\n | 'owner'\n\nexport interface SymbolScopePart {\n kind: ScopeKind\n name: string\n /** 1-based among sibling scope owners with the same kind and name. */\n ordinal: number\n}\n\nexport interface SymbolInfo {\n /** Stable qualified id; unique within a RepoIndex. */\n id: SymbolId\n /** Symbol name (identifier / type id / member name). */\n name: string\n kind: SymbolKind\n /** Repo-relative path of the containing file, always forward-slash. */\n file: string\n /** 1-based start line. */\n line: number\n /** 1-based end line (inclusive). */\n endLine: number\n /** True when the symbol is exported at module level (export .. / export default). */\n exported: boolean\n /** Short human-readable signature, e.g. `greet(name: string)` — empty when n/a. */\n signature: string\n /** Owners only; excludes the symbol itself. Empty at module level. */\n scope: SymbolScopePart[]\n /** 1-based among symbols with the same scope, kind, and name. */\n ordinal: number\n}\n\n/** One name bound by an import statement, with its local alias. */\nexport interface ImportBinding {\n /** Imported name: \"foo\" | \"default\" | \"*\" | null (namespace/package). */\n imported: string | null\n /** Name visible in this file (alias when renamed). */\n local: string\n kind: 'named' | 'default' | 'namespace' | 'package' | 'static' | 'glob'\n}\n\n/** Structured form of one import/include/use site. */\nexport interface ImportInfo {\n specifier: string\n line: number\n kind: 'import' | 'reexport' | 'include' | 'use'\n bindings: ImportBinding[]\n}\n\n/** One call site: callee name, line, and enclosing function ('' = module level). */\nexport interface CallInfo {\n /** Callee name as written (identifier, member/property, or qualified tail). */\n name: string\n /** 1-based line of the call expression. */\n line: number\n /** Enclosing function/method name, or '' for a module-level call. */\n from: string\n /** Structural owner from AST containment; null at module level. */\n fromId: SymbolId | null\n /** Receiver/namespace text when available: `ns.foo()` -> \"ns\"; bare -> null. */\n qualifier: string | null\n}\n\nexport interface IndexedFile {\n /** Repo-relative path (forward-slash). */\n path: string\n lang: string\n /** fs mtime of the source file at index time (milliseconds). */\n mtimeMs: number\n symbols: SymbolInfo[]\n /** Derived compatibility view of {@link importDetails} specifiers. */\n imports?: string[]\n /** Structured import/include/use sites with their name bindings. */\n importDetails?: ImportInfo[]\n /** Call sites found in this file (callee + line + enclosing function).\n * Optional because caches written before call-graph support lack it. */\n calls?: CallInfo[]\n}\n\nexport interface RepoIndex {\n /** Persisted layout version; see {@link REPO_INDEX_SCHEMA_VERSION}. */\n schemaVersion: typeof REPO_INDEX_SCHEMA_VERSION\n /** Absolute source root this index describes. */\n root: string\n /** Unix ms when the index was generated. */\n generatedAt: number\n files: IndexedFile[]\n excludedDirs: string[]\n}\n\nexport function symbolCount(index: RepoIndex): number {\n return index.files.reduce((n, f) => n + f.symbols.length, 0)\n}\n\n/** Optional config consumed by the index build pipeline. */\nexport interface IndexOptions {\n /** Extra directories to exclude, appended to the defaults. */\n excludeDirs?: string[]\n /** Minimum mtime delta (ms) that forces a re-extract in refresh mode. */\n staleToleranceMs?: number\n}","/**\n * Bounded, ranked repo map generation — the \"aider-style\" overview the model\n * can turn to before browsing files. Pure logic, no IO.\n */\n\nimport path from 'node:path'\nimport { SUPPORTED_EXTS } from './scan.js'\nimport type { IndexedFile, RepoIndex, SymbolKind } from './types.js'\n\n/** Higher-weight symbols pull their file up the map. */\nexport const KIND_WEIGHT: Record<SymbolKind, number> = {\n class: 1.0,\n interface: 1.0,\n type: 0.8,\n function: 0.8,\n method: 0.7,\n enum: 0.9,\n variable: 0.25,\n field: 0.2,\n import: 0.05,\n module: 0.3,\n}\n\nexport interface RepoMapOptions {\n /** Max files to include (default 24). */\n topFiles?: number\n /** Max symbols per file (default 18). */\n symbolsPerFile?: number\n /** Hard cap on rendered characters (default 3200). */\n maxChars?: number\n}\n\nexport interface RepoMapEntry {\n path: string\n score: number\n symbols: Array<{ name: string; kind: SymbolKind; line: number; signature: string }>\n}\n\n/**\n * Paths that look like tests. A map led by test files reads as noise: tests\n * reference an API, they rarely explain it — and symbol density actively\n * favours them (many small functions), so they need an explicit damper.\n */\nconst TEST_PATH_RE =\n /(^|\\/)(tests?|__tests__)(\\/|$)|\\.(?:spec|test)\\.[cm]?[jt]sx?$|(^|\\/)(?:test_[^/]+\\.py|[^/]+_test\\.(?:py|go))$/\n\n/** Density-aware file score: weighted symbols minus bloat; test paths damped. */\nexport function scoreFile(file: IndexedFile): number {\n let score = 0\n for (const sym of file.symbols) {\n score += KIND_WEIGHT[sym.kind] ?? 0.3\n if (sym.exported) score += 0.3\n }\n score /= 1 + file.symbols.length * 0.04\n if (TEST_PATH_RE.test(file.path)) score *= 0.2\n return score\n}\n\n/** Rank files, take the top slice, cap per-file symbols. */\nexport function rankRepoMap(index: RepoIndex, options: RepoMapOptions = {}): RepoMapEntry[] {\n const topFiles = options.topFiles ?? 24\n const perFile = options.symbolsPerFile ?? 18\n const density = new Map<string, number>()\n for (const f of index.files) {\n if (f.symbols.length > 0) density.set(f.path, scoreFile(f))\n }\n const centrality = referencePageRank(index.files, density)\n const ranked = index.files\n .filter((f) => f.symbols.length > 0)\n .map((f) => ({\n file: f,\n score: (density.get(f.path) ?? 0) + REF_WEIGHT * (centrality.get(f.path) ?? 0),\n }))\n .sort((a, b) => b.score - a.score || a.file.path.localeCompare(b.file.path))\n .slice(0, topFiles)\n\n return ranked.map(({ file, score }) => ({\n path: file.path,\n score,\n symbols: file.symbols.slice(0, perFile).map((s) => ({\n name: s.name,\n kind: s.kind,\n line: s.line,\n signature: s.signature,\n })),\n }))\n}\n\n/** How much one unit of reference centrality is worth in map score. */\nconst REF_WEIGHT = 0.5\n\n/**\n * Count in-repo references: how many OTHER indexed files import each file.\n * Self-imports don't count; each (importer, target) pair counts once.\n */\nexport function countReferences(files: IndexedFile[]): Map<string, number> {\n const fileSet = new Set(files.map((f) => f.path))\n const counts = new Map<string, number>()\n for (const file of files) {\n const targets = new Set<string>()\n for (const spec of file.imports ?? []) {\n const target = resolveImport(spec, file.path, fileSet)\n if (target && target !== file.path) targets.add(target)\n }\n for (const target of targets) {\n counts.set(target, (counts.get(target) ?? 0) + 1)\n }\n }\n return counts\n}\n\n/** PageRank damping — the standard 0.85. */\nconst DAMPING = 0.85\n/** Stop the power iteration once total rank movement drops below this. */\nconst CONVERGENCE_TOL = 1e-6\n/** Hard cap; convergence on repo-sized graphs needs ~20-40. */\nconst MAX_ITERATIONS = 100\n\n/**\n * Personalized PageRank over the import graph: nodes are files, an edge\n * A → B means A imports B, so rank flows toward heavily-imported hubs — and\n * a hub that other hubs themselves import accumulates more than a merely\n * popular leaf, which flat in-degree counting cannot see.\n *\n * Teleport uses each file's density share instead of a uniform vector, so\n * sparsely-linked repos keep their 0.2.x ordering (with no edges the fixed\n * point IS the normalized density vector). Returns L1-normalized importance\n * mass per file.\n */\nfunction referencePageRank(files: IndexedFile[], density: Map<string, number>): Map<string, number> {\n const nodes = files.filter((f) => density.has(f.path)).map((f) => f.path)\n const n = nodes.length\n if (n === 0) return new Map()\n if (n === 1) return new Map([[nodes[0]!, 1]])\n\n const totalDensity = nodes.reduce((sum, p) => sum + (density.get(p) ?? 0), 0)\n const teleport = nodes.map((p) => (density.get(p) ?? 0) / totalDensity)\n\n const fileSet = new Set(nodes)\n const out = new Map<string, Set<string>>()\n for (const file of files) {\n if (!fileSet.has(file.path)) continue\n const targets = out.get(file.path) ?? new Set<string>()\n for (const spec of file.imports ?? []) {\n const target = resolveImport(spec, file.path, fileSet)\n if (target && target !== file.path) targets.add(target)\n }\n out.set(file.path, targets)\n }\n\n const incoming = new Map<string, Array<[fromIdx: number, weight: number]>>()\n for (const [from, targets] of out) {\n if (targets.size === 0) continue\n const weight = 1 / targets.size\n const fromIdx = nodes.indexOf(from)\n for (const target of targets) {\n const list = incoming.get(target) ?? []\n list.push([fromIdx, weight])\n incoming.set(target, list)\n }\n }\n\n let rank = teleport.slice()\n for (let iter = 0; iter < MAX_ITERATIONS; iter++) {\n let danglingMass = 0\n for (let i = 0; i < n; i++) {\n if (!out.get(nodes[i]!)?.size) danglingMass += rank[i]!\n }\n const next = new Array<number>(n)\n let delta = 0\n for (let i = 0; i < n; i++) {\n let flow = 0\n for (const [fromIdx, weight] of incoming.get(nodes[i]!) ?? []) {\n flow += rank[fromIdx]! * weight\n }\n next[i] = (1 - DAMPING) * teleport[i]! + DAMPING * (flow + danglingMass * teleport[i]!)\n delta += Math.abs(next[i]! - rank[i]!)\n }\n rank = next\n if (delta < CONVERGENCE_TOL) break\n }\n\n const result = new Map<string, number>()\n for (let i = 0; i < n; i++) result.set(nodes[i]!, rank[i]!)\n return result\n}\n\n/** Outcome of {@link resolveImportDetailed}: the target plus how it matched. */\nexport interface ImportResolution {\n target: string | null\n /**\n * True when only the nested-segment suffix fallback matched (Go module paths,\n * Java packages). Callers that must not over-claim can use this to keep a\n * fuzzy match weaker; the NodeNext `.js`/`.jsx`/`.mjs`/`.cjs` → TS-source\n * substitution at skip 0 is a direct hit, not a fallback.\n */\n suffixSkipped: boolean\n}\n\n/**\n * Resolve a raw import specifier against the indexed file set, reporting both\n * the repo-relative target and whether the nested-segment suffix fallback was\n * needed. Relative specifiers resolve against the importing file; absolute\n * ones against the repo root — the suffix fallback lets Go module paths and\n * Java package names match their in-repo location without reading go.mod /\n * package-info.\n */\nexport function resolveImportDetailed(\n spec: string,\n fromPath: string,\n fileSet: Set<string>,\n): ImportResolution {\n if (!spec) return { target: null, suffixSkipped: false }\n if (spec.startsWith('./') || spec.startsWith('../')) {\n const base = path.posix.normalize(path.posix.join(path.posix.dirname(fromPath), spec))\n return { target: candidateFor(base, fileSet), suffixSkipped: false }\n }\n const segments = spec.split('/').filter(Boolean)\n for (let skip = 0; skip < segments.length; skip++) {\n const hit = candidateFor(segments.slice(skip).join('/'), fileSet)\n if (hit) return { target: hit, suffixSkipped: skip > 0 }\n }\n return { target: null, suffixSkipped: false }\n}\n\n/** Thin wrapper over {@link resolveImportDetailed} returning just the target. */\nexport function resolveImport(spec: string, fromPath: string, fileSet: Set<string>): string | null {\n return resolveImportDetailed(spec, fromPath, fileSet).target\n}\n\n/** Extension and index-file candidates for a specifier base path. */\nfunction candidateFor(base: string, fileSet: Set<string>): string | null {\n // Bare path first: C/C++ includes already carry their extension\n // (\"net/socket.hpp\"), and matching the exact file beats guessing.\n if (fileSet.has(base)) return base\n for (const ext of SUPPORTED_EXTS) {\n if (fileSet.has(`${base}${ext}`)) return `${base}${ext}`\n }\n // TS 5 / NodeNext ESM: a local import is written with the *emitted* extension\n // ('./util.js') while the source on disk is './util.ts'. Map the JS family\n // back to its TypeScript source before falling through to directory indexes.\n const aliased = tsSourceForJsSpecifier(base, fileSet)\n if (aliased) return aliased\n for (const ext of SUPPORTED_EXTS) {\n if (fileSet.has(`${base}/index${ext}`)) return `${base}/index${ext}`\n if (fileSet.has(`${base}/__init__${ext}`)) return `${base}/__init__${ext}`\n }\n return null\n}\n\n/** Resolve a JS-extension specifier ('.js/.jsx/.mjs/.cjs') to on-disk TS source. */\nfunction tsSourceForJsSpecifier(base: string, fileSet: Set<string>): string | null {\n const match = /\\.(js|jsx|mjs|cjs)$/.exec(base)\n if (!match) return null\n const stem = base.slice(0, base.length - match[0].length)\n const candidates =\n match[1] === 'jsx'\n ? ['.tsx', '.ts']\n : match[1] === 'mjs'\n ? ['.mts', '.ts']\n : match[1] === 'cjs'\n ? ['.cts', '.ts']\n : ['.ts', '.tsx']\n for (const ext of candidates) {\n if (fileSet.has(`${stem}${ext}`)) return `${stem}${ext}`\n }\n return null\n}\n\n/** Render the ranked map as markdown, hard-truncated to maxChars. */\nexport function renderRepoMap(entries: RepoMapEntry[], options: RepoMapOptions = {}): string {\n const maxChars = options.maxChars ?? 3200\n const lines: string[] = ['# repo map']\n let totalSymbols = 0\n for (const e of entries) {\n totalSymbols += e.symbols.length\n lines.push(`## ${e.path} (${e.symbols.length})`)\n for (const s of e.symbols) {\n const label = s.signature || s.name\n lines.push(` ${s.kind} ${label} :${s.line}`)\n }\n }\n let text = lines.join('\\n')\n if (text.length > maxChars) {\n text = `${text.slice(0, maxChars)}\\n… truncated`\n }\n return totalSymbols > 0 ? text : ''\n}","/** Function-level call graph built from the cached index — pure, no IO. */\n\nimport { resolveImport, resolveImportDetailed } from './repomap.js'\nimport type {\n CallInfo,\n ImportBinding,\n IndexedFile,\n RepoIndex,\n SymbolId,\n SymbolInfo,\n} from './types.js'\n\n/** name -> definitions; several when same-named symbols live in different files. */\nexport function buildSymbolTable(index: RepoIndex): Map<string, SymbolInfo[]> {\n const table = new Map<string, SymbolInfo[]>()\n for (const file of index.files) {\n for (const symbol of file.symbols) {\n const list = table.get(symbol.name)\n if (list) list.push(symbol)\n else table.set(symbol.name, [symbol])\n }\n }\n for (const list of table.values()) {\n list.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line)\n }\n return table\n}\n\n/** One call site that invokes the queried symbol. */\nexport interface CallerHit {\n file: string\n line: number\n from: string\n}\n\n/** One distinct symbol the queried function calls, with its first call line. */\nexport interface CalleeHit {\n name: string\n line: number\n /** In-repo definitions matched by the callee name. */\n targets: SymbolInfo[]\n}\n\nexport interface SymbolRefs {\n /** Definitions of the queried symbol (empty when only call sites exist). */\n defs: SymbolInfo[]\n callers: CallerHit[]\n callees: CalleeHit[]\n}\n\n/** How many call sites reference each name — used to rank search hits. */\nexport function callerCounts(index: RepoIndex): Map<string, number> {\n const counts = new Map<string, number>()\n for (const file of index.files) {\n for (const call of file.calls ?? []) {\n counts.set(call.name, (counts.get(call.name) ?? 0) + 1)\n }\n }\n return counts\n}\n\n/**\n * Resolve one symbol to its callers (call sites invoking it anywhere) and its\n * callees (calls made inside the definition, attributed by the extracted\n * enclosing-function name). Name-based, so it is a best-effort view: like-named\n * symbols are reported as candidates rather than guessed apart.\n */\nexport function symbolRefs(index: RepoIndex, symbol: string, limit = 200): SymbolRefs {\n const table = buildSymbolTable(index)\n const defs = table.get(symbol) ?? []\n\n const callers: CallerHit[] = []\n const calleeFirstLine = new Map<string, number>()\n for (const file of index.files) {\n for (const call of file.calls ?? []) {\n if (call.name === symbol) {\n callers.push({ file: file.path, line: call.line, from: call.from })\n }\n if (call.from === symbol && !calleeFirstLine.has(call.name)) {\n calleeFirstLine.set(call.name, call.line)\n }\n }\n }\n\n callers.sort(\n (a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.from.localeCompare(b.from),\n )\n\n const callees: CalleeHit[] = [...calleeFirstLine.entries()]\n .map(([name, line]) => ({ name, line, targets: table.get(name) ?? [] }))\n .sort((a, b) => a.line - b.line || a.name.localeCompare(b.name))\n\n return {\n defs,\n callers: callers.slice(0, limit),\n callees: callees.slice(0, limit),\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Provenance-labeled reference graph (design §2) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * How sure the graph is about one resolved edge. Deliberately coarse: the\n * index has no type checker, so `exact` only ever means \"one structurally\n * unambiguous target under this index's model\".\n */\nexport type ResolutionLabel = 'exact' | 'import-scoped' | 'name-only'\n\n/** Which resolution tier produced an edge — the *why* behind its label. */\nexport type ResolutionProvenance =\n | 'structural-owner'\n | 'local-unique'\n | 'explicit-import-binding'\n | 'namespace-import'\n | 'resolved-import-module'\n | 'global-name'\n\n/** One resolved call edge; one row per candidate target. */\nexport interface ReferenceEdge {\n /** Call's structural owner, or null for a module-level call. */\n sourceId: SymbolId | null\n targetId: SymbolId\n callSite: { file: string; line: number }\n /** Callee name as written at the call site. */\n name: string\n provenance: ResolutionProvenance\n resolution: ResolutionLabel\n /** Total candidates produced at this tier (may exceed the emitted edges). */\n candidateCount: number\n}\n\n/** Adjacency views over the same edge set, plus ownerless call sites. */\nexport interface ReferenceGraph {\n symbolsById: Map<SymbolId, SymbolInfo>\n /** sourceId -> edges it emits. */\n outgoing: Map<SymbolId, ReferenceEdge[]>\n /** targetId -> edges that point at it (including module-level calls). */\n incoming: Map<SymbolId, ReferenceEdge[]>\n /** Edges whose call site has no structural owner. */\n moduleLevelEdges: ReferenceEdge[]\n}\n\nexport interface ReferenceGraphOptions {\n /** Max candidate targets emitted per call site (default 8). */\n maxCandidatesPerCall?: number\n}\n\nconst DEFAULT_MAX_CANDIDATES = 8\n\n/**\n * Build the provenance-labeled reference graph for an index. Pure: reads the\n * cached index only. Existing `code_refs` helpers above keep their name-based\n * behavior; this graph is the precise-by-provenance successor.\n */\nexport function buildReferenceGraph(\n index: RepoIndex,\n options: ReferenceGraphOptions = {},\n): ReferenceGraph {\n const maxCandidates = options.maxCandidatesPerCall ?? DEFAULT_MAX_CANDIDATES\n const symbolsById = new Map<SymbolId, SymbolInfo>()\n const symbolsByFile = new Map<string, SymbolInfo[]>()\n for (const file of index.files) {\n for (const symbol of file.symbols) symbolsById.set(symbol.id, symbol)\n symbolsByFile.set(file.path, file.symbols)\n }\n const symbolsByName = buildSymbolTable(index)\n const fileSet = new Set(index.files.map((file) => file.path))\n\n const outgoing = new Map<SymbolId, ReferenceEdge[]>()\n const incoming = new Map<SymbolId, ReferenceEdge[]>()\n const moduleLevelEdges: ReferenceEdge[] = []\n\n for (const file of index.files) {\n for (const call of file.calls ?? []) {\n const edges = resolveCallTargetsFor(\n fileSet,\n file,\n call,\n symbolsByName,\n symbolsByFile,\n maxCandidates,\n )\n if (edges.length === 0) continue\n if (call.fromId) {\n appendEdges(outgoing, call.fromId, edges)\n } else {\n moduleLevelEdges.push(...edges)\n }\n for (const edge of edges) appendEdges(incoming, edge.targetId, [edge])\n }\n }\n\n return { symbolsById, outgoing, incoming, moduleLevelEdges }\n}\n\n/**\n * Resolve one call site to zero or more target edges, stopping at the first\n * non-empty resolution tier (see §2 of the design):\n *\n * 1. provably-owned local candidate (recursion / directly-owned declaration)\n * 2. explicit imported binding (incl. an honest default-binding path)\n * 3. qualifier matched to a namespace/package import\n * 4. names declared in resolved imported modules\n * 5. repo-wide name candidates\n */\nexport function resolveCallTargets(\n index: RepoIndex,\n file: IndexedFile,\n call: CallInfo,\n symbolsByName: Map<string, SymbolInfo[]>,\n maxCandidates = DEFAULT_MAX_CANDIDATES,\n): ReferenceEdge[] {\n const fileSet = new Set(index.files.map((f) => f.path))\n const symbolsByFile = new Map(index.files.map((f) => [f.path, f.symbols]))\n return resolveCallTargetsFor(fileSet, file, call, symbolsByName, symbolsByFile, maxCandidates)\n}\n\nfunction resolveCallTargetsFor(\n fileSet: Set<string>,\n file: IndexedFile,\n call: CallInfo,\n symbolsByName: Map<string, SymbolInfo[]>,\n symbolsByFile: Map<string, SymbolInfo[]>,\n maxCandidates: number,\n): ReferenceEdge[] {\n const named = symbolsByName.get(call.name) ?? []\n const qualified = call.qualifier !== null\n // Re-exports do not bind names in this module; only genuine imports can\n // target a call (§2 — re-export chains cannot claim exact).\n const imports = (file.importDetails ?? []).filter((info) => info.kind !== 'reexport')\n\n // Bare calls only: a qualified call names a member of its receiver, so a\n // same-named local or import binding must not capture it.\n if (!qualified) {\n // Tier 1 — a same-file symbol whose scope encloses this call site. `exact`\n // needs provable ownership: a parameter or local the index cannot see may\n // shadow any other name, including a module-level sibling.\n const locals = named.filter((s) => s.file === file.path && lexicallyVisible(s, call))\n if (locals.length > 0) {\n const unique = locals.length === 1\n const owned = unique && isStructuralOwner(call, locals[0]!)\n const provenance: ResolutionProvenance =\n owned && call.fromId !== null ? 'structural-owner' : 'local-unique'\n return toEdges(locals, call, file.path, provenance, owned ? 'exact' : 'name-only', maxCandidates)\n }\n\n // Tier 2 — explicit imported binding (`import { foo } from './x'`).\n const bound: SymbolInfo[] = []\n let directBinding = true\n let defaultBinding = false\n for (const info of imports) {\n for (const binding of info.bindings) {\n if (binding.local !== call.name) continue\n const isDefault = binding.kind === 'default' || binding.imported === 'default'\n if (!isDefault && !isExplicitBinding(binding)) continue\n const resolved = resolveImportDetailed(info.specifier, file.path, fileSet)\n const target = resolved.target\n if (!target) continue\n if (resolved.suffixSkipped) directBinding = false\n if (isDefault) {\n // `import x from './m'` binds a default export the index cannot name;\n // an alias match against the module's symbols is the only honest\n // target, else the module's exported set — and never `exact`.\n defaultBinding = true\n const moduleSymbols = symbolsByFile.get(target) ?? []\n const nameMatches = moduleSymbols.filter((s) => s.name === binding.local)\n bound.push(\n ...(nameMatches.length > 0 ? nameMatches : moduleSymbols.filter((s) => s.exported)),\n )\n continue\n }\n if (!isExplicitBinding(binding)) continue\n for (const def of symbolsByName.get(binding.imported) ?? []) {\n if (def.file === target) bound.push(def)\n }\n }\n }\n if (bound.length > 0) {\n const label: ResolutionLabel =\n bound.length === 1 && directBinding && !defaultBinding ? 'exact' : 'import-scoped'\n return toEdges(bound, call, file.path, 'explicit-import-binding', label, maxCandidates)\n }\n\n // Tier 4 — the name exists in a module this file imports, binding or not.\n const resolvedModules = new Set<string>()\n for (const info of imports) {\n const target = resolveImport(info.specifier, file.path, fileSet)\n if (target && target !== file.path) resolvedModules.add(target)\n }\n const imported = named.filter((s) => resolvedModules.has(s.file))\n if (imported.length > 0) {\n return toEdges(\n imported,\n call,\n file.path,\n 'resolved-import-module',\n 'import-scoped',\n maxCandidates,\n )\n }\n }\n\n // Tier 3 — `ns.foo()` where `ns` is a namespace/package import. A qualifier\n // must be an actual namespace/package binding; only a record that carries no\n // binding at all (e.g. a C/C++ include) may infer it from the path segment,\n // and even then it never elevates above `import-scoped`.\n if (qualified) {\n const qualifier = call.qualifier!\n const modules = new Set<string>()\n for (const info of imports) {\n const namespaceBound = info.bindings.some(\n (b) => (b.kind === 'namespace' || b.kind === 'package') && b.local === qualifier,\n )\n if (!namespaceBound) {\n if (info.bindings.length > 0) continue\n if (specifierLastSegment(info.specifier) !== qualifier) continue\n }\n const target = resolveImport(info.specifier, file.path, fileSet)\n if (target && target !== file.path) modules.add(target)\n }\n const qualifiedTargets = named.filter((s) => modules.has(s.file))\n if (qualifiedTargets.length > 0) {\n return toEdges(\n qualifiedTargets,\n call,\n file.path,\n 'namespace-import',\n 'import-scoped',\n maxCandidates,\n )\n }\n }\n\n // Tier 5 — repo-wide name match, no import evidence.\n if (named.length > 0) {\n return toEdges(named, call, file.path, 'global-name', 'name-only', maxCandidates)\n }\n return []\n}\n\n/** Materialize one edge per candidate, capped — `candidateCount` stays truthful. */\nfunction toEdges(\n candidates: SymbolInfo[],\n call: CallInfo,\n filePath: string,\n provenance: ResolutionProvenance,\n resolution: ResolutionLabel,\n maxCandidates: number,\n): ReferenceEdge[] {\n const unique = dedupeSymbols(candidates)\n const count = unique.length\n const cap = maxCandidates > 0 ? Math.floor(maxCandidates) : 0\n return unique.slice(0, cap).map((target) => ({\n sourceId: call.fromId,\n targetId: target.id,\n callSite: { file: filePath, line: call.line },\n name: call.name,\n provenance,\n resolution,\n candidateCount: count,\n }))\n}\n\nfunction appendEdges(\n map: Map<SymbolId, ReferenceEdge[]>,\n key: SymbolId,\n edges: ReferenceEdge[],\n): void {\n const list = map.get(key)\n if (list) list.push(...edges)\n else map.set(key, [...edges])\n}\n\nfunction dedupeSymbols(candidates: SymbolInfo[]): SymbolInfo[] {\n const sorted = [...candidates].sort(compareSymbols)\n const out: SymbolInfo[] = []\n const seen = new Set<SymbolId>()\n for (const symbol of sorted) {\n if (seen.has(symbol.id)) continue\n seen.add(symbol.id)\n out.push(symbol)\n }\n return out\n}\n\nfunction compareSymbols(a: SymbolInfo, b: SymbolInfo): number {\n return (\n a.file.localeCompare(b.file) ||\n a.line - b.line ||\n a.kind.localeCompare(b.kind) ||\n a.name.localeCompare(b.name) ||\n a.id.localeCompare(b.id)\n )\n}\n\n/**\n * A candidate is lexically visible at the call when its *containing* scope is\n * an ancestor of the call's structural owner (or of the module, for a\n * module-level call). The symbol-id path encodes the scope chain, so this is a\n * prefix test rather than a re-parse.\n */\nfunction lexicallyVisible(candidate: SymbolInfo, call: CallInfo): boolean {\n if (call.fromId) {\n const ownerPath = pathAfterHash(call.fromId)\n const scopePath = containerPath(candidate.id)\n if (scopePath === '') return true\n return ownerPath === scopePath || ownerPath.startsWith(`${scopePath}/`)\n }\n if (candidate.scope.length === 0) return true\n return candidate.line <= call.line && call.line <= candidate.endLine\n}\n\n/**\n * True when the target's containment structurally proves ownership: a\n * module-level target called from module scope (no callable can shadow it),\n * the call's own owner (recursion), or a declaration directly inside the\n * call's owner. A module-level symbol called from *inside* a callable is not\n * proof — an unseen parameter or local may shadow it.\n */\nfunction isStructuralOwner(call: CallInfo, target: SymbolInfo): boolean {\n if (!call.fromId) return containerPath(target.id) === ''\n if (target.id === call.fromId) return true\n return containerPath(target.id) === pathAfterHash(call.fromId)\n}\n\n/** Scope-chain portion of a symbol id (the part between `#` and the last `/`). */\nfunction pathAfterHash(id: SymbolId): string {\n const hash = id.indexOf('#')\n return hash >= 0 ? id.slice(hash + 1) : id\n}\n\nfunction containerPath(id: SymbolId): string {\n const full = pathAfterHash(id)\n const slash = full.lastIndexOf('/')\n return slash >= 0 ? full.slice(0, slash) : ''\n}\n\n/** A binding that names one concrete imported symbol (not a namespace/glob). */\nfunction isExplicitBinding(\n binding: ImportBinding,\n): binding is ImportBinding & { imported: string } {\n return binding.imported != null && binding.imported !== '*' && binding.imported !== 'default'\n}\n\n/** Last path-like segment of a specifier, extension stripped. */\nfunction specifierLastSegment(specifier: string): string {\n const clean = specifier.split(/[?#]/)[0] ?? specifier\n const segment = clean.split('/').filter(Boolean).pop() ?? clean\n return segment.replace(/\\.[A-Za-z0-9]+$/, '')\n}\n","/** Pure search / filter logic over a RepoIndex — unit-testable, no IO. */\n\nimport type { RepoIndex, SymbolInfo, SymbolKind } from './types.js'\nimport { callerCounts } from './refgraph.js'\n\nexport interface SymbolFilter {\n query?: string\n file?: string\n kind?: SymbolKind\n exportedOnly?: boolean\n}\n\nexport interface RankedHit extends SymbolInfo {\n /** 0..1 relevance. 1 = exact name match; lower = fuzzier. */\n score: number\n}\n\nfunction matchScore(name: string, query: string): number {\n const q = query.toLowerCase()\n const n = name.toLowerCase()\n if (n === q) return 1\n if (n.startsWith(q)) return 0.8\n if (n.includes(q)) return 0.5\n if (q.length >= 3 && isSubsequence(q, n)) return 0.3\n return 0\n}\n\n/**\n * Every query char appears in the name, in order — 'cfgldr' finds\n * 'configLoader'. Gated to 3+ chars so short queries don't match everything.\n */\nfunction isSubsequence(query: string, name: string): boolean {\n let i = 0\n for (const ch of name) {\n if (ch === query[i]) i++\n if (i === query.length) return true\n }\n return false\n}\n\n/** Filter symbols by file/kind/export, then score by name against query (if any). */\nexport function searchSymbols(\n index: RepoIndex,\n filter: SymbolFilter,\n limit = 50,\n refs: Map<string, number> = callerCounts(index),\n): RankedHit[] {\n const q = (filter.query ?? '').trim()\n const filePat = filter.file?.trim().toLowerCase()\n const hits: RankedHit[] = []\n\n for (const file of index.files) {\n if (filePat && !file.path.toLowerCase().includes(filePat)) continue\n for (const sym of file.symbols) {\n if (filter.kind && sym.kind !== filter.kind) continue\n if (filter.exportedOnly && !sym.exported) continue\n const score = q ? matchScore(sym.name, q) : 0.4\n if (q && score === 0) continue\n hits.push({ ...sym, score })\n }\n }\n\n // Export boost, then relevance, then call fan-in, then stable name order.\n hits.sort((a, b) => {\n const ab =\n Number(b.exported) - Number(a.exported) ||\n b.score - a.score ||\n (refs.get(b.name) ?? 0) - (refs.get(a.name) ?? 0) ||\n a.name.localeCompare(b.name) ||\n a.file.localeCompare(b.file)\n return ab\n })\n return hits.slice(0, limit)\n}\n\n/** Neat one-line rendering of a hit for terminal/chat output. */\nexport function renderHit(hit: RankedHit): string {\n const exportMark = hit.exported ? 'export ' : ''\n const sig = hit.signature || hit.name\n const score = hit.score < 1 ? ` [${hit.score.toFixed(2)}]` : ''\n return `${exportMark}${hit.kind} ${sig}${score} — ${hit.file}:${hit.line}`\n}\n","/** Import-graph health checks: circular dependencies and orphan modules. */\n\nimport { resolveImport } from './repomap.js'\nimport type { RepoIndex } from './types.js'\n\nexport interface ModuleGraph {\n nodes: string[]\n edges: Map<string, Set<string>>\n}\n\n/** Nodes are indexed files; an edge A -> B means A imports B (self-edges dropped). */\nexport function buildModuleGraph(index: RepoIndex): ModuleGraph {\n const nodes = index.files.map((file) => file.path).sort((a, b) => a.localeCompare(b))\n const fileSet = new Set(nodes)\n const edges = new Map<string, Set<string>>()\n for (const file of index.files) {\n const targets = new Set<string>()\n for (const spec of file.imports ?? []) {\n const target = resolveImport(spec, file.path, fileSet)\n if (target && target !== file.path) targets.add(target)\n }\n edges.set(file.path, targets)\n }\n return { nodes, edges }\n}\n\n/** Tarjan strongly-connected components of size > 1 — i.e. import cycles. */\nexport function findCycles(index: RepoIndex): string[][] {\n const { nodes, edges } = buildModuleGraph(index)\n const discovery = new Map<string, number>()\n const low = new Map<string, number>()\n const onStack = new Set<string>()\n const stack: string[] = []\n const components: string[][] = []\n let counter = 0\n\n const visit = (node: string): void => {\n discovery.set(node, counter)\n low.set(node, counter)\n counter++\n stack.push(node)\n onStack.add(node)\n\n for (const next of edges.get(node) ?? []) {\n if (!discovery.has(next)) {\n visit(next)\n low.set(node, Math.min(low.get(node)!, low.get(next)!))\n } else if (onStack.has(next)) {\n low.set(node, Math.min(low.get(node)!, discovery.get(next)!))\n }\n }\n\n if (low.get(node) === discovery.get(node)) {\n const component: string[] = []\n for (;;) {\n const member = stack.pop()!\n onStack.delete(member)\n component.push(member)\n if (member === node) break\n }\n if (component.length > 1) components.push(component.sort())\n }\n }\n\n for (const node of nodes) {\n if (!discovery.has(node)) visit(node)\n }\n components.sort((a, b) => a[0]!.localeCompare(b[0]!))\n return components\n}\n\nconst ENTRY_RE =\n /(^|\\/)(index|main|cli|app|server|mod|lib|__init__)\\.[A-Za-z0-9]+$|(^|\\/)(bin|cmd|scripts)\\/|\\.config\\.[A-Za-z0-9]+$/\nconst TEST_RE =\n /(^|\\/)(tests?|__tests__)(\\/|$)|\\.(?:spec|test)\\.[cm]?[jt]sx?$|(^|\\/)(?:test_[^/]+\\.py|[^/]+_test\\.(?:py|go))$/\n\n/**\n * Symbol-bearing files that neither import nor are imported by any other file,\n * excluding conventional entry points and tests (which are legitimately\n * unreferenced). A cheap, low-false-positive stand-in for dead-code detection.\n */\nexport function findOrphanModules(index: RepoIndex): string[] {\n const { nodes, edges } = buildModuleGraph(index)\n const incoming = new Map<string, number>()\n for (const targets of edges.values()) {\n for (const target of targets) incoming.set(target, (incoming.get(target) ?? 0) + 1)\n }\n const withSymbols = new Set(\n index.files.filter((file) => file.symbols.length > 0).map((file) => file.path),\n )\n return nodes.filter(\n (path) =>\n withSymbols.has(path) &&\n (incoming.get(path) ?? 0) === 0 &&\n (edges.get(path)?.size ?? 0) === 0 &&\n !ENTRY_RE.test(path) &&\n !TEST_RE.test(path),\n )\n}\n","/**\n * Unified-diff parsing and a thin `git` adapter.\n *\n * `parseUnifiedDiff` is pure (no IO) so it is unit-testable in isolation; the\n * two readers shell out to `git` exclusively through `execFile` with an argv\n * array — a ref or path is never interpolated into a shell string.\n */\n\nimport { execFile } from 'node:child_process'\nimport { readFile } from 'node:fs/promises'\nimport path from 'node:path'\n\n/** One `@@` hunk header; a missing count means 1 (git omits `,1`). */\nexport interface DiffHunk {\n oldStart: number\n oldLines: number\n newStart: number\n newLines: number\n}\n\n/** One file's entry in a unified diff. */\nexport interface FileChange {\n /** Repo-relative path on the base side, or null for an added file. */\n oldPath: string | null\n /** Repo-relative path on the current side, or null for a deleted file. */\n newPath: string | null\n status: 'added' | 'modified' | 'deleted' | 'renamed'\n hunks: DiffHunk[]\n}\n\nconst HUNK_RE = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/\nconst HEADER_PATH_PREFIX_RE = /^[ab]\\//\n/** Git can emit large diffs; keep a generous but bounded capture buffer. */\nconst MAX_BUFFER = 64 * 1024 * 1024\n\ninterface Draft {\n oldPath: string | null\n newPath: string | null\n /** Fallback paths from the `diff --git` line, overridden by later records. */\n gitOldPath: string | null\n gitNewPath: string | null\n /** Set when `---`/`+++` was seen, so an explicit /dev/null is not re-filled. */\n sawOldHeader: boolean\n sawNewHeader: boolean\n renameFrom: string | null\n renameTo: string | null\n newFile: boolean\n deletedFile: boolean\n hunks: DiffHunk[]\n /** Once a hunk starts, `---`/`+++` lines are content, not file headers. */\n sawHunk: boolean\n}\n\nfunction newDraft(): Draft {\n return {\n oldPath: null,\n newPath: null,\n gitOldPath: null,\n gitNewPath: null,\n sawOldHeader: false,\n sawNewHeader: false,\n renameFrom: null,\n renameTo: null,\n newFile: false,\n deletedFile: false,\n hunks: [],\n sawHunk: false,\n }\n}\n\n/**\n * Parse `git diff` / `diff -u` output into per-file changes. Handles\n * `diff --git`, `new file mode`, `deleted file mode`, `rename from/to`,\n * `---`/`+++` (including `/dev/null`), and `@@` headers with omitted counts.\n */\nexport function parseUnifiedDiff(text: string): FileChange[] {\n const changes: FileChange[] = []\n let draft: Draft | null = null\n\n for (const line of text.split('\\n')) {\n if (line.startsWith('diff --git ')) {\n if (draft) changes.push(finalize(draft))\n draft = newDraft()\n const [rawOld, rawNew] = splitDiffGitPaths(line.slice('diff --git '.length))\n draft.gitOldPath = rawOld === null ? null : parseHeaderPath(rawOld)\n draft.gitNewPath = rawNew === null ? null : parseHeaderPath(rawNew)\n continue\n }\n\n if (!draft) {\n // Bare unified diff without a `diff --git` preamble: start on the first\n // recognized file line and ignore anything before it.\n if (!isFileLine(line)) continue\n draft = newDraft()\n }\n\n if (line.startsWith('new file mode ')) {\n draft.newFile = true\n } else if (line.startsWith('deleted file mode ')) {\n draft.deletedFile = true\n } else if (line.startsWith('rename from ')) {\n draft.renameFrom = parseRawPath(line.slice('rename from '.length))\n } else if (line.startsWith('rename to ')) {\n draft.renameTo = parseRawPath(line.slice('rename to '.length))\n } else if (!draft.sawHunk && line.startsWith('--- ')) {\n draft.oldPath = parseHeaderPath(line.slice(4))\n draft.sawOldHeader = true\n } else if (!draft.sawHunk && line.startsWith('+++ ')) {\n draft.newPath = parseHeaderPath(line.slice(4))\n draft.sawNewHeader = true\n } else if (line.startsWith('@@ ')) {\n const hunk = parseHunk(line)\n if (hunk) {\n draft.hunks.push(hunk)\n draft.sawHunk = true\n }\n }\n }\n\n if (draft) changes.push(finalize(draft))\n return changes\n}\n\nfunction isFileLine(line: string): boolean {\n return (\n line.startsWith('--- ') ||\n line.startsWith('+++ ') ||\n line.startsWith('@@ ') ||\n line.startsWith('new file mode ') ||\n line.startsWith('deleted file mode ') ||\n line.startsWith('rename from ') ||\n line.startsWith('rename to ')\n )\n}\n\nfunction finalize(draft: Draft): FileChange {\n let oldPath = draft.renameFrom ?? (draft.sawOldHeader ? draft.oldPath : draft.gitOldPath)\n let newPath = draft.renameTo ?? (draft.sawNewHeader ? draft.newPath : draft.gitNewPath)\n if (draft.newFile) oldPath = null\n if (draft.deletedFile) newPath = null\n let status: FileChange['status'] = 'modified'\n if (draft.newFile || (oldPath === null && newPath !== null && draft.renameFrom === null)) {\n status = 'added'\n } else if (\n draft.deletedFile ||\n (newPath === null && oldPath !== null && draft.renameTo === null)\n ) {\n status = 'deleted'\n } else if (draft.renameFrom !== null || draft.renameTo !== null) {\n status = 'renamed'\n }\n return { oldPath, newPath, status, hunks: draft.hunks }\n}\n\n/**\n * Extract the two repo paths from a `diff --git` body, honoring git's C-style\n * quoting; the tokens keep their `a/`/`b/` prefix for {@link parseHeaderPath}.\n */\nfunction splitDiffGitPaths(rest: string): [string | null, string | null] {\n const tokens: string[] = []\n let index = 0\n while (index < rest.length && tokens.length < 2) {\n while (index < rest.length && rest[index] === ' ') index++\n if (index >= rest.length) break\n const start = index\n if (rest[index] === '\"') {\n index++\n while (index < rest.length) {\n if (rest[index] === '\\\\') index += 2\n else if (rest[index] === '\"') {\n index++\n break\n } else index++\n }\n } else {\n while (index < rest.length && rest[index] !== ' ') index++\n }\n tokens.push(rest.slice(start, index))\n }\n return [tokens[0] ?? null, tokens[1] ?? null]\n}\n\nfunction parseHunk(line: string): DiffHunk | null {\n const match = HUNK_RE.exec(line)\n if (!match) return null\n const oldCount = match[2] as string | undefined\n const newCount = match[4] as string | undefined\n return {\n oldStart: Number(match[1]),\n oldLines: oldCount === undefined ? 1 : Number(oldCount),\n newStart: Number(match[3]),\n newLines: newCount === undefined ? 1 : Number(newCount),\n }\n}\n\n/** `--- a/x` / `+++ b/x` / `--- /dev/null`, tolerating a trailing timestamp. */\nfunction parseHeaderPath(raw: string): string | null {\n let value = raw\n const tab = value.indexOf('\\t')\n if (tab >= 0) value = value.slice(0, tab)\n value = value.trim()\n if (value === '/dev/null') return null\n if (value.startsWith('\"')) value = unquoteGitPath(value)\n value = value.replace(HEADER_PATH_PREFIX_RE, '')\n return value.length > 0 ? value : null\n}\n\n/** `rename from/to` paths are repo-relative with no `a/`/`b/` prefix. */\nfunction parseRawPath(raw: string): string | null {\n let value = raw.trim()\n if (value.startsWith('\"')) value = unquoteGitPath(value)\n return value.length > 0 ? value : null\n}\n\n/** Decode git's C-style quoted path (octal escapes reassembled as UTF-8 bytes). */\nfunction unquoteGitPath(value: string): string {\n const inner = value.slice(1, -1)\n const bytes: number[] = []\n for (let i = 0; i < inner.length; i++) {\n const ch = inner[i]!\n if (ch !== '\\\\') {\n bytes.push(...Buffer.from(ch, 'utf8'))\n continue\n }\n i++\n const esc: string | undefined = inner[i]\n if (esc === undefined) break\n if (esc >= '0' && esc <= '7') {\n let octal = esc\n let next: string | undefined = inner[i + 1]\n while (octal.length < 3 && next !== undefined && next >= '0' && next <= '7') {\n octal += next\n i++\n next = inner[i + 1]\n }\n bytes.push(parseInt(octal, 8))\n continue\n }\n switch (esc) {\n case 'n':\n bytes.push(0x0a)\n break\n case 't':\n bytes.push(0x09)\n break\n case 'r':\n bytes.push(0x0d)\n break\n case 'f':\n bytes.push(0x0c)\n break\n case 'v':\n bytes.push(0x0b)\n break\n case 'b':\n bytes.push(0x08)\n break\n case 'a':\n bytes.push(0x07)\n break\n case '\"':\n bytes.push(0x22)\n break\n case '\\\\':\n bytes.push(0x5c)\n break\n default:\n bytes.push(...Buffer.from(esc, 'utf8'))\n }\n }\n return Buffer.from(bytes).toString('utf8')\n}\n\n/** Reject a ref that git would parse as an option rather than a revision. */\nfunction requireSafeRef(ref: string, label: string): void {\n if (ref.length === 0) throw new Error(`${label} must not be empty`)\n if (ref.startsWith('-')) throw new Error(`${label} must not start with '-': ${ref}`)\n}\n\nfunction runGit(args: readonly string[], cwd: string): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile('git', args, { cwd, encoding: 'utf8', maxBuffer: MAX_BUFFER }, (error, stdout) => {\n if (error) reject(error)\n else resolve(stdout)\n })\n })\n}\n\n/**\n * Working-tree diff against `baseRef`, rename-aware and hunk-minimal.\n * Excludes untracked files (git semantics) — callers should say so.\n */\nexport async function readWorkingTreeDiff(root: string, baseRef: string): Promise<string> {\n requireSafeRef(baseRef, 'baseRef')\n const tracked = await runGit(\n ['diff', '--no-ext-diff', '--find-renames', '--unified=0', baseRef, '--', '.'],\n root,\n )\n const untracked = await runGit(['ls-files', '--others', '--exclude-standard', '-z', '--'], root)\n const changes = parseUnifiedDiff(tracked)\n const untrackedFiles: Array<{ path: string; content: string; lines: number }> = []\n for (const rawPath of untracked.split('\\0')) {\n if (rawPath.length === 0) continue\n const normalized = rawPath.replace(/\\\\/g, '/')\n // The index cache is intentionally local state, even when the host repo\n // has no .gitignore yet. It must not appear as a source change.\n if (normalized === '.dsh-code-index' || normalized.startsWith('.dsh-code-index/')) continue\n try {\n const content = await readFile(path.resolve(root, normalized), 'utf8')\n const lines = content.length === 0 ? 0 : content.split(/\\r?\\n/).length - (content.endsWith('\\n') ? 1 : 0)\n untrackedFiles.push({ path: normalized, content, lines })\n } catch {\n // A file can disappear between ls-files and readFile. Git would also\n // omit that race, so leave it out rather than failing the whole diff.\n }\n }\n\n // Git cannot detect an unstaged rename because its destination is still\n // untracked. Pair exact-content deleted/base files with untracked files so\n // the change-context layer receives the same rename signal as a staged diff.\n const paired = new Set<string>()\n for (const change of changes) {\n if (change.status !== 'deleted' || change.oldPath === null) continue\n let oldContent: string\n try {\n oldContent = await runGit(['show', `${baseRef}:${change.oldPath}`], root)\n } catch {\n continue\n }\n const match = untrackedFiles.find((file) => !paired.has(file.path) && file.content === oldContent)\n if (!match) continue\n change.newPath = match.path\n change.status = 'renamed'\n change.hunks = []\n paired.add(match.path)\n }\n\n for (const file of untrackedFiles) {\n if (paired.has(file.path)) continue\n changes.push({\n oldPath: null,\n newPath: file.path,\n status: 'added',\n hunks: file.lines > 0 ? [{ oldStart: 0, oldLines: 0, newStart: 1, newLines: file.lines }] : [],\n })\n }\n return renderNormalizedDiff(changes)\n}\n\n/** Re-render only the structural part consumed by parseUnifiedDiff. */\nfunction renderNormalizedDiff(changes: readonly FileChange[]): string {\n return changes\n .map((change) => {\n const oldPath = change.oldPath ?? change.newPath!\n const newPath = change.newPath ?? change.oldPath!\n const lines = [`diff --git ${diffToken(`a/${oldPath}`)} ${diffToken(`b/${newPath}`)}`]\n if (change.status === 'added') lines.push('new file mode 100644')\n if (change.status === 'deleted') lines.push('deleted file mode 100644')\n if (change.status === 'renamed') {\n lines.push('similarity index 100%', `rename from ${diffToken(change.oldPath!)}`, `rename to ${diffToken(change.newPath!)}`)\n } else {\n lines.push(`--- ${change.oldPath === null ? '/dev/null' : diffToken(`a/${change.oldPath}`)}`)\n lines.push(`+++ ${change.newPath === null ? '/dev/null' : diffToken(`b/${change.newPath}`)}`)\n }\n for (const hunk of change.hunks) {\n const oldCount = hunk.oldLines === 1 ? '' : `,${hunk.oldLines}`\n const newCount = hunk.newLines === 1 ? '' : `,${hunk.newLines}`\n lines.push(`@@ -${hunk.oldStart}${oldCount} +${hunk.newStart}${newCount} @@`)\n }\n return `${lines.join('\\n')}\\n`\n })\n .join('')\n}\n\nfunction diffToken(value: string): string {\n return /[\\s\"]/.test(value) ? `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"` : value\n}\n\n/** Read one repo-relative file at a ref; null when the path/ref is absent. */\nexport async function readGitFileAtRef(\n root: string,\n ref: string,\n repoRelativePath: string,\n): Promise<string | null> {\n requireSafeRef(ref, 'ref')\n try {\n return await runGit(['show', `${ref}:${repoRelativePath}`], root)\n } catch {\n return null\n }\n}\n","/**\n * Change-aware context (design §3): map a git/working-tree diff (or an explicit\n * file/symbol selection) onto indexed symbols, then walk the provenance-labeled\n * reference graph to surface callers, import dependents, transitive impact,\n * entry-point paths, and likely affected tests.\n *\n * Every relation keeps the reference graph's honest label (`exact` /\n * `import-scoped` / `name-only`); a diff hunk intersecting a symbol's declared\n * line range is the only thing treated as `exact`.\n */\n\nimport path from 'node:path'\nimport { buildReferenceGraph, type ResolutionLabel, type ResolutionProvenance } from './refgraph.js'\nimport { buildModuleGraph } from './health.js'\nimport { resolveImport } from './repomap.js'\nimport { extractAll, languageForFile } from './extract.js'\nimport {\n parseUnifiedDiff,\n readGitFileAtRef,\n readWorkingTreeDiff,\n type FileChange,\n} from './git-diff.js'\nimport type { IndexedFile, RepoIndex, SymbolId, SymbolInfo, SymbolKind } from './types.js'\n\n/* -------------------------------------------------------------------------- */\n/* Types (design §3) */\n/* -------------------------------------------------------------------------- */\n\nexport type ChangeKind = 'added' | 'modified' | 'deleted' | 'renamed'\n\nexport interface ChangedSymbol {\n symbol: SymbolInfo\n change: ChangeKind\n side: 'current' | 'base'\n /** A hunk range intersecting the declaration is structural, not inferred. */\n resolution: 'exact'\n}\n\nexport interface UnmappedChange {\n file: string\n side: 'current' | 'base'\n ranges: Array<{ startLine: number; endLine: number }>\n reason: 'outside-symbol' | 'base-content-unavailable'\n}\n\nexport interface ImpactHop {\n fromId: SymbolId | null\n toId: SymbolId\n callSite: { file: string; line: number }\n resolution: ResolutionLabel\n reason: ResolutionProvenance\n}\n\nexport interface ImpactRow {\n symbol: SymbolInfo\n depth: number\n via: ImpactHop\n resolution: ResolutionLabel\n}\n\nexport interface SymbolPath {\n entry: SymbolInfo\n changed: SymbolInfo\n hops: ImpactHop[]\n resolution: ResolutionLabel\n}\n\nexport interface ImportDependent {\n file: string\n changedFile: string\n specifier: string\n resolution: 'import-scoped'\n}\n\nexport interface AffectedTest {\n file: string\n resolution: ResolutionLabel\n reason:\n | 'changed-test'\n | 'imports-changed-file'\n | 'imports-impact-file'\n | 'references-symbol-name'\n | 'path-convention'\n distance?: number\n}\n\nexport interface ChangeContextResult {\n root: string\n source: 'git' | 'diff' | 'files' | 'symbols'\n baseRef?: string\n changed: ChangedSymbol[]\n unmapped: UnmappedChange[]\n directCallers: ImpactRow[]\n importDependents: ImportDependent[]\n paths: SymbolPath[]\n impact: ImpactRow[]\n tests: AffectedTest[]\n warnings: string[]\n truncated: {\n callers: boolean\n dependents: boolean\n paths: boolean\n impact: boolean\n tests: boolean\n }\n}\n\nexport interface CodeChangeContextArgs {\n repoRoot?: string\n diff?: string\n baseRef?: string\n files?: string[]\n symbols?: SymbolId[]\n maxDepth?: number\n maxImpact?: number\n maxPaths?: number\n maxTests?: number\n}\n\nexport interface ChangeContextOptions {\n maxDepth?: number\n maxImpact?: number\n maxPaths?: number\n maxTests?: number\n}\n\n/** Normalized input: exactly one selection mode. */\nexport type ChangeContextInput =\n | { kind: 'git'; root: string; baseRef: string }\n | { kind: 'diff'; root: string; text: string; baseRef?: string }\n | { kind: 'files'; files: string[] }\n | { kind: 'symbols'; symbolIds: SymbolId[] }\n\nconst LABEL_STRENGTH: Record<ResolutionLabel, number> = {\n exact: 3,\n 'import-scoped': 2,\n 'name-only': 1,\n}\n\nconst ENTRY_KINDS = new Set<SymbolKind>(['function', 'method', 'class'])\nconst ENTRY_FILE_RE = /(^|\\/)(main|index|cli|server|app)\\.[^./]+$/\nconst TEST_RE =\n /(^|\\/)(tests?|__tests__)(\\/|$)|\\.(?:spec|test)\\.[cm]?[jt]sx?$|(^|\\/)(?:test_[^/]+\\.py|[^/]+_test\\.(?:py|go))$/\n\n/** Validate flat tool args and normalize them into one input mode. */\nexport function changeContextInputFromArgs(\n args: Pick<CodeChangeContextArgs, 'diff' | 'baseRef' | 'files' | 'symbols'>,\n root: string,\n): ChangeContextInput {\n const hasDiff = typeof args.diff === 'string' && args.diff.trim().length > 0\n const hasFiles = Array.isArray(args.files) && args.files.length > 0\n const hasSymbols = Array.isArray(args.symbols) && args.symbols.length > 0\n if ([hasDiff, hasFiles, hasSymbols].filter(Boolean).length > 1) {\n throw new Error('pass only one of diff, files, symbols')\n }\n const suppliedBaseRef =\n typeof args.baseRef === 'string' && args.baseRef.length > 0 ? args.baseRef : undefined\n if (hasDiff) {\n return suppliedBaseRef === undefined\n ? { kind: 'diff', root, text: args.diff! }\n : { kind: 'diff', root, text: args.diff!, baseRef: suppliedBaseRef }\n }\n if (hasFiles) return { kind: 'files', files: args.files!.map(requireSafePath) }\n if (hasSymbols) return { kind: 'symbols', symbolIds: [...args.symbols!] }\n return { kind: 'git', root, baseRef: suppliedBaseRef ?? 'HEAD' }\n}\n\nfunction requireSafePath(raw: string): string {\n const value = raw.replace(/\\\\/g, '/').trim()\n if (value.length === 0) throw new Error('file path must not be empty')\n if (value.startsWith('/') || /^[A-Za-z]:\\//.test(value)) {\n throw new Error(`absolute file path not allowed: ${raw}`)\n }\n if (/(^|\\/)\\.\\.(\\/|$)/.test(value)) throw new Error(`path must stay inside the repo: ${raw}`)\n return value.replace(/^\\.\\//, '')\n}\n\nfunction clamp(value: number | undefined, lo: number, hi: number, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback\n return Math.min(hi, Math.max(lo, Math.floor(value)))\n}\n\nfunction weakest(labels: readonly ResolutionLabel[]): ResolutionLabel {\n let out: ResolutionLabel = 'exact'\n for (const label of labels) {\n if (LABEL_STRENGTH[label] < LABEL_STRENGTH[out]) out = label\n }\n return out\n}\n\nfunction symbolLabel(symbol: SymbolInfo): string {\n return `${symbol.kind} ${symbol.signature || symbol.name}`\n}\n\n/* -------------------------------------------------------------------------- */\n/* Pipeline */\n/* -------------------------------------------------------------------------- */\n\nexport async function buildChangeContext(\n index: RepoIndex,\n input: ChangeContextInput,\n options: ChangeContextOptions = {},\n): Promise<ChangeContextResult> {\n const maxDepth = clamp(options.maxDepth, 1, 6, 3)\n const maxImpact = clamp(options.maxImpact, 1, 200, 40)\n const maxPaths = clamp(options.maxPaths, 1, 50, 10)\n const maxTests = clamp(options.maxTests, 1, 100, 20)\n\n const graph = buildReferenceGraph(index)\n const moduleGraph = buildModuleGraph(index)\n const filesByPath = new Map(index.files.map((file) => [file.path, file]))\n const fileSet = new Set(filesByPath.keys())\n const incomingCount = new Map<SymbolId, number>()\n for (const [id, edges] of graph.incoming) incomingCount.set(id, edges.length)\n\n const warnings: string[] = []\n const changedByKey = new Map<string, ChangedSymbol>()\n const unmapped: UnmappedChange[] = []\n const changedFiles = new Set<string>()\n\n const commandRoot = input.kind === 'git' || input.kind === 'diff' ? input.root : index.root\n if (path.resolve(commandRoot) !== path.resolve(index.root)) {\n warnings.push(\n `command root ${path.resolve(commandRoot)} differs from indexed root ${index.root}; using the cached index`,\n )\n }\n\n const addChanged = (\n symbol: SymbolInfo,\n change: ChangeKind,\n side: ChangedSymbol['side'],\n ): void => {\n const key = `${side}:${symbol.id}`\n if (!changedByKey.has(key)) changedByKey.set(key, { symbol, change, side, resolution: 'exact' })\n }\n\n const addUnmapped = (\n file: string,\n side: UnmappedChange['side'],\n ranges: Array<{ startLine: number; endLine: number }>,\n reason: UnmappedChange['reason'],\n ): void => {\n if (ranges.length > 0) unmapped.push({ file, side, ranges, reason })\n }\n\n let baseRef: string | undefined\n\n if (input.kind === 'files') {\n for (const filePath of input.files) {\n const file = filesByPath.get(filePath)\n if (!file) {\n warnings.push(`file not in index: ${filePath}`)\n continue\n }\n changedFiles.add(file.path)\n for (const symbol of file.symbols) addChanged(symbol, 'modified', 'current')\n if (file.symbols.length === 0) warnings.push(`no indexed symbols in changed file: ${filePath}`)\n }\n } else if (input.kind === 'symbols') {\n for (const id of input.symbolIds) {\n const symbol = graph.symbolsById.get(id)\n if (!symbol) {\n warnings.push(`symbol not in index: ${id}`)\n continue\n }\n changedFiles.add(symbol.file)\n addChanged(symbol, 'modified', 'current')\n }\n } else {\n let text: string\n if (input.kind === 'git') {\n baseRef = input.baseRef\n text = await readWorkingTreeDiff(input.root, input.baseRef)\n } else {\n text = input.text\n baseRef = input.baseRef\n }\n\n const changes = parseUnifiedDiff(text).map((change) => ({\n ...change,\n oldPath: change.oldPath === null ? null : requireSafePath(change.oldPath),\n newPath: change.newPath === null ? null : requireSafePath(change.newPath),\n }))\n if (changes.length === 0) warnings.push('no changes found in the diff')\n\n const baseSymbolsCache = new Map<string, Promise<SymbolInfo[] | null>>()\n const readBaseSymbols = (filePath: string): Promise<SymbolInfo[] | null> => {\n const cached = baseSymbolsCache.get(filePath)\n if (cached) return cached\n const pending = (async (): Promise<SymbolInfo[] | null> => {\n if (baseRef === undefined) return null\n const content = await readGitFileAtRef(commandRoot, baseRef, filePath)\n if (content === null) return null\n const lang = languageForFile(filePath)\n if (!lang) return null\n const extracted = await extractAll(content, lang, filePath)\n return extracted.symbols\n })()\n baseSymbolsCache.set(filePath, pending)\n return pending\n }\n\n const symbolsByPath = new Map(index.files.map((file) => [file.path, file.symbols]))\n await mapDiffChanges(\n changes,\n symbolsByPath,\n addChanged,\n addUnmapped,\n changedFiles,\n readBaseSymbols,\n warnings,\n )\n }\n\n const changedSymbols = [...changedByKey.values()].sort(compareChanged)\n\n // Direct callers: incoming edges of each changed symbol.\n const callerById = new Map<SymbolId, ImpactRow>()\n for (const changed of changedSymbols) {\n for (const edge of graph.incoming.get(changed.symbol.id) ?? []) {\n if (edge.sourceId === null) continue\n const caller = graph.symbolsById.get(edge.sourceId)\n if (!caller) continue\n const row: ImpactRow = {\n symbol: caller,\n depth: 1,\n via: hopOf(edge),\n resolution: edge.resolution,\n }\n const existing = callerById.get(caller.id)\n if (!existing || LABEL_STRENGTH[row.resolution] > LABEL_STRENGTH[existing.resolution]) {\n callerById.set(caller.id, row)\n }\n }\n }\n const allCallers = [...callerById.values()].sort(compareBySymbol)\n\n // Transitive impact (depth >= 2), bounded by maxDepth.\n const changedIds = new Set(changedSymbols.map((changed) => changed.symbol.id))\n const impactById = new Map<SymbolId, ImpactRow>()\n {\n const depthById = new Map<SymbolId, number>()\n const strengthById = new Map<SymbolId, ResolutionLabel>()\n for (const id of changedIds) {\n depthById.set(id, 0)\n strengthById.set(id, 'exact')\n }\n let frontier = [...changedIds]\n for (let depth = 0; depth < maxDepth; depth++) {\n const next: SymbolId[] = []\n for (const id of frontier) {\n const pathStrength = strengthById.get(id) ?? 'exact'\n for (const edge of graph.incoming.get(id) ?? []) {\n if (edge.sourceId === null || changedIds.has(edge.sourceId)) continue\n const caller = graph.symbolsById.get(edge.sourceId)\n if (!caller) continue\n const cumulative = weakest([pathStrength, edge.resolution])\n const row: ImpactRow = {\n symbol: caller,\n depth: depth + 1,\n via: hopOf(edge),\n resolution: cumulative,\n }\n const seen = depthById.get(edge.sourceId)\n if (seen === undefined) {\n depthById.set(edge.sourceId, depth + 1)\n strengthById.set(edge.sourceId, cumulative)\n next.push(edge.sourceId)\n if (depth + 1 >= 2) impactById.set(edge.sourceId, row)\n } else if (seen === depth + 1) {\n const previous = strengthById.get(edge.sourceId) ?? 'exact'\n if (LABEL_STRENGTH[cumulative] > LABEL_STRENGTH[previous]) {\n strengthById.set(edge.sourceId, cumulative)\n if (depth + 1 >= 2) impactById.set(edge.sourceId, row)\n }\n }\n }\n }\n frontier = next\n }\n }\n const allImpact = [...impactById.values()].sort(compareByDepthThenSymbol)\n\n // Shortest reverse-call paths from entry points to each changed symbol.\n const allPaths: SymbolPath[] = []\n const pathKey = new Set<string>()\n for (const changed of changedSymbols) {\n for (const found of pathsToEntryPoints(changed.symbol, graph, incomingCount, maxDepth)) {\n const key = `${found.entry.id}\\u0000${found.changed.id}`\n if (pathKey.has(key)) continue\n pathKey.add(key)\n allPaths.push(found)\n }\n }\n allPaths.sort(comparePaths)\n\n // Import dependents: reverse module-graph edges of each changed file.\n const importDependents = collectImportDependents(index, moduleGraph, fileSet, changedFiles)\n\n // Likely affected tests.\n const allTests = collectAffectedTests(\n index,\n moduleGraph,\n changedFiles,\n changedSymbols,\n [...allCallers, ...allImpact],\n )\n\n const truncated = {\n callers: allCallers.length > maxImpact,\n dependents: importDependents.length > maxImpact,\n paths: allPaths.length > maxPaths,\n impact: allImpact.length > maxImpact,\n tests: allTests.length > maxTests,\n }\n\n return {\n root: index.root,\n source: input.kind,\n ...(baseRef !== undefined ? { baseRef } : {}),\n changed: changedSymbols,\n unmapped: unmapped.sort(compareUnmapped),\n directCallers: allCallers.slice(0, maxImpact),\n importDependents: importDependents.slice(0, maxImpact),\n paths: allPaths.slice(0, maxPaths),\n impact: allImpact.slice(0, maxImpact),\n tests: allTests.slice(0, maxTests),\n warnings,\n truncated,\n }\n}\n\nfunction hopOf(edge: {\n sourceId: SymbolId | null\n targetId: SymbolId\n callSite: { file: string; line: number }\n resolution: ResolutionLabel\n provenance: ResolutionProvenance\n}): ImpactHop {\n return {\n fromId: edge.sourceId,\n toId: edge.targetId,\n callSite: edge.callSite,\n resolution: edge.resolution,\n reason: edge.provenance,\n }\n}\n\nasync function mapDiffChanges(\n changes: readonly FileChange[],\n symbolsByPath: Map<string, SymbolInfo[]>,\n addChanged: (symbol: SymbolInfo, change: ChangeKind, side: ChangedSymbol['side']) => void,\n addUnmapped: (\n file: string,\n side: UnmappedChange['side'],\n ranges: Array<{ startLine: number; endLine: number }>,\n reason: UnmappedChange['reason'],\n ) => void,\n changedFiles: Set<string>,\n readBaseSymbols: (filePath: string) => Promise<SymbolInfo[] | null>,\n warnings: string[],\n): Promise<void> {\n for (const change of changes) {\n const { oldPath, newPath, hunks } = change\n if (newPath) changedFiles.add(newPath)\n if (oldPath) changedFiles.add(oldPath)\n\n // Current side: hunk ranges that touch the new file.\n const currentSymbols =\n newPath !== null && change.status !== 'deleted' ? symbolsByPath.get(newPath) : undefined\n if (newPath !== null && change.status !== 'deleted') {\n const currentRanges = hunks\n .filter((hunk) => hunk.newLines > 0)\n .map((hunk) => ({\n startLine: hunk.newStart,\n endLine: hunk.newStart + Math.max(hunk.newLines, 1) - 1,\n }))\n if (currentRanges.length > 0 && currentSymbols) {\n for (const range of currentRanges) {\n for (const symbol of currentSymbols) {\n if (intersects(symbol, range)) addChanged(symbol, change.status, 'current')\n }\n }\n const missed = currentRanges.filter(\n (range) => !currentSymbols.some((symbol) => intersects(symbol, range)),\n )\n addUnmapped(newPath, 'current', missed, 'outside-symbol')\n } else if (currentRanges.length > 0) {\n // Changed file is absent from the cached index.\n addUnmapped(newPath, 'current', currentRanges, 'outside-symbol')\n }\n\n // A pure rename has no hunks, but it is still a structural change. Map\n // both sides so callers can see the old identity and the current file's\n // identity instead of receiving an empty context with only a warning.\n if (change.status === 'renamed' && hunks.length === 0) {\n for (const symbol of currentSymbols ?? []) addChanged(symbol, 'renamed', 'current')\n if (oldPath !== null) {\n const oldSymbols = await readBaseSymbols(oldPath)\n if (oldSymbols === null) {\n warnings.push(`rename baseline unavailable: ${oldPath}`)\n } else {\n for (const symbol of oldSymbols) addChanged(symbol, 'renamed', 'base')\n }\n }\n }\n }\n\n // Base side: deletion-only hunks (newLines === 0) are mapped against the\n // transiently extracted old file; the baseline is never persisted.\n const deletionHunks = hunks.filter((hunk) => hunk.newLines === 0)\n if (deletionHunks.length > 0 && oldPath !== null) {\n const oldRanges = deletionHunks.map((hunk) => ({\n startLine: hunk.oldStart,\n endLine: hunk.oldStart + Math.max(hunk.oldLines, 1) - 1,\n }))\n const oldSymbols = await readBaseSymbols(oldPath)\n if (oldSymbols === null) {\n addUnmapped(oldPath, 'base', oldRanges, 'base-content-unavailable')\n } else {\n const baseChange: ChangeKind = change.status === 'deleted' ? 'deleted' : 'modified'\n for (const range of oldRanges) {\n for (const symbol of oldSymbols) {\n if (intersects(symbol, range)) addChanged(symbol, baseChange, 'base')\n }\n }\n const missed = oldRanges.filter(\n (range) => !oldSymbols.some((symbol) => intersects(symbol, range)),\n )\n addUnmapped(oldPath, 'base', missed, 'outside-symbol')\n }\n }\n\n if (change.status === 'renamed' && hunks.length === 0) {\n warnings.push(`renamed with no content change: ${oldPath} -> ${newPath}`)\n }\n }\n}\n\nfunction intersects(symbol: SymbolInfo, range: { startLine: number; endLine: number }): boolean {\n return symbol.line <= range.endLine && symbol.endLine >= range.startLine\n}\n\n/**\n * BFS over incoming (caller) edges from `changed`; the first time an entry\n * point is reached is a shortest path. Bounded by `maxDepth` so path search\n * and transitive impact cover the same horizon.\n */\nfunction pathsToEntryPoints(\n changed: SymbolInfo,\n graph: ReturnType<typeof buildReferenceGraph>,\n incomingCount: Map<SymbolId, number>,\n maxDepth: number,\n): SymbolPath[] {\n const isEntry = (symbol: SymbolInfo): boolean => {\n if (ENTRY_FILE_RE.test(symbol.file)) return true\n if (!symbol.exported) return false\n if (symbol.kind === 'variable') {\n return symbol.scope.length === 0 || (incomingCount.get(symbol.id) ?? 0) === 0\n }\n if (ENTRY_KINDS.has(symbol.kind)) return true\n return (incomingCount.get(symbol.id) ?? 0) === 0\n }\n\n const found: SymbolPath[] = []\n const depthById = new Map<SymbolId, number>([[changed.id, 0]])\n const strengthById = new Map<SymbolId, ResolutionLabel>([[changed.id, 'exact']])\n const nextEdge = new Map<SymbolId, ImpactHop>()\n const entryIds = new Set<SymbolId>()\n const queue: SymbolId[] = [changed.id]\n\n while (queue.length > 0) {\n const node = queue.shift()!\n const nodeDepth = depthById.get(node) ?? 0\n if (nodeDepth >= maxDepth) continue\n const nodeStrength = strengthById.get(node) ?? 'exact'\n for (const edge of graph.incoming.get(node) ?? []) {\n if (edge.sourceId === null) continue\n const candidateDepth = nodeDepth + 1\n const cumulative = weakest([nodeStrength, edge.resolution])\n const existingDepth = depthById.get(edge.sourceId)\n if (existingDepth === undefined) {\n depthById.set(edge.sourceId, candidateDepth)\n strengthById.set(edge.sourceId, cumulative)\n nextEdge.set(edge.sourceId, hopOf(edge))\n queue.push(edge.sourceId)\n } else if (existingDepth === candidateDepth) {\n const existingStrength = strengthById.get(edge.sourceId) ?? 'exact'\n if (LABEL_STRENGTH[cumulative] > LABEL_STRENGTH[existingStrength]) {\n strengthById.set(edge.sourceId, cumulative)\n nextEdge.set(edge.sourceId, hopOf(edge))\n queue.push(edge.sourceId)\n }\n }\n const entry = graph.symbolsById.get(edge.sourceId)\n if (entry && isEntry(entry)) entryIds.add(edge.sourceId)\n }\n }\n\n for (const entryId of entryIds) {\n const entry = graph.symbolsById.get(entryId)\n if (!entry) continue\n const hops: ImpactHop[] = []\n let cursor = entryId\n const guard = new Set<SymbolId>()\n while (cursor !== changed.id && !guard.has(cursor)) {\n guard.add(cursor)\n const hop = nextEdge.get(cursor)\n if (!hop) break\n hops.push(hop)\n cursor = hop.toId\n }\n if (cursor === changed.id && hops.length > 0) {\n found.push({\n entry,\n changed,\n hops,\n resolution: weakest(hops.map((hop) => hop.resolution)),\n })\n }\n }\n return found\n}\n\nfunction collectImportDependents(\n index: RepoIndex,\n moduleGraph: ReturnType<typeof buildModuleGraph>,\n fileSet: Set<string>,\n changedFiles: Set<string>,\n): ImportDependent[] {\n const filesByPath = new Map(index.files.map((file) => [file.path, file]))\n const reverse = new Map<string, Set<string>>()\n for (const [from, targets] of moduleGraph.edges) {\n for (const target of targets) {\n const importers = reverse.get(target) ?? new Set<string>()\n importers.add(from)\n reverse.set(target, importers)\n }\n }\n\n // Deleted/renamed-away files are absent from the module graph, so resolve\n // every file's imports against a set that still contains those paths — one\n // pass total, not one pass per changed file.\n const augmented = new Set([...fileSet, ...changedFiles])\n let reverseImports: Map<string, Set<string>> | null = null\n const reverseImportIndex = (): Map<string, Set<string>> => {\n if (reverseImports) return reverseImports\n const map = new Map<string, Set<string>>()\n for (const file of index.files) {\n for (const info of file.importDetails ?? []) {\n const target = resolveImport(info.specifier, file.path, augmented)\n if (target === null) continue\n const importers = map.get(target) ?? new Set<string>()\n importers.add(file.path)\n map.set(target, importers)\n }\n }\n reverseImports = map\n return map\n }\n\n const dependents: ImportDependent[] = []\n const seen = new Set<string>()\n for (const changedFile of [...changedFiles].sort((a, b) => a.localeCompare(b))) {\n const importers = new Set(reverse.get(changedFile) ?? [])\n let resolutionSet = fileSet\n if (!fileSet.has(changedFile)) {\n resolutionSet = augmented\n for (const importerPath of reverseImportIndex().get(changedFile) ?? []) {\n importers.add(importerPath)\n }\n }\n for (const importerPath of [...importers].sort((a, b) => a.localeCompare(b))) {\n const importer = filesByPath.get(importerPath)\n if (!importer) continue\n const specifier = specifierFor(importer, changedFile, resolutionSet)\n if (specifier === null) continue\n const key = `${importerPath}\\u0000${changedFile}\\u0000${specifier}`\n if (seen.has(key)) continue\n seen.add(key)\n dependents.push({\n file: importerPath,\n changedFile,\n specifier,\n resolution: 'import-scoped',\n })\n }\n }\n return dependents.sort(\n (a, b) =>\n a.file.localeCompare(b.file) ||\n a.changedFile.localeCompare(b.changedFile) ||\n a.specifier.localeCompare(b.specifier),\n )\n}\n\nfunction specifierFor(file: IndexedFile, target: string, fileSet: Set<string>): string | null {\n for (const info of file.importDetails ?? []) {\n if (resolveImport(info.specifier, file.path, fileSet) === target) return info.specifier\n }\n for (const spec of file.imports ?? []) {\n if (resolveImport(spec, file.path, fileSet) === target) return spec\n }\n return null\n}\n\nconst TEST_RANK: Record<AffectedTest['reason'], number> = {\n 'changed-test': 0,\n 'imports-changed-file': 1,\n 'imports-impact-file': 2,\n 'references-symbol-name': 3,\n 'path-convention': 4,\n}\n\nfunction collectAffectedTests(\n index: RepoIndex,\n moduleGraph: ReturnType<typeof buildModuleGraph>,\n changedFiles: Set<string>,\n changedSymbols: readonly ChangedSymbol[],\n impactRows: readonly ImpactRow[],\n): AffectedTest[] {\n const changedNames = new Set(changedSymbols.map((changed) => changed.symbol.name))\n const impactFileDepth = new Map<string, number>()\n for (const row of impactRows) {\n const previous = impactFileDepth.get(row.symbol.file)\n if (previous === undefined || row.depth < previous) {\n impactFileDepth.set(row.symbol.file, row.depth)\n }\n }\n const changedStems = new Set([...changedFiles].map(pathStem))\n\n const tests: AffectedTest[] = []\n for (const file of index.files) {\n if (!TEST_RE.test(file.path)) continue\n const imports = moduleGraph.edges.get(file.path) ?? new Set<string>()\n\n if (changedFiles.has(file.path)) {\n tests.push({ file: file.path, resolution: 'exact', reason: 'changed-test', distance: 0 })\n continue\n }\n\n const changedImport = [...imports].find(\n (target) => changedFiles.has(target) && target !== file.path,\n )\n if (changedImport !== undefined) {\n tests.push({\n file: file.path,\n resolution: 'import-scoped',\n reason: 'imports-changed-file',\n distance: 1,\n })\n continue\n }\n\n const impactImports = [...imports]\n .filter((target) => impactFileDepth.has(target))\n .sort((a, b) => (impactFileDepth.get(a) ?? 0) - (impactFileDepth.get(b) ?? 0))\n if (impactImports.length > 0) {\n tests.push({\n file: file.path,\n resolution: 'import-scoped',\n reason: 'imports-impact-file',\n distance: impactFileDepth.get(impactImports[0]!) ?? 2,\n })\n continue\n }\n\n if ((file.calls ?? []).some((call) => changedNames.has(call.name))) {\n tests.push({\n file: file.path,\n resolution: 'name-only',\n reason: 'references-symbol-name',\n distance: 1,\n })\n continue\n }\n\n if (changedStems.has(pathStem(file.path))) {\n tests.push({ file: file.path, resolution: 'name-only', reason: 'path-convention' })\n }\n }\n\n return tests.sort(\n (a, b) =>\n TEST_RANK[a.reason] - TEST_RANK[b.reason] ||\n (a.distance ?? Number.MAX_SAFE_INTEGER) - (b.distance ?? Number.MAX_SAFE_INTEGER) ||\n a.file.localeCompare(b.file),\n )\n}\n\n/** Basename stem with test markers removed (`a/foo.test.ts` -> `foo`). */\nfunction pathStem(filePath: string): string {\n const base = filePath.split('/').pop() ?? filePath\n return base\n .replace(/\\.[A-Za-z0-9]+$/, '')\n .replace(/\\.(?:test|spec)$/, '')\n .replace(/^test_/, '')\n .replace(/_test$/, '')\n}\n\nfunction compareChanged(a: ChangedSymbol, b: ChangedSymbol): number {\n return (\n a.side.localeCompare(b.side) ||\n a.symbol.file.localeCompare(b.symbol.file) ||\n a.symbol.line - b.symbol.line ||\n a.symbol.id.localeCompare(b.symbol.id)\n )\n}\n\nfunction compareBySymbol(a: ImpactRow, b: ImpactRow): number {\n return (\n a.symbol.file.localeCompare(b.symbol.file) ||\n a.symbol.line - b.symbol.line ||\n a.symbol.id.localeCompare(b.symbol.id)\n )\n}\n\nfunction compareByDepthThenSymbol(a: ImpactRow, b: ImpactRow): number {\n return (\n a.depth - b.depth ||\n LABEL_STRENGTH[b.resolution] - LABEL_STRENGTH[a.resolution] ||\n compareBySymbol(a, b)\n )\n}\n\nfunction comparePaths(a: SymbolPath, b: SymbolPath): number {\n return (\n a.entry.file.localeCompare(b.entry.file) ||\n a.entry.line - b.entry.line ||\n a.changed.file.localeCompare(b.changed.file) ||\n a.changed.line - b.changed.line ||\n a.entry.id.localeCompare(b.entry.id)\n )\n}\n\nfunction compareUnmapped(a: UnmappedChange, b: UnmappedChange): number {\n return a.file.localeCompare(b.file) || a.side.localeCompare(b.side)\n}\n\n/* -------------------------------------------------------------------------- */\n/* Renderer */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Render the result as fixed skeleton sections. Section headers and warnings\n * are always kept; rows are trimmed to the final character cap, which then\n * appends an explicit truncation line.\n */\nexport function renderChangeContext(result: ChangeContextResult, maxChars = 12_000): string {\n const sections: Array<{ title: string; rows: string[] }> = [\n {\n title: 'CHANGED',\n rows: result.changed.map(\n (changed) =>\n `${changed.change} ${changed.side === 'base' ? 'base ' : ''}${symbolLabel(changed.symbol)} ${changed.symbol.file}:${changed.symbol.line} [${changed.resolution}]`,\n ),\n },\n {\n title: 'DIRECT CALLERS',\n rows: result.directCallers.map(\n (row) =>\n `${symbolLabel(row.symbol)} ${row.symbol.file}:${row.symbol.line} (called at ${row.via.callSite.file}:${row.via.callSite.line}) [${row.resolution}]`,\n ),\n },\n {\n title: 'IMPORT DEPENDENTS',\n rows: result.importDependents.map(\n (dependent) =>\n `${dependent.file} imports ${dependent.changedFile} ('${dependent.specifier}') [${dependent.resolution}]`,\n ),\n },\n {\n title: 'SHORTEST PATHS TO ENTRY POINTS',\n rows: result.paths.map(\n (symbolPath) =>\n `${symbolPath.entry.file}:${symbolPath.entry.line} ${symbolLabel(symbolPath.entry)} → ${symbolPath.changed.file}:${symbolPath.changed.line} ${symbolLabel(symbolPath.changed)} (${symbolPath.hops.length} hop(s)) [${symbolPath.resolution}]`,\n ),\n },\n {\n title: 'TRANSITIVE IMPACT',\n rows: result.impact.map(\n (row) =>\n `depth ${row.depth}: ${symbolLabel(row.symbol)} ${row.symbol.file}:${row.symbol.line} (reached via ${row.via.callSite.file}:${row.via.callSite.line}) [${row.resolution}]`,\n ),\n },\n {\n title: 'LIKELY AFFECTED TESTS',\n rows: result.tests.map(\n (test) =>\n `${test.file} (${test.reason}${test.distance !== undefined ? `, distance ${test.distance}` : ''}) [${test.resolution}]`,\n ),\n },\n {\n title: 'UNMAPPED',\n rows: result.unmapped.map(\n (entry) =>\n `${entry.file} ${entry.side} lines ${entry.ranges.map((range) => `${range.startLine}-${range.endLine}`).join(', ')} (${entry.reason})`,\n ),\n },\n ]\n\n const summary = `change context — source: ${result.source}${\n result.baseRef !== undefined ? ` (base ${result.baseRef})` : ''\n }: ${result.changed.length} changed symbol(s)`\n const warningLines = result.warnings.map((warning) => `- ${warning}`)\n\n const render = (kept: readonly number[]): string => {\n const lines: string[] = [summary]\n sections.forEach((section, index) => {\n if (section.rows.length === 0) {\n lines.push(`${section.title}: (none)`)\n return\n }\n lines.push(`${section.title}:`)\n const take = kept[index] ?? 0\n for (let row = 0; row < take; row++) lines.push(` ${section.rows[row]}`)\n if (take < section.rows.length) lines.push(` … (${section.rows.length - take} more)`)\n })\n lines.push('WARNINGS:')\n if (warningLines.length === 0) lines.push(' (none)')\n else for (const warning of warningLines) lines.push(` ${warning}`)\n return lines.join('\\n')\n }\n\n const flattened: Array<{ section: number; text: string }> = []\n sections.forEach((section, index) => {\n section.rows.forEach((text) => flattened.push({ section: index, text }))\n })\n\n const countsFor = (count: number): number[] => {\n const kept = sections.map(() => 0)\n for (let index = 0; index < count; index++) kept[flattened[index]!.section]!++\n return kept\n }\n\n const total = flattened.length\n const full = render(sections.map((section) => section.rows.length))\n if (full.length <= maxChars) return full\n\n const truncationNote =\n '\\n… truncated rows to fit the character cap (raise maxChars or narrow the change)'\n const headerOnly = render(countsFor(0))\n if (headerOnly.length > maxChars) {\n throw new Error(\n `maxChars ${maxChars} is below the renderer minimum ${headerOnly.length} (section headers and warnings cannot be kept)`,\n )\n }\n if (headerOnly.length + truncationNote.length > maxChars) return headerOnly\n\n const fits = (count: number): boolean =>\n render(countsFor(count)).length + truncationNote.length <= maxChars\n\n let lo = 0\n let hi = total\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n if (fits(mid)) lo = mid\n else hi = mid - 1\n }\n\n let out = render(countsFor(lo))\n if (lo < total) out += truncationNote\n return out\n}\n","/**\n * Task-aware structural context orchestration.\n *\n * This module deliberately contains no parser, search index, graph, or git\n * implementation of its own. It ranks the existing primitives into a compact\n * package that answers the question: which code matters for this task?\n */\n\nimport { buildChangeContext, type ChangeContextResult } from './change-context.js'\nimport { rankRepoMap, scoreFile } from './repomap.js'\nimport {\n buildReferenceGraph,\n callerCounts,\n type ReferenceEdge,\n type ResolutionLabel,\n} from './refgraph.js'\nimport { searchSymbols, type RankedHit } from './search.js'\nimport type { RepoIndex, SymbolInfo } from './types.js'\n\nexport type ContextTaskKind =\n | 'change'\n | 'symbol'\n | 'architecture'\n | 'test'\n | 'exploration'\n | 'ambiguous'\n\nexport interface ContextRoute {\n kind: ContextTaskKind\n queries: string[]\n mentionedFiles: string[]\n exactSymbolNames: string[]\n sources: string[]\n includeChangeContext: boolean\n includeRelationships: boolean\n}\n\nexport interface ContextOptions {\n budgetChars?: number\n maxFiles?: number\n maxSymbols?: number\n}\n\nexport interface ContextSymbol {\n symbol: SymbolInfo\n score: number\n provenance: 'exact' | 'lexical'\n}\n\nexport interface ContextFile {\n path: string\n score: number\n reason: string\n}\n\nexport interface ContextRelationship {\n text: string\n resolution: ResolutionLabel\n priority: number\n key: string\n}\n\nexport interface ContextConfidence {\n exact: number\n 'import-scoped': number\n 'name-only': number\n}\n\nexport interface TaskContextResult {\n root: string\n task: string\n route: ContextRoute\n primarySymbols: ContextSymbol[]\n relevantFiles: ContextFile[]\n relationships: ContextRelationship[]\n changeContext: ChangeContextResult | null\n tests: string[]\n confidence: ContextConfidence\n warnings: string[]\n budget: {\n usedChars: number\n budgetChars: number\n truncated: boolean\n }\n}\n\nconst TEST_PATH_RE =\n /(^|\\/)(tests?|__tests__)(\\/|$)|\\.(?:spec|test)\\.[cm]?[jt]sx?$|(^|\\/)(?:test_[^/]+\\.py|[^/]+_test\\.(?:py|go))$/i\nconst FILE_TOKEN_RE = /[A-Za-z0-9_./\\\\-]+\\.[A-Za-z0-9]+/g\nconst CODE_TOKEN_RE = /[A-Za-z_$][A-Za-z0-9_$]*(?:\\.[A-Za-z_$][A-Za-z0-9_$]*)?/g\nconst STOP_WORDS = new Set(\n [\n 'a',\n 'an',\n 'and',\n 'are',\n 'be',\n 'by',\n 'does',\n 'for',\n 'from',\n 'how',\n 'in',\n 'is',\n 'it',\n 'my',\n 'of',\n 'on',\n 'or',\n 'the',\n 'this',\n 'to',\n 'what',\n 'where',\n 'why',\n 'with',\n ],\n)\n\nconst CHANGE_RE =\n /\\b(fix|bug|broken|breaks?|change|changed|current|working\\s+tree|regression|impact|modified|duplicate|fails?|failure)\\b/i\nconst TEST_RE = /\\b(test|tests|spec|specs|failing|assert|coverage)\\b/i\nconst ARCH_RE =\n /\\b(architecture|architectural|flow|loading|authentication|authorization|plugin|startup|overview|pipeline|lifecycle|design|works?)\\b/i\nconst EXPLORE_RE =\n /\\b(where|implement|add|feature|introduce|entry\\s+point|similar|explore|understand|locate)\\b/i\n\nfunction unique<T>(values: readonly T[], key: (value: T) => string): T[] {\n const seen = new Set<string>()\n const out: T[] = []\n for (const value of values) {\n const id = key(value)\n if (seen.has(id)) continue\n seen.add(id)\n out.push(value)\n }\n return out\n}\n\nfunction clamp(value: number | undefined, min: number, max: number, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback\n return Math.min(max, Math.max(min, Math.floor(value)))\n}\n\nfunction wordBoundary(name: string): RegExp {\n return new RegExp(`(^|[^A-Za-z0-9_$])${name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}(?=$|[^A-Za-z0-9_$])`)\n}\n\nfunction symbolLabel(symbol: SymbolInfo): string {\n return `${symbol.kind} ${symbol.signature || symbol.name} — ${symbol.file}:${symbol.line}`\n}\n\nfunction isTestFile(file: string): boolean {\n return TEST_PATH_RE.test(file)\n}\n\nfunction fileMentionMatches(file: string, mentions: readonly string[]): boolean {\n const lower = file.toLowerCase()\n return mentions.some((mention) => {\n const normalized = mention.replace(/\\\\/g, '/').toLowerCase()\n return lower === normalized || lower.endsWith(`/${normalized}`) || lower.includes(normalized)\n })\n}\n\n/** Classify a task and decide which existing primitives should be composed. */\nexport function routeTask(task: string, index?: RepoIndex): ContextRoute {\n const text = task.trim()\n const mentionedFiles = unique(text.match(FILE_TOKEN_RE) ?? [], (value) => value.toLowerCase())\n .map((value) => value.replace(/\\\\/g, '/'))\n .filter((value) => !index || index.files.some((file) => fileMentionMatches(file.path, [value])))\n\n const exactSymbolNames = index\n ? unique(\n index.files.flatMap((file) => file.symbols.map((symbol) => symbol.name)),\n (name) => name,\n )\n .filter((name) => wordBoundary(name).test(text))\n .sort((a, b) => b.length - a.length || a.localeCompare(b))\n : []\n\n const codeTokens = unique(\n (text.match(CODE_TOKEN_RE) ?? [])\n .map((token) => token.replace(/^[^A-Za-z_$]+|[^A-Za-z0-9_$]+$/g, ''))\n .filter((token) => token.length >= 3 && !STOP_WORDS.has(token.toLowerCase())),\n (token) => token.toLowerCase(),\n )\n const queries = unique(\n [...exactSymbolNames, ...codeTokens.filter((token) => !exactSymbolNames.includes(token))],\n (value) => value.toLowerCase(),\n ).slice(0, 12)\n\n const kind: ContextTaskKind = TEST_RE.test(text) || mentionedFiles.some(isTestFile)\n ? 'test'\n : CHANGE_RE.test(text)\n ? 'change'\n : exactSymbolNames.length > 0\n ? 'symbol'\n : EXPLORE_RE.test(text)\n ? 'exploration'\n : ARCH_RE.test(text)\n ? 'architecture'\n : 'ambiguous'\n\n const includeChangeContext = kind === 'change' || kind === 'test'\n const includeRelationships = kind === 'change' || kind === 'test' || kind === 'symbol'\n const sources = new Set<string>()\n if (kind === 'change' || kind === 'test') sources.add('change context')\n if (kind === 'architecture' || kind === 'exploration' || kind === 'ambiguous') {\n sources.add('repo map')\n }\n if (queries.length > 0) sources.add('ranked search')\n if (includeRelationships) sources.add('call graph')\n if (mentionedFiles.length > 0) sources.add('file relevance')\n if (sources.size === 0) sources.add('repo map')\n\n return {\n kind,\n queries,\n mentionedFiles,\n exactSymbolNames,\n sources: [...sources],\n includeChangeContext,\n includeRelationships,\n }\n}\n\nfunction routeScore(route: ContextRoute, hit: RankedHit): number {\n let score = hit.score * 30\n if (route.exactSymbolNames.includes(hit.name)) score += 100\n if (fileMentionMatches(hit.file, route.mentionedFiles)) score += 30\n if (isTestFile(hit.file) && route.kind !== 'test') score -= 10\n // Structural importance is deliberately capped: it breaks ties but cannot\n // displace a task-specific symbol match.\n return score\n}\n\nfunction gatherPrimarySymbols(\n index: RepoIndex,\n route: ContextRoute,\n maxSymbols: number,\n changedIds: Set<string>,\n changedFiles: Set<string>,\n refs: Map<string, number>,\n): ContextSymbol[] {\n const hits: RankedHit[] = []\n for (const query of route.queries) {\n hits.push(...searchSymbols(index, { query }, Math.max(maxSymbols * 3, 20), refs))\n }\n const byId = new Map<string, ContextSymbol>()\n for (const hit of hits) {\n const exact = route.exactSymbolNames.includes(hit.name)\n let score = routeScore(route, hit)\n if (changedIds.has(hit.id)) score += 80\n else if (changedFiles.has(hit.file)) score += 55\n if (route.kind === 'test' && isTestFile(hit.file)) score += 35\n const candidate: ContextSymbol = { symbol: hit, score, provenance: exact ? 'exact' : 'lexical' }\n const previous = byId.get(hit.id)\n if (!previous || candidate.score > previous.score) byId.set(hit.id, candidate)\n }\n\n // A changed file may contain symbols that were not named in the task. They\n // are important enough to enter the primary set for change-aware tasks.\n if (route.includeChangeContext) {\n for (const file of index.files) {\n if (!changedFiles.has(file.path)) continue\n for (const symbol of file.symbols) {\n if (byId.has(symbol.id)) continue\n byId.set(symbol.id, {\n symbol,\n score: 70,\n provenance: 'lexical',\n })\n }\n }\n }\n\n return [...byId.values()]\n .sort(\n (a, b) =>\n b.score - a.score ||\n Number(b.provenance === 'exact') - Number(a.provenance === 'exact') ||\n a.symbol.file.localeCompare(b.symbol.file) ||\n a.symbol.line - b.symbol.line ||\n a.symbol.id.localeCompare(b.symbol.id),\n )\n .slice(0, maxSymbols)\n}\n\nfunction edgeText(\n graph: ReturnType<typeof buildReferenceGraph>,\n edge: ReferenceEdge,\n direction: 'caller' | 'callee',\n): string {\n const source = edge.sourceId ? graph.symbolsById.get(edge.sourceId) : undefined\n const target = graph.symbolsById.get(edge.targetId)\n const sourceText = source ? `${source.name} (${source.file}:${source.line})` : 'module'\n const targetText = target ? `${target.name} (${target.file}:${target.line})` : edge.name\n const arrow = direction === 'caller' ? `${sourceText} → ${targetText}` : `${sourceText} → ${targetText}`\n return `${arrow} at ${edge.callSite.file}:${edge.callSite.line} [${edge.resolution}; ${edge.provenance}]`\n}\n\nfunction collectRelationships(\n graph: ReturnType<typeof buildReferenceGraph>,\n primary: readonly ContextSymbol[],\n): ContextRelationship[] {\n const rows: ContextRelationship[] = []\n const seen = new Set<string>()\n const add = (edge: ReferenceEdge, direction: 'caller' | 'callee', priority: number): void => {\n const key = `${edge.sourceId ?? 'module'}:${edge.targetId}:${edge.callSite.file}:${edge.callSite.line}`\n if (seen.has(key)) return\n seen.add(key)\n rows.push({\n key,\n text: edgeText(graph, edge, direction),\n resolution: edge.resolution,\n priority,\n })\n }\n for (const candidate of primary) {\n for (const edge of graph.incoming.get(candidate.symbol.id) ?? []) add(edge, 'caller', 100)\n for (const edge of graph.outgoing.get(candidate.symbol.id) ?? []) add(edge, 'callee', 90)\n }\n return rows.sort(\n (a, b) =>\n b.priority - a.priority ||\n a.resolution.localeCompare(b.resolution) ||\n a.text.localeCompare(b.text),\n )\n}\n\nfunction addFile(\n files: Map<string, ContextFile>,\n path: string,\n score: number,\n reason: string,\n): void {\n const previous = files.get(path)\n if (!previous || score > previous.score) files.set(path, { path, score, reason })\n}\n\nfunction gatherFiles(\n index: RepoIndex,\n route: ContextRoute,\n primary: readonly ContextSymbol[],\n change: ChangeContextResult | null,\n maxFiles: number,\n): ContextFile[] {\n const files = new Map<string, ContextFile>()\n for (const file of index.files) {\n const base = Math.min(scoreFile(file), 8)\n if (route.kind === 'architecture' || route.kind === 'exploration' || route.kind === 'ambiguous') {\n addFile(files, file.path, base, 'structural importance')\n }\n if (fileMentionMatches(file.path, route.mentionedFiles)) addFile(files, file.path, 120, 'task-mentioned file')\n }\n for (const candidate of primary) {\n addFile(files, candidate.symbol.file, candidate.score + 45, 'primary symbol')\n }\n if (change) {\n for (const changed of change.changed) addFile(files, changed.symbol.file, 115, 'current change')\n for (const dependent of change.importDependents) addFile(files, dependent.file, 65, 'import dependent')\n for (const test of change.tests) addFile(files, test.file, 75, 'likely affected test')\n for (const pathRow of change.paths) {\n addFile(files, pathRow.entry.file, 60, 'entry path')\n addFile(files, pathRow.changed.file, 90, 'changed path')\n }\n }\n for (const entry of rankRepoMap(index, { topFiles: maxFiles * 2, symbolsPerFile: 8 })) {\n addFile(files, entry.path, Math.min(35, entry.score + 10), 'repo map')\n }\n return [...files.values()]\n .sort((a, b) => b.score - a.score || a.path.localeCompare(b.path))\n .slice(0, maxFiles)\n}\n\nfunction confidenceOf(\n primary: readonly ContextSymbol[],\n relationships: readonly ContextRelationship[],\n change: ChangeContextResult | null,\n): ContextConfidence {\n const out: ContextConfidence = { exact: 0, 'import-scoped': 0, 'name-only': 0 }\n for (const symbol of primary) if (symbol.provenance === 'exact') out.exact++\n for (const relation of relationships) out[relation.resolution]++\n if (change) {\n for (const row of [...change.directCallers, ...change.impact]) out[row.resolution]++\n for (const dependent of change.importDependents) out[dependent.resolution]++\n for (const test of change.tests) out[test.resolution]++\n }\n return out\n}\n\nfunction renderRows(\n result: Omit<TaskContextResult, 'budget'>,\n budgetChars: number,\n): { text: string; usedChars: number; truncated: boolean } {\n const lines = [\n `Task context — ${result.route.kind}`,\n `Task: ${result.task}`,\n `Sources: ${result.route.sources.join(', ')}`,\n '',\n 'Primary symbols:',\n ]\n if (result.primarySymbols.length === 0) lines.push('- (none found)')\n\n const optional: Array<{ priority: number; key: string; line: string; section: string }> = []\n for (const candidate of result.primarySymbols) {\n optional.push({\n priority: 1000 + candidate.score,\n key: `symbol:${candidate.symbol.id}`,\n section: 'primary',\n line: `- [${candidate.provenance}] ${symbolLabel(candidate.symbol)}`,\n })\n }\n optional.push({ priority: 700, key: 'files-header', section: 'files', line: '\\nRelevant files:' })\n for (const file of result.relevantFiles) {\n optional.push({ priority: 500 + file.score, key: `file:${file.path}`, section: 'files', line: `- ${file.path} (${file.reason})` })\n }\n optional.push({ priority: 400, key: 'relationships-header', section: 'relationships', line: '\\nRelationships:' })\n for (const relation of result.relationships) {\n optional.push({ priority: relation.priority, key: `relation:${relation.key}`, section: 'relationships', line: `- ${relation.text}` })\n }\n if (result.changeContext) {\n optional.push({ priority: 850, key: 'changes-header', section: 'changes', line: '\\nCurrent changes:' })\n for (const changed of result.changeContext.changed) {\n optional.push({\n priority: 840,\n key: `changed:${changed.side}:${changed.symbol.id}`,\n section: 'changes',\n line: `- ${changed.change} ${symbolLabel(changed.symbol)} [${changed.resolution}]`,\n })\n }\n if (result.changeContext.unmapped.length > 0) {\n optional.push({\n priority: 830,\n key: 'changes-unmapped',\n section: 'changes',\n line: `- unmapped: ${result.changeContext.unmapped.map((entry) => entry.file).join(', ')}`,\n })\n }\n }\n if (result.tests.length > 0) {\n optional.push({ priority: 350, key: 'tests-header', section: 'tests', line: '\\nLikely affected tests:' })\n for (const test of result.tests) optional.push({ priority: 340, key: `test:${test}`, section: 'tests', line: `- ${test}` })\n }\n if (result.warnings.length > 0) {\n optional.push({ priority: 200, key: 'warnings-header', section: 'warnings', line: '\\nWarnings:' })\n for (const warning of result.warnings) optional.push({ priority: 190, key: `warning:${warning}`, section: 'warnings', line: `- ${warning}` })\n }\n\n // Keep core sections ahead of weak candidates while preserving deterministic\n // order inside each priority band. Reserve room for the accounting footer.\n const ordered = optional\n .map((item, index) => ({ ...item, index }))\n .sort((a, b) => b.priority - a.priority || a.index - b.index || a.key.localeCompare(b.key))\n const footerReserve = 100\n let truncated = false\n const seen = new Set<string>()\n for (const item of ordered) {\n if (seen.has(item.key)) continue\n const next = lines.join('\\n') + `\\n${item.line}`\n if (next.length + footerReserve > budgetChars) {\n truncated = true\n continue\n }\n seen.add(item.key)\n lines.push(item.line)\n }\n lines.push(\n '',\n `Confidence: exact ${result.confidence.exact}; import-scoped ${result.confidence['import-scoped']}; name-only ${result.confidence['name-only']}`,\n )\n const body = lines.join('\\n')\n const withFooter = (bodyText: string, wasTruncated: boolean): { text: string; usedChars: number } => {\n let usedChars = bodyText.length + 1\n for (let iteration = 0; iteration < 10; iteration++) {\n const footer = `Budget: ${usedChars} / ${budgetChars} chars${wasTruncated ? ' (trimmed low-priority context)' : ''}`\n const text = `${bodyText}\\n${footer}`\n const nextUsedChars = text.length\n if (nextUsedChars === usedChars) return { text, usedChars: nextUsedChars }\n usedChars = nextUsedChars\n }\n const footer = `Budget: ${usedChars} / ${budgetChars} chars${wasTruncated ? ' (trimmed low-priority context)' : ''}`\n const text = `${bodyText}\\n${footer}`\n return { text, usedChars: text.length }\n }\n\n const complete = withFooter(body, truncated)\n if (complete.usedChars <= budgetChars) {\n return { text: complete.text, usedChars: complete.usedChars, truncated }\n }\n\n // The optional-row reserve above is intentionally conservative, but the\n // task and confidence lines are user-controlled/derived text. If they still\n // push the result over budget, truncate the body and recompute the footer so\n // both the bytes and the accounting remain truthful.\n truncated = true\n const candidate = (prefixLength: number): { text: string; usedChars: number } => {\n const prefix = `${body.slice(0, prefixLength).trimEnd()}…`\n return withFooter(prefix, true)\n }\n let low = 0\n let high = body.length\n let best = candidate(0)\n while (low <= high) {\n const middle = Math.floor((low + high) / 2)\n const current = candidate(middle)\n if (current.usedChars <= budgetChars) {\n best = current\n low = middle + 1\n } else {\n high = middle - 1\n }\n }\n return { text: best.text, usedChars: best.usedChars, truncated }\n}\n\n/** Build a deterministic, bounded context package from the current task. */\nexport async function buildTaskContext(\n index: RepoIndex,\n task: string,\n options: ContextOptions = {},\n): Promise<TaskContextResult> {\n const budgetChars = clamp(options.budgetChars, 300, 20_000, 5_000)\n const maxFiles = clamp(options.maxFiles, 1, 50, 12)\n const maxSymbols = clamp(options.maxSymbols, 1, 50, 10)\n const route = routeTask(task, index)\n let changeContext: ChangeContextResult | null = null\n const warnings: string[] = []\n\n if (route.includeChangeContext) {\n try {\n changeContext = await buildChangeContext(index, {\n kind: 'git',\n root: index.root,\n baseRef: 'HEAD',\n })\n warnings.push(...changeContext.warnings)\n } catch (error) {\n warnings.push(`change context unavailable: ${(error as Error).message ?? String(error)}`)\n }\n }\n\n const changedIds = new Set((changeContext?.changed ?? []).map((entry) => entry.symbol.id))\n const changedFiles = new Set((changeContext?.changed ?? []).map((entry) => entry.symbol.file))\n const primarySymbols = gatherPrimarySymbols(\n index,\n route,\n maxSymbols,\n changedIds,\n changedFiles,\n callerCounts(index),\n )\n const graph = route.includeRelationships ? buildReferenceGraph(index) : null\n const relationships = graph ? collectRelationships(graph, primarySymbols) : []\n if (changeContext) {\n const existing = new Set(relationships.map((row) => row.key))\n for (const row of changeContext.directCallers) {\n const key = `change:${row.symbol.id}:${row.via.callSite.file}:${row.via.callSite.line}`\n if (existing.has(key)) continue\n existing.add(key)\n relationships.push({\n key,\n text: `${row.symbol.name} (${row.symbol.file}:${row.symbol.line}) → changed symbol at ${row.via.callSite.file}:${row.via.callSite.line} [${row.resolution}; ${row.via.reason}]`,\n resolution: row.resolution,\n priority: 110,\n })\n }\n relationships.sort((a, b) => b.priority - a.priority || a.text.localeCompare(b.text))\n }\n const relevantFiles = gatherFiles(index, route, primarySymbols, changeContext, maxFiles)\n const tests = unique(changeContext?.tests.map((test) => test.file) ?? [], (file) => file)\n const confidence = confidenceOf(primarySymbols, relationships, changeContext)\n const partial: Omit<TaskContextResult, 'budget'> = {\n root: index.root,\n task,\n route,\n primarySymbols,\n relevantFiles,\n relationships,\n changeContext,\n tests,\n confidence,\n warnings,\n }\n const rendered = renderRows(partial, budgetChars)\n return {\n ...partial,\n budget: {\n usedChars: rendered.usedChars,\n budgetChars,\n truncated: rendered.truncated,\n },\n }\n}\n\n/** Render the result using the same compact text surface as the existing tools. */\nexport function renderTaskContext(result: TaskContextResult): string {\n const rendered = renderRows(result, result.budget.budgetChars)\n return rendered.text\n}\n","/** Model-visible tools: code_index, code_symbols, code_search. */\n\nimport { defineTool } from '@deepseek-ai/dsh-tools'\nimport path from 'node:path'\nimport { buildIndexWithCache, findRepoRoot } from './buildIndex.js'\nimport { renderHit, searchSymbols } from './search.js'\nimport { rankRepoMap, renderRepoMap } from './repomap.js'\nimport { symbolRefs } from './refgraph.js'\nimport { findCycles, findOrphanModules } from './health.js'\nimport {\n buildChangeContext,\n changeContextInputFromArgs,\n renderChangeContext,\n} from './change-context.js'\nimport { buildTaskContext, renderTaskContext } from './context.js'\nimport { getConfig, indexOptions } from './config.js'\nimport { RepoContextManager } from './repo-context.js'\nimport type { RepoIndex } from './types.js'\n\n/** Minimal structural types for the harness surfaces we touch. */\ninterface ToolCwdContext {\n agent?: {\n session?: { header?: { cwd?: string } }\n }\n session?: { header?: { cwd?: string } }\n cwd?: string\n}\ntype ToolRunExec = ToolCwdContext & { signal?: AbortSignal }\n\ninterface TextBlock {\n type: 'text'\n text: string\n}\n\ntype JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }\n\nlet activeRepoContexts: RepoContextManager | null = null\n\nexport function activateRepoContextManager(manager: RepoContextManager | null): void {\n activeRepoContexts = manager\n}\n\nexport function clearRepoContextManager(manager: RepoContextManager): void {\n if (activeRepoContexts === manager) activeRepoContexts = null\n}\n\nexport function getIndex(root: string, force = false): Promise<RepoIndex> {\n return activeRepoContexts\n ? activeRepoContexts.get(root, force)\n : buildIndexWithCache(root, indexOptions(), undefined, force ? new Set(['*']) : undefined)\n}\n\nexport function invalidateIndexCache(): void {\n // Context ownership is scoped to plugin apply/dispose; no global snapshot survives reload.\n}\n\nasync function resolveRoot(arg: string | undefined, exec: ToolRunExec): Promise<string> {\n const cwd = exec.agent?.session?.header?.cwd ?? exec.session?.header?.cwd ?? exec.cwd\n const base = arg ?? cwd ?? process.cwd()\n const root = await findRepoRoot(base)\n if (!root) throw new Error(`no git repository found from ${path.resolve(base)}`)\n return root\n}\n\n/** Group hit rows into the search card's matches shape for UI replay. */\nfunction hitsToSearchMeta(hits: JsonValue[]): JsonValue {\n const byFile = new Map<string, Array<{ lineNumber: number; line: string }>>()\n for (const raw of hits) {\n const hit = raw as unknown as {\n file?: string\n line?: number\n kind?: string\n name?: string\n signature?: string\n }\n if (!hit.file || typeof hit.line !== 'number') continue\n const label = `${hit.kind ?? ''} ${hit.signature || hit.name || ''}`.trim()\n const list = byFile.get(hit.file) ?? []\n list.push({ lineNumber: hit.line, line: label })\n byFile.set(hit.file, list)\n }\n return {\n shape: 'matches',\n files: [...byFile.entries()].map(([path, matches]) => ({ path, matches })),\n truncated: false,\n total: hits.length,\n }\n}\n\n/** Narrow persisted presentation metadata back into a completed search card. */\nfunction searchCardFromMeta(meta: JsonValue | undefined):\n | {\n card: 'search'\n shape: 'matches'\n files: Array<{ path: string; matches: Array<{ lineNumber: number; line: string }> }>\n truncated: boolean\n total: number\n }\n | undefined {\n if (!meta || typeof meta !== 'object' || Array.isArray(meta)) return undefined\n const record = meta as Record<string, JsonValue>\n if (record.shape !== 'matches' || !Array.isArray(record.files)) return undefined\n const files = record.files.filter(\n (entry): entry is { path: string; matches: Array<{ lineNumber: number; line: string }> } =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry),\n )\n return {\n card: 'search',\n shape: 'matches',\n files,\n truncated: record.truncated === true,\n total: typeof record.total === 'number' ? record.total : 0,\n }\n}\n\nexport const tools = [\n defineTool({\n name: 'code_index',\n description:\n 'Manage the code index: status or (re)build it for the current workspace. Auto-builds the first time it is queried. Returns file/symbol counts and the index location.',\n parameters: {\n action: {\n type: 'string',\n enum: ['status', 'build'],\n description: '\"status\" (default) reports without forcing a rebuild; \"build\" forces a fresh scan.',\n },\n repoRoot: {\n type: 'string',\n description:\n 'Optional absolute repo path. Defaults to the workspace root of the current session.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n async execute(args: { action?: string; repoRoot?: string }, exec: ToolRunExec): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root, args.action === 'build')\n const total = index.files.reduce((n, f) => n + f.symbols.length, 0)\n const langs = new Set(index.files.map((f) => f.lang))\n return [\n `repo: ${root}`,\n `files indexed: ${index.files.length}`,\n `symbols: ${total}`,\n `languages: ${[...langs].join(', ')}`,\n index.files.length === 0 ? 'no supported files found' : 'index up to date',\n ].join('\\n')\n } catch (error) {\n return `code_index: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_symbols',\n description:\n 'List symbols (functions, classes, interfaces, types, methods, variables) in the current repo. Filter by name substring, file path substring, or symbol kind. Results are exported-first, alphabetically ordered.',\n parameters: {\n query: {\n type: 'string',\n description: 'Substring of the symbol name to match (case-insensitive). Omit to list all.',\n },\n file: {\n type: 'string',\n description: 'Substring of the repo-relative file path to match, e.g. \"src/core\".',\n },\n kind: {\n type: 'string',\n enum: ['function', 'method', 'class', 'interface', 'type', 'enum', 'variable', 'field'],\n description: 'Only return symbols of this kind.',\n },\n exportedOnly: {\n type: 'boolean',\n description: 'Only exported (module-level public) symbols.',\n },\n limit: {\n type: 'number',\n description: 'Max rows (default 50).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'array' },\n render: (_args, value: JsonValue[]): TextBlock[] =>\n value.map((v) => ({\n type: 'text' as const,\n text: renderHit(v as unknown as Parameters<typeof renderHit>[0]),\n })),\n presentationMeta: (_args, value) => hitsToSearchMeta(value),\n },\n presentCall: (args) => ({\n card: 'generic',\n title: args.kind ? `List ${args.kind} symbols` : 'List symbols',\n kind: 'search',\n rawInput: { query: args.query, file: args.file, kind: args.kind },\n }),\n presentResult: (_args, result) => searchCardFromMeta(result.meta),\n async execute(\n args: {\n query?: string\n file?: string\n kind?: 'function' | 'method' | 'class' | 'interface' | 'type' | 'enum' | 'variable' | 'field'\n exportedOnly?: boolean\n limit?: number\n repoRoot?: string\n },\n exec: ToolRunExec,\n ): Promise<JsonValue[]> {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const hits = searchSymbols(\n index,\n { query: args.query, file: args.file, kind: args.kind, exportedOnly: args.exportedOnly },\n args.limit ?? 50,\n )\n return hits as unknown as JsonValue[]\n },\n }),\n\n defineTool({\n name: 'code_search',\n description:\n 'Ranked symbol search over the repo index: exact > prefix > substring name matches, exported symbols first. Results carry a relevance score and file:line, so the model can locate definitions quickly.',\n parameters: {\n query: {\n type: 'string',\n required: true,\n description: 'Symbol name (or fragment) to find.',\n },\n limit: {\n type: 'number',\n description: 'Max hits (default 20).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'array' },\n render: (_args, value: JsonValue[]): TextBlock[] =>\n value.map((v) => ({\n type: 'text' as const,\n text: renderHit(v as unknown as Parameters<typeof renderHit>[0]),\n })),\n presentationMeta: (_args, value) => hitsToSearchMeta(value),\n },\n presentCall: (args) => ({\n card: 'generic',\n title: `Search \"${args.query}\"`,\n kind: 'search',\n rawInput: { query: args.query },\n }),\n presentResult: (_args, result) => searchCardFromMeta(result.meta),\n async execute(\n args: { query: string; limit?: number; repoRoot?: string },\n exec: ToolRunExec,\n ): Promise<JsonValue[]> {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const hits = searchSymbols(index, { query: args.query }, args.limit ?? 20)\n return hits as unknown as JsonValue[]\n },\n }),\n\n defineTool({\n name: 'code_map',\n description:\n 'Return a bounded, ranked map of the current repo (top files by symbol density, with their key symbols and lines). The model can call this once per session to build an internal model of the codebase before browsing files.',\n parameters: {\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n async execute(args: { repoRoot?: string }, exec: ToolRunExec): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const cfg = getConfig()\n const map = renderRepoMap(\n rankRepoMap(index, { topFiles: cfg.mapTopFiles }),\n { maxChars: cfg.mapMaxChars },\n )\n if (!map) return 'no indexable symbols found in this repo'\n return map\n } catch (error) {\n return `code_index: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_refs',\n description:\n 'Trace a symbol through the call graph: who calls it (callers) and what it calls (callees), resolved to in-repo definitions with file:line. Complements code_search — search finds a definition, code_refs shows how it is used. Resolution is name-based, so like-named symbols are reported as candidate definitions.',\n parameters: {\n symbol: {\n type: 'string',\n required: true,\n description: 'Symbol name to trace (case-sensitive).',\n },\n direction: {\n type: 'string',\n enum: ['callers', 'callees', 'both'],\n description: 'Which side of the call graph to return (default \"both\").',\n },\n limit: {\n type: 'number',\n description: 'Max rows per side (default 50).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n presentCall: (args) => ({\n card: 'generic',\n title: `Refs ${args.symbol}`,\n kind: 'search',\n rawInput: { symbol: args.symbol, direction: args.direction },\n }),\n async execute(\n args: { symbol: string; direction?: string; limit?: number; repoRoot?: string },\n exec: ToolRunExec,\n ): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const refs = symbolRefs(index, args.symbol, args.limit ?? 50)\n const direction = args.direction ?? 'both'\n const lines: string[] = []\n\n if (refs.defs.length > 0) {\n lines.push('definitions:')\n for (const def of refs.defs) {\n lines.push(` ${def.kind} ${def.signature || def.name} — ${def.file}:${def.line}`)\n }\n } else {\n lines.push(`no definition of \"${args.symbol}\" in this repo`)\n }\n\n if (direction === 'callers' || direction === 'both') {\n lines.push('', `callers (${refs.callers.length}):`)\n if (refs.callers.length === 0) lines.push(' (none)')\n for (const caller of refs.callers) {\n lines.push(` ${caller.file}:${caller.line}${caller.from ? ` in ${caller.from}` : ''}`)\n }\n }\n\n if (direction === 'callees' || direction === 'both') {\n lines.push('', `callees (${refs.callees.length}):`)\n if (refs.callees.length === 0) lines.push(' (none)')\n for (const callee of refs.callees) {\n const target = callee.targets[0]\n lines.push(\n ` ${callee.name} :${callee.line}${target ? ` → ${target.file}:${target.line}` : ' (external)'}`,\n )\n }\n }\n\n return lines.join('\\n')\n } catch (error) {\n return `code_refs: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_change_context',\n description:\n 'Return the smallest change-aware context for the current diff: changed symbols, direct callers, import dependents, shortest paths to entry points, transitive impact, and likely affected tests. Every relation is labeled exact / import-scoped / name-only, so confidence is explicit. Select the change with an explicit diff, a list of files, a list of symbol ids, or (default) the working tree against baseRef.',\n parameters: {\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n diff: {\n type: 'string',\n description: 'Caller-supplied unified diff text; when present no git command runs.',\n },\n baseRef: {\n type: 'string',\n description: 'Git ref to diff against (default \"HEAD\"); also the baseline read for deletions.',\n },\n files: {\n type: 'array',\n items: { type: 'string' },\n description: 'Repo-relative files to treat as wholly changed (mutually exclusive with diff/symbols).',\n },\n symbols: {\n type: 'array',\n items: { type: 'string' },\n description: 'SymbolInfo ids to treat as changed (mutually exclusive with diff/files).',\n },\n maxDepth: {\n type: 'number',\n description: 'Transitive caller depth, 1..6 (default 3).',\n },\n maxImpact: {\n type: 'number',\n description: 'Max direct-caller / impact / dependent rows, 1..200 (default 40).',\n },\n maxPaths: {\n type: 'number',\n description: 'Max entry-point paths, 1..50 (default 10).',\n },\n maxTests: {\n type: 'number',\n description: 'Max affected-test rows, 1..100 (default 20).',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n presentCall: (args) => ({\n card: 'generic',\n title: 'Change context',\n kind: 'search',\n rawInput: {\n baseRef: args.baseRef,\n files: args.files,\n symbols: args.symbols,\n diff: args.diff !== undefined ? '(inline diff)' : undefined,\n },\n }),\n async execute(\n args: {\n repoRoot?: string\n diff?: string\n baseRef?: string\n files?: string[]\n symbols?: string[]\n maxDepth?: number\n maxImpact?: number\n maxPaths?: number\n maxTests?: number\n },\n exec: ToolRunExec,\n ): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const input = changeContextInputFromArgs(args, root)\n const result = await buildChangeContext(index, input, {\n maxDepth: args.maxDepth,\n maxImpact: args.maxImpact,\n maxPaths: args.maxPaths,\n maxTests: args.maxTests,\n })\n return renderChangeContext(result)\n } catch (error) {\n return `code_change_context: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_context',\n description:\n 'Return the smallest useful structural context for a code task. Pass the task in plain language; the deterministic router combines ranked symbols, relevant files, call/import relationships, repository structure, current Git changes, affected tests, provenance, and a hard character budget. Existing specialized tools remain available for focused follow-up queries.',\n parameters: {\n task: {\n type: 'string',\n required: true,\n description: 'The code task or question the agent is currently trying to complete.',\n },\n budgetChars: {\n type: 'number',\n description: 'Hard output budget in characters (default 5000).',\n },\n maxFiles: {\n type: 'number',\n description: 'Maximum relevant files to include (default 12).',\n },\n maxSymbols: {\n type: 'number',\n description: 'Maximum primary symbols to include (default 10).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n presentCall: (args) => ({\n card: 'generic',\n title: 'Task context',\n kind: 'search',\n rawInput: { task: args.task, budgetChars: args.budgetChars },\n }),\n async execute(\n args: {\n task: string\n budgetChars?: number\n maxFiles?: number\n maxSymbols?: number\n repoRoot?: string\n },\n exec: ToolRunExec,\n ): Promise<string> {\n try {\n if (typeof args.task !== 'string' || args.task.trim().length === 0) {\n throw new Error('task must be a non-empty string')\n }\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const result = await buildTaskContext(index, args.task, {\n budgetChars: args.budgetChars,\n maxFiles: args.maxFiles,\n maxSymbols: args.maxSymbols,\n })\n return renderTaskContext(result)\n } catch (error) {\n return `code_context: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n\n defineTool({\n name: 'code_health',\n description:\n 'Report structural health from the import graph: circular dependencies (import cycles) and orphan modules (symbol-bearing files that nothing imports and that import nothing, excluding entry points and tests).',\n parameters: {\n limit: {\n type: 'number',\n description: 'Max cycles and orphan rows to list (default 50).',\n },\n repoRoot: {\n type: 'string',\n description: 'Optional absolute repo path; defaults to the session workspace root.',\n },\n },\n output: {\n schema: { type: 'string' },\n render: (_args, value: string): TextBlock[] => [{ type: 'text', text: value }],\n },\n presentCall: () => ({ card: 'generic', title: 'Code health', kind: 'read' }),\n async execute(args: { limit?: number; repoRoot?: string }, exec: ToolRunExec): Promise<string> {\n try {\n const root = await resolveRoot(args.repoRoot, exec)\n const index = await getIndex(root)\n const limit = args.limit ?? 50\n const cycles = findCycles(index)\n const orphans = findOrphanModules(index)\n\n const lines = [`repo health — ${index.files.length} files`]\n lines.push('', `circular dependencies (${cycles.length}):`)\n if (cycles.length === 0) lines.push(' (none)')\n for (const cycle of cycles.slice(0, limit)) lines.push(` ${cycle.join(' → ')}`)\n\n lines.push('', `orphan modules (${orphans.length}):`)\n if (orphans.length === 0) lines.push(' (none)')\n for (const orphan of orphans.slice(0, limit)) lines.push(` ${orphan}`)\n\n return lines.join('\\n')\n } catch (error) {\n return `code_health: ${(error as Error).message ?? String(error)}`\n }\n },\n }),\n]\n","/** Plugin configuration: merged once at apply time, read wherever needed. */\n\nimport type { IndexOptions } from './types.js'\nimport Schema from '@deepseek-ai/schemastery'\n\n/** DSH 0.1.7+ renders fields marked volatile in its per-plugin config forms. */\nexport const Config = Schema.object({\n excludeDirs: Schema.array(Schema.string()).default([]).volatile(),\n mapTopFiles: Schema.number().default(24).volatile(),\n mapMaxChars: Schema.number().default(3200).volatile(),\n mapTtlMs: Schema.number().default(60_000).volatile(),\n autoInject: Schema.boolean().default(true).volatile(),\n codeHealth: Schema.boolean().default(false).volatile(),\n toolSurface: Schema.string().default('full').volatile(),\n externalWatch: Schema.boolean().default(true).volatile(),\n watchDebounceMs: Schema.number().default(120).volatile(),\n})\n\nexport interface PluginConfig {\n /** Extra directories to exclude from indexing (appended to defaults). */\n excludeDirs?: string[]\n /** Max files in the ranked repo map (code_map / auto section). */\n mapTopFiles?: number\n /** Hard char cap for rendered maps. */\n mapMaxChars?: number\n /** Refresh interval for the auto-injected map (ms, min 1000). */\n mapTtlMs?: number\n /** Set false to disable the auto-injected system section. */\n autoInject?: boolean\n /** Register the code_health tool (circles / orphans). Off by default. */\n codeHealth?: boolean\n /** Experimental tool surface; full preserves the complete v0.6 API. */\n toolSurface?: 'full' | 'compact'\n /** Observe source changes made by editors and external tools. */\n externalWatch?: boolean\n /** Coalesce filesystem events before refreshing affected files. */\n watchDebounceMs?: number\n}\n\ninterface EffectiveConfig {\n excludeDirs: string[]\n mapTopFiles: number\n mapMaxChars: number\n mapTtlMs: number\n autoInject: boolean\n codeHealth: boolean\n toolSurface: 'full' | 'compact'\n externalWatch: boolean\n watchDebounceMs: number\n}\n\nconst DEFAULTS: EffectiveConfig = {\n excludeDirs: [],\n mapTopFiles: 24,\n mapMaxChars: 3200,\n mapTtlMs: 60_000,\n autoInject: true,\n codeHealth: false,\n toolSurface: 'full',\n externalWatch: true,\n watchDebounceMs: 120,\n}\n\nconst state: { current: EffectiveConfig } = { current: { ...DEFAULTS } }\n\n/** Merge a plugin-provided partial config over the defaults (idempotent). */\nexport function applyConfig(partial?: PluginConfig): void {\n const resolved = partial\n ? Object.fromEntries(Object.entries(partial).map(([key, value]) => [key, unwrapVolatile(value)])) as PluginConfig\n : undefined\n state.current = {\n ...DEFAULTS,\n ...(resolved ?? {}),\n excludeDirs: [...DEFAULTS.excludeDirs, ...(resolved?.excludeDirs ?? [])],\n }\n // Coerce obviously wrong inputs.\n if (!Number.isFinite(state.current.mapTopFiles) || state.current.mapTopFiles < 1) {\n state.current.mapTopFiles = DEFAULTS.mapTopFiles\n }\n if (!Number.isFinite(state.current.mapMaxChars) || state.current.mapMaxChars < 200) {\n state.current.mapMaxChars = DEFAULTS.mapMaxChars\n }\n if (!Number.isFinite(state.current.mapTtlMs) || state.current.mapTtlMs < 1_000) {\n state.current.mapTtlMs = DEFAULTS.mapTtlMs\n }\n if (state.current.toolSurface !== 'full' && state.current.toolSurface !== 'compact') {\n state.current.toolSurface = DEFAULTS.toolSurface\n }\n if (typeof state.current.externalWatch !== 'boolean') state.current.externalWatch = DEFAULTS.externalWatch\n if (!Number.isFinite(state.current.watchDebounceMs) || state.current.watchDebounceMs < 20) {\n state.current.watchDebounceMs = DEFAULTS.watchDebounceMs\n }\n}\n\nfunction unwrapVolatile<T>(value: T): T {\n if (typeof value !== 'object' || value === null || !('get' in value) || typeof value.get !== 'function') {\n return value\n }\n return value.get() as T\n}\n\nexport function getConfig(): Readonly<EffectiveConfig> {\n return state.current\n}\n\n/** Map the effective config onto the index pipeline options. */\nexport function indexOptions(): IndexOptions {\n return { excludeDirs: state.current.excludeDirs }\n}\n","import { realpath } from 'node:fs/promises'\nimport path from 'node:path'\nimport chokidar, { type FSWatcher } from 'chokidar'\nimport { buildIndexWithCache } from './buildIndex.js'\nimport { DEFAULT_EXCLUDED_DIRS, isGitIgnoredPath, SUPPORTED_EXTS, type GitIgnoreMatcherCache } from './scan.js'\nimport { cacheKeyForRoot } from './store.js'\nimport type { IndexOptions, RepoIndex } from './types.js'\n\nexport interface RepoContext {\n readonly root: string\n index: RepoIndex | null\n lastRefreshAt: number\n readonly dirtyFiles: Set<string>\n readonly ignoreMatcherCache: GitIgnoreMatcherCache\n watcher: FSWatcher | null\n debounceTimer: ReturnType<typeof setTimeout> | null\n refresh: Promise<RepoIndex> | null\n disposed: boolean\n generation: number\n lastUsedAt: number\n}\n\nexport interface RepoContextManagerOptions {\n indexOptions: () => IndexOptions\n watch?: boolean\n debounceMs?: number\n maxContexts?: number\n onRefresh?: (root: string, index: RepoIndex) => void\n}\n\nfunction ignoredRelativePath(rel: string, options: IndexOptions): boolean {\n const components = rel.split(/[\\\\/]+/).filter(Boolean)\n const excluded = new Set([...DEFAULT_EXCLUDED_DIRS, ...(options.excludeDirs ?? [])])\n return components.some((component) => excluded.has(component))\n}\n\nexport async function canonicalRepoRoot(root: string): Promise<string> {\n const resolved = await realpath(path.resolve(root))\n return path.normalize(resolved)\n}\n\n/**\n * Bounded per-worktree context cache. Every tool read performs a cheap mtime\n * scan and reparses only files dirtied by watcher events or scan metadata.\n */\nexport class RepoContextManager {\n private readonly contexts = new Map<string, RepoContext>()\n private readonly options: Required<Omit<RepoContextManagerOptions, 'onRefresh'>> &\n Pick<RepoContextManagerOptions, 'onRefresh'>\n private disposed = false\n\n constructor(options: RepoContextManagerOptions) {\n this.options = {\n indexOptions: options.indexOptions,\n watch: options.watch ?? true,\n debounceMs: Math.max(20, options.debounceMs ?? 120),\n maxContexts: Math.max(1, options.maxContexts ?? 4),\n onRefresh: options.onRefresh,\n }\n }\n\n async get(root: string, force = false): Promise<RepoIndex> {\n if (this.disposed) throw new Error('repo context manager is disposed')\n const canonical = await canonicalRepoRoot(root)\n const key = cacheKeyForRoot(canonical)\n let context = this.contexts.get(key)\n if (!context) {\n context = {\n root: canonical,\n index: null,\n lastRefreshAt: 0,\n dirtyFiles: new Set(),\n ignoreMatcherCache: new Map(),\n watcher: null,\n debounceTimer: null,\n refresh: null,\n disposed: false,\n generation: 0,\n lastUsedAt: Date.now(),\n }\n this.contexts.set(key, context)\n this.attachWatcher(context)\n this.evictInactive()\n } else {\n this.contexts.delete(key)\n this.contexts.set(key, context)\n context.lastUsedAt = Date.now()\n }\n let index = await this.refresh(context, force)\n // A filesystem event can arrive while the first refresh is in flight.\n // Drain its dirty set before returning so the requesting tool sees it.\n while (!context.disposed && context.dirtyFiles.size > 0) {\n if (context.refresh) await context.refresh\n else index = await this.refresh(context)\n }\n return index\n }\n\n getContext(root: string): RepoContext | undefined {\n const key = cacheKeyForRoot(path.resolve(root))\n return this.contexts.get(key)\n }\n\n async dispose(): Promise<void> {\n if (this.disposed) return\n this.disposed = true\n const contexts = [...this.contexts.values()]\n this.contexts.clear()\n await Promise.all(contexts.map((context) => this.disposeContext(context)))\n }\n\n reconfigure(options: { watch?: boolean; debounceMs?: number }): void {\n if (options.debounceMs !== undefined) this.options.debounceMs = Math.max(20, options.debounceMs)\n if (options.watch === undefined || options.watch === this.options.watch) return\n this.options.watch = options.watch\n for (const context of this.contexts.values()) {\n if (options.watch) this.attachWatcher(context)\n else {\n if (context.debounceTimer) clearTimeout(context.debounceTimer)\n context.debounceTimer = null\n const watcher = context.watcher\n context.watcher = null\n void watcher?.close()\n }\n }\n }\n\n private async refresh(context: RepoContext, force = false): Promise<RepoIndex> {\n if (context.refresh) {\n const index = await context.refresh\n return force ? this.refresh(context, true) : index\n }\n const generation = context.generation\n const dirty = force ? new Set(['*']) : new Set(context.dirtyFiles)\n context.dirtyFiles.clear()\n const promise = buildIndexWithCache(context.root, this.options.indexOptions(), undefined, dirty)\n .then((index) => {\n if (!context.disposed && context.generation === generation) {\n context.index = index\n context.lastRefreshAt = Date.now()\n this.options.onRefresh?.(context.root, index)\n }\n return index\n })\n .finally(() => {\n if (context.refresh === promise) context.refresh = null\n if (!context.disposed && context.dirtyFiles.size > 0) this.scheduleRefresh(context)\n })\n context.refresh = promise\n return promise\n }\n\n private attachWatcher(context: RepoContext): void {\n if (!this.options.watch) return\n const options = this.options.indexOptions()\n const ignored = (absolute: string): boolean => {\n const rel = path.relative(context.root, absolute)\n return rel === '..' || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel)\n || ignoredRelativePath(rel, options)\n || isGitIgnoredPath(context.root, rel, context.ignoreMatcherCache)\n }\n const watcher = chokidar.watch(context.root, {\n ignored,\n ignoreInitial: true,\n persistent: true,\n awaitWriteFinish: { stabilityThreshold: 60, pollInterval: 20 },\n followSymlinks: false,\n })\n context.watcher = watcher\n watcher.on('all', (event, absolute) => {\n if (context.disposed || !['add', 'change', 'unlink'].includes(event)) return\n const rel = path.relative(context.root, absolute).split(path.sep).join('/')\n if (!rel || ignoredRelativePath(rel, this.options.indexOptions())\n || isGitIgnoredPath(context.root, rel, context.ignoreMatcherCache)) return\n if (!SUPPORTED_EXTS.has(path.extname(rel).toLowerCase())) return\n context.dirtyFiles.add(rel)\n this.scheduleRefresh(context)\n })\n watcher.on('error', (error) => {\n if (!context.disposed) console.warn(`[dsh-code-index] watcher failed for ${context.root}: ${String(error)}`)\n })\n }\n\n private scheduleRefresh(context: RepoContext): void {\n if (context.disposed || this.disposed) return\n if (context.debounceTimer) clearTimeout(context.debounceTimer)\n context.debounceTimer = setTimeout(() => {\n context.debounceTimer = null\n void this.refresh(context).catch((error: unknown) => {\n if (!context.disposed) console.warn(`[dsh-code-index] refresh failed for ${context.root}: ${String(error)}`)\n })\n }, this.options.debounceMs)\n }\n\n private evictInactive(): void {\n while (this.contexts.size > this.options.maxContexts) {\n const oldest = this.contexts.entries().next().value as [string, RepoContext] | undefined\n if (!oldest) return\n this.contexts.delete(oldest[0])\n void this.disposeContext(oldest[1])\n }\n }\n\n private async disposeContext(context: RepoContext): Promise<void> {\n context.disposed = true\n context.generation++\n if (context.debounceTimer) clearTimeout(context.debounceTimer)\n context.debounceTimer = null\n const watcher = context.watcher\n context.watcher = null\n if (watcher) await watcher.close()\n await context.refresh?.catch(() => undefined)\n context.dirtyFiles.clear()\n context.ignoreMatcherCache.clear()\n context.index = null\n }\n}\n","/** Host-side settings namespace for the plugin's user-editable config. */\n\nimport Schema from '@deepseek-ai/schemastery'\nimport type { PluginConfig } from './config.js'\nexport const SETTINGS_NAMESPACE = 'code-index'\n\nexport const settingsSchema = Schema.object({\n excludeDirs: Schema.array(Schema.string()).default([]),\n mapTopFiles: Schema.number().default(24),\n mapMaxChars: Schema.number().default(3200),\n mapTtlMs: Schema.number().default(60_000),\n autoInject: Schema.boolean().default(true),\n codeHealth: Schema.boolean().default(false),\n toolSurface: Schema.string().default('full'),\n externalWatch: Schema.boolean().default(true),\n watchDebounceMs: Schema.number().default(120),\n})\n\ninterface SettingsScopeLike<T> {\n get(): T\n watch(callback: (next: T, prev: T) => void | Promise<void>): () => void\n}\n\ninterface SettingsServiceLike {\n register<T>(ns: string, schema: unknown, options?: { base?: Partial<T> }): SettingsScopeLike<T>\n configure?(options: { auto: boolean }, fiber?: unknown): void | (() => void)\n}\n\n/**\n * Register the `code-index` settings namespace when a settings provider is\n * mounted, and mirror every resolved change into the plugin's live config.\n * Absent provider = the composed config stands, exactly as before.\n */\nexport function registerSettings(\n getService: (name: string) => unknown,\n pluginConfig: PluginConfig | undefined,\n onResolved: (config: PluginConfig) => void,\n fiber?: unknown,\n): (() => void) | undefined {\n const service = getService('settings') as SettingsServiceLike | undefined\n if (!service) return undefined\n // Current DSH renders volatile plugin fields as config forms. Configure the\n // legacy provider only to disable its automatic schema editor; the config\n // callback is fed by loader/volatile-update in the bundle entry.\n if (service.configure) {\n const dispose = service.configure({ auto: false }, fiber)\n onResolved(pluginConfig ?? {})\n return typeof dispose === 'function' ? dispose : undefined\n }\n const scope = service.register<PluginConfig>(SETTINGS_NAMESPACE, settingsSchema, {\n base: pluginConfig ?? {},\n })\n onResolved(scope.get())\n return scope.watch((next) => {\n onResolved(next)\n })\n}\n","/**\n * dsh-code-index — DeepSeek Harness bundle entry.\n *\n * Registers model-visible tools (code_index / code_symbols / code_search /\n * code_map / code_refs / code_change_context / code_context) plus an opt-in code_health\n * (config.codeHealth) backed by a tree-sitter symbol + call-graph index,\n * and injects a bounded auto-updating repo map for the default workspace\n * into the system prompt.\n */\n\ntype Disposer = void | (() => void)\n\n/** Minimal structural Context; the real @deepseek-ai/cordis type is a\n * runtime dependency we intentionally do not import in the bundle entry. */\ninterface MinimalContext {\n effect(fn: () => Disposer): void\n tools: { register(t: unknown): () => void }\n get?(name: string): unknown\n inject?(deps: string[], run: (ctx: MinimalContext) => void): unknown\n on?(event: string, listener: () => void): () => void\n fiber?: unknown\n systemPrompt: {\n section(section: {\n name: string\n order: number\n text: string | ((context: unknown) => string)\n }): () => void\n }\n}\n\ninterface PromptContext {\n agent?: { session?: { header?: { cwd?: string } } }\n session?: { header?: { cwd?: string } }\n}\n\nexport const name = 'dsh-code-index'\n\n// Public API surface (consumable by other bundles / tests).\nexport { buildIndex, buildIndexWithCache, findRepoRoot } from './buildIndex.js'\nexport { extractSymbols, extractAll, languageForFile, parseFileToSymbols } from './extract.js'\nexport { scanRepo, DEFAULT_EXCLUDED_DIRS, SUPPORTED_EXTS } from './scan.js'\nexport { loadIndex, saveIndex, defaultCachePath, CACHE_DIR_NAME } from './store.js'\nexport { symbolCount } from './types.js'\nexport type { RepoIndex, IndexedFile, SymbolInfo, SymbolKind, IndexOptions } from './types.js'\nexport { searchSymbols, renderHit } from './search.js'\nexport { rankRepoMap, renderRepoMap, scoreFile } from './repomap.js'\nexport { symbolRefs, buildSymbolTable, callerCounts } from './refgraph.js'\nexport { findCycles, findOrphanModules, buildModuleGraph } from './health.js'\nexport { parseUnifiedDiff, readWorkingTreeDiff, readGitFileAtRef } from './git-diff.js'\nexport {\n buildTaskContext,\n renderTaskContext,\n routeTask,\n} from './context.js'\nexport type {\n ContextFile,\n ContextOptions,\n ContextRelationship,\n ContextRoute,\n ContextSymbol,\n ContextTaskKind,\n TaskContextResult,\n} from './context.js'\nexport type { DiffHunk, FileChange } from './git-diff.js'\nexport {\n buildChangeContext,\n changeContextInputFromArgs,\n renderChangeContext,\n} from './change-context.js'\nexport type {\n CodeChangeContextArgs,\n ChangeContextInput,\n ChangeContextOptions,\n ChangeKind,\n ChangedSymbol,\n UnmappedChange,\n ImpactHop,\n ImpactRow,\n SymbolPath,\n ImportDependent,\n AffectedTest,\n ChangeContextResult,\n} from './change-context.js'\nexport { tools } from './tools.js'\nexport { Config } from './config.js'\n\nimport { activateRepoContextManager, clearRepoContextManager, getIndex, invalidateIndexCache, tools } from './tools.js'\nimport { findRepoRoot } from './buildIndex.js'\nimport { rankRepoMap, renderRepoMap } from './repomap.js'\nimport { symbolCount } from './types.js'\nimport { applyConfig, getConfig, indexOptions, type PluginConfig } from './config.js'\nimport { registerSettings } from './settings.js'\nimport { RepoContextManager } from './repo-context.js'\nimport { cacheKeyForRoot } from './store.js'\n\nexport const inject = ['tools', 'systemPrompt'] as const\n\nexport function apply(ctx: MinimalContext, pluginConfig?: PluginConfig) {\n applyConfig(pluginConfig)\n invalidateIndexCache()\n ctx.effect(() => {\n const disposers: Array<() => void> = []\n const repoContexts = new RepoContextManager({\n indexOptions,\n watch: getConfig().externalWatch,\n debounceMs: getConfig().watchDebounceMs,\n })\n activateRepoContextManager(repoContexts)\n const updateConfig = (next?: PluginConfig): void => {\n applyConfig(next)\n repoContexts.reconfigure({ watch: getConfig().externalWatch, debounceMs: getConfig().watchDebounceMs })\n }\n console.log('[dsh-code-index] plugin loaded')\n\n // User-editable settings resolve over the composed plugin row; when a\n // settings provider is mounted, every committed change reconfigures live.\n // The provider initializes asynchronously, so wait for the service rather\n // than reading it once at load (which can precede its availability).\n if (ctx.inject) {\n const injected = ctx.inject(['settings'], (settingsCtx) => {\n const dispose = registerSettings(\n (name) => settingsCtx.get!(name),\n pluginConfig,\n (resolved) => updateConfig(resolved),\n settingsCtx.fiber,\n )\n if (dispose) disposers.push(dispose)\n })\n if (typeof injected === 'function') disposers.push(injected as () => void)\n }\n const removeVolatileListener = ctx.on?.('loader/volatile-update', () => updateConfig(pluginConfig))\n if (removeVolatileListener) disposers.push(removeVolatileListener)\n\n const visibleTools =\n getConfig().toolSurface === 'compact'\n ? tools.filter((tool) => ['code_index', 'code_context', 'code_health'].includes(tool.name))\n : tools\n for (const tool of visibleTools) {\n if (tool.name === 'code_health' && !getConfig().codeHealth) continue\n disposers.push(ctx.tools.register(tool))\n console.log(`[dsh-code-index] registered tool: ${tool.name}`)\n }\n\n // Resolve a distinct map from each DSH agent's current session context.\n const cachedMaps = new Map<string, { root: string; at: number; text: string }>()\n const saveMap = (key: string, value: { root: string; at: number; text: string }): void => {\n cachedMaps.delete(key)\n cachedMaps.set(key, value)\n while (cachedMaps.size > 4) cachedMaps.delete(cachedMaps.keys().next().value!)\n }\n\n async function warmMap(base: string): Promise<void> {\n const now = Date.now()\n const cfg = getConfig()\n const key = cacheKeyForRoot(base)\n try {\n const root = await findRepoRoot(base)\n if (!root) {\n saveMap(key, { root: '', at: now, text: '' })\n return\n }\n const index = await getIndex(root)\n const text = renderRepoMap(\n rankRepoMap(index, { topFiles: cfg.mapTopFiles }),\n { maxChars: cfg.mapMaxChars },\n )\n const stats = symbolCount(index)\n saveMap(key, {\n root: index.root,\n at: Date.now(),\n text: text ? `Project: ${index.root}\\n${text}\\n\\n(summary: ${index.files.length} files, ${stats} symbols)` : '',\n })\n } catch {\n saveMap(key, { root: '', at: now, text: '' }) // never let injection fail the boot\n }\n }\n\n if (getConfig().autoInject) {\n disposers.push(ctx.systemPrompt.section({\n name: 'code-index:repo-map',\n order: 60, // before tool guidance (100–199), after persona (0)\n text: (rawContext) => {\n const context = rawContext as PromptContext\n const base = context.agent?.session?.header?.cwd ?? context.session?.header?.cwd ?? process.cwd()\n const key = cacheKeyForRoot(base)\n const now = Date.now()\n const cached = cachedMaps.get(key)\n if (cached && now - cached.at < getConfig().mapTtlMs) {\n saveMap(key, cached)\n return cached.text\n }\n void warmMap(base)\n return cached?.text ?? ''\n },\n }))\n }\n\n return () => {\n const errors: unknown[] = []\n for (const dispose of disposers.reverse()) {\n try {\n dispose()\n } catch (error) {\n errors.push(error)\n }\n }\n clearRepoContextManager(repoContexts)\n void repoContexts.dispose()\n cachedMaps.clear()\n console.log('[dsh-code-index] plugin unloaded')\n if (errors.length > 0) throw new AggregateError(errors, 'failed to unload dsh-code-index')\n }\n })\n}\n"],"mappings":"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","names":["readFile","stat","path","require","name","index","path","readFile","path","readFile","path","path","readFile","readFile","path","stat","path","path","name","unique","name","path","readFile","path","path","TEST_RE","path","TEST_PATH_RE","TEST_RE","clamp","name","symbolLabel","path","candidate","footer","text","path","path","path","path","Schema","name"]}
|