@ttsc/graph 0.16.6 → 0.16.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +22 -0
  2. package/lib/TtscGraphApplication.js +39 -16
  3. package/lib/TtscGraphApplication.js.map +1 -1
  4. package/lib/model/TtscGraphMemory.js +43 -4
  5. package/lib/model/TtscGraphMemory.js.map +1 -1
  6. package/lib/server/createServer.js +555 -221
  7. package/lib/server/createServer.js.map +1 -1
  8. package/lib/server/instructions.js +81 -69
  9. package/lib/server/instructions.js.map +1 -1
  10. package/lib/server/pathPolicy.js +35 -0
  11. package/lib/server/pathPolicy.js.map +1 -0
  12. package/lib/server/resultGuide.js +16 -0
  13. package/lib/server/resultGuide.js.map +1 -0
  14. package/lib/server/runDetails.js +71 -10
  15. package/lib/server/runDetails.js.map +1 -1
  16. package/lib/server/runEntrypoints.js +3 -4
  17. package/lib/server/runEntrypoints.js.map +1 -1
  18. package/lib/server/runLookup.js +21 -9
  19. package/lib/server/runLookup.js.map +1 -1
  20. package/lib/server/runOverview.js +13 -6
  21. package/lib/server/runOverview.js.map +1 -1
  22. package/lib/server/runTour.js +737 -0
  23. package/lib/server/runTour.js.map +1 -0
  24. package/lib/server/runTrace.js +108 -22
  25. package/lib/server/runTrace.js.map +1 -1
  26. package/lib/structures/ITtscGraphNext.js +3 -0
  27. package/lib/structures/ITtscGraphNext.js.map +1 -0
  28. package/lib/structures/ITtscGraphTour.js +3 -0
  29. package/lib/structures/ITtscGraphTour.js.map +1 -0
  30. package/lib/structures/index.js +2 -0
  31. package/lib/structures/index.js.map +1 -1
  32. package/package.json +2 -2
  33. package/src/TtscGraphApplication.ts +49 -16
  34. package/src/model/TtscGraphMemory.ts +46 -4
  35. package/src/server/instructions.ts +81 -69
  36. package/src/server/pathPolicy.ts +43 -0
  37. package/src/server/resultGuide.ts +20 -0
  38. package/src/server/runDetails.ts +90 -6
  39. package/src/server/runEntrypoints.ts +9 -4
  40. package/src/server/runLookup.ts +33 -6
  41. package/src/server/runOverview.ts +24 -8
  42. package/src/server/runTour.ts +881 -0
  43. package/src/server/runTrace.ts +151 -23
  44. package/src/structures/ITtscGraphApplication.ts +35 -64
  45. package/src/structures/ITtscGraphDetails.ts +74 -11
  46. package/src/structures/ITtscGraphEntrypoints.ts +46 -15
  47. package/src/structures/ITtscGraphEscape.ts +19 -9
  48. package/src/structures/ITtscGraphLookup.ts +36 -15
  49. package/src/structures/ITtscGraphNext.ts +23 -0
  50. package/src/structures/ITtscGraphOverview.ts +20 -5
  51. package/src/structures/ITtscGraphTour.ts +150 -0
  52. package/src/structures/ITtscGraphTrace.ts +58 -21
  53. package/src/structures/index.ts +2 -0
@@ -1,18 +1,22 @@
1
1
  import { TtscGraphMemory } from "../model/TtscGraphMemory";
2
+ import { ITtscGraphEdge } from "../structures/ITtscGraphEdge";
2
3
  import { ITtscGraphEvidence } from "../structures/ITtscGraphEvidence";
3
4
  import { ITtscGraphNode } from "../structures/ITtscGraphNode";
4
5
  import { ITtscGraphTrace } from "../structures/ITtscGraphTrace";
5
6
  import { accessAliasesFor } from "./accessAliases";
7
+ import { isExternalNode, isTestPath } from "./pathPolicy";
6
8
  import { resolveGraphHandle } from "./resolveHandle";
9
+ import { resultGuide, resultNext } from "./resultGuide";
7
10
  import { edgeEvidenceOf, edgeEvidenceTextOf, signatureOf } from "./runDetails";
8
11
 
9
12
  const DEFAULT_DEPTH = 2;
10
13
  const DEFAULT_MAX_NODES = 6;
11
14
  const MAX_OPEN_DEPTH = 2;
12
15
  const MAX_OPEN_NODES = 8;
13
- const MAX_HOPS_PER_NODE = 1;
16
+ const MAX_IMPACT_DEPTH = 4;
17
+ const MAX_IMPACT_NODES = 16;
18
+ const MAX_HOPS_PER_NODE = 2;
14
19
  const MAX_STEPS = 6;
15
- const MAX_NEXT_HANDLES = 2;
16
20
 
17
21
  /**
18
22
  * Breadth-first trace along the dependency graph. Structural
@@ -27,10 +31,22 @@ export function runTrace(
27
31
  ): ITtscGraphTrace {
28
32
  const direction = props.direction ?? "forward";
29
33
  const focus = props.focus ?? "all";
30
- const maxDepth = bound(props.maxDepth, DEFAULT_DEPTH, 1, MAX_OPEN_DEPTH);
31
- const maxNodes = bound(props.maxNodes, DEFAULT_MAX_NODES, 1, MAX_OPEN_NODES);
34
+ const impact = direction === "impact";
35
+ const maxDepth = bound(
36
+ props.maxDepth,
37
+ DEFAULT_DEPTH,
38
+ 1,
39
+ impact ? MAX_IMPACT_DEPTH : MAX_OPEN_DEPTH,
40
+ );
41
+ const maxNodes = bound(
42
+ props.maxNodes,
43
+ DEFAULT_MAX_NODES,
44
+ 1,
45
+ impact ? MAX_IMPACT_NODES : MAX_OPEN_NODES,
46
+ );
32
47
  const maxHops = maxNodes * MAX_HOPS_PER_NODE;
33
48
  const reverse = direction === "reverse" || direction === "impact";
49
+ const includeExternal = props.includeExternal === true;
34
50
  // Only an impact trace tags reached nodes with their public-surface role; for
35
51
  // forward/reverse the role is noise.
36
52
  const withRoles = direction === "impact";
@@ -43,6 +59,13 @@ export function runTrace(
43
59
  hops: [],
44
60
  reached: [],
45
61
  truncated: false,
62
+ next: resultNext(
63
+ "clarify",
64
+ "The start handle is ambiguous; choose one returned candidate.",
65
+ ),
66
+ guide: resultGuide(
67
+ "Disambiguate with the returned candidates, or ask the user for the intended symbol.",
68
+ ),
46
69
  candidates: start.candidates.map((n) => summary(graph, n)),
47
70
  };
48
71
  }
@@ -53,6 +76,13 @@ export function runTrace(
53
76
  hops: [],
54
77
  reached: [],
55
78
  truncated: false,
79
+ next: resultNext(
80
+ "clarify",
81
+ "The start handle did not resolve in the compiler graph.",
82
+ ),
83
+ guide: resultGuide(
84
+ "The start symbol was not resolved; answer that the graph has no trace from this handle.",
85
+ ),
56
86
  };
57
87
  }
58
88
 
@@ -65,6 +95,13 @@ export function runTrace(
65
95
  hops: [],
66
96
  reached: [],
67
97
  truncated: false,
98
+ next: resultNext(
99
+ "answer",
100
+ "The path result is the structural flow answer; cite path nodes and evidence ranges.",
101
+ ),
102
+ guide: resultGuide(
103
+ "Use the returned path, hops, and evidence ranges as the flow answer.",
104
+ ),
68
105
  };
69
106
  const target = resolveGraphHandle(graph, props.to);
70
107
  if (target.candidates) {
@@ -83,6 +120,7 @@ export function runTrace(
83
120
  target.node.id,
84
121
  bound(props.maxDepth, 12, 1, 12),
85
122
  focus,
123
+ includeExternal,
86
124
  );
87
125
  const path = found?.path ?? [];
88
126
  const hops = found?.hops ?? [];
@@ -93,7 +131,6 @@ export function runTrace(
93
131
  hops,
94
132
  path: path.map((node, i) => summary(graph, node, i, false, true)),
95
133
  steps: traceSteps(graph, hops),
96
- next: nextFromPath(path),
97
134
  };
98
135
  }
99
136
 
@@ -112,12 +149,18 @@ export function runTrace(
112
149
  truncated = true;
113
150
  continue;
114
151
  }
115
- const edges = reverse ? graph.incoming(id) : graph.outgoing(id);
152
+ const edges = orderedEdges(
153
+ graph,
154
+ reverse ? graph.incoming(id) : graph.outgoing(id),
155
+ direction,
156
+ reverse,
157
+ );
116
158
  for (const edge of edges) {
117
159
  if (!traversable(edge.kind, focus)) continue;
118
160
  const otherId = reverse ? edge.from : edge.to;
119
161
  const other = graph.node(otherId);
120
162
  if (other === undefined || other.kind === "file") continue;
163
+ if (!includeExternal && isExternalNode(other)) continue;
121
164
  const hop: ITtscGraphTrace.IHop = {
122
165
  from: edge.from,
123
166
  to: edge.to,
@@ -164,21 +207,17 @@ export function runTrace(
164
207
  hops,
165
208
  reached: [...reached.values()],
166
209
  steps: traceSteps(graph, hops),
167
- next: {
168
- details: [start.node.id, ...reached.keys()].slice(0, MAX_NEXT_HANDLES),
169
- traceFrom: [...reached.keys()].slice(0, MAX_NEXT_HANDLES),
170
- },
210
+ next: resultNext(
211
+ "answer",
212
+ "Steps, hops, reached nodes, and evidence ranges are the flow answer surface.",
213
+ ),
214
+ guide: resultGuide(
215
+ "Use steps, hops, reached nodes, and evidence ranges as the flow answer or reading-list anchor.",
216
+ ),
171
217
  truncated,
172
218
  };
173
219
  }
174
220
 
175
- function nextFromPath(path: ITtscGraphNode[]): ITtscGraphTrace.INext {
176
- return {
177
- details: path.map((node) => node.id),
178
- traceFrom: path.length > 0 ? [path[path.length - 1]!.id] : [],
179
- };
180
- }
181
-
182
221
  function traceSteps(
183
222
  graph: TtscGraphMemory,
184
223
  hops: ITtscGraphTrace.IHop[],
@@ -209,6 +248,7 @@ function findPath(
209
248
  targetId: string,
210
249
  maxDepth: number,
211
250
  focus: ITtscGraphTrace.IRequest["focus"],
251
+ includeExternal: boolean,
212
252
  ): { path: ITtscGraphNode[]; hops: ITtscGraphTrace.IHop[] } | null {
213
253
  const startNode = graph.node(startId);
214
254
  if (startNode === undefined) return null;
@@ -234,6 +274,7 @@ function findPath(
234
274
  if (visited.has(otherId)) continue;
235
275
  const other = graph.node(otherId);
236
276
  if (other === undefined || other.kind === "file") continue;
277
+ if (!includeExternal && isExternalNode(other)) continue;
237
278
  visited.add(otherId);
238
279
  const evidence = edgeEvidenceOf(edge);
239
280
  parent.set(otherId, {
@@ -282,6 +323,59 @@ function findPath(
282
323
  return null;
283
324
  }
284
325
 
326
+ function orderedEdges(
327
+ graph: TtscGraphMemory,
328
+ edges: readonly ITtscGraphEdge[],
329
+ direction: string,
330
+ reverse: boolean,
331
+ ): readonly ITtscGraphEdge[] {
332
+ if (direction !== "impact")
333
+ return [...edges].sort(
334
+ (a, b) =>
335
+ edgeKindRank(a.kind) - edgeKindRank(b.kind) ||
336
+ traceEndpointRank(graph, reverse ? a.from : a.to) -
337
+ traceEndpointRank(graph, reverse ? b.from : b.to) ||
338
+ evidenceRank(a) - evidenceRank(b),
339
+ );
340
+ return [...edges].sort(
341
+ (a, b) =>
342
+ impactEndpointRank(graph, reverse ? a.from : a.to) -
343
+ impactEndpointRank(graph, reverse ? b.from : b.to) ||
344
+ edgeKindRank(a.kind) - edgeKindRank(b.kind) ||
345
+ evidenceRank(a) - evidenceRank(b),
346
+ );
347
+ }
348
+
349
+ function impactEndpointRank(graph: TtscGraphMemory, id: string): number {
350
+ const node = graph.node(id);
351
+ if (node === undefined) return 9;
352
+ if (isTestPath(node.file)) return 0;
353
+ if (node.exported) return 1;
354
+ if (node.external || node.ignored) return 4;
355
+ return 2;
356
+ }
357
+
358
+ function traceEndpointRank(graph: TtscGraphMemory, id: string): number {
359
+ const node = graph.node(id);
360
+ if (node === undefined) return 9;
361
+ if (isTestPath(node.file)) return 6;
362
+ switch (node.kind) {
363
+ case "function":
364
+ case "method":
365
+ case "class":
366
+ return 0;
367
+ case "variable":
368
+ return 1;
369
+ case "property":
370
+ return 2;
371
+ case "interface":
372
+ case "type":
373
+ return 4;
374
+ default:
375
+ return 3;
376
+ }
377
+ }
378
+
285
379
  /**
286
380
  * Summarize a node for a trace result. With `withRoles`, tag the public-surface
287
381
  * roles (exported / test) an impact trace reports; other directions omit them.
@@ -299,6 +393,16 @@ function summary(
299
393
  kind: node.kind,
300
394
  file: node.file,
301
395
  };
396
+ if (node.evidence?.startLine !== undefined)
397
+ out.line = node.evidence.startLine;
398
+ const span = node.implementation ?? node.evidence;
399
+ if (span !== undefined) {
400
+ out.sourceSpan = {
401
+ file: span.file,
402
+ startLine: span.startLine,
403
+ ...(span.endLine !== undefined ? { endLine: span.endLine } : {}),
404
+ };
405
+ }
302
406
  if (depth !== undefined) out.depth = depth;
303
407
  if (withSignature) {
304
408
  const sig = signatureOf(graph.project, node);
@@ -307,7 +411,7 @@ function summary(
307
411
  if (withRoles) {
308
412
  const roles: string[] = [];
309
413
  if (node.exported) roles.push("exported");
310
- if (isTestFile(node.file)) roles.push("test");
414
+ if (isTestPath(node.file)) roles.push("test");
311
415
  if (roles.length > 0) out.roles = roles;
312
416
  }
313
417
  return out;
@@ -341,11 +445,35 @@ function traversable(
341
445
  return true;
342
446
  }
343
447
 
344
- function isTestFile(file: string): boolean {
345
- return (
346
- /(^|\/)(test|tests|__tests__|spec)\//.test(file) ||
347
- /\.(test|spec)\.[cm]?tsx?$/.test(file)
348
- );
448
+ function edgeKindRank(kind: string): number {
449
+ switch (kind) {
450
+ case "calls":
451
+ return 0;
452
+ case "instantiates":
453
+ return 1;
454
+ case "renders":
455
+ return 2;
456
+ case "accesses":
457
+ return 3;
458
+ case "tests":
459
+ return 4;
460
+ case "overrides":
461
+ case "decorates":
462
+ return 5;
463
+ case "extends":
464
+ case "implements":
465
+ return 6;
466
+ case "type_ref":
467
+ return 7;
468
+ default:
469
+ return 10;
470
+ }
471
+ }
472
+
473
+ function evidenceRank(edge: ITtscGraphEdge): number {
474
+ const line = edge.evidence?.startLine ?? 9_999;
475
+ const col = edge.evidence?.startCol ?? 999;
476
+ return line * 100 + col;
349
477
  }
350
478
 
351
479
  function bound(
@@ -3,114 +3,85 @@ import { ITtscGraphEntrypoints } from "./ITtscGraphEntrypoints";
3
3
  import { ITtscGraphEscape } from "./ITtscGraphEscape";
4
4
  import { ITtscGraphLookup } from "./ITtscGraphLookup";
5
5
  import { ITtscGraphOverview } from "./ITtscGraphOverview";
6
+ import { ITtscGraphTour } from "./ITtscGraphTour";
6
7
  import { ITtscGraphTrace } from "./ITtscGraphTrace";
7
8
 
8
- /**
9
- * The MCP tool surface of `@ttsc/graph`, as a typed application.
10
- *
11
- * The single method is the single MCP tool. Its parameter object becomes the
12
- * JSON schema once `typia.llm.controller` reflects this interface.
13
- * `TtscGraphApplication` implements it over the resident graph.
14
- */
9
+ /** The typed MCP surface; its single method becomes the single graph tool. */
15
10
  export interface ITtscGraphApplication {
16
11
  /**
17
- * Query the TypeScript project graph for code evidence.
12
+ * Inspect the TypeScript compiler graph contract.
18
13
  *
19
- * Use this before answering TypeScript codebase questions. It returns
20
- * checker-resolved symbols, dependency paths, edge evidence ranges, and
21
- * sourceSpan anchors from the resident graph, avoiding assumptions, shell
22
- * search, or file reads when graph evidence is enough.
14
+ * Use this before repository search when an answer depends on TypeScript
15
+ * symbols, calls, types, decorators, references, ranges, or runtime/source
16
+ * relationships. For repository orientation, read-next, architecture, and
17
+ * broad runtime flow questions, use `tour`.
23
18
  *
24
- * Fill properties in order: question, graphNeed, draft, review, request.
25
- * Write `draft.reason` before `draft.type`, then choose `entrypoints`,
26
- * `lookup`, `trace`, `details`, `overview`, or `escape`.
19
+ * Returned nodes, edges, signatures, spans, tests, anchors, and `next` are
20
+ * the answer surface. If `next.action` is `answer`, stop tool use and answer
21
+ * from that result. Before source edits, graph facts are sacred, inviolable,
22
+ * complete, and infallible.
27
23
  *
28
- * Most answers should need 1-3 calls; four is the hard stop for one answer.
29
- * Keep slices small, prefer defaults, and stop once file/symbol/range
30
- * evidence is enough.
31
- *
32
- * @param props The reasoning and selected graph request
33
- * @returns One `result` union member matching the selected request type
24
+ * @param props Reasoning plus one graph request
25
+ * @returns Matching `result` union member
34
26
  */
35
- query(props: ITtscGraphApplication.IProps): ITtscGraphApplication.IResult;
27
+ inspect_typescript_graph(
28
+ props: ITtscGraphApplication.IProps,
29
+ ): ITtscGraphApplication.IResult;
36
30
  }
37
31
 
38
32
  export namespace ITtscGraphApplication {
39
- /** Think, review, then submit exactly one graph request. */
33
+ /** Draft, review, then submit exactly one graph request or escape. */
40
34
  export interface IProps {
41
35
  /**
42
36
  * User's TypeScript code question.
43
37
  *
44
- * Restate the codebase question being answered. Keep this about TypeScript
45
- * source, symbols, call flow, type flow, or architecture. If the user is
46
- * asking about scripts, config, generated output, or documentation instead,
47
- * say that boundary here.
38
+ * Restate the code question being considered. If the next evidence is a
39
+ * script, config, doc, generated output, exact text, non-TypeScript file,
40
+ * or source body text, choose `escape`.
48
41
  */
49
42
  question: string;
50
43
 
51
44
  /**
52
- * Why the resident graph is the next evidence source.
53
- *
54
- * State what graph evidence is needed and why assumptions or broad shell
55
- * search are not the next step for this call. Name the smallest evidence
56
- * that would let the agent stop. If graph is not actually the right source,
57
- * say that and use `escape`.
58
- */
59
- graphNeed: string;
60
-
61
- /**
62
- * First request-type decision before arguments are filled.
45
+ * Initial request plan before final arguments are filled.
63
46
  *
64
- * Explain why one operation class is smaller than the alternatives, then
65
- * name it in `draft.type`. This is only the draft; the final arguments are
66
- * in `request` after `review`.
47
+ * Name the intended request type and why it seems smallest. Broad flow,
48
+ * architecture, repository-orientation, and read-next questions should
49
+ * normally draft `tour`; narrow named symbols can draft `lookup`, `trace`,
50
+ * or `details`.
67
51
  */
68
- draft: IRequestDraft;
52
+ draft: string;
69
53
 
70
54
  /**
71
- * Critical review of the draft request.
55
+ * Final self-review before calling.
72
56
  *
73
- * Check whether the draft avoids overfetch, non-graph fallback, broad
74
- * reads, and unnecessary neighbor expansion. If this would be a fourth
75
- * broad lookup, trace, or details call, prefer answering from evidence in
76
- * hand or choose `escape`. Do not spend graph calls only to hunt for tests.
77
- * If the draft is wrong, choose the corrected type in `request`.
57
+ * Correct a stale, broad, duplicate, or wrong draft here. If broad flow was
58
+ * split into search/detail steps, switch to `tour`. If graph facts already
59
+ * answer, or prior `next.action` was `answer`, make `request.type` be
60
+ * `escape`; do not call graph or read files to re-confirm returned facts.
78
61
  */
79
62
  review: string;
80
63
 
81
- /** The graph operation chosen from the reasoning above, or a no-op escape. */
64
+ /** Final graph operation chosen after review, or a no-op escape. */
82
65
  request:
83
66
  | ITtscGraphEntrypoints.IRequest
84
67
  | ITtscGraphLookup.IRequest
85
68
  | ITtscGraphTrace.IRequest
86
69
  | ITtscGraphDetails.IRequest
87
70
  | ITtscGraphOverview.IRequest
71
+ | ITtscGraphTour.IRequest
88
72
  | ITtscGraphEscape.IRequest;
89
73
  }
90
74
 
91
- /** First-pass operation choice before final request arguments. */
92
- export interface IRequestDraft {
93
- /** Why this operation type is the smallest useful next step. */
94
- reason: string;
95
-
96
- /** Draft discriminator for the intended graph operation. */
97
- type:
98
- | ITtscGraphEntrypoints.IRequest["type"]
99
- | ITtscGraphLookup.IRequest["type"]
100
- | ITtscGraphTrace.IRequest["type"]
101
- | ITtscGraphDetails.IRequest["type"]
102
- | ITtscGraphOverview.IRequest["type"]
103
- | ITtscGraphEscape.IRequest["type"];
104
- }
105
-
106
75
  /** The selected request's output. `result.type` mirrors `request.type`. */
107
76
  export interface IResult {
77
+ /** Result branch matching the submitted `request.type`. */
108
78
  result:
109
79
  | ITtscGraphEntrypoints
110
80
  | ITtscGraphLookup
111
81
  | ITtscGraphTrace
112
82
  | ITtscGraphDetails
113
83
  | ITtscGraphOverview
84
+ | ITtscGraphTour
114
85
  | ITtscGraphEscape;
115
86
  }
116
87
  }
@@ -1,23 +1,32 @@
1
1
  import { ITtscGraphDecorator } from "./ITtscGraphDecorator";
2
2
  import { ITtscGraphEvidence } from "./ITtscGraphEvidence";
3
+ import { ITtscGraphNext } from "./ITtscGraphNext";
3
4
 
4
5
  /**
5
- * The resolved symbol details returned for a set of handles.
6
+ * The source-free facts for a few selected handles.
6
7
  *
7
- * The default payload is source-free: signatures, member outlines, and direct
8
- * graph summaries with sourceSpan anchors.
8
+ * This is not a file reader. It returns signatures, member outlines, direct
9
+ * calls, direct types, implementation candidates, dependency summaries, and
10
+ * sourceSpan citation anchors.
9
11
  */
10
12
  export interface ITtscGraphDetails {
11
13
  /** Discriminator for selected symbol inspection. */
12
14
  type: "details";
13
15
 
16
+ /** Selected node facts, in the same order as resolved handles when possible. */
14
17
  nodes: ITtscGraphDetails.INode[];
15
18
 
19
+ /** How to use this source-free result next. */
20
+ next: ITtscGraphNext;
21
+
22
+ /** Human-readable compatibility note mirroring `next`. */
23
+ guide: string;
24
+
16
25
  /** Handles that resolved to no node, or that were ambiguous. */
17
26
  unknown: string[];
18
27
  }
19
28
  export namespace ITtscGraphDetails {
20
- /** Which handles to inspect, and how much of each to return. */
29
+ /** Which selected handles to inspect, and how much of each to return. */
21
30
  export interface IRequest {
22
31
  /** Discriminator for selected symbol inspection. */
23
32
  type: "details";
@@ -25,14 +34,16 @@ export namespace ITtscGraphDetails {
25
34
  /**
26
35
  * Node ids from another tool, or dotted symbol handles such as
27
36
  * `OrderService.create`. Pass the few handles you need for source-free
28
- * details; use `trace` when you need a path instead of widening this call.
37
+ * details. Prefer one to three handles. Use `trace` when you need a path
38
+ * instead of widening this call.
29
39
  */
30
40
  handles: string[];
31
41
 
32
42
  /**
33
43
  * Also list each node's direct dependencies and dependents (the symbols it
34
44
  * uses and the symbols that use it). The list is capped; raise
35
- * `neighborLimit` only when the first slice is not enough.
45
+ * `neighborLimit` when the first slice is truncated and the missing
46
+ * relation is named. This remains a relationship summary, not a file body.
36
47
  *
37
48
  * @default false
38
49
  */
@@ -42,13 +53,17 @@ export namespace ITtscGraphDetails {
42
53
  * Maximum dependencies and dependents to return per side when
43
54
  * `neighbors:true`.
44
55
  *
56
+ * Prefer the default. Values above a few neighbors are usually overfetch;
57
+ * call `trace` for flow instead.
58
+ *
45
59
  * @default 2
46
60
  */
47
61
  neighborLimit?: number;
48
62
 
49
63
  /**
50
64
  * Maximum owned members to return for a container or object literal. Raise
51
- * only when the first outline is truncated.
65
+ * only when the first outline is truncated and the missing member is
66
+ * named.
52
67
  *
53
68
  * @default 6
54
69
  */
@@ -56,73 +71,121 @@ export namespace ITtscGraphDetails {
56
71
 
57
72
  /**
58
73
  * Maximum direct execution and type references to return per group. Raise
59
- * only when the first dependency slice is not enough.
74
+ * only when the first dependency slice is truncated and the missing
75
+ * dependency is named.
60
76
  *
61
77
  * @default 1
62
78
  */
63
79
  dependencyLimit?: number;
80
+
81
+ /**
82
+ * Include dependency-boundary references from node_modules or bundled
83
+ * `.d.ts` libraries. Leave false for source-architecture answers; enable
84
+ * only when external type/API boundaries are the question.
85
+ *
86
+ * @default false
87
+ */
88
+ includeExternal?: boolean;
64
89
  }
65
90
 
66
91
  /** One inspected node: its declared shape and graph coordinates. */
67
92
  export interface INode {
93
+ /** Stable node id for subsequent `details` or `trace` calls. */
68
94
  id: string;
95
+
96
+ /** Qualified symbol name when available, otherwise the simple name. */
69
97
  name: string;
98
+
99
+ /** Declaration kind (`class`, `method`, `function`, ...). */
70
100
  kind: string;
101
+
102
+ /** Project-relative path of the file that declares this node. */
71
103
  file: string;
104
+
72
105
  /** 1-based declaration line, when known. */
73
106
  line?: number;
107
+
74
108
  /** The declaration signature: its first line(s) up to the body. */
75
109
  signature?: string;
110
+
76
111
  /** Decorators written on this declaration, when any. */
77
112
  decorators?: ITtscGraphDecorator[];
113
+
78
114
  /** Assigned implementation span, when source comes from one. */
79
115
  implementation?: ITtscGraphEvidence;
116
+
80
117
  /** Direct execution dependencies in source order, with edge evidence. */
81
118
  calls?: IReference[];
119
+
82
120
  /** Direct type dependencies in source order, with edge evidence. */
83
121
  types?: IReference[];
122
+
123
+ /** Concrete nodes that implement or override this interface/base member. */
124
+ implementedBy?: IReference[];
125
+
84
126
  /** String literal values from the signature. */
85
127
  literals?: string[];
128
+
86
129
  /**
87
130
  * For a container or object-literal variable: the owned symbol or top-level
88
131
  * property outline a consumer reaches for, without bodies.
89
132
  */
90
133
  members?: IMember[];
91
- /** The declaration or implementation file and line range, when known. */
134
+
135
+ /** Declaration or implementation citation range, when known. */
92
136
  sourceSpan?: Pick<ITtscGraphEvidence, "file" | "startLine" | "endLine">;
137
+
93
138
  /** Symbols this node uses (outgoing dependency edges). */
94
139
  dependsOn?: IReference[];
140
+
95
141
  /** Symbols that use this node (incoming dependency edges). */
96
142
  dependedOnBy?: IReference[];
97
143
  }
98
144
 
99
145
  /** One member of a container node, with its signature but not its body. */
100
146
  export interface IMember {
147
+ /** Member name, qualified when the graph records an owner-qualified handle. */
101
148
  name: string;
149
+
150
+ /** Member kind (`method`, `property`, `class`, ...). */
102
151
  kind: string;
152
+
103
153
  /** 1-based declaration line, when known. */
104
154
  line?: number;
155
+
105
156
  /** The member's declaration signature. */
106
157
  signature?: string;
158
+
107
159
  /** Decorators written on this member, when any. */
108
160
  decorators?: ITtscGraphDecorator[];
109
161
  }
110
162
 
111
163
  /** A dependency neighbor of an inspected node and the edge that links them. */
112
164
  export interface IReference {
165
+ /** Stable id of the neighboring node. */
113
166
  id: string;
167
+
168
+ /** Neighbor symbol name, qualified when available. */
114
169
  name: string;
170
+
171
+ /** Neighbor declaration kind. */
115
172
  kind: string;
173
+
174
+ /** Project-relative declaration file for the neighbor. */
116
175
  file: string;
176
+
117
177
  /** 1-based declaration line, when known. */
118
178
  line?: number;
179
+
119
180
  /** The edge kind connecting the two (`calls`, `type_ref`, ...). */
120
181
  relation: string;
182
+
121
183
  /**
122
- * Source span for the expression that produced this relationship. It lets
123
- * an agent see why the edge exists without opening the file.
184
+ * Source span for the expression that produced this relationship. It is
185
+ * repository evidence for the edge, not a file-read instruction.
124
186
  */
125
187
  evidence?: ITtscGraphEvidence;
188
+
126
189
  /**
127
190
  * Stable access-path aliases derived from edge evidence. For example, an
128
191
  * edge to `Owner.member` through `obj.slot.member` may expose