Releases · optave/ops-codegraph-tool · GitHub
Skip to content

Releases: optave/ops-codegraph-tool

Dev build 3.15.1-dev.9

25 Jun 04:35
4f15575

Choose a tag to compare

Pre-release

Dev build from commit 4f15575e01be72de8d047656ee605d9059b05f89 on main.

Dev build 3.15.1-dev.8

24 Jun 23:59
fb61cf2

Choose a tag to compare

Pre-release

Dev build from commit fb61cf2663435b4c868cd3b525359d9c6a4502e8 on main.

Dev build 3.15.1-dev.6

24 Jun 22:17
5c3077c

Choose a tag to compare

Pre-release

Dev build from commit 5c3077c51ad02689971561733a8c916c17131ac7 on main.

Dev build 3.15.1-dev.5

23 Jun 21:47
ad6cd86

Choose a tag to compare

Pre-release

Dev build from commit ad6cd86dac2d0d52c4db46d555ccd4c759ccd314 on main.

v3.15.0

22 Jun 03:53
cb42049

Choose a tag to compare

Dynamic call detection ships across all 34 languages, plus richer codegraph stats output and a new ignoreAdditionalDirs config option. Seven phases of dynamic dispatch detection land in a single release: Reflect/decorator patterns in JS/TS, JVM dynamic dispatch with Kotlin callable-reference resolution, Python getattr/eval/functools.partial, Ruby send/public_send and PHP call_user_func, Go MethodByName and C/C++ dlsym/function-pointer detection, and C#/Swift/Elixir/Lua long-tail patterns. Every pattern is classified with a DynamicKind taxonomy (computed-literal, computed-key, reflection, eval, unresolved-dynamic) and visible via a new codegraph roles --dynamic flag; resolved calls remain in the normal call graph while unresolvable patterns emit zero-confidence sink edges that never pollute regular queries. A closed dispatch-table resolver (RES-2) handles ({a:fnA,b:fnB})[key]() via the existing PTS wildcard solver. codegraph stats now breaks down dead symbols by actionable sub-role (dead-leaf, dead-unresolved, dead-ffi, dead-entry, dead-callable), fixing a pre-existing double-counting bug in the dead total. A new ignoreAdditionalDirs config field lets projects append additional directories to the built-in IGNORE_DIRS without patching codegraph source.

Features

  • dynamic-calls: detect and flag dynamic call sites in JS/TS — DynamicKind taxonomy classifies every dynamic call at extraction time; sink edges flagged as dynamic_kind in a new DB column (migration v20); new codegraph roles --dynamic flag surfaces them; Rust native extractor fully mirrored (#1629)
  • dynamic-calls: Reflect.apply/construct/get and TypeScript @Foo decorator detection (Phase 1) — JS/TS-specific reflection idioms emit reflection-kind calls; both walk and query extractor paths updated; Rust mirrored (#1637)
  • dynamic-calls: JVM dynamic dispatch — Java Method.invoke/Class.forName/getMethod, Kotlin callable references (::fn), Scala/Groovy invoke patterns; Kotlin ::fn refs resolve at 100% recall (Phase 2) (#1646)
  • dynamic-calls: Python getattr/eval/exec/functools.partial detection; getattr(obj, 'method') resolves at 100% recall for top-level functions (Phase 3) (#1653)
  • dynamic-calls: Ruby send/public_send and PHP call_user_func/$fn() detection; literal symbol calls resolve at 100% recall (Phase 4) (#1654)
  • dynamic-calls: Go reflect.MethodByName and C/C++ function-pointer/dlsym detection; both resolve at 100% recall for literal names (Phase 5) (#1655)
  • dynamic-calls: C# GetMethod/Invoke, Swift NSSelectorFromString/performSelector, Elixir apply, Lua load/loadstring/bracket-index calls, ObjC performSelector, Dart Function.apply; Swift resolves at 100% recall; Rust extractor mirrored for all four languages (Phase 6) (#1657, #1670)
  • dynamic-calls: RES-2 — closed dispatch-table resolution — ({a:fnA,b:fnB})[key]() resolves to each table entry via the PTS wildcard solver; Rust native mirror included (#1677)
  • stats: separate dead-code categories in codegraph stats — per-sub-role breakdown with actionability labels (dead-leaf, dead-unresolved, dead-ffi, dead-entry, dead-callable); fixes pre-existing double-counting bug where the synthetic dead aggregate was summed alongside individual sub-role counts (#1648)
  • config: add ignoreAdditionalDirs to .codegraphrc.json — array of directory names merged with the built-in IGNORE_DIRS at file-collection time; included in BUILD_HASH_KEYS to trigger a full rebuild when changed; crates removed from the global IGNORE_DIRS default (add it to ignoreAdditionalDirs in your own .codegraphrc.json if needed) (#1666)

Bug Fixes

  • dataflow: P4 incremental re-stitch + P6 vertex extraction on native engine path — vertex rows extracted during bulk-insert pass; re-stitch fires on callee-only changes without a full rebuild; P6 parity fix for incremental vs full-build paths (#1635)
  • dataflow: make dataflow vertex write and inter-procedural stitch atomic — closes half-written state gap when the process is killed between vertex insert and stitch (#1658)
  • dataflow: purge dataflow rows keyed by call_edge_id before edge deletion — prevents FK constraint failures during incremental file purge that left stale nodes after file deletion (#1662)
  • dynamic-calls: RES-3 type-aware method name lookup for JVM getMethod patterns — Rust resolver now uses receiver type to construct qualified lookup for Groovy, Java, and Scala getMethod calls
  • native: Kotlin callable-ref prefers class method over top-level function; suppress spurious invoke sink edge that diverged from WASM (#1686)
  • native: CJS require bindings now produce receiver-edge parity with WASM — require()-destructured class types emit receiver call edges on the native path (#1671, #1678, #1679)
  • native: always run JS role re-classification on full builds to fix hasActiveFileSiblings parity — incremental-only re-classification left stale role assignments on fresh builds
  • wasm: preserve dyn=1 when deduplicating edges with same source/target/kind/confidence — bare @Log decorator was silently dropped when @Log() call-expression had already been processed first (#1688)
  • native: dispatch-table PTS resolution in JS extractor — ({a:fnA,b:fnB})[key]() now resolves on the native path, matching WASM output (#1690)
  • stats: exclude sink edges (dynamic call placeholders, confidence=0.0) from the call-confidence denominator; lift minimum confidence for resolved ts-native edges from 0.3 → 0.5 (#1641)
  • stats: suppress false-positive high-fan-in warnings for Rust ::new() constructors (#1643)
  • mcp: break 37-file circular dependency by extracting McpToolContext to mcp/types.ts — two consecutive architectural audits had flagged this cycle (#1638)
  • config: ignoreAdditionalDirs and ignoreDirs now respected in watch mode (#1666)
  • analysis: exclude gitignored NAPI-RS artifacts from native gap detection — prevents spurious WARN and unnecessary WASM backfill on every fresh --no-incremental build (#1647)
  • analysis: exclude NAPI-RS generated index.js from WASM engine analysis — eliminates false 359 cognitive-complexity reading for requireNative in codegraph triage (#1636)
  • types: use @types/better-sqlite3 types in getDatabase() and McpToolContext — removes last any usages in the DB layer (#1639)

Chores

  • docs: add ADRs for dynamic call resolution and interprocedural dataflow (#1675)
  • deps: bump better-sqlite3 from 12.10.0 to 12.11.1 (#1634)
  • deps: bump vitest from 4.1.8 to 4.1.9 (#1633)
  • deps: bump actions/checkout from 6 to 7 (#1630)

Dev build 3.15.1-dev.4

22 Jun 17:38
c8fd894

Choose a tag to compare

Pre-release

Dev build from commit c8fd8942be1449a23b12e8aa34af1b14e6bc862b on main.

v3.14.0

20 Jun 00:11
7c674a2

Choose a tag to compare

Interprocedural dataflow analysis ships in full, plus a sweep of role-classifier accuracy fixes. The headline feature is a complete variable-level dataflow model: dataflow_vertices tracks param, return, and local variable locations per function; def_use edges connect definitions to uses within a function; arg_in and return_out edges stitch caller and callee dataflow across call boundaries. All 34 supported languages have dataflow rules. Incremental re-stitch (P4) fires on both the WASM/JS and native engine paths so arg_in edges are rebuilt when only a callee file changes, without a full rebuild. codegraph fn-impact --json gains direct and transitive shorthand fields alongside the existing levels breakdown. The role classifier received five accuracy fixes that eliminate a family of false-positive dead-symbol reports on real TypeScript and Rust codebases: exported interfaces with no cross-file call edges, type-def kinds in files with active callables, Commander.js dispatch methods, methods with active file siblings, and self-sibling sole-callable false-negatives. Erlang WASM parity is restored after the malicious package removal in v3.13.0.

Features

  • dataflow: interprocedural variable-level model across all 34 languages — new def_use (intra-function define-use), arg_in (caller arg → callee param), and return_out (callee return → caller capture) edge kinds; dataflow_vertices table tracks param/return/local locations; dataflow_summary table stores per-param transfer functions (flows_to_return, is_mutated); DB migrations v18 + v19; P4 incremental re-stitch runs on both JS and native engine paths so arg_in edges are rebuilt on callee-only changes without a full rebuild; parity-compare.mjs --dataflow flag for vertex multiset comparison (#1608, #1612, #1615)

Bug Fixes

  • fn-impact: add direct and transitive shorthand counts to JSON output — direct is the level-1 caller count, transitive is all callers at depth 2+; computed from the existing BFS levels data with no extra DB queries; fully backward-compatible (#1603)
  • roles: honour exported=1 flag for interfaces and type aliases with no cross-file edges — exported symbols used only as same-file type annotations now classify as entry rather than dead-unresolved (#1599)
  • roles: classify type-def kinds as leaf when the file has active callables — type, interface, struct, enum, and trait definitions in files with at least one callable (fan-in or fan-out > 0) no longer produce dead-ffi or dead-unresolved false positives (#1600)
  • roles: classify Commander.js execute/validate methods in framework dispatch directories as entry — eliminates ~12,000 false positives in codegraph roles --role dead output on Commander.js-based CLIs (#1601)
  • roles: classify methods and functions with active file siblings as leaf — interface-dispatch callbacks (visitor pattern), logical-or function defaults, and handler-table property callbacks no longer report as dead-unresolved; fanOut > 0 guard prevents over-promotion of trivial helpers; mirrored in Rust native classifier (#1602)
  • roles: prevent sole-callable self-sibling false-negative — a function whose only active file sibling is itself no longer satisfies the hasActiveFileSiblings heuristic; applied symmetrically in TypeScript and Rust classifiers (#1603)
  • db: derive rootDir from customDbPath when a custom --db path is set — openRepo/openReadonlyWithNative no longer always default to process.cwd() when a custom DB path is provided (#1606)
  • config: wire config.build.engine from .codegraphrc.json into pipeline and DB connection — openRepo/openReadonlyWithNative now read the file-level engine config; CLI --engine flag still takes priority (#1604)
  • dataflow: guard C/C++ function name and parameter extraction against unnamed declarators (#1608)
  • dataflow: guard exitFunction scope-stack pop against early-return from enterFunctionScope (#1612)
  • parity: restore Erlang WASM grammar — the grammar was lost when the malicious tree-sitter-erlang npm package was removed in v3.13.0; the validated WASM is now committed directly via a .gitignore negation rule so the WASM engine has Erlang support without reinstating the removed devDependency (#1598)
  • ci: fix Windows SSH git dependency resolution — add --add flag to the second git config insteadOf call to prevent silent overwrite on Windows runners (#1597)

Refactors

  • native-orchestrator: decompose into focused helper functions; extract call-resolution strategy dispatch to resolver/strategy.ts (#1591, #1592)
  • cfg: replace TS and Rust processStatement switch with handler-table dispatch — O(1) single-type handler lookup (#1590)
  • types: consolidate shared interfaces and extract DRY abstractions (#1588)
  • config: split config command subcommands; move JS type-resolution confidence threshold and engine env vars to DEFAULTS (#1589)
  • complexity: address warn-level complexity in ast-analysis visitors, features domain, and infrastructure (#1593)
  • roles: extract ANNOTATION_ONLY_KINDS constant in Rust classifier for parity with TS (#1602)

Chores

  • bench: update resolution benchmarks and embedding benchmarks for v3.13.0 (#1580, #1581)
  • bench: prune stale 3.11.x KNOWN_REGRESSIONS entries (#1580)

v3.13.0

17 Jun 05:43
fd4e62a

Choose a tag to compare

User-level global config, codegraph config scaffolding, and an explain alias land. The headline feature is a new user-level configuration layer (~/.config/codegraph/config.json via XDG, or ~/.codegraph/config.json fallback) with an interactive per-repo consent model — DEFAULTS → global (if consented) → project → env → secrets. codegraph config now shows a human-friendly key/value/source table by default (pass --json for machine output), and gains --init (scaffold a .codegraphrc.json with all sections pre-populated), --edit (open in $EDITOR), --enable-global, --disable-global, and --list-global flags. Global --user-config [path] and --no-user-config CLI flags are also new. The explain command lands as a discoverable alias for audit. TypeScript compiler-based type resolution now auto-enables for TS projects that have a tsconfig.json. A supply-chain incident is resolved — a malicious tree-sitter-erlang npm package is replaced with a clean source build. On engine accuracy, super-dispatch cross-file false edges are eliminated, CHA confidence is aligned between WASM and native, and a sweep of parity fixes improves call-graph correctness for Go, Python, C++, CUDA, Haskell, and Zig.

Features

  • cli: add explain as alias for auditcodegraph explain <target> is equivalent to codegraph audit <target>; makes the audit command easier to discover
  • config: codegraph config now shows a key/value/source table when --json is not passed — each key displays its current value and which layer it came from (default, user, project, env)
  • config: add --init and --edit scaffolding helpers — codegraph config --init scaffolds a .codegraphrc.json with all sections pre-populated; codegraph config --edit opens the project config file in $EDITOR
  • config: user-level (global) config with per-repo consent — new ~/.config/codegraph/config.json (XDG) or ~/.codegraph/config.json fallback; interactive per-repo consent model; codegraph config --enable-global, --disable-global, --list-global flags; global --user-config [path] and --no-user-config CLI flags; layered merge order: DEFAULTS → global (if consented) → project → env; config_hash invalidation triggers a full rebuild when build-relevant config changes; loadConfigWithProvenance returns per-key source map (#1559)

Bug Fixes

  • config: auto-enable TypeScript compiler resolver for TS projects — typescriptResolver now defaults to true; silently skips when typescript is unavailable or no tsconfig.json is present, so JS-only projects and environments without TypeScript are unaffected (#1461)
  • config: clarify consent prompt wording to reflect per-key inheritance semantics and improve question clarity
  • cha: eliminate super-dispatch cross-file false edges — super.method() calls no longer resolve to methods outside the class hierarchy; the native engine expands super-dispatch into CHA sibling overrides (#1506, #1514, #1537, #1544)
  • native: resolve this-dispatch in func-prop methods — fn.method = function(){ this.other() } now resolves other through the func-prop enclosing context (#1512)
  • native: seed typeMap entries for let/var object-literal methods — object literal methods defined with let/var now register their receiver types for downstream resolution
  • native: prefer bare name over qualified in span-tie caller attribution — when two candidates share the same span, the bare-name symbol wins to avoid false qualified-name attribution
  • native: resolve Go factory and Python constructor receiver types — NewFoo() in Go and Foo() constructors in Python now seed the typeMap for downstream method-call resolution (#1498)
  • native: align object-literal shorthand method node ordering with WASM — extraction order is now consistent between engines
  • wasm: align TypeScript CHA dispatch confidence (0.6 → 0.8) — WASM now matches the native engine's confidence for CHA-resolved edges (#1505)
  • wasm: port missing node extractions to JS extractor (jelly-micro #1471) — several edge-type gaps in the WASM engine aligned with the native engine (#1509)
  • wasm: emit receiver edges for declaration-typed locals (C++, CUDA) — typed local declarations in C++ and CUDA now produce receiver call edges (#1497)
  • parity: port the JS points-to solver to native — WASM and native now run identical resolution logic for JavaScript/TypeScript points-to bindings; the four JS pts post-passes on the hybrid path are removed, leaving a single source of truth (#1465)
  • parity: align Java interface dispatch across WASM, native, and hybrid engines — all three engines now agree on interface method resolution confidence and edge set (#1503)
  • parity: align enclosing-caller attribution for variable bindings (Haskell, Zig) — multi-binding let patterns now attribute calls to the correct enclosing caller (#1499)
  • extractor: strip brackets from computed string-key method names — obj['method']() no longer emits ['method'] as the method name
  • receiver: local function constructors block cross-file class receiver edges — prevents false cross-file receiver matches when a same-file function constructor is in scope
  • resolver: class-scope field annotation typeMap keys prevent cross-class collision — private repo: Repository in two classes no longer shares a typeMap key (#1495)
  • triage: normalize JSON output to use items key at all levels — all triage JSON responses now use a consistent items array structure
  • cli: accept --json flag in batch command as no-op — batch command no longer errors when --json is passed (#1563)
  • parser: downgrade WARN to debug for optional parsers with missing WASM grammar — language parse errors for optional grammars no longer pollute stderr with WARN messages
  • native: don't warn when a natively-supported file produces 0 symbols via WASM — gitignored Rust addon artifacts no longer trigger false-positive extractor failure warnings
  • deps: remove malicious tree-sitter-erlang, fix 3 moderate vulnerabilities — replaces the compromised npm package with a clean source build; also fixes 3 moderate-severity vulns (#1478)
  • hooks: track Bash file modifications to prevent false-positive commit blocks (#1483)
  • perf: scope runPostNativeCha to changed files on incremental builds — incremental rebuilds no longer run the full CHA post-pass on unchanged files (#1490)
  • perf: pass symbolsOnly through parseFilesWasmInline — avoids unnecessary data extraction during symbol-only parse passes (#1489)
  • bench: update Elixir, Julia, and Objective-C expected-edges to module-qualified names (#1496)
  • ci: accept v-prefixed versions in publish workflow_dispatch input (#1443)

Performance

  • native: replace O(n²) type-map dedup with O(n) write-then-dedup — large files with many type-map entries no longer degrade quadratically during the native post-pass

Refactors

  • native: mirror Rust crate module layout to the TypeScript src/ tree — crates/codegraph-core/src/ modules now follow the snake_case equivalent of their TypeScript counterparts (#1463)
  • extractors: deduplicate C-family primitive types into a shared constant

Chores

  • ci: add per-PR perf canary for extractor/graph/native changes (#1488)
  • ci: add dev-dependency audit step at critical severity (#1479)
  • deps-dev: bump @biomejs/biome from 2.4.16 to 2.5.0 (#1523)
  • deps-dev: bump tree-sitter-gleam (#1522)
  • deps-dev: bump @vitest/coverage-v8 from 4.1.7 to 4.1.8 (#1521)
  • deps: bump anthropics/claude-code-action from 0.0.63 to 1.0.148 (#1520)

v3.12.0

10 Jun 07:37
c09bd21

Choose a tag to compare

Phase 8 Analysis Depth lands in full, plus a 30-technique JavaScript/TypeScript resolution sweep. Sub-phases 8.1 through 8.6 are now complete, with 8.3 substantially complete (one stretch-goal item — full allocation-site abstraction with fixed-point iteration — deferred to a future release): TypeScript compiler API type resolution (typescriptResolver opt-in in .codegraphrc.json) upgrades confidence-0.7 heuristic edges to compiler-verified 1.0; inter-procedural return-type propagation resolves method chains and factory patterns up to 3 hops; field-based points-to analysis (Phases 8.3 through 8.3f) covers callbacks, event handlers, parameter flows, object property writes, and object destructuring rest parameters in both WASM and native engines; barrel re-export chain resolution traces symbols through index.ts re-exports to their actual declaration files; CHA+RTA dynamic dispatch resolves interface method calls to all instantiated concrete implementations; and Phase 8.6 adds a byTechnique breakdown to codegraph stats --json showing edges attributed to each resolver technique. Beyond the Phase 8 work, a parallel accuracy sweep adds resolution for prototype-based method calls, Object.defineProperty accessor this-dispatch, super.method() dispatch via class expressions and static blocks, .call/.apply/.bind receiver rebinding, for-of/Set/Array.from iteration callbacks, inline-array spread call edges, and constructor-assigned property types. C# call graphs improve with same-class bare static call resolution and var-typed local type inference. Six native engine parity issues in the incremental rebuild path are fixed. Caller coverage for real-world TypeScript projects is substantially higher after this release. Note: most resolver improvements appear under Bug Fixes below — they used fix: commit prefixes because they corrected missing edges in existing resolution logic rather than introducing entirely new CLI capabilities.

Features

  • stats: add byTechnique breakdown to codegraph statscodegraph stats --json now includes caller_coverage.byTechnique with edge counts per resolution technique (ts-native, points-to); displayed in human-readable stats output under the caller coverage line; DB migration v17 adds technique column to edges table (#1303)
  • config: new typescriptResolver option in .codegraphrc.json — set "build": { "typescriptResolver": true } to enable the TypeScript compiler API enrichment pass; compiler-verified edges (confidence 1.0) replace heuristic typeMap values for factory calls, generic constructors, and other patterns tree-sitter can't resolve alone (#1278)

Bug Fixes

  • resolver: TypeScript-native type resolution via ts.createProgram + type checker (Phase 8.1) — upgrades heuristic typeMap entries to compiler-verified confidence 1.0 for .ts/.tsx files; resolves container.get<MyService>()MyService.doThing() class of edges that tree-sitter cannot see (#1278)
  • resolver: inter-procedural return-type propagation (Phase 8.2) — const x = createUser() propagates return type to x for downstream method-call resolution; chain propagation up to 3 hops with confidence decay (1.0 → 0.9 → 0.8 → 0.7); analysis.typePropagationDepth config knob (#1279)
  • resolver: field-based points-to analysis for higher-order calls (Phase 8.3) — tracks callback assignments, event-handler registrations, and strategy-pattern wiring; resolves app.use(handler) and events.on('click', handler) call edges (#1289)
  • resolver: cross-module points-to propagation (Phase 8.3 + 8.3b) — WASM + native parity; inter-module flows through import edges now propagate type bindings across file boundaries (#1296)
  • resolver: parameter-flow tracking in points-to analysis (Phase 8.3c) — function parameters tracked through the call graph; typed parameters seed the receiver typeMap for downstream method resolution (#1294, #1308)
  • resolver: object property write tracking in points-to analysis (Phase 8.3d) — obj.handler = fn assignments tracked so obj.handler() resolves to the assigned function (#1295)
  • resolver: constructor-assigned property types for receiver-typed resolution (JS/TS) — this.svc = new Service() in constructors seeds the typeMap so this.svc.call() resolves to Service.call (#1314)
  • resolver: object destructuring rest parameter resolution (Phase 8.3f) — const { a, ...rest } = obj; rest.method() now resolves method via the rest binding's source type; WASM + native parity (#1355)
  • resolver: barrel re-export chain resolution — imports via components/index.ts barrel files now trace to the actual declaration file rather than mapping to the barrel; both WASM buildImportedNamesMap and buildBarrelEdges updated (Phase 8.4) (#1298, #1302)
  • resolver: CHA + RTA enhanced dynamic dispatch (Phase 8.5) — interface method calls emit edges to all instantiated concrete implementations; new X() calls tracked for RTA filtering; this.method() resolved through the class's own method table and parent hierarchy (#1302)
  • resolver: prototype-based method calls, func-prop this-dispatch, and spread/iteration callback resolution — Dog.prototype.bark = function() definitions extracted; fn.method = function(){ this.other() } this-dispatch wired; object-rest param dispatch (#1331)
  • resolver: Object.defineProperty accessor this-dispatch — this.method() calls inside defineProperty getter/setter callbacks resolve through the enclosing class (#1346, #1351)
  • resolver: calls through Object.defineProperty / defineProperties / Object.create — accessor definitions emit call edges to the object's own prototype chain (#1328)
  • resolver: generator functions extracted as definitions (JS/TS) — function* gen() and async function* gen() now emit definition nodes so callers that iterate them appear in the call graph (#1333)
  • resolver: super.method() dispatch via class expression, static block, and field def — super.f() in class bodies, class Foo extends Bar { static { super.f() } }, and field-level assignments now resolve to the parent class method (#1399)
  • resolver: .call()/.apply() this-rebinding — fn.call(obj, ...) and fn.apply(obj, [...]) patterns now resolve the call to fn with obj's type as receiver (#1405)
  • resolver: Function.bind/call/apply receiver-typed resolution — bound = fn.bind(obj) seeds the typeMap so bound() resolves as a method call on obj's type (#1330)
  • resolver: for-of, Set, and Array.from iteration-callback edges — for (const x of items) x.method() and new Set([...]).forEach(item => item.method()) patterns emit call edges (#1397)
  • resolver: inline-array spread call edges — fn(...[a, b, c]) unwraps the spread array and emits call edges to each element's method (#1394)
  • extractor: inline-new expression recognized as receiver type in extractReceiverName(new Dog()).bark() directly infers Dog as the receiver type without a prior assignment (#1415)
  • resolver: this.prop typeMap key scoped to enclosing class — prevents false edges in multi-class files where two classes define a property of the same name (#1382)
  • parity: C# same-class bare static calls resolved + confidence filter for static receiver fallback — MyClass.StaticMethod() from within the same class now resolves; heuristic static-receiver fallback gated on confidence ≥ 0.75 to reduce false positives (#1417, #1427)
  • parity: C# var-typed local types inferred from new-expression initializers — var svc = new MyService() now seeds the typeMap with MyService for downstream method-call resolution (#1424)
  • parity: C# static receiver calls in WASM engine — static method resolution aligned with the native engine for same-class and qualified receiver patterns (#1395)
  • native: extract parameters for prototype method definitions — Dog.prototype.bark = function(name) {} now emits name as a parameter node in the native engine (#1345)
  • native: complexity/CFG computed for prototype method definitions — Rust engine now calcul...
Read more

v3.11.2

01 Jun 21:27

Choose a tag to compare

Watch mode correctness sweep. Five independent bugs in the incremental rebuild path are fixed: the call resolver had drifted from the full-build authoritative version, causing inflated calls edges on any watch rebuild touching a widely-imported file; a missing dedup set let the same (caller, target) pair be inserted multiple times; receiver, extends, implements, and dynamic-import edges were silently absent from watch-mode rebuilds; top-level Ruby constants and program-level Python assignments were dropped by the native extractor while WASM captured them; and 10 native grammar crate versions had drifted from their WASM npm counterparts. A new shared call-resolver.ts module now backs both the full-build and incremental paths, closing the structural gap that let these bugs accumulate.

Bug Fixes

  • watch: align incremental call resolver with full build — the watcher's resolveCallTargets/buildCallEdges had drifted from the authoritative full-build resolver in build-edges.ts; on a comment-only rebuild of a widely-imported file, calls edges inflated by ~700 (#1261)
  • watcher: eliminate calls-edge inflation in incremental cascade — adds the missing seenCallEdges dedup set to buildCallEdges in the incremental path, and tightens the global name fallback in resolveCallTargets to match the full-build resolver (#1264)
  • extract: eliminate WASM/native node divergence — native Ruby extractor now handles top-level assignment nodes (program-level constants); native Python extractor extracts program-level function and class definitions that were previously dropped; eliminates the persistent full-build node count gap between engines (#1266)
  • watcher: add missing receiver/extends/implements/dynamic-import edges — receiver edges (method call receiver resolution), extends/implements class hierarchy edges, and dynamic-import edges were silently absent from watch-mode incremental rebuilds; now parity-aligned with the full build (#1267)
  • engine: align native grammar crate versions with WASM npm packages — upgrades 10 Rust tree-sitter grammar crates in Cargo.toml to match the npm devDependency versions, eliminating grammar-version drift identified as the structural source of native/WASM call-edge divergence (#1268)

Refactors

  • engine: extract shared call-resolver, eliminate build/watch duplication — findCaller, resolveByMethodOrGlobal, resolveCallTargets, and resolveReceiverEdge extracted into src/domain/graph/builder/call-resolver.ts; both the full-build and incremental paths share a single implementation via a CallNodeLookup interface (#1272)

Chores

  • ci: add grammar version parity check between npm devDeps and Cargo.toml — new scripts/check-grammar-versions.mjs compares grammar major versions across both package managers; wired as a lightweight CI job to catch future drift early (#1270)
  • deps: bump commander from 14.0.3 to 15.0.0 (#1251), tree-sitter-erlang to 0.18 (#1252), @biomejs/biome to 2.4.16 (#1250), commitlint to 21.0.2 (#1253, #1254)