CodeGraph
Brain app
First committed by colbymchenry
Published in colbymchenry/codegraph. Publisher page
77,372 GitHub stars
What it is
Supercharge AI coding agents with semantic code intelligence — surgical context, fewer tool calls, faster answers. 100% local.
AutoGineer overview, from the brain’s own files
CodeGraph is a local-first code intelligence platform that transforms how AI coding agents interact with large codebases. By parsing code into a structured knowledge graph using tree-sitter, it enables agents to perform precise, semantic queries rather than relying on inefficient file-crawling or grep-based searches. It stores symbol definitions, call edges, and dependencies in a local SQLite database, allowing agents to retrieve exact, relevant code snippets and blast-radius summaries in a single round-trip. Designed for seamless integration, it acts as an MCP server that connects to various coding agents, significantly reducing token usage and tool calls while improving the accuracy of agentic code navigation.
How it works
Memory model: Hybrid
AutoGineer overview, from the brain’s own files
CodeGraph operates as a local-first service that indexes a project by parsing source code into a graph of symbols and relationships. It uses tree-sitter for deterministic extraction and stores the resulting data in a local SQLite database. When an agent needs information, it queries this graph via an MCP server to retrieve specific code segments and call paths. The system includes an auto-sync feature that monitors file changes to keep the index updated without manual intervention.
| Folder | Role | Files |
|---|---|---|
| .claude | agent-config | 3 |
| .cursor | agent-config | 1 |
| .github | agent-config | 2 |
| __tests__ | tests | 1045 |
| assets | attachments | 40 |
| docs | docs | 76 |
| scripts | scripts | 75 |
| src | source-code | 359 |
| codegraph-kernel | folder | 59 |
| site | folder | 33 |
| telemetry-dashboard | folder | 22 |
| telemetry-worker | folder | 18 |
| ui | folder | 97 |
The agent reads
- docs/design/framework-coverage.md evidence: AGENTS.md
- AGENTS.md evidence: CLAUDE.md
- .gitignore evidence: README.md
The agent writes
- CLAUDE.md evidence: AGENTS.md
- docs/benchmarks/call-sequence-analysis.md evidence: AGENTS.md
- scripts/prepare-release.mjs evidence: AGENTS.md
- src/mcp/server-instructions.ts evidence: AGENTS.md
- AGENTS.md evidence: README.md
- .gitignore evidence: README.md
Requirements
Runtimes: Node.js >=20.0.0 <25.0.0
Databases: Redis, SQLite
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)
Set it up
This brain runs code automatically: 5 scripts. Review README.md, install.ps1, install.sh before opening the folder in Claude Code. No step below turns a hook on for you.
README.md:curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | shREADME.md:irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iexREADME.md:- **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 …[+42 chars]install.ps1:pwsh install.ps1install.sh:sh install.sh
- Not scanned by AutoGineerIts dependencies are installed by npm when you run it and were not scanned by AutoGineer (6 declared). https://www.npmjs.com/package/@colbymchenry/codegraph
First committed by colbymchenry. Published in colbymchenry/codegraph. Licence: MIT License.
Usage
AutoGineer overview, from the brain’s own files
- Install the CLI tool to manage project indexing and agent configuration.
- Initialize a project to build the local knowledge graph.
- Connect the MCP server to supported AI coding agents.
- Query the graph using natural language for structural code questions.
- “How does the authentication flow work in this project?”
- The agent uses codegraph_explore to retrieve the relevant call paths and source code for authentication-related symbols, providing a complete structural overview.
- “What is the blast radius of changing this function signature?”
- The agent queries the graph to identify all callers and dependent modules, returning a summary of affected files and logic.
Documentation by colbymchenry
<div align="center">
CodeGraph
Already installed? Run codegraph upgrade
Follow @getcodegraph on X for updates.
Supercharge Claude Code, Cursor, Codex, OpenCode, Hermes Agent, Gemini, Antigravity, Kiro, GitHub Copilot, and more with Semantic Code Intelligence
The fastest complete code graph · surgical context · built for how agents actually work · 100% local
<picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/rust-logo-dark.svg?v=1"> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/rust-logo.svg?v=1" height="30" alt="Rust" align="center"> </picture> **Kernel powered by Rust**
Documentation & Website →
Image: npm version Image: License: MIT Image: Self-contained Image: npm provenance Image: Attested builds
Image: Windows Image: macOS Image: Linux
Image: Claude Code Image: Cursor Image: Codex Image: opencode Image: Hermes Agent Image: Gemini Image: Antigravity Image: Kiro Image: GitHub Copilot Image: IBM Bob Image: Factory Droid Image: Windsurf Image: Qwen Code Image: DeepSeek Harness Image: Grok Build Image: Kimi Code Image: Qoder Image: Pi
<br>
The CodeGraph platform is coming — for every PR, know exactly what to test, what could break, which flows are affected, and whether business logic is compromised.
<a href="https://getcodegraph.com"><img alt="Join the waitlist for early beta access" src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/waitlist.svg?v=2" height="52"></a>
<sub>Get <b>early beta access</b> to the hosted product · <a href="https://getcodegraph.com">getcodegraph.com</a></sub>
</div>
Contents
Get Started
Language Support
Why CodeGraph?
Key Features
Framework-aware Routes
Mixed iOS / React Native / Expo bridging
Quick Start
How It Works
CLI Reference
MCP Tools
Library Usage
Configuration
Telemetry
Verified releases
Supported Platforms
Supported Agents
Supported Languages
Measured cross-file coverage
Troubleshooting
Contributing
License
Get Started
1. Install the CLI
No Node.js required — one command grabs the right build for your OS:
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh
# Windows (PowerShell)
irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iex<details> <summary><b>Already have Node? Use npm instead (works on any version)</b></summary>
npm i -g @colbymchenry/codegraph<sub>CodeGraph bundles its own runtime — nothing to compile, no native build, works the same everywhere. The installer puts codegraph on your PATH but doesn't change your current shell — open a new terminal before the next step so the command resolves.</sub>
<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>
</details>
2. Wire up your agent(s)
In a new terminal, run the installer to connect CodeGraph to the agents you use:
codegraph install<sub>Detects and auto-configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, GitHub Copilot (VS Code, Copilot CLI, JetBrains IDEs), IBM Bob, Factory Droid, Windsurf, Qwen Code, DeepSeek Harness, Grok Build, Kimi Code, Qoder CLI, and Pi — 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>
3. Initialize each project
cd your-project
codegraph init<sub>codegraph init creates the local .codegraph/ directory and builds the full graph in the same step — one command, done.</sub>
<div align="center">
Image: 1_C_VYnhpys0UHrOuOgpgoyw
</div>
4. No more syncing!
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.
Uninstall
Changed your mind? One command removes CodeGraph from every agent it configured and the CLI itself — every install it finds (standalone bundle, npm global package, launcher link), shown to you before anything is deleted:
codegraph uninstallPass --keep-cli to remove only the agent configurations and keep the CLI installed.
<sub>Reverses the installer — strips CodeGraph's MCP server config, instructions, and permissions from each configured agent. Your project indexes (.codegraph/) are left untouched; remove those per-project with codegraph uninit. Use --target to remove from specific agents, or --yes to run non-interactively.</sub>
Language Support
Every language below gets the same treatment — full structural extraction and cross-file resolution into one graph, no per-language setup:
<p align="center"> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/typescript.svg?v=1" width="104" height="104" alt="TypeScript" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/javascript.svg?v=1" width="104" height="104" alt="JavaScript" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/arkts.svg?v=1" width="104" height="104" alt="ArkTS" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/python.svg?v=1" width="104" height="104" alt="Python" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/go.svg?v=1" width="104" height="104" alt="Go" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/rust.svg?v=1" width="104" height="104" alt="Rust" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/java.svg?v=1" width="104" height="104" alt="Java" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/csharp.svg?v=1" width="104" height="104" alt="C#" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/php.svg?v=1" width="104" height="104" alt="PHP" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/ruby.svg?v=1" width="104" height="104" alt="Ruby" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/c.svg?v=1" width="104" height="104" alt="C" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/cpp.svg?v=1" width="104" height="104" alt="C++" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/objective-c.svg?v=1" width="104" height="104" alt="Objective-C" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/metal.svg?v=1" width="104" height="104" alt="Metal" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/cuda.svg?v=1" width="104" height="104" alt="CUDA" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/swift.svg?v=1" width="104" height="104" alt="Swift" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/kotlin.svg?v=1" width="104" height="104" alt="Kotlin" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/scala.svg?v=1" width="104" height="104" alt="Scala" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/dart.svg?v=1" width="104" height="104" alt="Dart" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/svelte.svg?v=1" width="104" height="104" alt="Svelte" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/vue.svg?v=1" width="104" height="104" alt="Vue" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/astro.svg?v=1" width="104" height="104" alt="Astro" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/liquid.svg?v=1" width="104" height="104" alt="Liquid" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/delphi.svg?v=1" width="104" height="104" alt="Pascal / Delphi" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/lua.svg?v=1" width="104" height="104" alt="Lua" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/r.svg?v=1" width="104" height="104" alt="R" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/luau.svg?v=1" width="104" height="104" alt="Luau" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/cfml.svg?v=1" width="104" height="104" alt="CFML" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/cobol.svg?v=1" width="104" height="104" alt="COBOL" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/vbnet.svg?v=1" width="104" height="104" alt="Visual Basic .NET" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/erlang.svg?v=1" width="104" height="104" alt="Erlang" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/solidity.svg?v=1" width="104" height="104" alt="Solidity" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/terraform.svg?v=1" width="104" height="104" alt="Terraform / OpenTofu" /> <img src="https://raw.githubusercontent.com/colbymchenry/codegraph/main/assets/languages/nix.svg?v=1" width="104" height="104" alt="Nix" /> </p>
<sub>Per-language details — extensions, frameworks, and what exactly gets extracted — in Supported Languages.</sub>
Why CodeGraph?
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.
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.
<img width="1536" height="1024" alt="token-cost-savings-scale" src="https://github.com/user-attachments/assets/eb74a11a-a3ab-4b01-80a6-19f78352ae8e" />
A note on cost: CodeGraph's win on every codebase is precision — the agent stops crawling files and answers from the graph. On current models that precision is also a large direct saving: the 2026-08 re-measurement, on a harness that blocks the CLI in both arms, put it at 44% lower cost and 62% fewer tokens on average across the seven benchmark repos, because a strong model without the graph burns its budget re-deriving structure. Cost tracks how much discovery a question demands more than raw repo size: 57–78% on questions the file-reading agent needed 28–43 tool calls to answer, near-even where it got there in 7.
A note on context: the numbers above measure throughput — tokens processed, tools called, dollars spent to reach one answer. They don't measure what is still sitting in your context window afterward, and on that axis CodeGraph costs more, not less. Across the same seven repos in multi-turn sessions, CodeGraph's responses leave about 80% more retrieval context resident at the end of a session than a file-reading agent's do — on VS Code, 67k tokens against 18k. The mechanism is the same one that makes it fast: CodeGraph returns one dense, verbatim payload that answers the question and then stays in the window, where a grep-and-read agent churns through many small results that get evicted. Fewer tokens processed and a larger persistent footprint are both real at once. If you run long sessions in a small window, budget for it. Measured per-repo:
docs/benchmarks/residual-context-occupancy.md.
Benchmark Results
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-measured 2026-08-05 on Claude Opus 4.8 against the current build, on a harness that blocks the codegraph CLI in both arms — contamination row: 0 of 28 without-arm runs.
The universal win — every repo, every size: 88% fewer tool calls · 53% faster · 62% fewer tokens · 44% cheaper · file reads cut to zero on all seven repos.
With the index available, the agent answers from one to four codegraph_explore calls and stops. Without it, the agent burns its budget on discovery — up to 43 tool calls and 19 file reads re-deriving what the graph already knew. Every repo was faster with CodeGraph in this measurement — by 35% on the narrowest question, by 3.6× on the widest.
| Codebase | Language | Tool calls | Time | File reads | Tokens | Cost |
|---|---|---|---|---|---|---|
| VS Code | TypeScript · ~11k files | 2 vs 28 | 2.2× faster (58s vs 2m 10s) | 0 vs 12 | 77% fewer | 71% cheaper |
| Excalidraw | TypeScript · ~640 | 2 vs 43 | 3.6× faster (45s vs 2m 42s) | 0 vs 18 | 84% fewer | 78% cheaper |
| Django | Python · ~3k | 3 vs 14 | 35% faster (54s vs 1m 23s) | 0 vs 8.5 | 41% fewer | 13% cheaper¹ |
| Tokio | Rust · ~790 | 3 vs 29 | 2.6× faster (1m 3s vs 2m 43s) | 0 vs 19 | 65% fewer | 64% cheaper |
| OkHttp | Java · ~645 | 1 vs 6 | 43% faster (33s vs 58s) | 0 vs 2 | 54% fewer | 21% cheaper |
| Gin | Go · ~110 | 1 vs 7 | 39% faster (28s vs 46s) | 0 vs 4 | 52% fewer | ~even¹ |
| Alamofire | Swift · ~110 | 4 vs 33 | 2.6× faster (54s vs 2m 22s) | 0 vs 16.5 | 59% fewer | 57% cheaper |
<sub>¹ Cost tracks how much discovery the question demanded, which is why it varies far more than the other columns: 57–78% on repos where the file-reading arm needed 28–43 tool calls, but only 13% on Django and even on Gin, where it got there in 14 and 7. The with-arm still answered in 3 and 1 calls with zero file reads. File reads = median files opened — the surgical-context win in one column: the agent never reads a file on any of the seven repos when CodeGraph is present.</sub>
<details> <summary><strong>Per-repo breakdown — WITH vs WITHOUT (median of 4)</strong></summary>
| Codebase | Metric | WITH cg | WITHOUT cg |
|---|---|---|---|
| VS Code | Time / Tools / Tokens / Cost | 58s / 2 / 155k / $0.53 | 2m 10s / 28 / 670k / $1.80 |
| Excalidraw | Time / Tools / Tokens / Cost | 45s / 2 / 156k / $0.54 | 2m 42s / 43 / 991k / $2.43 |
| Django | Time / Tools / Tokens / Cost | 54s / 3 / 183k / $0.55 | 1m 23s / 14 / 309k / $0.63 |
| Tokio | Time / Tools / Tokens / Cost | 1m 3s / 3 / 201k / $0.66 | 2m 43s / 29 / 573k / $1.83 |
| OkHttp | Time / Tools / Tokens / Cost | 33s / 1 / 107k / $0.39 | 58s / 6 / 230k / $0.50 |
| Gin | Time / Tools / Tokens / Cost | 28s / 1 / 87k / $0.31 | 46s / 7 / 180k / $0.31 |
| Alamofire | Time / Tools / Tokens / Cost | 54s / 4 / 209k / $0.54 | 2m 22s / 33 / 505k / $1.27 |
</details>
<details> <summary><strong>Full benchmark details</strong></summary>
Methodology. Each arm is claude -p (Claude Opus 4.8, claude-opus-4-8) run headlessly against the repo with --strict-mcp-config: WITH = CodeGraph's MCP server enabled, WITHOUT = an empty MCP config. Built-in Read/Grep/Bash stay available to both. Same question per repo, 4 runs per arm, median reported. Cost = the run's total_cost_usd; Tokens = total tokens processed, summed per assistant turn (input incl. cache reads + cache creation + output); Time = wall-clock; Tool calls = every tool invocation, including those inside any sub-agents the model spawns. Repos cloned at --depth 1 and indexed by the same CodeGraph build that served them. Re-measured 2026-08-05 on the current build.
The codegraph CLI is blocked in both arms. A sanitized PATH plus a PreToolUse hook denies any Bash invocation of the CLI, in the WITHOUT arm as well as the WITH arm. This matters: without that block the control arm is not a control. On an unblocked harness we measured the WITHOUT agent finding the CLI on PATH and reaching CodeGraph through Bash in 26 of 28 runs — which distorts the comparison in both directions, since a CLI call is not counted as a tool call and its output still enters the window. Earlier published figures were produced without this block. In the run reported above, all 28 WITHOUT runs attempted the CLI and all 28 were blocked — 0 contaminated.
Queries:
| Codebase | Query |
|---|---|
| VS Code | "How does the extension host communicate with the main process?" |
| Excalidraw | "How does Excalidraw render and update canvas elements?" |
| Django | "How does Django's ORM build and execute a query from a QuerySet?" |
| Tokio | "How does tokio schedule and run async tasks on its runtime?" |
| OkHttp | "How does OkHttp process a request through its interceptor chain?" |
| Gin | "How does gin route requests through its middleware chain?" |
| Alamofire | "How does Alamofire build, send, and validate a request?" |
Why CodeGraph wins: with the index available, the agent answers directly — usually one codegraph_explore returns the relevant source — and stops, with zero file reads on every benchmark repo. Without it, the agent spends most of its budget on discovery (find/ls/grep) before reading the right code. CodeGraph only helps when queried directly, so its instructions steer agents to answer directly rather than delegate exploration to file-reading sub-agents — otherwise a sub-agent reads files regardless and CodeGraph becomes overhead.
</details>
Built for speed — the Rust kernel
CodeGraph's parsing engine is a native Rust kernel: 20 languages — TypeScript, JavaScript, Java, Python, Go, C, C++, Rust, C#, Ruby, PHP, Swift, Kotlin, Scala, Dart, R, Lua, Luau (Metal and CUDA ride the C++ path) — parse in compiled code with one boundary crossing per file. Every language shipped only after its graphs proved byte-for-byte identical to the reference engine on real repositories, from small libraries up to the Linux kernel; platforms without a prebuilt binary and files with syntax errors fall back per-file automatically, same graph either way.
And it scales itself to the machine it's on. Worker pools, parallel resolution, and analysis caches are sized from what the system actually has — real core counts (container/cgroup-aware, so a VPS that grants 2 cores gets sized for 2, not the host's 64), honestly-measured available RAM on macOS and Linux, and the measured cost of your project's resolution work:
On a workstation: the full parallel pipeline — native parse workers, a multi-worker resolver pool that engages the moment it pays for itself, memory-gated analysis caches. The Swift compiler repository (27k files of Swift and C++) fresh-indexes in about 100 seconds; a one-file edit re-syncs in ~4.
On a 2-core / 6GB VPS: the same graph, from a pipeline tuned to finish — the Linux kernel (70k files, 2M symbols, 6.4M relationships) indexes to completion in under 12 minutes where RAM-first designs run out of memory before reaching 1%.
Every day after day one: saving a file updates the graph in well under a second — the watcher fires 300ms after a lone save and syncs exactly what changed (~0.3s of work on a 4,400-file project, ~0.4s on the 27,000-file Swift compiler repo), never re-scanning the tree. Measured against the fastest competing indexer's re-index-on-change: 2–7× faster on medium and larger repos across a 31-repo, 30-language benchmark — and the gap widens with repo size, because their cost grows with the repository and ours grows with the change.
Key Features
| Native Rust Kernel | Parsing and extraction run in a compiled Rust engine for 20 languages — with graphs verified byte-for-byte identical to the reference engine, and automatic per-file fallback so nothing ever breaks |
| Adapts to Your Machine | Sizes its worker pools and caches from what the system actually has — real core counts (container-aware), honest available RAM, measured per-project cost. A workstation gets the full parallel pipeline; a 2-core VPS gets one tuned to finish reliably |
| Surgical Context | One tool call returns entry points, related symbols, and code snippets — no slow file-by-file exploration |
| Full-Text Search | Find code by name instantly across your entire codebase, powered by FTS5 |
| Impact Analysis | Trace callers, callees, and the full impact radius of any symbol before making changes |
| Always Fresh | File watcher uses native OS events (FSEvents/inotify/ReadDirectoryChangesW) with debounced auto-sync — the graph stays current as you code, zero config |
| 20+ Languages | TypeScript, JavaScript, ArkTS, Python, Go, Rust, Java, C#, VB.NET, PHP, Ruby, C, C++, CUDA, Objective-C, Metal, Swift, Kotlin, Scala, Dart, Lua, Luau, R, Nix, Erlang, CFML, COBOL, Solidity, Terraform/OpenTofu, Svelte, Vue, Astro, Liquid, Pascal/Delphi |
| Framework-aware Routes | Recognizes web-framework routing files and links URL patterns to their handlers across 17 frameworks |
| Mixed iOS / React Native / Expo | Closes cross-language flows that static parsing misses: Swift ↔ ObjC bridging, React Native legacy bridge + TurboModules + Fabric view components, native → JS event emitters, Expo Modules |
| Tauri | Follows a desktop app across its web frontend and Rust core: invoke('save_file'), tauri-specta's typed commands.saveFile(), your own wrappers around invoke, and events in both directions |
| 100% Local | No data leaves your machine. No API keys. No external services. SQLite database only |
<details> <summary><strong>How auto-syncing works — and why you don't need to run <code>codegraph sync</code> manually</strong></summary>
When your agent (Claude Code, Cursor, Codex, opencode) launches codegraph serve --mcp, three layers keep the index in step with your code — and make sure the agent never gets a silent wrong answer in the brief window between an edit and the next sync:
File watcher with debounced auto-sync. A native FSEvents / inotify / ReadDirectoryChangesW watcher captures every source-file create / modify / delete and triggers a re-index after a debounce window (default
2000ms, tunable viaCODEGRAPH_WATCH_DEBOUNCE_MS, clamped to[100ms, 60s]). Bursts of edits collapse into a single sync. On a large TypeScript or Vue repo nearly every edit also asks for a repo-wide rebuild of the synthesized callback and event edges;CODEGRAPH_SYNTH_MIN_INTERVAL_MS(1s to 24h) bounds how often that runs, and a rebuild a sync puts off runs when the interval is up. Until then those edges can be that far behind the code, and tool output doesn't say so.Per-file staleness banner. During the brief debounce window, MCP tool responses that would reference a still-pending file prepend a
⚠️banner naming it and telling the agent toReadit directly. Pending files NOT referenced by the response surface as a small footer instead. Either way, the agent gets an explicit signal — validated with Claude Code, where the agent literally says "Reading the file directly for the live content" before opening it.Connect-time catch-up. When the MCP server (re)connects, codegraph runs a fast
(size, mtime)+ content-hash reconciliation against the working tree before answering the first query — so edits made while no MCP server was running (agit pullfrom the terminal, edits from another editor, a previous agent session that exited) get absorbed on the next session's first tool call.
agent writes src/Widget.ts
→ watcher fires (<100ms)
→ debounce (default 2s)
→ sync; Widget.ts is in the index
→ next agent query sees itVerify any time with codegraph status (CLI). If anything is pending, you'll see a ### Pending sync: section naming the files and their edit age.
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.
→ Full deep-dive in Guides → Indexing a Project.
</details>
Framework-aware Routes
CodeGraph detects web-framework routing files and emits route nodes linked by references edges to their handler classes or functions. Querying callers of a view/controller now surfaces the URL pattern that binds it.
| Framework | Shapes recognized |
|---|---|
| Django | path(), re_path(), url(), include() in urls.py (CBV .as_view(), dotted paths) |
| Flask | @app.route('/path', methods=[...]), blueprint routes |
| FastAPI | @app.get(...), @router.post(...), all standard methods |
| Express | app.get(...), router.post(...) with middleware chains |
| NestJS | @Controller + @Get/@Post/... (with RouterModule prefixes, setGlobalPrefix and URI versioning), GraphQL @Resolver + @Query/@Mutation, @MessagePattern/@EventPattern, @SubscribeMessage |
| Laravel | Route::get(), Route::resource(), Controller@action, tuple syntax |
| Drupal | *.routing.yml routes (_controller, _form, entity handlers); hook_* implementations in .module/.theme/.install/.inc and #[Hook] methods; *.services.yml services, and calls through \Drupal::service(); plugin definitions, as attributes or annotations |
| CodeIgniter 3 | Every public controller method by convention, $route[...] in routes.php, HMVC modules; $this->load models, libraries and views |
| Rails | get '/x', to: 'users#index', hash-rocket => syntax |
| Spring | @GetMapping, @PostMapping, @RequestMapping on methods |
| Play | GET/POST/… verb routes in conf/routes → Controller.method actions (Scala + Java) |
| Gin / chi / gorilla / mux | r.GET(...), router.HandleFunc(...) |
| Axum / actix / Rocket | .route("/x", get(handler)) |
| ASP.NET | [HttpGet("/x")] attributes on action methods |
| Vapor | app.get("x", use: handler) |
| Astro | src/pages/ file-based routes (.astro pages + .ts endpoints, [param]/[...rest] syntax) |
Routers — routes and the navigation between them
These frameworks additionally emit navigates edges: the function that sends a user somewhere is linked to the screen it names, so "where does tapping this go" is one hop in the graph rather than a search. Each reads a literal destination — a computed one, or a path no route serves, is left unresolved rather than guessed — and a link written in markup is marked as inferred.
| Router | Routes from | Navigation from |
|---|---|---|
| Expo Router | Every screen file under app/ (app/item/[id].tsx → /item/[id], groups stripped), bound to its default-export component; +api files are endpoints (GET /hello) bound to their handlers | router.push / replace / navigate, template hrefs, { pathname } objects, and a helper's returned href |
| Next.js | App Router app/**/page.tsx and Pages Router pages ((group) stripped, [slug] → :slug); app/api/**/route.ts exports and pages/api/* are endpoints, not screens | router.push / replace / prefetch, redirect() / permanentRedirect() in a server action or page, NextResponse.redirect(new URL(…)) in middleware, <Link href> and internal <a href> |
| React Router | <Route path component/element> (v5 and v6) and createBrowserRouter([{ path, element }]) | history.push / replace, useNavigate's navigate, a loader's redirect, <Link to> / <NavLink to> / <Navigate to> / v5's <Redirect to> / react-router-bootstrap's <LinkContainer to>, and a styled(Link) wrapper |
| TanStack Router | createFileRoute('/posts/$postId') (file-based) and createRoute({ path, getParentRoute }) composed up its parent chain (code-based); _pathless segments, (group) folders, __root and <Outlet/> layouts are not addresses | navigate({ to }), a thrown redirect({ to }), <Link to> / <Navigate to> — where to is the route PATTERN and the values ride beside it in params |
| Vue Router / Nuxt | createRouter({ routes: [...] }) / new Router(...) and the route tables it's given (export const constantRoutes = [...], per-module route files), with the view each entry names — a lazy () => import(…) bound to its file — and children joined onto their parent's path, the parent being the layout around them; plus Nuxt pages/ file-based routes, server/api/ endpoints and route middleware | router.push / replace, this.$router.push, Nuxt's navigateTo, <router-link> / <RouterLink> / <NuxtLink> — by route name (push({ name: 'profile' })) as well as by path |
| SvelteKit | src/routes/**/+page.svelte ([slug] → :slug, [[opt]] → :opt?, [id=matcher] → :id, (group) folders stripped), joined to the +page.server.js beside it so a loader's guard belongs to its page | goto('/x'), redirect(status, '/x') from a load or form action, and the plain <a href> that is a link in a SvelteKit app |
| Angular | Routes arrays (RouterModule.forRoot / forChild, provideRouter, a routes file's default export) with component or a lazy loadComponent; children and lazy loadChildren (an NgModule's through its routing module) joined into full paths; paths written as route constants or $localize strings; a route with children is a layout around the screens inside it | router.navigate([...]), navigateByUrl, a guard's createUrlTree / parseUrl — a command array, a route constant, or a component property holding one — routerLink / [routerLink] in the component's template, and redirectTo. Each template's child components (<app-foo>) are linked to the component that renders them |
In a repository holding several apps, each app's routes are matched only against navigation written inside that app.
Mixed iOS / React Native / Expo bridging
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.
| Boundary | JS / Swift side | Native side | How |
|---|---|---|---|
| Swift → ObjC | Swift obj.foo(bar:) | ObjC selector -fooWithBar: | @objc auto-bridging rules (including init/property/protocol forms) + Cocoa preposition prefixes (With/For/By/In/On/At/…) |
| ObjC → Swift | ObjC [obj fooWithBar:] | Swift @objc func foo(bar:) | Reverse-bridge name candidates; verifies @objc exposure from source |
| React Native legacy bridge | JS NativeModules.X.fn(...) | ObjC RCT_EXPORT_METHOD / RCT_REMAP_METHOD · Java/Kotlin @ReactMethod | Parses macro/annotation declarations to build a JS-name → native-method map |
| React Native TurboModules | JS import M from './NativeM'; M.fn(...) | Native impl matching the Codegen spec | Treats the Native<X>.ts spec interface as ground truth |
| RN native → JS events | JS new NativeEventEmitter(...).addListener('e', cb) | ObjC [self sendEventWithName:@"e" body:...] · Swift sendEvent(withName: "e", ...) · Java/Kotlin .emit("e", ...) | Synthesized cross-language event channel keyed by literal event name |
| Expo Modules | JS requireNativeModule('X').fn(...), directly or through a binding (export default requireNativeModule<T>('X')) | Swift / Kotlin Module { Name("X"); AsyncFunction("fn") { ... } } | Parses the Expo DSL literals into method nodes; a call on a binding resolves to module X's fn on both platforms, else to the method on the binding's declared type |
| Fabric view components | JSX <MyView prop={v}/> | TS Codegen spec + native impl class | Spec → component node; convention-based name+suffix lookup (View/ComponentView/Manager/ViewManager) bridges to native |
| Legacy Paper view managers | JSX <MyView prop={v}/>, through a requireNativeComponent('X') module | ObjC RCT_EXPORT_VIEW_PROPERTY · Java/Kotlin @ReactProp | Same as Fabric — requireNativeComponent('X') is a JS component node, and Paper-era declarations also produce component + property nodes |
Validated on real codebases (small + medium + large for each bridge):
| Bridge | Small | Medium | Large |
|---|---|---|---|
| Swift ↔ ObjC | Charts | realm-swift | Wikipedia-iOS |
| RN legacy bridge | AsyncStorage | react-native-svg | react-native-firebase |
| RN native → JS events | RNGeolocation | — | react-native-firebase |
| Expo Modules | expo-haptics | expo-camera | expo SDK sweep (7 packages) |
| Fabric / Paper views | react-native-segmented-control | react-native-screens | react-native-skia |
Every bridge hop says how it got into the graph. A hop matched by a bridge resolver carries metadata.resolvedBy: 'framework' and metadata.framework naming the resolver (swift-objc-bridge, react-native-bridge, expo-modules-js, fabric-view). A synthesized channel is tagged provenance:'heuristic' with metadata.synthesizedBy (rn-event-channel, fabric-native-impl).
Quick Start
1. Run the Installer
npx @colbymchenry/codegraphThe installer will:
Ask which agent(s) to configure — auto-detects installed ones from: Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, GitHub Copilot (VS Code, Copilot CLI, JetBrains IDEs), IBM Bob, Factory Droid, Windsurf, Qwen Code, DeepSeek Harness, Grok Build, Kimi Code, Qoder CLI, and Pi
Prompt to install
codegraphon your PATH (so agents can launch the MCP server)Ask whether configs apply to all your projects or just this one
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/QWEN.md) — that's how subagents and non-MCP agents learn thecodegraph explorecommand, since the MCP server's own guidance only reaches the main agent. Removed cleanly bycodegraph uninstall.Set up auto-allow permissions when Claude Code or Qwen Code is one of the targets
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.
Non-interactive (scripting / CI):
codegraph install --yes # auto-detect agents, install global
codegraph install --yes --init # same, then build the current project's index (one-shot bootstrap)
codegraph install --target=cursor,claude --yes # explicit target list
codegraph install --target=auto --location=local # detected agents, project-local
codegraph install --target=copilot-vscode,copilot-cli,copilot-jetbrains --yes # GitHub Copilot everywhere
codegraph install --print-config codex # print snippet, no file writes
codegraph install --print-config copilot-vscode # same, for Copilot in VS Code| Flag | Values | Default |
|---|---|---|
--target | auto, all, none, or csv (claude,cursor,...) | prompt |
--location | global, local | prompt |
--yes | (boolean) | prompt every step |
--init | (boolean) run codegraph init in the current directory after wiring agents | — |
--no-permissions | (boolean) skip the auto-allow list (Claude Code, Qwen Code) | permissions on |
--print-config <id> | dump snippet for one agent and exit | — |
2. Restart Your Agent
Restart your agent (Claude Code / Cursor / Codex CLI / opencode / Hermes Agent / Gemini CLI / Antigravity IDE / Kiro / VS Code, the Copilot CLI, or your JetBrains IDE for GitHub Copilot / IBM Bob / Factory Droid / Windsurf / Qwen Code / DeepSeek Harness / Grok Build / Kimi Code / Qoder CLI / Pi) for the MCP server to load.
3. Initialize Projects
cd your-project
codegraph initBuilds 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. Add --yes to skip every prompt (scripts / CI / container bootstraps).
That's it — your agent will use CodeGraph tools automatically when a .codegraph/ directory exists.
<details> <summary><strong>Manual Setup (Alternative)</strong></summary>
Install globally:
npm install -g @colbymchenry/codegraphAdd to ~/.claude.json:
{
"mcpServers": {
"codegraph": {
"type": "stdio",
"command": "codegraph",
"args": ["serve", "--mcp"],
"alwaysLoad": true
}
}
}alwaysLoad keeps codegraph_explore loaded from the first prompt. Claude Code otherwise defers every MCP tool behind a tool-search step, so a fresh session sees only the tool's name until the model searches for it.
Add to ~/.claude/settings.json (optional, for auto-allow):
{
"permissions": {
"allow": [
"mcp__codegraph__*"
]
}
}<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>
</details>
<details> <summary><strong>Agent Tool Guidance</strong></summary>
CodeGraph's MCP server delivers its usage guidance to your agent automatically, in the MCP initialize response. In short, it tells the agent to:
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.
Reach for
codegraph_explorefor 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.Trust the results — don't re-verify with grep, and check the staleness banner after edits.
Works per project: query any project that has a
.codegraph/index by passingprojectPath— 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.
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.
</details>
How It Works
┌───────────────────────────────────────────────────────────────────┐
│ Claude Code │
│ │
│ "How does a request reach the database?" │
│ calls CodeGraph tools directly — no Explore sub-agent │
│ │ │
└─────────────────────────────────┬─────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────┐
│ CodeGraph MCP Server │
│ │
│ explore · one call → verbatim source + call flow + blast radius │
│ │ │
│ ▼ │
│ SQLite knowledge graph │
│ symbols · edges · files · FTS5 full-text search │
└───────────────────────────────────────────────────────────────────┘Extraction — a native Rust kernel parses source with tree-sitter grammars compiled into it, extracting nodes (functions, classes, methods) and edges (calls, imports, extends, implements) for 20 languages; remaining languages and per-file fallbacks use the same extraction logic on the portable engine, producing identical graphs.
Storage — Everything goes into a local SQLite database (
.codegraph/codegraph.db) with FTS5 full-text search.Resolution — After extraction, references are resolved: function calls → definitions, imports → source files, class inheritance, and framework-specific patterns.
Auto-Sync — The MCP server watches your project using native OS file events. Changes are debounced (2-second quiet window), filtered to source files only, and incrementally synced. The graph stays fresh as you code — no configuration needed.
CLI Reference
codegraph # Run interactive installer
codegraph install # Run installer (explicit)
codegraph uninstall # Remove CodeGraph from your agents AND the CLI (--keep-cli for configs only)
codegraph init [path] # Initialize a project + build its graph (one step; --local-only keeps .codegraph/ out of git)
codegraph uninit [path] # Remove CodeGraph from a project (--force to skip prompt)
codegraph index [path] # Full index (--force to re-index, --quiet for less output)
codegraph sync [path] # Incremental update
codegraph status [path] # Show statistics (--json, --strict)
codegraph unlock [path] # Remove a stale lock file that's blocking indexing
codegraph query <search> # Search symbols (--kind, --limit, --json)
codegraph explore <query> # Relevant symbols' source + call paths in one shot (same output as the codegraph_explore MCP tool)
codegraph node <symbol|file> # One symbol's source + callers, or read a file with line numbers (same output as codegraph_node)
codegraph files [path] # Show file structure (--format, --filter, --max-depth, --tests, --json)
codegraph callers <symbol> # Find what calls a function/method (--limit, --json)
codegraph callees <symbol> # Find what a function/method calls (--limit, --json)
codegraph impact <symbol> # Analyze what code is affected by changing a symbol (--depth, --json)
codegraph implementations <symbol> # List the types that implement or extend a type (--depth, --json)
codegraph affected [files...] # Find test files affected by changes (see below)
codegraph cycles [path] # List circular imports between files (--json); exits 1 when there are any
codegraph daemon # Manage background daemons — pick one to stop (alias: daemons)
codegraph telemetry [on|off] # Show or change anonymous usage telemetry
codegraph upgrade [version] # Update to the latest release (--check, --force)
codegraph version # Print the installed version (also -v, --version)
codegraph help [command] # Show help, optionally for one commandcodegraph affected
Traces import dependencies transitively to find which test files are affected by changed source files.
codegraph affected src/utils.ts src/api.ts # Pass files as arguments
git diff --name-only | codegraph affected --stdin # Pipe from git diff
codegraph affected src/auth.ts --filter "e2e/*" # Custom test file pattern| Option | Description | Default |
|---|---|---|
--stdin | Read file list from stdin | false |
-d, --depth <n> | Max dependency traversal depth | 5 |
-f, --filter <glob> | Custom glob to identify test files | auto-detect |
-j, --json | Output as JSON | false |
-q, --quiet | Output file paths only | false |
CI/hook example:
#!/usr/bin/env bash
AFFECTED=$(git diff --name-only HEAD | codegraph affected --stdin --quiet)
if [ -n "$AFFECTED" ]; then
npx vitest run $AFFECTED
fiMCP Tools
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:
| Tool | Purpose |
|---|---|
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. |
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).
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.
Library Usage
CodeGraph can be embedded directly. The npm package re-exports its programmatic
API, so both import and require resolve the CodeGraph class in your own
process — handy for embedding it in an app (e.g. an Electron main process).
import CodeGraph from '@colbymchenry/codegraph';
// CommonJS works too:
// const { CodeGraph } = require('@colbymchenry/codegraph');
const cg = await CodeGraph.init('/path/to/project');
// Or: const cg = await CodeGraph.open('/path/to/project');
await cg.indexAll({
onProgress: (p) => console.log(`${p.phase}: ${p.current}/${p.total}`)
});
const results = cg.searchNodes('UserService');
const callers = cg.getCallers(results[0].node.id);
const context = await cg.buildContext('fix login bug', { maxNodes: 20, includeCode: true, format: 'markdown' });
const impact = cg.getImpactRadius(results[0].node.id, 2);
cg.watch(); // auto-sync on file changes
cg.unwatch(); // stop watching
cg.close();Lower-level building blocks are exported from the same entry point for callers
that drive the graph directly: DatabaseConnection, QueryBuilder,
getDatabasePath, initGrammars / loadGrammarsForLanguages, and FileLock.
Embedding requirements
Install from npm (
npm i @colbymchenry/codegraph) so the matching per-platform package — which carries the compiled library and its dependencies — is fetched alongside the shim.The API runs on your runtime, so it needs Node 22.5+ for the built-in
node:sqlite(Electron qualifies when its bundled Node is 22.5+). The CLI and MCP server are unaffected — they run on the self-contained bundled runtime.TypeScript types ship with the package. As with any Node-targeting library, keep
@types/nodeavailable andskipLibCheck: true(the common default).
Configuration
Next to none — CodeGraph is zero-config by default, with nothing to write or keep in sync to get started. Language support is automatic from the file extension; there's nothing to wire up per language. The one optional file is for mapping custom file extensions.
What it skips out of the box:
Dependency, build, and cache directories —
node_modules,vendor,dist,build,target,.venv,Pods,.next, and the like across every supported stack — so the graph is your code, not third-party noise. This holds even with no.gitignore. Abuildfolder insidesrc/is the exception: no build step writes TypeScript, JSX, Vue, Svelte, Astro, Go, C# or Rust files into one, so those are indexed from it, and a Java, Kotlin or Scala package namedbuildis indexed whole.Anything in your
.gitignore— honored in git repos via git, and in non-git projects by reading.gitignoredirectly (root and nested).Files larger than 1 MB — generated bundles, minified JS, vendored blobs.
To keep something else out, add it to .gitignore. To pull a default-excluded
directory back in (say you really do want a vendored dependency indexed),
add a negation — !vendor/. The defaults apply uniformly, so committing a
dependency or build directory doesn't force it into the graph; the .gitignore
negation is the explicit opt-in.
.gitignore can't drop a directory you've committed, though. For a vendored
theme or SDK that's checked into the repo (e.g. a Metronic theme under
static/), list it under exclude in codegraph.json — gitignore-style
patterns, matched against repo-root-relative paths, honored on index, sync, and
watch:
{
"exclude": ["static/", "**/vendor/**"]
}Conversely, when real source is gitignored on purpose — a project under a second
VCS (SVN, Perforce) that .gitignores its own source so it stays out of Git —
force it back in with include (the opposite of exclude; includeIgnored
only revives embedded git repos, not plain source):
{
"include": ["Tools/", "Local/typescript/"]
}CodeGraph discovers those files off disk, overriding .gitignore, on index,
sync, and watch. An explicit exclude still wins, and built-in skips
(node_modules, dist, .git) are never re-included.
Sometimes a directory shouldn't leave the index — you still want to find things
in it — it just shouldn't outrank your real code. A scripts/ or
optional-skills/ tree whose helpers use generic names (usage, status,
run) can win on an exact name match and crowd out the product code that
actually answers the query. Name those trees under deprioritize:
{
"deprioritize": ["optional-skills/", "scripts/"]
}This is the ranking counterpart to exclude: those paths stay indexed and
findable — searching for them directly still works — they just stop winning
against first-party code. It applies to query / search and to explore's
ranking. It is not a filter: unlike the built-in example/, sample/,
fixture/, benchmark/ and demo/ handling — which also drops those files
from some result sets outright — deprioritize only ever changes rank. Reach
for exclude when you want something gone.
Custom file extensions
If your project uses a non-standard extension for a supported
language — say .dota_lua for Lua, or .tpl for PHP —
those files are skipped by default, because the extension isn't one CodeGraph
recognizes. Map them with an optional codegraph.json at your project root:
{
"extensions": {
".dota_lua": "lua",
".tpl": "php"
}
}Each value is a supported language id. The mappings merge on top of the built-in
defaults and win on conflict, so you can also re-point a built-in (e.g.
".h": "cpp"). Commit the file to share the mapping with your team. A typo'd
language or a malformed file is warned about and skipped — it never breaks
indexing — and a project with no codegraph.json behaves exactly as before.
Re-index (codegraph index) after adding or changing mappings.
Telemetry
CodeGraph collects anonymous usage statistics — which tools and commands get used, which languages get indexed — to guide where language and agent support work goes. Never any code, paths, file or symbol names, queries, or IP addresses; usage is aggregated locally into daily totals before anything is sent, and the ingest endpoint is public code in this repo that enforces the documented field list. The installer asks up front; turn it off any time:
codegraph telemetry off # or: CODEGRAPH_TELEMETRY=0, or DO_NOT_TRACK=1TELEMETRY.md lists every field, with the off-switches and the
full data-handling story.
Verified releases
Every artifact is built and published by the public Release workflow — never from a laptop — and carries cryptographic proof of it:
npm packages are published via trusted publishing (OIDC — no long-lived npm tokens exist that could be stolen) with provenance attestations linking every version to the exact commit and workflow run that built it. Verify what's installed:
npm audit signaturesGitHub Release bundles (and
SHA256SUMS) carry signed build attestations (SLSA v1.0 Build Level 2). Verify any downloaded bundle:gh attestation verify codegraph-darwin-arm64.tar.gz -R colbymchenry/codegraph
Releases published before July 2026 predate this pipeline and don't carry attestations.
Supported Platforms
Every release ships a self-contained build (bundled Node runtime — nothing to compile) for all three desktop OSes, on both Intel/AMD (x64) and ARM (arm64):
| Platform | Architectures | Install |
|---|---|---|
| Windows | x64, arm64 | PowerShell installer or npm |
| macOS | x64, arm64 | shell installer or npm |
| Linux | x64, arm64 | shell installer or npm |
See Get Started for the one-line install commands.
Supported Agents
The interactive installer auto-detects and configures each of these — wiring up
the MCP server, which delivers its own usage guidance. For Claude Code, Codex
CLI, Gemini CLI, opencode, Factory Droid, Qwen Code, DeepSeek Harness, Grok
Build, Kimi Code and Pi it also writes a short marker-fenced CodeGraph section
into the agent's instructions file (CLAUDE.md / AGENTS.md / GEMINI.md /
QWEN.md, or rules/codegraph.md for Grok Build), so subagents and non-MCP
agents learn the codegraph explore command:
Claude Code
Cursor
Codex CLI — the Codex IDE extension reads the same config: a global install writes
$CODEX_HOME/config.toml(default~/.codex/config.toml), and a local install writes.codex/config.toml, which Codex uses only in a project you've marked as trustedopencode — MCP entry is OpenCode 2's
mcp.servers.codegraphwithcodemode: false(keepscodegraph_exploreon the native tool list;codegraph installmigrates the oldermcp.codegraphshape)Hermes Agent
Gemini CLI
Antigravity IDE
Kiro
GitHub Copilot — Copilot Chat in VS Code (
copilot-vscode), the Copilot CLI (copilot-cli), and the Copilot plugin in JetBrains IDEs (copilot-jetbrains)IBM Bob (
bob) — Bob IDE and Bob Shell:~/.bob/settings/mcp.json, or.bob/mcp.jsonin a projectFactory Droid (
droid) —~/.factory/mcp.json, or.factory/mcp.json, which is meant to be committed; Droid reloads the file on its ownWindsurf (
windsurf) — global only:~/.codeium/windsurf/mcp_config.json, which Devin, Windsurf's new name, imports by defaultQwen Code (
qwen) —settings.jsonin$QWEN_HOME(default~/.qwen) or.qwen/, keeping any comments in itDeepSeek Harness (
dsh) — global only: one entry in$DSH_HOME/cordis.patch.yml(default~/.dsh) covers every profileGrok Build (
grok) —$GROK_HOME/config.toml(default~/.grok), or.grok/config.toml, which Grok uses only in a trusted folderKimi Code (
kimi) —$KIMI_CODE_HOME/mcp.json(default~/.kimi-code), or.kimi-code/mcp.json, which Kimi Code uses only in a trusted folderQoder CLI (
qoder) —$QODER_CONFIG_DIR/settings.json(default~/.qoder), or.qoder/settings.local.json; in the Qoder IDE, add the server under Settings > MCPPi (
pi) —mcp.jsonin Pi's agent directory (default~/.pi/agent), or.pi/mcp.json, which Pi reads once you trust the project;exposure: "direct"keepscodegraph_exploreon the model's tool list
Supported Languages
| Language | Extension | Status |
|---|---|---|
| TypeScript | .ts, .tsx | Full support |
| JavaScript | .js, .jsx, .mjs | Full support |
| ArkTS (HarmonyOS) | .ets | Full support (everything TypeScript has, plus @Component/@ComponentV2 structs with their ArkUI decorators (@State/@Prop/@Link/@Local/@Builder/…), build() view trees — parent→child component edges, chained-attribute links to @Extend/@Styles functions, .onClick(this.handler) event bindings — dynamic-dispatch bridges for state→build() re-renders, @ohos.events.emitter emit→subscriber pairs (static event keys only), and router.pushUrl literal urls → the target page struct; ohpm workspace modules resolve bare import { X } from "data" through oh-package.json5 file: dependencies, honoring each module's main entry) |
| Python | .py | Full support |
| Go | .go | Full support |
| Rust | .rs | Full support |
| Java | .java | Full support |
| C# | .cs | Full support |
| PHP | .php | Full support |
| Ruby | .rb | Full support |
| C | .c, .h | Full support |
| C++ | .cpp, .hpp, .cc | Full support |
| Objective-C | .m, .mm, .h | Partial support (classes, protocols, methods, @property, #import, message sends; .mm ObjC++ may parse incompletely) |
| Metal | .metal | Full support (vertex/fragment/kernel functions, structs, type aliases, call edges — MSL parses as C++, with [[attribute]] annotations handled) |
| CUDA | .cu, .cuh | Full support (kernels and device/host functions, structs, classes, host→kernel call edges through <<<grid, block>>> launch syntax — templated launches, function-pointer launches (auto kernel = &fn<...>), dim3{...} configs, and macro-defined kernels included; __global__/__device__/__launch_bounds__ specifiers handled; CUDA in plain .h/.hpp headers recognized by content) |
| Swift | .swift | Full support |
| Kotlin | .kt, .kts | Full support |
| Scala | .scala, .sc | Full support (classes, traits, methods, type aliases, Scala 3 enums) |
| Dart | .dart | Full support |
| Svelte | .svelte | Full support (script extraction, Svelte 5 runes, SvelteKit routes) |
| Vue | .vue | Full support (script + script-setup extraction, Nuxt page/API/middleware routes) |
| Astro | .astro | Full support (frontmatter + script extraction, template component/call references, src/pages/ routes) |
| Liquid | .liquid | Full support |
| Pascal / Delphi | .pas, .dpr, .dpk, .lpr | Full support (classes, records, interfaces, enums, DFM/FMX form files) |
| Lua | .lua | Full support (functions, methods with receivers, local variables, require imports, call edges) |
| R | .R .r | Full support (functions in every assignment form, S4/R5/R6 classes with methods, library/require imports, source() file references, call edges) |
| Luau | .luau | Full support (everything in Lua, plus type/export type aliases, typed signatures, and Roblox instance-path require) |
| CFML | .cfc, .cfm, .cfs | Full support (tag-based <cfcomponent>/<cffunction> and bare-script component { ... } styles, extends/implements, embedded <cfscript> delegation, call edges) |
| COBOL | .cbl, .cob, .cpy | Full support (programs, sections/paragraphs with PERFORM/GO TO call edges, CALL 'literal' cross-program calls, COPY copybook imports — including standalone .cpy files — DATA DIVISION records/fields/88-levels, EXEC CICS LINK/XCTL and EXEC SQL INCLUDE targets; fixed and free format) |
| Visual Basic .NET | .vb | Full support (classes, Modules, interfaces, structures, enums, properties, events, Declare P/Invoke, Handles/WithEvents, Inherits/Implements edges, call edges through VB's call/index paren ambiguity, As New instantiation, interpolated strings, LINQ, Unicode identifiers) |
| Erlang | .erl, .hrl, .escript, .app.src, .app | Full support (functions with multi-clause/multi-arity grouping, -spec signatures, records with fields, -type/-opaque aliases, -define macros, -include/-include_lib/-import edges, local and mod:fn remote call edges, fun name/arity references, spawn/apply/proc_lib/timer/rpc MFA-argument call edges, gen_server:call/cast(?MODULE) → own handle_call/handle_cast links, -behaviour links, -export-based visibility) |
| Solidity | .sol | Full support (contracts, libraries, interfaces, structs, enums, modifiers, events, errors, state variables, import/using directives, emit/revert calls) |
| Terraform / OpenTofu | .tf, .tfvars, .tofu | Full support (resources, data sources, modules, variables, outputs, providers incl. aliases, locals; var./local./module./resource references with Terraform's per-directory scoping enforced; module calls bridged across the boundary — inputs to the child module's variables, module.M.out to the child's output, source to the module's files; cloudposse/atmos remote-state cross-component wiring when the component is statically named; provider = aws.east selections resolved up the module tree; moved/import/removed/check block references; .tfvars assignments linked to the variables they set) |
| Nix | .nix | Full support (functions with simple/destructured/curried params, let/attrset bindings, inherit, import ./path file edges — ./dir resolving through default.nix — plus NixOS module imports = [ ./x.nix ] lists and callPackage ./pkg.nix file edges; call edges; module-system option wiring — a config write like launchd.user.agents.x = { ... } links to the module declaring options.launchd.user.agents, so option flows trace across modules) |
Measured cross-file coverage
Impact and blast-radius queries are only as good as the dependency graph behind them, so coverage is measured rather than asserted. Fair coverage = the share of symbol-bearing source files that have at least one resolved cross-file dependent — something that imports, calls, references, or (through a framework convention) routes to them — on a real-world benchmark repo per language. The residual is always a genuine static-analysis frontier (runtime dynamic dispatch, reflection / DI containers, framework-convention entry points, vendored third-party code), never hidden by gaming the denominator.
| Language | Benchmark repo | Coverage |
|---|---|---|
| TypeScript / JavaScript | this repo | 95.8% |
| Python | psf/requests | 100% |
| Go | gin-gonic/gin | 96.6% |
| Rust | BurntSushi/ripgrep | 86.7% |
| Java | google/gson | 93.3% |
| C# | jbogard/MediatR | 85.2% |
| PHP | guzzle/guzzle | 100% |
| Ruby | sidekiq/sidekiq | 100% |
| C | redis/redis | 92.2% |
| C++ | google/leveldb | 94.8% |
| Objective-C | SDWebImage | 91.6% |
| Swift | Alamofire | 95.3% |
| Kotlin | square/okhttp | 96.2% |
| Scala | gatling/gatling | 91.2% |
| Dart | flutter/packages | 92.4% |
| Svelte / SvelteKit | sveltejs/realworld | 100% |
| Vue / Nuxt | nuxt/movies | 93.5% |
| Astro | xingwangzhe/stalux | 93.0% |
| Lua | nvim-telescope/telescope.nvim | 84.2% |
| Luau | dphfox/Fusion | 92.2% |
| Liquid | Shopify/dawn | 73.8% |
| Pascal / Delphi | PascalCoin | 77.4% |
Framework routing is validated the same way, on a canonical app per framework: Express 100%, FastAPI 98%, Flask 100%, NestJS 96.8%, Gin 96.5%, Axum 100%, Rocket 93.8%, Vapor 100%, Laravel 92%, Rails 89.6%, React Router 100% — and the convention/reflection-heavy ones at their honest static-analysis ceiling: ASP.NET 83.9%, Spring 83.3%, Drupal 78.9%, Play 76.3%, Django 74.1%. SvelteKit, Vue/Nuxt, and Astro use file-based routing, so their page/endpoint coverage is the Svelte/SvelteKit (100%), Vue/Nuxt (93.5%), and Astro (93.0% — every src/pages/ file maps to a route node on the two validation repos) figures in the table above.
Troubleshooting
"CodeGraph not initialized" — Run codegraph init in your project directory first.
Indexing is slow — Check that node_modules and other large directories are excluded. Use --quiet to reduce output overhead.
MCP hits database is locked — current builds shouldn't: CodeGraph bundles its own Node runtime and uses Node's built-in node:sqlite in WAL mode, where concurrent reads never block on a writer. If you still see it:
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), ornpm i -g @colbymchenry/codegraph@latest.codegraph statusshowsJournal:other thanwal— 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.
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.
Two codegraph serve --mcp on one project fight over the index / auto-sync stops — CodeGraph allows one live MCP writer per project (the shared background daemon, or a single direct-mode process). Extra clients should proxy to that daemon. If you set CODEGRAPH_NO_DAEMON=1, run only one serve --mcp for that project; a second instance exits with a clear writer-lock error (see writer.pid under .codegraph/). Prefer leaving the daemon enabled so multiple MCP hosts share one watcher.
MCP tool calls fail with Transport closed while codegraph status/sync are healthy — almost always WSL2 with the project on a Windows drive (a /mnt/c or /mnt/d path), where the local socket CodeGraph uses to share one background server across sessions is unreliable. CodeGraph works around this itself now: when the project's filesystem can't host that socket, the shared server puts it in the system temp directory instead, and when the shared server still can't be reached, or drops, the session is served in-process instead of losing the connection. If you still hit it, set CODEGRAPH_NO_DAEMON=1 in your MCP server's environment to skip the shared server entirely (each session runs in its own process). Moving the project onto the Linux-native filesystem (e.g. under ~/ instead of /mnt/) restores the shared server.
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 .gitignored or default-excluded directory (e.g. node_modules, dist).
Sharing one checkout between Windows and WSL — Don't point both at the same .codegraph/: the background-server lock and the SQLite index are tied to the OS that wrote them, and SQLite locking across the WSL2/Windows filesystem boundary is unreliable (WSL reports it as a disk I/O error). For a project on a Windows drive (a /mnt/c/… path), WSL keeps its own index automatically: an index first built from WSL goes in .codegraph-wsl/, leaving .codegraph/ to Windows. An index already in .codegraph/ stays where it is, so if Windows built that one, give WSL its own by setting CODEGRAPH_DIR=.codegraph-wsl in WSL and running codegraph init there. CODEGRAPH_DIR always picks the name when set, on either side. CodeGraph skips any sibling .codegraph-* directory when indexing and watching, so the two never trip over each other.
Very large repositories (hundreds of thousands of files), or a large .codegraph/codegraph.db-wal file — The -wal file is SQLite's write-ahead log: writes waiting to be folded into codegraph.db. While a big index is being built, CodeGraph lets it grow in proportion to the index (soft threshold = the larger of 256 MB and a quarter of the index size, up to 2 GB) before folding it back, because folding too often is what made large indexes slow on ordinary disks. At rest it is trimmed to 64 MB, and a leftover from a killed session is folded and trimmed the next time the project opens — the index itself has no size limit. Two environment variables tune this: CODEGRAPH_WAL_VALVE_MB (the soft threshold during indexing) and CODEGRAPH_WAL_HEAL_MB (the resting size and the trim threshold). CODEGRAPH_WAL_VALVE_DEBUG=1 prints every decision to stderr.
Contributing
See CONTRIBUTING.md to build from source, test a change and prepare a pull request. The documentation index links to the project's guides and design notes.
License
MIT
<div align="center">
Made for AI coding agents — Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, GitHub Copilot, IBM Bob, Factory Droid, Windsurf, Qwen Code, DeepSeek Harness, Grok Build, Kimi Code, Qoder CLI, and Pi
</div>
docs/SEARCH_QUALITY_LOOP.md
CodeGraph Language Verification Guide
You are verifying that CodeGraph fully supports a specific programming language. The user will give you a path to a real-world, popular open-source codebase cloned locally. Your job is to run a battery of realistic prompts against it using CodeGraph's API and verify the results are good enough to say that language is covered and supported.
A language is NOT verified until an LLM can reliably use CodeGraph's MCP tools to navigate that codebase — finding the right symbols, understanding call chains, exploring subsystems, and getting useful context for real tasks.
Setup
1. Build and index
npm run build
rm -rf <codebase_path>/.codegraph
node dist/bin/codegraph.js init -v <codebase_path>init builds the index; the -v flag gives verbose output showing extraction progress, node/edge counts, and timing.
2. Quick sanity check
# Verify nodes were extracted with proper qualified names
sqlite3 <codebase_path>/.codegraph/codegraph.db \
"SELECT name, kind, qualified_name FROM nodes WHERE kind = 'method' LIMIT 10;"
# GOOD: file.go::StructName::method_name (owner type present)
# BAD: file.go::file.go::method_name (owner type missing — needs getReceiverType)
# Check edge counts
sqlite3 <codebase_path>/.codegraph/codegraph.db \
"SELECT kind, COUNT(*) FROM edges GROUP BY kind ORDER BY COUNT(*) DESC;"
# Check node kind distribution
sqlite3 <codebase_path>/.codegraph/codegraph.db \
"SELECT kind, COUNT(*) FROM nodes GROUP BY kind ORDER BY COUNT(*) DESC;"If methods are missing their owner type in qualified_name, fix that first (see Adding getReceiverType) before proceeding with the full test battery.
The Test Battery
Run all of the following test categories against the codebase. Use the Node.js API directly — the test scripts below are templates. Adapt the queries to match real types, methods, and subsystems in the codebase you're testing.
Pass criteria for each test: Does the result give an LLM enough correct information to answer the question or complete the task? Would you trust these results if you were the LLM?
Test 1: codegraph_explore — Deep Exploration (MOST IMPORTANT)
This is the primary tool LLMs use. It must return relevant source code grouped by file, with correct relationships, for a natural language query. Test it with at least 5 different query types:
node -e "
const { CodeGraph } = require('./dist/index.js');
async function test() {
const cg = await CodeGraph.open('<codebase_path>');
const queries = [
// A. Subsystem exploration — broad topic, should find the right files and key classes
'How does the caching system work?',
// B. Specific class/type deep dive — should return that class, its methods, and related types
'CacheBuilder configuration and build process',
// C. Cross-cutting concern — should find implementations across multiple files
'How are errors handled and propagated?',
// D. Data flow question — should trace through multiple layers
'How does data flow from input to storage?',
// E. Implementation detail — specific method behavior
'How does eviction decide which entries to remove?',
];
for (const query of queries) {
console.log(\`\n========================================\`);
console.log(\`QUERY: \${query}\`);
console.log(\`========================================\`);
const subgraph = await cg.findRelevantContext(query, {
searchLimit: 8, traversalDepth: 3, maxNodes: 80, minScore: 0.2,
});
// Show entry points — these are what the LLM sees first
console.log(\`\nEntry points (\${subgraph.roots.length}):\`);
for (const rootId of subgraph.roots.slice(0, 8)) {
const node = subgraph.nodes.get(rootId);
if (node) console.log(\` \${node.name} (\${node.kind}) — \${node.filePath}:\${node.startLine}\`);
}
// Show file distribution — are the right files surfacing?
const fileGroups = new Map();
for (const node of subgraph.nodes.values()) {
if (!fileGroups.has(node.filePath)) fileGroups.set(node.filePath, []);
fileGroups.get(node.filePath).push(node.name);
}
console.log(\`\nFiles (\${fileGroups.size}):\`);
for (const [file, nodes] of [...fileGroups.entries()].sort((a,b) => b[1].length - a[1].length).slice(0, 8)) {
console.log(\` \${file} (\${nodes.length} symbols): \${nodes.slice(0, 6).join(', ')}\`);
}
// Show edge distribution — are relationships being captured?
const edgeKinds = new Map();
for (const edge of subgraph.edges) {
edgeKinds.set(edge.kind, (edgeKinds.get(edge.kind) || 0) + 1);
}
console.log(\`\nEdges (\${subgraph.edges.length}):\`);
for (const [kind, count] of [...edgeKinds.entries()].sort((a,b) => b - a)) {
console.log(\` \${kind}: \${count}\`);
}
console.log(\`\nTotal: \${subgraph.nodes.size} nodes, \${subgraph.edges.length} edges, \${fileGroups.size} files\`);
}
await cg.close();
}
test().catch(console.error);
"What to check for each query:
Do the entry points make sense for the question?
Are the right files surfacing (not just test files or unrelated code)?
Is there a mix of edge types (calls, contains, extends, implements) — not just
contains?Does the node count feel right? Too few (<5) means search failed. Too many irrelevant ones means noise.
Test 2: codegraph_search — Symbol Lookup
Test that searching for specific symbols returns the right results ranked correctly.
node -e "
const { CodeGraph } = require('./dist/index.js');
async function test() {
const cg = await CodeGraph.open('<codebase_path>');
const searches = [
// A. Class by name
{ query: 'CacheBuilder', kinds: ['class'], desc: 'Find a specific class' },
// B. Method on a specific type (the classic disambiguation test)
{ query: 'CacheBuilder build', kinds: ['method'], desc: 'Method on specific class' },
// C. Common method name — should still find relevant ones
{ query: 'get', kinds: ['method'], desc: 'Common method name' },
// D. Interface/trait
{ query: 'Cache', kinds: ['interface'], desc: 'Find an interface' },
// E. Enum
{ query: 'Strength', kinds: ['enum'], desc: 'Find an enum' },
];
for (const s of searches) {
console.log(\`\n--- \${s.desc}: \"\${s.query}\" (kinds: \${s.kinds}) ---\`);
const results = cg.searchNodes(s.query, { limit: 10, kinds: s.kinds });
for (const r of results) {
console.log(\` \${r.score.toFixed(1)} | \${r.node.name} (\${r.node.kind}) | \${r.node.qualifiedName}\`);
}
if (results.length === 0) console.log(' *** NO RESULTS ***');
}
await cg.close();
}
test().catch(console.error);
"What to check:
Does the target symbol rank in the top 3?
For common names like
get, do the results include qualified names that help disambiguate?Are there zero-result queries? That's a bug.
Test 3: codegraph_callers / codegraph_callees — Call Chain Tracing
Test that call relationships were extracted correctly.
node -e "
const { CodeGraph } = require('./dist/index.js');
async function test() {
const cg = await CodeGraph.open('<codebase_path>');
// Pick 3-4 important methods and check their call graphs
const symbols = ['build', 'get', 'put', 'invalidate'];
for (const sym of symbols) {
// Find the symbol
const results = cg.searchNodes(sym, { limit: 5, kinds: ['method'] });
if (results.length === 0) { console.log(\`\${sym}: not found\`); continue; }
const node = results[0].node;
console.log(\`\n--- \${node.name} (\${node.qualifiedName}) ---\`);
// Check callees (what does it call?)
const callees = cg.getCallees(node.id);
console.log(\` Callees (\${callees.length}): \${callees.slice(0, 10).map(c => c.node.name).join(', ')}\`);
// Check callers (what calls it?)
const callers = cg.getCallers(node.id);
console.log(\` Callers (\${callers.length}): \${callers.slice(0, 10).map(c => c.node.name).join(', ')}\`);
}
await cg.close();
}
test().catch(console.error);
"What to check:
Do methods have callers AND callees? If a method has 0 of both, edge extraction may be broken.
Do the callers/callees make sense? A
build()method should call constructor-like things, and be called by setup/initialization code.Are the counts reasonable? A core method in a popular codebase should have multiple callers.
Test 4: codegraph_impact — Change Impact Analysis
Test that the impact radius correctly identifies affected code.
node -e "
const { CodeGraph } = require('./dist/index.js');
async function test() {
const cg = await CodeGraph.open('<codebase_path>');
// Pick a core class or interface that many things depend on
const results = cg.searchNodes('<CoreClass>', { limit: 1, kinds: ['class', 'interface'] });
if (results.length === 0) { console.log('Not found'); return; }
const node = results[0].node;
console.log(\`Impact analysis for: \${node.name} (\${node.kind}) — \${node.filePath}\`);
const impact = cg.getImpactRadius(node.id, 2);
console.log(\`\nAffected nodes: \${impact.nodes.size}\`);
console.log(\`Affected edges: \${impact.edges.length}\`);
// Group by file
const files = new Map();
for (const n of impact.nodes.values()) {
if (!files.has(n.filePath)) files.set(n.filePath, []);
files.get(n.filePath).push(n.name);
}
console.log(\`Affected files: \${files.size}\`);
for (const [file, nodes] of [...files.entries()].sort((a,b) => b[1].length - a[1].length).slice(0, 10)) {
console.log(\` \${file}: \${nodes.slice(0, 5).join(', ')}\`);
}
await cg.close();
}
test().catch(console.error);
"What to check:
Does changing a core interface/class show a wide impact radius?
Are the affected files reasonable (things that import/extend/use it)?
Is the impact radius non-empty? Zero impact on a core type means edges are missing.
Test 5: Edge Extraction Quality
Directly verify that the major edge types are being extracted for this language.
node -e "
const { CodeGraph } = require('./dist/index.js');
async function test() {
const cg = await CodeGraph.open('<codebase_path>');
// Check overall edge distribution
console.log('=== Edge distribution ===');
// (Use sqlite3 query from sanity check above)
// Find a class that extends another
const classes = cg.searchNodes('', { limit: 100, kinds: ['class'] });
let foundExtends = false, foundImplements = false;
for (const r of classes) {
const callees = cg.getCallees(r.node.id);
// getCallees returns all outgoing edges, check for extends/implements
// Better: use graph traversal
}
// Verify specific relationship types exist
const checks = [
{ desc: 'contains edges (class → method)', query: 'SELECT COUNT(*) FROM edges WHERE kind = \"contains\"' },
{ desc: 'calls edges', query: 'SELECT COUNT(*) FROM edges WHERE kind = \"calls\"' },
{ desc: 'imports edges', query: 'SELECT COUNT(*) FROM edges WHERE kind = \"imports\"' },
{ desc: 'extends edges', query: 'SELECT COUNT(*) FROM edges WHERE kind = \"extends\"' },
{ desc: 'implements edges', query: 'SELECT COUNT(*) FROM edges WHERE kind = \"implements\"' },
];
// Run these via sqlite3 (shown in sanity check section)
await cg.close();
}
test().catch(console.error);
"sqlite3 <codebase_path>/.codegraph/codegraph.db "
SELECT kind, COUNT(*) as cnt FROM edges GROUP BY kind ORDER BY cnt DESC;
"What to check:
containsshould be the most common (structural hierarchy).callsshould be plentiful — if near zero, call extraction is broken for this language.importsshould exist — if zero, import parsing is broken.extendsandimplementsshould exist if the language has inheritance — if zero,extractInheritance()may not handle this language's AST.
Test 6: Node Extraction Completeness
Verify all expected node kinds are being extracted.
sqlite3 <codebase_path>/.codegraph/codegraph.db "
SELECT kind, COUNT(*) as cnt FROM nodes GROUP BY kind ORDER BY cnt DESC;
"What to check for each language:
| Node Kind | Expected? | Notes |
|---|---|---|
file | Always | One per source file |
class | If language has classes | |
method | If language has methods | Should include owner type in qualified_name |
function | If language has top-level functions | |
interface | If language has interfaces/protocols | |
enum | If language has enums | |
enum_member | If language has enums | Values inside enums |
import | Always | One per import statement |
variable / field | Usually | Fields, constants, top-level vars |
struct | If language has structs | Go, Rust, C, Swift |
trait | If language has traits | Rust |
If an expected node kind has 0 count, the language extractor is missing that AST type.
Test 7: Real-World LLM Prompts
This is the final and most important test. Simulate the kinds of questions a developer would actually ask an LLM that's using CodeGraph. For each prompt, run findRelevantContext (which powers codegraph_explore) and evaluate whether the returned context would let an LLM give a correct, complete answer.
Run at least 5 of these prompt styles, adapted to the actual codebase:
node -e "
const { CodeGraph } = require('./dist/index.js');
async function test() {
const cg = await CodeGraph.open('<codebase_path>');
const prompts = [
// 1. \"How does X work?\" — subsystem understanding
'How does the cache eviction policy work?',
// 2. \"Where is X implemented?\" — symbol location
'Where is the LRU eviction logic implemented?',
// 3. \"What calls X?\" — usage discovery
'What code triggers cache invalidation?',
// 4. \"I want to change X, what breaks?\" — impact assessment
'If I change the Cache interface, what else is affected?',
// 5. \"How do X and Y interact?\" — cross-component relationships
'How does CacheBuilder connect to LocalCache?',
// 6. \"Show me the flow from A to B\" — data/control flow
'What happens when a cache entry expires?',
// 7. \"What are all the implementations of X?\" — polymorphism
'What classes implement the Cache interface?',
// 8. Bug investigation prompt
'Cache entries are not being evicted when they should be — where should I look?',
];
for (const prompt of prompts) {
console.log(\`\n========================================\`);
console.log(\`PROMPT: \${prompt}\`);
console.log(\`========================================\`);
const subgraph = await cg.findRelevantContext(prompt, {
searchLimit: 8, traversalDepth: 3, maxNodes: 80, minScore: 0.2,
});
console.log(\`Result: \${subgraph.nodes.size} nodes, \${subgraph.edges.length} edges, \${subgraph.roots.length} entry points\`);
console.log('Entry points:');
for (const rootId of subgraph.roots.slice(0, 5)) {
const node = subgraph.nodes.get(rootId);
if (node) console.log(\` \${node.name} (\${node.kind}) — \${node.filePath}:\${node.startLine}\`);
}
const fileGroups = new Map();
for (const node of subgraph.nodes.values()) {
if (!fileGroups.has(node.filePath)) fileGroups.set(node.filePath, []);
fileGroups.get(node.filePath).push(node.name);
}
console.log('Top files:');
for (const [file, nodes] of [...fileGroups.entries()].sort((a,b) => b[1].length - a[1].length).slice(0, 5)) {
console.log(\` \${file} (\${nodes.length}): \${nodes.slice(0, 5).join(', ')}\`);
}
// PASS/FAIL judgment
const hasEntryPoints = subgraph.roots.length > 0;
const hasEdges = subgraph.edges.length > 0;
const hasMultipleFiles = fileGroups.size > 1;
console.log(\`\\nVERDICT: \${hasEntryPoints && hasEdges && hasMultipleFiles ? 'PASS' : 'FAIL — needs investigation'}\`);
}
await cg.close();
}
test().catch(console.error);
"What to check for each prompt:
Does it return entry points? Zero entry points = total failure.
Are the entry points relevant to the question? (Not just random symbols that happen to share a word.)
Does it span multiple files? Most real questions involve cross-file understanding.
Are relationships present? An LLM needs to understand how symbols connect, not just a list of names.
Would you be able to answer the question from this context?
Diagnosing Failures
| Symptom | Likely Cause | Where to Fix |
|---|---|---|
Method missing owner type in qualified_name | Language needs getReceiverType | src/extraction/languages/<lang>.ts |
codegraph_explore returns irrelevant files | Common names flooding FTS; co-location boost not helping | src/db/queries.ts: findNodesByExactName, src/context/index.ts |
Zero calls edges | callTypes missing or wrong AST node type | src/extraction/languages/<lang>.ts: callTypes |
Zero extends/implements edges | extractInheritance() doesn't handle this language's AST | src/extraction/tree-sitter.ts: extractInheritance() |
| Missing node kinds (no enums, no interfaces) | AST type not listed in extractor | src/extraction/languages/<lang>.ts: enumTypes, interfaceTypes, etc. |
| Search term dropped from query | Term is in the stop words list | src/search/query-utils.ts: STOP_WORDS |
qualified_name missing class for nested methods | Extraction not walking parent stack correctly | src/extraction/tree-sitter.ts: visitNode() |
| Import edges missing | extractImport returns null for this syntax | src/extraction/languages/<lang>.ts: extractImport |
| C++ classes/structs/enums missing from macro namespaces | Macros like NLOHMANN_JSON_NAMESPACE_BEGIN cause tree-sitter to misparse namespace blocks as function_definition | src/extraction/languages/c-cpp.ts: isMisparsedFunction filters bad names; src/extraction/tree-sitter.ts: visitFunctionBody extracts structural nodes |
C++ classes missing from .h headers | .h files default to c language which has classTypes: [] | src/extraction/grammars.ts: looksLikeCpp() — content-based heuristic promotes .h files to cpp when C++ patterns detected |
Ruby methods inside modules missing owner in qualified_name | Ruby module AST nodes not being extracted | src/extraction/languages/ruby.ts: visitNode hook extracts modules; src/extraction/tree-sitter.ts: isInsideClassLikeNode includes module kind |
| TypeScript abstract classes missing | abstract_class_declaration not in classTypes | src/extraction/languages/typescript.ts: classTypes — add abstract_class_declaration |
| Single-expression arrow functions silently dropped | extractName finds identifier in expression body instead of returning <anonymous> | src/extraction/tree-sitter.ts: extractName — skip identifier search for arrow_function/function_expression nodes |
| Kotlin interfaces/enums extracted as classes | class_declaration matches classTypes first; interfaceTypes/enumTypes never fire | src/extraction/languages/kotlin.ts: classifyClassNode detects interface/enum keywords in AST children |
| Kotlin functions have zero calls extracted | Tree-sitter grammar doesn't use field names, so getChildByField(node, 'function_body') returns null | src/extraction/languages/kotlin.ts: resolveBody finds body by type (function_body, class_body, enum_class_body) |
Kotlin navigation_expression calls not resolved cleanly | navigation_expression fell through to getNodeText producing messy names with parentheses | src/extraction/tree-sitter.ts: extractCall — handle navigation_expression by extracting method name from navigation_suffix > simple_identifier |
Kotlin fun interface declarations invisible | Tree-sitter-kotlin doesn't support fun interface syntax (Kotlin 1.4+), producing ERROR or misparse as function_declaration | src/extraction/languages/kotlin.ts: visitNode detects three misparse patterns: (1) ERROR node + lambda body, (2) function_declaration with user_type("interface") direct child + name in ERROR child, (3) function_declaration with ERROR child containing user_type("interface") + name. isFunInterfaceNode checks both direct and ERROR-nested user_type children |
Kotlin class/interface methods missing when nested fun interface present | Tree-sitter misparsed parent body as ERROR (starting with {) + class_body (nested interface body); resolveBody found wrong body | src/extraction/languages/kotlin.ts: resolveBody prefers ERROR bodies starting with {; visitNode excludes body-like ERROR from fun interface detection |
Svelte $props() destructuring produces ugly variable names | let { x, y } = $props() has object_pattern as variable name node; getNodeText returns full pattern | src/extraction/tree-sitter.ts: extractVariable skips object_pattern/array_pattern named declarators |
Svelte template function calls invisible (e.g. class={cn(...)}) | SvelteExtractor only parsed <script> blocks, missing calls in template markup | src/extraction/svelte-extractor.ts: extractTemplateCalls scans {expression} blocks in template for call patterns |
Svelte $state/$derived rune calls creating noise | Runes are compiler builtins, not real function calls | src/extraction/svelte-extractor.ts filters SVELTE_RUNES set from unresolved references |
| Object literal getters/setters extracted as standalone functions | method_definition inside object literals treated same as class methods | src/extraction/tree-sitter.ts: extractMethod skips method_definition nodes whose parent is object/object_expression |
JavaScript class extends produces zero inheritance edges | JS tree-sitter uses class_heritage → identifier (bare), not class_heritage → extends_clause → identifier like TypeScript | src/extraction/tree-sitter.ts: extractInheritance — handle bare identifier/type_identifier children when parent is class_heritage |
| PHP traits extracted as classes | trait_declaration in classTypes but extractClass hardcodes class kind | src/extraction/languages/php.ts: classifyClassNode returns 'trait' for trait_declaration; src/extraction/tree-sitter-types.ts adds 'trait' to return type |
| PHP class properties missing (0 field nodes) | extractField looks for variable_declarator children; PHP uses property_element > variable_name > name | src/extraction/tree-sitter.ts: extractField — handle property_element children with variable_name > name path |
| PHP class constants skipped inside classes | variableTypes check has !isInsideClassLikeNode() guard, so const_declaration inside classes falls through | src/extraction/languages/php.ts: visitNode hook catches const_declaration, extracts const_element > name as constant kind |
PHP use TraitName inside classes invisible | use_declaration nodes in class body not processed for edges | src/extraction/languages/php.ts: visitNode hook extracts trait names from use_declaration and creates implements unresolved references |
After Fixing Issues
npm run build
rm -rf <codebase_path>/.codegraph
node dist/bin/codegraph.js init -v <codebase_path>
# Re-run the failing tests from aboveAlways run the full test suite before marking a language as verified:
npm testAdding getReceiverType
Only needed for languages where methods are top-level or outside their owner type in the AST. If the language nests methods inside class/struct bodies (Python, Java, TypeScript, C#), the qualified name already includes the parent — verify with the sanity check before adding anything.
1. Add the hook to the language extractor
In src/extraction/languages/<lang>.ts, add getReceiverType to the extractor object:
getReceiverType: (node, source) => {
// Extract the owner type name from the method's AST node.
// Return the type name string, or undefined if not applicable.
//
// The core extractMethod() in tree-sitter.ts will use this to set:
// qualifiedName = `${filePath}::${receiverType}::${methodName}`
},2. Reference: Go implementation
// src/extraction/languages/go.ts
getReceiverType: (node, source) => {
const receiver = getChildByField(node, 'receiver');
if (!receiver) return undefined;
const text = getNodeText(receiver, source);
const match = text.match(/\*?\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)/);
return match?.[1];
},3. Where it's consumed
src/extraction/tree-sitter.ts in extractMethod():
const receiverType = this.extractor.getReceiverType?.(node, this.source);
if (receiverType) {
extraProps.qualifiedName = `${this.filePath}::${receiverType}::${name}`;
}Key Files
| File | Role |
|---|---|
src/extraction/languages/<lang>.ts | Language extractor — node types, call types, getReceiverType |
src/extraction/tree-sitter.ts | Core extraction — extractMethod(), extractCall(), extractInheritance() |
src/extraction/tree-sitter-types.ts | LanguageExtractor interface definition |
src/search/query-utils.ts | STOP_WORDS, extractSearchTerms, scorePathRelevance |
src/db/queries.ts | searchNodesFTS (BM25), findNodesByExactName (co-location boost) |
src/context/index.ts | findRelevantContext — hybrid search + graph traversal |
src/mcp/tools.ts | MCP tool handlers — codegraph_explore implementation |
Language Status
Verified
[x] Go —
getReceiverTypeextracts receiver fromfunc (sl *Type) method()[x] Swift — NOT needed. Tree-sitter nests methods inside class/extension bodies
[x] Java — NOT needed. Methods nested in class body. Verified against Guava
[x] Python — NOT needed. Methods nested in class body. Verified against Flask
[x] Rust —
getReceiverTypewalks up to parentimpl_itemto extract type name. Also addscontainsedges from struct to impl methods. Verified against Deno[x] C — NOT needed. No methods in C. Strong function/struct/enum extraction with excellent call edge density. Verified against Redis
[x] C++ — NOT needed for header-only libs.
isMisparsedFunctionhook filters macro-caused misparse artifacts (e.g.NLOHMANN_JSON_NAMESPACE_BEGIN).visitFunctionBodynow extracts structural nodes (classes/structs/enums) inside macro-confused "function" bodies. Content-based.hdetection (looksLikeCppingrammars.ts) promotes C++ headers tocpplanguage so classes in.hfiles are extracted. Verified against nlohmann/json and gRPC. Note: out-of-classType::method()definitions would needgetReceiverTypebut are uncommon in header-only codebases.[x] C# — NOT needed. Methods nested in class body. Added
base_listhandling inextractInheritancefor C#'s: Parent, IInterfacesyntax. AddedpropertyTypessupport for C#property_declarationnodes. FixedextractFieldto handle C#'s nestedvariable_declaration > variable_declaratorstructure. Verified against Jellyfin[x] Ruby — NOT needed for
getReceiverType. Methods nested in class body. AddedvisitNodehook to extract Rubymodulenodes (concerns, namespaces) with proper containment and qualified names. Methods inside modules getModule::methodqualified names. Also wired up theExtractorContextwithpushScope/popScopefor language hooks. Verified against Discourse[x] TypeScript — NOT needed for
getReceiverType. Methods nested in class body. Addedabstract_class_declarationtoclassTypesso abstract classes are properly extracted. Fixed single-expression arrow function extraction (const fn = () => exprwas silently dropped becauseextractNamepicked up the body identifier instead of returning<anonymous>for parent name resolution). Verified against Grafana[x] Dart — NOT needed for
getReceiverType. Methods nested in class body. Added bare call extraction for selector-based method calls (e.g.object.method()). Verified against Flutter[x] Kotlin —
getReceiverTypeextracts receiver from extension functionsfun Type.method(). AddedclassifyClassNodeto distinguish interfaces/enums from classes (all useclass_declarationAST node). AddedresolveBodyhook since Kotlin's tree-sitter grammar doesn't use field names. Addednavigation_expressionhandling for method call extraction. Addedobject_declarationviaextraClassNodeTypes. Addeddelegation_specifierhandling inextractInheritancefor Kotlin's: Parent, Interfacesyntax. Also fixedextractInterfaceto visit body children (interface methods were not being extracted). AddedvisitNodehook to handlefun interface(SAM) declarations — tree-sitter-kotlin doesn't support this Kotlin 1.4+ syntax, producing ERROR or function_declaration misparse; the hook detects both patterns and extracts the interface. Verified against Koin, LeakCanary[x] Svelte — Custom
SvelteExtractordelegates<script>blocks to TS/JS parser; createscomponentnodes for each.sveltefile. Added template expression call extraction: scans{expression}blocks in markup for function calls (e.g.class={cn(...)}), creating call edges from component to callees — increased Svelte call edges from 29 to 387. Filtered Svelte 5 rune calls ($state,$props,$derived,$effect,$bindable). Also fixed: destructured$props()patterns (e.g.let { x, y } = $props()) no longer extracted as ugly multi-line variable names (skipobject_pattern/array_patterninextractVariable). Object literal getter/setter methods no longer extracted as standalone functions. Verified against shadcn-svelte[x] PHP — NOT needed for
getReceiverType. Methods nested in class body. AddedclassifyClassNodeto distinguish traits from classes (trait_declaration→traitkind). Added'trait'toclassifyClassNodereturn type intree-sitter-types.tsand handling in visitor. Fixed PHP property extraction:extractFieldnow handlesproperty_element > variable_name > nameAST structure (added 4,366 field nodes). AddedvisitNodehook for class constants (const_declarationinside classes was skipped byvariableTypesguard) and traitusedeclarations (use HasFactory, SoftDeletes;createsimplementsedges — increased from 636 to 1,514). Verified against Laravel
Needs Verification
(none currently)
512 files · 493 not served here
- .claude/skills/add-lang/SKILL.md (not served here)
- .claude/skills/agent-eval/SKILL.md (not served here)
- .claude/skills/agent-eval/corpus.json (not served here)
- .cursor/rules/codegraph.mdc
- .dockerignore (not served here)
- .gitattributes (not served here)
- .github/workflows/deploy-site.yml (not served here)
- .github/workflows/release.yml (not served here)
- .gitignore (not served here)
- AGENTS.md
- ATTRIBUTION.md
- AUTOGINEER-RUNS.md
- BUNDLING.md
- CHANGELOG.md
- CLAUDE.md
- CONTRIBUTING.md
- LICENSE
- README.md
- TELEMETRY.md
- __tests__/absent-member-calls.test.ts (not served here)
- __tests__/adaptive-explore-sizing.test.ts (not served here)
- __tests__/add-lang-check-grammar.test.ts (not served here)
- __tests__/add-lang-verify-extraction.test.ts (not served here)
- __tests__/alias-binding-resolution.test.ts (not served here)
- __tests__/ambient-module-imports.test.ts (not served here)
- __tests__/android-res-exclusion.test.ts (not served here)
- __tests__/angular-router.test.ts (not served here)
- __tests__/arkts-resolution.test.ts (not served here)
- __tests__/astro-component-markup-only.test.ts (not served here)
- __tests__/awaited-receiver.test.ts (not served here)
- __tests__/bare-call-no-method.test.ts (not served here)
- __tests__/batched-ref-cleanup.test.ts (not served here)
- __tests__/beta-signup.test.ts (not served here)
- __tests__/bounded-source.test.ts (not served here)
- __tests__/branch-guards-languages.test.ts (not served here)
- __tests__/branch-guards.test.ts (not served here)
- __tests__/browser-host-globals.test.ts (not served here)
- __tests__/bundle-launcher.test.ts (not served here)
- __tests__/c-calls-never-methods.test.ts (not served here)
- __tests__/c-cpp-declaration-types.test.ts (not served here)
- __tests__/c-cpp-member-supertypes.test.ts (not served here)
- __tests__/c-cpp-member-type-refs.test.ts (not served here)
- __tests__/c-feature-macro-variants.test.ts (not served here)
- __tests__/c-fnptr-kernel-sweep.test.ts (not served here)
- __tests__/c-fnptr-synthesizer.test.ts (not served here)
- __tests__/c-include-lone-macros.test.ts (not served here)
- __tests__/c-macro-renames.test.ts (not served here)
- __tests__/c-macro-return-types.test.ts (not served here)
- __tests__/c-statement-macro-names.test.ts (not served here)
- __tests__/c-static-call-rescue.test.ts (not served here)
- __tests__/call-receiver-no-fabrication.test.ts (not served here)
- __tests__/call-value-targets.test.ts (not served here)
- __tests__/callers-call-sites.test.ts (not served here)
- __tests__/catch-all-path-alias.test.ts (not served here)
- __tests__/celery-dispatch-synthesizer.test.ts (not served here)
- __tests__/cfml-call-scope.test.ts (not served here)
- __tests__/cfml-create-object.test.ts (not served here)
- __tests__/cfml-embedded-parse-warning.test.ts (not served here)
- __tests__/cfml-include.test.ts (not served here)
- __tests__/cfml-inheritance-resolution.test.ts (not served here)
- __tests__/cfml-receiver-inference.test.ts (not served here)
- __tests__/cfml-tag-calls.test.ts (not served here)
- __tests__/child-process-windows-hide.test.ts (not served here)
- __tests__/chinese-filename-retrieval.test.ts (not served here)
- __tests__/cjk-query-tokens.test.ts (not served here)
- __tests__/cli-affected-filter-globs.test.ts (not served here)
- __tests__/cli-affected-paths.test.ts (not served here)
- __tests__/cli-affected-test-conventions.test.ts (not served here)
- __tests__/cli-context-command.test.ts (not served here)
- __tests__/cli-cycles.test.ts (not served here)
- __tests__/cli-definition-grouping.test.ts (not served here)
- __tests__/cli-files-test-classification.test.ts (not served here)
- __tests__/cli-implementations.test.ts (not served here)
- __tests__/cli-index-explicit-path.test.ts (not served here)
- __tests__/cli-install-init.test.ts (not served here)
- __tests__/cli-no-color.test.ts (not served here)
- __tests__/cli-node-command.test.ts (not served here)
- __tests__/cli-parse-warning.test.ts (not served here)
- __tests__/cli-query-command.test.ts (not served here)
- __tests__/cli-sync-stale-index.test.ts (not served here)
- __tests__/cli-sync.test.ts (not served here)
- __tests__/cli-truncation.test.ts (not served here)
- __tests__/cli-ui-command.test.ts (not served here)
- __tests__/cli-unlock.test.ts (not served here)
- __tests__/cli-version.test.ts (not served here)
- __tests__/closure-collection-synthesizer.test.ts (not served here)
- __tests__/cobol-sequence-area-period.test.ts (not served here)
- __tests__/codeigniter.test.ts (not served here)
- __tests__/commonjs-exports.test.ts (not served here)
- __tests__/commonjs-require-calls.test.ts (not served here)
- __tests__/commonjs-require-imports.test.ts (not served here)
- __tests__/compile-cache-missing-drive.test.ts (not served here)
- __tests__/component-same-folder.test.ts (not served here)
- __tests__/concurrent-locking.test.ts (not served here)
- __tests__/config-secret-redaction.test.ts (not served here)
- __tests__/const-alias-flow.test.ts (not served here)
- __tests__/context-ranking.test.ts (not served here)
- __tests__/context.test.ts (not served here)
- __tests__/cooperative-yield.test.ts (not served here)
- __tests__/cpp-absl-holder-receiver.test.ts (not served here)
- __tests__/cpp-alias-inherited-member.test.ts (not served here)
- __tests__/cpp-anonymous-union-members.test.ts (not served here)
- __tests__/cpp-attribute-macros.test.ts (not served here)
- __tests__/cpp-auto-iterator-arrow.test.ts (not served here)
- __tests__/cpp-auto-local-receiver.test.ts (not served here)
- __tests__/cpp-auto-range-for-receiver.test.ts (not served here)
- __tests__/cpp-base-class-lookup.test.ts (not served here)
- __tests__/cpp-binding-and-wrapper-receivers.test.ts (not served here)
- __tests__/cpp-block-comment-lines.test.ts (not served here)
- __tests__/cpp-brace-scopes.test.ts (not served here)
- __tests__/cpp-class-name-receiver-members.test.ts (not served here)
- __tests__/cpp-comparisons-and-template-declarators.test.ts (not served here)
- __tests__/cpp-conditional-class.test.ts (not served here)
- __tests__/cpp-container-accessor-calls.test.ts (not served here)
- __tests__/cpp-declarator-clause-names.test.ts (not served here)
- __tests__/cpp-declared-type-receiver.test.ts (not served here)
- __tests__/cpp-dereferenced-iterator-calls.test.ts (not served here)
- __tests__/cpp-element-access-calls.test.ts (not served here)
- __tests__/cpp-free-function-overloads.test.ts (not served here)
- __tests__/cpp-global-alias-target.test.ts (not served here)
- __tests__/cpp-global-scope-names.test.ts (not served here)
- __tests__/cpp-gtest-fixture-scope.test.ts (not served here)
- __tests__/cpp-implicit-this-calls.test.ts (not served here)
- __tests__/cpp-included-test-suite.test.ts (not served here)
- __tests__/cpp-iterator-arrow.test.ts (not served here)
- __tests__/cpp-library-type-receiver.test.ts (not served here)
- __tests__/cpp-listed-declarator-receiver.test.ts (not served here)
- __tests__/cpp-local-callable-calls.test.ts (not served here)
- __tests__/cpp-lookup-memos.test.ts (not served here)
- __tests__/cpp-macro-and-constructor-calls.test.ts (not served here)
- __tests__/cpp-macro-defined-methods.test.ts (not served here)
- __tests__/cpp-macro-include-walk.test.ts (not served here)
- __tests__/cpp-macro-namespace.test.ts (not served here)
- __tests__/cpp-map-iterator-calls.test.ts (not served here)
- __tests__/cpp-member-chain-base-members.test.ts (not served here)
- __tests__/cpp-member-chain-outside-calls.test.ts (not served here)
- __tests__/cpp-member-chain-project-calls.test.ts (not served here)
- __tests__/cpp-member-receiver.test.ts (not served here)
- __tests__/cpp-member-template-returns.test.ts (not served here)
- __tests__/cpp-namespace-qualifier.test.ts (not served here)
- __tests__/cpp-nested-template-receiver.test.ts (not served here)
- __tests__/cpp-nullptr-deleted-overloads.test.ts (not served here)
- __tests__/cpp-operator-arrow-targets.test.ts (not served here)
- __tests__/cpp-outside-type-receiver.test.ts (not served here)
- __tests__/cpp-overload-argument-reentry.test.ts (not served here)
- __tests__/cpp-overload-argument-types.test.ts (not served here)
- __tests__/cpp-overload-choice.test.ts (not served here)
- __tests__/cpp-overload-constness.test.ts (not served here)
- __tests__/cpp-pimpl-member-chains.test.ts (not served here)
- __tests__/cpp-qualified-declarator-receiver.test.ts (not served here)
- __tests__/cpp-range-for-receiver.test.ts (not served here)
- __tests__/cpp-raw-string-delimiter-haserror.test.ts (not served here)
- __tests__/cpp-raw-string-preparse-1505.test.ts (not served here)
- __tests__/cpp-raw-strings.test.ts (not served here)
- __tests__/cpp-receiver-global-far-library.test.ts (not served here)
- __tests__/cpp-smart-pointer-receiver.test.ts (not served here)
- __tests__/cpp-specialization-names.test.ts (not served here)
- __tests__/cpp-specialization-qualifiers.test.ts (not served here)
- __tests__/cpp-string-literal-declarations.test.ts (not served here)
- __tests__/cpp-template-member-types.test.ts (not served here)
- __tests__/cpp-test-fixture-call.test.ts (not served here)
- __tests__/cpp-test-translation-unit.test.ts (not served here)
- __tests__/cpp-translation-unit-visibility.test.ts (not served here)
- __tests__/cpp-translation-unit.test.ts (not served here)
- __tests__/cpp-two-line-receivers.test.ts (not served here)
- __tests__/cpp-type-alias-receiver.test.ts (not served here)
- __tests__/cpp-undeclared-qualifier.test.ts (not served here)
- __tests__/cpp-written-scope-class-names.test.ts (not served here)
- __tests__/cross-file-visibility.test.ts (not served here)
- __tests__/cross-language-resolution.test.ts (not served here)
- __tests__/csharp-bare-member-scope.test.ts (not served here)
- __tests__/csharp-declared-receivers.test.ts (not served here)
- __tests__/csharp-member-initializers.test.ts (not served here)
- __tests__/csharp-namespace-scope.test.ts (not served here)
- __tests__/csharp-namespace-visibility.test.ts (not served here)
- __tests__/csharp-property-accessors.test.ts (not served here)
- __tests__/csharp-type-position-refs.test.ts (not served here)
- __tests__/curried-wrapper-handlers.test.ts (not served here)
- __tests__/daemon-attach-log.test.ts (not served here)
- __tests__/daemon-bind-failure.test.ts (not served here)
- __tests__/daemon-candidates.ts (not served here)
- __tests__/daemon-client-liveness.test.ts (not served here)
- __tests__/daemon-install-check.test.ts (not served here)
- __tests__/daemon-lock-holder.test.ts (not served here)
- __tests__/daemon-lock-refresh.test.ts (not served here)
- __tests__/daemon-manager.test.ts (not served here)
- __tests__/daemon-older-version.test.ts (not served here)
- __tests__/daemon-pid-reuse.test.ts (not served here)
- __tests__/daemon-registry.test.ts (not served here)
- __tests__/daemon-rendezvous-case.test.ts (not served here)
- __tests__/daemon-silent-holder.test.ts (not served here)
- __tests__/daemon-socket-fallback.test.ts (not served here)
- __tests__/dart-annotated-member-docs.test.ts (not served here)
- __tests__/dart-annotation-comments.test.ts (not served here)
- __tests__/dart-annotation-targets.test.ts (not served here)
- __tests__/dart-bare-call-scope.test.ts (not served here)
- __tests__/dart-bodiless-member-docs.test.ts (not served here)
- __tests__/dart-chain-links.test.ts (not served here)
- __tests__/dart-comment-split-chains.test.ts (not served here)
- __tests__/dart-const-constructors.test.ts (not served here)
- __tests__/dart-extension-receiver.test.ts (not served here)
- __tests__/dart-extension-type.test.ts (not served here)
- __tests__/dart-generic-calls.test.ts (not served here)
- __tests__/dart-generic-factory-chain.test.ts (not served here)
- __tests__/dart-getter-reads.test.ts (not served here)
- __tests__/dart-import-prefix-calls.test.ts (not served here)
- __tests__/dart-import-uris.test.ts (not served here)
- __tests__/dart-initializer-calls.test.ts (not served here)
- __tests__/dart-library-visibility.test.ts (not served here)
- __tests__/dart-local-call-scope.test.ts (not served here)
- __tests__/dart-part-directives.test.ts (not served here)
- __tests__/dart-part-privacy.test.ts (not served here)
- __tests__/dart-type-positions.test.ts (not served here)
- __tests__/dart-typedef-refs.test.ts (not served here)
- __tests__/dart-unnamed-extension.test.ts (not served here)
- __tests__/db-perf.test.ts (not served here)
- __tests__/db-reopen-on-replace.test.ts (not served here)
- __tests__/dead-code.test.ts (not served here)
- __tests__/declared-member-receiver.test.ts (not served here)
- __tests__/default-export-declaration.test.ts (not served here)
- __tests__/deprioritize-config.test.ts (not served here)
- __tests__/destructured-call-result.test.ts (not served here)
- __tests__/dominant-file-cache.test.ts (not served here)
- __tests__/dominant-file-plan.test.ts (not served here)
- __tests__/dominant-file-window.test.ts (not served here)
- __tests__/dotdot-folder-names.test.ts (not served here)
- __tests__/drupal-services.test.ts (not served here)
- __tests__/drupal.test.ts (not served here)
- __tests__/dynamic-boundaries.test.ts (not served here)
- __tests__/dynamic-import-binding.test.ts (not served here)
- __tests__/enclosing-class-member-call.test.ts (not served here)
- __tests__/enum-constant-bodies.test.ts (not served here)
- __tests__/erlang-arity-resolution.test.ts (not served here)
- __tests__/erlang-behaviour-synthesizer.test.ts (not served here)
- __tests__/esm-unexported-binding.test.ts (not served here)
- __tests__/evaluation/runner.ts (not served here)
- __tests__/evaluation/scoring.ts (not served here)
- __tests__/evaluation/test-cases.ts (not served here)
- __tests__/evaluation/types.ts (not served here)
- __tests__/exact-name-binding.test.ts (not served here)
- __tests__/exclude-config.test.ts (not served here)
- __tests__/explore-allocation-1500.test.ts (not served here)
- __tests__/explore-allocation-e2e.test.ts (not served here)
- __tests__/explore-blast-radius.test.ts (not served here)
- __tests__/explore-cluster-starvation.test.ts (not served here)
- __tests__/explore-cobol-copybook.test.ts (not served here)
- __tests__/explore-completeness-note.test.ts (not served here)
- __tests__/explore-corroboration-ranking.test.ts (not served here)
- __tests__/explore-cross-call-dedup.test.ts (not served here)
- __tests__/explore-declaration-only.test.ts (not served here)
- __tests__/explore-diagnostics.test.ts (not served here)
- __tests__/explore-displacement-guard.test.ts (not served here)
- __tests__/explore-elided-symbol-names.test.ts (not served here)
- __tests__/explore-empty-diagnostics.test.ts (not served here)
- __tests__/explore-exact-target.test.ts (not served here)
- __tests__/explore-factory-closure.test.ts (not served here)
- __tests__/explore-isolated-named-cluster.test.ts (not served here)
- __tests__/explore-long-query.test.ts (not served here)
- __tests__/explore-low-value-tests.test.ts (not served here)
- __tests__/explore-merged-spine-cluster.test.ts (not served here)
- __tests__/explore-named-file-valve.test.ts (not served here)
- __tests__/explore-named-gap-budget.test.ts (not served here)
- __tests__/explore-named-symbol-render.test.ts (not served here)
- __tests__/explore-nl-stopword-collision.test.ts (not served here)
- __tests__/explore-output-budget.test.ts (not served here)
- __tests__/explore-oversize-member.test.ts (not served here)
- __tests__/explore-path-pinning.test.ts (not served here)
- __tests__/explore-pinned-allocation.test.ts (not served here)
- __tests__/explore-pinned-cap-named.test.ts (not served here)
- __tests__/explore-proportional-allocation.test.ts (not served here)
- __tests__/explore-queried-oversize-symbol.test.ts (not served here)
- __tests__/explore-relevance-scoring.test.ts (not served here)
- __tests__/explore-reservation-invariant.test.ts (not served here)
- __tests__/explore-result-count.test.ts (not served here)
- __tests__/explore-same-basename-pin.test.ts (not served here)
- __tests__/explore-session-state.test.ts (not served here)
- __tests__/explore-synth-constant-endpoints.test.ts (not served here)
- __tests__/explore-synth-link-endpoints.test.ts (not served here)
- __tests__/explore-unindexed-names.test.ts (not served here)
- __tests__/expo-modules.test.ts (not served here)
- __tests__/expo-router.test.ts (not served here)
- __tests__/express-heuristic-same-file.test.ts (not served here)
- __tests__/express-inline-function-handler.test.ts (not served here)
- __tests__/expression-receiver-calls.test.ts (not served here)
- __tests__/extension-mapping.test.ts (not served here)
- __tests__/external-declared-receiver.test.ts (not served here)
- __tests__/external-type-receiver.test.ts (not served here)
- __tests__/extraction-old-git.test.ts (not served here)
- __tests__/extraction.test.ts (not served here)
- __tests__/fabric-view.test.ts (not served here)
- __tests__/fastendpoints-routes.test.ts (not served here)
- __tests__/fatal-handler.test.ts (not served here)
- __tests__/field-channel-scope.test.ts (not served here)
- __tests__/field-name-retrieval.test.ts (not served here)
- __tests__/file-cycles.test.ts (not served here)
- __tests__/file-routed-page-component.test.ts (not served here)
- __tests__/filelock-stale-takeover.test.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/package.json (not served here)
- __tests__/fixtures/ambient-decls-ts/src/lib/bucket.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/src/lib/queue.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/src/lib/request.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/src/routes/upload.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/src/storage/metadata.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/src/storage/stream.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/src/storage/types.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/types/platform-shims.d.ts (not served here)
- __tests__/fixtures/ambient-decls-ts/types/worker-configuration.d.ts (not served here)
- __tests__/fixtures/dense-header-ts/package.json (not served here)
- __tests__/fixtures/dense-header-ts/src/core/queue.ts (not served here)
- __tests__/fixtures/dense-header-ts/src/core/request-builder.ts (not served here)
- __tests__/fixtures/dense-header-ts/src/core/task-factory.ts (not served here)
- __tests__/fixtures/dense-header-ts/src/core/types.ts (not served here)
- __tests__/fixtures/dense-header-ts/src/index.ts (not served here)
- __tests__/fixtures/dense-header-ts/src/net/session.ts (not served here)
- __tests__/fixtures/displacement-ts/package.json (not served here)
- __tests__/fixtures/displacement-ts/src/index.ts (not served here)
- __tests__/fixtures/displacement-ts/src/pipeline/enrich.ts (not served here)
- __tests__/fixtures/displacement-ts/src/pipeline/ingest.ts (not served here)
- __tests__/fixtures/displacement-ts/src/pipeline/normalize.ts (not served here)
- __tests__/fixtures/displacement-ts/src/pipeline/publish.ts (not served here)
- __tests__/fixtures/displacement-ts/src/pipeline/sink.ts (not served here)
- __tests__/fixtures/displacement-ts/src/pipeline/types.ts (not served here)
- __tests__/fixtures/explore-path-pinning/package.json (not served here)
- __tests__/fixtures/explore-path-pinning/src/lib/background-image-table.ts (not served here)
- __tests__/fixtures/explore-path-pinning/src/lib/background-store.ts (not served here)
- __tests__/fixtures/explore-path-pinning/src/lib/runs-store.ts (not served here)
- __tests__/fixtures/explore-path-pinning/src/routes/(protected)/chat-window/+page.ts (not served here)
- __tests__/fixtures/explore-path-pinning/src/routes/m/projects/[id]/runs/[runId]/+page.ts (not served here)
- __tests__/fixtures/factory-closure-ts/package.json (not served here)
- __tests__/fixtures/factory-closure-ts/src/index.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/lib/http.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/lib/metrics.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/services/filter-parser.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/services/metric-service.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/stores/alerts-store.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/stores/dashboard-store.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/stores/session-store.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/stores/types.ts (not served here)
- __tests__/fixtures/factory-closure-ts/src/ui/panel.ts (not served here)
- __tests__/fixtures/filelock-contender.cjs (not served here)
- __tests__/fixtures/kernel-parity/ScalaCompanions.scala (not served here)
- __tests__/fixtures/kernel-parity/Torture.cs (not served here)
- __tests__/fixtures/kernel-parity/Torture.java (not served here)
- __tests__/fixtures/kernel-parity/TortureAnnotatedComments.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureAnnotatedDocs.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureCommentChains.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureConstCtors.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureCtors.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureDeclarationDocs.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureDirectives.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureDocs.scala (not served here)
- __tests__/fixtures/kernel-parity/TortureDoubleWalk.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureExt.scala (not served here)
- __tests__/fixtures/kernel-parity/TortureFileScoped.cs (not served here)
- __tests__/fixtures/kernel-parity/TortureFnref.scala (not served here)
- __tests__/fixtures/kernel-parity/TortureFnrefDart.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureGenericCalls.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureGiven.scala (not served here)
- __tests__/fixtures/kernel-parity/TortureHtml.php (not served here)
- __tests__/fixtures/kernel-parity/TortureIndent.scala (not served here)
- __tests__/fixtures/kernel-parity/TortureInitializers.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureMini.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureMisc.scala (not served here)
- __tests__/fixtures/kernel-parity/TortureModule.module (not served here)
- __tests__/fixtures/kernel-parity/TorturePartOfName.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureReadsTypes.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureRecord.java (not served here)
- __tests__/fixtures/kernel-parity/TortureScript.kts (not served here)
- __tests__/fixtures/kernel-parity/TortureScript.sc (not served here)
- __tests__/fixtures/kernel-parity/TortureSigs.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureTopLevel.cs (not served here)
- __tests__/fixtures/kernel-parity/TortureTry.swift (not served here)
- __tests__/fixtures/kernel-parity/TortureTypedefs.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureVref.scala (not served here)
- __tests__/fixtures/kernel-parity/TortureVrefDart.dart (not served here)
- __tests__/fixtures/kernel-parity/TortureWrappedCalls.swift (not served here)
- __tests__/fixtures/kernel-parity/docstrings.py (not served here)
- __tests__/fixtures/kernel-parity/torture-macros-ctors.cpp (not served here)
- __tests__/fixtures/kernel-parity/torture-macros.c (not served here)
- __tests__/fixtures/kernel-parity/torture.R (not served here)
- __tests__/fixtures/kernel-parity/torture.c (not served here)
- __tests__/fixtures/kernel-parity/torture.cpp (not served here)
- __tests__/fixtures/kernel-parity/torture.dart (not served here)
- __tests__/fixtures/kernel-parity/torture.go (not served here)
- __tests__/fixtures/kernel-parity/torture.hpp (not served here)
- __tests__/fixtures/kernel-parity/torture.js (not served here)
- __tests__/fixtures/kernel-parity/torture.kt (not served here)
- __tests__/fixtures/kernel-parity/torture.lua (not served here)
- __tests__/fixtures/kernel-parity/torture.luau (not served here)
- __tests__/fixtures/kernel-parity/torture.php (not served here)
- __tests__/fixtures/kernel-parity/torture.py (not served here)
- __tests__/fixtures/kernel-parity/torture.rb (not served here)
- __tests__/fixtures/kernel-parity/torture.rs (not served here)
- __tests__/fixtures/kernel-parity/torture.scala (not served here)
- __tests__/fixtures/kernel-parity/torture.swift (not served here)
- __tests__/fixtures/kernel-parity/torture.tsx (not served here)
- __tests__/fixtures/older-daemon.cjs (not served here)
- __tests__/fixtures/oversize-member-ts/package.json (not served here)
- __tests__/fixtures/oversize-member-ts/src/index.ts (not served here)
- __tests__/fixtures/oversize-member-ts/src/report/format.ts (not served here)
- __tests__/fixtures/oversize-member-ts/src/report/monthly.ts (not served here)
- __tests__/fixtures/oversize-member-ts/src/report/quarterly.ts (not served here)
- __tests__/fixtures/oversize-member-ts/src/report/store.ts (not served here)
- __tests__/fixtures/oversize-member-ts/src/report/types.ts (not served here)
- __tests__/fixtures/oversize-member-ts/src/report/weekly.ts (not served here)
- __tests__/fixtures/payroll-go/README.md (not served here)
- __tests__/fixtures/payroll-go/cmd/payrolld/main.go (not served here)
- __tests__/fixtures/payroll-go/go.mod (not served here)
- __tests__/fixtures/payroll-go/internal/domain/payroll/payslip.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/fkit/employee/contract.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/fkit/employee/employee.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/fkit/payroll/calculate.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/fkit/payroll/dto.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/fkit/payroll/payroll_cycle.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/fkit/payroll/payslip.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/fkit/payroll/store.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/fkit/timesheet/timesheet.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/payrollpb/payroll.pb.go (not served here)
- __tests__/fixtures/payroll-go/internal/gen/payrollpb/payroll_grpc.pb.go (not served here)
- __tests__/fixtures/payroll-go/internal/platform/clock/clock.go (not served here)
- __tests__/fixtures/payroll-go/internal/store/payslipstore/store.go (not served here)
- __tests__/fixtures/payroll-go/internal/transport/httpapi/payroll_handler.go (not served here)
- __tests__/fixtures/payroll-go/internal/transport/httpapi/router.go (not served here)
- __tests__/fixtures/payroll-go/internal/usecase/payroll/cycle.go (not served here)
- __tests__/fixtures/payroll-go/internal/usecase/payroll/payslip_builder.go (not served here)
- __tests__/fixtures/payroll-go/internal/usecase/payroll/prorate.go (not served here)
- __tests__/fixtures/php-import-alias-static/app/Http/Controllers/Backend/SettleController.php (not served here)
- __tests__/fixtures/php-import-alias-static/app/Repositories/SettleRepository.php (not served here)
- __tests__/fixtures/php-import-alias-static/app/Services/SettleService.php (not served here)
- __tests__/fixtures/record-detached-spawns.cjs (not served here)
- __tests__/fixtures/starved-cluster-ts/package.json (not served here)
- __tests__/fixtures/starved-cluster-ts/src/app/client.ts (not served here)
- __tests__/fixtures/starved-cluster-ts/src/app/config.ts (not served here)
- __tests__/fixtures/starved-cluster-ts/src/index.ts (not served here)
- __tests__/fixtures/starved-cluster-ts/src/pipeline/chain.ts (not served here)
- __tests__/fixtures/starved-cluster-ts/src/pipeline/framing.ts (not served here)
- __tests__/fixtures/starved-cluster-ts/src/pipeline/interceptors.ts (not served here)
- __tests__/fixtures/starved-cluster-ts/src/pipeline/types.ts (not served here)
- __tests__/fixtures/starved-cluster-ts/src/transport/socket.ts (not served here)
- __tests__/fixtures/tail-render-ts/README.md (not served here)
- __tests__/fixtures/tail-render-ts/package.json (not served here)
- __tests__/fixtures/tail-render-ts/src/components/ChatComposer.ts (not served here)
- __tests__/fixtures/tail-render-ts/src/lib/message-builder.ts (not served here)
- __tests__/fixtures/tail-render-ts/src/lib/session-store.ts (not served here)
- __tests__/fixtures/tail-render-ts/src/lib/socket.ts (not served here)
- __tests__/fixtures/tail-render-ts/types/worker-configuration.d.ts (not served here)
- __tests__/flask-url-rules.test.ts (not served here)
- __tests__/flow-directed-exact-names.test.ts (not served here)
- __tests__/flow-js.test.ts (not served here)
- __tests__/flow-library-globals.test.ts (not served here)
- __tests__/flow-named-implementation.test.ts (not served here)
- __tests__/flow-named-longer-route.test.ts (not served here)
- __tests__/foundation-enum-macros.test.ts (not served here)
- __tests__/foundation.test.ts (not served here)
- __tests__/framework-edge-name.test.ts (not served here)
- __tests__/framework-hint-resolver-only.test.ts (not served here)
- __tests__/framework-name-heuristic-scope.test.ts (not served here)
- __tests__/framework-resolve-language.test.ts (not served here)
- __tests__/frameworks-integration.test.ts (not served here)
- __tests__/frameworks.test.ts (not served here)
- __tests__/frontload-hook.test.ts (not served here)
- __tests__/fts5-fallback.test.ts (not served here)
- __tests__/function-ref-package-imports.test.ts (not served here)
- __tests__/function-ref-project-imports.test.ts (not served here)
- __tests__/function-ref.test.ts (not served here)
- __tests__/fuzzy-case-sensitivity.test.ts (not served here)
- __tests__/fuzzy-lexical-reach.test.ts (not served here)
- __tests__/generated-detection.test.ts (not served here)
- __tests__/generated-flag-index.test.ts (not served here)
- __tests__/generic-supertypes.test.ts (not served here)
- __tests__/gin-middleware-chain.test.ts (not served here)
- __tests__/git-changed-untracked-dir.test.ts (not served here)
- __tests__/git-hooks.test.ts (not served here)
- __tests__/git-ignored-dirs-scope.test.ts (not served here)
- __tests__/git-index-currency.test.ts (not served here)
- __tests__/git-status-subdir-project.test.ts (not served here)
- __tests__/gitignore-pattern-parity.test.ts (not served here)
- __tests__/global-setup-dist.test.ts (not served here)
- __tests__/global-setup-dist.ts (not served here)
- __tests__/global-setup-home-sandbox.ts (not served here)
- __tests__/glyphs.test.ts (not served here)
- __tests__/go-asserted-locals.test.ts (not served here)
- __tests__/go-bare-call-no-method.test.ts (not served here)
- __tests__/go-build-constraint-twins.test.ts (not served here)
- __tests__/go-chained-receivers.test.ts (not served here)
- __tests__/go-conversion-references.test.ts (not served here)
- __tests__/go-declared-receiver.test.ts (not served here)
- __tests__/go-defined-type-refs.test.ts (not served here)
- __tests__/go-detached-doc-comments.test.ts (not served here)
- __tests__/go-doc-directives.test.ts (not served here)
- __tests__/go-dot-import-field-type.test.ts (not served here)
- __tests__/go-embedding-no-override.test.ts (not served here)
- __tests__/go-external-package-qualifier.test.ts (not served here)
- __tests__/go-external-test-package.test.ts (not served here)
- __tests__/go-framework-own-package.test.ts (not served here)
- __tests__/go-func-field-dispatch.test.ts (not served here)
- __tests__/go-grouped-const-docs.test.ts (not served here)
- __tests__/go-implements-arity.test.ts (not served here)
- __tests__/go-implements-defined-types.test.ts (not served here)
- __tests__/go-implements-embedding.test.ts (not served here)
- __tests__/go-implements-stdlib.test.ts (not served here)
- __tests__/go-implements-types.test.ts (not served here)
- __tests__/go-implements-unexported.test.ts (not served here)
- __tests__/go-import-alias-precedence.test.ts (not served here)
- codegraph-kernel/grammars/dart/LICENSE
- codegraph-kernel/grammars/lua/LICENSE
- codegraph-kernel/grammars/scala/LICENSE
- codegraph-kernel/grammars/swift/LICENSE
- docs/AGENTS.md
- docs/README.md
- docs/SEARCH_QUALITY_LOOP.md
- docs/viewer-launch-changelog.md
Advantages
- Reduces token usage and tool calls by providing surgical, pre-indexed code context. evidence: README.md
- Operates 100% locally with no external dependencies or cloud data transmission. evidence: README.md
- Maintains an up-to-date index automatically through file-system watching. evidence: README.md
Limitations
- Requires an initial indexing step per project which may take time for very large codebases. evidence: README.md
- Increases the persistent context window footprint in long-running agent sessions. evidence: README.md
Security
Risk level: High risk
This brain runs
Agent instructions that run or fetch something (75)
.claude/skills/add-lang/SKILL.md:Run from the codegraph repo root..claude/skills/add-lang/SKILL.md:node scripts/add-lang/check-grammar.mjs <lang> path/to/valid-sample.<ext>.claude/skills/add-lang/SKILL.md:npm pack @tree-sitter-grammars/tree-sitter-<lang> # often ships a prebuilt *.wasm.claude/skills/add-lang/SKILL.md:then add the token to the vendored branch in Step 4 and re-run check-grammar on the vendored path until it PASSes..claude/skills/add-lang/SKILL.md:or `curl` a raw file from a known repo), then:· uses the network.claude/skills/add-lang/SKILL.md:node scripts/add-lang/dump-ast.mjs <lang> path/to/sample.<ext>.claude/skills/add-lang/SKILL.md:node scripts/add-lang/dump-ast.mjs src/extraction/wasm/tree-sitter-<lang>.wasm sample.<ext>.claude/skills/add-lang/SKILL.md:npm run build # tsc + copy-assets (copies any vendored *.wasm into dist/).claude/skills/add-lang/SKILL.md:node scripts/add-lang/verify-extraction.mjs <sample-repo> <lang>.claude/skills/add-lang/SKILL.md:On FAIL or a thin WARN: re-run `dump-ast.mjs` on a richer file, fix the mappings in `<lang>.ts`, `npm run build`, re-index, re-verify..claude/skills/add-lang/SKILL.md:npx vitest run __tests__/extraction.test.ts.claude/skills/add-lang/SKILL.md:npm run build && ./scripts/local-install.sh.claude/skills/add-lang/SKILL.md:`bench.sh` clones (shared `/tmp/codegraph-corpus`), wipes + indexes, runs `verify-extraction.mjs`, then the with/without retrieval A/B via `scripts/agent-eval/run-all.sh` (skips the paid A/B if extraction is broken)..claude/skills/add-lang/SKILL.md:Read each `parse-run.mjs` summary printed by `run-all.sh`: tool calls, file `Read`s, Grep/Bash, codegraph-tool calls, duration, and **cost** — for both the `with` and `without` arms..claude/skills/add-lang/SKILL.md:After the loop, restore the dev link if needed: `./scripts/local-install.sh`..claude/skills/add-lang/SKILL.md:Any new `*.wasm` must live in `src/extraction/wasm/` — `copy-assets` (run by `npm run build`) ships it;.claude/skills/agent-eval/SKILL.md:Run from the codegraph repo root..claude/skills/agent-eval/SKILL.md:- [ ] 5. Run audit.sh in the background.claude/skills/agent-eval/SKILL.md:**Step 4 — harness.** Ask with `AskUserQuestion` which harness to run, and map the answer to a MODE token:.claude/skills/agent-eval/SKILL.md:**Step 5 — run.** Launch in the background (sets the version, clones if missing, wipes + re-indexes, runs the chosen arms — several minutes):.claude/skills/agent-eval/SKILL.md:Headless (`parse-run.mjs`): total tool calls, file `Read`s, Grep/Bash, codegraph-tool calls, duration, **total cost**..claude/skills/agent-eval/SKILL.md:The index is rebuilt every run (`audit.sh` wipes `.codegraph`) — different versions extract differently, so an index must be served by the same binary that built it..claude/skills/agent-eval/SKILL.md:`audit.sh` temporarily mutates the global `codegraph` install for the test, then restores your dev link via `local-install.sh`..cursor/rules/codegraph.mdc:Indexing is the user's decision: tell them they can run `codegraph init` to build the index, but don't run it yourself.AGENTS.md:npm run build # tsc + copy schema.sql and *.wasm + build the viewer into dist/; chmods dist/bin/codegraph.jsAGENTS.md:npm run build:lib # the viewer's components as @colbymchenry/codegraph-ui (ui/dist) — NOT part of `build`AGENTS.md:npm run dev # tsc --watchAGENTS.md:npm run clean # rm -rf distAGENTS.md:npm test # vitest run (all)AGENTS.md:npm run test:watchAGENTS.md:npm run test:eval # only __tests__/evaluation/AGENTS.md:npm run eval # build then run __tests__/evaluation/runner.ts via tsxAGENTS.md:npm run cli # build then run the local dist binaryAGENTS.md:npx vitest run __tests__/installer-targets.test.tsAGENTS.md:npx vitest run __tests__/extraction.test.ts -t "TypeScript"AGENTS.md:`npm run build:lib` is separate and does NOT run as part of `npm run build`: it compiles the same `ui/src` tree a second way, with `svelte-package`, into `ui/dist` — the `@colbymchenry/codegraph-ui` component library the Pro app imports (task CG-61).AGENTS.md:Tests run as **two Vitest projects** (`test.projects` in `vitest.config.mts`): `engine` (node) and `ui` (jsdom, the Svelte plugin, `resolve.conditions: ['browser']`) for the single `__tests__/ui-package.test.ts`.AGENTS.md:`npm test` still runs both.AGENTS.md:That range is what users run.AGENTS.md:Working in this repo needs Node 22.12 or newer: `devEngines` makes `npm ci` and `npm run` stop on anything older, for Vite 7 and Vitest 4.AGENTS.md:Subcommands: `install`, `uninstall`, `init`, `uninit`, `index`, `sync`, `status`, `unlock`, `query`, `explore`, `context`, `node`, `files`, `callers`, `callees`, `impact`, `affected`, `cycles`, `daemon`, `telemetry`, `upgrade`, `version`.AGENTS.md:`src/installer/` is the entry point for `codegraph install` (and the bare `codegraph`/`npx @colbymchenry/codegraph` invocation).AGENTS.md:An entry already in the file is the user's: agents write switches into it and users pin a `command` or `cwd`, so a re-install or `--refresh` only fills in missing keys.AGENTS.md:Edits are surgical via `jsonc-parser` so user comments and formatting survive install/re-install/uninstall round-trips.AGENTS.md:a pre-#1698 `mcp.codegraph` + `enabled` entry is migrated on re-install and removed by uninstall.AGENTS.md:their `install` only strips one a previous install left behind.AGENTS.md:All installer changes need matching coverage in `__tests__/installer-targets.test.ts` — there are ~47 parameterized contract tests covering install idempotency, sibling preservation, uninstall reverses install, byte-equal re-runs returning `unchanged`, and partial-state recovery for Codex.AGENTS.md:Every expected/recoverable condition — project not indexed, symbol not found, file not in the index — returns a **SUCCESS-shaped response carrying the guidance** (`NotIndexedError` → `textResult`, see `ToolHandler.execute`'s catch).AGENTS.md:deterministic probes (`scripts/agent-eval/probe-*.mjs`) then agent A/B (`scripts/agent-eval/run-all.sh` / `ab-new-vs-baseline.sh`).AGENTS.md:run via `npm run eval` (builds first).AGENTS.md:Not part of `npm test`.AGENTS.md:The dev machine — and the default `npm test` target — is **macOS**, so local runs cover the macOS path.AGENTS.md:Build a throwaway image from the repo and run the suite inside it:AGENTS.md:`RUN npm ci && npm run build`.AGENTS.md:Run with **`docker run --rm --init`**.AGENTS.md:Connect / run from the Mac host: `ssh <user>@<guest_ip> "..."`.· uses the networkAGENTS.md:ssh [email protected] "powershell -NoProfile -ExecutionPolicy Bypass -Command -" <<'PS'· uses the networkAGENTS.md:Clone fresh into a **Windows-local** path (`C:\dev\codegraph`) and `npm ci` there — never run npm against the shared Mac repo, since `esbuild`/`rollup` ship platform-specific binaries.AGENTS.md:Fetch a contributor PR head straight from their fork to dodge `pull/<n>/head` lag: `git fetch <fork-url> <branch>` then `git checkout -f FETCH_HEAD`.· uses the networkAGENTS.md:**Keep:** language & framework names (Go, Spring, NestJS, …), things a user types or sets (`codegraph install`, `codegraph_explore`, the `CODEGRAPH_*` env vars), agent / IDE names (Claude Code, Cursor, opencode, Kiro, …), and a brief `Thanks @user` when a contributor is credited.AGENTS.md:Publishing manually is **wrong** now — a plain `npm publish` ships the root package (non-bundled), which breaks anyone on Node < 22.5.AGENTS.md:When the maintainer DOES bump the version, the only edit strictly required is to `package.json` — the workflow's "Sync package-lock.json" step detects a mismatch between `package.json` and `package-lock.json`, runs `npm install --package-lock-only --ignore-scripts` to rewrite the lock …[+120 chars]AGENTS.md:Once `package.json` is at the target version on `main`, trigger **Actions → Release → Run workflow** (on `main`).AGENTS.md:Any change to `src/installer/` (especially `targets/`) needs corresponding test coverage and a CHANGELOG entry — installer regressions break every new install silently.AGENTS.md:The **last main commit** — `git log --first-parent main -1 --format='%ai %h %s'`.docs/AGENTS.md:**Agent A/B** (`scripts/agent-eval/run-all.sh <repo> "<Q>"`): with vs without codegraph, **≥2 runs/arm** (run-to-run variance is large — never conclude from n=1).docs/AGENTS.md:**Every run also reports three feedback metrics** — residual context occupancy, explore sufficiency (what the agent did NEXT after each explore), and allocation efficiency (share of returned bytes the answer cited) — under each run, plus a side-by-side arm table (`compare-arms.mjs`).docs/AGENTS.md:Check the contamination row before believing any number: `CLI calls that RETURNED output` > 0 invalidates the run (in a new-vs-baseline A/B it silently drops calls from all three metrics, since a CLI explore is not a tool call).docs/AGENTS.md:(b) **Sonnet is the deliberate floor model** — codegraph's real users attach it to whatever agent they already run (Cursor Composer, Gemini, etc.), so we validate on a "dumber" model on purpose: a stronger model's tool-use covers up the salience/sufficiency problems a weaker one exposes.docs/AGENTS.md:**MCP attach is a startup-latency issue, not a hard block.** On a multi-step task the agent dives into Read/grep before codegraph finishes its ~2-3s startup (worse when the eval is itself run nested inside a Claude session, under CPU contention), so it runs with no codegraph.docs/AGENTS.md:judge by actual codegraph usage in `parse-run.mjs`'s `by type`.docs/AGENTS.md:To isolate a change — **new-build vs baseline-build, both codegraph-on** (vs run-all.sh's with-vs-without) — use `scripts/agent-eval/ab-new-vs-baseline.sh <indexed-repo> "<task>" [baseline-ref]` (it bakes in the pre-warm).docs/AGENTS.md:After steering flow questions to `codegraph_trace` first: **best run 0 Read / 0 Grep / 3 codegraph / 51s**;docs/AGENTS.md:Run-to-run variance is still real;docs/AGENTS.md:node count stable at 9,289;
MCP servers (1)
README.md(codegraph):codegraph serve --mcp
Install scripts (5)
README.md:curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh· uses the networkREADME.md:irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iex· uses the networkREADME.md:- **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 …[+42 chars]· uses the networkinstall.ps1:pwsh install.ps1· uses the networkinstall.sh:sh install.sh· uses the network
Binaries (29)
src/extraction/wasm/tree-sitter-arkts.wasm:ships native binariessrc/extraction/wasm/tree-sitter-c.wasm:ships native binariessrc/extraction/wasm/tree-sitter-c_sharp.wasm:ships native binariessrc/extraction/wasm/tree-sitter-cfml.wasm:ships native binariessrc/extraction/wasm/tree-sitter-cfquery.wasm:ships native binariessrc/extraction/wasm/tree-sitter-cfscript.wasm:ships native binariessrc/extraction/wasm/tree-sitter-cobol.wasm:ships native binariessrc/extraction/wasm/tree-sitter-cpp.wasm:ships native binariessrc/extraction/wasm/tree-sitter-dart.wasm:ships native binariessrc/extraction/wasm/tree-sitter-erlang.wasm:ships native binariessrc/extraction/wasm/tree-sitter-go.wasm:ships native binariessrc/extraction/wasm/tree-sitter-java.wasm:ships native binariessrc/extraction/wasm/tree-sitter-javascript.wasm:ships native binariessrc/extraction/wasm/tree-sitter-kotlin.wasm:ships native binariessrc/extraction/wasm/tree-sitter-lua.wasm:ships native binariessrc/extraction/wasm/tree-sitter-luau.wasm:ships native binariessrc/extraction/wasm/tree-sitter-nix.wasm:ships native binariessrc/extraction/wasm/tree-sitter-pascal.wasm:ships native binariessrc/extraction/wasm/tree-sitter-php.wasm:ships native binariessrc/extraction/wasm/tree-sitter-python.wasm:ships native binariessrc/extraction/wasm/tree-sitter-r.wasm:ships native binariessrc/extraction/wasm/tree-sitter-ruby.wasm:ships native binariessrc/extraction/wasm/tree-sitter-rust.wasm:ships native binariessrc/extraction/wasm/tree-sitter-scala.wasm:ships native binariessrc/extraction/wasm/tree-sitter-swift.wasm:ships native binariessrc/extraction/wasm/tree-sitter-terraform.wasm:ships native binariessrc/extraction/wasm/tree-sitter-tsx.wasm:ships native binariessrc/extraction/wasm/tree-sitter-typescript.wasm:ships native binariessrc/extraction/wasm/tree-sitter-vbnet.wasm:ships native binaries
- High risk: runs-install-script-remote-exec (install.ps1)
- High risk: remote-exec (install.ps1:72)
- Medium risk: runs-instruction-instruction-network (.claude/skills/add-lang/SKILL.md:82)
- Medium risk: runs-instruction-instruction-network (AGENTS.md:209)
- Medium risk: runs-instruction-instruction-network (AGENTS.md:211)
- Medium risk: runs-instruction-instruction-network (AGENTS.md:218)
- Medium risk: runs-install-script-remote-exec (README.md:91)
- Medium risk: runs-install-script-remote-exec (README.md:94)
- Medium risk: runs-install-script-remote-exec (README.md:915)
- Medium risk: remote-exec-pipe (install.ps1:72)
- Medium risk: network-variable-host (install.ps1:146)
- Medium risk: runs-install-script-network-variable-host (install.sh)
- Medium risk: network-variable-host (install.sh:76)
- Low risk: scripts-present (__tests__/evaluation/runner.ts)
- Low risk: scripts-present (install.ps1)
- Low risk: scripts-present (install.sh)
- Low risk: scripts-present (scripts/add-lang/check-grammar.mjs)
- Low risk: scripts-present (scripts/add-lang/dump-ast.mjs)
- Low risk: scripts-present (scripts/add-lang/verify-extraction.mjs)
- Low risk: scripts-present (scripts/check-ui-build.mjs)
Attribution and licence
- First committed by
colbymchenry
- Publisher
- Colby Mchenry (Community)
- Source
- colbymchenry/codegraph · commit f72c9d2
- Licence
- MIT License (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- colbymchenry, JosefAschauer, inth3shadows, maxmilian, GeneralClaw
AutoGineer is not affiliated with or endorsed by colbymchenry.
Install from source
493 of its files are not served here, so there is no ZIP. colbymchenry/codegraph at f72c9d2