feat(ui): where the graph stops — the Flow strip's dynamic-dispatch end cap (CG-51)
A flow that does not reach what it was asked about now ends in a cap instead of in silence: the dispatch form that ended it, the line, the static key when the source spells one out, the candidate runtime targets as clickable rows, and the name-only matches under 0.6 the search refused to follow. A flow that does reach its destination never shows one. The verdict is lifted out of `ToolHandler` into `src/graph/dynamic-boundary-report.ts` and both callers render it — `codegraph_explore`'s prose and `/api/flow`'s `WireFlowBoundary` — the same move `named-symbol-flow.ts` made for the path finder, and for the same reason: a reader holding the strip and the MCP answer must not be told two different things. The explore prose is unchanged, byte for byte. When nothing connects at all and a dispatch site explains why, the strip is that site: one card opened at the line where the static path ends, plus the cap. When nothing explains it, no stopping point is invented.
This commit is contained in:
@@ -459,11 +459,50 @@ export interface WireFlowHop {
|
||||
source: WireFlowSource | null;
|
||||
}
|
||||
|
||||
/** One plausible runtime target of a keyed dispatch — a clickable cap row. */
|
||||
export interface WireBoundaryCandidate {
|
||||
node: WireNodeRef;
|
||||
display: string;
|
||||
named: boolean;
|
||||
}
|
||||
|
||||
/** A dynamic-dispatch site: the form, the key when it is visible, the targets. */
|
||||
export interface WireBoundarySite {
|
||||
form: string;
|
||||
label: string;
|
||||
snippet: string;
|
||||
line: number;
|
||||
key: string | null;
|
||||
keyIsType: boolean;
|
||||
moreSites: number;
|
||||
candidates: WireBoundaryCandidate[];
|
||||
candidateNote: string | null;
|
||||
}
|
||||
|
||||
export interface WireFlowContinuation {
|
||||
node: WireNodeRef;
|
||||
line: number | null;
|
||||
confidence: number | null;
|
||||
}
|
||||
|
||||
/** Where the graph stops — the strip's end cap (design spec §3.5). */
|
||||
export interface WireFlowBoundary {
|
||||
node: WireNodeRef;
|
||||
sites: WireBoundarySite[];
|
||||
uncertain: WireList<WireFlowContinuation>;
|
||||
further: WireList<WireFlowContinuation>;
|
||||
missed: WireNodeRef[];
|
||||
}
|
||||
|
||||
export interface WireFlow {
|
||||
id: string;
|
||||
/** "execute → rowToFileRecord", for the header's flow picker. */
|
||||
label: string;
|
||||
hops: WireFlowHop[];
|
||||
/** Null on a flow that reaches everything it was asked about. */
|
||||
boundary: WireFlowBoundary | null;
|
||||
/** One card at the dispatch site, not a path: the answer ran out here. */
|
||||
partial: boolean;
|
||||
}
|
||||
|
||||
export interface WireFlowAmbiguity {
|
||||
|
||||
Reference in New Issue
Block a user