Releases: colbymchenry/codegraph
v0.9.2
[0.9.2] - 2026-05-21
Added
- Installer target: Hermes Agent (Nous Research).
codegraph installnow supports Hermes Agent — it writes themcp_servers.codegraphentry and ensuresplatform_toolsets.cliincludesmcp-codegraphin$HERMES_HOME/config.yaml, so Hermes can drive the CodeGraph knowledge graph like the other agents. - Framework support: Drupal 8/9/10/11 — CodeGraph now detects Drupal projects (via a
drupal/*dependency incomposer.json) and adds three levels of intelligence:- Route extraction:
*.routing.ymlfiles emit aroutenode per route, linked by areferencesedge to the_controller,_form, or entity-handler class/method, so querying a controller method surfaces the URL route that binds it. - Hook detection: hook implementations in
.module,.install,.theme, and.incfiles are detected via docblock (Implements hook_X()) with a module-name-prefix fallback. Each emits areferencesedge to the canonicalhook_Xname socodegraph_callers("hook_form_alter")returns every implementation across modules. - Resolution:
_controller/_formFQCNs resolve to their PHP class/method nodes.
Newyaml/twiglanguages are tracked at the file level, the Drupal PHP extensions (.module/.install/.theme/.inc) are indexed with the PHP grammar, andweb/core,web/modules/contrib,web/themes/contribare excluded by default. Resolves #268.
- Route extraction:
Changed
- Zero-config indexing that respects
.gitignore. CodeGraph no longer has a config file. It indexes every file whose extension maps to a supported language and honors your.gitignoreeverywhere: in git repos via git itself, and in non-git projects (e.g. a freshly-scaffolded app beforegit init) by reading.gitignorefiles directly — root and nested, the same way git does (via theignorelibrary, so negation/anchoring/nested rules all behave correctly). To keep something out of the graph, add it to.gitignore. Behavior change: committed files that are not gitignored are now indexed even undervendor/,Pods/, or a committeddist/— previously a hardcoded exclude list skipped those names; now.gitignoreis the single source of truth. Resolves #283.
Fixed
- Windows:
npm i -g @colbymchenry/codegraphthen anycodegraphcommand failed withspawnSync …\codegraph.cmd EINVAL. The npm launcher spawned the bundle's.cmdfile directly, which modern Node refuses to do on Windows (the CVE-2024-27980 hardening — seen on Node 24). The launcher now invokes the bundlednode.exeagainst the app directly, socodegraphworks on Windows regardless of your Node version. Resolves #289.
Removed
.codegraph/config.jsonand the entire config surface. Every field was either inert or now redundant with.gitignore:languages/frameworksnever affected indexing (languages are detected per file from extensions; frameworks are auto-detected).languageswas also broken — its validator only knew the original 8 languages, so setting it to anything newer (C#, PHP, Ruby, C/C++, Swift, Kotlin, Dart, Vue, Scala, Lua, …) threwInvalid configuration format.extractDocstrings/trackCallSites/customPatternswere never read by any extractor.includeis now derived from the supported language extensions,excludeis replaced by.gitignore, andmaxFileSize(1 MB) is a constant.
Breaking (library API): the CodeGraphConfig type, the config option on CodeGraph.init(), and the getConfig()/updateConfig()/getConfigPath exports are gone. Existing .codegraph/config.json files are simply ignored. The .codegraphignore marker is no longer supported — use .gitignore.
Security
- MCP session marker no longer follows symlinks (CWE-59). Every
codegraph_contextcall writes acodegraph-consulted-*marker into the system temp dir; the previous write followed symlinks, so on a multi-user system another local user could pre-plant that path as a symlink and redirect the write onto a victim-writable file. The marker is now opened withO_NOFOLLOWand mode0600, and a planted symlink is refused rather than followed. Resolves #280.
v0.9.1
0.9.1 - 2026-05-21
Fixed
- Standalone installers (
curl … | sh,irm … | iex): the bundled launcher failed withexec: …/node: not foundbecause it didn't resolve the symlink the installer puts on your PATH. Installing on a machine with no Node now works. - npm:
@colbymchenry/codegraph-linux-x64is now published — the 0.9.0 release silently shipped 6 of 7 packages, sonpm i -gon linux-x64 couldn't find its bundle. The release pipeline now verifies every package reached the registry (and is idempotent), so a release can't pass green-but-broken again.
v0.9.0
0.9.0 - 2026-05-21
🎉 Self-contained: CodeGraph bundles its own runtime — install anywhere, on any Node (or none)
No more database is locked. No more native build failures. No more "WASM fallback active."
CodeGraph used to need better-sqlite3, a native module compiled against your exact
Node version. When that build failed (common on Windows and locked-down machines) it
silently dropped to a slow WASM SQLite build with no WAL — the root cause of the
intermittent database is locked errors on concurrent MCP tool calls
(#238). That entire class of
problem is gone: CodeGraph now ships a self-contained Node runtime and uses Node's
built-in node:sqlite (real SQLite, full WAL + FTS5).
- ✅ Zero native compilation — nothing to build, ever; nothing to rebuild when Node changes.
- ✅ Runs on any Node version — or with no Node at all. Install via the standalone installers with no Node present, or keep using
npm/npxon any version (your Node only launches the bundled runtime). - ✅
database is lockedfixed at the root — real WAL means readers never block on a writer. - ⚡ 5–10× faster than the old WASM fallback for anyone who was stuck on it.
# macOS / Linux — no Node required
curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh
# Windows (PowerShell) — no Node required
irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iex
# or, if you have Node (any version):
npm i -g @colbymchenry/codegraphAdded
- Standalone installers — one-line install with no Node.js required:
curl -fsSL .../install.sh | sh(macOS/Linux) andirm .../install.ps1 | iex(Windows). They fetch the matching self-contained bundle from GitHub Releases and putcodegraphon your PATH. - Lua: CodeGraph now indexes Lua (
.lua) — functions, methods (tablet.fandt:mdefinitions become methods with at::freceiver-qualified name), local variables,require(...)imports, and the call edges between them. Querying a Lua project (Neovim plugins, Kong, OpenResty, game code) now surfaces its modules, methods, and call graph. - Luau (#232): CodeGraph now indexes Luau (
.luau), Roblox's typed superset of Lua — everything Lua extracts, plustype/export typealiases, typed function signatures, generics, and Roblox instance-pathrequire(script.Parent.X)imports.
Changed
- SQLite backend is now Node's built-in
node:sqlite(real SQLite, WAL + FTS5), shipped inside a bundled Node runtime. This fixes the concurrent-readdatabase is lockederrors (#238) at the root and removes the native build step entirely. npm i -g/npxnow install a self-contained bundle. The main package is a tiny shim; the runtime ships as per-platformoptionalDependencies, so the install works on any Node version (your Node only launches the bundle).codegraph statusnow reports the effective journal mode (walvs not), so adatabase is lockedreport is triageable at a glance.
Removed
better-sqlite3(optional native dependency) andnode-sqlite3-wasm(WASM fallback) — along with the native-build banner, the WASM fallback path, and the no-WAL lock retries they required. The dependency tree now has zero native addons.
Fixed
- Installer: re-running
codegraph installnow removes the broken auto-sync hooks that pre-0.8 versions wrote to Claude Code'ssettings.json. Those builds added aStop → codegraph sync-if-dirtyhook (and aPostToolUse → codegraph mark-dirtypartner); both subcommands were later removed from the CLI, so Claude Code reportedStop hook error: ... unknown command 'sync-if-dirty'on every turn. The cleanup is surgical — only codegraph's own hook entries are stripped, so unrelated hooks sharing the same file or event (e.g. a GitKrakengk ai hook runhook) are left untouched — and it also runs on uninstall, so the npmpreuninstallstep fully reverses a legacy install. Re-runcodegraph installonce on an affected machine to clear the error.
v0.8.0
[0.8.0] - 2026-05-20
Added
- Framework routes (NestJS): CodeGraph now recognises NestJS projects and emits
routenodes — each linked by areferencesedge to its handler method — across all four transport layers: HTTP controllers (the@Controllerprefix joined with@Get/@Post/@Put/@Patch/@Delete/@Head/@Options/@All, including empty@Controller()/@Get()), GraphQL resolvers (@Query/@Mutation/@Subscription), microservice handlers (@MessagePattern/@EventPattern), and WebSocket gateways (@SubscribeMessage, prefixed with the gateway namespace). Detected automatically from any@nestjs/*dependency inpackage.json. Querying a controller method or resolver now surfaces the route that binds it. Resolves #220. - MCP / explore:
codegraph_exploresource sections now carry line numbers (cat -n style<num>\t<code>, matching the Read tool). This lets the agent citefile:linestraight from the explore payload instead of re-opening the file just to find a line number — the dominant residual cost on precise-tracing questions. In an isolated A/B (answer a "which exact line" question with the relevant code already in the payload), the no-line-numbers arm spent 2 file Reads + a grep recovering the line number while the line-numbered arm answered with zero follow-up tool calls. Payload cost is small (~3-5%). SetCODEGRAPH_EXPLORE_LINENUMS=0to disable. - MCP / watcher: CodeGraph now skips the live file watcher on WSL2
/mnt/*drives, where recursivefs.watchis slow enough to break MCP startup (see Fixed). When the watcher is off,codegraph init/codegraph installoffer to keep the index fresh via git hooks (post-commit,post-merge,post-checkout) that runcodegraph syncin the background — accept for automatic refresh on commit / pull / checkout, or decline and sync by hand. Either way you're told the index stays frozen until it's re-synced. New controls:CODEGRAPH_NO_WATCH=1(orcodegraph serve --mcp --no-watch) forces the watcher off anywhere;CODEGRAPH_FORCE_WATCH=1overrides the WSL auto-detect when your/mntsetup is actually fast.codegraph uninitremoves any hooks it installed.
Changed
- MCP / agent guidance: CodeGraph now tells agents to answer "how does X work" / architecture questions directly —
codegraph_context, then onecodegraph_explorefor the surfaced symbols — instead of delegating to a file-reading sub-agent or a grep+read loop. The server instructions and the installed instruction files (CLAUDE.md,.cursor/rules/codegraph.mdc,AGENTS.md) previously suggested spawning a sub-agent for explore-class questions, which produced the opposite, more expensive behavior: the sub-agent reads files regardless of the index, so CodeGraph became overhead stacked on top of the reads. In rigorous N≥4-per-arm benchmarks this cut the cost of an architecture question by ~42–47% versus a no-CodeGraph agent on medium and large repos (Excalidraw ~600 files, VS Code ~10k), with equal-or-better,file:line-cited answers and ~6× fewer tool calls; on a tiny repo (~25 files) it's a wash, since native grep is already trivially cheap there. - MCP / codegraph_node:
includeCode=trueon a class/interface/struct/enum now returns a compact member outline (fields + method signatures + line numbers) instead of the entire class body — which could be thousands of characters and was rarely needed in full. Functions and methods still return their full body; request a specific member for its source. - Minimum Node.js is now 20 (was 18). Node 18 is end-of-life and the native SQLite binding (
better-sqlite312.x) no longer ships a Node 18 prebuilt binary. Node 22 LTS and Node 24 get the native backend out of the box; on other Node versions CodeGraph still runs via the WASM fallback (slower, but functional). Node 25+ remains blocked (V8 WASM JIT crash, see #81). - MCP / explore:
codegraph_exploreoutput is now adaptive to project size. The tool used to apply a fixed 35KB cap regardless of how large the codebase was, which on small projects (~100 files) produced bigger responses than the agent's native grep+Read flow would have — exactly the scenario reported in #185. The budget now scales with indexed file count: small projects (<500 files) cap at ~18KB and skip the "Additional relevant files" / completeness / explore- budget reminders that earn their keep on bigger codebases; medium (<5,000) caps at ~13KB; large (<15,000) keeps the historical ~35KB; very large goes up to ~38KB. A new per-file char cap also prevents a single file with many adjacent symbols from collapsing into one whole-file dump (the AlamofireSession.swiftcase from #185). Per-file cluster selection ranks clusters that contain a query entry point ahead of dense declaration blocks, and whole-file "envelope" nodes (a class/struct that spans most of the file) are excluded from clustering so the methods the query asked about aren't buried under the container's opening lines. Measured against the same repos used in the README benchmark, end state with line numbers on: Alamofire ~60% smaller per call, Excalidraw ~32%, VS Code ~12%. Agent-trust floor still holds — the Relationships section, scored cluster selection, and structured-source output are all retained. Thanks to @essopsp for the repro. - Search ranking (Kotlin / Swift / Scala / C#): test files in these languages are now correctly de-prioritized in
codegraph_search,codegraph_context, andcodegraph affected. Detection previously only recognizedsnake_case/.test.-style names plus a handful of Java suffixes, so CamelCase test files (FooTest.kt,BarTests.swift,BazSpec.scala,QuxTestCase.cs) and Gradle / Kotlin-Multiplatform / Xcode test source-set directories (jvmTest/,commonTest/,androidTest/,iosTest/,integrationTest/) were treated as production code and could outrank the real implementation. Detection now matches capital-led*Test/*Tests/*Spec/*TestCasefilenames and source-set directories — deliberately capital-led so lowercase look-alikes likelatest.ktandmanifest.ktare not misclassified.
Fixed
- MCP / explore:
codegraph_exploreoutput is now hard-capped to its adaptive size budget. It could previously overrun (e.g. ~30K against a 28K cap) once the relationship map and trailer sections were appended; the oversized payload then sat in the agent's context and was re-read on every later turn. - Sync / status: git-untracked files are no longer reported as pending "Added" forever. After
codegraph syncindexed a newly-created untracked source file,codegraph statuskept listing it under Pending Changes and every subsequentsyncre-indexed it from scratch — even though its symbols were already queryable. Change detection trustedgit statusand counted every untracked (??) entry as new without checking the index, but indexing a file doesn't make git track it, so the file stayed??and got re-added on each run. CodeGraph now hash-compares untracked files against the index the same way it does tracked files: a file counts as "added" only if it's missing from the index, "modified" if its contents changed, and is skipped otherwise. Closes #206. Thanks to @15290391025 for the report. - Indexing:
codegraph init -inow finds source inside nested, independent git repositories — separate clones living inside the workspace that are not git submodules (common in CMake "super-repo" layouts). When the top-level workspace is itself a git repo,git ls-filesreports an embedded repo only as an opaquesubdir/entry and never lists its files, so indexing from the workspace root reported "No files found to index" even though indexing each sub-repo individually worked. CodeGraph now detects these embedded repos and indexes their tracked and untracked source, honoring each repo's own.gitignore. Closes #193. Thanks to @timxx for the report. - Native SQLite backend on Node 24: indexing on Node 24 always dropped to the 5-10x-slower WASM backend, printing a
better-sqlite3 unavailablewarning thatnpm rebuild better-sqlite3/xcode-select --installcould not clear (#203). The bundledbetter-sqlite3was pinned to a v11 release that ships no prebuilt binary for Node 24's ABI (node-v137), so every Node 24 install silently degraded — and because CodeGraph is usually installed globally, thenpm install/npm rebuildpeople ran in their own project never touched CodeGraph's copy. CodeGraph now requiresbetter-sqlite3^12.4.1, whose prebuilds include Node 24, so a fresh install on Node 22 or Node 24 gets the native backend with no compiler. On an already-broken install, reinstall CodeGraph (e.g.npm install -g @colbymchenry/codegraph) to pull the new binding;codegraph statusshould then reportBackend: native. Thanks to @Finndersen for the report. - MCP: tools no longer fail with "CodeGraph not initialized" when the index actually exists. This hit clients that launch the MCP server from a directory other than your project and don't report a workspace root in
initialize(some IDE/JetBrains-family integrations) — the server fell back to its own working directory, missed the project's.codegraph/, and returned the misleading "Run 'codegraph init' first" on every call. The only workaround was passingprojectPathto each tool by hand. Now, when no project path is supplied, the server asks the client for its workspace root via the standard MCP `roots/li...
v0.7.10
0.7.10 - 2026-05-19
Fixed
- MCP: tools no longer silently fail to appear in clients on slow filesystems (Docker Desktop VirtioFS on macOS, WSL2). The
initializehandshake was blocking on opening the SQLite database and bootstrapping the tree-sitter WASM runtime, which on slow I/O could exceed Claude Code's ~30s handshake timeout — leaving the codegraph process alive but unresponsive and no tools visible. The handshake now returns immediately and defers project open to the background; tool calls wait on the in-flight init rather than racing it with a second open. Closes #172. Thanks to @sashanclrp for the original report and detailed reproduction, and @sgrimm for the decisive wire capture that isolated the actual root cause. - CLI: terminal output no longer mojibakes on Windows PowerShell / cmd.exe during
codegraph indexandcodegraph sync. The shimmer progress renderer writes from a worker thread viafs.writeSync(1, …)to keep the animation smooth while the main thread is busy in SQLite, which bypasses Node's TTY-aware UTF-8→codepage conversion — so glyphs like│ ◆ —were emitted as raw UTF-8 bytes and reinterpreted as the console's OEM codepage (CP437, CP936, …), producing strings like鋍?[0m 鉒?[0m Scanning files 鈥?N found. CodeGraph now picks an ASCII glyph set on Windows by default (| * -instead of│ ◆ —); setCODEGRAPH_UNICODE=1to opt back into the Unicode glyphs (e.g. on pwsh 7 with UTF-8 codepage), orCODEGRAPH_ASCII=1on any platform to force ASCII (useful for log collectors / non-TTY pipelines). Closes #168. Thanks to @starkleek for the report and to @Bortlesboat for the initial PR. - MCP / search: module-qualified symbol lookups now resolve. The MCP tools (
codegraph_node,codegraph_callees,codegraph_impact, …) acceptmodule::symbol(Rust / C++ / Ruby),Module.symbol(TS / JS / Python), andmodule/symbol(path-style) — multi-level forms (crate::configurator::stage_apply::run) and Rust path prefixes (crate,super,self) are handled. Closes #173. Thanks to @joselhurtado for the detailed reproduction. Three underlying fixes:- The FTS5 query builder now treats
::as a token separator instead of stripping it to nothing, sostage_apply::runno longer collapses to the unsearchablestage_applyrun. matchesSymbolfalls back to a file-path containment check whenqualifiedNamedoesn't carry the module hierarchy (Rust file-level functions, Python free functions in a package): aruninsrc/configurator/stage_apply.rsnow matchesstage_apply::runbecausestage_applyappears as a path segment.- Qualified lookups that don't match the qualifier no longer fall through to fuzzy text matches —
stage_apply::nonexistent_fnreturnsnullinstead of resolving to an unrelatedrollbackin the same file.
- The FTS5 query builder now treats
v0.7.9
0.7.9 - 2026-05-17
Fixed
- opencode: install actually wires up the MCP server now. v0.7.7 wrote
~/.config/opencode/opencode.json, but opencode readsopencode.jsoncby default — so thecodegraphentry never showed up in any opencode session. The installer now prefers an existing.jsonc, falls back to.jsonwhen only that exists, and creates.jsoncfor greenfield installs. Re-runcodegraph install --target=opencodeafter upgrading so the entry lands in the file opencode actually reads.
Added
- opencode: installer now writes
AGENTS.md(global~/.config/opencode/AGENTS.md, local./AGENTS.md) with the same codegraph usage guidance the other agents already received. Without it, opencode's model would call nativeGrepinstead of thecodegraph_*tools it could see in its MCP list. - User comments and formatting in
opencode.jsoncsurvive install / re-install / uninstall round-trips — surgical edits viajsonc-parserrather than full-file rewrites.
v0.7.7
0.7.7 - 2026-05-17
Added
- Multi-agent installer (closes #137).
codegraph installnow opens with a multi-select prompt for Claude Code, Cursor, Codex CLI, and opencode — detected agents are pre-checked. Each writes its native MCP config + instructions file (e.g.~/.cursor/mcp.json+.cursor/rules/codegraph.mdc,~/.codex/config.toml+~/.codex/AGENTS.md,~/.config/opencode/opencode.json). The runtime MCP server was already agent-agnostic; this brings the installer to parity. - Non-interactive install flags for scripting / CI:
--target=<csv|auto|all|none>,--location=<global|local>,--yes,--no-permissions,--print-config <id>. codegraph initnow auto-wires project-local agent surfaces for any agent configured globally. In practice: Cursor's.cursor/rules/codegraph.mdcis dropped oninitso a single globalcodegraph installworks in every project you open — no per-project re-install needed.
Fixed
- Cursor: globally-installed codegraph reported "not initialized" in every workspace because Cursor launches MCP-server subprocesses with the wrong working directory and doesn't pass
rootUriin the MCP initialize call. We now inject--pathinto Cursor's MCP args — absolute path for local installs,${workspaceFolder}for global installs.
Changed
- Agent-instructions template is now agent-agnostic. The previous template was inherited from the Claude-only era and prescribed "spawn an Explore agent" — a Claude Code-specific concept that confused Cursor's and Codex's agents and caused them to fall back to native grep even with codegraph available. The new template adds explicit "trust codegraph results, don't re-verify with grep" guidance and a clear tool-by-question matrix. Applies to
~/.claude/CLAUDE.md,.cursor/rules/codegraph.mdc, and~/.codex/AGENTS.md. codegraph installprompt order: agent picker is now step 1, before the PATH-install and location prompts.- Disambiguated "global" wording in install prompts ("Install codegraph CLI on your PATH?" vs "Apply agent configs to all your projects, or just this one?") — both used to say "Global" and read as duplicates.
Internal
- New
AgentTargetinterface insrc/installer/targets/— adding a 5th agent (Continue, Zed, Windsurf, …) is a new file + one entry inregistry.ts. - Hand-rolled TOML serializer for Codex (
src/installer/targets/toml.ts) — no new dependency, scoped to the[mcp_servers.codegraph]table only, sibling tables and[[array_of_tables]]preserved verbatim. - +47 parameterized contract tests across the 4 targets — install idempotency, sibling preservation, uninstall reverses install, byte-equal re-runs return
unchanged, partial-state recovery for Codex.
Based on substantive draft by @andreinknv
(fork commit c5165e4).
Thank you.
v0.7.6
0.7.6 - 2026-05-13
Fixed
codegraphCLI failing withzsh: permission denied: codegraphafter a fresh global install. The published 0.7.5 tarball shippeddist/bin/codegraph.jswithout the executable bit, so the shell refused to run it through the npm symlink. The build nowchmod +x's the binary before packing.
Already on 0.7.5? Either upgrade to 0.7.6, or unblock yourself in place:
chmod +x "$(npm root -g)/@colbymchenry/codegraph/dist/bin/codegraph.js"