github colbymchenry/codegraph v1.6.0

3 hours ago

[1.6.0] - 2026-08-26

Highlights

  • GitHub Copilot is now supportedcodegraph install sets it up in VS Code, the Copilot CLI, and JetBrains IDEs, next to the agents it already knew.
  • Set up in one commandcodegraph install --yes --init wires up your agents and indexes your project with no prompts, ideal for a fresh container or CI.
  • Better answers for your agentcodegraph_explore no longer repeats code it already showed you, always brings back the files and symbols you asked for by name, and spends its space on the code that actually answers the question rather than look-alikes, generated files, and type shims.
  • Your graph stays right as you keep coding — a long-running index no longer drifts from a fresh one, and edits to codegraph.json (such as exclude) apply immediately without a restart.
  • No more silent crashes or hangs — deeply nested C/C++ files, Swift Vapor projects, and large sync batches that used to kill or stall indexing now finish cleanly.
  • A disk-space leak is fixed — a force-killed session could leave the database's write-ahead log behind to grow without bound (tens of gigabytes was reported); the leftover log is now folded back into the index and trimmed automatically the next time the project opens. The index itself has no size limit.
  • Works from a workspace or monorepo root — the MCP server finds your indexed project when launched from a folder above it, and says so clearly when it can't find one.
  • More accurate code graphs for TypeScript, Rust, Erlang, C/C++, and Python projects — see the full list below.
  • Also new: per-project Codex setup (codegraph install --location=local), a deprioritize setting to keep helper folders from outranking your real code, the codegraph context command, and usage stats that now stay entirely on CodeGraph's own servers.

After upgrading, run codegraph index once in each project so your existing graph picks up these fixes — codegraph status reminds you when it's needed.

New Features

  • GitHub Copilot is now a supported agent: codegraph install can configure Copilot Chat in VS Code (copilot-vscode), the GitHub Copilot CLI (copilot-cli), and the Copilot plugin in JetBrains IDEs (copilot-jetbrains). Installed Copilot surfaces are auto-detected like every other agent, existing MCP server entries in their config files are preserved, and codegraph uninstall reverses the setup cleanly. Restart VS Code or your JetBrains IDE after installing so Copilot picks up the server.

  • codegraph install --init wires up your agents and builds the current project's index in one command, and codegraph init --yes runs without any prompts — so a fresh container or CI job can bootstrap CodeGraph with a single non-interactive line (codegraph install --yes --init). The installer still never indexes anything unless you ask for it with the flag, and the usual safety refusal for a home directory or filesystem root applies. (#1578)

  • Codex CLI can now be set up per project instead of only user-wide: codegraph install --location=local writes ./.codex/config.toml and the CodeGraph block in your project's AGENTS.md, so CodeGraph is wired into that repo only rather than every Codex session on the machine. codegraph uninstall --location=local reverses it, and the global install is untouched either way. Codex only applies a project's config once you've marked the project trusted, so the installer says so after a local install. Thanks @maxmilian. (#1531)

  • A new deprioritize setting in codegraph.json keeps the paths you name from outranking your product code in search and codegraph_explore answers, without removing anything from the index. It takes gitignore-style patterns just like exclude, but is ranking-only: helper-script trees, generated output, or optional add-on directories whose generic symbol names (usage, run, status) would otherwise crowd out the code that actually answers a query stay fully indexed and findable — and a query that genuinely targets such a tree still returns it. Thanks @maxmilian. (#982)

  • codegraph_explore no longer re-sends source it already returned earlier in the same conversation. A file it has already shown you comes back as a short pointer — the path, the symbols and the exact line range, with confirmation that the file hasn't changed since — and the space that frees is spent on code you haven't seen yet, so a follow-up call covers new ground instead of repeating the last one. If a file was edited in between, its source is always shown again in full. Set CODEGRAPH_EXPLORE_DEDUP=0 to turn this off.

  • When an agent connects over MCP, CodeGraph now states up front that it indexes 30+ languages — TypeScript/JavaScript, Python, Go, Rust, Java, C#, C/C++, PHP, Ruby, Swift, Kotlin, and more — so agents no longer assume a language isn't supported and skip the graph. (#671)

  • Anonymous usage telemetry is now stored entirely on CodeGraph's own first-party infrastructure — no third-party analytics vendor receives any of it, and the endpoint that receives it makes no outbound requests at all. Individual events are deleted after 90 days, leaving only anonymous daily totals. Nothing about what is collected changed, your IP address is still never read or stored, and every off-switch works exactly as before (codegraph telemetry off, CODEGRAPH_TELEMETRY=0, DO_NOT_TRACK=1). TELEMETRY.md remains the complete field-by-field list.

Fixes

Better answers from codegraph_explore

  • Naming a file by its path in a codegraph_explore query now works reliably: the path is resolved against the index and that file is guaranteed a place at the top of the answer. Previously the path was broken into fragments — bracketed route segments like SvelteKit's [id] made this worst — and pieces like page or runs matched every sibling file, so the file you actually named could be crowded out of the answer entirely. A path that doesn't match any indexed file is now called out instead of silently ignored.

  • Naming a kebab-case file without its extension in a codegraph_explore query — background-image-table rather than background-image-table.tsx, the way import paths and prose spell it — now returns that exact file too. Previously the name was split at the hyphens, and in a kebab-cased frontend those pieces (background, image, table) are among the most common words in the codebase, so look-alike sibling files filled the answer while the named file never appeared. Hyphenated words that don't name an indexed file, like "cross-call" or "non-blocking", are left alone.

  • Plainly-worded codegraph_explore questions now find camelCase code: a query like "auto-scroll to bottom" can reach a function named scrollFeedToBottom, because query words are matched against the words inside identifiers, not just whole names.

  • Variables and constants now count when codegraph_explore picks its starting symbols, so state held in plain variables — $state-style variables in Svelte, for example — no longer gets overlooked.

  • codegraph_explore now concentrates its answer on the code that actually answers your question instead of spreading it across files that merely share a word with it, so more of the answer arrives in a single call. Thanks @LeDuyViet for the detailed measurements and reproduction. (#1500)

  • Files only weakly related to your question now come back as a name, symbol and line number instead of spending the answer on their source — name one of them in a follow-up codegraph_explore to get it back in full. (#1500)

  • A generated CRUD or protobuf layer no longer crowds out the hand-written code sitting beside it: generated files are now recognized by the // Code generated by … DO NOT EDIT. style banner written at the top of the file, not just by a filename that looks generated. Re-index after upgrading to pick up the new detection. (#1500)

  • Test and spec files in a repository's top-level test/ or spec/ directory are now recognized as such, so they no longer take room from the code you asked about. (#1500)

  • Generated type-declaration files that announce themselves with a "Generated by … by running …" banner — Cloudflare Wrangler's worker-configuration.d.ts is the common one — are now recognized as generated. Previously a file like that could take most of a codegraph_explore answer on nothing more than a few common words, pushing the hand-written code you asked about out of the response entirely. Re-index after upgrading to pick up the new detection.

  • A hand-written type-declaration file — an ambient .d.ts of global shims, vendored typings, module augmentation — no longer takes over a codegraph_explore answer about how something works. Files like these declare common names (Body, Message, ImageMetadata) and nothing else, so a plainly-worded question could match one strongly enough that it ranked first and crowded the actual handler out of the answer. They are now ranked lower for questions about behaviour, and are still listed by name so one follow-up call fetches them. Asking about a type by name still returns its declaration first, and a shared types module the rest of your code imports is unaffected.

  • When you name a symbol in a codegraph_explore query, its definition now actually comes back. Two cases previously lost it. If the symbols you named don't call one another — sibling functions inside the same factory or module are the everyday example — CodeGraph stopped treating them as symbols you had asked for, and answered with whatever sat at the top of their file instead; on one 1,400-line file that meant a same-stem QueuedMessage interface on line 70 came back while the queueMessage function on line 1087 did not. And when an answer had to be trimmed to fit, it was trimmed from the bottom of the file down, so a symbol near the end of a long file was always the first thing cut. Trimming now protects the definitions you named wherever they sit in the file.

  • A file built around one very long function no longer takes the whole codegraph_explore answer for itself — or disappears from it. Previously such a file was shown in full however big it was, which used up the room every file after it needed, and when the function was larger than the entire response the file was dropped without a word. These files now come back as a bounded window on whole lines — the signature and the top of the body, plus the call site when the call path runs through it — with the rest one follow-up codegraph_explore away.

  • codegraph_explore no longer lets the first file in an answer spend the room set aside for the files below it, so the rest of the answer still arrives. Previously a large file near the top could quietly use up everything left, and the files ranked under it — each already judged relevant enough to include — were dropped with no source at all; on one question only one of six made it into the answer. Every file now keeps what it was given, and a question that really is about one file still concentrates on that file.

  • When a codegraph_explore answer runs right up against its size limit, it now drops the trailing notes rather than a whole file's source. Previously the last file was cut even though trimming the notes alone would have fit, so a file that had already been read, ranked and rendered was thrown away at the last moment. Across a range of real projects this returns one more file and up to 20% more source per call.

  • Every file codegraph_explore decides to include now actually arrives. A file shown in full could still spend room set aside for files below it — the fix above covered files shown as excerpts but not files shown whole — and the answer's own size bookkeeping under-counted each file's heading, so the answer ran past its limit and a fully prepared file was discarded at the end. A file that no longer fits whole is now shown as excerpts instead of vanishing, and one that overshoots by a little is trimmed to fit rather than dropped.

  • The list of files an answer could not cover — the "explore these names for their source" pointers — is no longer thrown away when the answer is full. It is now budgeted for and trimmed to fit, so a full answer still tells you what it left out and which names to ask for next, instead of ending with no pointers at all.

  • When a codegraph_explore answer shows a file as excerpts, a large excerpt that no longer fit was dropped entirely instead of being shortened. If the file's first excerpt happened to be a trivial one — an import block, a one-line helper next to the code you asked about — the excerpt carrying the actual answer was the one thrown away, and the file came back with a quarter of the room it had been given. On real projects that meant the top-ranked file delivered a fraction of its share while a far less relevant file took the rest. Excerpts are now shortened to fit, whole method by whole method, and only dropped when what is left is too small to hold anything readable.

  • The blast-radius section of codegraph_explore flagged "no covering tests found" whenever no test called a symbol directly — falsely branding helpers that tests exercise through their callers as untested (about 40% of flagged symbols in a measured sample). The check now follows caller chains up to 3 hops and reports indirect coverage as "tested via callers"; when nothing is found it states exactly what was checked instead of an unconditional warning. Thanks @inth3shadows for measuring the false-positive rate. (#1475)

  • When a file changed on disk after its last index sync, codegraph_node and codegraph_explore could return a different symbol's code under the requested name — current file bytes cut at outdated line positions — while presenting it as verbatim, trustworthy source. This hit hardest on projects queried through projectPath (for example, sub-projects of a monorepo), which have no live file watcher to flag pending edits. Both tools now verify each file against the index before showing sliced code: an out-of-date file is either shown whole with its full current source, or its code is withheld with a clear "changed on disk" notice — never served as a wrong slice. A fresh re-index restores normal output automatically. Thanks @inth3shadows for the thorough report and verification passes. (#1474)

Finding your project, live updates, and the CLI

  • The MCP server now finds your project when it's launched from a workspace folder above it: if the launch directory has no index of its own but exactly one indexed project sits below it (a repo container, an agent workspace, a monorepo root), that project becomes the session's default — live file watching and the shared daemon included — instead of every tool call failing until a projectPath or --path is supplied. Thanks @nakisen. (#1606)

  • When no project can be resolved at all, the MCP server now says so instead of starting silently: a startup log line names the directory it searched, and tool calls list the indexed sub-projects it can see nearby so you can pass one as projectPath. Previously the server looked healthy from the outside while every tool quietly had no project to answer from. Thanks @nakisen. (#1607)

  • Editing codegraph.json's exclude or include (or a .gitignore) while the MCP server is running now takes effect immediately. Previously the running file watcher kept the scope it had when it started, so a newly excluded file was removed by codegraph sync and then quietly re-added by the watcher seconds later — which looked like exclude not working at all — until the server was restarted. A scope change now refreshes the watcher and triggers a full reconcile, and a changed file the watcher hands to sync is re-checked against the current scope first, so the CLI and the live server can no longer disagree about what belongs in the index. Thanks @K1nG11. (#1590)

  • codegraph status now sees new files inside brand-new directories. Git reports an entirely-untracked directory as a single collapsed entry, so source files created there — a freshly scaffolded frontend/, for example — were missing from the pending-changes report, which could claim everything was up to date while those files had not yet been indexed. Thanks @maxmilian. (#1213)

  • The codegraph context <task> command documented in the CLI help now actually exists — it builds a ready-to-inject context pack for a task (relevant symbols, their relationships, and code) in markdown or JSON, restoring the contract external integrations like Memorix rely on (--path, --format json, --max-nodes, --no-code). (#1611)

  • On Windows, the Claude Code prompt hook written by codegraph install failed with "command not found" when hooks run through Git Bash, which needs the .cmd extension to find the launcher. The installer now writes the platform-correct command, and re-running codegraph install (or codegraph upgrade) repairs an existing install in place. (#1466)

  • Looking a symbol up by name no longer reads the whole graph. Every search made one full pass over all indexed symbols for each word you typed, and a question that named several symbols made two more passes per name — including for a word that matches nothing, which is the common case. The cost therefore grew with the size of the project, and it was paid again on every message when the prompt hook is enabled. These lookups now go through the name index instead. Results are identical; only the time to get them changes, and it no longer grows with the project. Thanks @maxmilian.

Indexing reliability and disk usage

  • Indexing no longer crashes the whole process — a segmentation fault with no message and no partial index — on a C/C++ (or any other) file with extremely deep nesting, such as the parser stress-test fixtures in the clang and gcc test suites or a fuzzer corpus. Such a file is now handed to the fallback parser and recorded with a parse warning while the rest of the repository indexes normally. Thanks @apollo600 for the exact diagnosis. (#1581)

  • Indexing no longer hangs on a Swift Vapor project containing a call with a long argument list. A single .get(...)-style call with many labeled arguments and no use: handler — the shape generated request builders produce — could stall codegraph index, codegraph sync, and the MCP server indefinitely. Route detection now handles such files in milliseconds, and every previously-recognized route shape still parses exactly as before. Thanks @maxmilian. (#1544) (Swift)

  • Syncing a large batch of changed files no longer crashes with "Maximum call stack size exceeded" partway through. The crash aborted reference resolution after the files' symbols were already stored, leaving the graph with far fewer connections than a fresh index would have — and it hit exactly the scenarios that re-parse many files at once, including the automatic repair above. Thanks @netbrah for pinpointing the failure. (#1558)

  • A long-lived index no longer drifts away from what a fresh codegraph index would produce. When a file gained or lost a symbol, references to that name in files the sync never touched kept pointing at the definition that was correct before the change, and — because nothing distinguished two same-named definitions — the winner could come down to the order files happened to be written, which differs between a full index and a sync. On this project's own repository, replaying 80 commits through sync left 5.7% of connections wrong; it is now 1.3%, and the wrong-answers-still-being-asserted half drops by 99.7%. Since call edges are what flow questions follow and what codegraph_explore ranks files by, this quietly degraded answers as an index aged, with nothing to indicate it. Syncing is unchanged in speed, and an edit that only changes a function's body does no extra work at all. Set CODEGRAPH_NO_REBIND=1 to opt out.

  • Fixed a v1.5.0 regression where a perfectly valid file could be permanently recorded as having 0 symbols, with no error reported. When a file's first parse attempt was interrupted — a parsing worker crash or timeout, most likely on slow or heavily loaded machines — the automatic retry stored an empty result for any language on the native extraction path, so the file's functions and classes silently vanished from search, callers, and impact until the file was next edited. Retries now store the file's real symbols, and a file already recorded as symbol-free is detected and repaired automatically by the next sync or re-index after upgrading. Thanks @Baiae for the report. (#1541)

  • A CodeGraph process that gets force-killed — by the stuck-process watchdog, a crash, or the OS — no longer leaves the database's write-ahead log behind to grow without bound. Previously each killed session stacked more data onto the same log file and nothing ever shrank it, which on machines where sessions were killed regularly could quietly eat tens of gigabytes of disk. The log's resting size is now bounded (64 MB by default; CODEGRAPH_WAL_HEAL_MB changes it), and any oversized leftover is folded back into the index and trimmed automatically the next time the project is opened. This bounds only the log — the index itself has no size limit, and a large repository's log is still allowed to grow in proportion to its index while it is being built. Thanks @tiendungdev for the exceptional Windows report that pinned this down. (#1431)

  • The background server's watchdog no longer kills a healthy server that is just waiting on a slow disk: like indexing already does, it now checks whether the database files are still making progress before concluding the process is stuck. Fewer spurious kills also means fewer leftover write-ahead logs. (#1431)

  • codegraph status now shows the write-ahead log's size next to the database size and warns when killed sessions have left it oversized, and every line in the background server's log now carries a timestamp so kills and restarts can be placed in time. (#1431)

  • A background daemon left behind by an out-of-memory kill or force-kill can no longer block every future session when the operating system reuses its process ID: daemon management now verifies a recorded process is really a CodeGraph daemon before trusting or signaling it, and codegraph unlock clears stale daemon artifacts as well as the indexing lock. Thanks @hcg1023 for the report and @danusha2345 for the fix. (#1553)

  • When indexing has to fall back to parsing a file with its comment lines stripped — a last-resort recovery after repeated parser crashes — the file is now flagged with a visible warning instead of being reported as cleanly indexed. The recovered result can be incomplete, and reporting success made a fresh index quietly disagree with a later re-parse of the same unchanged file. Thanks @jeremypetz for the precise init-versus-sync symbol accounting that exposed this. (#1565)

  • Data-only C/C++ headers near the file-size limit no longer hold a parser worker for several minutes before timing out; the default large-file parse budget is now bounded, while an explicitly configured larger timeout is still honored. (#1555)

  • Reopening an index after a crash during bulk loading now restores every dropped database index, and a successful recovery sync marks the index complete instead of leaving it permanently flagged as interrupted. (#1556)

  • Files skipped because they are too large or repeatedly fail to parse are now recorded with the reason, so unchanged rejected files are no longer rediscovered and retried on every status check and sync — and a later successful parse of such a file replaces the record with its real symbols. Thanks @netbrah for the exceptional failure analysis behind this batch, and @danusha2345 for the fixes. (#1557)

  • C/C++ function-pointer analysis now bounds its compiled-pattern caches, so very large repositories can no longer exhaust the JavaScript engine's regular-expression code space during indexing. (#1559)

  • JSX rendering analysis now runs only on JavaScript-family files, so JSX-looking strings in C/C++ (or any other language) no longer create impossible call edges — in pure-C projects and in mixed-language monorepos alike. (#1560)

Language and framework accuracy

  • Calls to the methods of an exported object-literal constant — export const api = { call() { … } } used as a module's namespace, a common way to organize a TypeScript API surface — now resolve to the method, both in the defining file and through imports. Previously such a call linked to nothing (or to the constant itself), so codegraph callers and impact analysis reported zero callers for methods that are called from everywhere. Re-index after upgrading to pick up the edges. Thanks @IAliceBobI for the precise report and root-cause. (#1573)

  • Import aliases defined in a shared TypeScript config are now picked up. Nx-style monorepos keep every @scope/... alias in a tsconfig.base.json that the root tsconfig.json only inherits through extends, so CodeGraph found no aliases at all and every cross-package import fell back to matching on name alone — which quietly attaches results to unrelated symbols that happen to share a name, exactly where a monorepo needs codegraph_impact and codegraph_callers to be right. Chains several configs deep, a config inherited from a package in node_modules, and a baseUrl declared in an inherited config are all followed now, and a tsconfig.base.json is read directly when the root tsconfig.json is only a project-references shell or isn't there at all. Re-index after upgrading. Thanks @maxmilian. (#1534)

  • Methods implemented in a generic or lifetime-parameterized impl block (impl<T> Source for BufSource<T>, impl<'a> Iterator for Parents<'a>) are now recorded under the implementing type instead of the trait. Previously such a method could not be found by its type — "who calls BufSource::read" had no answer — and it collided with the trait's own declaration, which could even invent a call-graph edge out of an impl body that contains no call at all. Impls on a reference (impl Trait for &Foo) and on a module-qualified type (impl Trait for m::Foo) are attributed to their type too. Re-index after upgrading. Thanks @Dshuishui. (#1588) (Rust)

  • A method call on a struct field — self.inner.run() with inner: Inner — now resolves to the method on the field's declared type. Previously the call was reduced to the bare method name and matched whichever same-named method was nearest, which was often the calling method itself, recording recursion that isn't in the source (a few hundred such self-edges in ripgrep alone), or a method of an unrelated type. References and Box/Rc/Arc fields are looked through, as Rust's own method calls are; a field whose type is external (a std or third-party type), a generic parameter, or a container like Option/Vec is left unresolved rather than guessed. Re-index after upgrading. Thanks @Dshuishui. (#1585) (Rust)

  • Erlang functions that share a name but differ in arity are now separate symbols with the language's own module:fun/arity identity, so the everyday f/1 delegating to f/2 shows as a real call edge instead of a self-loop, each arity keeps its own -spec and source span, -export([f/1]) marks exactly that arity as public, and asking codegraph_explore for a symbol the way Erlang spells it — cowboy_req:header/3 — returns that definition. Re-index Erlang projects after upgrading. Thanks @Dshuishui. (#1610) (Erlang)

  • Erlang behaviour dispatch no longer miscounts a call site's arity when an argument is a binary literal like <<1,2,3>> — the commas inside were counted as argument separators, which silently dropped (or could mislink) the dispatch edge to the behaviour callback. (#1358) (Erlang)

  • A C++ .h header whose only C++ construct is a plain derived type — struct Derived : Base with no export macro, class keyword, or access section — is now recognized as C++ (previously only the export-macro form was). Such a header was read as C, so the derived struct vanished from the index and a phantom function named after the base type appeared in its place. The check now also covers the whole file rather than its first few kilobytes, so a long C-compatible preamble no longer hides the signal. Re-index after upgrading to pick up affected headers. Thanks @Jaysenpeng. (#1592)

  • C, C++, Objective-C and Rust unions are now indexed as first-class union nodes. A union declaration previously produced no symbol at all, so it never appeared in search or codegraph_explore, and anything attached to it disappeared with it — in Rust, every impl SomeTrait for MyUnion lost its edge, the methods from that impl were left pointing at a type the graph did not contain, and asking which types implement a trait quietly skipped the union ones. A union-shaped dispatch table in C now resolves its function pointers like a struct-shaped one. A typedef union { … } Name; in C keeps the typedef's name and is no longer mistaken for a plain type alias. Thanks @ctype-lab. Re-index after upgrading to pick up unions in existing projects. (#1515)

  • Python classes used as values — return SomeSerializer from a factory method, handler = SomeClass aliases, registry dicts and lists, and classes passed as arguments — now produce reference edges in the graph. Previously these idioms were invisible, so on Django and Django REST Framework projects, asking for a serializer's callers or the impact of editing it missed the views that actually use it. Re-index after upgrading to pick up the new edges. (#1478)

  • SAP HANA .xsjs / .xsjslib imports now resolve across files: an extensionless import { x } from './helpers' in a .xsjs file finds helpers.xsjslib, so the cross-file call edge is created and codegraph_callers / codegraph_impact see it. Previously the import path resolved to nothing and the call fell back to same-name matching, which could bind the edge to an unrelated file that happened to export the same symbol. Complements the .xsjs / .xsjslib extraction support. Thanks @maxmilian. (#556)

Don't miss a new codegraph release

NewReleases is sending notifications on new releases.