Files
codegraph/__tests__
ferres c0ccbacd3f fix(cli): route callers/callees/impact through one symbol resolver
`callers`, `callees` and `impact` each carried their own symbol filter,
comparing the user's query against the BARE node name only:

    node.name === symbol || node.name.endsWith('.' + symbol)

That fails in two opposite directions in the same repository.

A bare name OVER-reports. Every same-named definition passes the filter
and their results are unioned under one heading — "Callers of group" can
list callers that belong to an entirely different `group`, with nothing
saying the name was ambiguous. Collisions cluster on short generic names
(`group`, `num`, `parse`), so this bites hardest exactly where the verbs
would otherwise be most useful.

A qualified name UNDER-reports. `Foo.Bar.baz` can never equal a bare
`baz`, so every candidate fails the filter, and the guarded fallback
takes whichever node full-text search ranked first — or reports "not
found" for a symbol that plainly exists. It only ever appeared to work
when FTS happened to return exactly one hit.

All three now resolve through graph/symbol-lookup, which the MCP tools
share, so a verb cannot drift from the matcher again:

- the exact-name index is consulted first and is authoritative. It is
  complete and uncapped, whereas FTS ranks, truncates, and tokenises
  `::` away — so resolution no longer depends on search ranking. FTS
  stays as the fallback for the fuzzy cases it is good at.
- `matchesSymbol` gains a boundary-aligned suffix match under a
  canonical separator. Splitting on every separator assumes no scope
  component contains one, which is false for any language whose module
  names are themselves dotted: the stored `A.B::c` can never equal the
  split-and-rejoined `A::B::c`, so a precise query resolved to nothing.
- an ambiguous bare name still aggregates (an interface method and its
  overrides are usually all wanted) but the union is now disclosed, with
  the matched definitions named and a qualified spelling that narrows
  it. `--json` gains a `targets` array and an `ambiguous` flag.

`matchesSymbol` moves out of mcp/tools.ts unchanged apart from the new
stage; the tool path delegates to it, so its existing coverage applies.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Bsi9EH64kMisnik4E1gf7
2026-08-30 21:15:43 +00:00
..