行业动态
GitHub ·
@colbymchenry
CodeGraph v1.6.2 发布:跨语言符号解析与路由识别修复
CodeGraph 发布 v1.6.2,重点修复跨语言名称解析:调用、导入和类型现在按语言作用域(import、package、namespace、所在类)解析,减少同名符号误链接,覆盖 TypeScript/JavaScript、Python、Java、Kotlin、Scala、C#、VB.NET、Swift、Objective-C、Go、Rust、C/C++、PHP、Ruby、Dart、Lua、R 等。重载、super 调用和递归解析得到修正。新增 Angular(含 Nx 库)、Vue Router、Rails 嵌套路由、Flask add_url_rule、ASP.NET FastEndpoints、Play、Vapor、Expo Router 等路由识别,并扩展 Vue Options API、Java/Kotlin 枚举常量、Flow 类型 JS、Kotlin 中缀调用、React Native 原生视图等索引范围。Windows 端修复控制台弹窗和索引/关闭时的偶发崩溃,后台服务在 MCP 客户端重连、会话恢复和空闲项目释放方面更稳定。官方提示升级后需重新索引项目。
AI推荐理由 官方 release notes,信息密度高且具体:跨语言名称解析按 import/package/namespace/类作用域修正错误链接,重载、super、递归解析修复,新增 Angular/Vue Router/Rails/Flask/ASP.NET/Play/Vapor/Expo Router 等路由识别,Windows 崩溃与后台服务稳定性修复,并明确要求升级后重新索引。局限是仅覆盖该工具自身更新,未提供独立验证或性能数据。
72
正文
Official release notes (https://github.com/colbymchenry/codegraph/releases/tag/v1.6.2)
## [1.6.2] - 2026-10-03
### Highlights
- **Far fewer wrong links, in every language.** A call, import or type now resolves the way its language scopes names — through imports, packages, namespaces and the class it is written in — so it stops landing on an unrelated symbol that only shares its name. This covers TypeScript and JavaScript, Python, Java, Kotlin, Scala, C#, VB.NET, Swift, Objective-C, Go, Rust, C and C++, PHP, Ruby, Dart, Lua, R and more, and makes callers, impact and `codegraph_explore` answers more trustworthy.
- **Overloads, `super` and recursion resolve correctly.** A call reaches the overload its arguments fit, a `super` call reaches the parent's method, and a method that calls another overload, or another object's method of the same name, no longer looks like it calls itself.
- **Routes for more frameworks.** Angular (including Nx libraries), Vue Router admin apps, Rails nested routes, Flask's `add_url_rule`, ASP.NET FastEndpoints, Play subprojects, Vapor closure routes and Expo Router API routes are found. NestJS and Laravel routes are named by the path a request actually takes, and a Spring or Laravel test that calls a route by URL counts as covering it.
- **More of your code in the graph.** Vue Options API components, Java and Kotlin enum constants with bodies, Flow-typed JavaScript, Kotlin infix calls, React Native native views and events, Expo modules, tag-based CFML and Delphi `.inc` files are all indexed now.
- **Windows: no flashing windows, no random crashes.** The background server no longer pops up console windows while it works, sporadic access-violation crashes (exit code 3221225477) while indexing or shutting down are fixed, and `codegraph upgrade` works while an agent session is using CodeGraph.
- **A steadier background server.** Newer MCP clients such as Antigravity connect again, Claude Code sees the full text of `codegraph_status`, a session that lost the shared server reconnects by itself, and a project queried through `projectPath` is released after 10 idle minutes.
- **Indexing that finishes.** Large C and C++ projects no longer run out of memory while resolving references, a COBOL file can no longer stall indexing, and `codegraph sync` keeps every caller of a name that is defined more than once.
- **Upgrading:** re-index your projects after this release — most of these fixes are written while indexing.
### New Features
- In Nuxt and Astro projects, a file-routed page is now linked to the component its file defines. An Astro endpoint is linked to the HTTP-verb handlers it exports, like `export const GET`. Before, a page route like Nuxt's `pages/admin.vue` or Astro's `src/pages/about.astro` linked to nothing, so callers, impact and flows stopped at the route.
- React Router links and `navigate(…)` calls written through a route-config object, like bulletproof-react's `paths.app.discussion.getHref(id)`, now reach the route they open. A `` with an arrow-function attribute before its `to`, such as `onMouseEnter={() => …}`, is read too.
- React Router data-router routes are named by their full path: nested `children` paths are joined to their parent's, `path: paths.app.root.path` constants are read, and `lazy: () => import('./routes/x')` routes link to the module's component. A guard wrapper like `` no longer stands in for the page. On bulletproof-react, every route now has its real path and page.
- Vapor routes whose handler is a trailing closure, like `app.get("hello") { req in … }`, WebSocket routes like `app.webSocket("chat") { req, ws in … }`, and `routes.on(.POST, "x", use: handler)` registrations are now found, and a closure route links to what the closure calls, the way an Express inline handler does. Before, only routes with a `use:` handler were read, and a closure route linked to nothing, so callers, impact and flows stopped at it.
- Flow-typed JavaScript files (those with `@flow` in their header comment) are now parsed like TypeScript, so type annotations like `render(): React.Node` no longer cut classes short. This mostly affects React Native code: on React Native's own libraries the graph gained over 8,000 links, and component classes keep their methods. Files without the pragma are unchanged. Re-index after upgrading.
- A link made by a framework or bridge resolver now records which one made it (`metadata.framework`, such as `swift-objc-bridge` or `react-native-bridge`), as the README describes. Before, only synthesized event and view channels were named.
- ASP.NET apps built with FastEndpoints now have their routes: each endpoint class's `Get(…)` / `Post(…)` in `Configure()` becomes a route linked to its own `HandleAsync` / `ExecuteAsync`, including paths kept in a request class's `Route` constant. ardalis/CleanArchitecture went from no routes to 24. Minimal API routes written without a leading slash (`app.MapGet("api/todos", …)`) are now named `/api/todos`.
- Play projects kept in subdirectories are recognized, so each one's `conf/routes` is read. A repository with no Play build at its root, like playframework's samples, went from no routes to over 130.
- Rails routes are now read with their nesting: `namespace` and `scope` add their path and controller module, nested `resources` sit under their parent's `:id`, and `member` / `collection` blocks add their actions. A namespaced route now links to its own module's controller. Routes in a Rails engine's `config/routes.rb` are found too: solidus went from no routes to over 600, and mastodon's route-to-action links nearly tripled.
- Flask routes registered with `add_url_rule(…)` are now found and linked to their view function or class-based view. So are routes registered through a project's own helper that passes a list of paths and a `view_func=`. flaskbb, which registers every view that way, went from no routes to over 100.
- Vue components written with the Options API (`export default { methods: {…}, computed: {…}, watch: {…}, mounted() {…} }`), as every Vue 2 app is, now have their methods, computed properties, watchers and lifecycle hooks in the graph. Each one has its own callers and calls, and a template's `@click="handleLogin"` links to the method it runs. On vue-element-admin that's over 800 new links, where a component's calls used to belong to the whole file.
- React Native events whose name is held in a constant now link native code to the JavaScript that listens for them, like NetInfo's `addListener(PrivateTypes.DEVICE_CONNECTIVITY_EVENT, …)` or a Java `.emit(PROGRESS_EVENT, …)`. The constant is read the way the language scopes it, from the same file, an import or its owning class, so a parameter that happens to share a constant's name is never mistaken for it.
- React Native views declared with `requireNativeComponent('X')`, the older Paper style that react-native-maps and segmented-control use, now link from JavaScript to their native iOS and Android implementations, as Codegen specs already did, including in plain `.js` files. A JSX tag written under a different name than its component, like `` for `import Autocomplete from './autocomplete.vue'`, now links to the component it renders.
- Expo Router API routes (`app/hello+api.ts`) are now endpoints, one per exported method, like `GET /hello`, bound to the function that handles them. They used to show up as a screen named `/hello+api`. In a repository whose root declares Expo Router for an example app, a Next.js app in its own folder, like react-native-true-sheet's `docs/`, no longer gets Expo screens made from its files.
- Calls into an Expo module now reach the module's native functions even when the JavaScript names the module something else, like expo-camera's `CameraManager` for `requireNativeModule('ExpoCamera')`. Both the iOS and the Android implementations are linked. expo-camera's calls used to link back to the same-named method making the call, so a method looked like it called itself.
- Angular apps split across Nx libraries, like angular-spotify, now have their routes and navigation. A lazily loaded route written `async () => (await import('@app/home')).HomeModule` is followed through the library's `index.ts` to the module it re-exports, and a `routerLink` in one library now reaches a screen declared in another. Route paths built from a class constant (`RouterUtil.Configuration.Lyrics`, `` `issue/:${ProjectConst.IssueId}` ``) or an enum are now read. A redirect in a routes file that only lazy-loads others now counts, and `router.navigate(['project', 'issue', id])` without `relativeTo` is read from the root, as Angular does. Re-index Angular projects after upgrading.
- React Router apps now show navigation written as React Router v5's `` and through a styled link, like react-boilerplate's `HeaderLink = styled(Link)` used as ``. Apps built this way had routes but no links between their screens.
- SvelteKit routes are now named by the address a browser asks for. A `(group)` folder like `(app)` or `(marketing)` is no longer part of a route's path, and a parameter with a matcher, like `[id=integer]`, is just `:id`. So `goto('/blocks')` and `` now reach a page that lives in `src/routes/(app)/blocks/`, where before they reached nothing and the app's screens showed no navigation. Re-index SvelteKit projects after upgrading.
- Vue Router apps built like vue-element-admin, vue-admin-template or vben now have their routes and screens. Routes declared in a named table (`export const constantRoutes = [...]`, `const routes: RouteRecordRaw[] = [...]`), in per-module route files, or through `new Router(...)` are now read. Child routes are joined onto their parent's path, and the parent's component is the layout around them. A lazily loaded view (`() => import('@/views/dashboard/index')`) is bound to the file it names, and `this.$router.push(...)` counts as navigation. Nuxt's file-based routes now come only from a Nuxt app, so a plain Vue app's `pages/` folder no longer turns into made-up screens, and a Nuxt app at the root of its repository now gets its routes. Re-index Vue projects after upgrading.
- NestJS routes are now named by the path a request takes: the global prefix from `app.setGlobalPrefix('api')` is applied, along with its `exclude` list, and so is URI versioning from `app.enableVersioning(...)`, with `@Version`, `VERSION_NEUTRAL` and a controller's own `version` taken into account. A route that used to appear as `GET /user` is now `GET /api/v1/user`, so a front end's `this.http.get('/api/v1/user')` or `fetch` call connects to the controller method that serves it. Re-index NestJS projects after upgrading.
- Laravel routes are now named by the path a request takes: a leading `/` is added where the routes file leaves it out, `Route::prefix()` and `Route::group(['prefix' => …])` groups are applied, and routes in `routes/api.php` carry the `/api` prefix Laravel serves them under, read from your `RouteServiceProvider`, `bootstrap/app.php` or any file that mounts a routes file. A front-end `fetch('/api/…')` now connects to the Laravel route that serves it. Re-index Laravel projects after upgrading.
- Controllers that Spring or Laravel tests exercise by URL now count as tested. That covers MockMvc's `perform(post("/owners/new"))`, WebTestClient, TestRestTemplate, RestAssured, Laravel's `$this->postJson('api/me')`, Pest's `get('/about')`, and a project's own request helpers built on them. `codegraph_explore` now names the test suite that reaches such an endpoint, where before every one of them looked untested. Re-index Spring and Laravel projects after upgrading.
- In an Angular app, a method a template calls, like `(click)="toggleFavorite()"` or `(ngSubmit)="submitForm()"`, is now linked from its component. These methods used to show no callers at all, so impact and callers questions stopped at them, and dead-code checks could list them as unused. Re-index Angular projects after upgrading.
- Angular apps now have routes and navigation in the graph. Each screen in a `Routes` array is a route named by its full path, including children, lazily loaded `loadChildren` files and NgModules, paths written as route constants or `$localize` strings, and redirects. Each route is linked to its component. `router.navigate([...])`, `navigateByUrl`, a guard's `createUrlTree` and every `routerLink` in a component's template link to the screen they open, and a template's child components (``) are linked to the component that renders them. Questions like "where does this button go" and "what renders this component" now have answers in `codegraph_explore`. Re-index Angular projects after upgrading.
- Delphi and Free Pascal include files (`.inc`) are now indexed as Pascal. Before, they were read as PHP and came up empty. A `.inc` file with a ``, ``/``, ``, `` and `#…#` expressions. Before, only `` and `` code was read, so callers and impact found almost nothing in tag-based components. Functions wrapped in tags like `` or `` are now indexed too, and a `` is indexed as an interface that `implements` links to. Re-index CFML projects after upgrading. Thanks @HarryMuc for the report. (#2091)
- Java enum constants and Kotlin enum entries with a body of their own now have their methods in the graph. Examples are `PLUS { int apply(…) { … } }` and `NewBuffer { override fun pipe() … }`. Before, those methods were missing and every call inside them was dropped. jsoup's HTML tokenizer and tree builder are written this way, so over 2,000 of their calls were invisible. Re-index to pick this up.
- Kotlin infix calls, like `Users.id eq id1` or koin's `single { … } bind MyApi::class`, are now recorded as calls to the infix function. Before, they had no callers at all. On Exposed, `eq` now shows over a thousand callers. Bit operations on numbers (`x and 0xff`, `h shr 8`) are left to Kotlin's own operators, even where the project defines a same-named extension. Re-index after upgrading.
### Fixes
#### Windows
- On Windows, terminal windows no longer flash open and closed while CodeGraph runs in the background. Since 1.6.1, a background MCP server popped up a console window (a full Windows Terminal window when that is the default terminal) several times when it started and again every time it re-synced a changed file. All of CodeGraph's git calls now run hidden. Thanks @Suharaz, @23q3, @A-Van-Gestel, @HarryMuc and @MzaGuille. (#2094, #2096, #2312)
- On Windows, a project opened with a different drive-letter or folder-name case, like `d:\work\app` and `D:\Work\App`, now joins the CodeGraph background server that is already running for it. Before, each spelling started a server of its own that exited at once, so the session quietly served the graph by itself with no shared file watching or auto-sync, and `codegraph list` showed the project twice. Thanks @greatjackzhou. (#2278)
- On Windows, `codegraph upgrade` no longer breaks the install while an agent session is using CodeGraph. It used to stop partway and leave CodeGraph unable to start; it now swaps the new files in with CodeGraph running and puts the previous version back if anything fails, and re-running the PowerShell installer works the same way. If an earlier upgrade already broke your install, re-run `irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iex` to repair it. Thanks @tippmar-nr for the report. (#2185)
- On Windows, CodeGraph no longer sometimes crashes with exit code 3221225477 (an access violation) on a busy machine: right after parsing in `codegraph init`, `codegraph index` and background syncs, or as the background server shuts down. Stopping one of its helper threads (the ones that parse files, resolve references, write the index and count changes for `codegraph_status`) while it was still starting up, or before it had finished cleaning up its memory, took the whole process down. Threads now finish starting and clean up before they exit.
#### The background server, sessions and the CLI
- The Claude Code prompt hook no longer runs on the messages Claude Code uses to hand a subagent's report back to the main session. Before, such a long report could keep the hook busy past Claude Code's 30-second hook timeout and inject context unrelated to what you asked. Thanks @danusha2345, and @tippmar-nr for the report. (#2184)
- Newer MCP clients such as Antigravity 2.5 connect again: the server now answers their `server/discover` probe right away with "method not found", so they go straight on to the regular handshake instead of waiting on a reply that could take seconds or never come. Thanks @danusha2345, and @samem26 for the report. (#2084)
- A CodeGraph session that queried another project through `projectPath` no longer keeps that project locked for as long as it runs: after 10 minutes without a query it lets the project go, so the project's own session and `codegraph index` can take over again (tune with `CODEGRAPH_PROJECT_IDLE_TIMEOUT_MS`, `0` keeps it open). Thanks @danusha2345, and @bompus for the report. (#2087)
- Claude Code now shows the model the full text of `codegraph_status` and of explore's stale-index refusal. Both results also carried `structuredContent`, and Claude Code shows a result's `structuredContent` in place of its text, so the model saw only a freshness JSON object: no refusal message, no retry guidance and no status report. Both results are now text only. Thanks @bompus. (#2088)
- When an agent asks CodeGraph about a separate git repository nested inside an indexed project, one the project's index leaves out (for example because the parent's `.gitignore` excludes it), it now gets the usual "isn't indexed" guidance instead of answers from the parent project's code. Nested repositories the parent does index, such as submodules, work as before. Thanks @wstczyw for the report. (#2110)
- An agent session that lost its connection to CodeGraph's shared background server, or couldn't reach it at startup, no longer stops that server from running for the rest of the session. It reconnects on its own once the server can start, so other sessions on the same project get auto-sync back instead of running read-only. Thanks @ijbranch for the report. (#2277)
- `codegraph index` no longer gives up with "Could not verify that the active CodeGraph daemon has stopped" while the background server is still finishing its shutdown, and `codegraph daemon` no longer reports such a server as one it could not stop; both now wait for it to exit, for up to about 20 seconds. An agent session that is serving CodeGraph by itself, because the background server was unavailable, now also waits for that work to stop before it exits instead of exiting partway through, which could crash on Windows. Thanks @bompus. (#2311)
- Anonymous usage telemetry now sends one daily count per tool or command, as documented, instead of one per codegraph process. Before, every MCP server launch, CLI command and prompt hook queued its own entry, so a busy machine uploaded thousands of copies of the same count each day. If you have telemetry turned off, nothing changes.
#### Indexing and sync
- A COBOL file whose last line ends inside the sequence area (columns 1-6), such as a closing period indented only four spaces, no longer stalls indexing for over a minute and then ends up in the index with no symbols.
- Editing a file that defines the same name more than once, like two classes that each have an `execute` method or a method's overloads, no longer moves every caller from other files onto one of them during `codegraph sync`. A sync interrupted partway through a file also no longer loses those callers until a full re-index. Thanks @ijbranch for the report. (#2276)
- Indexing a large C or C++ project no longer runs out of memory partway through "Resolving refs". Headers whose include guard is written as `#define X_H 1`, as in OpenSceneGraph and osgEarth, or that are included under a build flag codegraph cannot know, used to be re-read on every include path, which grows exponentially with the depth of the include tree. Each is now read once per include state, and a hard limit stops the check on any include tree that is still too large. Thanks @danusha2345, and @coolhitmanleon for the report. (#2127)
- On a busy machine, indexing or syncing a small project no longer starts extra background threads for resolving references that it can't use. Under heavy load the slower pace made a ten-file project look big enough to need them, which added seconds to the run and held extra memory.
#### Across languages
- A type that extends another type of the same name now links to that other type instead of to itself. When the source spells out the qualifier, that qualifier picks between same-named candidates. Before, cats' `trait BigDecimalInstances extends cats.kernel.instances.BigDecimalInstances` and every `trait AllOps … with Functor.AllOps[…]` pointed back at the declaring trait, and Newtonsoft.Json's `JsonConverter : JsonConverter` extended itself.
- Framework name conventions for Django, FastAPI, Flask, ASP.NET, Gin, SwiftUI and Vapor now only pick a class the reference can see. Examples of these conventions are "a `…View` is a view", "a `…Service` is a service" and "a capitalized name is a model". The pick starts from the reference's own file and then its package, and never takes a class declared inside some function or nested in another file's class. Before, Django REST framework's tests linked each file's own `MockView` and `Serializer` to another file's, and netbox's tests linked `TestForm()` to a form declared inside a different test function.
- A method that calls a same-named method on another expression's result is no longer linked to itself in any language. Examples are Scala's `requestToArmeria(request).execute()` inside `execute()`, Rust's `self.0.into_route(state)` inside `into_route()`, and Kotlin's `this@Buffer.write(…)` from an inner object. A value whose initializer chain calls a same-named method, like sttp's `val response = basicRequest.get(…).response(…)`, no longer links to itself either.
- A method that hands its call on to another object is no longer linked to itself. In TypeScript and JavaScript, a call through `this.` or `window.` counts as recursion only when the field is declared as the method's own class. A guess from a receiver's name alone never lands on the calling method. Before, BookStack's `toggle()` doing `this.container.classList.toggle('open')`, `listen()` doing `window.$events.listen(…)`, and `FileStorage::delete` doing `$storage->delete($path)` each pointed at themselves.
- A function or name passed as a value now resolves to what is in scope where it's written. A function nested inside another function is only reachable from inside it. In Python, a parameter or local of the same name is that local. A pytest fixture is a test's parameter only in its own module or under its `conftest.py`. Before, httpx's `self._build_auth(auth)` linked to an `auth` a test defines inside another function, and `auth_flow(self, request)` handing `request` on linked to the package's `request()` function.
- In Java, C#, Kotlin, Swift, Scala, Dart and VB.NET, a call now reaches the overload whose parameters fit its arguments, not whichever same-named overload was indexed first. For example, `HashCodeBuilder.reflectionHashCode(this)` now reaches the one-argument overload with varargs, not a three-parameter one. Each overload's callers are now its own.
- A method that calls another overload of itself now links to that overload rather than to itself. An example is `toInstant(instant)` returning `toInstant(instant,
Repository README (current repository documentation, not release changes)
# CodeGraph
Already installed? Run `codegraph upgrade`
Follow [@getcodegraph](https://x.com/getcodegraph) on X for updates.
### Supercharge Claude Code, Cursor, Codex, OpenCode, Hermes Agent, Gemini, Antigravity, Kiro, and GitHub Copilot with Semantic Code Intelligence
**The fastest complete code graph · surgical context · built for how agents actually work · 100% local**
**Kernel powered by Rust**
### [Documentation & Website →](https://colbymchenry.github.io/codegraph/)
[](https://www.npmjs.com/package/@colbymchenry/codegraph)
[](https://opensource.org/licenses/MIT)
[](https://nodejs.org/)
[](#verified-releases)
[](#verified-releases)
[](#supported-platforms)
[](#supported-platforms)
[](#supported-platforms)
[](#supported-agents)
[](#supported-agents)
[](#supported-agents)
[](#supported-agents)
[](#supported-agents)
[](#supported-agents)
[](#supported-agents)
[](#supported-agents)
[](#supported-agents)
**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.
Get early beta access to the hosted product · getcodegraph.com
## Contents
- [Get Started](#get-started)
- [Language Support](#language-support)
- [Why CodeGraph?](#why-codegraph)
- [Key Features](#key-features)
- [Framework-aware Routes](#framework-aware-routes)
- [Mixed iOS / React Native / Expo bridging](#mixed-ios--react-native--expo-bridging)
- [Quick Start](#quick-start)
- [How It Works](#how-it-works)
- [CLI Reference](#cli-reference)
- [MCP Tools](#mcp-tools)
- [Library Usage](#library-usage)
- [Configuration](#configuration)
- [Telemetry](#telemetry)
- [Verified releases](#verified-releases)
- [Supported Platforms](#supported-platforms)
- [Supported Agents](#supported-agents)
- [Supported Languages](#supported-languages)
- [Measured cross-file coverage](#measured-cross-file-coverage)
- [Troubleshooting](#troubleshooting)
- [License](#license)
## Get Started
### 1. Install the CLI
**No Node.js required** — one command grabs the right build for your OS:
```bash
# 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
```
Already have Node? Use npm instead (works on any version)
```bash
npm i -g @colbymchenry/codegraph
```
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.
**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 ` to pin one.
### 2. Wire up your agent(s)
In a **new terminal**, run the installer to connect CodeGraph to the agents you use:
```bash
codegraph install
```
Detects and auto-configures Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity IDE, Kiro, and GitHub Copilot (VS Code, Copilot CLI, JetBrains IDEs) — 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.)
### 3. Initialize each project
```bash
cd your-project
codegraph init
```
`codegraph init` creates the local `.codegraph/` directory and builds the full graph in the same step — one command, done.

### 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:
```bash
codegraph uninstall
```
Pass `--keep-cli` to remove only the agent configurations and keep the CLI installed.
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.
---
## Language Support
Every language below gets the same treatment — full structural extraction and cross-file resolution into one graph, no per-language setup:
Per-language details — extensions, frameworks, and what exactly gets extracted — in [Supported Languages](#supported-languages).
---
## 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.
> **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`](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 |
¹ 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.
Per-repo breakdown — WITH vs WITHOUT (median of 4)
| 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 |
Full benchmark details
**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.
---
## 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,