@colbymchenry/codegraph 1.0.0 โ†’ 1.1.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.
Files changed (34) hide show
  1. package/README.md +87 -51
  2. package/dist/bin/fatal-handler.d.ts +20 -0
  3. package/dist/db/index.d.ts +22 -1
  4. package/dist/db/queries.d.ts +14 -0
  5. package/dist/directory.d.ts +58 -0
  6. package/dist/extraction/grammars.d.ts +11 -3
  7. package/dist/extraction/tree-sitter-types.d.ts +13 -0
  8. package/dist/extraction/tree-sitter.d.ts +119 -0
  9. package/dist/index.d.ts +33 -0
  10. package/dist/installer/instructions-template.d.ts +3 -3
  11. package/dist/installer/targets/claude.d.ts +18 -12
  12. package/dist/installer/targets/shared.d.ts +12 -2
  13. package/dist/installer/targets/types.d.ts +7 -0
  14. package/dist/mcp/daemon-manager.d.ts +42 -0
  15. package/dist/mcp/daemon-registry.d.ts +47 -0
  16. package/dist/mcp/index.d.ts +1 -0
  17. package/dist/mcp/liveness-watchdog.d.ts +18 -0
  18. package/dist/mcp/server-instructions.d.ts +18 -14
  19. package/dist/mcp/tools.d.ts +51 -1
  20. package/dist/project-config.d.ts +19 -0
  21. package/dist/reasoning/config.d.ts +45 -0
  22. package/dist/reasoning/credentials.d.ts +5 -0
  23. package/dist/reasoning/login.d.ts +21 -0
  24. package/dist/reasoning/reasoner.d.ts +43 -0
  25. package/dist/resolution/c-fnptr-synthesizer.d.ts +33 -0
  26. package/dist/resolution/callback-synthesizer.d.ts +6 -1
  27. package/dist/resolution/frameworks/goframe.d.ts +41 -0
  28. package/dist/resolution/frameworks/index.d.ts +1 -0
  29. package/dist/resolution/goframe-synthesizer.d.ts +28 -0
  30. package/dist/resolution/strip-comments.d.ts +1 -1
  31. package/dist/sync/watcher.d.ts +68 -1
  32. package/dist/telemetry/index.d.ts +0 -3
  33. package/dist/utils.d.ts +14 -1
  34. package/package.json +7 -7
package/README.md CHANGED
@@ -4,11 +4,13 @@
4
4
 
5
5
  ## ๐ŸŽ‰ 1.0 Released!
6
6
 
7
+ Already installed? Run `codegraph upgrade` to update in place.
8
+
7
9
  Follow [@getcodegraph](https://x.com/getcodegraph) on X for updates.
8
10
 
9
11
  ### Supercharge Claude Code, Cursor, Codex, OpenCode, Hermes Agent, Gemini, Antigravity, and Kiro with Semantic Code Intelligence
10
12
 
11
- **~16% cheaper ยท ~58% fewer tool calls ยท 100% local**
13
+ **Surgical context ยท fewer tool calls ยท faster answers ยท 100% local**
12
14
 
13
15
  ### [Documentation & Website โ†’](https://colbymchenry.github.io/codegraph/)
14
16
 
@@ -53,7 +55,8 @@ curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install
53
55
  irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iex
54
56
  ```
55
57
 
56
- Already have Node? Use npm instead (works on any version):
58
+ <details>
59
+ <summary><b>Already have Node? Use npm instead (works on any version)</b></summary>
57
60
 
58
61
  ```bash
59
62
  npm i -g @colbymchenry/codegraph
@@ -63,6 +66,8 @@ npm i -g @colbymchenry/codegraph
63
66
 
64
67
  <sub>**Upgrade any time** with `codegraph upgrade` โ€” it detects how you installed (bundle, npm, or npx) and updates in place. Add `--check` to see if an update is available, or `codegraph upgrade <version>` to pin one.</sub>
65
68
 
69
+ </details>
70
+
66
71
  ### 2. Wire up your agent(s)
67
72
 
68
73
  In a **new terminal**, run the installer to connect CodeGraph to the agents you use:
@@ -71,16 +76,16 @@ In a **new terminal**, run the installer to connect CodeGraph to the agents you
71
76
  codegraph install
72
77
  ```
73
78
 
74
- <sub>Detects and auto-configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, and Kiro โ€” wiring the CodeGraph MCP server into each. **This is the step that connects CodeGraph to your agent;** installing the CLI in step 1 does not do it on its own. (Shortcut: `npx @colbymchenry/codegraph` downloads and runs this in one go.)</sub>
79
+ <sub>Detects and auto-configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, and Kiro โ€” wiring the CodeGraph MCP server into each. **This is the step that connects CodeGraph to your agent;** installing the CLI in step 1 does not do it on its own. It only wires up your agent โ€” it does **not** index any code; building each project's graph is the separate `codegraph init` in step 3. (Shortcut: `npx @colbymchenry/codegraph` downloads and runs this in one go.)</sub>
75
80
 
76
81
  ### 3. Initialize each project
77
82
 
78
83
  ```bash
79
84
  cd your-project
80
- codegraph init -i
85
+ codegraph init
81
86
  ```
82
87
 
83
- <sub>`codegraph init` just creates the local `.codegraph/` index directory; adding `-i` (`--index`) also builds the initial graph in the same step. Without `-i`, run `codegraph index` afterwards to populate it.</sub>
88
+ <sub>`codegraph init` creates the local `.codegraph/` directory and builds the full graph in the same step โ€” one command, done.</sub>
84
89
 
85
90
  <div align="center">
86
91
 
@@ -88,6 +93,10 @@ codegraph init -i
88
93
 
89
94
  </div>
90
95
 
96
+ ### 4. No more syncing!
97
+
98
+ Auto-sync is enabled by default. CodeGraph watches the project and updates the graph on every file change โ€” while your agent edits code, or you add, modify, or delete files. **The index is never stale, and there is nothing to re-run.**
99
+
91
100
  ### Uninstall
92
101
 
93
102
  Changed your mind? One command removes CodeGraph from every agent it configured:
@@ -102,27 +111,33 @@ codegraph uninstall
102
111
 
103
112
  ## Why CodeGraph?
104
113
 
105
- When Claude Code explores a codebase, it spawns **Explore agents** that scan files with grep, glob, and Read โ€” consuming tokens on every tool call.
114
+ When an AI agent needs to understand code โ€” to answer a question or make a change โ€” it discovers structure the slow way: grep, glob, and Read, one file at a time, rebuilding call paths and dependencies by hand. That's a pile of tool calls and round-trips before it even starts the real work.
115
+
116
+ **CodeGraph hands the agent the exact code it needs in one call.** It's a pre-built knowledge graph of every symbol, call edge, and dependency in your codebase โ€” so instead of crawling files, the agent asks one question and gets back the relevant source, the call paths between those symbols (including dynamic-dispatch hops grep can't follow), and the blast radius of a change. **Surgical context, not a file-by-file search** โ€” which means fewer tool calls and faster answers on every codebase, large or small.
117
+
118
+ <img width="1536" height="1024" alt="token-cost-savings-scale" src="https://github.com/user-attachments/assets/eb74a11a-a3ab-4b01-80a6-19f78352ae8e" />
106
119
 
107
- **CodeGraph gives those agents a pre-indexed knowledge graph** โ€” symbol relationships, call graphs, and code structure. Agents query the graph instantly instead of scanning files.
120
+ > **A note on cost:** CodeGraph's win on *every* codebase is precision and speed โ€” fewer tool calls, faster answers. It cuts token and dollar cost too, but those savings are **scale-dependent**: small and noisy on a modest codebase, and material only once a repo is large and tangled โ€” at the scale of a Google or Microsoft monorepo, multiplied by a whole team's daily agent usage โ€” for them to compound into a real line item. On a 500-file project, adopt CodeGraph for the speed; the cost savings show up when the codebase (and the team) gets big.
108
121
 
109
122
  ### Benchmark Results
110
123
 
111
- Tested across **7 real-world open-source codebases** spanning 7 languages, comparing an agent (Claude Code, headless) answering one architecture question **with** and **without** CodeGraph. Each cell is the savings at the **median of 4 runs per arm**. _Re-validated on Opus 4.8 (2026-06-02), on the current build (`codegraph_explore` as the primary tool)._
124
+ Tested across **7 real-world open-source codebases** spanning 7 languages, comparing an agent (Claude Code, headless) answering one architecture question **with** and **without** CodeGraph, at the **median of 4 runs per arm**. _Re-validated on Opus 4.8 (2026-06-02), on the current build (`codegraph_explore` as the primary tool)._
112
125
 
113
- > **Average: 16% cheaper ยท 47% fewer tokens ยท 22% faster ยท 58% fewer tool calls**
126
+ > **The universal win โ€” every repo, every size: 58% fewer tool calls ยท 22% faster ยท file reads cut to ~zero.**
114
127
 
115
- | Codebase | Language | Cost | Tokens | Time | Tool calls |
116
- |----------|----------|------|--------|------|------------|
117
- | **VS Code** | TypeScript ยท ~10k files | 18% cheaper | 64% fewer | 11% faster | 81% fewer |
118
- | **Excalidraw** | TypeScript ยท ~640 | even | 25% fewer | 27% faster | 40% fewer |
119
- | **Django** | Python ยท ~3k | 8% cheaper | 60% fewer | 13% faster | 77% fewer |
120
- | **Tokio** | Rust ยท ~790 | even | 38% fewer | 18% faster | 57% fewer |
121
- | **OkHttp** | Java ยท ~645 | 25% cheaper | 54% fewer | 31% faster | 50% fewer |
122
- | **Gin** | Go ยท ~110 | 19% cheaper | 23% fewer | 24% faster | 44% fewer |
123
- | **Alamofire** | Swift ยท ~110 | 40% cheaper | 64% fewer | 33% faster | 58% fewer |
128
+ The reliable, universal payoff is **surgical context and speed**: CodeGraph collapses the agent's grep/find/Read crawl into a few direct queries โ€” returning the exact methods you asked about even when they're buried in a multi-thousand-line file โ€” so it answers with **near-zero file reads** while the no-CodeGraph agent spends its budget on discovery. The **Tokens** and **Cost** columns are real too, but โ€” as noted above โ€” they're **scale-dependent**: small and noisy per query, compounding into real money only at large-codebase, high-volume scale.
124
129
 
125
- CodeGraph cuts **tokens, tool calls, and wall-clock time on every repo** โ€” across small, medium, and large codebases โ€” and answers them with **near-zero file reads**, while the no-CodeGraph agent spends its budget on grep/find/Read discovery. `codegraph_explore` shows the answer in full โ€” the mechanism plus the exact methods you asked about, even when they're buried in a multi-thousand-line file โ€” while collapsing redundant interchangeable implementations to signatures, so the response is sized to the *answer* rather than the file count. **Cost stays flat-to-cheaper everywhere** โ€” largest on the small repos (Alamofire, OkHttp), roughly break-even on the most response-heavy ones (Excalidraw, Tokio), where CodeGraph trades the no-CodeGraph agent's many small grep/read round-trips for a few large, cache-heavy tool responses.
130
+ | Codebase | Language | Tool calls | Time | File reads | Tokens | Cost |
131
+ |----------|----------|------------|------|------------|--------|------|
132
+ | **VS Code** | TypeScript ยท ~10k files | 81% fewer | 11% faster | 0 vs 9 | 64% fewer | 18% cheaper |
133
+ | **Excalidraw** | TypeScript ยท ~640 | 40% fewer | 27% faster | 0 vs 7 | 25% fewer | even |
134
+ | **Django** | Python ยท ~3k | 77% fewer | 13% faster | 0 vs 9 | 60% fewer | 8% cheaper |
135
+ | **Tokio** | Rust ยท ~790 | 57% fewer | 18% faster | 0 vs 8 | 38% fewer | even |
136
+ | **OkHttp** | Java ยท ~645 | 50% fewer | 31% faster | 0 vs 4 | 54% fewer | 25% cheaper |
137
+ | **Gin** | Go ยท ~110 | 44% fewer | 24% faster | 1 vs 6 | 23% fewer | 19% cheaper |
138
+ | **Alamofire** | Swift ยท ~110 | 58% fewer | 33% faster | 0 vs 9 | 64% fewer | 40% cheaper |
139
+
140
+ <sub>**File reads** = median files the agent opened **with** vs **without** CodeGraph โ€” the surgical-context win in one column. **Tokens** and **Cost** are the same with-vs-without deltas; they're directional (they move run-to-run) and, per query, small in absolute terms โ€” which is why they only become a line item at scale. `codegraph_explore` also collapses redundant interchangeable implementations to signatures, so a response is sized to the *answer* rather than the file count.</sub>
126
141
 
127
142
  <details>
128
143
  <summary><strong>Per-repo breakdown โ€” WITH vs WITHOUT (median of 4)</strong></summary>
@@ -225,7 +240,7 @@ CodeGraph cuts **tokens, tool calls, and wall-clock time on every repo** โ€” acr
225
240
 
226
241
  | | |
227
242
  |---|---|
228
- | **Smart Context Building** | One tool call returns entry points, related symbols, and code snippets โ€” no expensive exploration agents |
243
+ | **Surgical Context** | One tool call returns entry points, related symbols, and code snippets โ€” no slow file-by-file exploration |
229
244
  | **Full-Text Search** | Find code by name instantly across your entire codebase, powered by FTS5 |
230
245
  | **Impact Analysis** | Trace callers, callees, and the full impact radius of any symbol before making changes |
231
246
  | **Always Fresh** | File watcher uses native OS events (FSEvents/inotify/ReadDirectoryChangesW) with debounced auto-sync โ€” the graph stays current as you code, zero config |
@@ -253,7 +268,7 @@ agent writes src/Widget.ts
253
268
  โ†’ next agent query sees it
254
269
  ```
255
270
 
256
- **Verify any time** with `codegraph_status` (via MCP) or `codegraph status` (CLI). If anything is pending, you'll see a `### Pending sync:` section naming the files and their edit age.
271
+ **Verify any time** with `codegraph status` (CLI). If anything is pending, you'll see a `### Pending sync:` section naming the files and their edit age.
257
272
 
258
273
  The handful of cases where manual `codegraph sync` makes sense: the watcher is disabled (sandboxed environments, or `CODEGRAPH_NO_DAEMON=1`), or you're scripting against the index outside an agent session and want a pre-flight sync at the start of your script.
259
274
 
@@ -291,7 +306,7 @@ CodeGraph detects web-framework routing files and emits `route` nodes linked by
291
306
 
292
307
  ## Mixed iOS / React Native / Expo bridging
293
308
 
294
- Real iOS and React Native codebases live across multiple languages โ€” a Swift caller invokes an Objective-C selector that's been auto-bridged, a JS file calls into a native module via the React Native bridge, a JSX component delegates to a native view manager. Static tree-sitter extraction stops at each language boundary. CodeGraph bridges them so `trace`, `callers`, `callees`, and `impact` connect end-to-end across the gap.
309
+ Real iOS and React Native codebases live across multiple languages โ€” a Swift caller invokes an Objective-C selector that's been auto-bridged, a JS file calls into a native module via the React Native bridge, a JSX component delegates to a native view manager. Static tree-sitter extraction stops at each language boundary. CodeGraph bridges them so `codegraph_explore` connects the flow end-to-end across the gap โ€” call paths and blast radius cross the boundary instead of stopping at it.
295
310
 
296
311
  | Boundary | JS / Swift side | Native side | How |
297
312
  |---|---|---|---|
@@ -330,9 +345,10 @@ The installer will:
330
345
  - Ask which agent(s) to configure โ€” auto-detects installed ones from: **Claude Code**, **Cursor**, **Codex CLI**, **opencode**, **Hermes Agent**, **Gemini CLI**, **Antigravity IDE**, **Kiro**
331
346
  - Prompt to install `codegraph` on your PATH (so agents can launch the MCP server)
332
347
  - Ask whether configs apply to all your projects or just this one
333
- - Write each chosen agent's MCP server config, plus a small marker-fenced CodeGraph section in the agent's instructions file (`CLAUDE.md` / `AGENTS.md` / `GEMINI.md`) โ€” that's how subagents and non-MCP agents learn the `codegraph explore` / `codegraph node` commands, since the MCP server's own guidance only reaches the main agent. Removed cleanly by `codegraph uninstall`.
348
+ - Write each chosen agent's MCP server config, plus a small marker-fenced CodeGraph section in the agent's instructions file (`CLAUDE.md` / `AGENTS.md` / `GEMINI.md`) โ€” that's how subagents and non-MCP agents learn the `codegraph explore` command, since the MCP server's own guidance only reaches the main agent. Removed cleanly by `codegraph uninstall`.
334
349
  - Set up auto-allow permissions when Claude Code is one of the targets
335
- - Initialize your current project (local installs only)
350
+
351
+ The installer **wires up your agents only โ€” it does not index your code.** After it finishes, build each project's graph yourself with `codegraph init` (step 3). One global `codegraph install` covers every project; you run `codegraph init` once per project.
336
352
 
337
353
  **Non-interactive (scripting / CI):**
338
354
 
@@ -359,10 +375,10 @@ Restart your agent (Claude Code / Cursor / Codex CLI / opencode / Hermes Agent /
359
375
 
360
376
  ```bash
361
377
  cd your-project
362
- codegraph init -i
378
+ codegraph init
363
379
  ```
364
380
 
365
- Builds the per-project knowledge graph index. A single global `codegraph install` works in every project you open โ€” no need to re-run the installer per project.
381
+ Builds the per-project knowledge graph index, which then auto-syncs on every file change. A single global `codegraph install` works in every project you open โ€” no need to re-run the installer per project.
366
382
 
367
383
  That's it โ€” your agent will use CodeGraph tools automatically when a `.codegraph/` directory exists.
368
384
 
@@ -392,19 +408,14 @@ npm install -g @colbymchenry/codegraph
392
408
  {
393
409
  "permissions": {
394
410
  "allow": [
395
- "mcp__codegraph__codegraph_search",
396
- "mcp__codegraph__codegraph_explore",
397
- "mcp__codegraph__codegraph_callers",
398
- "mcp__codegraph__codegraph_callees",
399
- "mcp__codegraph__codegraph_impact",
400
- "mcp__codegraph__codegraph_node",
401
- "mcp__codegraph__codegraph_status",
402
- "mcp__codegraph__codegraph_files"
411
+ "mcp__codegraph__*"
403
412
  ]
404
413
  }
405
414
  }
406
415
  ```
407
416
 
417
+ <sub>One wildcard auto-approves every CodeGraph tool โ€” `codegraph_explore` is the only one listed by default, but if you re-enable others via `CODEGRAPH_MCP_TOOLS` they're already permitted, no prompt.</sub>
418
+
408
419
  </details>
409
420
 
410
421
  <details>
@@ -413,11 +424,11 @@ npm install -g @colbymchenry/codegraph
413
424
  CodeGraph's MCP server delivers its usage guidance to your agent **automatically**, in the MCP `initialize` response. In short, it tells the agent to:
414
425
 
415
426
  - **Answer structural questions directly with CodeGraph** โ€” it *is* the pre-built index, so a grep/read loop just repeats work it already did. Treat the returned source as already read.
416
- - **Pick the tool by intent:** `codegraph_explore` for almost anything โ€” "how does X work", a flow/"how does X reach Y", or surveying an area (one call returns the relevant symbols' source grouped by file); `codegraph_search` to just locate a symbol; `codegraph_callers` for every call site (including callback registrations); `codegraph_node` for one symbol's full source + callers, or to read a file like the Read tool.
427
+ - **Reach for `codegraph_explore` for almost anything** โ€” "how does X work", a flow/"how does X reach Y", or surveying an area. One call returns the relevant symbols' verbatim source grouped by file, the call paths between them (dynamic-dispatch hops included), and a blast-radius summary. Name a file or symbol in the query to read its current line-numbered source.
417
428
  - **Trust the results โ€” don't re-verify with grep**, and check the staleness banner after edits.
418
- - In a workspace with no index, CodeGraph announces itself inactive and serves no tools โ€” indexing stays your decision.
429
+ - Works **per project**: query any project that has a `.codegraph/` index by passing `projectPath` โ€” so a monorepo where only some services are indexed, or a second repo, works in one session. A path with no index returns clean guidance to use built-in tools; indexing stays your decision.
419
430
 
420
- The exact text is `src/mcp/server-instructions.ts` โ€” the single source of truth for the main agent. Because subagents and non-MCP harnesses never see the MCP guidance, the installer also writes a four-line marker-fenced section into the agent's instructions file pointing at the `codegraph explore` / `codegraph node` CLI equivalents.
431
+ The exact text is `src/mcp/server-instructions.ts` โ€” the single source of truth for the main agent. Because subagents and non-MCP harnesses never see the MCP guidance, the installer also writes a short marker-fenced section into the agent's instructions file pointing at the `codegraph explore` CLI equivalent.
421
432
 
422
433
  </details>
423
434
 
@@ -438,7 +449,7 @@ The exact text is `src/mcp/server-instructions.ts` โ€” the single source of trut
438
449
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
439
450
  โ”‚ CodeGraph MCP Server โ”‚
440
451
  โ”‚ โ”‚
441
- โ”‚ explore ยท search ยท callers ยท callees ยท impact ยท node โ”‚
452
+ โ”‚ explore ยท one call โ†’ verbatim source + call flow + blast radius โ”‚
442
453
  โ”‚ โ”‚ โ”‚
443
454
  โ”‚ โ–ผ โ”‚
444
455
  โ”‚ SQLite knowledge graph โ”‚
@@ -462,11 +473,12 @@ The exact text is `src/mcp/server-instructions.ts` โ€” the single source of trut
462
473
  codegraph # Run interactive installer
463
474
  codegraph install # Run installer (explicit)
464
475
  codegraph uninstall # Remove CodeGraph from your agents (inverse of install)
465
- codegraph init [path] # Initialize in a project (--index to also index)
476
+ codegraph init [path] # Initialize a project + build its graph (one step)
466
477
  codegraph uninit [path] # Remove CodeGraph from a project (--force to skip prompt)
467
478
  codegraph index [path] # Full index (--force to re-index, --quiet for less output)
468
479
  codegraph sync [path] # Incremental update
469
480
  codegraph status [path] # Show statistics
481
+ codegraph unlock [path] # Remove a stale lock file that's blocking indexing
470
482
  codegraph query <search> # Search symbols (--kind, --limit, --json)
471
483
  codegraph explore <query> # Relevant symbols' source + call paths in one shot (same output as the codegraph_explore MCP tool)
472
484
  codegraph node <symbol|file> # One symbol's source + callers, or read a file with line numbers (same output as codegraph_node)
@@ -475,8 +487,11 @@ codegraph callers <symbol> # Find what calls a function/method (--limit,
475
487
  codegraph callees <symbol> # Find what a function/method calls (--limit, --json)
476
488
  codegraph impact <symbol> # Analyze what code is affected by changing a symbol (--depth, --json)
477
489
  codegraph affected [files...] # Find test files affected by changes (see below)
478
- codegraph serve --mcp # Start MCP server
490
+ codegraph daemon # Manage background daemons โ€” pick one to stop (alias: daemons)
491
+ codegraph telemetry [on|off] # Show or change anonymous usage telemetry
479
492
  codegraph upgrade [version] # Update to the latest release (--check, --force)
493
+ codegraph version # Print the installed version (also -v, --version)
494
+ codegraph help [command] # Show help, optionally for one command
480
495
  ```
481
496
 
482
497
  ### `codegraph affected`
@@ -511,18 +526,15 @@ fi
511
526
 
512
527
  ## MCP Tools
513
528
 
514
- When running as an MCP server, CodeGraph exposes a focused set of four tools โ€” measured agent behavior showed a leaner list steers agents to the right tool and saves context every session:
529
+ When running as an MCP server, CodeGraph exposes a **single tool** โ€” `codegraph_explore`. Measured agent behavior showed that one strong tool steers agents better than a menu of narrower ones โ€” fewer mis-picks, and it saves context every session:
515
530
 
516
531
  | Tool | Purpose |
517
532
  |------|---------|
518
- | `codegraph_explore` | **Primary.** Answer almost any question in one call โ€” "how does X work", a flow ("how does X reach Y"), or surveying an area โ€” returning the relevant symbols' verbatim source grouped by file, plus a relationship map and blast radius. Surfaces dynamic-dispatch hops (callbacks, React re-render, interfaceโ†’impl) grep can't follow. |
519
- | `codegraph_node` | One symbol's full source + caller/callee trail (every overload for an ambiguous name) โ€” or pass a file path to **read a whole file like the Read tool** (same line-numbered output, `offset`/`limit`), with its dependents attached. |
520
- | `codegraph_search` | Find symbols by name across the codebase |
521
- | `codegraph_callers` | Every call site of a function โ€” including where it's registered as a callback โ€” with one section per definition when several share a name |
533
+ | `codegraph_explore` | Answer almost any question in one call โ€” "how does X work", a flow ("how does X reach Y"), or surveying an area โ€” returning the relevant symbols' verbatim source grouped by file, plus the call paths between them and a blast-radius summary. Surfaces dynamic-dispatch hops (callbacks, React re-render, interfaceโ†’impl) grep can't follow. Name a file or symbol in the query to read its current line-numbered source, the same shape the Read tool gives you. |
522
534
 
523
- Four more tools (`codegraph_callees`, `codegraph_impact`, `codegraph_files`, `codegraph_status`) stay fully functional but unlisted by default โ€” measured across eval runs, agents never or rarely picked them, and their information already arrives inline on the four above (explore's blast-radius section, node's dependents note, a symbol's body as its callee list). Re-enable any of them with the `CODEGRAPH_MCP_TOOLS` environment variable (e.g. `CODEGRAPH_MCP_TOOLS=explore,node,search,callers,impact`), or use their CLI equivalents (`codegraph callees` / `impact` / `files` / `status`).
535
+ The other tools (`codegraph_node`, `codegraph_search`, `codegraph_callers`, `codegraph_callees`, `codegraph_impact`, `codegraph_files`, `codegraph_status`) stay fully functional but **unlisted by default** โ€” everything they return already arrives inline on `codegraph_explore` (its blast-radius section, the relationship map, a symbol's body as its callee list). Re-enable any of them for the MCP surface with the `CODEGRAPH_MCP_TOOLS` environment variable (e.g. `CODEGRAPH_MCP_TOOLS=explore,node,search,callers`), or use their CLI equivalents (`codegraph node` / `query` / `callers` / `callees` / `impact` / `files` / `status`).
524
536
 
525
- In a workspace with no `.codegraph/` index, the server announces itself inactive and lists **no** tools โ€” agents work normally with their built-in tools, and indexing stays your decision.
537
+ Even when the server's own root has no `.codegraph/` index, the tools stay available: pass `projectPath` to query any indexed project โ€” a sub-service in a monorepo, or a second repo โ€” in the same session. A path that has no index returns clean guidance to use built-in tools instead, so nothing fails loudly, and indexing stays your decision.
526
538
 
527
539
  ---
528
540
 
@@ -573,9 +585,10 @@ that drive the graph directly: `DatabaseConnection`, `QueryBuilder`,
573
585
 
574
586
  ## Configuration
575
587
 
576
- There isn't any โ€” CodeGraph is zero-config, with **no config file** to write or
577
- keep in sync. Language support is automatic from the file extension; there's
578
- nothing to wire up per language.
588
+ Next to none โ€” CodeGraph is **zero-config by default**, with nothing to write or
589
+ keep in sync to get started. Language support is automatic from the file
590
+ extension; there's nothing to wire up per language. The one optional file is for
591
+ mapping [custom file extensions](#custom-file-extensions).
579
592
 
580
593
  What it skips out of the box:
581
594
 
@@ -593,6 +606,29 @@ add a negation โ€” `!vendor/`. The defaults apply uniformly, so committing a
593
606
  dependency or build directory doesn't force it into the graph; the `.gitignore`
594
607
  negation is the explicit opt-in.
595
608
 
609
+ ### Custom file extensions
610
+
611
+ If your project uses a non-standard extension for a [supported
612
+ language](#supported-languages) โ€” say `.dota_lua` for Lua, or `.tpl` for PHP โ€”
613
+ those files are skipped by default, because the extension isn't one CodeGraph
614
+ recognizes. Map them with an optional **`codegraph.json`** at your project root:
615
+
616
+ ```json
617
+ {
618
+ "extensions": {
619
+ ".dota_lua": "lua",
620
+ ".tpl": "php"
621
+ }
622
+ }
623
+ ```
624
+
625
+ Each value is a supported language id. The mappings merge on top of the built-in
626
+ defaults and win on conflict, so you can also re-point a built-in (e.g.
627
+ `".h": "cpp"`). Commit the file to share the mapping with your team. A typo'd
628
+ language or a malformed file is warned about and skipped โ€” it never breaks
629
+ indexing โ€” and a project with no `codegraph.json` behaves exactly as before.
630
+ Re-index (`codegraph index`) after adding or changing mappings.
631
+
596
632
  ## Telemetry
597
633
 
598
634
  CodeGraph collects **anonymous usage statistics** โ€” which tools and commands get
@@ -709,7 +745,7 @@ Framework routing is validated the same way, on a canonical app per framework: E
709
745
  - **You're on an old (pre-0.9) install.** Reinstall to get the bundled runtime โ€” `curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh` (macOS/Linux), `irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iex` (Windows), or `npm i -g @colbymchenry/codegraph@latest`.
710
746
  - **`codegraph status` shows `Journal:` other than `wal`** โ€” WAL couldn't be enabled on this filesystem (common on network shares and WSL2 `/mnt`), so reads can block on writes. Move the project (with its `.codegraph/` folder) onto a local disk.
711
747
 
712
- **MCP server not connecting** โ€” Ensure the project is initialized/indexed, verify the path in your MCP config, and check that `codegraph serve --mcp` works from the command line.
748
+ **MCP server not connecting** โ€” Your agent starts the server itself, so you don't launch it by hand. Make sure the project is initialized and indexed (`codegraph status`) and that the path in your MCP config is correct. If it still won't connect, re-run `codegraph install` to rewrite the config.
713
749
 
714
750
  **Missing symbols** โ€” The MCP server auto-syncs on save (wait a couple seconds). Run `codegraph sync` manually if needed. Check that the file's language is supported and isn't inside a `.gitignore`d or default-excluded directory (e.g. `node_modules`, `dist`).
715
751
 
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Render an uncaught value for the last-resort log WITHOUT triggering stack
3
+ * formatting. Pure and total โ€” never throws, never touches `.stack`.
4
+ */
5
+ export declare function describeFatal(value: unknown): string;
6
+ /** Injectable seams so the wiring is testable without registering real handlers. */
7
+ export interface FatalHandlerDeps {
8
+ /** Event target to attach to. Defaults to `process`. */
9
+ target?: NodeJS.EventEmitter;
10
+ /** How to terminate. Defaults to `process.exit`. */
11
+ exit?: (code: number) => void;
12
+ /** How to emit the bounded line. Defaults to a synchronous fd-2 write. */
13
+ write?: (line: string) => void;
14
+ }
15
+ /**
16
+ * Install the uncaught-exception / unhandled-rejection handlers. Both log a
17
+ * bounded line and then exit non-zero (Node's default fatal semantics).
18
+ */
19
+ export declare function installFatalHandlers(deps?: FatalHandlerDeps): void;
20
+ //# sourceMappingURL=fatal-handler.d.ts.map
@@ -13,6 +13,15 @@ export declare class DatabaseConnection {
13
13
  private db;
14
14
  private dbPath;
15
15
  private backend;
16
+ /**
17
+ * `dev:ino` of the DB file at the moment we opened it (or null when the
18
+ * platform/filesystem reports no usable inode). Lets us notice when the file
19
+ * we hold open has been unlinked and REPLACED by a new file at the same path
20
+ * โ€” a git worktree removed and re-added, or `.codegraph/` deleted and
21
+ * re-`init`ed under a long-lived server โ€” at which point our fd reads a now
22
+ * dead inode forever (#925). See `isReplacedOnDisk`.
23
+ */
24
+ private openedInode;
16
25
  private constructor();
17
26
  /**
18
27
  * Initialize a new database at the given path
@@ -41,7 +50,7 @@ export declare class DatabaseConnection {
41
50
  *
42
51
  * SQLite silently keeps the prior mode if WAL can't be enabled โ€” e.g. on
43
52
  * filesystems without shared-memory support (some network/virtualized mounts,
44
- * WSL2 /mnt), and always on the wasm backend. So the effective mode can differ
53
+ * WSL2 /mnt). So the effective mode can differ
45
54
  * from what `configureConnection` requested. Surfaced in `codegraph status` so
46
55
  * a "database is locked" report is triageable: 'wal' โ‡’ readers never block on a
47
56
  * writer; anything else โ‡’ they can. See issue #238.
@@ -89,6 +98,18 @@ export declare class DatabaseConnection {
89
98
  * Check if the database connection is open
90
99
  */
91
100
  isOpen(): boolean;
101
+ /**
102
+ * True when the DB file at our path has been REPLACED on disk since we opened
103
+ * it โ€” a different inode now lives at the same path, so the fd we still hold
104
+ * points at a now-unlinked inode that can never receive new writes (#925).
105
+ * The trigger is removing and recreating `.codegraph/` at the same path under
106
+ * a long-lived process (`git worktree remove` + re-add, or `rm -rf
107
+ * .codegraph` + `codegraph init`). Returns false when the inode is unchanged,
108
+ * when the file is momentarily absent (mid-recreate โ€” nothing to reopen onto
109
+ * yet), or when the platform doesn't report a usable inode (Windows can't
110
+ * unlink an open file and its st_ino is unreliable, so this never fires there).
111
+ */
112
+ isReplacedOnDisk(): boolean;
92
113
  }
93
114
  /**
94
115
  * Default database filename
@@ -268,6 +268,20 @@ export declare class QueryBuilder {
268
268
  * (all kinds except `contains`); same reason imports-only is insufficient.
269
269
  */
270
270
  getDependencyFilePaths(filePath: string): string[];
271
+ /**
272
+ * Cross-file edges whose TARGET is a node in `filePath` and whose SOURCE is a
273
+ * node in a *different* file, paired with the target node's (name, kind) so a
274
+ * caller can re-resolve the edge to the re-indexed target's new ID (node IDs
275
+ * are `sha256(filePath:kind:name:line)`, so any line shift in the callee file
276
+ * changes target IDs and a naive re-insert by old ID silently drops them).
277
+ * Used by `storeExtractionResult` to preserve incoming edges across a file
278
+ * re-index (issue #899). Same edge-kind rules as
279
+ * {@link getDependentFilePaths}: all kinds except `contains`.
280
+ */
281
+ getCrossFileIncomingEdgesWithTarget(filePath: string): Array<Edge & {
282
+ targetName: string;
283
+ targetKind: NodeKind;
284
+ }>;
271
285
  /**
272
286
  * Insert or update a file record
273
287
  */
@@ -57,7 +57,65 @@ export declare function isInitialized(projectRoot: string): boolean;
57
57
  * @param startPath - Directory to start searching from
58
58
  * @returns The project root containing .codegraph/, or null if not found
59
59
  */
60
+ /**
61
+ * Reason a directory is unsafe to use as an index ROOT, or null when it's fine.
62
+ *
63
+ * Indexing your home directory or a filesystem root drags in caches, `Library`,
64
+ * every other project, etc. โ€” a multi-GB index, constant file-watcher churn, and
65
+ * (pre-1.0 on macOS) a file-descriptor blowup that exhausted `kern.maxfiles` and
66
+ * took unrelated apps / the whole machine down (#845). The classic trigger:
67
+ * running the installer or `codegraph init` from `$HOME`, which auto-indexes the
68
+ * current directory. These are never intended project roots, so the installer
69
+ * and `init`/`index` refuse them (overridable with `--force`).
70
+ *
71
+ * Pure-ish (reads only `os.homedir()` + realpath) so it's easy to unit-test.
72
+ * The returned string is a human phrase that slots into "โ€ฆ looks like {reason}".
73
+ */
74
+ export declare function unsafeIndexRootReason(projectRoot: string): string | null;
60
75
  export declare function findNearestCodeGraphRoot(startPath: string): string | null;
76
+ /**
77
+ * Indexed sub-project roots beneath `root` (bounded breadth-first scan). For
78
+ * the monorepo case behind #964: the index lives in a CHILD
79
+ * (`packages/x/.codegraph/`), not at the workspace root the agent's cwd points
80
+ * at. Descent stops at the first indexed directory on a branch (a project's
81
+ * own sub-dirs aren't separate projects) and is bounded by depth + count so it
82
+ * never turns into a full-tree crawl on a large repo.
83
+ */
84
+ export declare function findIndexedSubprojectRoots(root: string, opts?: {
85
+ maxDepth?: number;
86
+ max?: number;
87
+ }): string[];
88
+ /**
89
+ * What the front-load hook should do for a prompt issued from a directory.
90
+ */
91
+ export interface FrontloadPlan {
92
+ /** Open + explore this project and inject its source as context. `null` when
93
+ * there's no single project to front-load (none indexed, or several indexed
94
+ * sub-projects with no clear match โ€” see {@link nudgeProjects}). */
95
+ exploreRoot: string | null;
96
+ /** Indexed sub-projects to surface in a "pass `projectPath`" nudge: the rest
97
+ * of a monorepo's indexed projects alongside `exploreRoot`, or โ€” when no one
98
+ * project clearly matches โ€” the full list (with `exploreRoot` null). */
99
+ nudgeProjects: string[];
100
+ /** True when the plan came from scanning DOWN into sub-projects (cwd itself
101
+ * is not under any index) โ€” the monorepo case, where a follow-up
102
+ * `codegraph_explore` needs an explicit `projectPath`. */
103
+ viaSubScan: boolean;
104
+ }
105
+ /**
106
+ * Decide what the front-load hook injects for a `prompt` issued from `cwd`,
107
+ * shaped by where the `.codegraph/` index(es) actually are:
108
+ * 1. **cwd (or an ancestor) is indexed** โ†’ front-load that project. The
109
+ * normal single-project / nested-file case.
110
+ * 2. **cwd isn't indexed but looks like a workspace root** โ†’ the indexes live
111
+ * in sub-projects (the monorepo case behind #964). One indexed
112
+ * sub-project โ†’ front-load it; several โ†’ front-load the one the prompt
113
+ * names (by relative path like `packages/api`, or package directory name)
114
+ * and nudge about the rest; several with no match โ†’ nudge the full list so
115
+ * the agent passes `projectPath`, rather than guessing wrong.
116
+ * 3. **nothing indexed reachable** โ†’ do nothing (the agent's own tools apply).
117
+ */
118
+ export declare function planFrontload(cwd: string, prompt: string): FrontloadPlan;
61
119
  /**
62
120
  * Create the .codegraph directory structure
63
121
  * Note: Only throws if codegraph.db already exists, not just if .codegraph/ exists.
@@ -16,8 +16,12 @@ export declare const EXTENSION_MAP: Record<string, Language>;
16
16
  * Whether a file is one CodeGraph can parse, based purely on its extension.
17
17
  * This is the single source of truth for "should we index this file" โ€” derived
18
18
  * from EXTENSION_MAP so parser support and indexing selection never drift.
19
+ *
20
+ * `overrides` is the project's validated custom extension โ†’ language map (from
21
+ * `codegraph.json`); when present its extensions count as indexable in addition
22
+ * to the built-ins. Omitting it is byte-identical to the zero-config behavior.
19
23
  */
20
- export declare function isSourceFile(filePath: string): boolean;
24
+ export declare function isSourceFile(filePath: string, overrides?: Record<string, Language>): boolean;
21
25
  /**
22
26
  * Shopify OS 2.0 JSON template (`templates/*.json`) or section group
23
27
  * (`sections/*.json`) โ€” these reference sections by `"type"`, so the Liquid
@@ -57,9 +61,13 @@ export declare function isGrammarsInitialized(): boolean;
57
61
  */
58
62
  export declare function getParser(language: Language): Parser | null;
59
63
  /**
60
- * Detect language from file extension
64
+ * Detect language from file extension.
65
+ *
66
+ * `overrides` is the project's validated custom extension โ†’ language map (from
67
+ * `codegraph.json`); when present its mappings take precedence over the built-in
68
+ * `EXTENSION_MAP`. Omitting it is byte-identical to the zero-config behavior.
61
69
  */
62
- export declare function detectLanguage(filePath: string, source?: string): Language;
70
+ export declare function detectLanguage(filePath: string, source?: string, overrides?: Record<string, Language>): Language;
63
71
  /**
64
72
  * Check if a language is supported (has a grammar defined).
65
73
  * Returns true if the grammar exists, even if not yet loaded.
@@ -147,6 +147,19 @@ export interface LanguageExtractor {
147
147
  * Used by languages with fundamentally different AST structures (e.g. Pascal).
148
148
  */
149
149
  visitNode?: (node: SyntaxNode, ctx: ExtractorContext) => boolean;
150
+ /**
151
+ * Synthesize members that exist at compile time but not in the source AST,
152
+ * called at the end of class extraction with the class still on the scope
153
+ * stack (so `ctx.createNode` attaches containment + qualified names) and the
154
+ * class's real members already extracted (so the hook can skip a member the
155
+ * source explicitly declares). Used by Java for Lombok-generated accessors
156
+ * (`@Getter`/`@Setter`/`@Data`/`@Value`/`@Builder` โ†’ `getX`/`setX`/`builder`/
157
+ * `equals`/`hashCode`/`toString` + the `log` field), which are otherwise
158
+ * invisible and break call-chain analysis (#912). The created nodes carry a
159
+ * `lombok` decorator + a docstring naming the generating annotation, so an
160
+ * agent can tell them apart from hand-written code.
161
+ */
162
+ synthesizeMembers?: (classNode: SyntaxNode, ctx: ExtractorContext) => void;
150
163
  /**
151
164
  * Classify a class_declaration node when the grammar reuses one node type
152
165
  * for multiple concepts (e.g. Swift uses class_declaration for classes, structs, and enums).