- Fix: cpp a folded parameterless member declaration (
bar()) records its implementation indefinition_fileas a path anchored to the same root assource_file, instead of a../-walk relative to the cache/out root. The zero-argument reconciliation added in 0.9.106 stored the internal_cpp_source_keyproof form, which_norm_source_filecannot re-anchor (it only relativizes absolute paths), so an out-of-tree corpus got a mangleddefinition_file. The sibling decl/def merge already stored the rawsource_filefor this reason; both paths now agree. The include-path proof still uses the key form. - Fix: llm a slice whose timeout or context overflow is recognised and given up on (it cannot be split further, or the retry depth is exhausted) now marks its file partial, so a document whose tail slice timed out is no longer cached and stamped complete from its other slices; it is re-queued on the next run while sibling files' results are kept (#5099, thanks @khrisshie).
- Fix: php a route path scan stops at the closure's own argument, so
$app->get('/users', function () { ... })keepsGET /usersinstead of reading a trailing string argument after the closure as the route; a legitimate path before the closure is unchanged (#5135, thanks @mppyxx). - Fix: ids two module-level declarations of the same kind in one file whose names differ only by leading/trailing underscores (
function _save(){}andfunction save(){ return _save() }) are two nodes again instead of one, and the call between them is a realsave -> _saveedge instead of a fabricatedsave -> saveself-call; the declaration that appears first keeps the plain id and the other is salted. Affects JS, TS, C, C++, PHP, Ruby, Kotlin, Swift and Lua (#2810, thanks @khrisshie). - Fix: php methods of one class, trait, interface or enum whose names differ only by a leading/trailing
_(_x()/x()) are separate nodes instead of one swallowing the other: the one public name keeps its id and the others are salted, as in Python, C#, JS/TS and Solidity, so$this->x()and$b->x()reachx()instead of being lost and$this->_x()no longer looks like a self-call (#5137, thanks @khrisshie). - Fix: java members of one class whose names differ only by a leading/trailing
_(_name/name) or only by case (run/Run, which Java treats as distinct) get separate node ids instead of one swallowing the other; a public name keeps its id and the twins are salted, as in the other languages, so calls to each resolve correctly (#5151, thanks @rohit-jsfreaky). - Fix: test the copied-cache terraform id test accepts a worker pool that could not start under resource pressure (it falls back to sequential and warns), instead of asserting the pool always starts; a genuinely broken pool still fails the test (#5136, thanks @mppyxx).
- Fix: php/js a call through an ESM namespace member (
import * as ns; ns.handler()) or whole-module require resolves only when the target is actually callable, so a namespace member that names a non-callable export (an object literal, a constant) no longer gets a spurious call edge (#5144, thanks @ayushcodes10). - Perf: query the read path (query/explain/path/affected and the MCP graph load) no longer imports every language extractor, cutting import cost on read-only commands; graph output is unchanged (thanks @rohit-jsfreaky).
- Perf: extract the AST worker pool is sized by the amount of uncached work (one worker per ~500 KB of uncached source, capped at CPU count and file count) when no worker count is set, so small incremental builds stop spinning up a full pool; output is invariant to worker count (thanks @rohit-jsfreaky).
- Change: cloud the OSS surfaces (README, CLI help/install text, the translated docs in all 31 locales, and the agent skill) now point at the free plan with no card at
app.graphify.com/signup, instead of a "14-day trial" at/login(the trial is paid-plans-only and needs a card, so the old copy conflated the two). Links carryutm_campaign=ossUTMs tagged per surface, so a signup can be attributed to where it came from. - Change: cloud the post-build CLI nudge is contextual. It is TTY-only (never in CI or the agent pipeline), respects
GRAPHIFY_NO_TIPS/GRAPHIFY_NO_CTA, and shows on builds 1, 5 and 20 then stays quiet for good. When a local graph reaches 25k nodes, the free plan's per-repo cut-off, the nudge switches to a scale-specific line (taggedutm_content=scale) that sells Graphify Pro and links to pricing with the 14-day trial, instead of the free signup: a repo that size no longer fits the free plan, so pointing it at the free plan would land straight on the limit.
The AST cache schema is bumped to 44; warm caches re-run the affected C++, PHP, Java and module-level-id extractions.