Skip to content

v1.1.0

Latest

Choose a tag to compare

@github-actions github-actions released this 23 Jun 21:46

[1.1.0] - 2026-06-23

New Features

  • Claude Code: an optional front-load hook makes your agent reach for CodeGraph automatically. When you ask a structural question — "how does X work", "what calls Y", "trace the flow from A to B" — CodeGraph injects the relevant source and call paths into the prompt up front, so the agent answers from the graph instead of grepping around to rebuild it. You're asked during codegraph install (default yes; Claude Code only, since it's the agent with prompt hooks), it's removed by codegraph uninstall, and codegraph upgrade turns it on for existing Claude setups. It's strictly additive and degradable — non-structural prompts and un-indexed projects are left alone — and you can switch it off any time without uninstalling by setting CODEGRAPH_NO_PROMPT_HOOK=1.

  • Vue store actions, mutations, and getters are now indexed as symbols you can find and read. Whether your store is Vuex (mutations / actions objects in a module) or Pinia — both the options form (defineStore({ actions: { … } })) and the setup form (defineStore('id', () => { … }), where actions are local functions) — each action, mutation, and getter is now a real node. So codegraph search finds login or getSessionList, and codegraph_explore / codegraph_node show its body and what it calls, instead of "not found" because the function only existed as an object-literal property.

  • codegraph_explore now connects a Vue component to the Pinia store action it calls. When code does const store = useUserStore() and then store.fetchUser(), that call now links through to the fetchUser action in the store module — so "what happens when this view loads its data?" traces from the component into the action's body instead of stopping at the store.fetchUser() line. Works for both Pinia store styles (options and setup), and stays precise (a built-in like store.$patch() or an unrelated same-named method isn't mislinked).

  • codegraph_explore now follows Vuex string dispatch. A dispatch('user/login') or commit('SET_TOKEN') call — namespaced 'module/action' keys included — now links to the action or mutation it names, resolved to the correct store module even when several modules share an action name (and without being fooled by a same-named api/ helper). So "what runs when this dispatches?" traces from the call into the store handler and on to the mutations it commits. Vuex's canonical export default { namespaced, actions, mutations } module shape is now indexed too, so those handlers are findable symbols.

  • codegraph_explore now connects React data-fetching flows built on RTK Query (Redux Toolkit's createApi). An endpoint defined inside createApi({ endpoints }) and the useGetXQuery / useUpdateYMutation hook it generates were both invisible to analysis — so "what does this component fetch?" or "where does useGetThingQuery get its data?" dead-ended, because the hook, the endpoint, and the component had nothing linking them. CodeGraph now indexes each endpoint and each generated hook as real symbols and wires the path component → useGetXQuery → getX → queryFn, so the flow resolves in one explore call instead of reading the API slice by hand. Both the arrow (endpoints: build => ({ … })) and method (endpoints(builder) { return { … } }) styles are recognized, along with the useLazyGetXQuery variant; hand-written hooks of a similar name are left untouched.

  • codegraph_explore now follows Celery task dispatch in Python. A send_email.delay(...) or send_email.apply_async(...) call now links to the @shared_task / @app.task function it runs — typically defined in a different module (tasks.py) from where it's triggered (a view or service) — so "what actually happens when this is dispatched?" traces from the call site straight into the task body instead of stopping at the .delay() line. Both decorator dialects are recognized (bare @shared_task and the arg'd @app.task(bind=True, …) form), including the module-qualified tasks.invalidate_cache.apply_async() call style. It stays precise: a .delay() on something that isn't a Celery task is never mislinked, so a project that doesn't use Celery is unaffected.

  • codegraph_explore now follows Spring application events in Java. A publishEvent(new OrderShippedEvent(...)) call now links to every @EventListener that handles that event — usually in a different class — so "what reacts when this is published?" traces from the publisher straight into each listener method instead of dead-ending at publishEvent(...). The link is by event type, and all the common listener styles are recognized: a @EventListener typed on its parameter, the @EventListener(SomeEvent.class) form, @TransactionalEventListener, and the older implements ApplicationListener<SomeEvent>. One event fans out to all its listeners, and a plain Spring app with no event bus is unaffected.

  • codegraph_explore now follows MediatR request and notification dispatch in C#/.NET. A _mediator.Send(command) or _mediator.Publish(notification) call now links to the Handle method of the matching IRequestHandler<> / INotificationHandler<> — usually in a different file in a Clean Architecture layout — so "what handles this command?" traces from the controller straight into the handler instead of stopping at the mediator call. The sent type is recognized whether it's constructed inline (Send(new GetFooQuery())), built into a local first (var cmd = new …; Send(cmd)), or passed in as a parameter, and it's matched by type — so a MessagingCenter.Send(...) or a same-named DTO that isn't a request is never mislinked, and a project without MediatR is unaffected.

  • codegraph_explore now follows Sidekiq background-job dispatch in Ruby. A DestroyUserWorker.perform_async(id) (or .perform_in / .perform_at) call now links to that worker's perform method — usually in app/workers/ away from the controller or model that enqueues it — so "what runs in the background here?" traces from the enqueue straight into the job body. Both the modern include Sidekiq::Job and the older Sidekiq::Worker are recognized, namespaced workers resolve to the right class even when several share a name (e.g. Comments::NotifyWorker vs Articles::NotifyWorker), and Rails ActiveJob's perform_later — a different mechanism — is intentionally left alone.

  • codegraph_explore now follows Laravel events in PHP. An event(new OrderShipped($order)) call now links to every listener that handles it — each listener's handle() method, usually a separate app/Listeners/ class — so "what reacts to this event?" traces from the dispatch straight into the listener bodies. Listeners are found both ways Laravel registers them: by a typed handle(OrderShipped $event) (auto-discovery, including a handle(A|B $event) union that listens for two events) and by the protected $listen map in your EventServiceProvider (which also catches a listener whose handle() has no type-hint). One event fans out to all its listeners, and queued jobs — dispatched via ::dispatch() rather than event() — are correctly left out.

  • CodeGraph now understands Lombok-generated methods in Java. @Getter, @Setter, @Data, @Value, and @Builder generate getters, setters, builder(), equals/hashCode/toString, and the @Slf4j log field at compile time, so those methods never appear in the source — and a user.getName(), User.builder(), or log.info(...) call used to resolve to nothing, silently breaking call-chain analysis (the agent would conclude the method didn't exist and reconstruct it by hand). Those members are now indexed from the annotations and fields, so they appear in codegraph search and codegraph_explore/codegraph_node, and callers trace through them like any hand-written method. They're marked as Lombok-generated so they read as generated, not hand-written; a method you write yourself is never overridden, static fields get no accessor, and a class without Lombok is unaffected. Thanks @git87663849. (#912)

  • codegraph_explore now follows C and C++ function-pointer dispatch. C does polymorphism with function pointers: a struct carries a function-pointer field, concrete functions are registered into it through a table (static struct cmd commands[] = {{"add", cmd_add}, …}), a designated initializer (.handler = on_open), or an assignment, and the code dispatches indirectly (p->fn(argv)). None of that was visible to analysis — the indirect call resolved to nothing, so git's command runner looked like it called nothing and a vtable's implementations had no callers. CodeGraph now links the dispatch site to the registered handlers, keyed by the struct field, so "what runs when this dispatches?" traces from p->fn(...) into every function registered for that field. This covers the command-table idiom (git, redis) and the ops-struct/vtable idiom (curl's content-encoders, protocol handlers), including the case where a generic hook slot is reassigned from a registry (h->func = found->fn). It stays precise — distinct function-pointer fields don't cross-link, a plain data field is never treated as a dispatch, and a project without function-pointer dispatch is unaffected. (#932)

  • codegraph_explore now follows GoFrame route bindings in Go. GoFrame's standard router wires routes reflectively: the path and method live in a g.Meta struct tag on a request type (g.Meta `path:"/user/sign-in" method:"post"`), the controller method that serves it is matched by that request type, and the two are joined at runtime by group.Bind(...) — so there was no path string and no edge from a route to its handler, and "where is /user/sign-in handled?" or "where are the routes bound to controllers?" could only be answered by reading. CodeGraph now indexes each g.Meta route as a real route node and links it to the controller method whose signature takes that request type, so a route resolves to its handler structurally in one codegraph_explore call. The link is by request type, not method name — so it's correct even when the two differ (a DeptSearchReq served by a List method); it tells apart the many identical request types a large app defines one-per-module (cash.ListReq vs order.ListReq) by package, including cloned addon modules; and a route whose handler isn't present is left unlinked rather than guessed. (#747)

  • The MCP server now works in monorepos and multi-project setups. Before, if you started CodeGraph somewhere with no .codegraph/ of its own — most often a monorepo root where you only indexed individual services — the server exposed no tools at all, so your agent couldn't query CodeGraph even for the sub-projects that were indexed. Now the tools are always available: point a query at any indexed project with the projectPath argument (its path, or anywhere inside it) and CodeGraph answers from that project's index — for as many projects as you like in one session. It also means a project you index after the server started is picked up without restarting, where before the tools stayed hidden because the server only checked for an index once at launch. A project that genuinely has no index still cleanly tells your agent to use its built-in tools there (and that you can run codegraph init to enable it), so single-project use is unchanged. Thanks @MaiLunJiye. (#964)

  • The Claude front-load hook now finds your indexed sub-projects in a monorepo. The optional UserPromptSubmit hook that injects CodeGraph context for structural questions previously only looked for an index at or above your working directory — so if you opened the monorepo root but indexed individual packages (packages/api, services/auth), it found nothing and stayed silent exactly where it was most useful. It now also looks into sub-projects: a single indexed sub-project gets its context front-loaded automatically, and with several the hook front-loads the one your question names (and lists the rest so the agent can target them by projectPath). Single-project repos are unaffected, and the scan is bounded and skipped entirely outside a recognizable workspace root. (#964)

  • codegraph_explore now surfaces the right code in large multi-layer projects. When you ask a backend-flow question in a repo that pairs an API server with a big frontend that mirrors the same domain words — say an app/ admin UI sitting over an api/ server — the server-side file that genuinely matches several of your query's terms is no longer pushed out of the results by the larger, more interconnected frontend layer. A file corroborated by two or more distinct query terms is now kept in the answer even when a denser unrelated layer would otherwise crowd it out, so "how does X read items / handle the request" returns the service or handler that does the work instead of a wall of frontend views. Single-layer projects are unaffected; set CODEGRAPH_RANK_NO_MULTITERM=1 to revert to the previous ranking.

  • Impact and blast-radius analysis for TypeScript, JavaScript, Go, Python, Rust, Ruby, C, Java, C#, PHP, Scala, Kotlin, Swift, Dart, and Pascal/Delphi now understands the readers of a constant. When you change a file-scope, package-level, module-level, or class-level constant — a config object, a lookup table, a shared constant — the other symbols in that file that read it now show up as affected, where before they were invisible (impact only followed calls, imports, and inheritance, so a constant's consumers looked like "nothing depends on this"). This makes codegraph impact, and the impact trail in codegraph_explore/codegraph_node, catch the "change this table, break its readers" class of change. It's on by default and adds no nodes to your graph; bundled/minified files and ambiguously-shadowed names are skipped to keep results precise. Set CODEGRAPH_VALUE_REFS=0 to turn it off.

  • C file-scope constants and globals — static const scalars, pointer/array lookup tables, and shared mutable globals — are now recognized as symbols in their own right. They previously weren't extracted at all, so they never appeared in search or carried any dependents; now they show up in codegraph search and participate in impact analysis (see above), so changing a C lookup table surfaces the same-file functions that read it.

  • Java static final constants, C# const / static readonly constants, Scala object vals, and Kotlin top-level / object / companion object vals are now classified as constants rather than generic fields, so they participate in the constant-reader impact analysis above — change a public static final table, a const string, a Scala object Config { val Timeout = … }, or a Kotlin companion object { const val … } and the methods that read it now show up as affected. (Per-object Java final / C# readonly / Scala & Kotlin class instance properties are unchanged.) Kotlin constants were previously not indexed as their own symbols at all, so they now also appear in codegraph search.

  • Swift top-level lets and static let constants (including those namespaced in an enum/struct, the common Swift pattern) are now indexed as constants and participate in the constant-reader impact analysis above — change a static let defaultRetryLimit or an enum Constants { static let … } and the same-file code that reads it shows up as affected. Computed properties and per-instance lets are not treated as constants.

  • Dart top-level const/final and class static const/static final constants are now indexed as constants and participate in the constant-reader impact analysis above. Instance fields, vars, and locals are not treated as constants. (Generated Dart code with the standard .g.dart/.freezed.dart/.pb.dart suffixes is already skipped.)

  • You can now teach CodeGraph about custom file extensions. Drop a codegraph.json at your repo root with an extensions map — { "extensions": { ".dota_lua": "lua", ".tpl": "php" } } — and files with those extensions get indexed under the language you name, instead of being silently skipped because the extension wasn't one of the built-in defaults. It's opt-in and committed alongside your code so the whole team shares it, your mappings layer on top of the built-ins and win on conflict (you can even re-point a built-in, e.g. .hcpp), and a typo'd language or a malformed config is warned about and skipped rather than breaking indexing. Projects without a codegraph.json behave exactly as before. (#906)

Fixes

  • codegraph index and codegraph init no longer crawl during the "Resolving refs" phase on large projects — most painfully ones that mix a big front-end and back-end, where the phase could stretch to many minutes. A package or module imported across hundreds or thousands of files (react, a shared UI package, Python logging / typing) was being treated as if every one of those import statements might be its definition, so the resolver compared each import against all the others — work that grows with the square of how widely a package is imported, which is why it blew up only on big, import-heavy repos. Imports now resolve straight to the definitions they actually point at, so those redundant comparisons are gone (reference resolution is dramatically faster on large repos), and the graph no longer accumulates the meaningless import-to-import links the old fallback created. (#915)
  • MCP tool results no longer show up as oversized headings in Markdown-rendering clients (such as the Claude Code VSCode extension). Results used Markdown headings (##/###) for things like the status summary, each search hit, and every file section in an exploration, so a normal query filled the transcript with large-font lines — worst with codegraph_search and codegraph_explore, where the noise grew with the number of results. Section headers are now bold labels, which render at normal text size while keeping the same structure. Terminal/CLI output is unchanged. (#778)
  • An MCP server pointed at a very large repository (tens of thousands of files) no longer hangs on the first tool call after a fresh start. On startup CodeGraph reconciles its index against the current files on disk, and on a huge repo that reconcile could run for minutes while blocking the very first request — long enough that the background server was sometimes force-restarted mid-scan, so the first query never came back at all. The reconcile now yields as it runs (keeping the server responsive instead of pinning it), and the first tool call waits only briefly for it before answering and letting the rest finish in the background — so you get a fast first response and the index still catches up. Set CODEGRAPH_CATCHUP_GATE_TIMEOUT_MS to tune how long that first call waits (default 3000ms), or =0 to always wait for the full reconcile. (#905)
  • codegraph install now wires up your agents and stops there — it no longer indexes the current directory. Building a project's graph is always the explicit codegraph init (or codegraph index), so you decide what gets indexed and when, and the steps are the same whether you installed globally or just for one project. This clears up the confusion where a project-local install silently indexed but a global one didn't, and where the docs and the tool disagreed about whether you still had to run init. (#826)
  • React components declared with forwardRef, memo, or styled-components / emotion (const Button = forwardRef(...), const Card = memo(...), const Box = styled.button\…`) are now recognized as components, so finding where they're used works. Before, they were indexed as plain constants, so codegraph callersand impact analysis reported "no callers found" even when the component was rendered across dozens of files — a dangerous false "safe to change" right before refactoring a shared component. Now every` usage links back to the component, so callers and blast radius are complete. This is the standard shadcn/ui declaration style, so for typical React design systems the whole UI layer is no longer invisible to impact analysis. Thanks @Arlandaren for the report and @maxmilian for the root-cause. (#841)
  • React Router and Next.js routes defined in .tsx / .jsx files are now indexed. Routes written as JSX — <Route path="/users" element={<UsersPage/>}/>, createBrowserRouter([...]), and Next.js app//pages/ page files — were being skipped entirely (only routes that happened to live in plain .ts/.js were picked up), so "what renders at this path?" and the route → page-component link were missing for most React apps. Now those routes show up in codegraph search/codegraph_explore and connect to the component they render, just like the backend route → handler links on other frameworks.
  • codegraph sync (and the file-watcher auto-sync behind always-on / MCP use) no longer drops a function's callers when you edit the file that function lives in. Re-indexing a file after an edit — even a docstring-only change — was severing the calls / references edges coming from other, unchanged files (e.g. from pkg import mod; mod.fn() callers, or any cross-file reference), so codegraph callers / impact would abruptly report "no callers" for a function that's used throughout the codebase, until the next full re-index. Sync now preserves those incoming cross-file edges across the re-index, re-matching them to the symbol even when the edit shifted its line number. Most visible in large Python package trees, but it applies to every language. Thanks @JosefAschauer. (#899)
  • codegraph index now rebuilds the full graph from scratch, so it produces the same result as a fresh codegraph init instead of reporting "0 nodes, 0 edges" and looking like it wiped your index. Previously, re-running index on an unchanged project skipped every file (their contents hadn't changed) and showed an empty-looking summary; it now clears and re-indexes for an honest, complete rebuild every time. Use codegraph sync for fast incremental updates between full rebuilds. Thanks @Arc-univer. (#874)
  • The file watcher that auto-syncs the graph now fails cleanly when live watching can no longer be trusted, instead of looking healthy while the index quietly goes stale. If the operating system runs out of file-watch resources, or another process holds the write lock far longer than a normal save, CodeGraph now disables auto-sync once — with a single clear message telling you to run codegraph sync (or rely on the git sync hooks) to refresh — rather than retrying forever or repeating the same error on a loop. And while auto-sync is disabled, CodeGraph's tool responses (and codegraph status) now say so plainly, so your AI agent knows to read files directly instead of trusting a frozen index. This mostly matters for long-running MCP/daemon sessions, which could otherwise keep serving stale results while appearing to work. Thanks @thismilktea. (#876)
  • On Linux, hitting the kernel's inotify watch limit on a large project no longer silently leaves half the tree unwatched. CodeGraph now tells you once — naming the exact setting to raise (fs.inotify.max_user_watches, e.g. sudo sysctl fs.inotify.max_user_watches=1048576) — and keeps live-watching the directories it could register while codegraph sync (or the git sync hooks) covers the rest. (#876)
  • A long-running MCP server now notices when a git worktree gains its own index. Before, if the server (or shared daemon) first saw a worktree before you ran codegraph init in it — so the lookup walked up to the main checkout's index — it pinned that decision for its whole life: even after the worktree had its own .codegraph/, every query kept hitting the main checkout's index and every result carried a false "this index belongs to a different git working tree" warning, until you restarted the server. The CLI got it right but the MCP server didn't, and re-indexing didn't help. The server now re-checks which index a path belongs to on each call, so the worktree's own index is picked up — and the stale warning drops — without a restart. (#926)
  • A long-running MCP server now recovers when your index is deleted and rebuilt at the same path. If .codegraph/ was removed and recreated while the server held it open — most easily by recreating a git worktree at the same path, or rm-ing .codegraph/ and running codegraph init again — the server kept reading the old, deleted database file and served a frozen snapshot: renamed or removed symbols still showed as live, new ones were missing, and codegraph sync couldn't refresh it — only restarting the server fixed it. The server now detects that the database file was swapped out from under it and reopens the live one in place, so results stay correct without a restart. (On Linux and macOS; Windows doesn't allow deleting an open file, so it isn't affected.) (#925)
  • The MCP server now opens and auto-syncs a project that lives inside a folder an enclosing git repository ignores. Before, if the directory you indexed sat within a larger repo that gitignored it, the shared MCP daemon failed to open the project — its log repeated Failed to open project … path should be a path.relative() d string, but got "./" — so the file watcher never started and the index silently went stale until you ran codegraph sync by hand (setting CODEGRAPH_NO_DAEMON=1 was the only workaround). The daemon now opens the project and starts watching as expected. Most visible with Codex on Windows, but the cause wasn't platform-specific. (#936)
  • A git worktree of a submodule is no longer indexed as a duplicate copy of that submodule's code. CodeGraph already skips ordinary worktrees (a second working view of a repo it indexes), but a worktree created from a submodule — common in monorepos that check submodules out into worktrees for parallel feature work — was mistaken for a genuine embedded repo and swept in, duplicating every symbol it shared with the real submodule checkout (one report had ~28% of its index as duplicates, inflating both query results and the database). These submodule worktrees are now recognized and skipped, while the submodule's own checkout stays indexed as distinct code. Thanks @charlesxu2026-ship-it. (#945)
  • A C++ class or struct annotated with an export/visibility macro — class MYLIB_EXPORT Foo : public Bar { … }, the common DLL-export / visibility pattern in headers — is no longer mis-indexed as a function spanning the whole class body. Not knowing the macro is a macro, the parser read it as a type and the whole declaration as a function, so the class surfaced as a phantom function that showed up as a false caller in codegraph callers, codegraph impact, and blast-radius analysis, and skewed symbol counts. CodeGraph now recognizes this misparse and drops the bogus node. Thanks @spwlyzx. (#946)
  • codegraph status no longer reports phantom pending changes for files CodeGraph deliberately keeps out of the index — a tracked file inside a committed dependency dir (a checked-in vendor/ or node_modules/), or a tracked file under a .gitignored directory. A full index correctly excludes these, and codegraph sync never indexes them, but the fast change-detector behind codegraph status flagged every edit to such a file as "modified" (and a new one as "added") — so the pending-changes count never cleared no matter how many times you synced. Change detection now applies the same ignore rules the full index does, so status agrees with sync, and tools built on CodeGraph's change-detection API get the same corrected list. (#766)
  • Files reached through a symlinked directory that points outside your project now index instead of being silently skipped. When a folder in your repo is a symlink to a location outside the repo root — the standard layout for Dota 2 custom games and similar SDK-linked projects, where game/ and content/ link into the engine tree — CodeGraph followed the symlink to discover those files but then blocked every one of them while reading, logging Path traversal blocked in batch reader and indexing nothing under them. The reader now agrees with the directory scan and indexes those files. The guard against ../ path escapes is unchanged, and the protection that keeps your agent from being served file contents from outside the repo is also unchanged — only the indexer's own read path follows these in-repo symlinks. (#935)