@abdulmunimjemal/codescope 0.1.0 → 0.3.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store.ts","../src/indexer.ts","../src/languages.ts","../src/parser.ts","../src/watcher.ts","../src/mcp.ts","../src/format.ts","../src/version.ts"],"sourcesContent":["import Database from \"better-sqlite3\";\nimport type {\n IndexStats,\n Neighborhood,\n ParsedRef,\n ParsedSymbol,\n RefRow,\n SymbolKind,\n SymbolRow,\n} from \"./types.js\";\n\nexport interface FileMeta {\n path: string;\n lang: string;\n hash: string;\n size: number;\n mtime: number;\n}\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS files (\n id INTEGER PRIMARY KEY,\n path TEXT NOT NULL UNIQUE,\n lang TEXT NOT NULL,\n hash TEXT NOT NULL,\n size INTEGER NOT NULL,\n mtime INTEGER NOT NULL,\n indexed_at INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS symbols (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n container TEXT,\n exported INTEGER NOT NULL DEFAULT 0,\n signature TEXT,\n start_row INTEGER NOT NULL,\n start_col INTEGER NOT NULL,\n end_row INTEGER NOT NULL,\n end_col INTEGER NOT NULL,\n start_byte INTEGER NOT NULL,\n end_byte INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS refs (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n from_symbol TEXT,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n start_row INTEGER NOT NULL,\n start_col INTEGER NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id);\nCREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);\nCREATE INDEX IF NOT EXISTS idx_refs_name ON refs(name);\nCREATE INDEX IF NOT EXISTS idx_refs_file ON refs(file_id);\nCREATE INDEX IF NOT EXISTS idx_refs_from ON refs(from_symbol);\n\n-- Trigram FTS index for fast substring symbol search at scale. Kept in sync\n-- manually (rowid = symbols.id) so it survives the per-file replace/delete path.\nCREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(name, tokenize='trigram');\n`;\n\ninterface SymbolDbRow {\n id: number;\n file: string;\n name: string;\n kind: string;\n container: string | null;\n exported: number;\n signature: string | null;\n start_row: number;\n start_col: number;\n end_row: number;\n end_col: number;\n}\n\ninterface RefDbRow {\n id: number;\n file: string;\n from_symbol: string | null;\n name: string;\n kind: string;\n start_row: number;\n start_col: number;\n}\n\nconst SYMBOL_COLUMNS = `\n s.id, f.path AS file, s.name, s.kind, s.container, s.exported, s.signature,\n s.start_row, s.start_col, s.end_row, s.end_col`;\n\n/**\n * The on-disk (or in-memory) code graph. All writes go through\n * {@link GraphStore.replaceFile} / {@link GraphStore.removeFile}, which operate\n * on a single file at a time so incremental updates stay O(file), not O(repo).\n */\nexport class GraphStore {\n readonly db: Database.Database;\n\n constructor(location = \":memory:\") {\n this.db = new Database(location);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.db.exec(SCHEMA);\n }\n\n /** The content hash of an already-indexed file, if present. */\n getFileHash(path: string): string | undefined {\n const row = this.db\n .prepare<[string], { hash: string }>(\"SELECT hash FROM files WHERE path = ?\")\n .get(path);\n return row?.hash;\n }\n\n /** All indexed file paths. */\n listFiles(): string[] {\n return this.db\n .prepare<[], { path: string }>(\"SELECT path FROM files ORDER BY path\")\n .all()\n .map((r) => r.path);\n }\n\n /** Insert or replace a file and all of its symbols/refs in one transaction. */\n replaceFile(meta: FileMeta, symbols: ParsedSymbol[], refs: ParsedRef[], now: number): void {\n this.transaction(() => {\n this.dropFtsForFile(meta.path);\n this.db.prepare(\"DELETE FROM files WHERE path = ?\").run(meta.path);\n const fileId = Number(\n this.db\n .prepare(\n \"INSERT INTO files (path, lang, hash, size, mtime, indexed_at) VALUES (?, ?, ?, ?, ?, ?)\",\n )\n .run(meta.path, meta.lang, meta.hash, meta.size, meta.mtime, now).lastInsertRowid,\n );\n\n const insSym = this.db.prepare(\n `INSERT INTO symbols\n (file_id, name, kind, container, exported, signature,\n start_row, start_col, end_row, end_col, start_byte, end_byte)\n VALUES (@file_id, @name, @kind, @container, @exported, @signature,\n @start_row, @start_col, @end_row, @end_col, @start_byte, @end_byte)`,\n );\n const insFts = this.db.prepare(\"INSERT INTO symbols_fts(rowid, name) VALUES (?, ?)\");\n for (const s of symbols) {\n const symId = insSym.run({\n file_id: fileId,\n name: s.name,\n kind: s.kind,\n container: s.container,\n exported: s.exported ? 1 : 0,\n signature: s.signature,\n start_row: s.startRow,\n start_col: s.startCol,\n end_row: s.endRow,\n end_col: s.endCol,\n start_byte: s.startByte,\n end_byte: s.endByte,\n }).lastInsertRowid;\n insFts.run(symId, s.name);\n }\n\n const insRef = this.db.prepare(\n `INSERT INTO refs (file_id, from_symbol, name, kind, start_row, start_col)\n VALUES (@file_id, @from_symbol, @name, @kind, @start_row, @start_col)`,\n );\n for (const r of refs) {\n insRef.run({\n file_id: fileId,\n from_symbol: r.fromSymbol,\n name: r.name,\n kind: r.kind,\n start_row: r.startRow,\n start_col: r.startCol,\n });\n }\n });\n }\n\n /** Remove a file and its symbols/refs. Returns true if anything was deleted. */\n removeFile(path: string): boolean {\n return this.transactionResult(() => {\n this.dropFtsForFile(path);\n return this.db.prepare(\"DELETE FROM files WHERE path = ?\").run(path).changes > 0;\n });\n }\n\n /** Remove the FTS rows for a file's current symbols (call before deleting it). */\n private dropFtsForFile(path: string): void {\n const ids = this.db\n .prepare<[string], { id: number }>(\n \"SELECT s.id FROM symbols s JOIN files f ON f.id = s.file_id WHERE f.path = ?\",\n )\n .all(path);\n if (ids.length === 0) return;\n const del = this.db.prepare(\"DELETE FROM symbols_fts WHERE rowid = ?\");\n for (const { id } of ids) del.run(id);\n }\n\n // ── Queries ────────────────────────────────────────────────────────────\n\n /**\n * Fuzzy substring search over symbol names. Queries of 3+ characters use the\n * trigram FTS index (fast at scale); shorter queries fall back to LIKE since\n * trigram matching needs at least three characters.\n */\n searchSymbols(query: string, opts: { kind?: SymbolKind; limit?: number } = {}): SymbolRow[] {\n const limit = clampLimit(opts.limit);\n if (query.trim().length >= 3) {\n const match = `\"${query.replace(/\"/g, '\"\"')}\"`;\n const rows = opts.kind\n ? this.db\n .prepare<[string, string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols_fts ft\n JOIN symbols s ON s.id = ft.rowid JOIN files f ON f.id = s.file_id\n WHERE symbols_fts MATCH ? AND s.kind = ?\n ORDER BY s.exported DESC, length(s.name), s.name LIMIT ?`,\n )\n .all(match, opts.kind, limit)\n : this.db\n .prepare<[string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols_fts ft\n JOIN symbols s ON s.id = ft.rowid JOIN files f ON f.id = s.file_id\n WHERE symbols_fts MATCH ?\n ORDER BY s.exported DESC, length(s.name), s.name LIMIT ?`,\n )\n .all(match, limit);\n return rows.map(toSymbolRow);\n }\n\n const like = `%${escapeLike(query)}%`;\n const rows = opts.kind\n ? this.db\n .prepare<[string, string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols s JOIN files f ON f.id = s.file_id\n WHERE s.name LIKE ? ESCAPE '\\\\' AND s.kind = ?\n ORDER BY s.exported DESC, length(s.name), s.name LIMIT ?`,\n )\n .all(like, opts.kind, limit)\n : this.db\n .prepare<[string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols s JOIN files f ON f.id = s.file_id\n WHERE s.name LIKE ? ESCAPE '\\\\'\n ORDER BY s.exported DESC, length(s.name), s.name LIMIT ?`,\n )\n .all(like, limit);\n return rows.map(toSymbolRow);\n }\n\n /** Exact-name definition lookup. */\n getSymbol(name: string, opts: { limit?: number } = {}): SymbolRow[] {\n return this.db\n .prepare<[string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols s JOIN files f ON f.id = s.file_id\n WHERE s.name = ? ORDER BY s.exported DESC, f.path LIMIT ?`,\n )\n .all(name, clampLimit(opts.limit))\n .map(toSymbolRow);\n }\n\n /** Symbols that call a given name (both bare `foo()` and `x.foo()`). */\n findCallers(name: string, opts: { limit?: number } = {}): RefRow[] {\n return this.db\n .prepare<[string, number], RefDbRow>(\n `SELECT r.id, f.path AS file, r.from_symbol, r.name, r.kind, r.start_row, r.start_col\n FROM refs r JOIN files f ON f.id = r.file_id\n WHERE r.name = ? AND r.kind IN ('call', 'method')\n ORDER BY f.path, r.start_row LIMIT ?`,\n )\n .all(name, clampLimit(opts.limit))\n .map(toRefRow);\n }\n\n /** All references (calls + imports) to a name. */\n findReferences(\n name: string,\n opts: { kind?: \"call\" | \"method\" | \"import\"; limit?: number } = {},\n ): RefRow[] {\n const limit = clampLimit(opts.limit);\n const rows = opts.kind\n ? this.db\n .prepare<[string, string, number], RefDbRow>(\n `SELECT r.id, f.path AS file, r.from_symbol, r.name, r.kind, r.start_row, r.start_col\n FROM refs r JOIN files f ON f.id = r.file_id\n WHERE r.name = ? AND r.kind = ? ORDER BY f.path, r.start_row LIMIT ?`,\n )\n .all(name, opts.kind, limit)\n : this.db\n .prepare<[string, number], RefDbRow>(\n `SELECT r.id, f.path AS file, r.from_symbol, r.name, r.kind, r.start_row, r.start_col\n FROM refs r JOIN files f ON f.id = r.file_id\n WHERE r.name = ? ORDER BY f.path, r.start_row LIMIT ?`,\n )\n .all(name, limit);\n return rows.map(toRefRow);\n }\n\n /** The symbols defined in a file, in source order. */\n fileOutline(path: string): SymbolRow[] {\n return this.db\n .prepare<[string], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols s JOIN files f ON f.id = s.file_id\n WHERE f.path = ? ORDER BY s.start_row, s.start_col`,\n )\n .all(path)\n .map(toSymbolRow);\n }\n\n /** Distinct (callee, callKind) pairs invoked from inside symbols named `from`. */\n private calleesOf(from: string): Array<{ name: string; kind: \"call\" | \"method\" }> {\n return this.db\n .prepare<[string], { name: string; kind: \"call\" | \"method\" }>(\n \"SELECT DISTINCT name, kind FROM refs WHERE from_symbol = ? AND kind IN ('call','method')\",\n )\n .all(from);\n }\n\n /** Distinct caller symbol names that invoke `name`. */\n private callersOf(name: string): string[] {\n return this.db\n .prepare<[string], { from_symbol: string }>(\n \"SELECT DISTINCT from_symbol FROM refs WHERE name = ? AND kind IN ('call','method') AND from_symbol IS NOT NULL\",\n )\n .all(name)\n .map((r) => r.from_symbol);\n }\n\n /**\n * Resolve a callee name to project definitions, honouring how it was called:\n * a bare `foo()` resolves to non-method symbols, an `x.foo()` resolves to\n * methods. Ambiguous names (more than `ambiguityCap` definitions — typically\n * library-ish names like `push`/`map`) are treated as unresolved so they\n * don't blow up the neighbourhood. Returns `null` when nothing resolves.\n */\n private resolveCallee(\n name: string,\n callKind: \"call\" | \"method\",\n ambiguityCap: number,\n ): SymbolRow[] | null {\n const defs = this.getSymbol(name, { limit: ambiguityCap + 1 }).filter((d) =>\n callKind === \"method\" ? d.kind === \"method\" : d.kind !== \"method\",\n );\n if (defs.length === 0 || defs.length > ambiguityCap) return null;\n return defs;\n }\n\n /**\n * A bounded call neighbourhood around `name`: callers and callees expanded\n * breadth-first up to `depth`. Only edges between *resolvable project\n * symbols* are followed, so the result is the relevant slice of the codebase\n * — the payload a coding agent reads instead of grepping the whole repo.\n */\n neighborhood(\n name: string,\n opts: { depth?: number; limit?: number; maxFanout?: number; ambiguityCap?: number } = {},\n ): Neighborhood {\n const depth = Math.max(1, Math.min(opts.depth ?? 2, 5));\n const limit = clampLimit(opts.limit, 200);\n const maxFanout = opts.maxFanout ?? 25;\n const ambiguityCap = opts.ambiguityCap ?? 4;\n\n const seen = new Set<string>([name]);\n const edges: Array<{ from: string; to: string }> = [];\n const edgeKeys = new Set<string>();\n let frontier = [name];\n\n for (let d = 0; d < depth && frontier.length > 0 && seen.size < limit; d++) {\n const next = new Set<string>();\n for (const node of frontier) {\n let fanout = 0;\n for (const callee of this.calleesOf(node)) {\n if (fanout >= maxFanout) break;\n if (!this.resolveCallee(callee.name, callee.kind, ambiguityCap)) continue;\n fanout++;\n addEdge(edges, edgeKeys, node, callee.name);\n if (!seen.has(callee.name) && seen.size < limit) {\n seen.add(callee.name);\n next.add(callee.name);\n }\n }\n let callerFanout = 0;\n for (const caller of this.callersOf(node)) {\n if (callerFanout >= maxFanout) break;\n callerFanout++;\n addEdge(edges, edgeKeys, caller, node);\n if (!seen.has(caller) && seen.size < limit) {\n seen.add(caller);\n next.add(caller);\n }\n }\n }\n frontier = [...next];\n }\n\n const nodes: SymbolRow[] = [];\n const unresolved: string[] = [];\n for (const n of seen) {\n const defs = this.getSymbol(n, { limit: 5 });\n if (defs.length > 0) nodes.push(...defs);\n else unresolved.push(n);\n }\n return { root: name, nodes, edges, unresolved };\n }\n\n /** Aggregate counts for the whole graph. */\n stats(): IndexStats {\n const files = this.count(\"SELECT COUNT(*) AS n FROM files\");\n const symbols = this.count(\"SELECT COUNT(*) AS n FROM symbols\");\n const refs = this.count(\"SELECT COUNT(*) AS n FROM refs\");\n const byKind: Record<string, number> = {};\n for (const r of this.db\n .prepare<[], { kind: string; n: number }>(\n \"SELECT kind, COUNT(*) AS n FROM symbols GROUP BY kind\",\n )\n .all()) {\n byKind[r.kind] = r.n;\n }\n const byLang: Record<string, number> = {};\n for (const r of this.db\n .prepare<[], { lang: string; n: number }>(\n \"SELECT lang, COUNT(*) AS n FROM files GROUP BY lang\",\n )\n .all()) {\n byLang[r.lang] = r.n;\n }\n return { files, symbols, refs, byKind, byLang };\n }\n\n close(): void {\n this.db.close();\n }\n\n private count(sql: string): number {\n return this.db.prepare<[], { n: number }>(sql).get()?.n ?? 0;\n }\n\n private transaction(fn: () => void): void {\n this.db.transaction(fn)();\n }\n\n private transactionResult<T>(fn: () => T): T {\n return this.db.transaction(fn)();\n }\n}\n\nfunction addEdge(\n edges: Array<{ from: string; to: string }>,\n keys: Set<string>,\n from: string,\n to: string,\n): void {\n const key = `${from}\u0000${to}`;\n if (!keys.has(key)) {\n keys.add(key);\n edges.push({ from, to });\n }\n}\n\nfunction clampLimit(limit: number | undefined, max = 500): number {\n if (!limit || limit <= 0) return 50;\n return Math.min(limit, max);\n}\n\nfunction escapeLike(s: string): string {\n return s.replace(/[\\\\%_]/g, (c) => `\\\\${c}`);\n}\n\nfunction toSymbolRow(r: SymbolDbRow): SymbolRow {\n return {\n id: r.id,\n file: r.file,\n name: r.name,\n kind: r.kind as SymbolKind,\n container: r.container,\n exported: r.exported === 1,\n signature: r.signature,\n startRow: r.start_row,\n startCol: r.start_col,\n endRow: r.end_row,\n endCol: r.end_col,\n };\n}\n\nfunction toRefRow(r: RefDbRow): RefRow {\n return {\n id: r.id,\n file: r.file,\n fromSymbol: r.from_symbol,\n name: r.name,\n kind: r.kind as RefRow[\"kind\"],\n startRow: r.start_row,\n startCol: r.start_col,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { readFileSync } from \"node:fs\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport { relative, resolve, sep } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\nimport { glob } from \"tinyglobby\";\nimport { SUPPORTED_EXTENSIONS, languageForPath } from \"./languages.js\";\nimport { parseSource } from \"./parser.js\";\nimport type { GraphStore } from \"./store.js\";\nimport type { IndexRunResult } from \"./types.js\";\n\n/** Directories never worth indexing, regardless of .gitignore. */\nconst DEFAULT_IGNORES = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/coverage/**\",\n \"**/.codescope/**\",\n \"**/.next/**\",\n \"**/out/**\",\n \"**/target/**\",\n \"**/.venv/**\",\n \"**/venv/**\",\n \"**/vendor/**\",\n \"**/__pycache__/**\",\n];\n\nexport interface IndexOptions {\n /** Extra glob patterns to ignore. */\n ignore?: string[];\n /** Honour the repo's root `.gitignore` (default: true). */\n gitignore?: boolean;\n}\n\nexport type FileIndexOutcome = \"indexed\" | \"skipped\" | \"unsupported\";\n\n/**\n * Walks a repository and keeps a {@link GraphStore} in sync with it. Every\n * operation is per-file and content-hash gated, so a full re-scan skips\n * unchanged files and a single-file update touches only that file.\n */\nexport class Indexer {\n readonly root: string;\n\n constructor(\n private readonly store: GraphStore,\n root: string,\n ) {\n this.root = resolve(root);\n }\n\n /** Index every supported, non-ignored file and prune deleted ones. */\n async indexAll(opts: IndexOptions = {}): Promise<IndexRunResult> {\n const start = Date.now();\n const result: IndexRunResult = {\n indexed: 0,\n skipped: 0,\n removed: 0,\n errors: [],\n durationMs: 0,\n };\n\n const files = await this.listSourceFiles(opts);\n const present = new Set<string>();\n\n for (const abs of files) {\n present.add(this.rel(abs));\n try {\n const outcome = await this.indexFile(abs, start);\n if (outcome === \"indexed\") result.indexed++;\n else if (outcome === \"skipped\") result.skipped++;\n } catch (err) {\n result.errors.push({ file: this.rel(abs), error: errorMessage(err) });\n }\n }\n\n for (const known of this.store.listFiles()) {\n if (!present.has(known) && this.store.removeFile(known)) result.removed++;\n }\n\n result.durationMs = Date.now() - start;\n return result;\n }\n\n /** Index a single file by absolute path. Cheap when the content is unchanged. */\n async indexFile(abs: string, now = Date.now()): Promise<FileIndexOutcome> {\n const lang = languageForPath(abs);\n if (!lang) return \"unsupported\";\n\n const rel = this.rel(abs);\n const content = await readFile(abs, \"utf8\");\n const hash = sha1(content);\n if (this.store.getFileHash(rel) === hash) return \"skipped\";\n\n const mtime = await fileMtime(abs, now);\n const { symbols, refs } = await parseSource(lang.id, content);\n this.store.replaceFile(\n { path: rel, lang: lang.id, hash, size: content.length, mtime },\n symbols,\n refs,\n now,\n );\n return \"indexed\";\n }\n\n /** Drop a file from the graph by absolute path. */\n removeFile(abs: string): boolean {\n return this.store.removeFile(this.rel(abs));\n }\n\n /** Repo-relative, POSIX-separated path used as the stable graph key. */\n rel(abs: string): string {\n return relative(this.root, resolve(abs)).split(sep).join(\"/\");\n }\n\n private async listSourceFiles(opts: IndexOptions): Promise<string[]> {\n const patterns = SUPPORTED_EXTENSIONS.map((ext) => `**/*${ext}`);\n const files = await glob(patterns, {\n cwd: this.root,\n absolute: true,\n ignore: [...DEFAULT_IGNORES, ...(opts.ignore ?? [])],\n dot: false,\n });\n\n if (opts.gitignore === false) return files;\n const ig = this.loadGitignore();\n if (!ig) return files;\n return files.filter((f) => {\n const rel = this.rel(f);\n return rel.length > 0 && !ig.ignores(rel);\n });\n }\n\n private loadGitignore(): Ignore | null {\n try {\n const content = readFileSync(resolve(this.root, \".gitignore\"), \"utf8\");\n return ignore().add(content);\n } catch {\n return null;\n }\n }\n}\n\nfunction sha1(content: string): string {\n return createHash(\"sha1\").update(content).digest(\"hex\");\n}\n\nasync function fileMtime(abs: string, fallback: number): Promise<number> {\n try {\n const st = await stat(abs);\n return Math.floor(st.mtimeMs);\n } catch {\n return fallback;\n }\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import type { SymbolKind } from \"./types.js\";\n\n/**\n * Per-language configuration driving the AST walk in {@link ./parser.ts}.\n *\n * Rather than maintain a tree-sitter query (`.scm`) per grammar, we walk the\n * tree once and classify nodes by `type` using these tables. Grammars disagree\n * on a lot — C buries a function's name inside nested declarators, Java and Ruby\n * hang the callee straight off the call node, Go/Rust/C++ each use a different\n * \"member access\" node — so definitions, calls, and imports are all described\n * declaratively here and interpreted by a single generic walker.\n */\n\nexport type NameStrategy = \"field\" | \"c_declarator\";\n\nexport interface DefRule {\n kind: SymbolKind;\n /** How to read the definition's name (default: the `name` field). */\n name?: NameStrategy;\n}\n\nexport interface CallRule {\n /** AST node type for this kind of call. */\n type: string;\n /** Field holding the callee expression (for `foo()` / `a.foo()` forms). */\n fnField?: string;\n /** Callee-expression node types that mean \"method call\". */\n memberTypes?: string[];\n /** Field on a member node holding the method name. */\n memberField?: string;\n /** Callee-expression node types that are path-qualified (`a::b`). */\n scopedTypes?: string[];\n /** Field on a scoped node holding the final name. */\n scopedField?: string;\n /** The call node holds the callee name directly in this field (Java/Ruby). */\n nameField?: string;\n /** Presence of this field on the call node marks it a method call. */\n receiverField?: string;\n /** Force the ref kind regardless of shape. */\n forceKind?: \"call\" | \"method\";\n}\n\nexport interface ImportRule {\n type: string;\n /** Read the import target from this field's text. */\n field?: string;\n /** Collect import targets from named children of these types. */\n childTypes?: string[];\n}\n\nexport interface LanguageConfig {\n id: string;\n wasm: string;\n defs: Record<string, DefRule>;\n /** Bindings (`const x = …`) that become `function` symbols when assigned a function. */\n functionBindings: Set<string>;\n /** A nested `function` whose enclosing definition is a class becomes a `method`. */\n nestedFunctionsAreMethods: boolean;\n callRules: CallRule[];\n importRules: ImportRule[];\n /** Node types whose presence as an ancestor marks a definition as exported. */\n exportTypes: Set<string>;\n}\n\nconst JS_CALLS: CallRule[] = [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"member_expression\"], memberField: \"property\" },\n];\n\nconst typescript: LanguageConfig = {\n id: \"typescript\",\n wasm: \"typescript\",\n defs: {\n function_declaration: { kind: \"function\" },\n generator_function_declaration: { kind: \"function\" },\n function_signature: { kind: \"function\" },\n method_definition: { kind: \"method\" },\n method_signature: { kind: \"method\" },\n class_declaration: { kind: \"class\" },\n abstract_class_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n type_alias_declaration: { kind: \"type\" },\n enum_declaration: { kind: \"enum\" },\n },\n functionBindings: new Set([\"variable_declarator\", \"public_field_definition\"]),\n nestedFunctionsAreMethods: false,\n callRules: JS_CALLS,\n importRules: [{ type: \"import_statement\", field: \"source\" }],\n exportTypes: new Set([\"export_statement\"]),\n};\n\nconst tsx: LanguageConfig = { ...typescript, id: \"tsx\", wasm: \"tsx\" };\n\nconst javascript: LanguageConfig = {\n id: \"javascript\",\n wasm: \"javascript\",\n defs: {\n function_declaration: { kind: \"function\" },\n generator_function_declaration: { kind: \"function\" },\n method_definition: { kind: \"method\" },\n class_declaration: { kind: \"class\" },\n },\n functionBindings: new Set([\"variable_declarator\", \"field_definition\"]),\n nestedFunctionsAreMethods: false,\n callRules: JS_CALLS,\n importRules: [{ type: \"import_statement\", field: \"source\" }],\n exportTypes: new Set([\"export_statement\"]),\n};\n\nconst python: LanguageConfig = {\n id: \"python\",\n wasm: \"python\",\n defs: {\n function_definition: { kind: \"function\" },\n class_definition: { kind: \"class\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"call\", fnField: \"function\", memberTypes: [\"attribute\"], memberField: \"attribute\" }],\n importRules: [\n { type: \"import_statement\", childTypes: [\"dotted_name\", \"aliased_import\"] },\n { type: \"import_from_statement\", field: \"module_name\" },\n ],\n exportTypes: new Set(),\n};\n\nconst go: LanguageConfig = {\n id: \"go\",\n wasm: \"go\",\n defs: {\n function_declaration: { kind: \"function\" },\n method_declaration: { kind: \"method\" },\n type_spec: { kind: \"class\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"selector_expression\"], memberField: \"field\" },\n ],\n importRules: [{ type: \"import_spec\", field: \"path\" }],\n exportTypes: new Set(),\n};\n\nconst rust: LanguageConfig = {\n id: \"rust\",\n wasm: \"rust\",\n defs: {\n function_item: { kind: \"function\" },\n struct_item: { kind: \"class\" },\n union_item: { kind: \"class\" },\n enum_item: { kind: \"enum\" },\n trait_item: { kind: \"interface\" },\n type_item: { kind: \"type\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n {\n type: \"call_expression\",\n fnField: \"function\",\n memberTypes: [\"field_expression\"],\n memberField: \"field\",\n scopedTypes: [\"scoped_identifier\"],\n scopedField: \"name\",\n },\n ],\n importRules: [{ type: \"use_declaration\", field: \"argument\" }],\n exportTypes: new Set(),\n};\n\nconst java: LanguageConfig = {\n id: \"java\",\n wasm: \"java\",\n defs: {\n class_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n enum_declaration: { kind: \"enum\" },\n record_declaration: { kind: \"class\" },\n method_declaration: { kind: \"method\" },\n constructor_declaration: { kind: \"method\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"method_invocation\", nameField: \"name\", receiverField: \"object\" }],\n importRules: [{ type: \"import_declaration\", childTypes: [\"scoped_identifier\", \"identifier\"] }],\n exportTypes: new Set(),\n};\n\nconst ruby: LanguageConfig = {\n id: \"ruby\",\n wasm: \"ruby\",\n defs: {\n method: { kind: \"method\" },\n singleton_method: { kind: \"method\" },\n class: { kind: \"class\" },\n module: { kind: \"class\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"call\", nameField: \"method\", receiverField: \"receiver\" }],\n importRules: [],\n exportTypes: new Set(),\n};\n\nconst c: LanguageConfig = {\n id: \"c\",\n wasm: \"c\",\n defs: {\n function_definition: { kind: \"function\", name: \"c_declarator\" },\n struct_specifier: { kind: \"class\" },\n union_specifier: { kind: \"class\" },\n enum_specifier: { kind: \"enum\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"field_expression\"], memberField: \"field\" },\n ],\n importRules: [{ type: \"preproc_include\", field: \"path\" }],\n exportTypes: new Set(),\n};\n\nconst cpp: LanguageConfig = {\n id: \"cpp\",\n wasm: \"cpp\",\n defs: {\n function_definition: { kind: \"function\", name: \"c_declarator\" },\n class_specifier: { kind: \"class\" },\n struct_specifier: { kind: \"class\" },\n enum_specifier: { kind: \"enum\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: true,\n callRules: [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"field_expression\"], memberField: \"field\" },\n ],\n importRules: [{ type: \"preproc_include\", field: \"path\" }],\n exportTypes: new Set(),\n};\n\nconst csharp: LanguageConfig = {\n id: \"csharp\",\n wasm: \"c_sharp\",\n defs: {\n class_declaration: { kind: \"class\" },\n struct_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n enum_declaration: { kind: \"enum\" },\n record_declaration: { kind: \"class\" },\n method_declaration: { kind: \"method\" },\n constructor_declaration: { kind: \"method\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n {\n type: \"invocation_expression\",\n fnField: \"function\",\n memberTypes: [\"member_access_expression\"],\n memberField: \"name\",\n },\n ],\n importRules: [{ type: \"using_directive\", childTypes: [\"identifier\", \"qualified_name\"] }],\n exportTypes: new Set(),\n};\n\nconst php: LanguageConfig = {\n id: \"php\",\n wasm: \"php\",\n defs: {\n function_definition: { kind: \"function\" },\n method_declaration: { kind: \"method\" },\n class_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n trait_declaration: { kind: \"class\" },\n enum_declaration: { kind: \"enum\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n { type: \"function_call_expression\", fnField: \"function\" },\n { type: \"member_call_expression\", nameField: \"name\", forceKind: \"method\" },\n { type: \"scoped_call_expression\", nameField: \"name\", forceKind: \"method\" },\n ],\n importRules: [{ type: \"namespace_use_declaration\", childTypes: [\"namespace_use_clause\"] }],\n exportTypes: new Set(),\n};\n\n/** All languages codescope can parse, keyed by config id. */\nexport const LANGUAGES: Record<string, LanguageConfig> = {\n typescript,\n tsx,\n javascript,\n python,\n go,\n rust,\n java,\n ruby,\n c,\n cpp,\n csharp,\n php,\n};\n\n/** File extension → language id. */\nconst EXT_TO_LANG: Record<string, string> = {\n \".ts\": \"typescript\",\n \".mts\": \"typescript\",\n \".cts\": \"typescript\",\n \".tsx\": \"tsx\",\n \".js\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".jsx\": \"javascript\",\n \".py\": \"python\",\n \".pyi\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n \".java\": \"java\",\n \".rb\": \"ruby\",\n \".c\": \"c\",\n \".h\": \"c\",\n \".cc\": \"cpp\",\n \".cpp\": \"cpp\",\n \".cxx\": \"cpp\",\n \".hpp\": \"cpp\",\n \".hh\": \"cpp\",\n \".cs\": \"csharp\",\n \".php\": \"php\",\n};\n\n/** The set of file extensions codescope indexes (with leading dot). */\nexport const SUPPORTED_EXTENSIONS: readonly string[] = Object.keys(EXT_TO_LANG);\n\n/** Resolve a language config from a file path, or `undefined` if unsupported. */\nexport function languageForPath(path: string): LanguageConfig | undefined {\n const dot = path.lastIndexOf(\".\");\n if (dot === -1) return undefined;\n const ext = path.slice(dot).toLowerCase();\n const id = EXT_TO_LANG[ext];\n return id ? LANGUAGES[id] : undefined;\n}\n","import { createRequire } from \"node:module\";\nimport Parser from \"web-tree-sitter\";\nimport {\n LANGUAGES,\n type CallRule,\n type DefRule,\n type ImportRule,\n type LanguageConfig,\n} from \"./languages.js\";\nimport type { ParsedRef, ParsedSymbol, ParseResult, SymbolKind } from \"./types.js\";\n\nconst require = createRequire(import.meta.url);\n\nlet initPromise: Promise<void> | null = null;\nconst parserCache = new Map<string, Parser>();\n\n/** Resolve a grammar wasm shipped by `tree-sitter-wasms`. */\nfunction grammarPath(wasm: string): string {\n return require.resolve(`tree-sitter-wasms/out/tree-sitter-${wasm}.wasm`);\n}\n\nasync function ensureInit(): Promise<void> {\n if (!initPromise) initPromise = Parser.init();\n await initPromise;\n}\n\n/** Lazily load (and cache) a configured parser for a language. */\nasync function getParser(lang: LanguageConfig): Promise<Parser> {\n const cached = parserCache.get(lang.id);\n if (cached) return cached;\n await ensureInit();\n const language = await Parser.Language.load(grammarPath(lang.wasm));\n const parser = new Parser();\n parser.setLanguage(language);\n parserCache.set(lang.id, parser);\n return parser;\n}\n\nconst FUNCTION_VALUE_TYPES = new Set([\n \"arrow_function\",\n \"function\",\n \"function_expression\",\n \"generator_function\",\n]);\n\n/** Parse a source string into symbols and references. */\nexport async function parseSource(langId: string, source: string): Promise<ParseResult> {\n const lang = LANGUAGES[langId];\n if (!lang) throw new Error(`Unknown language: ${langId}`);\n const parser = await getParser(lang);\n const tree = parser.parse(source);\n const symbols: ParsedSymbol[] = [];\n const refs: ParsedRef[] = [];\n if (tree?.rootNode) {\n walk(tree.rootNode, lang, null, null, symbols, refs);\n tree.delete();\n }\n return { lang: lang.id, symbols, refs };\n}\n\nfunction walk(\n node: Parser.SyntaxNode,\n lang: LanguageConfig,\n container: string | null,\n containerKind: SymbolKind | null,\n symbols: ParsedSymbol[],\n refs: ParsedRef[],\n): void {\n let childContainer = container;\n let childContainerKind = containerKind;\n\n const rule = classify(node, lang);\n const call = lang.callRules.find((r) => r.type === node.type);\n const imp = lang.importRules.find((r) => r.type === node.type);\n\n if (rule) {\n const sym = buildSymbol(node, rule, container, containerKind, lang);\n if (sym) {\n symbols.push(sym);\n childContainer = sym.name;\n childContainerKind = sym.kind;\n }\n } else if (call) {\n const ref = extractCall(node, call, container);\n if (ref) refs.push(ref);\n } else if (imp) {\n for (const ref of extractImports(node, imp, container)) refs.push(ref);\n }\n\n for (const child of node.namedChildren) {\n walk(child, lang, childContainer, childContainerKind, symbols, refs);\n }\n}\n\nfunction classify(node: Parser.SyntaxNode, lang: LanguageConfig): DefRule | null {\n const direct = lang.defs[node.type];\n if (direct) return direct;\n if (lang.functionBindings.has(node.type)) {\n const value = node.childForFieldName(\"value\");\n if (value && FUNCTION_VALUE_TYPES.has(value.type)) return { kind: \"function\" };\n }\n return null;\n}\n\nfunction buildSymbol(\n node: Parser.SyntaxNode,\n rule: DefRule,\n container: string | null,\n containerKind: SymbolKind | null,\n lang: LanguageConfig,\n): ParsedSymbol | null {\n const name = symbolName(node, rule.name ?? \"field\");\n if (!name) return null;\n let kind = rule.kind;\n if (kind === \"function\" && lang.nestedFunctionsAreMethods && containerKind === \"class\") {\n kind = \"method\";\n }\n return {\n name,\n kind,\n container,\n exported: isExported(node, lang),\n signature: signatureOf(node),\n startRow: node.startPosition.row,\n startCol: node.startPosition.column,\n endRow: node.endPosition.row,\n endCol: node.endPosition.column,\n startByte: node.startIndex,\n endByte: node.endIndex,\n };\n}\n\nfunction symbolName(node: Parser.SyntaxNode, strategy: DefRule[\"name\"]): string | null {\n if (strategy === \"c_declarator\") return cDeclaratorName(node);\n return node.childForFieldName(\"name\")?.text ?? null;\n}\n\n/** Dig through C/C++ declarator chains (`int *foo(...)`) to the actual name. */\nfunction cDeclaratorName(node: Parser.SyntaxNode): string | null {\n let decl = node.childForFieldName(\"declarator\");\n for (let i = 0; decl && i < 10; i++) {\n if (decl.type === \"identifier\" || decl.type === \"field_identifier\") return decl.text;\n if (decl.type === \"qualified_identifier\" || decl.type === \"destructor_name\") {\n return decl.childForFieldName(\"name\")?.text ?? decl.text;\n }\n const inner = decl.childForFieldName(\"declarator\");\n if (!inner) break;\n decl = inner;\n }\n return null;\n}\n\n/** A definition is exported if an `export` statement directly wraps it. */\nfunction isExported(node: Parser.SyntaxNode, lang: LanguageConfig): boolean {\n if (lang.exportTypes.size === 0) return false;\n let cur = node.parent;\n for (let i = 0; cur && i < 2; i++) {\n if (lang.exportTypes.has(cur.type)) return true;\n cur = cur.parent;\n }\n return false;\n}\n\n/** The declaration text up to (but not including) the body, on one line. */\nfunction signatureOf(node: Parser.SyntaxNode): string | null {\n const body = node.childForFieldName(\"body\");\n const raw = body\n ? node.text.slice(0, body.startIndex - node.startIndex)\n : node.text;\n const text = raw.replace(/\\s+/g, \" \").trim();\n if (!text) return null;\n return text.length > 240 ? `${text.slice(0, 239)}…` : text;\n}\n\nfunction extractCall(\n node: Parser.SyntaxNode,\n rule: CallRule,\n container: string | null,\n): ParsedRef | null {\n let name: string | null = null;\n let kind: \"call\" | \"method\" = \"call\";\n\n if (rule.nameField) {\n // The call node carries the callee name directly (Java/Ruby/PHP member).\n name = node.childForFieldName(rule.nameField)?.text ?? null;\n if (rule.receiverField && node.childForFieldName(rule.receiverField)) kind = \"method\";\n } else if (rule.fnField) {\n const fn = node.childForFieldName(rule.fnField);\n if (fn) {\n if (rule.memberTypes?.includes(fn.type)) {\n name = fn.childForFieldName(rule.memberField ?? \"\")?.text ?? null;\n kind = \"method\";\n } else if (rule.scopedTypes?.includes(fn.type)) {\n name = fn.childForFieldName(rule.scopedField ?? \"\")?.text ?? null;\n } else if (fn.type === \"identifier\" || fn.type === \"name\") {\n name = fn.text;\n }\n }\n }\n\n if (rule.forceKind) kind = rule.forceKind;\n if (!name) return null;\n return {\n fromSymbol: container,\n name,\n kind,\n startRow: node.startPosition.row,\n startCol: node.startPosition.column,\n };\n}\n\nfunction extractImports(\n node: Parser.SyntaxNode,\n rule: ImportRule,\n container: string | null,\n): ParsedRef[] {\n const out: ParsedRef[] = [];\n const add = (spec: string | null | undefined): void => {\n const name = spec ? unquote(spec) : \"\";\n if (name) {\n out.push({\n fromSymbol: container,\n name,\n kind: \"import\",\n startRow: node.startPosition.row,\n startCol: node.startPosition.column,\n });\n }\n };\n\n if (rule.field) {\n add(node.childForFieldName(rule.field)?.text);\n }\n if (rule.childTypes) {\n for (const child of node.namedChildren) {\n if (!rule.childTypes.includes(child.type)) continue;\n // python `import x as y` exposes the real module under the `name` field\n if (child.type === \"aliased_import\") add(child.childForFieldName(\"name\")?.text);\n else add(child.text);\n }\n }\n return out;\n}\n\nfunction unquote(text: string): string {\n const t = text.trim();\n if (t.length >= 2) {\n const first = t[0];\n const last = t[t.length - 1];\n if ((first === '\"' || first === \"'\" || first === \"`\") && first === last) {\n return t.slice(1, -1);\n }\n // C/C++ include targets: <stdio.h>\n if (first === \"<\" && last === \">\") return t.slice(1, -1);\n }\n return t;\n}\n\n/** Test helper: drop cached parsers so a fresh init can be exercised. */\nexport function _resetParsers(): void {\n parserCache.clear();\n initPromise = null;\n}\n","import { watch as chokidarWatch } from \"chokidar\";\nimport { languageForPath } from \"./languages.js\";\nimport type { Indexer } from \"./indexer.js\";\n\nexport interface WatchEvents {\n /** A file was (re-)indexed or removed from the graph. */\n onChange?: (relPath: string, action: \"indexed\" | \"removed\") => void;\n onError?: (error: unknown) => void;\n /** Fired once the initial scan has settled and the watcher is live. */\n onReady?: () => void;\n}\n\nexport interface WatchOptions {\n /** Force polling — slower but deterministic, useful in tests/CI. */\n usePolling?: boolean;\n /** Polling interval in ms when `usePolling` is set. */\n interval?: number;\n}\n\nexport interface WatchHandle {\n close: () => Promise<void>;\n}\n\nconst IGNORED = /(?:^|[\\\\/])(?:node_modules|\\.git|dist|build|coverage|\\.codescope|target|__pycache__)(?:[\\\\/]|$)/;\n\n/**\n * Watch the indexer's root and keep the graph fresh as files change. This is\n * codescope's differentiator: the agent never reads a stale graph because the\n * graph re-indexes the touched file (and only that file) on save.\n */\nexport function watch(indexer: Indexer, events: WatchEvents = {}, opts: WatchOptions = {}): WatchHandle {\n const watcher = chokidarWatch(indexer.root, {\n ignoreInitial: true,\n ignored: (path: string) => IGNORED.test(path),\n usePolling: opts.usePolling,\n interval: opts.interval,\n });\n\n const onUpsert = (abs: string): void => {\n if (!languageForPath(abs)) return;\n indexer\n .indexFile(abs)\n .then((outcome) => {\n if (outcome === \"indexed\") events.onChange?.(indexer.rel(abs), \"indexed\");\n })\n .catch((err) => events.onError?.(err));\n };\n\n watcher\n .on(\"add\", onUpsert)\n .on(\"change\", onUpsert)\n .on(\"unlink\", (abs: string) => {\n if (indexer.removeFile(abs)) events.onChange?.(indexer.rel(abs), \"removed\");\n })\n .on(\"error\", (err: unknown) => events.onError?.(err))\n .on(\"ready\", () => events.onReady?.());\n\n return {\n close: () => watcher.close(),\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport * as fmt from \"./format.js\";\nimport type { GraphStore } from \"./store.js\";\nimport { VERSION } from \"./version.js\";\n\nconst KIND = z.enum([\"function\", \"method\", \"class\", \"interface\", \"type\", \"enum\", \"variable\"]);\n\nfunction textResult(text: string): { content: Array<{ type: \"text\"; text: string }> } {\n return { content: [{ type: \"text\", text }] };\n}\n\n/**\n * Build the codescope MCP server over an already-populated {@link GraphStore}.\n * Tool descriptions are written *for the agent*: they nudge it to query the\n * graph instead of grepping and reading whole files.\n */\nexport function createServer(store: GraphStore): McpServer {\n const server = new McpServer({ name: \"codescope\", version: VERSION });\n\n server.registerTool(\n \"search_symbols\",\n {\n title: \"Search code symbols\",\n description:\n \"Fuzzy-search definitions (functions, classes, methods, interfaces, types, enums) by name across the whole repo. Prefer this over grep/glob/read when locating where something is defined — it returns exact file:line locations and signatures in a few tokens.\",\n inputSchema: {\n query: z.string().describe(\"substring to match against symbol names\"),\n kind: KIND.optional().describe(\"restrict to one symbol kind\"),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ query, kind, limit }) =>\n textResult(fmt.formatSymbols(store.searchSymbols(query, { kind, limit }))),\n );\n\n server.registerTool(\n \"get_symbol\",\n {\n title: \"Get a symbol definition\",\n description:\n \"Look up a definition by its exact name. Returns each matching definition's kind, file:line, and signature. Use this to jump straight to a definition instead of reading files.\",\n inputSchema: {\n name: z.string().describe(\"exact symbol name\"),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ name, limit }) => textResult(fmt.formatSymbols(store.getSymbol(name, { limit }))),\n );\n\n server.registerTool(\n \"find_callers\",\n {\n title: \"Find callers\",\n description:\n \"List the symbols that call a given function/method name, with file:line. Use this to trace impact and call sites without scanning files.\",\n inputSchema: {\n name: z.string().describe(\"the called function/method name\"),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ name, limit }) => textResult(fmt.formatRefs(store.findCallers(name, { limit }))),\n );\n\n server.registerTool(\n \"find_references\",\n {\n title: \"Find references\",\n description:\n \"List all references (calls and imports) to a name. Useful for understanding how widely something is used.\",\n inputSchema: {\n name: z.string(),\n kind: z.enum([\"call\", \"method\", \"import\"]).optional(),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ name, kind, limit }) =>\n textResult(fmt.formatRefs(store.findReferences(name, { kind, limit }))),\n );\n\n server.registerTool(\n \"file_outline\",\n {\n title: \"Outline a file\",\n description:\n \"List every symbol defined in a file, in source order, with signatures. A compact alternative to reading the whole file when you only need its shape.\",\n inputSchema: {\n path: z.string().describe(\"repo-relative file path\"),\n },\n },\n async ({ path }) => textResult(fmt.formatSymbols(store.fileOutline(path))),\n );\n\n server.registerTool(\n \"neighborhood\",\n {\n title: \"Call neighbourhood\",\n description:\n \"Return the call neighbourhood around a symbol — its callers and callees expanded a few hops — as a compact subgraph. This is the high-leverage tool: it gives you the relevant slice of the codebase for a change without reading dozens of files.\",\n inputSchema: {\n name: z.string(),\n depth: z.number().int().min(1).max(5).optional().describe(\"hops to expand (default 2)\"),\n limit: z.number().int().positive().max(200).optional(),\n },\n },\n async ({ name, depth, limit }) =>\n textResult(fmt.formatNeighborhood(store.neighborhood(name, { depth, limit }))),\n );\n\n server.registerTool(\n \"stats\",\n {\n title: \"Graph stats\",\n description: \"Summary counts for the indexed graph (files, symbols, refs, by kind and language).\",\n inputSchema: {},\n },\n async () => textResult(fmt.formatStats(store.stats())),\n );\n\n return server;\n}\n\n/** Connect a codescope server to stdio (the transport coding agents speak). */\nexport async function runStdioServer(store: GraphStore): Promise<void> {\n const server = createServer(store);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","import type { IndexStats, Neighborhood, RefRow, SymbolRow } from \"./types.js\";\n\n/**\n * Compact, line-oriented renderers. The whole point of codescope is to hand an\n * agent the *answer* in as few tokens as possible, so these favour terse,\n * grep-like lines over verbose prose or JSON.\n */\n\nfunction symbolLine(s: SymbolRow): string {\n const loc = `${s.file}:${s.startRow + 1}`;\n const container = s.container ? `${s.container}.` : \"\";\n const exp = s.exported ? \"export \" : \"\";\n const sig = s.signature ? ` · ${s.signature}` : \"\";\n return `${s.kind} ${exp}${container}${s.name} — ${loc}${sig}`;\n}\n\nexport function formatSymbols(rows: SymbolRow[]): string {\n if (rows.length === 0) return \"No matching symbols.\";\n return rows.map(symbolLine).join(\"\\n\");\n}\n\nexport function formatRefs(rows: RefRow[]): string {\n if (rows.length === 0) return \"No references.\";\n return rows\n .map((r) => {\n const where = r.fromSymbol ? `${r.fromSymbol}` : \"(top level)\";\n return `${where} → ${r.name} [${r.kind}] — ${r.file}:${r.startRow + 1}`;\n })\n .join(\"\\n\");\n}\n\nexport function formatNeighborhood(n: Neighborhood): string {\n const lines: string[] = [`neighbourhood of ${n.root}:`];\n lines.push(\"\", \"definitions:\");\n if (n.nodes.length === 0) lines.push(\" (none indexed)\");\n else for (const s of n.nodes) lines.push(` ${symbolLine(s)}`);\n if (n.edges.length > 0) {\n lines.push(\"\", \"call edges:\");\n for (const e of n.edges) lines.push(` ${e.from} → ${e.to}`);\n }\n if (n.unresolved.length > 0) {\n lines.push(\"\", `unresolved (referenced, not defined in index): ${n.unresolved.join(\", \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function formatStats(s: IndexStats): string {\n const kinds = Object.entries(s.byKind)\n .sort((a, b) => b[1] - a[1])\n .map(([k, n]) => `${k}=${n}`)\n .join(\" \");\n const langs = Object.entries(s.byLang)\n .sort((a, b) => b[1] - a[1])\n .map(([k, n]) => `${k}=${n}`)\n .join(\" \");\n return [\n `files: ${s.files}`,\n `symbols: ${s.symbols} (${kinds || \"none\"})`,\n `refs: ${s.refs}`,\n `langs: ${langs || \"none\"}`,\n ].join(\"\\n\");\n}\n","/** The codescope version. Kept in sync with package.json at release time. */\nexport const VERSION = \"0.1.0\";\n"],"mappings":"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","names":["rows","c","require"]}
1
+ {"version":3,"sources":["../src/store.ts","../src/indexer.ts","../src/languages.ts","../src/parser.ts","../src/watcher.ts","../src/mcp.ts","../src/affected.ts","../src/format.ts","../src/version.ts","../src/install.ts"],"sourcesContent":["import Database from \"better-sqlite3\";\nimport type {\n ContextBundle,\n ImpactRow,\n IndexStats,\n Neighborhood,\n ParsedRef,\n ParsedSymbol,\n RefRow,\n SymbolKind,\n SymbolRow,\n} from \"./types.js\";\n\nexport interface FileMeta {\n path: string;\n lang: string;\n hash: string;\n size: number;\n mtime: number;\n}\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS files (\n id INTEGER PRIMARY KEY,\n path TEXT NOT NULL UNIQUE,\n lang TEXT NOT NULL,\n hash TEXT NOT NULL,\n size INTEGER NOT NULL,\n mtime INTEGER NOT NULL,\n indexed_at INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS symbols (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n container TEXT,\n exported INTEGER NOT NULL DEFAULT 0,\n signature TEXT,\n start_row INTEGER NOT NULL,\n start_col INTEGER NOT NULL,\n end_row INTEGER NOT NULL,\n end_col INTEGER NOT NULL,\n start_byte INTEGER NOT NULL,\n end_byte INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS refs (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n from_symbol TEXT,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n start_row INTEGER NOT NULL,\n start_col INTEGER NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id);\nCREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);\nCREATE INDEX IF NOT EXISTS idx_refs_name ON refs(name);\nCREATE INDEX IF NOT EXISTS idx_refs_file ON refs(file_id);\nCREATE INDEX IF NOT EXISTS idx_refs_from ON refs(from_symbol);\n\n-- Trigram FTS index for fast substring symbol search at scale. Kept in sync\n-- manually (rowid = symbols.id) so it survives the per-file replace/delete path.\nCREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(name, tokenize='trigram');\n`;\n\ninterface SymbolDbRow {\n id: number;\n file: string;\n name: string;\n kind: string;\n container: string | null;\n exported: number;\n signature: string | null;\n start_row: number;\n start_col: number;\n end_row: number;\n end_col: number;\n}\n\ninterface RefDbRow {\n id: number;\n file: string;\n from_symbol: string | null;\n name: string;\n kind: string;\n start_row: number;\n start_col: number;\n}\n\nconst SYMBOL_COLUMNS = `\n s.id, f.path AS file, s.name, s.kind, s.container, s.exported, s.signature,\n s.start_row, s.start_col, s.end_row, s.end_col`;\n\n/**\n * The on-disk (or in-memory) code graph. All writes go through\n * {@link GraphStore.replaceFile} / {@link GraphStore.removeFile}, which operate\n * on a single file at a time so incremental updates stay O(file), not O(repo).\n */\nexport class GraphStore {\n readonly db: Database.Database;\n\n constructor(location = \":memory:\") {\n this.db = new Database(location);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.db.exec(SCHEMA);\n }\n\n /** The content hash of an already-indexed file, if present. */\n getFileHash(path: string): string | undefined {\n const row = this.db\n .prepare<[string], { hash: string }>(\"SELECT hash FROM files WHERE path = ?\")\n .get(path);\n return row?.hash;\n }\n\n /** All indexed file paths. */\n listFiles(): string[] {\n return this.db\n .prepare<[], { path: string }>(\"SELECT path FROM files ORDER BY path\")\n .all()\n .map((r) => r.path);\n }\n\n /** Insert or replace a file and all of its symbols/refs in one transaction. */\n replaceFile(meta: FileMeta, symbols: ParsedSymbol[], refs: ParsedRef[], now: number): void {\n this.transaction(() => {\n this.dropFtsForFile(meta.path);\n this.db.prepare(\"DELETE FROM files WHERE path = ?\").run(meta.path);\n const fileId = Number(\n this.db\n .prepare(\n \"INSERT INTO files (path, lang, hash, size, mtime, indexed_at) VALUES (?, ?, ?, ?, ?, ?)\",\n )\n .run(meta.path, meta.lang, meta.hash, meta.size, meta.mtime, now).lastInsertRowid,\n );\n\n const insSym = this.db.prepare(\n `INSERT INTO symbols\n (file_id, name, kind, container, exported, signature,\n start_row, start_col, end_row, end_col, start_byte, end_byte)\n VALUES (@file_id, @name, @kind, @container, @exported, @signature,\n @start_row, @start_col, @end_row, @end_col, @start_byte, @end_byte)`,\n );\n const insFts = this.db.prepare(\"INSERT INTO symbols_fts(rowid, name) VALUES (?, ?)\");\n for (const s of symbols) {\n const symId = insSym.run({\n file_id: fileId,\n name: s.name,\n kind: s.kind,\n container: s.container,\n exported: s.exported ? 1 : 0,\n signature: s.signature,\n start_row: s.startRow,\n start_col: s.startCol,\n end_row: s.endRow,\n end_col: s.endCol,\n start_byte: s.startByte,\n end_byte: s.endByte,\n }).lastInsertRowid;\n insFts.run(symId, s.name);\n }\n\n const insRef = this.db.prepare(\n `INSERT INTO refs (file_id, from_symbol, name, kind, start_row, start_col)\n VALUES (@file_id, @from_symbol, @name, @kind, @start_row, @start_col)`,\n );\n for (const r of refs) {\n insRef.run({\n file_id: fileId,\n from_symbol: r.fromSymbol,\n name: r.name,\n kind: r.kind,\n start_row: r.startRow,\n start_col: r.startCol,\n });\n }\n });\n }\n\n /** Remove a file and its symbols/refs. Returns true if anything was deleted. */\n removeFile(path: string): boolean {\n return this.transactionResult(() => {\n this.dropFtsForFile(path);\n return this.db.prepare(\"DELETE FROM files WHERE path = ?\").run(path).changes > 0;\n });\n }\n\n /** Remove the FTS rows for a file's current symbols (call before deleting it). */\n private dropFtsForFile(path: string): void {\n const ids = this.db\n .prepare<[string], { id: number }>(\n \"SELECT s.id FROM symbols s JOIN files f ON f.id = s.file_id WHERE f.path = ?\",\n )\n .all(path);\n if (ids.length === 0) return;\n const del = this.db.prepare(\"DELETE FROM symbols_fts WHERE rowid = ?\");\n for (const { id } of ids) del.run(id);\n }\n\n // ── Queries ────────────────────────────────────────────────────────────\n\n /**\n * Fuzzy substring search over symbol names. Queries of 3+ characters use the\n * trigram FTS index (fast at scale); shorter queries fall back to LIKE since\n * trigram matching needs at least three characters.\n */\n searchSymbols(query: string, opts: { kind?: SymbolKind; limit?: number } = {}): SymbolRow[] {\n const limit = clampLimit(opts.limit);\n if (query.trim().length >= 3) {\n const match = `\"${query.replace(/\"/g, '\"\"')}\"`;\n const rows = opts.kind\n ? this.db\n .prepare<[string, string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols_fts ft\n JOIN symbols s ON s.id = ft.rowid JOIN files f ON f.id = s.file_id\n WHERE symbols_fts MATCH ? AND s.kind = ?\n ORDER BY s.exported DESC, length(s.name), s.name LIMIT ?`,\n )\n .all(match, opts.kind, limit)\n : this.db\n .prepare<[string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols_fts ft\n JOIN symbols s ON s.id = ft.rowid JOIN files f ON f.id = s.file_id\n WHERE symbols_fts MATCH ?\n ORDER BY s.exported DESC, length(s.name), s.name LIMIT ?`,\n )\n .all(match, limit);\n return rows.map(toSymbolRow);\n }\n\n const like = `%${escapeLike(query)}%`;\n const rows = opts.kind\n ? this.db\n .prepare<[string, string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols s JOIN files f ON f.id = s.file_id\n WHERE s.name LIKE ? ESCAPE '\\\\' AND s.kind = ?\n ORDER BY s.exported DESC, length(s.name), s.name LIMIT ?`,\n )\n .all(like, opts.kind, limit)\n : this.db\n .prepare<[string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols s JOIN files f ON f.id = s.file_id\n WHERE s.name LIKE ? ESCAPE '\\\\'\n ORDER BY s.exported DESC, length(s.name), s.name LIMIT ?`,\n )\n .all(like, limit);\n return rows.map(toSymbolRow);\n }\n\n /** Exact-name definition lookup. */\n getSymbol(name: string, opts: { limit?: number } = {}): SymbolRow[] {\n return this.db\n .prepare<[string, number], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols s JOIN files f ON f.id = s.file_id\n WHERE s.name = ? ORDER BY s.exported DESC, f.path LIMIT ?`,\n )\n .all(name, clampLimit(opts.limit))\n .map(toSymbolRow);\n }\n\n /**\n * Distinct callers of a name (both bare `foo()` and `x.foo()`). Multiple call\n * sites from the same caller in the same file collapse to one row — fewer\n * tokens and a more useful \"who depends on this\" answer.\n */\n findCallers(name: string, opts: { limit?: number } = {}): RefRow[] {\n return this.db\n .prepare<[string, number], RefDbRow>(\n `SELECT MIN(r.id) AS id, f.path AS file, r.from_symbol, r.name,\n MIN(r.kind) AS kind, MIN(r.start_row) AS start_row, MIN(r.start_col) AS start_col\n FROM refs r JOIN files f ON f.id = r.file_id\n WHERE r.name = ? AND r.kind IN ('call', 'method')\n GROUP BY f.path, r.from_symbol\n ORDER BY f.path, start_row LIMIT ?`,\n )\n .all(name, clampLimit(opts.limit))\n .map(toRefRow);\n }\n\n /** The definitions that a symbol calls, resolved kind-aware to project symbols. */\n findCallees(name: string, opts: { limit?: number } = {}): SymbolRow[] {\n const limit = clampLimit(opts.limit);\n const out: SymbolRow[] = [];\n const seen = new Set<string>();\n for (const callee of this.calleesOf(name)) {\n const defs = this.resolveCallee(callee.name, callee.kind, 6);\n if (!defs) continue;\n for (const d of defs) {\n const key = `${d.name}@${d.file}:${d.startRow}`;\n if (!seen.has(key)) {\n seen.add(key);\n out.push(d);\n if (out.length >= limit) return out;\n }\n }\n }\n return out;\n }\n\n /** How many call sites reference this name (popularity / centrality signal). */\n callerCount(name: string): number {\n return (\n this.db\n .prepare<[string], { n: number }>(\n \"SELECT COUNT(*) AS n FROM refs WHERE name = ? AND kind IN ('call','method')\",\n )\n .get(name)?.n ?? 0\n );\n }\n\n /**\n * The blast radius of changing a symbol: its transitive callers, breadth-first,\n * annotated with hop distance and ordered nearest-first. Answers \"what could\n * break if I change this?\" without reading the codebase.\n */\n impact(name: string, opts: { depth?: number; limit?: number } = {}): ImpactRow[] {\n const depth = Math.max(1, Math.min(opts.depth ?? 3, 6));\n const limit = clampLimit(opts.limit, 300);\n const distance = new Map<string, number>([[name, 0]]);\n let frontier = [name];\n for (let d = 0; d < depth && frontier.length > 0 && distance.size < limit; d++) {\n const next: string[] = [];\n for (const node of frontier) {\n for (const caller of this.callersOf(node)) {\n if (!distance.has(caller)) {\n distance.set(caller, d + 1);\n next.push(caller);\n }\n }\n }\n frontier = next;\n }\n const out: ImpactRow[] = [];\n for (const [n, dist] of distance) {\n if (dist === 0) continue; // exclude the symbol itself\n for (const def of this.getSymbol(n, { limit: 3 })) out.push({ ...def, distance: dist });\n }\n out.sort((a, b) => a.distance - b.distance || a.file.localeCompare(b.file));\n return out.slice(0, limit);\n }\n\n /**\n * A token-budgeted relevance map for a task: the symbols matching `query` plus\n * their immediate call neighbourhood, ranked by call-site centrality, capped at\n * `maxSymbols`. This is the slice of the codebase an agent needs to start a\n * change — delivered as graph facts, not file dumps.\n */\n context(query: string, opts: { maxSymbols?: number } = {}): ContextBundle {\n const maxSymbols = Math.max(5, Math.min(opts.maxSymbols ?? 30, 100));\n const seeds = this.searchSymbols(query, { limit: Math.min(8, maxSymbols) });\n const picked = new Map<string, SymbolRow>();\n const key = (s: SymbolRow): string => `${s.name}@${s.file}:${s.startRow}`;\n for (const s of seeds) picked.set(key(s), s);\n\n // Gather neighbours of each seed, ranked by how widely they are called.\n const candidates = new Map<string, { row: SymbolRow; score: number }>();\n const edges: Array<{ from: string; to: string }> = [];\n const edgeKeys = new Set<string>();\n for (const seed of seeds) {\n for (const callee of this.findCallees(seed.name, { limit: 15 })) {\n addEdge(edges, edgeKeys, seed.name, callee.name);\n const k = key(callee);\n if (!picked.has(k) && !candidates.has(k)) {\n candidates.set(k, { row: callee, score: this.callerCount(callee.name) });\n }\n }\n for (const caller of this.findCallers(seed.name, { limit: 15 })) {\n if (!caller.fromSymbol) continue;\n addEdge(edges, edgeKeys, caller.fromSymbol, seed.name);\n for (const def of this.getSymbol(caller.fromSymbol, { limit: 1 })) {\n const k = key(def);\n if (!picked.has(k) && !candidates.has(k)) {\n candidates.set(k, { row: def, score: this.callerCount(def.name) });\n }\n }\n }\n }\n\n const related = [...candidates.values()]\n .sort((a, b) => b.score - a.score)\n .slice(0, Math.max(0, maxSymbols - picked.size))\n .map((c) => c.row);\n\n const keptNames = new Set([...seeds, ...related].map((s) => s.name));\n return {\n query,\n seeds,\n related,\n edges: edges.filter((e) => keptNames.has(e.from) && keptNames.has(e.to)),\n };\n }\n\n /** All references (calls + imports) to a name. */\n findReferences(\n name: string,\n opts: { kind?: \"call\" | \"method\" | \"import\"; limit?: number } = {},\n ): RefRow[] {\n const limit = clampLimit(opts.limit);\n const rows = opts.kind\n ? this.db\n .prepare<[string, string, number], RefDbRow>(\n `SELECT r.id, f.path AS file, r.from_symbol, r.name, r.kind, r.start_row, r.start_col\n FROM refs r JOIN files f ON f.id = r.file_id\n WHERE r.name = ? AND r.kind = ? ORDER BY f.path, r.start_row LIMIT ?`,\n )\n .all(name, opts.kind, limit)\n : this.db\n .prepare<[string, number], RefDbRow>(\n `SELECT r.id, f.path AS file, r.from_symbol, r.name, r.kind, r.start_row, r.start_col\n FROM refs r JOIN files f ON f.id = r.file_id\n WHERE r.name = ? ORDER BY f.path, r.start_row LIMIT ?`,\n )\n .all(name, limit);\n return rows.map(toRefRow);\n }\n\n /**\n * Files whose imports reference a module basename (e.g. `store` for\n * `src/store.ts`). Matches `import … from \"./store\"`, `\"../src/store.js\"`,\n * etc. Used by affected-test analysis to follow import edges, which — unlike\n * call edges — reliably reach test files (tests import the module under test).\n */\n findImporters(moduleBasename: string): string[] {\n return this.db\n .prepare<[string, string, string], { path: string }>(\n `SELECT DISTINCT f.path FROM refs r JOIN files f ON f.id = r.file_id\n WHERE r.kind = 'import' AND (r.name = ? OR r.name LIKE ? OR r.name LIKE ?)`,\n )\n .all(moduleBasename, `%/${moduleBasename}`, `%/${moduleBasename}.%`)\n .map((r) => r.path);\n }\n\n /** The symbols defined in a file, in source order. */\n fileOutline(path: string): SymbolRow[] {\n return this.db\n .prepare<[string], SymbolDbRow>(\n `SELECT ${SYMBOL_COLUMNS} FROM symbols s JOIN files f ON f.id = s.file_id\n WHERE f.path = ? ORDER BY s.start_row, s.start_col`,\n )\n .all(path)\n .map(toSymbolRow);\n }\n\n /** Distinct (callee, callKind) pairs invoked from inside symbols named `from`. */\n private calleesOf(from: string): Array<{ name: string; kind: \"call\" | \"method\" }> {\n return this.db\n .prepare<[string], { name: string; kind: \"call\" | \"method\" }>(\n \"SELECT DISTINCT name, kind FROM refs WHERE from_symbol = ? AND kind IN ('call','method')\",\n )\n .all(from);\n }\n\n /** Distinct caller symbol names that invoke `name`. */\n private callersOf(name: string): string[] {\n return this.db\n .prepare<[string], { from_symbol: string }>(\n \"SELECT DISTINCT from_symbol FROM refs WHERE name = ? AND kind IN ('call','method') AND from_symbol IS NOT NULL\",\n )\n .all(name)\n .map((r) => r.from_symbol);\n }\n\n /**\n * Resolve a callee name to project definitions, honouring how it was called:\n * a bare `foo()` resolves to non-method symbols, an `x.foo()` resolves to\n * methods. Ambiguous names (more than `ambiguityCap` definitions — typically\n * library-ish names like `push`/`map`) are treated as unresolved so they\n * don't blow up the neighbourhood. Returns `null` when nothing resolves.\n */\n private resolveCallee(\n name: string,\n callKind: \"call\" | \"method\",\n ambiguityCap: number,\n ): SymbolRow[] | null {\n const defs = this.getSymbol(name, { limit: ambiguityCap + 1 }).filter((d) =>\n callKind === \"method\" ? d.kind === \"method\" : d.kind !== \"method\",\n );\n if (defs.length === 0 || defs.length > ambiguityCap) return null;\n return defs;\n }\n\n /**\n * A bounded call neighbourhood around `name`: callers and callees expanded\n * breadth-first up to `depth`. Only edges between *resolvable project\n * symbols* are followed, so the result is the relevant slice of the codebase\n * — the payload a coding agent reads instead of grepping the whole repo.\n */\n neighborhood(\n name: string,\n opts: { depth?: number; limit?: number; maxFanout?: number; ambiguityCap?: number } = {},\n ): Neighborhood {\n const depth = Math.max(1, Math.min(opts.depth ?? 2, 5));\n const limit = clampLimit(opts.limit, 200);\n const maxFanout = opts.maxFanout ?? 25;\n const ambiguityCap = opts.ambiguityCap ?? 4;\n\n const seen = new Set<string>([name]);\n const edges: Array<{ from: string; to: string }> = [];\n const edgeKeys = new Set<string>();\n let frontier = [name];\n\n for (let d = 0; d < depth && frontier.length > 0 && seen.size < limit; d++) {\n const next = new Set<string>();\n for (const node of frontier) {\n let fanout = 0;\n for (const callee of this.calleesOf(node)) {\n if (fanout >= maxFanout) break;\n if (!this.resolveCallee(callee.name, callee.kind, ambiguityCap)) continue;\n fanout++;\n addEdge(edges, edgeKeys, node, callee.name);\n if (!seen.has(callee.name) && seen.size < limit) {\n seen.add(callee.name);\n next.add(callee.name);\n }\n }\n let callerFanout = 0;\n for (const caller of this.callersOf(node)) {\n if (callerFanout >= maxFanout) break;\n callerFanout++;\n addEdge(edges, edgeKeys, caller, node);\n if (!seen.has(caller) && seen.size < limit) {\n seen.add(caller);\n next.add(caller);\n }\n }\n }\n frontier = [...next];\n }\n\n const nodes: SymbolRow[] = [];\n const unresolved: string[] = [];\n for (const n of seen) {\n const defs = this.getSymbol(n, { limit: 5 });\n if (defs.length > 0) nodes.push(...defs);\n else unresolved.push(n);\n }\n return { root: name, nodes, edges, unresolved };\n }\n\n /** Aggregate counts for the whole graph. */\n stats(): IndexStats {\n const files = this.count(\"SELECT COUNT(*) AS n FROM files\");\n const symbols = this.count(\"SELECT COUNT(*) AS n FROM symbols\");\n const refs = this.count(\"SELECT COUNT(*) AS n FROM refs\");\n const byKind: Record<string, number> = {};\n for (const r of this.db\n .prepare<[], { kind: string; n: number }>(\n \"SELECT kind, COUNT(*) AS n FROM symbols GROUP BY kind\",\n )\n .all()) {\n byKind[r.kind] = r.n;\n }\n const byLang: Record<string, number> = {};\n for (const r of this.db\n .prepare<[], { lang: string; n: number }>(\n \"SELECT lang, COUNT(*) AS n FROM files GROUP BY lang\",\n )\n .all()) {\n byLang[r.lang] = r.n;\n }\n return { files, symbols, refs, byKind, byLang };\n }\n\n close(): void {\n this.db.close();\n }\n\n private count(sql: string): number {\n return this.db.prepare<[], { n: number }>(sql).get()?.n ?? 0;\n }\n\n private transaction(fn: () => void): void {\n this.db.transaction(fn)();\n }\n\n private transactionResult<T>(fn: () => T): T {\n return this.db.transaction(fn)();\n }\n}\n\nfunction addEdge(\n edges: Array<{ from: string; to: string }>,\n keys: Set<string>,\n from: string,\n to: string,\n): void {\n const key = `${from}\u0000${to}`;\n if (!keys.has(key)) {\n keys.add(key);\n edges.push({ from, to });\n }\n}\n\nfunction clampLimit(limit: number | undefined, max = 500): number {\n if (!limit || limit <= 0) return 50;\n return Math.min(limit, max);\n}\n\nfunction escapeLike(s: string): string {\n return s.replace(/[\\\\%_]/g, (c) => `\\\\${c}`);\n}\n\nfunction toSymbolRow(r: SymbolDbRow): SymbolRow {\n return {\n id: r.id,\n file: r.file,\n name: r.name,\n kind: r.kind as SymbolKind,\n container: r.container,\n exported: r.exported === 1,\n signature: r.signature,\n startRow: r.start_row,\n startCol: r.start_col,\n endRow: r.end_row,\n endCol: r.end_col,\n };\n}\n\nfunction toRefRow(r: RefDbRow): RefRow {\n return {\n id: r.id,\n file: r.file,\n fromSymbol: r.from_symbol,\n name: r.name,\n kind: r.kind as RefRow[\"kind\"],\n startRow: r.start_row,\n startCol: r.start_col,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { readFileSync } from \"node:fs\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport { relative, resolve, sep } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\nimport { glob } from \"tinyglobby\";\nimport { SUPPORTED_EXTENSIONS, languageForPath } from \"./languages.js\";\nimport { parseSource } from \"./parser.js\";\nimport type { GraphStore } from \"./store.js\";\nimport type { IndexRunResult } from \"./types.js\";\n\n/** Directories never worth indexing, regardless of .gitignore. */\nconst DEFAULT_IGNORES = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/coverage/**\",\n \"**/.codescope/**\",\n \"**/.next/**\",\n \"**/out/**\",\n \"**/target/**\",\n \"**/.venv/**\",\n \"**/venv/**\",\n \"**/vendor/**\",\n \"**/__pycache__/**\",\n];\n\nexport interface IndexOptions {\n /** Extra glob patterns to ignore. */\n ignore?: string[];\n /** Honour the repo's root `.gitignore` (default: true). */\n gitignore?: boolean;\n}\n\nexport type FileIndexOutcome = \"indexed\" | \"skipped\" | \"unsupported\";\n\n/**\n * Walks a repository and keeps a {@link GraphStore} in sync with it. Every\n * operation is per-file and content-hash gated, so a full re-scan skips\n * unchanged files and a single-file update touches only that file.\n */\nexport class Indexer {\n readonly root: string;\n\n constructor(\n private readonly store: GraphStore,\n root: string,\n ) {\n this.root = resolve(root);\n }\n\n /** Index every supported, non-ignored file and prune deleted ones. */\n async indexAll(opts: IndexOptions = {}): Promise<IndexRunResult> {\n const start = Date.now();\n const result: IndexRunResult = {\n indexed: 0,\n skipped: 0,\n removed: 0,\n errors: [],\n durationMs: 0,\n };\n\n const files = await this.listSourceFiles(opts);\n const present = new Set<string>();\n\n for (const abs of files) {\n present.add(this.rel(abs));\n try {\n const outcome = await this.indexFile(abs, start);\n if (outcome === \"indexed\") result.indexed++;\n else if (outcome === \"skipped\") result.skipped++;\n } catch (err) {\n result.errors.push({ file: this.rel(abs), error: errorMessage(err) });\n }\n }\n\n for (const known of this.store.listFiles()) {\n if (!present.has(known) && this.store.removeFile(known)) result.removed++;\n }\n\n result.durationMs = Date.now() - start;\n return result;\n }\n\n /** Index a single file by absolute path. Cheap when the content is unchanged. */\n async indexFile(abs: string, now = Date.now()): Promise<FileIndexOutcome> {\n const lang = languageForPath(abs);\n if (!lang) return \"unsupported\";\n\n const rel = this.rel(abs);\n const content = await readFile(abs, \"utf8\");\n const hash = sha1(content);\n if (this.store.getFileHash(rel) === hash) return \"skipped\";\n\n const mtime = await fileMtime(abs, now);\n const { symbols, refs } = await parseSource(lang.id, content);\n this.store.replaceFile(\n { path: rel, lang: lang.id, hash, size: content.length, mtime },\n symbols,\n refs,\n now,\n );\n return \"indexed\";\n }\n\n /** Drop a file from the graph by absolute path. */\n removeFile(abs: string): boolean {\n return this.store.removeFile(this.rel(abs));\n }\n\n /** Repo-relative, POSIX-separated path used as the stable graph key. */\n rel(abs: string): string {\n return relative(this.root, resolve(abs)).split(sep).join(\"/\");\n }\n\n private async listSourceFiles(opts: IndexOptions): Promise<string[]> {\n const patterns = SUPPORTED_EXTENSIONS.map((ext) => `**/*${ext}`);\n const files = await glob(patterns, {\n cwd: this.root,\n absolute: true,\n ignore: [...DEFAULT_IGNORES, ...(opts.ignore ?? [])],\n dot: false,\n });\n\n if (opts.gitignore === false) return files;\n const ig = this.loadGitignore();\n if (!ig) return files;\n return files.filter((f) => {\n const rel = this.rel(f);\n return rel.length > 0 && !ig.ignores(rel);\n });\n }\n\n private loadGitignore(): Ignore | null {\n try {\n const content = readFileSync(resolve(this.root, \".gitignore\"), \"utf8\");\n return ignore().add(content);\n } catch {\n return null;\n }\n }\n}\n\nfunction sha1(content: string): string {\n return createHash(\"sha1\").update(content).digest(\"hex\");\n}\n\nasync function fileMtime(abs: string, fallback: number): Promise<number> {\n try {\n const st = await stat(abs);\n return Math.floor(st.mtimeMs);\n } catch {\n return fallback;\n }\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import type { SymbolKind } from \"./types.js\";\n\n/**\n * Per-language configuration driving the AST walk in {@link ./parser.ts}.\n *\n * Rather than maintain a tree-sitter query (`.scm`) per grammar, we walk the\n * tree once and classify nodes by `type` using these tables. Grammars disagree\n * on a lot — C buries a function's name inside nested declarators, Java and Ruby\n * hang the callee straight off the call node, Go/Rust/C++ each use a different\n * \"member access\" node — so definitions, calls, and imports are all described\n * declaratively here and interpreted by a single generic walker.\n */\n\nexport type NameStrategy = \"field\" | \"c_declarator\" | \"first_typed\";\n\nexport interface DefRule {\n kind: SymbolKind;\n /** How to read the definition's name (default: `field` on `name`). */\n name?: NameStrategy;\n /** For the `field` strategy: which field holds the name (default `name`). */\n nameField?: string;\n /** For the `first_typed` strategy: pick the first named child of these types. */\n nameTypes?: string[];\n}\n\nexport interface CallRule {\n /** AST node type for this kind of call. */\n type: string;\n /** Field holding the callee expression (for `foo()` / `a.foo()` forms). */\n fnField?: string;\n /** Callee-expression node types that mean \"method call\". */\n memberTypes?: string[];\n /** Field on a member node holding the method name. */\n memberField?: string;\n /** Callee-expression node types that are path-qualified (`a::b`). */\n scopedTypes?: string[];\n /** Field on a scoped node holding the final name. */\n scopedField?: string;\n /** The call node holds the callee name directly in this field (Java/Ruby). */\n nameField?: string;\n /** Presence of this field on the call node marks it a method call. */\n receiverField?: string;\n /** Force the ref kind regardless of shape. */\n forceKind?: \"call\" | \"method\";\n}\n\nexport interface ImportRule {\n type: string;\n /** Read the import target from this field's text. */\n field?: string;\n /** Collect import targets from named children of these types. */\n childTypes?: string[];\n}\n\nexport interface LanguageConfig {\n id: string;\n wasm: string;\n defs: Record<string, DefRule>;\n /** Bindings (`const x = …`) that become `function` symbols when assigned a function. */\n functionBindings: Set<string>;\n /** A nested `function` whose enclosing definition is a class becomes a `method`. */\n nestedFunctionsAreMethods: boolean;\n callRules: CallRule[];\n importRules: ImportRule[];\n /** Node types whose presence as an ancestor marks a definition as exported. */\n exportTypes: Set<string>;\n}\n\nconst JS_CALLS: CallRule[] = [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"member_expression\"], memberField: \"property\" },\n];\n\nconst typescript: LanguageConfig = {\n id: \"typescript\",\n wasm: \"typescript\",\n defs: {\n function_declaration: { kind: \"function\" },\n generator_function_declaration: { kind: \"function\" },\n function_signature: { kind: \"function\" },\n method_definition: { kind: \"method\" },\n method_signature: { kind: \"method\" },\n class_declaration: { kind: \"class\" },\n abstract_class_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n type_alias_declaration: { kind: \"type\" },\n enum_declaration: { kind: \"enum\" },\n },\n functionBindings: new Set([\"variable_declarator\", \"public_field_definition\"]),\n nestedFunctionsAreMethods: false,\n callRules: JS_CALLS,\n importRules: [{ type: \"import_statement\", field: \"source\" }],\n exportTypes: new Set([\"export_statement\"]),\n};\n\nconst tsx: LanguageConfig = { ...typescript, id: \"tsx\", wasm: \"tsx\" };\n\nconst javascript: LanguageConfig = {\n id: \"javascript\",\n wasm: \"javascript\",\n defs: {\n function_declaration: { kind: \"function\" },\n generator_function_declaration: { kind: \"function\" },\n method_definition: { kind: \"method\" },\n class_declaration: { kind: \"class\" },\n },\n functionBindings: new Set([\"variable_declarator\", \"field_definition\"]),\n nestedFunctionsAreMethods: false,\n callRules: JS_CALLS,\n importRules: [{ type: \"import_statement\", field: \"source\" }],\n exportTypes: new Set([\"export_statement\"]),\n};\n\nconst python: LanguageConfig = {\n id: \"python\",\n wasm: \"python\",\n defs: {\n function_definition: { kind: \"function\" },\n class_definition: { kind: \"class\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"call\", fnField: \"function\", memberTypes: [\"attribute\"], memberField: \"attribute\" }],\n importRules: [\n { type: \"import_statement\", childTypes: [\"dotted_name\", \"aliased_import\"] },\n { type: \"import_from_statement\", field: \"module_name\" },\n ],\n exportTypes: new Set(),\n};\n\nconst go: LanguageConfig = {\n id: \"go\",\n wasm: \"go\",\n defs: {\n function_declaration: { kind: \"function\" },\n method_declaration: { kind: \"method\" },\n type_spec: { kind: \"class\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"selector_expression\"], memberField: \"field\" },\n ],\n importRules: [{ type: \"import_spec\", field: \"path\" }],\n exportTypes: new Set(),\n};\n\nconst rust: LanguageConfig = {\n id: \"rust\",\n wasm: \"rust\",\n defs: {\n function_item: { kind: \"function\" },\n struct_item: { kind: \"class\" },\n union_item: { kind: \"class\" },\n enum_item: { kind: \"enum\" },\n trait_item: { kind: \"interface\" },\n type_item: { kind: \"type\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n {\n type: \"call_expression\",\n fnField: \"function\",\n memberTypes: [\"field_expression\"],\n memberField: \"field\",\n scopedTypes: [\"scoped_identifier\"],\n scopedField: \"name\",\n },\n ],\n importRules: [{ type: \"use_declaration\", field: \"argument\" }],\n exportTypes: new Set(),\n};\n\nconst java: LanguageConfig = {\n id: \"java\",\n wasm: \"java\",\n defs: {\n class_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n enum_declaration: { kind: \"enum\" },\n record_declaration: { kind: \"class\" },\n method_declaration: { kind: \"method\" },\n constructor_declaration: { kind: \"method\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"method_invocation\", nameField: \"name\", receiverField: \"object\" }],\n importRules: [{ type: \"import_declaration\", childTypes: [\"scoped_identifier\", \"identifier\"] }],\n exportTypes: new Set(),\n};\n\nconst ruby: LanguageConfig = {\n id: \"ruby\",\n wasm: \"ruby\",\n defs: {\n method: { kind: \"method\" },\n singleton_method: { kind: \"method\" },\n class: { kind: \"class\" },\n module: { kind: \"class\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"call\", nameField: \"method\", receiverField: \"receiver\" }],\n importRules: [],\n exportTypes: new Set(),\n};\n\nconst c: LanguageConfig = {\n id: \"c\",\n wasm: \"c\",\n defs: {\n function_definition: { kind: \"function\", name: \"c_declarator\" },\n struct_specifier: { kind: \"class\" },\n union_specifier: { kind: \"class\" },\n enum_specifier: { kind: \"enum\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"field_expression\"], memberField: \"field\" },\n ],\n importRules: [{ type: \"preproc_include\", field: \"path\" }],\n exportTypes: new Set(),\n};\n\nconst cpp: LanguageConfig = {\n id: \"cpp\",\n wasm: \"cpp\",\n defs: {\n function_definition: { kind: \"function\", name: \"c_declarator\" },\n class_specifier: { kind: \"class\" },\n struct_specifier: { kind: \"class\" },\n enum_specifier: { kind: \"enum\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: true,\n callRules: [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"field_expression\"], memberField: \"field\" },\n ],\n importRules: [{ type: \"preproc_include\", field: \"path\" }],\n exportTypes: new Set(),\n};\n\nconst csharp: LanguageConfig = {\n id: \"csharp\",\n wasm: \"c_sharp\",\n defs: {\n class_declaration: { kind: \"class\" },\n struct_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n enum_declaration: { kind: \"enum\" },\n record_declaration: { kind: \"class\" },\n method_declaration: { kind: \"method\" },\n constructor_declaration: { kind: \"method\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n {\n type: \"invocation_expression\",\n fnField: \"function\",\n memberTypes: [\"member_access_expression\"],\n memberField: \"name\",\n },\n ],\n importRules: [{ type: \"using_directive\", childTypes: [\"identifier\", \"qualified_name\"] }],\n exportTypes: new Set(),\n};\n\nconst php: LanguageConfig = {\n id: \"php\",\n wasm: \"php\",\n defs: {\n function_definition: { kind: \"function\" },\n method_declaration: { kind: \"method\" },\n class_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n trait_declaration: { kind: \"class\" },\n enum_declaration: { kind: \"enum\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n { type: \"function_call_expression\", fnField: \"function\" },\n { type: \"member_call_expression\", nameField: \"name\", forceKind: \"method\" },\n { type: \"scoped_call_expression\", nameField: \"name\", forceKind: \"method\" },\n ],\n importRules: [{ type: \"namespace_use_declaration\", childTypes: [\"namespace_use_clause\"] }],\n exportTypes: new Set(),\n};\n\nconst scala: LanguageConfig = {\n id: \"scala\",\n wasm: \"scala\",\n defs: {\n class_definition: { kind: \"class\" },\n object_definition: { kind: \"class\" },\n trait_definition: { kind: \"interface\" },\n function_definition: { kind: \"method\" },\n type_definition: { kind: \"type\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [\n { type: \"call_expression\", fnField: \"function\", memberTypes: [\"field_expression\"], memberField: \"field\" },\n ],\n importRules: [{ type: \"import_declaration\", childTypes: [\"stable_identifier\", \"identifier\"] }],\n exportTypes: new Set(),\n};\n\nconst solidity: LanguageConfig = {\n id: \"solidity\",\n wasm: \"solidity\",\n defs: {\n contract_declaration: { kind: \"class\" },\n interface_declaration: { kind: \"interface\" },\n library_declaration: { kind: \"class\" },\n function_definition: { kind: \"method\" },\n modifier_definition: { kind: \"function\" },\n struct_declaration: { kind: \"class\" },\n enum_declaration: { kind: \"enum\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"call_expression\", fnField: \"function\" }],\n importRules: [{ type: \"import_directive\", field: \"source\" }],\n exportTypes: new Set(),\n};\n\nconst zig: LanguageConfig = {\n id: \"zig\",\n wasm: \"zig\",\n defs: { function_declaration: { kind: \"function\" } },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"call_expression\", fnField: \"function\" }],\n importRules: [],\n exportTypes: new Set(),\n};\n\nconst kotlin: LanguageConfig = {\n id: \"kotlin\",\n wasm: \"kotlin\",\n defs: {\n class_declaration: { kind: \"class\", name: \"first_typed\", nameTypes: [\"type_identifier\"] },\n object_declaration: { kind: \"class\", name: \"first_typed\", nameTypes: [\"type_identifier\"] },\n function_declaration: { kind: \"function\", name: \"first_typed\", nameTypes: [\"simple_identifier\"] },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: true,\n callRules: [],\n importRules: [{ type: \"import_header\", childTypes: [\"identifier\"] }],\n exportTypes: new Set(),\n};\n\nconst objc: LanguageConfig = {\n id: \"objc\",\n wasm: \"objc\",\n defs: {\n class_interface: { kind: \"class\", name: \"first_typed\", nameTypes: [\"identifier\"] },\n class_implementation: { kind: \"class\", name: \"first_typed\", nameTypes: [\"identifier\"] },\n method_declaration: { kind: \"method\", name: \"first_typed\", nameTypes: [\"identifier\"] },\n method_definition: { kind: \"method\", name: \"first_typed\", nameTypes: [\"identifier\"] },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [{ type: \"call_expression\", fnField: \"function\" }],\n importRules: [{ type: \"preproc_include\", field: \"path\" }],\n exportTypes: new Set(),\n};\n\nconst lua: LanguageConfig = {\n id: \"lua\",\n wasm: \"lua\",\n defs: {\n function_definition_statement: { kind: \"function\" },\n local_function_definition_statement: { kind: \"function\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [],\n importRules: [],\n exportTypes: new Set(),\n};\n\nconst bash: LanguageConfig = {\n id: \"bash\",\n wasm: \"bash\",\n defs: { function_definition: { kind: \"function\" } },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [],\n importRules: [],\n exportTypes: new Set(),\n};\n\nconst ocaml: LanguageConfig = {\n id: \"ocaml\",\n wasm: \"ocaml\",\n defs: {\n let_binding: { kind: \"function\", name: \"field\", nameField: \"pattern\" },\n module_definition: { kind: \"class\" },\n type_definition: { kind: \"type\" },\n },\n functionBindings: new Set(),\n nestedFunctionsAreMethods: false,\n callRules: [],\n importRules: [],\n exportTypes: new Set(),\n};\n\n/** All languages codescope can parse, keyed by config id. */\nexport const LANGUAGES: Record<string, LanguageConfig> = {\n typescript,\n tsx,\n javascript,\n python,\n go,\n rust,\n java,\n ruby,\n c,\n cpp,\n csharp,\n php,\n scala,\n solidity,\n zig,\n kotlin,\n objc,\n lua,\n bash,\n ocaml,\n};\n\n/** File extension → language id. */\nconst EXT_TO_LANG: Record<string, string> = {\n \".ts\": \"typescript\",\n \".mts\": \"typescript\",\n \".cts\": \"typescript\",\n \".tsx\": \"tsx\",\n \".js\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".jsx\": \"javascript\",\n \".py\": \"python\",\n \".pyi\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n \".java\": \"java\",\n \".rb\": \"ruby\",\n \".c\": \"c\",\n \".h\": \"c\",\n \".cc\": \"cpp\",\n \".cpp\": \"cpp\",\n \".cxx\": \"cpp\",\n \".hpp\": \"cpp\",\n \".hh\": \"cpp\",\n \".cs\": \"csharp\",\n \".php\": \"php\",\n \".scala\": \"scala\",\n \".sc\": \"scala\",\n \".sol\": \"solidity\",\n \".zig\": \"zig\",\n \".kt\": \"kotlin\",\n \".kts\": \"kotlin\",\n \".m\": \"objc\",\n \".lua\": \"lua\",\n \".sh\": \"bash\",\n \".bash\": \"bash\",\n \".ml\": \"ocaml\",\n \".mli\": \"ocaml\",\n};\n\n/** The set of file extensions codescope indexes (with leading dot). */\nexport const SUPPORTED_EXTENSIONS: readonly string[] = Object.keys(EXT_TO_LANG);\n\n/** Resolve a language config from a file path, or `undefined` if unsupported. */\nexport function languageForPath(path: string): LanguageConfig | undefined {\n const dot = path.lastIndexOf(\".\");\n if (dot === -1) return undefined;\n const ext = path.slice(dot).toLowerCase();\n const id = EXT_TO_LANG[ext];\n return id ? LANGUAGES[id] : undefined;\n}\n","import { createRequire } from \"node:module\";\nimport Parser from \"web-tree-sitter\";\nimport {\n LANGUAGES,\n type CallRule,\n type DefRule,\n type ImportRule,\n type LanguageConfig,\n} from \"./languages.js\";\nimport type { ParsedRef, ParsedSymbol, ParseResult, SymbolKind } from \"./types.js\";\n\nconst require = createRequire(import.meta.url);\n\nlet initPromise: Promise<void> | null = null;\nconst parserCache = new Map<string, Parser>();\n\n/** Resolve a grammar wasm shipped by `tree-sitter-wasms`. */\nfunction grammarPath(wasm: string): string {\n return require.resolve(`tree-sitter-wasms/out/tree-sitter-${wasm}.wasm`);\n}\n\nasync function ensureInit(): Promise<void> {\n if (!initPromise) initPromise = Parser.init();\n await initPromise;\n}\n\n/** Lazily load (and cache) a configured parser for a language. */\nasync function getParser(lang: LanguageConfig): Promise<Parser> {\n const cached = parserCache.get(lang.id);\n if (cached) return cached;\n await ensureInit();\n const language = await Parser.Language.load(grammarPath(lang.wasm));\n const parser = new Parser();\n parser.setLanguage(language);\n parserCache.set(lang.id, parser);\n return parser;\n}\n\nconst FUNCTION_VALUE_TYPES = new Set([\n \"arrow_function\",\n \"function\",\n \"function_expression\",\n \"generator_function\",\n]);\n\n/** Parse a source string into symbols and references. */\nexport async function parseSource(langId: string, source: string): Promise<ParseResult> {\n const lang = LANGUAGES[langId];\n if (!lang) throw new Error(`Unknown language: ${langId}`);\n const parser = await getParser(lang);\n const tree = parser.parse(source);\n const symbols: ParsedSymbol[] = [];\n const refs: ParsedRef[] = [];\n if (tree?.rootNode) {\n walk(tree.rootNode, lang, null, null, symbols, refs);\n tree.delete();\n }\n return { lang: lang.id, symbols, refs };\n}\n\nfunction walk(\n node: Parser.SyntaxNode,\n lang: LanguageConfig,\n container: string | null,\n containerKind: SymbolKind | null,\n symbols: ParsedSymbol[],\n refs: ParsedRef[],\n): void {\n let childContainer = container;\n let childContainerKind = containerKind;\n\n const rule = classify(node, lang);\n const call = lang.callRules.find((r) => r.type === node.type);\n const imp = lang.importRules.find((r) => r.type === node.type);\n\n if (rule) {\n const sym = buildSymbol(node, rule, container, containerKind, lang);\n if (sym) {\n symbols.push(sym);\n childContainer = sym.name;\n childContainerKind = sym.kind;\n }\n } else if (call) {\n const ref = extractCall(node, call, container);\n if (ref) refs.push(ref);\n } else if (imp) {\n for (const ref of extractImports(node, imp, container)) refs.push(ref);\n }\n\n for (const child of node.namedChildren) {\n walk(child, lang, childContainer, childContainerKind, symbols, refs);\n }\n}\n\nfunction classify(node: Parser.SyntaxNode, lang: LanguageConfig): DefRule | null {\n const direct = lang.defs[node.type];\n if (direct) return direct;\n if (lang.functionBindings.has(node.type)) {\n const value = node.childForFieldName(\"value\");\n if (value && FUNCTION_VALUE_TYPES.has(value.type)) return { kind: \"function\" };\n }\n return null;\n}\n\nfunction buildSymbol(\n node: Parser.SyntaxNode,\n rule: DefRule,\n container: string | null,\n containerKind: SymbolKind | null,\n lang: LanguageConfig,\n): ParsedSymbol | null {\n const name = symbolName(node, rule);\n if (!name) return null;\n let kind = rule.kind;\n if (kind === \"function\" && lang.nestedFunctionsAreMethods && containerKind === \"class\") {\n kind = \"method\";\n }\n return {\n name,\n kind,\n container,\n exported: isExported(node, lang),\n signature: signatureOf(node),\n startRow: node.startPosition.row,\n startCol: node.startPosition.column,\n endRow: node.endPosition.row,\n endCol: node.endPosition.column,\n startByte: node.startIndex,\n endByte: node.endIndex,\n };\n}\n\nfunction symbolName(node: Parser.SyntaxNode, rule: DefRule): string | null {\n switch (rule.name ?? \"field\") {\n case \"c_declarator\":\n return cDeclaratorName(node);\n case \"first_typed\": {\n const types = rule.nameTypes ?? [];\n for (const child of node.namedChildren) {\n if (types.includes(child.type)) return child.text;\n }\n return null;\n }\n default:\n return node.childForFieldName(rule.nameField ?? \"name\")?.text ?? null;\n }\n}\n\n/** Dig through C/C++ declarator chains (`int *foo(...)`) to the actual name. */\nfunction cDeclaratorName(node: Parser.SyntaxNode): string | null {\n let decl = node.childForFieldName(\"declarator\");\n for (let i = 0; decl && i < 10; i++) {\n if (decl.type === \"identifier\" || decl.type === \"field_identifier\") return decl.text;\n if (decl.type === \"qualified_identifier\" || decl.type === \"destructor_name\") {\n return decl.childForFieldName(\"name\")?.text ?? decl.text;\n }\n const inner = decl.childForFieldName(\"declarator\");\n if (!inner) break;\n decl = inner;\n }\n return null;\n}\n\n/** A definition is exported if an `export` statement directly wraps it. */\nfunction isExported(node: Parser.SyntaxNode, lang: LanguageConfig): boolean {\n if (lang.exportTypes.size === 0) return false;\n let cur = node.parent;\n for (let i = 0; cur && i < 2; i++) {\n if (lang.exportTypes.has(cur.type)) return true;\n cur = cur.parent;\n }\n return false;\n}\n\n/** The declaration text up to (but not including) the body, on one line. */\nfunction signatureOf(node: Parser.SyntaxNode): string | null {\n const body = node.childForFieldName(\"body\");\n const raw = body\n ? node.text.slice(0, body.startIndex - node.startIndex)\n : node.text;\n const text = raw.replace(/\\s+/g, \" \").trim();\n if (!text) return null;\n return text.length > 240 ? `${text.slice(0, 239)}…` : text;\n}\n\nfunction extractCall(\n node: Parser.SyntaxNode,\n rule: CallRule,\n container: string | null,\n): ParsedRef | null {\n let name: string | null = null;\n let kind: \"call\" | \"method\" = \"call\";\n\n if (rule.nameField) {\n // The call node carries the callee name directly (Java/Ruby/PHP member).\n name = node.childForFieldName(rule.nameField)?.text ?? null;\n if (rule.receiverField && node.childForFieldName(rule.receiverField)) kind = \"method\";\n } else if (rule.fnField) {\n const fn = node.childForFieldName(rule.fnField);\n if (fn) {\n if (rule.memberTypes?.includes(fn.type)) {\n name = fn.childForFieldName(rule.memberField ?? \"\")?.text ?? null;\n kind = \"method\";\n } else if (rule.scopedTypes?.includes(fn.type)) {\n name = fn.childForFieldName(rule.scopedField ?? \"\")?.text ?? null;\n } else if (fn.type === \"identifier\" || fn.type === \"name\") {\n name = fn.text;\n }\n }\n }\n\n if (rule.forceKind) kind = rule.forceKind;\n if (!name) return null;\n return {\n fromSymbol: container,\n name,\n kind,\n startRow: node.startPosition.row,\n startCol: node.startPosition.column,\n };\n}\n\nfunction extractImports(\n node: Parser.SyntaxNode,\n rule: ImportRule,\n container: string | null,\n): ParsedRef[] {\n const out: ParsedRef[] = [];\n const add = (spec: string | null | undefined): void => {\n const name = spec ? unquote(spec) : \"\";\n if (name) {\n out.push({\n fromSymbol: container,\n name,\n kind: \"import\",\n startRow: node.startPosition.row,\n startCol: node.startPosition.column,\n });\n }\n };\n\n if (rule.field) {\n add(node.childForFieldName(rule.field)?.text);\n }\n if (rule.childTypes) {\n for (const child of node.namedChildren) {\n if (!rule.childTypes.includes(child.type)) continue;\n // python `import x as y` exposes the real module under the `name` field\n if (child.type === \"aliased_import\") add(child.childForFieldName(\"name\")?.text);\n else add(child.text);\n }\n }\n return out;\n}\n\nfunction unquote(text: string): string {\n const t = text.trim();\n if (t.length >= 2) {\n const first = t[0];\n const last = t[t.length - 1];\n if ((first === '\"' || first === \"'\" || first === \"`\") && first === last) {\n return t.slice(1, -1);\n }\n // C/C++ include targets: <stdio.h>\n if (first === \"<\" && last === \">\") return t.slice(1, -1);\n }\n return t;\n}\n\n/** Test helper: drop cached parsers so a fresh init can be exercised. */\nexport function _resetParsers(): void {\n parserCache.clear();\n initPromise = null;\n}\n","import { watch as chokidarWatch } from \"chokidar\";\nimport { languageForPath } from \"./languages.js\";\nimport type { Indexer } from \"./indexer.js\";\n\nexport interface WatchEvents {\n /** A file was (re-)indexed or removed from the graph. */\n onChange?: (relPath: string, action: \"indexed\" | \"removed\") => void;\n onError?: (error: unknown) => void;\n /** Fired once the initial scan has settled and the watcher is live. */\n onReady?: () => void;\n}\n\nexport interface WatchOptions {\n /** Force polling — slower but deterministic, useful in tests/CI. */\n usePolling?: boolean;\n /** Polling interval in ms when `usePolling` is set. */\n interval?: number;\n}\n\nexport interface WatchHandle {\n close: () => Promise<void>;\n}\n\nconst IGNORED = /(?:^|[\\\\/])(?:node_modules|\\.git|dist|build|coverage|\\.codescope|target|__pycache__)(?:[\\\\/]|$)/;\n\n/**\n * Watch the indexer's root and keep the graph fresh as files change. This is\n * codescope's differentiator: the agent never reads a stale graph because the\n * graph re-indexes the touched file (and only that file) on save.\n */\nexport function watch(indexer: Indexer, events: WatchEvents = {}, opts: WatchOptions = {}): WatchHandle {\n const watcher = chokidarWatch(indexer.root, {\n ignoreInitial: true,\n ignored: (path: string) => IGNORED.test(path),\n usePolling: opts.usePolling,\n interval: opts.interval,\n });\n\n const onUpsert = (abs: string): void => {\n if (!languageForPath(abs)) return;\n indexer\n .indexFile(abs)\n .then((outcome) => {\n if (outcome === \"indexed\") events.onChange?.(indexer.rel(abs), \"indexed\");\n })\n .catch((err) => events.onError?.(err));\n };\n\n watcher\n .on(\"add\", onUpsert)\n .on(\"change\", onUpsert)\n .on(\"unlink\", (abs: string) => {\n if (indexer.removeFile(abs)) events.onChange?.(indexer.rel(abs), \"removed\");\n })\n .on(\"error\", (err: unknown) => events.onError?.(err))\n .on(\"ready\", () => events.onReady?.());\n\n return {\n close: () => watcher.close(),\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { affected } from \"./affected.js\";\nimport * as fmt from \"./format.js\";\nimport type { GraphStore } from \"./store.js\";\nimport { VERSION } from \"./version.js\";\n\nconst KIND = z.enum([\"function\", \"method\", \"class\", \"interface\", \"type\", \"enum\", \"variable\"]);\n\nfunction textResult(text: string): { content: Array<{ type: \"text\"; text: string }> } {\n return { content: [{ type: \"text\", text }] };\n}\n\n/**\n * Build the codescope MCP server over an already-populated {@link GraphStore}.\n * Tool descriptions are written *for the agent*: they nudge it to query the\n * graph instead of grepping and reading whole files.\n */\nexport function createServer(store: GraphStore): McpServer {\n const server = new McpServer({ name: \"codescope\", version: VERSION });\n\n server.registerTool(\n \"search_symbols\",\n {\n title: \"Search code symbols\",\n description:\n \"Fuzzy-search definitions (functions, classes, methods, interfaces, types, enums) by name across the whole repo. Prefer this over grep/glob/read when locating where something is defined — it returns exact file:line locations and signatures in a few tokens.\",\n inputSchema: {\n query: z.string().describe(\"substring to match against symbol names\"),\n kind: KIND.optional().describe(\"restrict to one symbol kind\"),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ query, kind, limit }) =>\n textResult(fmt.formatSymbols(store.searchSymbols(query, { kind, limit }))),\n );\n\n server.registerTool(\n \"get_symbol\",\n {\n title: \"Get a symbol definition\",\n description:\n \"Look up a definition by its exact name. Returns each matching definition's kind, file:line, and signature. Use this to jump straight to a definition instead of reading files.\",\n inputSchema: {\n name: z.string().describe(\"exact symbol name\"),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ name, limit }) => textResult(fmt.formatSymbols(store.getSymbol(name, { limit }))),\n );\n\n server.registerTool(\n \"find_callers\",\n {\n title: \"Find callers\",\n description:\n \"List the symbols that call a given function/method name, with file:line. Use this to trace impact and call sites without scanning files.\",\n inputSchema: {\n name: z.string().describe(\"the called function/method name\"),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ name, limit }) => textResult(fmt.formatRefs(store.findCallers(name, { limit }))),\n );\n\n server.registerTool(\n \"find_callees\",\n {\n title: \"Find callees\",\n description:\n \"List the functions/methods that a given symbol calls (resolved to their definitions). The outgoing side of the call graph — what this symbol depends on.\",\n inputSchema: {\n name: z.string().describe(\"the calling function/method name\"),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ name, limit }) => textResult(fmt.formatSymbols(store.findCallees(name, { limit }))),\n );\n\n server.registerTool(\n \"impact\",\n {\n title: \"Change impact / blast radius\",\n description:\n \"Show the transitive callers of a symbol — everything that could be affected if you change it — annotated with hop distance. Use before editing a widely-used function.\",\n inputSchema: {\n name: z.string(),\n depth: z.number().int().min(1).max(6).optional().describe(\"hops to expand (default 3)\"),\n limit: z.number().int().positive().max(300).optional(),\n },\n },\n async ({ name, depth, limit }) => textResult(fmt.formatImpact(store.impact(name, { depth, limit }))),\n );\n\n server.registerTool(\n \"context\",\n {\n title: \"Build task context\",\n description:\n \"Given a task or feature query, return a compact, ranked relevance map: the matching symbols plus their immediate call neighbourhood, ordered by how widely each is called. The fastest way to orient an agent before a change — graph facts instead of reading files.\",\n inputSchema: {\n query: z.string().describe(\"a task description or symbol/feature name\"),\n maxSymbols: z.number().int().min(5).max(100).optional().describe(\"cap on symbols (default 30)\"),\n },\n },\n async ({ query, maxSymbols }) => textResult(fmt.formatContext(store.context(query, { maxSymbols }))),\n );\n\n server.registerTool(\n \"find_references\",\n {\n title: \"Find references\",\n description:\n \"List all references (calls and imports) to a name. Useful for understanding how widely something is used.\",\n inputSchema: {\n name: z.string(),\n kind: z.enum([\"call\", \"method\", \"import\"]).optional(),\n limit: z.number().int().positive().max(500).optional(),\n },\n },\n async ({ name, kind, limit }) =>\n textResult(fmt.formatRefs(store.findReferences(name, { kind, limit }))),\n );\n\n server.registerTool(\n \"file_outline\",\n {\n title: \"Outline a file\",\n description:\n \"List every symbol defined in a file, in source order, with signatures. A compact alternative to reading the whole file when you only need its shape.\",\n inputSchema: {\n path: z.string().describe(\"repo-relative file path\"),\n },\n },\n async ({ path }) => textResult(fmt.formatSymbols(store.fileOutline(path))),\n );\n\n server.registerTool(\n \"neighborhood\",\n {\n title: \"Call neighbourhood\",\n description:\n \"Return the call neighbourhood around a symbol — its callers and callees expanded a few hops — as a compact subgraph. This is the high-leverage tool: it gives you the relevant slice of the codebase for a change without reading dozens of files.\",\n inputSchema: {\n name: z.string(),\n depth: z.number().int().min(1).max(5).optional().describe(\"hops to expand (default 2)\"),\n limit: z.number().int().positive().max(200).optional(),\n },\n },\n async ({ name, depth, limit }) =>\n textResult(fmt.formatNeighborhood(store.neighborhood(name, { depth, limit }))),\n );\n\n server.registerTool(\n \"affected\",\n {\n title: \"Affected tests\",\n description:\n \"Given a list of changed files, return the test files likely affected — the symbols those files define, walked through their transitive callers, filtered to tests. Use before running a suite to know what's worth re-running.\",\n inputSchema: {\n files: z.array(z.string()).describe(\"repo-relative paths of the changed files\"),\n depth: z.number().int().min(1).max(6).optional(),\n },\n },\n async ({ files, depth }) => textResult(fmt.formatAffected(affected(store, files, { depth }))),\n );\n\n server.registerTool(\n \"stats\",\n {\n title: \"Graph stats\",\n description: \"Summary counts for the indexed graph (files, symbols, refs, by kind and language).\",\n inputSchema: {},\n },\n async () => textResult(fmt.formatStats(store.stats())),\n );\n\n return server;\n}\n\n/** Connect a codescope server to stdio (the transport coding agents speak). */\nexport async function runStdioServer(store: GraphStore): Promise<void> {\n const server = createServer(store);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","import type { GraphStore } from \"./store.js\";\n\n/**\n * Heuristics for \"is this a test file\", across the languages codescope supports.\n * Deliberately broad — a false positive (flagging a non-test) is cheaper for an\n * agent than missing a test that should run.\n */\nconst TEST_PATTERNS: RegExp[] = [\n /(^|\\/)(tests?|spec|specs|__tests__|e2e|integration)\\//i,\n /\\.(test|spec)\\.[a-z]+$/i, // foo.test.ts, foo.spec.js\n /_test\\.[a-z]+$/i, // foo_test.go, foo_test.py, foo_test.rs\n /(^|\\/)test_[^/]+\\.(py|rb)$/i, // test_foo.py\n /(Test|Tests|Spec)\\.[a-z]+$/i, // FooTest.java, FooTests.cs, FooSpec.scala\n /_spec\\.rb$/i, // foo_spec.rb\n];\n\n/** Whether a repo-relative path looks like a test file. */\nexport function isTestFile(path: string): boolean {\n return TEST_PATTERNS.some((re) => re.test(path));\n}\n\nexport interface AffectedResult {\n changed: string[];\n /** Every file that defines a symbol transitively affected by the changes. */\n impactedFiles: string[];\n /** The impacted files that look like tests — the suite worth re-running. */\n tests: string[];\n}\n\n/**\n * Given a set of changed files, compute which test files are likely affected:\n * collect the symbols defined in the changed files, walk their transitive\n * callers, and keep the test files among the results. Answers \"what should I\n * re-run?\" without executing anything.\n */\n/** The module basename a file is imported as: `src/store.ts` → `store`. */\nfunction moduleBasename(path: string): string {\n const base = path.slice(path.lastIndexOf(\"/\") + 1);\n const dot = base.indexOf(\".\");\n return dot === -1 ? base : base.slice(0, dot);\n}\n\nexport function affected(\n store: GraphStore,\n changedPaths: string[],\n opts: { depth?: number } = {},\n): AffectedResult {\n const depth = opts.depth ?? 4;\n const impactedFiles = new Set<string>(changedPaths);\n\n // Signal 1 — call graph: transitive callers of the changed files' symbols.\n for (const path of changedPaths) {\n for (const sym of store.fileOutline(path)) {\n for (const caller of store.impact(sym.name, { depth })) {\n impactedFiles.add(caller.file);\n }\n }\n }\n\n // Signal 2 — import graph: files that (transitively) import the changed\n // files. This is what reliably reaches test files, since a test imports the\n // module it exercises even when it never appears in the call graph.\n let frontier = [...changedPaths];\n for (let d = 0; d < depth && frontier.length > 0; d++) {\n const next: string[] = [];\n for (const path of frontier) {\n for (const importer of store.findImporters(moduleBasename(path))) {\n if (!impactedFiles.has(importer)) {\n impactedFiles.add(importer);\n next.push(importer);\n }\n }\n }\n frontier = next;\n }\n\n return {\n changed: changedPaths,\n impactedFiles: [...impactedFiles].sort(),\n tests: [...impactedFiles].filter(isTestFile).sort(),\n };\n}\n","import type { AffectedResult } from \"./affected.js\";\nimport type {\n ContextBundle,\n ImpactRow,\n IndexStats,\n Neighborhood,\n RefRow,\n SymbolRow,\n} from \"./types.js\";\n\n/**\n * Compact, line-oriented renderers. The whole point of codescope is to hand an\n * agent the *answer* in as few tokens as possible, so these favour terse,\n * grep-like lines over verbose prose or JSON.\n */\n\n/** Keep signatures short — agents pay per token; full detail is one query away. */\nfunction shortSig(sig: string | null): string {\n if (!sig) return \"\";\n const s = sig.length > 88 ? `${sig.slice(0, 87)}…` : sig;\n return ` · ${s}`;\n}\n\nfunction symbolLine(s: SymbolRow): string {\n const loc = `${s.file}:${s.startRow + 1}`;\n const container = s.container ? `${s.container}.` : \"\";\n const exp = s.exported ? \"export \" : \"\";\n return `${s.kind} ${exp}${container}${s.name} — ${loc}${shortSig(s.signature)}`;\n}\n\nexport function formatSymbols(rows: SymbolRow[]): string {\n if (rows.length === 0) return \"No matching symbols.\";\n return rows.map(symbolLine).join(\"\\n\");\n}\n\nexport function formatRefs(rows: RefRow[]): string {\n if (rows.length === 0) return \"No references.\";\n // The referenced name is the query itself, so don't repeat it on every line.\n return rows\n .map((r) => {\n const where = r.fromSymbol ?? \"(top level)\";\n return `${r.file}:${r.startRow + 1} ${where}`;\n })\n .join(\"\\n\");\n}\n\nexport function formatNeighborhood(n: Neighborhood): string {\n const lines: string[] = [`neighbourhood of ${n.root}:`];\n lines.push(\"\", \"definitions:\");\n if (n.nodes.length === 0) lines.push(\" (none indexed)\");\n else for (const s of n.nodes) lines.push(` ${symbolLine(s)}`);\n if (n.edges.length > 0) {\n lines.push(\"\", \"call edges:\");\n for (const e of n.edges) lines.push(` ${e.from} → ${e.to}`);\n }\n if (n.unresolved.length > 0) {\n lines.push(\"\", `unresolved (referenced, not defined in index): ${n.unresolved.join(\", \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function formatImpact(rows: ImpactRow[]): string {\n if (rows.length === 0) return \"No callers — changing this is low-risk.\";\n return rows.map((r) => `[${r.distance} hop] ${symbolLine(r)}`).join(\"\\n\");\n}\n\nexport function formatContext(b: ContextBundle): string {\n const lines: string[] = [`context for \"${b.query}\":`, \"\", \"matches:\"];\n if (b.seeds.length === 0) lines.push(\" (no symbols matched)\");\n else for (const s of b.seeds) lines.push(` ${symbolLine(s)}`);\n if (b.related.length > 0) {\n lines.push(\"\", \"related (ranked by call-site centrality):\");\n for (const s of b.related) lines.push(` ${symbolLine(s)}`);\n }\n if (b.edges.length > 0) {\n lines.push(\"\", \"call edges:\");\n for (const e of b.edges) lines.push(` ${e.from} → ${e.to}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function formatAffected(r: AffectedResult): string {\n if (r.tests.length === 0) {\n return `No test files appear affected by ${r.changed.length} changed file(s).`;\n }\n const lines = [`${r.tests.length} test file(s) affected by your changes:`, \"\"];\n for (const t of r.tests) lines.push(` ${t}`);\n return lines.join(\"\\n\");\n}\n\nexport function formatStats(s: IndexStats): string {\n const kinds = Object.entries(s.byKind)\n .sort((a, b) => b[1] - a[1])\n .map(([k, n]) => `${k}=${n}`)\n .join(\" \");\n const langs = Object.entries(s.byLang)\n .sort((a, b) => b[1] - a[1])\n .map(([k, n]) => `${k}=${n}`)\n .join(\" \");\n return [\n `files: ${s.files}`,\n `symbols: ${s.symbols} (${kinds || \"none\"})`,\n `refs: ${s.refs}`,\n `langs: ${langs || \"none\"}`,\n ].join(\"\\n\");\n}\n","/** The codescope version. Kept in sync with package.json at release time. */\nexport const VERSION = \"0.3.0\";\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/** The npm package name and the MCP server key codescope registers under. */\nexport const PACKAGE = \"@abdulmunimjemal/codescope\";\nexport const MCP_SERVER_NAME = \"codescope\";\n\n/** Agents whose config is plain JSON with an `mcpServers` map (auto-wirable). */\nexport type AgentId = \"claude\" | \"cursor\";\nexport const SUPPORTED_AGENTS: readonly AgentId[] = [\"claude\", \"cursor\"];\n\nexport interface ServerEntry {\n command: string;\n args: string[];\n}\n\n/** The MCP server entry agents need to launch codescope over stdio. */\nexport function serverEntry(serveTarget = \".\"): ServerEntry {\n return { command: \"npx\", args: [\"-y\", PACKAGE, \"mcp\", serveTarget] };\n}\n\n/** The config file codescope writes for a given agent. */\nexport function configPath(agent: AgentId, root: string, global = false): string {\n switch (agent) {\n case \"claude\":\n return global ? join(homedir(), \".mcp.json\") : join(root, \".mcp.json\");\n case \"cursor\":\n return global ? join(homedir(), \".cursor\", \"mcp.json\") : join(root, \".cursor\", \"mcp.json\");\n }\n}\n\nexport interface InstallOutcome {\n agent: AgentId;\n path: string;\n action: \"added\" | \"updated\";\n}\n\ntype JsonObject = Record<string, unknown>;\n\nfunction readJson(path: string): JsonObject {\n if (!existsSync(path)) return {};\n try {\n const parsed: unknown = JSON.parse(readFileSync(path, \"utf8\"));\n return parsed && typeof parsed === \"object\" ? (parsed as JsonObject) : {};\n } catch {\n return {};\n }\n}\n\n/**\n * Idempotently wire codescope into an agent's MCP config. Preserves any other\n * servers already configured and overwrites only the `codescope` entry.\n */\nexport function installInto(\n agent: AgentId,\n root: string,\n opts: { global?: boolean; serveTarget?: string } = {},\n): InstallOutcome {\n const path = configPath(agent, root, opts.global ?? false);\n const config = readJson(path);\n\n const existing = config.mcpServers;\n const servers: JsonObject =\n existing && typeof existing === \"object\" ? (existing as JsonObject) : {};\n const existed = Object.prototype.hasOwnProperty.call(servers, MCP_SERVER_NAME);\n servers[MCP_SERVER_NAME] = serverEntry(opts.serveTarget);\n config.mcpServers = servers;\n\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(config, null, 2)}\\n`);\n return { agent, path, action: existed ? \"updated\" : \"added\" };\n}\n\n/** Wire codescope into one or more agents. */\nexport function install(\n root: string,\n opts: { agents?: AgentId[]; global?: boolean; serveTarget?: string } = {},\n): InstallOutcome[] {\n const agents = opts.agents ?? [...SUPPORTED_AGENTS];\n return agents.map((agent) => installInto(agent, root, opts));\n}\n\n/** Copy-paste config for agents whose config isn't plain JSON (e.g. Codex, TOML). */\nexport function codexSnippet(serveTarget = \".\"): string {\n return [\n \"[mcp_servers.codescope]\",\n 'command = \"npx\"',\n `args = [\"-y\", \"${PACKAGE}\", \"mcp\", \"${serveTarget}\"]`,\n ].join(\"\\n\");\n}\n"],"mappings":"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","names":["rows","c","moduleBasename","require","readFileSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abdulmunimjemal/codescope",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Local-first codebase knowledge-graph MCP server. Parses your repo into a symbol graph and serves it to AI coding agents so they stop wasting tokens re-scanning files. Watch-first: the graph stays fresh as you type.",
5
5
  "type": "module",
6
6
  "bin": {