Skip to content

Reconcile upstream 553d5d10 with native language resolution fixes - #548

Merged
bompus merged 64 commits into
fork/consolidatedfrom
merge/upstream-553d5d10
Oct 23, 2026
Merged

bompus merged 64 commits into
fork/consolidatedfrom
merge/upstream-553d5d10

Conversation

@bompus

@bompus bompus commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Reconciles upstream through 553d5d101dd8c8ed65e83480e31192e836d8431a while keeping extraction and reference resolution in the native kernel.

The 61 upstream commits improve Rust module paths and receiver types, Python package roots and attribute calls, C++ qualified calls, Objective-C receivers, TypeScript type scope, React wrappers and Express handlers. Go function-field calls gain synthesis, and private interface methods retain package identity. The reconciliation records upstream ancestry with an ours merge and ports behavior into the fork's existing native architecture.

Incremental sync rechecks original references when defaults or barrel exports change. Native readers drain checkpoint work before opening a database scope. Go synthesis reads source trees without borrowing a live database connection. Git hooks keep their installed project root, including trailing spaces, and unsupported non-shell hooks stay unchanged.

Python attribute inference follows one field hop. Runtime import-root changes such as pytest's syspath_prepend remain unsupported, so some calls under those dynamic roots remain unresolved. Imported upstream tests retain conservative refusals where a receiver's type is unproved. C++ macro aliases, dependent owners and indexed receivers can also remain unresolved. Visible conditional type-alias targets describe declarations; they do not prove an active build branch or a constructor implementation. Type/value namespace and React wrapper expectations now assert the selected upstream behavior while retaining adjacent negative controls.

Validation completed locally:

  • Full suite: 10,304 passed and 40 platform/capability skips across 861 files.
  • Kernel release build, Clippy with warnings denied, TypeScript/application/viewer build, agent-document guard and native-rule guard passed.
  • Golden graphs: 8/8 passed; reviewed changes retain callback connectivity and add the ported initializer ownership.
  • Saved-query replay: all 46 answers identical, with zero regressions.
  • Precision checks passed on all 11 pinned real repositories. Edge review records the conservative recall limits and declaration targets above.
  • Independent native and parent reviews found seven blockers; each was reproduced or confirmed, repaired and checked. Six test-floor scanner cues were individually dispositioned.

Cross-platform installer and hook checks run on Linux, Windows and macOS in this PR.

README rows checked: upstream merge point, native extraction/resolution, call-resolution differences, Go synthesis and private-method package scope. The resolution page and framework coverage notes match these changes. Existing benchmark rows retain their original measured revisions; no new performance claim or benchmark campaign is included.

Review bot capacity: CodeRabbit skipped because 154 files exceed its 100-file limit and reported insufficient usage credits or metered capacity. Cubic reached its monthly line allowance (40,438/40,000), and Greptile reached its 50-credit trial limit. No automated review completed. The local native and parent reviews and their verified fixes are recorded above; the standing no-capacity policy applies to these bot skips.

Windows CI follow-up: the first repair normalized drive-letter casing and passed its native checks, but hosted Windows CI still failed. A second native reproduction showed that JavaScript realpath preserves Windows 8.3 directory names while Git expands them. Windows hook ownership now uses native realpath and canonicalizes existing absolute stored markers. The published first repair fails the short-path check; this repair passes on native Windows Node 24.21 for both drive spellings, including legacy recognition, subproject refusal, reinstall deduplication, stored short markers and removal. Linux hook, installer and README checks pass 288 tests with 8 skipped; TypeScript typecheck and the follow-up test audit pass. README fork behavior, the resolution page and Unreleased notes include the correction. Platform CI on the new head remains required.

colbymchenry and others added 30 commits October 20, 2026 16:32
…st picks, inherent first (colbymchenry#2701)

A Rust method called through a self declared Pin<&mut Self>, Box<Self>,
Rc<Self> or Arc<Self> was typed by its wrapper. tokio's
self.poll_flush(cx) in impl AsyncWrite for File went to its blanket impl
AsyncWrite for Pin<P>, whose poll_flush would need a Pin<&mut Pin<...>>,
and nearly every other such call linked to nothing: tokio's
self.poll_write_priv(..) and self.get_pin_mut(), dioxus's
self.in_scope(..) through self: &Rc<Self>.

Such a call is now looked up as Rust does: the type's own method taking
self through that wrapper first, then the wrapper's own (Pin::get_mut,
Rc's clone: std's, which the index doesn't hold, or a project impl on the
wrapper taking &self), then the type's other methods by deref. A value
declared Pin<&mut T> is looked up the same way on T, so
read.poll_read(..) on a generic R no longer reaches the Pin<P> impl.

A type's inherent method comes before a trait's of the same name, as in
Rust: on a path (tokio's Arc::from_raw(ptr) is std's, not its impl Link
for Arc<ScheduledIo>'s), on a typed value, and through self, where each
of several trait impls for one type calls its own block's method. In a
trait impl, fn wake(self) { self.wake() } hands the call on to the
type's own method, never back to itself, and (self.f)(x) calls what a
field holds, no method. A method called on a tuple, serde's
(self.ip(), self.port()).serialize(s), is no named type's.

A/B on tokio, axum, clap, serde, ripgrep, gleam and dioxus: 30 wrong
links removed, 13 moved to the right target, 74 right links added, none
lost. express, gin, flask and leveldb are byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… declared as (colbymchenry#2703)

An Objective-C message to a local or a parameter was typed by its
declaration (`FMResultSet *rs` makes `[rs close]` FMResultSet's). One to
an instance variable or a property was not, since that declaration sits
outside the calling method: in a header's @interface, an @implementation's
ivar block, a superclass, or synthesized for a property. The receiver's
name decided instead. ObjFW's tar tool's `[_archive nextEntry]` reached
OFLHAArchive::nextEntry, and React Native's `[_displayLink invalidate]` on
a CADisplayLink reached RN's own RCTDisplayLink::invalidate.

- objcFileMembers reads what each class declares, per file: the ivar
  block right after an @interface head (seen by subclasses; the head may
  go on over several lines, a protocol list on a line of its own), a
  class extension's or an @implementation's ivar block (the class's own),
  @Property declarations, including ObjFW's two-line ones and IBOutlet
  ones, and @synthesize lines. Types take protocol lists, type arguments
  and ObjFW's OF_GENERIC(...).
- objcMemberReceiverType, after the local inferrer, follows the language.
  `self.name` is a property of the class or a superclass. A bare name is
  an ivar: the class's own, one its own property synthesizes (`_name`,
  never a category property's), one @synthesize names, or a superclass's
  @interface ivar. A bare name is never a property's: `arcs` in
  `initWithArcs: (...)arcs` is the parameter. A capitalized bare name is a
  class, and `self.name` needs a property node, which skips most lookups.
  The type then takes the typed path (resolveMethodOnType at 0.9), and a
  class from outside the project has no project method, as for locals.
- objcClassFiles: when more than one file declares `@interface Name`
  itself, those are namesakes in separate targets, and only the ones in
  the calling file's directory count. SDWebImage's TV demo ViewController
  was otherwise typed by the macOS demo's `NSImageView *imageView1`.
- localReceiverTypePatterns('objc'): a local's or a parameter's type may
  carry OF_GENERIC(...), like `OFMutableArray OF_GENERIC(OFNumber *) *arcs`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pe reaches that type's method (colbymchenry#2706)

Go receiver inference read a parameter's type only when the line
patterns could: a lowercase name of the caller's own package (`s
*server`) or a capitalized one (`lg Logger`). A parameter declared
through a package, like `client rest.Interface`, `c clock.PassiveClock`
or `t *testing.T`, had no type, so a call on it was matched by name:
kubernetes' `client.Patch()` reached `RESTClient::Patch` instead of the
interface, `c.Now()` an unrelated `Clock`, and every `t.Errorf(…)` a
test helper's `T` interface. Only standard method names (PR 2664) and
receivers named like an import (PR 2448) asked the scope reader.

inferLocalReceiverType now asks the scope reader first for every Go
receiver. The declaration in scope (a parameter, a result, a name
grouped with others, a `var (…)` spec, a function literal's parameter)
gives the named type it writes, as GoReceiverDecl.declared, ahead of
the patterns, which scan back with no block scope. matchMethodCall,
matchMemberFunctionRef and matchGoFieldChainCall all use it:
- a project type resolves in its own package, through embedding and
  aliases;
- a type from outside the project, a predeclared one or an alias of
  either (goHasNoProjectMethods) reaches none of the project's methods,
  and neither does a type literal;
- a qualifier none of the file's imports names keeps the old lookup by
  name.
Standard method names keep the rules PR 2664 gave them. Any other name
the declared project type lacks goes on to the name strategies, as on a
receiver of unread type. The block that typed only receivers named
like an import is subsumed and removed, with the field it read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…name or a module path (colbymchenry#2707)

A `type` or `const` written inside an `impl` belongs to the type: Rust
reaches it only through a path like `Self::Err`, `<T as FromStr>::Err` or
`T::Err`, never by its name alone, and no module path or `use` names it.
Both extractors put it at file scope under its bare name, so the resolver
could not tell it from a module's own alias:
- a same-file `Err(…)` call linked to a `FromStr` impl's `type Err`, and
  serde's `Ok(…)` calls to a serializer's `type Ok`;
- axum's routing tests' `Response` linked to the `type Response` of
  `routing/mod.rs`'s `impl Service`, a private item the modules inside
  it can see;
- `io::Error` and `std::error::Error` linked to the `type Error` of an
  impl in the same file, and serde's `use crate::de::Error` to one in
  `de/mod.rs`.

Fix:
- Both extractors (rustImplItemOwner, and the kernel's impl_item_owner)
  qualify an item written directly in an impl by the impl's type, as they
  already qualify its methods: `ValueHint::Err`, `Limits::MAX`. A type no
  single name stands for keeps the impl's spelling, whitespace collapsed:
  `(A, B)::First`, `[u8]::Out`, `u64::WIDTH`.
- isRustAssociatedItem: a Rust type alias or const with a qualified name.
  Nothing else of those kinds gets one: an inline module adds no prefix,
  a function body's items aren't indexed, and a trait's default `type`
  is already its trait's.
- isRustNameInScope: such an item never matches a bare name, and matches a
  path only as `Self::X` in its own impl or as `<…>::X` (unchanged).
- resolveRustPathReference never picks one for a `crate::m::X` path.

Tests: rust-associated-item-scope.test.ts, 6 tests, on both engines; 5
fail on origin/main. The kernel parity torture fixture gains associated
items on a tuple, a slice reference and a primitive.

A/B on fresh indexes, origin/main 5530676 vs this change. Every changed
edge was triaged; no right link was lost:
- axum: 8 wrong links gone, 14 moved to axum-core's `pub type Response`.
- tokio: 46 wrong links gone.
- clap: 12 wrong links gone, 7 of them `Err(…)` calls.
- serde: 98 wrong links gone; `First<…>`/`Second<…>` now reach the
  module's aliases.
- ripgrep: 54 wrong links gone; `impl Captures for RegexCaptures` (3)
  now implements grep-matcher's `Captures` trait.
- gleam: 5 wrong links gone, 10 moved to the right target, 1 moved from
  one wrong target to another.
- dioxus: 71 wrong links gone, 40 moved to the right target, 3 moved from
  one wrong target to another.
- Controls (gin, serilog, flask, express) byte-identical; indexing time
  unchanged within noise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
colbymchenry#2575)

The dominant-file aggregation behind codegraph_explore could let SQLite
drive the query from the nodes table, which on a large index took
seconds to a minute. The query now pins an edges-first plan. On four
indexes it returns the same rows, 4 to 12 times faster.

Fixes issue 2571.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ame-named project method (colbymchenry#2606)

A Python call on a module the file imports from outside the project,
like subprocess.run(...) after import subprocess or sp.run(...) after
import subprocess as sp, is that module's function, never a project
class's method of the same name. The receiver must be bound only by
such imports: an assignment, loop or tuple target, a global write in a
function, or a fallback class or def of the name keeps the old lookup.

On django, mealie, fastapi and flask this removes 168 wrong links
(mock.call, time.sleep, sa.text, unicodedata.normalize, click.command)
and adds none. CPU time on django is unchanged.

Fixes issue 2599.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… method (colbymchenry#2608)

A Python call through a module-level instance of the same file, like
_svc.delete(obj) after _svc = SceneService(), now links to the method
its class has or inherits, as a method value through that global
already did.

On django and fastapi: 50 correct links added, 42 moved to the right
class (DEBUG_ENGINE's Engine, the dispatch tests' Signal), confidence
raised on about 400 more. CPU time on django is unchanged.

Fixes issue 2582.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… variable (colbymchenry#2603)

The module of a Python `from X import ...` names a module or package,
never a symbol, so `from app import email` no longer links the
importing file to a project variable named app, like a FastAPI or
Flask app = FastAPI(). A from-import module that resolves to anything
but a file or module links nothing. On five Python repos this removes
12 wrong import links and nothing else.

Fixes issue 2584.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ls (colbymchenry#2607)

`import a.b as X` written inside a function binds X there, ahead of any
module-level binding of X, so X.f() reaches a/b.py's f, as the same
import at module level already did. An undotted alias is left alone,
since an optional dependency's name can match any project file.
mealie's lifespan_fn now links init_db.main; the other repos are
unchanged.

Fixes issue 2600.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sult's parameters are not locals (colbymchenry#2597)

Main's gate for a Go call to a local func value or parameter that
shadows a package function (PR 2658) reads scopes through the Go scope
reader, and two of its readings were too wide. A name declared in one
case of a switch or select stayed in scope in the clauses after it, and
the parameter names inside a func-typed result, like
func() func(run string), *func(...) or chan<- func(...), were read as
the function's own. Either made a later call to the package function
look shadowed and drop its link.

The PR's own earlier shadowing check is left out: the gate already
covers every case its tests pin. Go A/B on gin, cobra, etcd, prometheus
and hugo is byte-identical.

Fixes issue 2580.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…colbymchenry#1965)

Git runs hooks from the top of the work tree, so a hook running a bare
`codegraph sync` never reached a sub-project's index. Each hook block
now names the project root it syncs, shell-quoted, one block per root,
placed right after the shebang so a user hook that ends in exit cannot
skip it. A hook in another language is left untouched and reported,
and a block from an older install counts as the top-level project's. A
project path with a line break is refused, since the root is written
on a comment line in the hook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…llback renders from where its calls are attributed (colbymchenry#2611)

JSX outside every function now renders from what a plain call there is
attributed to: a top-level value, or the file. Ownership is by line,
so no tag counts twice. Merged with main's destructuring rules (PRs
2676 and 2677): an owning parent takes a name as its local by its own
lines or by the file's top-level destructuring, and function parents
keep main's scope rules. The viewer's shared-chrome count no longer
counts a file as a render parent.

A/B: excalidraw +132 and bulletproof-react +38 render sites (tests to
the components they render, entries to their root apps, stories to
their components), none removed.

Fixes issue 2587.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bymchenry#2595)

tree-sitter-typescript parses `await f<T>(x)` as a call whose callee is
`await f`, so the reference was named `await f` and matched nothing.
Both engines now peel the await, skipping a comment after it, and the
reference sits where the callee starts, as for `await f(x)`: on the
call node, which starts at await, the checks that read the source at a
call's position missed the callee, and a package-imported
`await get<T>()` linked to a project class's static get.

A/B: excalidraw +2 (compressData, decompressData), vben +6, zod and
bulletproof-react unchanged.

Fixes issue 2586.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-exports (colbymchenry#1955)

Import and re-export lists are now read with TypeScript's `type`
modifiers (`export type { A } from`, `export { type A } from`,
`export type * from`), comments inside the list, ES2022 string names
and JSDoc @import tags. A type re-exported from a package, like vben's
`export type { VxeGridProps } from 'vxe-table'`, no longer links to a
project type of the same name, and type imports link through the
import rather than by name. The import-related suites pass (609 tests)
and indexing CPU time on vben is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…line (colbymchenry#1957)

An Express route keeps its named handler when a middleware before it
holds an arrow function, like rateLimit({ keyGenerator: (req) => req.ip })
or (req, res, next) => next(). Only the last argument decides whether
the handler is inline, and strings, regex literals and type arguments
no longer end an argument or a body early. The Express, route and
framework suites pass (757 tests); on express itself three named
handlers gain their link.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…othing, not a function elsewhere of its name (colbymchenry#2708)

A C++ call written by its bare name on a name the calling function binds
itself (a parameter, a lambda's parameter, a local lambda or functor, a
range-for variable) calls that local: C++ lookup finds it before any function
or method of that name. The name strategies linked such calls by name:
protocolbuffers/protobuf's code generators' `format(...)` on their
`Formatter& format` parameter went to the conformance suite's
`TestResult::format`, and facebook/rocksdb's tests' local
`auto key = [](int i) {...};` calls to `ArenaWrappedDBIter::key`.

isCppLocalCallableCall, checked in matchReference beside the JS/TS rule,
reads the caller's declarations of the name: its parameters, a declaration
that starts a statement (`auto x = ...`, `T x = ...`, `T x(args)`, a later
name in a list), a range-for variable or a lambda's parameter, the nearest one
in a block still open at the call deciding. A local type or a function the
body declares is not a local callable (the call constructs it or calls the
function), and an expression that reads like a declaration (`a && f(x)`)
declares nothing. A local's type may carry a function type in its template
arguments (`std::function<void()> done, failed;`), so the first name of such
a list counts as the later ones do, and the colbymchenry#2698 test of that list now
expects no edge for either. The looser isCppLocalName used by implicit-this
is unchanged.

A/B on main 5530676: protobuf 269 and rocksdb 51 edges removed, all calls
on locals, nothing else changed; glog, leveldb, breakpad and redis
byte-identical. The check costs 3.2 s of about 450 s CPU on protobuf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…declaration (colbymchenry#2709)

blankLoneMacroLines blanks a macro alone on its line, like
FMT_BEGIN_NAMESPACE, before C and C++ parse, unless the line above ends
in an operator it could be an operand of. A directive like
`#include <glib/gtypes.h>` ends in `>`, so GLib's G_BEGIN_DECLS below it
stayed, and the parser read `G_BEGIN_DECLS typedef struct _GBytes
GBytes;` as one broken declaration. The first declaration of nearly
every GLib header went missing (GBytes, GError, GHashTable, GList,
GQuark, the GIOCondition enum), a few headers grew junk functions (one
named `enum` swallowing a whole header), and the parse error kept the
file off the native kernel.

Objective-C already read a directive as ending at its line (colbymchenry#2691,
directivesEnd). C and C++ now do too, so the flag goes: a directive
continues only through a trailing backslash. The kernel takes C and C++
input from the hoisted preParse, so it needs no change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…declared type (colbymchenry#2710)

A Rust call written x.as_mut().m(..) or x.as_ref().m(..) reaches the
resolver by its bare name, so it was matched by name alone. tokio's
self.delay.as_mut().reset(now) on a Pin<Box<Sleep>> field linked to the
calling Interval::reset, its this.timer.as_mut().as_pin_mut() on an
Option to a stream's as_pin_mut, reader.as_mut().poll_read(..) on a
generic R to BufReader::poll_read, and dioxus's
self.child.as_mut().map(..) and self.server.as_mut().filter(..) on
Options to its own GenerationalRefMut::map and Store::filter.

Such a call is now read from the call's own chain and resolved on the
receiver's declared type as as_mut passes it on: a Pin<P> re-pins what
it points at (Rust's lookup through the Pin from the previous change),
a Box, NonNull, Rc or Arc lends what it holds, an Option stays an
Option, whose methods are std's, unless ? takes the value back out
(self.client.as_mut()?.next()), and a type parameter or another std or
dependency type gives no project method. A field is read from its
struct's declaration, also through pin-project's let me = self.project()
(a #[pin] field projects to Pin<&mut T>), even when a pin_project! macro
wraps the struct; a local or parameter from its own declaration, which
now also reads let x: T = .. annotations. A receiver whose type isn't
written where it can be read, a pin! local or a call's result, is left
to the name strategies as before.

A/B on tokio, axum, clap, serde, ripgrep, gleam and dioxus: 33 wrong
links removed, 7 moved to the right method, 13 right links added, none
lost, and 28 same-target links now resolved from the declared type
instead of by name. axum, clap, serde and the controls express, gin,
flask and leveldb are byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…walks (colbymchenry#2702)

tokio's signal/mod.rs writes `use crate::sync::watch::Receiver;` and
tokio-stream `use tokio::sync::watch::Receiver;`, and both linked their
`Receiver<()>` to the `Receiver` of net/unix/pipe.rs. Every `Receiver` in
the crate read as in scope once the file imported one, and the first won.

isRustNameInScope now walks the modules a `use` path names, from the module
the `use` is written in: crate::, self::, super::, a module declared there
(2018 paths), the crate's own name, or a project crate its manifest depends
on. It looks the item up there as Rust does: declared in that module (not
inside a function or an inline module), else brought in by the module's own
`use` of that name, macro-wrapped ones included (tokio's `cfg_sync! { pub use
mutex::{Mutex, ...}; }`), else by its globs. A module declared inline, like
`pub mod futures { ... }`, is found by its braces. A candidate the path does
not name is out of scope, so every strategy, the framework name rule
included, lands on the item the path names.

What the walk can't follow says nothing, and name matching answers as
before: a module with no file, one a path attribute puts elsewhere, a glob
over an enum, a file whose braces don't balance. A module that holds no
such item the index knows, because a macro declares it or another crate
does, leaves nothing in scope. A `use` of the name that yields no item
doesn't hide the globs: clap's `pub use clap_derive::ValueEnum` is a derive
macro, and the trait comes in through `pub use clap_builder::*`.

A/B with fresh indexes, main 5530676 against this branch, every changed
edge triaged: tokio 233 links move to the item the path names and 78 wrong
links go (the real items are declared inside cfg_*! macros, or are std's
io::Result); axum 6 move; clap 20; ripgrep 49 move and 2 go (termcolor's
ColorChoice); gleam 404 move; dioxus 58 move. No right link is lost, and
527 more keep their target at a higher confidence. serde changes only
confidences; express, gin, flask and leveldb are byte-identical. The new
lookups cost about 0.2 s of CPU per full index of tokio or gleam.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a same-file namesake (colbymchenry#2711)

A Rust name written through a path is an item of what the path names: a
module (`ast::Pattern`, `io::Error`), a type (`Source::Record { … }`) or a
crate (`mio::Interest`, `std::ffi::OsStr`). isRustNameInScope accepted any
candidate in the file the path is written in, whatever the path said, and
a std path only when the candidate was in another file:
- clap's `std::ffi::OsStr` linked to its own `struct OsStr`, and
  `io::Error`, `fmt::Error` and `fmt::Result` in `error/mod.rs` to its own
  `Error` and `Result`;
- tokio's `mio::Interest` linked to its own `Interest`, and
  `std::time::Instant` to its own `Instant`;
- serde's tests' `Token::Struct { … }` literals linked to their own
  `Struct`s, and serde_derive's `syn::Path { … }` to a `Default::Path`
  variant;
- gleam's `ast::Pattern` linked to the `enum Pattern` beside it, and
  `BinaryBuilderPosition::RecordAttribute { … }` to another enum's
  variant of that name.

Fix, in the path branch of isRustNameInScope:
- A path from std, core, alloc or a crate the manifests depend on names
  nothing of the project's, in any file, unless the project is that crate
  or a `use` in the file binds the root.
- The same-file shortcut is gone. A candidate is the path's when its
  file is the path's module, its qualified name holds the segment (a
  type's variant or method), or it sits in an inline `mod` of that name
  in the file (isInRustInlineModule; rustfmt closes the block at the
  indentation it opens at).
- Through a module a `use` binds, a candidate must be in a crate that
  `use`'s path can reach (rustUseCanReach, as for a bare name): tokio's
  `io::Handle` under `use crate::runtime::io` is tokio's own, not
  tokio-test's `io.rs` `Handle` (a dev-dependency).

Tests: rust-path-same-file.test.ts, 6 tests, on both engines; 5 fail
on main (the sixth is the inline-module guard), and the crate-reach one
also fails with only that rule switched off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…olbymchenry#1921)

Python imports now resolve the way the interpreter finds modules: from
the package roots the project has, not by any file whose path merely
ends in the module's name. A project root is the repository, each
service with its own pyproject.toml, setup.cfg or setup.py, its src/,
and the package directories its build config declares; a local root
answers only importers within its reach, so a test fixture's copy of a
package never becomes the application's. Relative imports climb from
the importer's own package.

Before, `import json` or `from datetime import date` could link to a
project file or function of that name, and a src-layout package like
flask's was found through a test fixture named flask.py. On flask,
fastapi, mealie and django, relative imports now resolve (about 2,200
links added), stdlib and third-party names stop linking to project
namesakes (about 1,300 wrong links removed), and imports of a module's
function land on the function rather than its file. A sync re-opens
what an added or removed module, an edited __init__.py or a changed
package root can move. Indexing CPU time is unchanged.

Merged with main: a function-local `import a.b as X` (PR 2607) now uses
the root-aware lookup, the outside-module receiver check (PR 2606)
passes the importer, and plain imports are read at module level only,
since the mappings apply to every function of the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… as `Trait<X = …>` links only to what it names (colbymchenry#2712)

A trait's associated type is named in two more ways than `Self::X`, and
neither names a module item:
- Through a qualified self, `<T as Trait>::X`. isRustNameInScope took any
  associated item of the name for it. axum's `<L as Listener>::Io`, with
  `L` a generic, went to `ReadyListener`'s `type Io`. A trait's own
  `fn call(…) -> <Self as HandlerCallWithExtractors<T, S>>::Future;`
  went to an impl's `type Future` further down the file.
- As a binding in the trait's arguments, `Iterator<Item = &str>` or
  `Readable<Storage = UnsyncStorage>`. The name was matched like a bare
  type. axum's `impl Iterator<Item = &str>` went to a same-file
  `enum Item`, and dioxus's `Storage = …` bindings to the `Storage` trait.

Fix, in isRustNameInScope:
- isRustAssocBinding: a name followed by `=` or `:` inside an unclosed
  `<` on its line is a binding or bound, and links nothing. The trait's
  own associated type is no node.
- rustQualifiedSelf reads `<T as Trait>::X` (and `<T>::X`) as its self
  type and trait, each as the last segment of its path:
  - `Self` means `Self::X`: the enclosing impl's own item, nothing in a
    trait's body;
  - a generic means no impl's;
  - a type means its impl of that trait (the candidate's
    `Owner::Name` must match, and its impl header's trait too).

Tests: rust-assoc-qualified-self.test.ts, 3 tests, on both engines; all
3 fail before the fix, and switching off either rule fails its tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…not its indentation (colbymchenry#2713)

PR colbymchenry#2711 and PR colbymchenry#2702 landed a way each to tell which inline `mod` a
place in a Rust file is in. colbymchenry#2711's isInRustInlineModule scanned lines
upward for `mod <name> {` and trusted rustfmt's indentation to find where
the block closes. colbymchenry#2702's rustModBlocks scans the braces, skipping
strings, raw strings, char literals and comments, and keeps the result in
rustUsesOf. isInRustInlineModule now asks rustBlockAt for the innermost
block around the candidate, as rustDeclaredItems does, so there is one
answer to that question.

What changes:
- An item written without indentation inside `mod flat { … }` is found
  through `flat::Flat`. The indentation rule rejected it.
- `outer::Shell` is only `outer`'s own `Shell`, not one declared in a
  `mod deep` inside it. The upward scan accepted any item below the
  `mod outer {` line.
- A file whose braces don't all close says nothing, as it does for the
  `use` walk of PR colbymchenry#2702.

The A/B (main 818e780 vs this change; axum, tokio, clap, serde,
ripgrep, gleam, dioxus, and the gin, serilog, flask and express
controls) is byte-identical. rust-path-same-file.test.ts gains the two
cases. The `flat::Flat` one fails on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…passes on (colbymchenry#2714)

dioxus's examples write `use dioxus::prelude::*;` and then `Element` or
`use_signal(...)`, which the prelude re-exports from dioxus-core and
dioxus-hooks: `pub use dioxus_core::{Element, ...}`, and `pub use
crate::hooks::*` through `pub use dioxus_hooks as hooks;`. The glob rule
(rustGlobCovers) only took an item declared in a file named like the glob's
last segment, so all of those went unlinked, while `use super::*` took
anything in the parent's directory and a glob over another crate's `types`
or `error` module took this crate's file of that name.

A name only globs bring in now goes through the module walk of colbymchenry#2702:
rustGlobItems walks each of the file's globs from the module it is written
in and looks the name up there. Two additions to the walk:
- a step through a module its parent passes on under that name
  (`pub use dioxus_hooks as hooks;`, `pub use dioxus_signals::{self, *}`);
- Rust's visibility for globs: seen from inside a module (`use super::*`) a
  glob takes everything; from anywhere else only what the module declares
  `pub`, `pub use`s or `pub` globs. dioxus-hooks' `pub use use_effect::*`
  does not pass on that module's own `use dioxus_core::*`, so the prelude
  never brings in dioxus-core's `Ok` function; without this rule 146 std
  `Ok(...)` calls in dioxus's examples linked to it.
A glob that brings the name in settles it, so one the walk can't follow
(a macro's module, a #[path] module) matters only when none does; then the
old module-name rule answers as before.

A/B with fresh indexes, main 505c355 and again on 818e780, every changed
edge triaged: gleam 2053 links added (its `use crate::ast::*` and
`pretty_arena::*` names), 32 moved to the right item, 44 wrong ones gone
(std `Result` taken for the crate's alias through a test module's
`use super::*`, a `compile` parameter); dioxus 2329 added (the prelude's
hooks, signals, stores and rsx/html items), 24 dispatch fan-outs updated by
new implements edges, 7 wrong ones gone; tokio 6 added (`tokio::time::*`),
3 moved to a same-file enum; axum 2 added, 1 wrong gone; serde, ripgrep and
clap only confidences or nothing. No right link lost; express, gin, flask
and leveldb byte-identical. Cost: about 0.24 s of CPU per full index of
dioxus, 0.02 s on gleam.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lared with (colbymchenry#2715)

A Rust method call on a local variable or a parameter (`opts.build()`) was
matched by the method's name whenever the receiver's declaration wasn't one
of two unscoped line patterns. dioxus's `Commands::Build(opts) =>
opts.build()` lost its link once the build module's `BuildRequest::build`
shared the name, and calls on std or dependency values linked to project
namesakes: `cx.waker()` on a `Context` to tokio's `CachedParkThread::waker`.

The receiver is now typed by the binding the call sees. The new
src/resolution/rust-scopes.ts reads each file's parameters, closure
parameters, lets, if-let / while-let / let-else, for and match-arm bindings
with block scope. A binding's type is its written one, the value it is
built from, or the variant or struct field its pattern takes. The method is
the one Rust picks on that type: inherent first, then a trait impl whose
trait is in scope, then a trait's provided method (a blanket impl only where
its bounds are met), then Deref. `&`, Box, Rc, Arc, Pin, Cow and the lock
guards are looked through, their own methods kept (one list with the
self-call path's), and a project impl on the wrapper itself answers before
what the wrapper holds, as it does for `self`. `impl Trait`, `dyn Trait` and
bounded generics reach the trait's method or a supertrait's. Among types
sharing a name, the one its path names through the project's modules wins,
the path written or bound by a block-scoped `use`, else the one that has
the method. A std, dependency or primitive type reaches only a project trait
impl in scope, and not one that hands the call on to the type's own method
of that name.

A binding that writes no type leaves the call to the name strategies, which
no longer take a project type from another declaration of the name. A
trait's own methods carry no `pub`: isVisibleAcrossFiles lets them through
for the calls this path resolved, and name guesses stay out as before.

A/B with fresh indexes against main on axum, serde, ripgrep, clap, dioxus,
tokio and gleam, every changed edge triaged: 4,645 calls linked that were
not, 887 removed (calls on std or dependency values, project types without
the method, a wrapper's own methods), 459 moved to the declared type's
method, 3,669 kept at a higher confidence. gin, serilog, flask and express
are byte-identical. The new code costs 0.6 to 0.9 s of CPU per full index
of tokio, dioxus or gleam.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hod returns (colbymchenry#2716)

A Rust local bound to a method call (`let server = b.port(80).build()`,
`let s = cfg.load()?`, `let conn = c.connect().await`, `if let Some(c) =
arg.get::<Completer>()`) had no type the typed receiver path could read,
so calls on it fell to the name strategies. Those strategies did not read
`?` on a returned `Result`, a `self` method's value or a turbofish, and
picked a same-named method of another type.

The value is now the return type of the method the call reaches on its
receiver's type, read from that method's signature. A receiver is a local,
`self`, or another such call. `.await` hands out an `async fn`'s return
type (read off the source: the extractor's async flag is never set for
Rust) or an `impl Future`'s `Output`, and an `async fn` not awaited is a
future, left unread. A method's own type parameter is the call's turbofish
argument. A parameter the call doesn't write stays opaque: `Standard<W>`
is a `Standard`, but a value that is `W` itself is unread rather than its
bound. A trait's provided method returning `Self` gives the receiver's
own type.

A type with two impls of one trait, `Encoder<Bytes>` and `Encoder<&[u8]>`
or `Service<IncomingStream>` and `Service<Request<B>>`, was ambiguous for
a typed call. The impl whose trait argument is the call's first
argument's type now wins.

A/B with fresh indexes against main on axum, serde, ripgrep, clap, dioxus,
tokio and gleam, every changed edge triaged: 536 calls linked that were
not, 69 removed (calls on std or dependency values a method returns, and
tokio values whose read and write methods come from macro-declared
extension traits), 50 moved to the declared type's method, 565 kept at a
higher confidence. gin, serilog, flask and express are byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…one whose name contains it (colbymchenry#1935)

A call through a class name, `Logger.log()`, or through a receiver named
after one, `logger.log()`, now binds to that class itself: its own
method, else the nearest one a declared supertype has. Before, the
method was any one in the class's file whose qualified name contained
the class's name, so a `FileLogger` declared first took every
`Logger.log()`, and Kotlin's `Foo.create()` went to `FooBar`'s.

Reworked from the exact-owner rule alone, which lost inherited methods
(Django's `form.is_valid()` on `Form(BaseForm)`, Alamofire's protocol
methods). Also in this change:

- A class declared inside a function is named only there: a call from
  anywhere else no longer reaches a class a test declares in its body,
  through the class name, the receiver's name, or the method-name
  fallback. Those methods were never in the running, and the one method
  such a filter leaves is still only a guess by the receiver's name.
- Production code never names a test suite's class, as the method-name
  fallback already held: `manager.check()` in Django's
  `Model._check_managers` is no test app's `Manager` model.
- A Python base built by a class's factory, Django's
  `class Manager(BaseManager.from_queryset(QuerySet))`, names that class
  as the supertype, besides the factory's arguments.

A/B against main with fresh indexes, every changed edge triaged. Django:
67 links added (model instances reaching `Model.save`, inherited lookups
and expressions), 40 removed (links into test-local classes from outside
their function, and one polymorphic manager call), 263 retargeted:
about 170 to the right class (`user.has_perm` to `PermissionsMixin`
rather than `AnonymousUser`, `parser.parse` to the template `Parser`
rather than `MultiPartParser`, `field.get_lookup` to
`RegisterLookupMixin`), about 90 from one guess to another, and about
20 worse, where a receiver named after a model holds something else
(`session.save()` on a session store now guesses the `Session` model).
flask: one fix (`app.get` to `Scaffold.get`), 3 wrong links removed.
Alamofire: one fix and 3 protocol-typed locals that now guess the
`Adapter` class. zod, excalidraw and spring-petclinic: higher
confidence on the same targets. gin, cobra, express, eShopOnWeb and
jekyll are byte-identical. Full suite on the merged tree: 7,908 passed,
0 failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… it is bound from (colbymchenry#2717)

A Rust `for` loop's variable, and a name a tuple pattern binds (`for (k,
v) in &map`, `let (tx, rx) = mpsc::channel(8)`), had no type the typed
receiver path could read, so calls on them fell to the older receiver
inference and the name strategies. tokio's 198 `tx.send(…)` calls on
channel senders went to the internal `chan::Tx::send`, and 100 calls on
the receivers to `chan::Rx`.

The scope reader now records what a `for` loop iterates, and gives the
plain names of a top-level tuple pattern their place in it. A loop's
variable is an item of what it iterates: a std sequence's element, a std
map's `(K, V)`, a slice's, a std iterator's or an `impl Iterator<Item =
T>`'s item, through `&` and the pointers that deref to what they hold.
The std adapters that keep the items (`.iter()`, `.rev()`, `.skip(n)`)
or project them (`.keys()`, `.values()`, `.enumerate()`) are looked
through only where what they are called on is read, so a project method
of one of those names is read from its own signature. A tuple pattern's
name is the matched tuple's field at its place. A field access
(`self.items`, `opts.config`, `pair.0`) has the type the receiver's
struct declares for the field.

A free function called through a module that a `use … as` renames was
looked up by the alias: tokio's loom tests' `oneshot::channel()` under
`use crate::runtime::tests::loom_oneshot as oneshot` read the return type
of `sync::oneshot::channel`. The path's head now goes through its `use`,
and the project's modules are walked along it.

A/B with fresh indexes against main on axum, serde, ripgrep, clap, dioxus,
tokio and gleam, every changed edge triaged: 394 calls linked that were
not, 86 removed (calls on std or dependency values, tokio values whose
read and write methods come from macro-declared extension traits, derived
`Clone`s, fields that hold functions), 404 moved to the declared type's
method, 625 kept at a higher confidence. gin, serilog, flask and express
are byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y or a base gives the attribute (colbymchenry#1926)

Python calls through an attribute reach the method the code gives that
attribute: `self.sink.stop()` follows `self.sink = Sink()`, a `sink: Sink`
annotation, a typed `__init__` parameter, a factory's return type or what
every `return` in it builds, and a base class's `__init__` in another file.
Calls straight on a factory's result (`Client.from_env().send()`) resolve
the same way, and a sync re-opens these answers when the factory or base
they were read from changes. The native Python extractor now keeps a call's
receiver text as the wasm one does, so `self.data.append(1)` is never a bare
`append` that matches an unrelated project function. This includes all of
PR 1704.

Reworked from evidence-or-silence, which dropped about 3,000 correct Django
links (`self.client.get()`, `self.engine.render_to_string()`). The reader
now has three answers. A project class that has the method: that method.
Evidence that rules project methods out: no edge, for a builtin, a class
from outside the project built in a method or named by an annotation, an
attribute only an outside base can give (Django's `TestCase` in an app), or
a class without the method whose bases are all known. Nothing typed: the
call is guessed by the name of its last link, read as written, as any
receiver is, but only for an owner whose name holds the link's head noun
(`self.session` for `SessionBase`, not `database.group_shopping_lists` for
`GroupRepositoryAIProvider`) and never as the one method of a name; the
guess records the files the reader looked at, so a sync re-opens it too. A
class-body field an outside class builds (`author = models.ForeignKey(Author)`)
may be a descriptor, so it is no evidence. A chain through an imported
module (`os.path.exists()`) is the module's. In the shared scoring, a
receiver that spells an owner's whole name (`client` for `Client`)
outscores one that only shares its word (`RedisCacheClient`). A call
through an imported value's attribute chain (`app.jinja_env.filters.keys()`)
no longer links to the value's `jinja_env`.

A/B against main with fresh indexes, every changed edge triaged, sites
matched by position since the extractor now names these calls by their
whole chain. Django: 3,317 calls linked that were not
(`self.client.force_login()` to `ClientMixin`, `User.objects.create_user()`
to `UserManager`, `self.stdout.write()` to `OutputWrapper`), 127 moved,
nearly all to a more precise target (`self.site.register()` to
`AdminSite.register` rather than the `register` decorator), and 134
removed: main's bare-name links on builtin values (`value.lower()` to the
template filter, `.encode()` to a test password hasher) and calls on
expressions such as `(q1 | q2).order_by()`, which now go unresolved as they
do in the wasm engine. flask: 32 linked, 4 moved to `JSONProvider`.
fastapi: 58 linked. mealie: 740 linked. Guesses still wrong, as main makes
them for a plain receiver of the same name: fastapi's
`request.headers.get()` to a telemetry `_HeadersGetter`, and about 20 of
mealie's repository attributes to a controller. Go, C#, Ruby, Swift,
Kotlin, Java and TS repositories are byte-identical, except excalidraw's
5 `props.onChange()` calls, which move between two unrelated `Props`
interfaces. Indexing CPU: Django +7%, mealie +5%, fastapi flat; wall time
unchanged within noise. Full suite on the merged tree: 7,999 passed, 0 failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ks to that declaration (colbymchenry#2718)

A `declare module 'mammoth' { ... }` in a script .d.ts declares the module
outright, and TypeScript takes it before any file the specifier resolves to.
Nothing mapped a package name to a file in the repository, so an import of
such a package linked nothing, or, where the out-of-repo guard did not fire
(VS Code's extensions list no `vscode` dependency), a project namesake. A
bodiless function in an ambient context produced no node either, so
`convertToHtml` had nothing to link to.

- ambient-modules.ts: a token scanner for `declare module` blocks, a
  per-context index of the project's declaration files, and the lookup the
  import resolver makes: named, default (`export default`, `export =`),
  export-clause and namespace-member imports, by position in the block.
- The import resolver consults a script declaration before a file a path
  alias maps the specifier to (copilot's `paths` shim), and the import's
  module reference and namespace or default binding link the declaring file.
- Extraction, both engines: a function_signature under `declare`, in
  `declare global`, at a declaration file's top level or directly in its
  `declare module` body is a function; never in a namespace, nor in an
  ordinary module file's `declare module`, an augmentation.
- A module's function is reached from another file only through an import.
- A type merged across the files declaring one module is no single
  declaration when a receiver is typed.
- Sync re-opens the importers of a package a changed declaration file
  declares.

Augmentations, wildcard patterns, shorthands and test-fixture declarations
are left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
colbymchenry and others added 17 commits October 21, 2026 08:16
… `operator->`, like rocksdb's `FileSystemPtr` and `MultiGetContext::Range::Iterator` (colbymchenry#2735)

C++ reads `x->m` on a class value as `x.operator->()->m`, and applies
`->` again to a class it returns. Only a library holder's `->` and a
container iterator's (`std::vector<T>::iterator`) were read. A call
through a project iterator or smart-pointer wrapper was guessed by the
method's name:
- rocksdb's `fs_->NewWritableFile(…)` on a `FileSystemPtr`, whose
  `operator->` returns a `std::shared_ptr<FileSystem>`, reached
  `FaultInjectionTestFS`;
- `writable_file_->Truncate(…)` on an `FSWritableFilePtr` reached the
  legacy `WritableFile::Truncate`;
- `iter->lkey->user_key()` through `MultiGetContext::Range::Iterator`,
  whose `KeyContext* operator->()` is a `KeyContext*`, reached
  `BlobCountingIterator::user_key`.

Both a member chain's `->` and a `->` call on a declared receiver end in
cppIteratorTarget. For a type that is no container's iterator, it now
falls back to cppOperatorTarget:
- what the class's `operator->` returns, through the pointer it is, or
  with `->` applied again to a class it is: a library holder, or another
  of these;
- else what its `operator*` returns;
- the return type is read where the class declares it, and the class's
  own template parameters are bound to the type's written arguments
  (cppTemplateBound): `UnownedPtr<DB>`'s `T* operator->()` is a `DB*`;
- a parameter the type doesn't bind names no particular class.

A log-only census on main bdf288a found 304 rocksdb and 42 protobuf
dereferences of a project class with an `operator->` that gave no
element. Among the rocksdb calls, 77 were bare-name guesses and 56 were
unlinked.

Kit A/B against bdf288a:

| repo | removed | added | retargeted | same target, now typed |
|---|---|---|---|---|
| rocksdb | 2 | 49 | 158 | 89 |
| protobuf | 0 | 0 | 7 | 3 |
| leveldb, fmt, redis | identical | | | |

- Retargeted:
  - FaultInjectionTestFS → FileSystem (57), WritableFile → FSWritableFile
    (32), and TruncatedRangeDelIterator through UnownedPtr (16);
  - LookupKey and GetContext through MultiGetContext's iterator;
  - SequentialFile and RandomAccessFile → FSSequentialFile and
    FSRandomAccessFile;
  - protobuf's `map_field_->` calls from WeakRepeatedPtrField to the map
    field bases;
  - overloads (DB::Put, PinnableSlice) chosen on the now-known class.
- Removed: `iter->timestamp->assign(…)` on a `std::string*`, which had
  reached `autovector::assign`.
- Added: Status::PermitUncheckedError, FileSystem::OptimizeFor…,
  Cleanable::RegisterCleanup, and gtest's ParamGeneratorInterface through
  linked_ptr.
- About 40 changed sites read by hand were all right.

Mutations: dropping the fallback, the operator* fallback, the second
`->` or the template binding each fail the new tests. Accepting an
inexact class, found only as the sole one of its name, survives; the
guard stays, as in the member-chain matcher.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lbymchenry#2736)

A TypeScript module reaches another module's type only through an import,
so a type it names without importing it is its own or a global one: a
script's top-level declaration or one in a declare global block. colbymchenry#2726
held a supertype to that. A type annotation, a type argument and a type
alias's value went to the name matcher like any other name, which handed
them a project type of that name: vscode's Omit<...> annotations reached
quickInput.ts's export type Omit instead of TypeScript's own, and type
parameters and mapped keys, like excalidraw's <Point extends ...> and
frontend's <T>, reached other modules' types and enum members.

Both name-match strategies now leave out another module's non-global type
for a TS or JS module's type reference to a name the file doesn't import,
ahead of the ranking, so a declare global type still wins over a nearer
module's namesake. Left as they were: the last name of a qualified type,
vscode.TextDocument, written after a dot; a name inside a declare module
'x' block, which is module x's own; and a name an import X = ns.X alias
binds, which the file's import list doesn't hold.

Globals come from declaration files and declare global blocks. A script
.ts's top level is a sample's or a fixture's, global to its own program
only (vscode's colorize fixtures declare type T), and a test's or
fixture's globals reach its tests only, as its declare module blocks do.
That holds for supertypes too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…me-named component (colbymchenry#2737)

React's Pattern 1 ran its component lookup on every PascalCase name in a
.tsx or .jsx file, type annotations included, and its candidate could
outrank name matching, so an annotation linked to a component: outline's
InputSelect.tsx declares `type Option`, and its annotations went to the
`Option` component of Export/ExportDialog.tsx; mastodon's `<Item>` type
parameters went to the `Item` class of media_gallery.jsx, and bulletproof's
`TableProps<Entry>` to another app's `function Entry`.

A type annotation is now name matching's, which scopes a type as TypeScript
does since PR colbymchenry#2736: the file's own, an import's or a global one. Pattern 1
decides only a type alias or interface the file declares beside a value or
a component of the same name, both of them the file's own: the annotation is
the type. That covers bigbluebutton's `type ModalRegistration` beside its
render-prop component, mastodon's `type ShortNumberRenderer` and `interface
AccountList` beside their functions, and a type beside a value that PR colbymchenry#2420
reads through its wrapper or loader. Every other reference keeps PR colbymchenry#2420's
order: a value's loaded or wrapped component, then a function, class or
component the file declares, then name matching for any other declaration
of the file's, and the component lookup only for a name the file doesn't
declare.

Validated on 13 React repos, main 458ad51 against this fix, every changed
site checked against the TypeScript checker and the source:
- 11 annotations move from a component to the type their file declares
  (bbb 5, outline 3, mastodon 3);
- 15 type parameters and qualified types lose a wrong component and link
  nothing (mastodon 8, bulletproof 3, bbb 3, outline 1);
- 220 last names of qualified types, like `React.ReactNode`, `Y.Doc` and
  `SectionKind.Legend`, now come from name matching, wrong before and after:
  219 keep their target and 1 moves to another wrong one (outline 205,
  excalidraw 9, signoz 3, mastodon 3); PR colbymchenry#2736 left that name to name
  matching on purpose;
- next-saas, proshop, t3-turbo, minimal-kit, matx, berry and mantis are
  byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wns the calls in its styles (colbymchenry#2738)

A component declared through a wrapper with no render function of its own
(`styled.div`…``, `styled(ActionButton).attrs(…)<Props>`…``, MUI's
`styled(Box)(({ theme }) => …)`, `memo(Button)`) was a bodyless component
node: nothing walked its initializer, so the calls in its styles went
nowhere, and nothing linked it to the component it wraps, so a render flow
stopped at it. On outline, explore printed no Flow for
"OverflowMenuButton NudeButton ActionButton performAction".

Extraction (TS and the native kernel) now walks the initializer with the
component on the stack: the template's interpolations, the .attrs() /
.withConfig() / options arguments, a style function and a memo comparator
are the component's code. The wrapper's own chain (styled, styled.div,
.attrs, memo) names the library and is not recorded; a typed tag's type
operands are not walked; and the wrapped component is no function-as-value
reference, from the component or from the file (the declaration-wide scan
skips the walked initializer). A component is also a value-ref reader, as
a function is.

The jsx-render synthesizer links a wrapper to the component it wraps
(`wrappedComponentName` in frameworks/react.ts, beside `wrappedName`),
bound as a tag of that name in the file would be, but only where the file
binds the name by a declaration or an import of a project module, so a
package's styled(Link), a Meteor /imports/… path and a destructured name
render nothing rather than a namesake. Files that declare such wrappers are
synthesis inputs, so a sync redraws the link.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er names, not any declaration of that name (colbymchenry#2739)

Both extractors record the last name of a qualified type alone, so
`React.ReactNode` reached name matching as `ReactNode` and bound by word:
outline's 197 `React.ReactNode` annotations linked to its own editor
`class ReactNode`, excalidraw's `TChat.ChatMessage` to a `ChatMessage`
component, signoz's `EQueryType.CLICKHOUSE` to another enum's member, and
outline's `UnfurlResourceType.Group` to the `Group` model the file imports.
PR colbymchenry#2736 left that name to name matching on purpose.

A TypeScript `references` ref written after a qualifier now resolves
through the qualifier, ahead of the framework, import and name strategies:
- an import: the module's export (`import * as T`, through barrels and the
  repository's own `declare module` blocks), or the member of the enum,
  class or namespace a named or default import binds;
- a declaration of the file's own, in the innermost namespace around the
  reference that declares it, else at the top level: an enum's or a
  class's `::` member, or a member of a namespace block;
- otherwise a namespace the project declares global (`Express.User` in a
  `declare global` block).
A package from outside the repository, which no manifest of the importing
file's declares as its own and no `declare module` block declares, and a
global the project doesn't declare, link nothing. An import this resolver
can't follow but no manifest declares as a dependency (zod's own tests'
`import * as z from "zod/v3"`, through the package's `exports`), an
`import X = ns.Y` alias, and a name written after an expression
(`import('./x').T`) keep the old strategies.

The index holds no node for a TypeScript namespace, and its members are
indexed by their bare names, so ambient-modules gains scanNamespaceBlocks:
every `namespace A.B { … }` block with its full name and whether it is
global, read from the same tokens as the module blocks.

Validated on 18 TypeScript repos (13 React apps plus zod, vben, mealie,
prometheus's web UI and fastapi-template), main 2c4a16d against this fix,
every changed site checked with the TypeScript checker in a program over
each file's tsconfig and the repository's declaration files, without
node_modules:
- 300 qualified types move from a wrong declaration to the member
  TypeScript binds (zod 224, outline 39, excalidraw 23, signoz 10,
  mastodon 3, prometheus 1);
- 297 lose a wrong link and link nothing, where TypeScript binds nothing
  of the project, a package's member (outline 254, signoz 32, bbb 8,
  mastodon 3);
- 43 unresolved ones now link the member (outline 28, zod 9, signoz 6);
- 1966 keep their target, now resolved through the qualifier;
- next-saas, proshop, t3-turbo, minimal-kit, matx, berry, mantis,
  bulletproof, fastapi-template and mealie are byte-identical;
- index time is unchanged (125 s before, 120 s after, all 18 repos).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tsconfig paths (colbymchenry#2740)

bigbluebutton's client imports nearly everything from its root,
`import Icon from '/imports/ui/components/common/icon/component'`, which its
tsconfig maps with `"paths": { "/*": ["*"] }`. tsc maps a rooted name through
`paths` (only `./` and `../` count as relative there) and never reads it
from `baseUrl`. ownConfigCandidates refused every specifier starting with
`/`, so all 2,375 of these imports stayed unresolved and every name they
import linked by bare-name matching, often to the wrong one of several
same-named components.

A rooted specifier now goes through the nearest config's `paths` patterns
only; `baseUrl` is still never applied to it, and a protocol-relative
`//host/x` stays out. On bigbluebutton the unresolved refs fall from 26,189
to 22,565 and its rooted imports from 2,375 unresolved to 1 (a module that
isn't in the repository); 13 control repos are byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rapped callee is the plain call (colbymchenry#2742)

A TS/JS call whose callee was no name and no member access (an IIFE, a
curried `connect(mapState)(View)`, `handlers[type]()`, `(0, fn)()`, a
tagged template on a call) stored the callee's whole source text as the
reference's name. Nothing can answer such a name, so each one parked as a
failed reference, an IIFE's entire body among them. extractCall now reads
the callee past the wrappers that keep it the same callee (parentheses,
`!`, `as` / `satisfies`, `await`, type arguments) and records nothing when
that is not a name or a dotted chain; the calls inside are visited on
their own. Mirrored in the kernel (tsjs/extractors.rs callee_name_of).

The reference of a wrapped callee sits at its name, where a plain call's
does, and the resolver's bare-call check reads `fn!(`, `(fn)(`,
`(fn as F)(` and `(fn satisfies F)(` as it reads `fn(`: SigNoz's
`(callback as FrameRequestCallback)(0)` and `(callback)(0)` name the
arrow's own parameter, and from the `(` they bound a generated interface's
`callback` property.

tree-sitter-typescript parses a prefix operator over a generic call as it
parses `await f<T>()` (colbymchenry#2586): `!settings.get<boolean>('X')` and
`void apiRequest<T>()` are calls whose callee is `!settings.get` /
`void apiRequest`. The callee peel that handled `await` now peels a prefix
operator too (peelTsPrefixedCallee; the kernel's peel_await_callee), so the
call is to `settings.get`, and `void apiRequest<T>().then()` encodes as
`apiRequest().then`, not `voidapiRequest().then`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…what the initializer declares (colbymchenry#2743)

PRs colbymchenry#693 and colbymchenry#1802 walk a declaration's initializer under the symbol it declares,
so `const routes = { home }` references `home` from `routes`. The
dispatcher's declaration-wide function-as-value scan then took the same
values again for the enclosing file (or class). Flush-time dedup keys on
the source, so both stayed: a second reference to the same function from
the same spot.

Each initializer walk now records what it walked, and the scan skips it.
PR colbymchenry#2738 added that mechanism for component wrappers, and C#, Scala and Dart
already had their own. The newly covered paths:
- TS/JS module-level constants and variables, owned object literals
  included (colbymchenry#2300), and TS/JS class properties;
- Python assignments, Go var/const specs, Rust const/static items;
- Java fields, and Kotlin properties (walkInitializer takes the property's
  id, so their walk is unchanged).
Mirrored in the kernel: tsjs, python, go, rustlang, java and kotlin.

References no initializer walk takes are unchanged: a module-level call
argument `register(fn)`, C-family tables, Rust's `static CB: fn() = handler`
(the declaration's own value, which the scan still reads).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the barrel its re-export (colbymchenry#2744)

Sync and the file watcher now link `import { useInvocation } from './context'`,
and every use of the name, when an edit gives the barrel context/index.ts
that re-export after the importing file was indexed. Before, the import,
its calls and its JSX or template tags stayed unlinked until the importing
file changed or the project was re-indexed.

The barrel declares none of the names it passes on, so sync's retry by name
never reached the importers' failed references. The edit adds no file and
changes no definition, so neither the importer re-open through added files
(PR colbymchenry#2512) nor the barrel walks (PR colbymchenry#2560, PR colbymchenry#2665) run.

importBindingTail now parks the whole name of a plain named import under
its module's key (`module:context`), as PR colbymchenry#2450 does for default, namespace
and aliased bindings and PR colbymchenry#2507 for Python's unaliased imports. It does so
only while the import resolves to a project file that carries that key and
that module doesn't give the name yet; the by-name lookup still finds the
reference by its own name.

Three versions were measured on 18 repos, and all fix the same barrel-edit
cases. This narrowest one parks 2,727 references on a fresh index, against
11,061 for parking every plain named import, and keeps the retries per
changed file within +1% to +3% of main on folo, vben and milo-ui. Fresh
indexes are identical in nodes, edges and files in all 18 repos, and on
vben's gut scenario sync's difference from a fresh index falls from 2,337
lines to 194.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ns put in it (colbymchenry#2745)

A Go struct can hold a function in a field and call it through the field.
Prometheus' service discovery runs every provider that way: refresh.Discovery
calls d.refreshf(ctx), NewDiscovery copies refreshf from Options.RefreshF,
and each provider passes its own method (RefreshF: d.refresh). Nothing
answered d.refreshf, so a flow from Discovery.Run stopped at the field; colbymchenry#2430
rightly dropped the interface-impl edges that had stood in for it.

goFuncFieldEdges, a Go-only synthesis pass, links a call x.F(...) through a
func field of a struct to each function or method value put in that field:
by a composite literal (keyed or positional, found through its instantiates
edge), by an assignment x.F = v, or by one level of field-to-field copy
(refreshf: opts.RefreshF). A value is what the resolver already linked it
to, else x's method m for x.m, an interface's method for an interface value.
Receivers are typed through the resolver's own Go scope reader
(goLocalDeclarationAt over goLocalDecl, colbymchenry#2706), or by a local's composite
literal, new(T), type assertion or resolved call result. Channels are keyed
by package, struct and field, so a generic field name never crosses between
unrelated structs; one package's test wiring links no other package's test;
an edge cites a function's production wiring; generated files are not read.

Edges are calls, provenance heuristic, synthesizedBy go-func-field, with
field, via (package-qualified when the copied field is another package's)
and registeredAt; explore, the node trail and ContextBuilder read them as
"func field `Discovery.refreshf` (set from `Options.RefreshF`)". The pass
sits after the Go framework passes, with a pool cost hint, and every Go file
now counts as a synthesis input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n package (colbymchenry#2746)

An unexported Go method name belongs to the package that declares it.
goImplementsEdges matched method names only, so an interface asking for
an unexported method was linked to every type in any package with a
method of that name: each of prometheus's `refresher { refresh(...) }`
interfaces (one per discovery package) went to about 37 providers in
other packages, such as discovery/aws.EC2Discovery, none of which Go
lets satisfy it.

Method sets now hold an unexported name together with the directory of
the file that declares the method (goMethodKey), on both sides. Where
the method is declared is what counts, not where the type is: etcd's
gRPC servers outside api/etcdserverpb keep their KVServer edges,
because the UnsafeKVServer or UnimplementedKVServer they embed declares
mustEmbedUnimplementedKVServer in the interface's package.

The interface-dispatch bridge uses the same key, so a call through the
interface reaches the method of the interface's package: not the
type's own namesake from another package, and not one Go's selector
would skip at a shallower embedding depth.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the query names first (colbymchenry#2748)

codegraph_explore's "Dynamic-dispatch links among your symbols" section
deduped its lines by `source name > target name`. Every interface →
implementation link of one method reads the same way (`TrySet →
TrySet`), so an interface method with several implementations printed
one line, and which implementation it kept was edge order, not the
query. On gin, `tryToSetValue setter.TrySet multipartRequest.TrySet
setByForm` printed only `TrySet → TrySet @binding/header.go:35` and hid
formSource's link.

Lines are now deduped by the edge's endpoints (node ids), and the
6-line cap stays. When more links exist than fit:
- a link that reaches a test or example file through an end the query
  didn't name goes last, as explore's answer leaves those files out;
  the predicate is explore's own `isLowValue`, moved to module scope so
  both uses share it;
- otherwise links go by how pointedly the query named their two ends.
  A symbol a token picks out (at most three definitions, the same
  notion as the boundary scan's agent-specific symbols) or a named
  non-callable endpoint weighs 3, a candidate of an ambiguous token 1,
  an unnamed symbol 0. An implementation the query names always comes
  before one it doesn't. The weights also keep an ambiguous token's
  candidates from crowding out a precise one: prometheus's
  `Discovery.refresh` matches a `Discovery` in each discovery package,
  and in `Discovery.refresh fetchApps Decoder.Decode` their links to
  each other filled the cap and hid the one link into `fetchApps`;
- edge order breaks ties.

The section takes the rendered Flow chain itself. It leaves out an edge
between two of the chain's nodes, as before, and also a line that reads
the same as one of the chain's synthesized hops or as a line already
listed. gin declares its `Binding` and `StructValidator` interfaces
once per build tag (binding.go, binding_nomsgpack.go), so the twin
declaration's link printed exactly like the Flow's hop.

A same-name link names each end by its owner, `setter.TrySet →
formSource.TrySet`, the way an agent writes it in a query.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… moves it (colbymchenry#2749)

An edit that changes which declaration a module exports as its default
(`export default A` becoming `export default B` while A stays, or the
default dropped) left every reference through a default import of it on
the old declaration. A sync moves other files' edges into a changed file
onto the node that replaces each target, and an `export default` statement
is no node, so no definition delta, failed-ref retry or importer walk saw
the change. A fresh index links the new default, or nothing.

- ReferenceResolver.changedDefaultExports: for each modified JS/TS module
  that unchanged files import by default or as a namespace (an imports edge
  into its file node named for the binding), compare what the whole-name
  references through those bindings resolved to with the module's default
  now (moduleDefaultExport, the lookup resolveViaImport makes). No file is
  read; a module forwarding its default samples 8 importers' edges.
- reopenReferencesThroughChangedDefaults (module-importers.ts): when one
  moved, the edges bound before this sync resolved anything go back for
  the sweep: through every binding that reads the default (importersOf
  seeded with `default`: default imports, { default as Y },
  require('./x').default, modules passing it on), the routers'
  `layout:<binding>` references, and into the old default's own members
  (typed receivers, inherited members).

Regression test sync-default-export-change.test.ts: 6 cases comparing the
synced graph with a fresh index of the final tree; all fail on main.
Fresh indexes are byte-identical on 8 repos.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sh.Discovery.refresh` (colbymchenry#2750)

Explore's token resolution, codegraph_node's lookup and the callers,
callees and impact lookups dropped every Go symbol written the way Go
code names it: `refresh.Discovery.refresh`, `storage.Queryable.Querier`
and `gin.Context.Next` resolved to nothing, and so did `binding.Default`.
Three gaps:

- A qualified name was matched against the qualifiedName, which holds
  the type and not the package, or entirely against the path, which
  holds the package and not the type, never as a package followed by a
  type. A new matcher stage reads `pkg.Type.method` as leading
  qualifiers that name the package by path segment and trailing ones
  that end the node's scope. A Python `pkg.mod.Class.method` and a Rust
  `module::Type::method` read the same way.
- A module's root package has no directory: gin's `context.go` is
  `package gin`. A Go package qualifier now also matches the package the
  file declares, read from its `package` clause (src/graph/go-package.ts).
  That covers versioned `v2/` directories and generated packages like
  prometheus's `io_prometheus_client` as well. The clause is read last
  and only where it can decide, a top-level function or a node whose
  scope already ends with the written type, so a common name's hundreds
  of definitions cost no file reads.
- Explore and codegraph_node took a qualified token's matches from the
  full-text search's top 50 only, and for gin's `binding.Default` those
  were three `binding/default_validator*.go` files. Through one shared
  helper they now fall back to the exact-name index when the search has
  no match; the CLI's lookup already started there.

The new stage runs only after the existing ones fail, and the search
keeps its order, so a name that resolved before keeps its result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nks list (colbymchenry#2751)

Links of the same rank were listed in edge order, so one named symbol's
long fan-out could fill the 6-line list before another named symbol's
first link. prometheus's `refresh.Discovery.refresh` hands its func
field to 28 discovery packages, and in `refresh.Discovery.refresh
hetzner.refresher.refresh hcloudDiscovery.refresh` those links filled
the list before `refresher.refresh` → `robotDiscovery.refresh`.

Each link now has a turn: how many links of its rank the named symbol
it hangs from already has. Links sort by rank as before, then by turn,
then by edge order, so links of the same rank alternate between the
named symbols. A token that names two interfaces gets both: prometheus's
`Appender.Append` matches storage.Appender and chunkenc.Appender, and
storage's implementations no longer wait behind six of chunkenc's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…olves another way (colbymchenry#2752)

A named import that a name match linked to a declaration elsewhere while
its module did not export the name kept that link after an edit gave the
module the name. A barrel's `export { EmptyState } from './EmptyState'`
declares nothing, so no definition delta, failed-ref retry or barrel walk
saw it (the "retargets" PR colbymchenry#2744 left). A name match into the module
itself, a class exported only as its default and imported by name, kept
its link after the default was dropped, where a fresh index finds nothing.

reopenNameMatchedImports (module-importers.ts): for each module the sync
modified, its importers' binding edges that resolved some other way than
their import (getImportBindingsResolvedElsewhere, an indexed range per
importer), whose import statement names this module, are resolved again
against the graph as it is (ReferenceResolver.resolveNow, writing
nothing). When the answer differs, the importer's edges through the name
and into the members of what the name match took go back for the sweep.

Regression test sync-name-matched-imports.test.ts: 4 cases comparing the
synced graph with a fresh index of the final tree. Fresh indexes are
byte-identical on 8 repos.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port the fixed upstream language, sync and graph changes through the native
kernel while preserving the fork architecture and upstream ancestry.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bompus has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 154 files, which is 54 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2ed7a658-08b6-4d9c-9d4b-31e7906955b9
📥 Commits

Reviewing files that changed from the base of the PR and between d0f288a and e0bb69b.

📒 Files selected for processing: 154
  • .github/workflows/daemon-lifecycle.yml
  • CHANGELOG.md
  • README.md
  • __tests__/ambient-module-imports.test.ts
  • __tests__/bindings-receiver.test.ts
  • __tests__/c-include-lone-macros.test.ts
  • __tests__/call-receiver-no-fabrication.test.ts
  • __tests__/cpp-anonymous-union-members.test.ts
  • __tests__/cpp-declarator-clause-names.test.ts
  • __tests__/cpp-local-callable-calls.test.ts
  • __tests__/cpp-namespace-qualifier.test.ts
  • __tests__/cpp-operator-arrow-targets.test.ts
  • __tests__/cpp-pimpl-member-chains.test.ts
  • __tests__/cpp-specialization-qualifiers.test.ts
  • __tests__/cpp-undeclared-qualifier.test.ts
  • __tests__/dominant-file-plan.test.ts
  • __tests__/explore-synth-link-endpoints.test.ts
  • __tests__/expo-router.test.ts
  • __tests__/express-handler-arguments.test.ts
  • __tests__/extraction.test.ts
  • __tests__/fixtures/golden/markdown-docs.dump
  • __tests__/fixtures/golden/torture-multilang.dump
  • __tests__/fixtures/kernel-parity/Torture.java
  • __tests__/fixtures/kernel-parity/torture.kt
  • __tests__/fixtures/kernel-parity/torture.rs
  • __tests__/function-ref.test.ts
  • __tests__/git-hooks.test.ts
  • __tests__/go-declared-receiver.test.ts
  • __tests__/go-func-field-dispatch.test.ts
  • __tests__/go-implements-unexported.test.ts
  • __tests__/go-local-shadows-function.test.ts
  • __tests__/go-native-port.test.ts
  • __tests__/installer-targets.test.ts
  • __tests__/js-function-local-binding.test.ts
  • __tests__/jsx-render-outside-function.test.ts
  • __tests__/method-call-owner-class.test.ts
  • __tests__/objc-typed-receivers.test.ts
  • __tests__/python-attr-chain.test.ts
  • __tests__/python-attr-types.test.ts
  • __tests__/python-call-fabrication.test.ts
  • __tests__/python-external-module-receiver.test.ts
  • __tests__/python-from-import-module-name.test.ts
  • __tests__/python-initializer-references.test.ts
  • __tests__/python-local-import-alias.test.ts
  • __tests__/python-module-global-receiver-call.test.ts
  • __tests__/python-module-resolution.test.ts
  • __tests__/python-native-port.test.ts
  • __tests__/qualified-name-boundary.test.ts
  • __tests__/react-own-declaration.test.ts
  • __tests__/react-wrapper-initializers.test.ts
  • __tests__/reconcile-native-regressions.test.ts
  • __tests__/rust-as-mut-chains.test.ts
  • __tests__/rust-assoc-qualified-self.test.ts
  • __tests__/rust-associated-item-scope.test.ts
  • __tests__/rust-declared-type-scope.test.ts
  • __tests__/rust-generic-bound-paths.test.ts
  • __tests__/rust-glob-use-items.test.ts
  • __tests__/rust-loop-tuple-field-types.test.ts
  • __tests__/rust-method-value-types.test.ts
  • __tests__/rust-path-same-file.test.ts
  • __tests__/rust-self-field-types.test.ts
  • __tests__/rust-turbofish-calls.test.ts
  • __tests__/rust-typed-receivers.test.ts
  • __tests__/rust-use-path-module.test.ts
  • __tests__/rust-wrapped-self-calls.test.ts
  • __tests__/symbol-lookup-go-packages.test.ts
  • __tests__/sync-default-export-change.test.ts
  • __tests__/sync-import-binding-retry.test.ts
  • __tests__/sync-name-matched-imports.test.ts
  • __tests__/synthesized-hop.test.ts
  • __tests__/ts-awaited-generic-calls.test.ts
  • __tests__/ts-interface-extends.test.ts
  • __tests__/ts-qualified-type-names.test.ts
  • __tests__/ts-type-modifier-imports.test.ts
  • __tests__/ts-type-reference-scope.test.ts
  • __tests__/ts-type-value-namespace.test.ts
  • __tests__/wal-deferral.test.ts
  • codegraph-kernel/src/ccpp/mod.rs
  • codegraph-kernel/src/go/mod.rs
  • codegraph-kernel/src/go/refs.rs
  • codegraph-kernel/src/java/mod.rs
  • codegraph-kernel/src/java/refs.rs
  • codegraph-kernel/src/kotlin/hooks.rs
  • codegraph-kernel/src/kotlin/mod.rs
  • codegraph-kernel/src/kotlin/refs.rs
  • codegraph-kernel/src/python.rs
  • codegraph-kernel/src/resolve/affix.rs
  • codegraph-kernel/src/resolve/cpp_namespace.rs
  • codegraph-kernel/src/resolve/cpp_overloads.rs
  • codegraph-kernel/src/resolve/cpp_range_for.rs
  • codegraph-kernel/src/resolve/cpp_receivers.rs
  • codegraph-kernel/src/resolve/cpp_specializations.rs
  • codegraph-kernel/src/resolve/go_asserted.rs
  • codegraph-kernel/src/resolve/imports.rs
  • codegraph-kernel/src/resolve/js_scope_upstream.rs
  • codegraph-kernel/src/resolve/member_fn_ref.rs
  • codegraph-kernel/src/resolve/member_scope.rs
  • codegraph-kernel/src/resolve/method_call.rs
  • codegraph-kernel/src/resolve/mod.rs
  • codegraph-kernel/src/resolve/name_scope.rs
  • codegraph-kernel/src/resolve/names.rs
  • codegraph-kernel/src/resolve/pipeline.rs
  • codegraph-kernel/src/resolve/prefilter.rs
  • codegraph-kernel/src/resolve/python_globals.rs
  • codegraph-kernel/src/resolve/python_modules.rs
  • codegraph-kernel/src/resolve/python_types.rs
  • codegraph-kernel/src/resolve/query.rs
  • codegraph-kernel/src/resolve/resolver_upstream.rs
  • codegraph-kernel/src/resolve/rust_crates.rs
  • codegraph-kernel/src/resolve/rust_impls.rs
  • codegraph-kernel/src/resolve/rust_modules.rs
  • codegraph-kernel/src/resolve/rust_paths.rs
  • codegraph-kernel/src/resolve/rust_types.rs
  • codegraph-kernel/src/resolve/ts_known.rs
  • codegraph-kernel/src/rustlang/mod.rs
  • codegraph-kernel/src/rustlang/refs.rs
  • codegraph-kernel/src/textutil.rs
  • codegraph-kernel/src/tsjs/calls.rs
  • codegraph-kernel/src/tsjs/exports.rs
  • codegraph-kernel/src/tsjs/extractors.rs
  • codegraph-kernel/src/tsjs/fnref.rs
  • codegraph-kernel/src/tsjs/mod.rs
  • docs/design/framework-coverage.md
  • site/src/content/docs/core-concepts/resolution.md
  • src/bin/codegraph.ts
  • src/codegraph.ts
  • src/db/queries.ts
  • src/db/reference-tail.ts
  • src/extraction/index.ts
  • src/extraction/kernel/loader.ts
  • src/extraction/languages/c-cpp.ts
  • src/extraction/languages/kotlin.ts
  • src/extraction/languages/rust.ts
  • src/extraction/languages/typescript.ts
  • src/extraction/tree-sitter-types.ts
  • src/extraction/tree-sitter.ts
  • src/graph/go-package.ts
  • src/graph/named-symbol-flow.ts
  • src/graph/symbol-lookup.ts
  • src/graph/synthesized-hop.ts
  • src/installer/index.ts
  • src/mcp/tools.ts
  • src/resolution/callback-synthesizer.ts
  • src/resolution/frameworks/express.ts
  • src/resolution/frameworks/react.ts
  • src/resolution/go-func-field-synthesizer.ts
  • src/resolution/import-resolver.ts
  • src/resolution/index.ts
  • src/resolution/module-importers.ts
  • src/resolution/strip-comments.ts
  • src/resolution/type-parameters.ts
  • src/resolution/types.ts
  • src/sync/git-hooks.ts
  • src/ui-server/api/steps.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@bompus

bompus commented Oct 22, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review skipped: 154 files exceed the limit of 100.

@bompus

bompus commented Oct 22, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review skipped: 154 files exceed the limit of 100.

@bompus

bompus commented Oct 22, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review skipped: 154 files exceed the limit of 100.

@bompus

bompus commented Oct 23, 2026

Copy link
Copy Markdown
Owner Author

Landing direction for this PR, recorded before merge.

  • Head verified: e0bb69b6b36ad64ef995e9aa0e9614ecbe2b199c. Base fork/consolidated is still d0f288ab, already contained in the head. All six platform checks (source-reads and lifecycle on Linux, Windows, macOS) pass; no review threads are open.
  • CodeRabbit did not review this head: "Review skipped: 154 files exceed the limit of 100". It reviewed nothing here, so there are no findings to answer.
  • cubic did not review it either: its check is NEUTRAL, titled "AI review line limit reached" (monthly quota). The other review bots are out of quota or on trial limits and are skipped.
  • On 2026-10-23 the user directed landing this one PR, at this head, past the installed review gate's refusal for the CodeRabbit skip. It is not a general waiver.
  • This is an upstream reconcile (pinned to 553d5d101dd8c8ed65e83480e31192e836d8431a), so it lands with a merge commit that keeps upstream's parent.

@bompus
bompus merged commit 76937a3 into fork/consolidated Oct 23, 2026
8 checks passed
@bompus
bompus deleted the merge/upstream-553d5d10 branch October 23, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants