Summary
graphify explain "<name>" resolves exactly one node when multiple nodes share the label, and gives no indication that other candidates exist. The output reads as "everything connected to this name" while actually being "everything connected to one silently-chosen node." In a real codebase this hid the caller list of an identically-named standalone function that sat on the critical path of the task at hand — the invisible half was only found by grep.
Extraction is not at fault: both symbols are present in graph.json as distinct nodes. This is purely a resolution/UX gap in explain (and presumably any other name-addressed command).
Minimal reproduction (4 files, TypeScript)
// helpers.ts
export class Helpers {
fetchAuthors(ids: string[]): string[] {
return ids.map((i) => "author-" + i);
}
}
// util.ts
export function fetchAuthors(ids: string[]): string[] {
return ids.map((i) => "util-author-" + i);
}
// method-caller.ts
import { Helpers } from "./helpers";
export function viaMethod(): string[] { return new Helpers().fetchAuthors(["1"]); }
// util-caller.ts
import { fetchAuthors } from "./util";
export function viaUtil(): string[] { return fetchAuthors(["2"]); }
Build the graph, then:
$ graphify explain "fetchAuthors"
Node: .fetchAuthors()
ID: helpers_helpers_fetchauthors
Source: helpers.ts L2
...
Connections (1):
<-- Helpers [method] [EXTRACTED] helpers.ts:L2
No mention of util_fetchauthors, which is in the graph:
$ python -c "...dump nodes matching fetchauthors..."
helpers_helpers_fetchauthors | .fetchAuthors()
util_fetchauthors | fetchAuthors()
Expected
Any of these would fix it (in order of preference):
- When N > 1 nodes match a label, print all matches (or all matches' connection blocks), the way IDE "go to definition" pickers do.
- At minimum, a one-line warning:
⚠ 2 nodes share this label — showing helpers_helpers_fetchauthors; also: util_fetchauthors.
- A
--all flag if the default must stay single-node.
The silent single-resolution is the dangerous part: a partial answer that presents as total. Users who trust it skip the confirming grep exactly when they shouldn't.
Environment
graphifyy 0.9.27 (pip), Python 3.12.x, Windows 11, TypeScript corpus via tree-sitter. Directed and undirected graphs both reproduce.
Summary
graphify explain "<name>"resolves exactly one node when multiple nodes share the label, and gives no indication that other candidates exist. The output reads as "everything connected to this name" while actually being "everything connected to one silently-chosen node." In a real codebase this hid the caller list of an identically-named standalone function that sat on the critical path of the task at hand — the invisible half was only found by grep.Extraction is not at fault: both symbols are present in
graph.jsonas distinct nodes. This is purely a resolution/UX gap inexplain(and presumably any other name-addressed command).Minimal reproduction (4 files, TypeScript)
Build the graph, then:
No mention of
util_fetchauthors, which is in the graph:Expected
Any of these would fix it (in order of preference):
⚠ 2 nodes share this label — showing helpers_helpers_fetchauthors; also: util_fetchauthors.--allflag if the default must stay single-node.The silent single-resolution is the dangerous part: a partial answer that presents as total. Users who trust it skip the confirming grep exactly when they shouldn't.
Environment
graphifyy 0.9.27 (pip), Python 3.12.x, Windows 11, TypeScript corpus via tree-sitter. Directed and undirected graphs both reproduce.