# Changelog All notable changes to CodeGraph are documented here. Each entry also ships as a [GitHub Release](https://github.com/colbymchenry/codegraph/releases) tagged `vX.Y.Z`, which is where most people will look. This project follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Security - Closed a path-traversal hole where a symbolic link inside an indexed project that pointed *outside* the project root could make CodeGraph serve that out-of-root file's contents (for example a file under your home directory) to the AI agent. CodeGraph now resolves symlinks when validating file access and refuses to read anything whose real location is outside the project, while still allowing symlinks that stay within it. Thanks @sulthonzh. (#527) - CodeGraph now indexes Spring configuration files (`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) ### New Features - TypeScript and JavaScript **class fields are now reported as properties instead of methods**. A plain field like `public fonts: Fonts;` previously extracted as a method, misrepresenting class shape and letting calls to same-named functions resolve to data fields (a boolean field named `isArray` was soaking up `Array.isArray(...)` call edges). Fields holding arrow functions or function expressions (`onClick = () => {…}`, including wrapped ones like `onScroll = throttle(() => {…})`) correctly remain methods and their bodies are still analyzed. Field initializers are analyzed too, so `history = createHistory()` records its call — and JavaScript class fields, which previously produced no symbol at all, now appear in the graph. Re-index a project to benefit. (#808) (TypeScript, JavaScript) - Callback registration through `this` now resolves precisely in TypeScript and JavaScript: `window.addEventListener("online", this.onOfflineStatusToggle)` or an API object like `{ mutateElement: this.mutateElement }` produces a reference edge to the **enclosing class's own method** — never a same-named method on an unrelated class, and never a data field. Builds on the callback-registration support below. (#808) (TypeScript, JavaScript) - Callback-registration coverage deepened across four more shapes: a `this.` registration whose method lives on a **base class** now resolves through the inheritance chain (`bus.on("submit", this.handleSubmit)` in a subclass links to the parent's `handleSubmit`); Java and Kotlin **method references to other classes** (`Handlers::onMessage`, `OtherClass::handle`) resolve across files, with `this::` and `super::` scoped to the defining class and references through a variable deliberately left out; and Swift bare callback names now match only the **enclosing type's** methods (implicit `self`), eliminating a class of wrong edges where a parameter like `request` linked to a same-named method on an unrelated type. (Java, Kotlin, Swift, TypeScript, JavaScript) - PHP **string and array callables** now register: a string passed to a callable-taking core function (`usort($items, 'cmp_items')`, `array_map('absint', …)`, `call_user_func`, `spl_autoload_register`, …) links to that function — including across files — and the array forms `[$this, 'method']` and `[Foo::class, 'method']` link to the named method (the `$this` form resolves through the class and its parents). Strings passed to arbitrary functions are deliberately ignored: only known callable positions are trusted. Validated on WordPress core (+556 edges, every sampled edge a genuine registration). (PHP) - Ruby **lifecycle-hook symbols** now register: `before_action :authenticate`, `after_save :reindex`, `around_create`, `validate :check`, `rescue_from(…, with: :handler)` and friends link the symbol to the method it names — on the class itself or **inherited from a parent** (`before_action :authenticate` in a controller resolves to `ApplicationController`'s method). `validates` (plural) is excluded since its symbols name attributes, not methods. Validated on rails/rails (+385 edges, every sampled edge genuine). (Ruby) - Method references to a type that needed **no import** now resolve: Java/Kotlin same-package references (`.concatMapMaybe(Maybe::just, …)`), **Kotlin companion-object members** (`KtHandlers::handle`), and cross-file C++ member pointers (`&TestSuite::RunSetUpTestSuite`). Resolution stays anchored to the named type, so a same-named member on a different class never matches. (Java, Kotlin, C++) - CodeGraph now sees where a function is **registered as a callback**, not just where it's called. A function name passed as an argument (`signal(SIGINT, handler)`, `qsort(…, compare)`, `addEventListener(…, onBlur)`), assigned to a function pointer or field (`ops->recv_cb = my_cb`, `OnClick := Handler`), or placed in a struct initializer or handler table (`{ .recv_cb = my_cb }`, `{ "get", getCommand }`) now produces a reference edge from the registration site to the function — so `codegraph_callers` and `codegraph_impact` surface callback wiring that previously looked like dead code. Works across all supported languages, including the language-specific forms: C/C++ `&fn`, Java `Class::method`, Kotlin `::fn`, Swift `#selector`, Objective-C `@selector`, Ruby `method(:fn)`, Scala eta-expansion, and Delphi/Pascal `@Handler` and `OnClick := Handler` event wiring. Callers output labels these "via callback registration". Resolution is deliberately conservative: an ambiguous name produces no edge rather than a wrong one. Re-index a project to benefit. Thanks @zmcrazy. (#756) - The `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 `` 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. - New `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 ` 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. - Cross-file impact and blast-radius coverage now spans **all 22 supported languages and 14 web frameworks**, each validated on a real-world repo — see the new coverage table in the README. This release ships the cross-file resolution behind it, including Lua and Luau `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. - C# types are now tracked by their namespace-qualified name. Same-named types in different namespaces — a domain entity and a DTO both called `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#) - ASP.NET Razor (`.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 `` 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) - A Razor/Blazor type reference now resolves through the component's `@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` / `` / `@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) - TypeScript service/RPC contracts defined as a tuple of generic types — `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) - New `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) ### Fixes - Doc comments are now captured for exported, `const`-assigned, and decorated declarations, and the documentation a symbol carries is now clean across every supported language. Previously a comment above `export class X`, `export const fn = () => …`, a plain `const fn = () => …`, or a decorated Python `def`/`class` (`@app.route(...)`, `@dataclass`) was dropped entirely — only comments directly above a plain declaration were kept. CodeGraph now finds the comment through the `export` / `const` / decorator wrapper. Comment-marker cleanup was also rounded out for every language CodeGraph supports: Rust/Swift/Kotlin doc lines (`///`, `//!`), Python/Ruby/shell `#`, Lua/Luau (`--` and `--[[ ]]`), and Pascal (`{ }` and `(* *)`) no longer leave stray markers in the stored text — validated end-to-end across all 19 code languages plus Svelte/Vue `