All notable changes to CodeGraph are documented here. Each entry also ships as
a GitHub Release tagged
vX.Y.Z, which is where most people will look.
This project follows Keep a Changelog and adheres to Semantic Versioning.
application.properties / application.yml) by key only, and never includes their values in codegraph_explore or codegraph_node output. Previously a secret committed to one of these files — a database password, API key, or connection string with embedded credentials — could be surfaced to an AI agent that asked about nearby code, even though the agent never opened the file. The configuration keys are still indexed, so reference and impact analysis are unaffected; an agent that genuinely needs a value reads the file itself. Shopify Liquid {% schema %} blocks are likewise indexed by name only. (#383)codegraph_node MCP tool can now read a whole source file like the built-in Read tool — only faster, served from the index. Pass a file path with no symbol and it returns that file's current source with line numbers (the same <n>⇥<line> shape Read produces, so an assistant can edit straight from it), narrowable with offset/limit exactly like Read, plus a one-line note of which files depend on it (the file's blast radius). Use it anywhere you'd reach for Read on an indexed source file. Pass symbolsOnly: true for just the file's structure. Configuration/data files (.yml / .properties) are summarized by key only, never dumped, so secrets in them are never surfaced. The agent-facing guidance was also retuned so assistants reach for codegraph while implementing a change (not only when answering questions), since one codegraph call returns the same bytes plus the blast radius, faster than re-reading the file.codegraph upgrade command updates CodeGraph to the latest release in place — it detects how you installed (the standalone install.sh / install.ps1 bundle, npm, or npx) and does the right thing for each, on macOS, Linux, and Windows. Use codegraph upgrade --check to see whether an update is available without installing, or codegraph upgrade <version> to move to a specific version. After upgrading it reminds you to re-index your projects so they pick up the newer engine's improvements. (#679)codegraph status now flags when a project's index was built by an older engine than the one you're running and recommends re-indexing (also surfaced in codegraph status --json), so you know when a codegraph index -f or codegraph sync will add coverage a newer release introduced.require, Shopify OS 2.0 Liquid section templates, Delphi form code-behind, Rust cross-module calls and Rocket route macros, Swift Fluent relationships, and the SvelteKit / Nuxt / Vapor / Axum route conventions. The residual everywhere is genuine static-analysis frontiers (runtime dispatch, reflection / DI, framework-convention entry points), never hidden.CatalogBrand, say — are told apart instead of collapsing into one arbitrary match, so a reference resolves to the right one and impact no longer conflates them. (C#).cshtml) and Blazor (.razor) markup are now parsed for code relationships. A @model / @inherits / @inject directive links the view to the C# view-model, base type, or service it names; a Blazor <MyComponent/> tag (plus @typeof(...) and generic TItem="..." arguments) links to the component class; and the C# inside @code { } / @functions { } / @{ } blocks is analyzed too, so services and types used in component logic are linked. A view-model, component, or service referenced only from markup is no longer reported as having no dependents, and editing it surfaces the views that use it. (ASP.NET, Blazor)@using namespaces — including the folder's cascading _Imports.razor — so a simple name that exists in several namespaces lands on the right one. A @model / <MyComponent> / @code reference to CatalogBrand resolves to the @using'd DTO (BlazorShared.Models.CatalogBrand) rather than a same-named domain entity. (ASP.NET, Blazor)codegraph status --json now also reports the running CLI version, the index directory (indexPath), and a lastIndexed timestamp (ISO-8601, or null when nothing's indexed yet), so CI and scripts can pin the CLI version and check index freshness from a single command. A matching CodeGraph.getLastIndexedAt() library method exposes the same freshness check without shelling out. Thanks @12122J and @eddieran. (#329)type MyServiceList = [Service<'query_apply_record', …>, Service<'apply_confirm', …>] — now index each entry's string-literal name as a searchable symbol. Previously these names existed only as type arguments, so codegraph query query_apply_record found nothing even though the names are the app's primary API surface. The pattern is common in typed RPC / BFF clients and mock servers where the types are the source of truth for a runtime proxy object. Utility types (Pick, Omit, Record) and route paths are deliberately left out to avoid noise. Thanks @jiezhiyong. (#634) (TypeScript)CODEGRAPH_DIR environment variable sets the per-project index directory name (default .codegraph). This lets one working tree hold two independent indexes — most usefully when you open the same checkout from both Windows and WSL, which can't safely share a single .codegraph/: the background-server lock and the SQLite database are tied to the OS that wrote them, and SQLite locking across the WSL2/Windows filesystem boundary is unreliable. Set CODEGRAPH_DIR=.codegraph-win on the Windows side, leave WSL on the default, and each keeps its own index in the same folder without clobbering the other. CodeGraph also skips any sibling .codegraph-* directory when indexing and watching, so neither environment trips over the other's data. Thanks @rrtt2323. (#636)New().Method() used to drop the receiver, so the chained method attached to a same-named method on an unrelated type — or didn't resolve. CodeGraph now captures Go return types (a pointer *Foo resolves to Foo, and a multi-return (*Foo, error) to its first result), infers the chained receiver's type from what the factory function returns, and resolves the method on it — including methods promoted from an embedded struct — creating the edge only when the type or an embedded type genuinely has the method. Existing Go indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Go)apply now resolve to the correct type. A call like Foo.create().bar() or Builder(cfg).bar() used to drop the receiver, so the chained method silently attached to a same-named method on an unrelated type — most often mis-attributing a standard-library Option / Iterator .map / .flatMap / .foreach onto your own same-named class. CodeGraph now captures Scala return types (a generic List[Foo] resolves to its container List, a qualified pkg.Foo to Foo), infers the chained receiver's type from what the inner call returns or constructs, and resolves the method on it — including methods inherited from a trait the type extends — creating the edge only when that type or one of its traits genuinely has the method (so a wrong inference produces no edge instead of a misleading one). Existing Scala indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Scala)Foo::new().bar() or Foo::with(cfg).build() used to drop the receiver, so the chained method silently attached to a same-named method on an unrelated type — or didn't resolve. CodeGraph now captures Rust return types (-> Self resolves to the implementing type), infers the chained receiver's type from what the associated function returns, and resolves the method on it — including methods provided by a trait the type implements (via the new impl Trait for Type relationships) — creating the edge only when the type or one of its traits genuinely has the method. Existing Rust indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Rust)Foo.create().bar() used to drop the receiver, so the chained method silently attached to a same-named method on an unrelated type — most often mis-attributing a standard-library Option / Iterator .map / .where onto your own same-named class. CodeGraph now indexes Dart factory and named constructors (factory Foo.create(), Foo.named()) as first-class members so calls to them resolve, captures Dart return types (a generic List<Foo> resolves to its container List), infers the chained receiver's type from what the inner call returns or constructs, and resolves the method on it — including methods inherited from a superclass or mixin — creating the edge only when that type genuinely has the method. Plain construction (Foo(...)) is still recorded as instantiation. Existing Dart indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Dart)[[Foo create] doIt] used to drop the receiver, so doIt silently attached to a same-named method on an unrelated class — most often a test helper or stdlib class. CodeGraph now captures Objective-C method return types and infers the chained receiver's type from what the inner message returns. For the ubiquitous [[X alloc] init] and singleton ([[X sharedInstance] …]) patterns — where the factory returns instancetype — the receiver is the class X itself, so the chained method resolves on X (including methods inherited from a superclass), creating the edge only when the class genuinely has the method. Existing Objective-C indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Objective-C)TFoo.GetInstance().DoIt() used to drop the receiver, so DoIt silently attached to a same-named method on an unrelated class. CodeGraph now captures Pascal return types and infers the chained receiver's type from what the factory function returns — resolving to the declared type (including an interface return like IFoo), and for a constructor (TFoo.Create().…) or a typecast (TFoo(x).…) to the class TFoo itself, since both yield a TFoo. The edge is created only when that type genuinely has the method (so a wrong inference produces no edge). Existing Pascal/Delphi indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Pascal/Delphi)Obj.Free;, List.Clear;, TFoo.GetInstance.DoIt;), which previously weren't recorded as calls at all — so callers, impact, and trace missed them. CodeGraph now extracts these, scoped to statement position so a field or property access (which looks identical) is never mistaken for a call. On a real Delphi codebase this added ~1,100 previously-missing call edges with no false positives. Existing Pascal/Delphi indexes should be re-indexed (codegraph index -f) to benefit. (Pascal/Delphi)interface declaration, defined only in the implementation section) are now attributed to that routine instead of the whole file. Previously such a routine had no symbol of its own, so everything it called was lumped under the unit — codegraph_callers returned the file, and impact couldn't tell which routine was responsible. These routines are now indexed and their calls attributed correctly. Existing Pascal/Delphi indexes should be re-indexed (codegraph index -f) to benefit. (Pascal/Delphi)Either.Right(x).combine(...)) that invokes a method defined on its parent type. Previously these chains found no caller edge even though the factory's type was known, so the call was invisible to callers, impact, and trace. CodeGraph now walks the type's supertypes (its extends / implements relationships) to find the method, creating the edge only when a supertype genuinely declares it (so a wrong inference still produces no edge). This makes Java, Kotlin, and C# factory and fluent chains more complete. Existing indexes should be re-indexed (codegraph index -f) to benefit. (#750)Foo.make().draw() or Foo().draw() used to drop the receiver, so the chained method silently attached to a same-named method on an unrelated class — or didn't resolve at all. CodeGraph now captures Swift return types and infers the chained receiver's type from what the inner call returns (or the constructed type), creating the edge only when that class genuinely has the method (so a wrong inference produces no edge instead of a misleading one). Existing Swift indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Swift)Foo.Create().Bar() or JObject.Parse(s).Property(...) used to lose the receiver's type, so the chained method didn't resolve and the call was invisible to callers/impact/trace. CodeGraph now captures C# return types and infers the chained receiver's type from what the inner call returns, creating the edge only when that class genuinely has the method (so a wrong inference produces no edge). Existing C# indexes should be re-indexed (codegraph index -f) to benefit. (#750) (C#)Foo.getInstance().bar() or Config.create(opts).build() used to drop the receiver entirely, so the chained method silently attached to a same-named method on an unrelated class — or didn't resolve at all — corrupting callers, impact, and trace. CodeGraph now captures Kotlin return types and infers the chained receiver's type from what the inner call returns, creating the edge only when that class genuinely has the method (so a wrong inference produces no edge instead of a misleading one). Existing Kotlin indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Kotlin)Foo.getInstance().bar() or Config.create(opts).build() used to lose the receiver's type, so when two classes had a same-named method the call silently attached to whichever was indexed first — or didn't resolve at all — corrupting callers, impact, and trace. CodeGraph now captures Java return types and infers the chained receiver's type from what the inner call returns, creating the edge only when that class genuinely has the method (so a wrong inference produces no edge instead of a misleading one). Covers factories and fluent builders that take arguments (hashKeys().arrayListValues()), including builders that return a nested type. Existing Java indexes should be re-indexed (codegraph index -f) to benefit. (#750) (Java)Cls::for($x)->method(...), the canonical Laravel per-credential / per-tenant client idiom — now records a caller edge. Previously the receiver type (what for() returns) was never recovered, so codegraph_callers returned nothing for the method and the call was invisible to codegraph_impact. CodeGraph now captures PHP return types — : self / : static resolve to the declaring class, : SomeClass to that class — and resolves the chained method on the factory's result, creating the edge only when that class actually has the method (so a wrong inference produces no edge). Existing PHP indexes should be re-indexed (codegraph index -f) to benefit. Thanks @cvanderlinden. (#608) (PHP)MyApp backend routes) no longer buries the part of the codebase the query is actually about. The project name lexically matches whatever stack embeds it — a MyAppFrontend/ directory, a MyAppApp class — and it was over-weighted two ways: a single PascalCase word was scored once per sub-token (my / app / myapp), so one concept boosted that path several times over; and the name carried full path / disambiguation weight even though it names the whole repo, not any symbol. Now path relevance counts each query word once, and a word matching the project name (derived from go.mod, package.json, or the repo directory) is dropped from path scoring and from codegraph_explore's type-disambiguation bias — unless it's the only term, so a bare project-name search still works. In a mixed-stack repo, a backend question now surfaces the backend even with the project name in the query. Thanks @MiNuo1. (#720)RunE: func(…) {…} handler, a goroutine literal, or a callback closure stored in a package-level var — now shows its real caller. Previously the call leaked to the file node, so codegraph_callers and codegraph_impact reported such a function as having no meaningful caller; the call is now attributed to the enclosing declaration, so editing the function surfaces the closures that use it. Existing Go indexes should be re-indexed (codegraph index -f) to benefit. Thanks @Cyclone1070. (#693) (Go).gitignore contains non-UTF-8 bytes or an unparseable pattern. A .gitignore transparently encrypted in place by corporate DLP / endpoint-security software (a common enterprise scenario) — or one with a stray pattern the matcher can't compile (\[, producing "Unterminated character class") — used to crash the entire sync / index with a screen of garbled bytes and never name the offending file, leaving Files: 0 / Nodes: 0. CodeGraph now skips a .gitignore that isn't valid UTF-8 text whole, drops only the individual unparseable patterns from a text one, and logs a warning naming the file — indexing continues either way. Thanks @zhanghang-9527. (#682)Foo::instance().bar(), WidgetFactory::create().draw(), openSession()->run(), or the same stored in an auto local first, used to lose the receiver's type — so when two classes had a same-named method the call silently attached to whichever was indexed first (or didn't resolve at all), corrupting callers, impact, and trace. CodeGraph now infers the receiver's type from what the inner call returns (capturing C++ return types for the first time) and creates the edge only when that class genuinely has the method, so a wrong guess produces no edge instead of a misleading one. Covers singletons and self-returning accessors, factories that return a different type, free-function factories, make_unique / make_shared / new / direct construction, and single-level member chains. Existing C/C++ indexes should be re-indexed (codegraph index -f) to benefit. Thanks @stabey. (#645) (C/C++)[error] … undefined line on every session start. Attaching to the shared daemon is normal, healthy behavior, but the informational message was being surfaced by MCP hosts (Claude Code and others) as an error; it's now silent by default — set CODEGRAPH_MCP_LOG_ATTACH=1 to surface it when debugging daemon attach. Thanks @mturac. (#618)sendEvent(context, "X", body) wrapper. Many libraries (react-native-device-info and others) wrap the event emitter behind a helper whose .emit(eventName, …) takes a variable, so the matcher — which looked for .emit("literal", …) — missed it; the literal event name actually lives in the wrapper call. Now a native method that fires sendEvent(…, "batteryLevelChanged", …) links to the JS addListener('batteryLevelChanged', …) handler, so editing the native emitter surfaces the JS subscriber. (React Native)AsyncFunction<Float>("getBatteryLevelAsync") — is now indexed (the <Float> used to defeat the matcher, so every Android Expo method was dropped and a JS call resolved only to the iOS Swift impl). The iOS and Android implementations of the same JS-visible method — both Expo Modules and classic NativeModules (@ReactMethod on Android, the matching method on iOS) — are now linked to each other, so a JS call that resolves to one platform still reaches the other and editing either platform's native code surfaces the JS caller. And a Type.member static read in native code (e.g. Android's BatteryManager.EXTRA_LEVEL) no longer falsely links to a coincidentally same-named class in another language (a web BatteryManager) — type references stay within a language family, while genuine cross-language bridges (config→code, JS↔native calls) are unaffected. (React Native, Expo)TestRunner type and a Kotlin TestRunner class, a TS reference to TestRunner — or an import React sitting next to a Swift React — used to resolve onto the native symbol (the component resolver matched any same-named class regardless of language, and import statements weren't language-checked at all). References and imports now stay within their language family, so they land on the right symbol while genuine cross-language bridges (JS↔native calls, config→code) are untouched. A C/C++ #include "Foo.h" likewise no longer resolves to a same-named header from another platform (an iOS Objective-C Foo.h). (React Native, Expo, TypeScript, C/C++)#include "Foo.h" now resolves to the header in the including file's own directory first (the C quoted-include rule), so when a module ships a same-named header per platform (a Windows, an Apple, and an Android Foo.h side by side) the local one correctly shows its dependents instead of an arbitrary other-platform header looking like the dependency. And a Kotlin Multiplatform expect declaration is no longer reported as having no dependents: a commonMain import now resolves to the commonMain expect (matched within the importing source set) rather than being absorbed by one platform's actual. (C/C++, Kotlin)codegraph affected now reports the tests and files that actually depend on your changes. It used to follow only import statements — but those never cross file boundaries in CodeGraph's graph — so it returned no affected tests for any change, in every language. It now traces the real cross-file usage graph (calls, references, instantiations, and class extends / implements), so git diff --name-only | codegraph affected surfaces the test files that exercise the changed code. Circular-dependency detection, which had the same blind spot, now works too.codegraph affected now recognize far more of the dependencies that were already in your code. A symbol now counts as a dependency whether it's called, used only in a type annotation inside a function body (const items: Foo[] = []), imported and placed in a registry array or passed as an argument, used as a JSX component, simply re-exported from a barrel (export { X } from './x'), or pulled in as a namespace (import * as ns from '@/x') — including through tsconfig path aliases like @/. Previously only called, instantiated, or signature-typed symbols created a cross-file link, so a file that used a dependency in any other way could look like it depended on nothing — and the file that defined a widely-used symbol could look like nothing depended on it. The graph still indexes exactly the same symbols; it just connects the ones that were already there. (TypeScript/JavaScript)from module import X is recorded as a dependency on that module even when X is only stored in a list/dict, passed as an argument, used as a decorator, or re-exported through an __init__.py. Previously Python linked only imports that were called or instantiated, so a module consumed purely by value — or only re-exported — looked like nothing depended on it.codegraph_callers (and the callers command) now lists the places a class is instantiated, not just where it's imported. Constructing a class — Foo(...) in Python, new Foo() elsewhere — is calling its constructor, so asking who calls a class now returns the construction sites, and codegraph_callees / trace cross the instantiation the same way. Previously a class's instantiation sites were invisible to callers, so "what breaks if I change this class?" could come back empty even when the constructor was called from many places. Works on your existing index — no re-index needed. (#774)codegraph affected now connect far more of the module graph. Struct literals (Widget { n: 1 }) are recorded as instantiations; a use / pub use brings its item into the dependency graph — so a pub use re-export hub (a mod.rs re-exporting its submodules) depends on the modules it re-exports — resolved by Rust module path (crate::/self::/super::), so a re-export of a common name like read links to the right module instead of a same-named symbol elsewhere; and trait dispatch reaches implementations — a struct whose methods cover a trait's is treated as implementing it, and a call through &dyn Trait resolves to the concrete method. Previously a Rust type linked only when called or used in a type position, so structs built by literal, modules surfaced only through pub use, and trait-only implementations looked like they had no dependents. (#584 for Rust traits)users::router(), the common router-assembly / handler-registration pattern where mod users; makes users a child of the current module — is now resolved relative to the current module, not only the crate root. Deeper module-path calls (database::profiles::find() — the db.run(|c| …) data-access shape) now resolve too; these were being discarded before resolution even ran, because the path's leaf function name was never checked. Previously such a call linked to nothing, so a module reached only as module::path::function() looked like it had no dependents; a web app wired this way (Axum, Rocket, and similar) now surfaces its handler and data-access modules' real callers. (Rust)routes![a::b::handler, …] or catchers![…] macro used to be invisible — the macro body is a raw token tree, so the handler looked like it had no caller (Rocket mounts it at runtime) and its file showed no dependents. The handler paths are now read out of the macro and linked to the mount/register call, so editing a Rocket handler surfaces its route registration and a routes module is no longer reported as unused. (Rust, Rocket)load functions. SvelteKit wires a +page.server.js / +page.js load (and form actions) to the sibling +page.svelte's data by file path, with no import between them — so editing a load previously showed no impact on the page it feeds. Each page is now linked to the load/actions in its own route directory (and likewise for +layout), so editing a loader surfaces the page that renders its data, and tracing a page reaches its server-side data source. (Svelte, SvelteKit)components/media/Card.vue is used in templates as <MediaCard/> — but it was tracked by its file name (Card), so the usage didn't resolve and the component looked unused. PascalCase component tags (<MediaCard>, <NavBar>) in a .vue template are now matched, falling back to the Nuxt directory-prefixed name, so editing a nested component surfaces every page and component that renders it. (Vue, Nuxt)require calls now connect to their module files. A dotted module path (require("telescope.config") → telescope/config.lua or .../config/init.lua) and a Roblox/Luau instance-path require (require(script.Parent.Signal) → the Signal module) now link to the file they load, so editing a module surfaces every file that requires it. Previously requires resolved to nothing, so a Lua/Luau module looked like it had no dependents. (Lua, Luau)templates/*.json, plus section groups sections/*.json) that list sections by type rather than with a {% section %} Liquid tag, so a section used only from a JSON template was reported as having no dependents. Those JSON files are now read and each section type is linked to its sections/<type>.liquid, so editing a section surfaces the templates that render it. (Liquid, Shopify).dfm (VCL) or .fmx (FireMonkey) form is owned by its same-named .pas unit through the {$R *.dfm} directive rather than a uses clause, so a form file used only as a definition was reported as having no dependents. The unit is now linked to its form, so editing a form surfaces the unit that owns it. (Pascal/Delphi)@Argument / @Published / @State / custom @propertyWrapper on a property — and attributes on types, methods, and functions (@objc, @MainActor, …) — now record a dependency on the wrapper/attribute type. Previously these were dropped entirely (Swift attributes parse differently from other languages, and stored properties weren't being inspected), so the wrapper type looked unused and the file using it depended on nothing — a big gap for SwiftUI and argument-parser-style code.@Siblings(through: AcronymCategoryPivot.self, …), the many-to-many pivot/join model — now records a dependency on that type. Previously only the wrapper itself (Siblings) and the property's declared type were captured, so a pivot model reached solely through the relationship looked like nothing depended on it and editing it surfaced no impact. (Swift, Vapor/Fluent)@interface Foo) are indexed as types, and every @Foo usage on a class, method, or field is recorded as a dependency on it. Previously neither side was captured — annotation usages were dropped (they live inside the declaration's modifiers) and @interface types weren't indexed at all — so annotation-driven code (Spring @GetMapping, JPA @Entity, Gson @SerializedName, …) showed the annotation as having no users and the annotated class as not depending on it.expect/actual declarations are now connected. A platform implementation — actual fun, actual class, or an actual typealias in a jvm / native / js / wasm source set — is linked to the common expect declaration it fulfills (including the common case of an expect class fulfilled by an actual typealias). Previously a caller in common code resolved to the expect declaration, so every platform actual looked like it had no dependents and editing one showed an empty blast radius; now changing a platform implementation surfaces the common API and everything that uses it. (Kotlin)codegraph affected now connect the type graph that typeclass-style code is built on. A parameterized supertype (trait Monoid[A] extends Semigroup[A] with Serializable) now links to each parent; a type used in a val/def signature, as a type argument, or as a context bound (def f[A: Monoid]) — including the trailing implicit parameter list ((implicit M: Monoid[A])) where typeclass instances are passed — now records a dependency; and new T[...] { … } counts as an instantiation. Previously Scala linked only plain calls and bare, non-generic supertypes, so a trait extended with type parameters, used as a type, or required as an implicit looked like nothing depended on it — which on a typeclass-heavy codebase (cats, algebra) was most of the graph. (Scala)codegraph affected now understand namespaces and use imports. Classes are tracked by their namespaced name, so the many same-named classes a framework defines (Laravel has 7+ Factory interfaces, several Dispatchers, across namespaces) are told apart instead of collapsing into one arbitrary match. A use App\Contracts\Cache\Factory; now records a dependency on exactly that class — so a contract or interface that's imported and constructor-injected (the dependency-injection pattern) is no longer reported as having no dependents — and parameter, property, and return type-hints are recorded too. Previously PHP ignored namespaces entirely and linked only calls, new, and inheritance. (PHP)codegraph affected are dramatically more complete. Four gaps are fixed: a single-argument message ([cache storeImage:key] — the most common call form) now matches its storeImage: method instead of dropping the colon; a class-message receiver ([SDImageCache sharedCache], [[Foo alloc] init]) now records a dependency on the class, whose @interface lives in the header; #import "Foo.h" now resolves to the header file, so a header is no longer reported as having no dependents; and class-method message calls now resolve through the receiver type. Together these took typical libraries from a third-to-half of their files showing real dependents to ~90%. (Objective-C)MediaKind.video), a static constant (Colors.red, JsonScope.EMPTY_DOCUMENT), or a class constant (Foo::BAR) now links to the type — previously only method calls and new did, so a type or enum used purely by value (enum-heavy APIs, constants classes — a very common pattern) looked like nothing depended on it. Applies to Java, C#, Kotlin, Swift, Scala, Dart, PHP, and C++.codegraph affected now follow mixins and method type annotations. A with mixin — Dart's core composition mechanism, which Flutter is built on — now records a dependency, so editing a mixin surfaces every class that mixes it in (the whole with clause used to be dropped, and a class declared with M alone even lost its real superclass link). And types used in a method's parameters or return value now link to their definition, so a class or enum referenced only as a type — not constructed or called — is no longer reported as having no dependents. (Dart)std::string TableFileName(const std::string& dbname)) or an auto … -> std::string trailing return type was mistakenly named after that type (string), so calls to it never resolved, codegraph_node couldn't find it by name, and the file defining it looked like nothing depended on it. The function now keeps its real name, so cross-file calls, callers, and blast radius work — a meaningful gain for any namespaced C++ codebase (this is how most free functions in a library look). (C++)codegraph affected now follow mixins and requires. include, extend, and prepend of a module — Ruby's primary composition mechanism (ActiveSupport concerns, Comparable, Enumerable) — now record a dependency on that module, so editing a concern surfaces every class that mixes it in; previously these were read as a call to a method named include, so a module whose methods are exercised only by application code looked like nothing depended on it. And require "lib/foo" / require_relative "../foo" now link to the required file, so a file pulled in only by a require (config-loaded components, gems that don't autoload) is no longer reported as having no dependents. Together these took a typical gem from ~71% of its files showing real dependents to ~100%. (Ruby)record types are now indexed. record, record class, and record struct declarations (everywhere in modern C# — DTOs, value objects, CQRS messages, MediatR notifications) were previously skipped entirely, so every reference, generic type argument (IEnumerable<MyRecord>), and new MyRecord(...) pointed at nothing and the file defining a record looked like it had no callers or dependents. (#237)class OrderService(IRepo repo, [FromKeyedServices("primary")] ICache cache) { … } is now indexed reliably — previously the constructor parameter list confused the parser and could drop the whole class (and all of its methods) from the index, most often exactly when a parameter carried an attribute, as in the ASP.NET keyed-dependency-injection pattern. The primary-constructor parameters are also recorded as dependencies, so the services a type is constructed with show up in its blast radius and "who depends on this contract" answers. Method return types, base types, and members all continue to resolve, and #if-guarded members in multi-targeting code keep parsing correctly. (#237)implements keyword — a type satisfies an interface just by having the right methods — so CodeGraph now infers that link: a struct whose methods cover an interface's method set is treated as implementing it, and a call through the interface (API.Marshal(...)) reaches every concrete implementation. This means a type used only via an interface (the common plugin/strategy pattern — e.g. JSON-codec or renderer implementations selected at runtime) is no longer reported as having no callers or no dependents, and impact now flows from an interface method to the implementations behind it. (#584)render.XML{...} or pkga.Widget{...} — including ones registered in a package-level var registry = map[string]R{...} — now links to the package that defines the type. Cross-package function calls and type references already resolved; this closes struct instantiation, so a package whose types are only constructed elsewhere (a common pattern for interface implementations) is no longer reported as having no dependents. Go type conversions such as (*Wrapped)(x) now link to the converted-to type as well.from . import certs then certs.where(), or from pkg import sub then sub.run(). Calls and attribute access through an imported submodule now resolve to that submodule, and importing a module is recorded as a dependency on it even when the member you use is itself re-exported from a third-party package. This also fixed Python relative-import path resolution generally (from .sub.mod import x), so codegraph affected and impact see the real module graph of a package.import conduit.apps.signals) to that module's file, not just from x import y. A module imported by its dotted path — common in package setup and side-effect imports — is no longer reported as having no dependents. Standard-library imports (import os) correctly create no edge. (Python)from package import submodule now links to that submodule's file, resolved through the import's package so it lands on the right one when same-named modules exist in sibling packages (the FastAPI / Django router-aggregator pattern: from app.api.routes import authentication with an unrelated authentication.py elsewhere). So a route/handler module pulled in only by an aggregator is no longer reported as having no dependents. (Python)from pkg import module (or import pkg.module) followed by module.func(), a common testing and namespacing pattern. Previously only the module-level dependency was tracked, so codegraph_callers, codegraph_callees, and impact on the target function came back empty even though the import itself resolved. (#578) (Python)include('app.urls') now records a dependency from the project URLconf onto the included app's urls.py, so an app's routes module is no longer reported as having no dependents and editing it surfaces the project that mounts it. (Django)builder.Services.AddCoreServices(...)) now resolves to its definition. Previously only a single-segment receiver (obj.method()) resolved, so a call through a property/member chain — very common for C# extension methods like ASP.NET dependency-injection registration (AddCoreServices/AddWebServices) and Guard clauses — found no definition. (C#, and any language with chained calls)import articlesController from './article.controller' where the module does export default router) now records a dependency on the imported module. Previously only named imports linked, so a module consumed only through a default import — the standard Express/NestJS route-controller pattern — looked like nothing depended on it. External packages (import React from 'react') still create no edge. (TypeScript/JavaScript).codegraph/ index folder no longer clutters git status: its generated ignore file now excludes everything in the folder except itself, so the database, daemon.pid, sockets, and logs stop showing up as untracked changes. (#492, #484).codegraph/.gitignore written before this change — which listed only the database, cache, and logs and so let the daemon's daemon.pid get committed — is upgraded in place the next time you run any CodeGraph command. A .gitignore you've customized yourself is left untouched. (#788).xsjs / .xsjslib files are now indexed as JavaScript. (#556).mts and .cts module files are now indexed instead of being skipped. (#366)func (s *Stack[T]) Push(...)) are now correctly attached to their type, so callers, callees, and impact include them. (#583)type itself — the idiomatic split where type User struct{…} lives in one file and func (u *User) Save() in another. Previously a cross-file method was orphaned from its struct, so the type's member list, callers/callees, and impact missed it; as a knock-on, a struct whose interface-satisfying methods are spread across files now also links to the interfaces it implements. (#583)resources/list and prompts/list probes with an empty list instead of an error, clearing the -32601 messages some clients (opencode, Codex) logged on connect. (#621)export { default as Button } from './Button.svelte' re-exported from an index.ts and imported elsewhere — are no longer falsely reported as having 0 callers. CodeGraph now follows the default re-export all the way to the component and resolves the imports that .svelte / .vue files themselves use, so codegraph_callers and codegraph_impact see every place a component is used. This also covers components imported from another package in a workspace/monorepo (@scope/ui/widgets) and bare directory imports (import { x } from './'). Previously a live component consumed only through a barrel looked like dead code. Thanks @nakisen. (#629)<template> — <MyButton />, or the kebab-case <my-button /> — are now indexed as usages, so codegraph_callers and codegraph_impact include components that appear only in another component's markup (including through a barrel re-export). Previously only a Vue component's <script> block was analyzed, so template-only usages were invisible. (#629)include / require / include_once / require_once of a static path now create a file→file dependency edge, so codegraph_callers and codegraph_impact follow includes in procedural / script-style PHP codebases — previously only namespace use statements became dependency edges. Dynamic includes (include $var, require __DIR__ . '/x') are skipped. Thanks @atahan150 (#660).codegraph_explore is now the primary tool, and one call is usually all an agent needs: it returns the verbatim source of the symbols relevant to your question (a plain question works as the query — you no longer need exact symbol names), grouped by file and Read-equivalent, so the agent answers without falling back to read/grep. The narrower codegraph_context and codegraph_trace tools were removed in favor of it — explore already surfaces the call flow among the symbols you name (the job trace did), so there's one obvious tool to reach for instead of three.codegraph_explore now includes a compact "Blast radius" for the symbols you're looking at — who depends on each (just the locations, not their source) and which test files cover it — so before editing, the agent can see what else to update and which tests to run, without a separate impact lookup. Symbols nothing depends on are skipped, so it stays short.create((set, get) => ({ … })) store, and the same shape in Redux, Pinia, MobX, or any exported handler/route map — are now indexed as real symbols. Previously they existed only as object properties, so looking one up by name or asking who calls it returned "not found" and the agent had to read the whole store file to follow the flow; now codegraph_node, codegraph_callers, and codegraph_explore resolve them directly — including calls made through useStore.getState().fetchUser() or a destructured const { fetchUser } = useStore.getState().codegraph_explore now surfaces the right definition when a method name is overloaded across types. Asking about, say, DataRequest's task and validate used to return a same-named method from an unrelated file (or an abstract base stub) and bury the one you meant; explore now recognizes the type you named in the query and leads with that type's own overloads, in full.codegraph_explore's results).codegraph_node now returns every definition when a name is ambiguous — an overloaded method, or the same method name on different types — instead of returning one (sometimes the wrong one) with a note listing the rest. Asking for such a symbol now hands back all of the matching definitions with their source in a single call, so the agent stops having to read the file by hand to find the specific overload it wanted (common in Swift, Go, Java, and C#). For a heavily-overloaded name (a poll/validate with dozens of definitions), pass file (and/or line) — e.g. the file:line shown in a trail — to get that exact definition's body. Large overload sets show the most relevant ones in full and list the remainder by location.codegraph_explore never returns half a method anymore: when output runs up against its size budget it drops whole methods or whole files (and lists what it dropped, so you can ask for them in another call) instead of cutting off a method body partway. A truncated method was the one case that still sent the agent to read the file for the rest — so the source explore returns is now always complete and usable as-is.codegraph init now builds the initial index by default — you no longer need the -i/--index flag (it's still accepted, so existing commands and scripts keep working). (#483)codegraph_trace and codegraph_explore — following a request reaches the middleware and route handlers registered via .Use() / .GET() instead of dead-ending where the framework dispatches the chain dynamically.codegraph_explore now sizes its response to the answer instead of the file count: it shows the mechanism and the exact methods you asked about in full — even when they're buried deep in a large file — while collapsing the redundant interchangeable implementations of an interface (an HTTP interceptor chain, a query-compiler family) down to signatures. Fewer tokens for a more complete answer, so on the flows that used to occasionally cost more than plain grep/read it's now clearly cheaper — and the win holds across small, medium, and large codebases. Distinct, non-interchangeable code is shown in full as before. Disable with CODEGRAPH_ADAPTIVE_EXPLORE=0.codegraph_trace and codegraph_explore — following a request's lifecycle reaches the validators registered with .validate { … } instead of dead-ending where the framework runs them by iterating a stored list of closures. Any pattern where closures are appended to a collection and later invoked by looping over it is now traced.codegraph_explore now spells out the dynamic-dispatch relationships of the symbols you ask about — e.g. "the closures registered here are run by didCompleteTask" — so the indirect hops you'd otherwise grep to reconstruct are listed alongside the call flow.codegraph_explore answers multi-phase questions that span a large "god file" far more completely. For a flow like "build, send, and validate a request" — where one big file holds the build chain and the validate logic lives in others — it now keeps every method on the flow path in full, collapses the file's off-path methods to one-line signatures, and guarantees each phase's defining file is shown (instead of truncating at a fixed size and dropping whichever phase came last, which sent you to read it by hand). Incidental files that merely name-drop the flow are still trimmed, so the response stays focused on the code that answers the question.require("@colbymchenry/codegraph") and import now resolve the programmatic API — the CodeGraph class plus building blocks like DatabaseConnection, QueryBuilder, initGrammars, and FileLock — so you can drive the graph directly from your own app (for example an Electron process) instead of only through the CLI or MCP server. Embedding runs on your own runtime, so it needs Node 22.5+ for the built-in SQLite. (#354)codegraph_trace now resolves an overloaded symbol name to its real implementation instead of an empty protocol/delegate stub. Tracing a flow through a heavily-overloaded API (common in Swift, Java, C#, and Go) could land on an unrelated no-op method that happened to share the name and report "no path"; it now picks the substantive definition the flow actually runs through..properties) no longer misleadingly reports "No files found to index" — these files are tracked at the file level and are now counted as indexed. Thanks @luojiyin1987 (#357).codegraph_trace can't find a static path (a dynamic-dispatch break), it now inlines both endpoints' source, callers, and callees in one response, so the agent gets the full picture without a flurry of follow-up calls.codegraph_explore (Go, Ruby, JS/TS, Java/Kotlin/Scala), so the explore budget goes to your real implementation source.codegraph_context now auto-traces flow questions like "how does X reach Y" or "trace the path from A to B", splicing the trace into the response so you don't need a separate codegraph_trace call.codegraph_context now inlines a URL-to-handler routing table and the source of your main routes file for routing questions on small projects, so you don't have to go read routes.rb or web.php yourself.codegraph_context search now boosts results in the directory of a project's core framework file, so a small same-named extension file no longer outranks the actual framework core.new T() { ... }) and their overridden methods are now indexed as real class nodes, so an agent sees those hidden overrides in its trail without a Read.## CodeGraph instructions block into your agent's instructions file (CLAUDE.md, AGENTS.md, GEMINI.md, Cursor's .cursor/rules/codegraph.mdc, or Kiro's steering doc) — the MCP server is now the single source of truth, and re-running codegraph install or codegraph uninstall strips a block a previous version left behind (#529). If you added your own notes inside the CODEGRAPH_START/CODEGRAPH_END markers, move them outside the markers first, since the whole marked block is removed.codegraph index and init -i now report the true edge count in their summary, instead of undercounting by missing resolution and synthesizer edges.@Value and @ConfigurationProperties references resolve to the matching keys in your application.yml/.properties config (including relaxed kebab/camel/snake binding), and field-injected concrete beans like this.field.method() resolve through to their implementation (#389).codegraph install, detected and configured out of the box with sibling settings and MCP servers preserved across re-installs (#399).codegraph install on macOS, Linux, and Windows, with its own steering file so it loads CodeGraph guidance naturally (#385).#include "header.h" directives now connect to the real header file instead of a phantom import, so includes show up as true file-to-file edges; system and stdlib headers are filtered out so they don't false-resolve (#453).type aliases with object shapes (including function-typed members and intersection types) now surface their members in the graph, so a call like handle.stop() resolves to the alias member instead of an unrelated look-alike class in a sibling directory (#359).pkg.Func() now resolve to the right package by reading your go.mod, so callers, callees, impact, and trace return complete results on Go monorepos instead of almost nothing (#388).codegraph_files now returns the whole project when an agent passes a root-ish path like /, ., ./, "", or a Windows-style \, and subdirectory filters like /src, ./src, and src\components all resolve correctly instead of returning "No files found" (#426).const token = getToken()) and inside inline object-literal methods are no longer dropped, so they show up in callers as expected, including in Vue single-file components (#425).FOREIGN KEY constraint failed error in a long-running daemon; a stale lookup now drops a single edge instead of failing the whole sync (#455).codegraph install --target hermes no longer corrupts ~/.hermes/config.yaml, correctly handling PyYAML's block-style lists and re-installing cleanly even on an already-corrupted file (#456).RouterModule.register([...]) (including nested children) now propagate to controller routes, so a route shows up at its full path like GET /admin/users instead of GET / (#459).m_alg->Processing(), including out-of-line method definitions and the common case of two classes sharing a method name (#445, #454).CODEGRAPH_DAEMON_IDLE_TIMEOUT_MS (default five minutes).CODEGRAPH_NO_DAEMON=1 to opt out and get one independent server per client, handy for debugging or sandboxes that disallow local sockets; the daemon is also version-pinned, so upgrading CodeGraph never mixes versions over the connection.CODEGRAPH_WATCH_DEBOUNCE_MS lets you tune the file-watcher quiet window (default 2000ms) for workspaces with bursty writes like format-on-save chains or large generated outputs, without touching your agent's command line (#403)..m, .mm, and content-sniffed .h files now parse with full structural extraction, including full multi-part selectors, properties, imports, and superclass/protocol relationships, so trace, callers, and callees work across iOS codebases (#165).codegraph init -i in the worktree (#155)..gitignore) before registering watches, so CodeGraph can run alongside your editor or dev server without hitting the per-user watch ceiling (#276).git pull, branch switches, and edits made outside your editor; change detection is filesystem-based instead of relying on git status, so pulled or checked-out code is picked up without a full re-index.node_modules, vendor, dist, build, target, .venv, __pycache__, Pods, and .next are now excluded by default, so context and search reflect your code instead of third-party noise even in a project with no .gitignore; add a .gitignore negation to index one anyway (#407).codegraph_trace, codegraph_callees, and codegraph_explore now follow flows that have no static call edge — callback and observer registration, EventEmitter, React re-renders and JSX children, Flutter setState to build, C++ virtual overrides, and Java/Kotlin interface-to-implementation dispatch (like Spring's @Autowired service calls) — and each bridged hop is labeled inline in trace with where it was wired up.codegraph_trace now returns a self-contained flow dossier: every hop shows its full body inline plus the destination's own outgoing calls, so a single trace usually answers a "how does X reach Y" question without a follow-up explore, node, or Read.codegraph_explore now leads with the execution flow when your query names the symbols of a flow, finding the call path among those symbols (including across dynamic-dispatch hops) so you get a trace-quality answer without switching tools.codegraph_node and codegraph_trace now emit line-numbered source (matching codegraph_explore and Read), so you can cite or edit exact lines without re-reading the file just to recover line numbers.CODEGRAPH_MCP_TOOLS environment variable lets you expose only a chosen subset of codegraph tools over MCP (e.g. trace,search,node,context) without editing your client's MCP config; unset exposes all of them.SHA256SUMS file, and the npm launcher verifies the bundle it downloads against it, aborting on a mismatch (releases published before this change skip verification rather than failing).index/get/update that were being silently dropped, and an explore output-budget issue that under-returned source on repos with very large files.codegraph serve --mcp no longer keeps running after its parent agent is force-killed (OOM, kill -9, or container teardown) on Linux, where it used to hold inotify watches, file descriptors, and the SQLite WAL indefinitely; the server now shuts down as soon as its parent process changes, tunable via CODEGRAPH_PPID_POLL_MS (#277).@colbymchenry/codegraph through a registry mirror that hadn't yet mirrored the matching per-platform package no longer fails with no prebuilt bundle for <platform>; the launcher now downloads the bundle from GitHub Releases and caches it, with CODEGRAPH_NO_DOWNLOAD=1 to disable the fallback and CODEGRAPH_DOWNLOAD_BASE to point it at your own mirror (#303).install.sh no longer fails with 403 / "could not resolve latest version" on shared or cloud hosts that exhaust GitHub's unauthenticated API rate limit; it now resolves the version through the unthrottled releases redirect, and CODEGRAPH_VERSION accepts a bare version like 0.9.4 as well as v0.9.4 (#325).codegraph uninstall command cleanly removes CodeGraph from every agent it's configured on — Claude Code, Cursor, Codex CLI, opencode, and Hermes Agent — in one step, asking whether to clean up your global or this project's local config and reporting exactly which agents it touched; it accepts --location, --target, and --yes for scripted or non-interactive use, removes only what codegraph install wrote, and leaves your .codegraph/ index alone (#313).Fatal process out of memory: Zone crash on Node.js 22 and 24, even with plenty of RAM free — CodeGraph now launches with a V8 flag that keeps grammar compilation off the optimizing tier, and any launch path that doesn't get the flag directly re-execs once with it automatically (#298, #293). Node 25 stays blocked for now, since its variant of this bug isn't fixed by the same flag..cursor/rules/codegraph.mdc file outright instead of leaving an orphaned, empty rule behind, while keeping any content you added outside CodeGraph's markers..codegraph/config.json and the entire config surface are gone, and the library API for it (the config type, the config option on init(), and the get/update config exports) has been removed — existing config files are now ignored, and .gitignore is the single source of truth for what gets indexed. The .codegraphignore marker is also no longer supported; use .gitignore instead.codegraph install now supports Hermes Agent (Nous Research), wiring up the CodeGraph MCP server so Hermes can drive the knowledge graph like the other agents.*.routing.yml link to their controller, form, or entity-handler, and hook implementations across modules are connected to their canonical hook name, so asking for callers of a hook returns every implementation (#268)..gitignore everywhere — in git repos via git, and in non-git projects by reading .gitignore files directly — so to keep something out of the graph you just add it to .gitignore. Behavior change: committed files that aren't gitignored are now indexed even under vendor/, Pods/, or a committed dist/; add a .gitignore negation to exclude them (#283).codegraph command no longer fails — the launcher now invokes the bundled runtime directly instead of a .cmd file that modern Node refuses to spawn, so codegraph works regardless of your Node version (#289).codegraph_context call is now opened safely so it can't follow a symlink, closing a hole where another local user on a shared machine could redirect that write onto a file you can write (#280).curl … | sh and irm … | iex) no longer fail to launch on a machine that has no Node installed.npm i -g on Linux x64 now finds its bundle, after the 0.9.0 release silently shipped without the linux-x64 package; the release pipeline now verifies every package reached the npm registry so a release can't pass green-but-broken again.CodeGraph now ships its own self-contained runtime, so it installs on any Node version — or none at all — with no native build step, and the old intermittent "database is locked" errors are gone for good.
install.sh on macOS and Linux, and install.ps1 on Windows fetch the self-contained bundle and put codegraph on your PATH (you can still use npm/npx on any Node version too)..lua projects (Neovim plugins, Kong, OpenResty, game code), surfacing functions, table methods, local variables, require(...) imports, and the call edges between them..luau, Roblox's typed superset of Lua, adding type and export type aliases, typed function signatures, generics, and Roblox instance-path requires on top of everything Lua extracts (#232).codegraph status now reports the effective journal mode, so a "database is locked" report is easy to triage at a glance.codegraph install now strips the broken auto-sync hooks that pre-0.8 versions wrote into Claude Code's settings, which had been causing a "Stop hook error: unknown command 'sync-if-dirty'" on every turn. The cleanup is surgical and leaves unrelated hooks untouched. Re-run codegraph install once on an affected machine to clear the error.@nestjs/* dependency (#220).codegraph_explore source now includes line numbers, so an agent can cite file:line straight from the result instead of reopening the file to find a line number; set CODEGRAPH_EXPLORE_LINENUMS=0 to disable./mnt/* drives, where the live file watcher is too slow and could break MCP startup, CodeGraph now skips the watcher and offers to keep the index fresh with git hooks instead; new CODEGRAPH_NO_WATCH=1 (or serve --mcp --no-watch) forces the watcher off anywhere, and CODEGRAPH_FORCE_WATCH=1 overrides the WSL auto-detect when your setup is actually fast.file:line-cited answers on medium and large repos.codegraph_node with code on a class, interface, struct, or enum now returns a compact member outline (fields plus method signatures with line numbers) instead of the entire class body; functions and methods still return their full source.codegraph_explore output now scales with project size, so small projects get tighter responses than your native grep-and-read flow would produce while large codebases keep their fuller budget, and a per-file cap stops a single dense file from collapsing into a whole-file dump (#185). Thanks @essopsp.FooTest.kt, BarTests.swift, BazSpec.scala, QuxTestCase.cs) and test source-set directories in Kotlin, Swift, Scala, and C#, so real implementations no longer get outranked by tests.codegraph_explore output is now hard-capped to its size budget, so an oversized response no longer overruns the cap and sits in the agent's context to be re-read every turn.codegraph sync; CodeGraph now hash-compares them against the index the same way it does tracked files (#206). Thanks @15290391025.codegraph init -i now finds source inside nested, independent git repositories that aren't submodules (common in CMake super-repo layouts), instead of reporting "No files found to index" (#193). Thanks @timxx.codegraph status should report it (#203). Thanks @Finndersen.roots/list request before falling back, and the error message is actionable when a project still can't be resolved (#196). Thanks @zhangyu1197./mnt/* mount, so the codegraph tools actually appear; CodeGraph auto-skips the watcher there with manual and git-hook sync fallbacks (#199). Thanks @mengfanbo123..mcp.json (the file Claude Code actually reads for project-scoped servers) instead of a file it ignores, and re-running codegraph install migrates an affected project automatically (#207). Thanks @Jhsmit.codegraph_explore and codegraph_context output are now language-neutral instead of C-style comments, so they no longer look wrong inside Python, Ruby, and other non-C source blocks.codegraph index and codegraph sync no longer turns into garbled characters; CodeGraph now uses plain ASCII glyphs by default on Windows, with CODEGRAPH_UNICODE=1 to opt back into the Unicode glyphs or CODEGRAPH_ASCII=1 to force ASCII on any platform (#168). Thanks @starkleek and @Bortlesboat.module::symbol (Rust, C++, Ruby), Module.symbol (TypeScript, JavaScript, Python), or module/symbol, including multi-level paths and Rust prefixes like crate, super, and self (#173). Thanks @joselhurtado.AGENTS.md file with CodeGraph usage guidance, so opencode reaches for the codegraph_* tools instead of falling back to its native search.opencode.jsonc now survive install, re-install, and uninstall, because the installer makes surgical edits instead of rewriting the whole file.codegraph install now wires up the MCP server in the file opencode actually reads — previously it wrote to a config file opencode ignores by default, so the CodeGraph entry never appeared in any opencode session; re-run codegraph install --target=opencode after upgrading so the entry lands in the right place.codegraph install now sets up Claude Code, Cursor, Codex CLI, and opencode from one multi-select prompt, with any agents it detects pre-checked, so a single install wires up every editor you use (#137).--target, --location, --yes, --no-permissions, and --print-config.codegraph init now auto-wires project-local agent config for any agent you installed globally, so one global codegraph install works in every project you open without re-installing per project.Thanks @andreinknv for the substantive draft this release was based on.
codegraph command failing with permission denied right after a fresh global install — the 0.7.5 package shipped the CLI without its executable bit, so your shell refused to run it. New installs work out of the box. If you're stuck on 0.7.5, upgrade to 0.7.6 or unblock yourself in place by making the installed binary executable with chmod +x.