@ttsc/graph 0.16.5 → 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.
- package/README.md +22 -0
- package/lib/TtscGraphApplication.js +58 -22
- package/lib/TtscGraphApplication.js.map +1 -1
- package/lib/model/TtscGraphMemory.js +43 -4
- package/lib/model/TtscGraphMemory.js.map +1 -1
- package/lib/model/loadGraph.js +17 -17
- package/lib/server/accessAliases.js +53 -0
- package/lib/server/accessAliases.js.map +1 -0
- package/lib/server/createServer.js +1490 -657
- package/lib/server/createServer.js.map +1 -1
- package/lib/server/instructions.js +81 -21
- package/lib/server/instructions.js.map +1 -1
- package/lib/server/pathPolicy.js +35 -0
- package/lib/server/pathPolicy.js.map +1 -0
- package/lib/server/resultGuide.js +16 -0
- package/lib/server/resultGuide.js.map +1 -0
- package/lib/server/runDetails.js +474 -0
- package/lib/server/runDetails.js.map +1 -0
- package/lib/server/{runIndex.js → runEntrypoints.js} +92 -28
- package/lib/server/runEntrypoints.js.map +1 -0
- package/lib/server/runLookup.js +246 -0
- package/lib/server/runLookup.js.map +1 -0
- package/lib/server/runOverview.js +44 -27
- package/lib/server/runOverview.js.map +1 -1
- package/lib/server/runTour.js +737 -0
- package/lib/server/runTour.js.map +1 -0
- package/lib/server/runTrace.js +224 -43
- package/lib/server/runTrace.js.map +1 -1
- package/lib/structures/ITtscGraphDetails.js +3 -0
- package/lib/structures/ITtscGraphDetails.js.map +1 -0
- package/lib/structures/ITtscGraphEntrypoints.js +3 -0
- package/lib/structures/ITtscGraphEntrypoints.js.map +1 -0
- package/lib/structures/{ITtscGraphExpand.js → ITtscGraphEscape.js} +1 -1
- package/lib/structures/ITtscGraphEscape.js.map +1 -0
- package/lib/structures/ITtscGraphLookup.js +3 -0
- package/lib/structures/ITtscGraphLookup.js.map +1 -0
- package/lib/structures/{ITtscGraphIndex.js → ITtscGraphNext.js} +1 -1
- package/lib/structures/ITtscGraphNext.js.map +1 -0
- package/lib/structures/{ITtscGraphQuery.js → ITtscGraphTour.js} +1 -1
- package/lib/structures/ITtscGraphTour.js.map +1 -0
- package/lib/structures/index.js +6 -3
- package/lib/structures/index.js.map +1 -1
- package/package.json +2 -2
- package/src/TtscGraphApplication.ts +70 -30
- package/src/model/TtscGraphMemory.ts +46 -4
- package/src/server/accessAliases.ts +55 -0
- package/src/server/createServer.ts +4 -7
- package/src/server/instructions.ts +81 -21
- package/src/server/pathPolicy.ts +43 -0
- package/src/server/resultGuide.ts +20 -0
- package/src/server/runDetails.ts +553 -0
- package/src/server/{runIndex.ts → runEntrypoints.ts} +116 -36
- package/src/server/runLookup.ts +284 -0
- package/src/server/runOverview.ts +59 -31
- package/src/server/runTour.ts +881 -0
- package/src/server/runTrace.ts +299 -45
- package/src/structures/ITtscGraphApplication.ts +75 -56
- package/src/structures/ITtscGraphDecorator.ts +12 -14
- package/src/structures/ITtscGraphDetails.ts +197 -0
- package/src/structures/ITtscGraphEntrypoints.ts +149 -0
- package/src/structures/ITtscGraphEscape.ts +49 -0
- package/src/structures/ITtscGraphEvidence.ts +5 -8
- package/src/structures/ITtscGraphLookup.ts +82 -0
- package/src/structures/ITtscGraphNext.ts +23 -0
- package/src/structures/ITtscGraphNode.ts +10 -4
- package/src/structures/ITtscGraphOverview.ts +41 -18
- package/src/structures/ITtscGraphTour.ts +150 -0
- package/src/structures/ITtscGraphTrace.ts +93 -13
- package/src/structures/TtscGraphNodeKind.ts +2 -2
- package/src/structures/index.ts +6 -3
- package/lib/server/runExpand.js +0 -177
- package/lib/server/runExpand.js.map +0 -1
- package/lib/server/runIndex.js.map +0 -1
- package/lib/server/runQuery.js +0 -147
- package/lib/server/runQuery.js.map +0 -1
- package/lib/structures/ITtscGraphExpand.js.map +0 -1
- package/lib/structures/ITtscGraphIndex.js.map +0 -1
- package/lib/structures/ITtscGraphQuery.js.map +0 -1
- package/src/server/runExpand.ts +0 -186
- package/src/server/runQuery.ts +0 -150
- package/src/structures/ITtscGraphExpand.ts +0 -85
- package/src/structures/ITtscGraphIndex.ts +0 -100
- package/src/structures/ITtscGraphQuery.ts +0 -49
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { TtscGraphMemory } from "./model/TtscGraphMemory";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { resultGuide, resultNext } from "./server/resultGuide";
|
|
3
|
+
import { runDetails } from "./server/runDetails";
|
|
4
|
+
import { runEntrypoints } from "./server/runEntrypoints";
|
|
5
|
+
import { runLookup } from "./server/runLookup";
|
|
4
6
|
import { runOverview } from "./server/runOverview";
|
|
5
|
-
import {
|
|
7
|
+
import { runTour } from "./server/runTour";
|
|
6
8
|
import { runTrace } from "./server/runTrace";
|
|
7
9
|
import { ITtscGraphApplication } from "./structures/ITtscGraphApplication";
|
|
8
|
-
import {
|
|
9
|
-
import { ITtscGraphIndex } from "./structures/ITtscGraphIndex";
|
|
10
|
-
import { ITtscGraphOverview } from "./structures/ITtscGraphOverview";
|
|
11
|
-
import { ITtscGraphQuery } from "./structures/ITtscGraphQuery";
|
|
12
|
-
import { ITtscGraphTrace } from "./structures/ITtscGraphTrace";
|
|
10
|
+
import { ITtscGraphEscape } from "./structures/ITtscGraphEscape";
|
|
13
11
|
|
|
14
12
|
export type TtscGraphSource = TtscGraphMemory | (() => TtscGraphMemory);
|
|
15
13
|
|
|
@@ -17,12 +15,11 @@ export type TtscGraphSource = TtscGraphMemory | (() => TtscGraphMemory);
|
|
|
17
15
|
* The MCP tool surface as a plain class over the resident
|
|
18
16
|
* {@link TtscGraphMemory}.
|
|
19
17
|
*
|
|
20
|
-
*
|
|
21
|
-
* {@link ITtscGraphApplication} to generate
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* binds them to the graph.
|
|
18
|
+
* Its public method is the MCP tool: `typia.llm.controller` reflects
|
|
19
|
+
* {@link ITtscGraphApplication} to generate the tool's JSON schema and argument
|
|
20
|
+
* validator from the signature and JSDoc, with no hand-written schema. The
|
|
21
|
+
* method delegates to the pure graph functions in `./server`, which are
|
|
22
|
+
* unit-testable without a transport; this class only binds them to the graph.
|
|
26
23
|
*
|
|
27
24
|
* Every method answers from the resident graph; none recompiles. Output is kept
|
|
28
25
|
* compact and bounded so a model can read structure without a file read, which
|
|
@@ -35,23 +32,66 @@ export class TtscGraphApplication implements ITtscGraphApplication {
|
|
|
35
32
|
this.graph = typeof source === "function" ? source : () => source;
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
public
|
|
39
|
-
|
|
35
|
+
public inspect_typescript_graph(
|
|
36
|
+
props: ITtscGraphApplication.IProps,
|
|
37
|
+
): ITtscGraphApplication.IResult {
|
|
38
|
+
if (props.request.type === "escape") {
|
|
39
|
+
const result = this.escape(props.request.reason);
|
|
40
|
+
if (props.request.nextStep !== undefined) {
|
|
41
|
+
result.nextStep = props.request.nextStep;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
result,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
switch (props.request.type) {
|
|
48
|
+
case "entrypoints":
|
|
49
|
+
return {
|
|
50
|
+
result: runEntrypoints(this.graph(), props.request),
|
|
51
|
+
};
|
|
52
|
+
case "lookup":
|
|
53
|
+
return {
|
|
54
|
+
result: runLookup(this.graph(), props.request),
|
|
55
|
+
};
|
|
56
|
+
case "trace":
|
|
57
|
+
return {
|
|
58
|
+
result: runTrace(this.graph(), props.request),
|
|
59
|
+
};
|
|
60
|
+
case "details":
|
|
61
|
+
return {
|
|
62
|
+
result: runDetails(this.graph(), props.request),
|
|
63
|
+
};
|
|
64
|
+
case "overview":
|
|
65
|
+
return {
|
|
66
|
+
result: runOverview(this.graph(), props.request),
|
|
67
|
+
};
|
|
68
|
+
case "tour":
|
|
69
|
+
return {
|
|
70
|
+
result: runTour(this.graph(), props.request),
|
|
71
|
+
};
|
|
72
|
+
default:
|
|
73
|
+
throw new Error("Unknown graph request type");
|
|
74
|
+
}
|
|
40
75
|
}
|
|
41
76
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
77
|
+
private escape(
|
|
78
|
+
reason: string,
|
|
79
|
+
nextStep?: string,
|
|
80
|
+
action: "answer" | "outside" | "clarify" = "outside",
|
|
81
|
+
): ITtscGraphEscape {
|
|
82
|
+
return {
|
|
83
|
+
type: "escape",
|
|
84
|
+
skipped: true,
|
|
85
|
+
reason,
|
|
86
|
+
next: resultNext(
|
|
87
|
+
action,
|
|
88
|
+
nextStep ??
|
|
89
|
+
"Graph evidence is exhausted or not the next evidence source.",
|
|
90
|
+
),
|
|
91
|
+
guide: resultGuide(
|
|
92
|
+
"Finish from existing graph evidence, state the graph gap, or ask for clarification.",
|
|
93
|
+
),
|
|
94
|
+
...(nextStep !== undefined ? { nextStep } : {}),
|
|
95
|
+
};
|
|
56
96
|
}
|
|
57
97
|
}
|
|
@@ -9,9 +9,9 @@ import { TtscGraphEdgeKind } from "../structures/TtscGraphEdgeKind";
|
|
|
9
9
|
* It loads one `ttscgraph dump` — the checker-resolved fact graph — then
|
|
10
10
|
* synthesizes the structural relationships the dump deliberately leaves to this
|
|
11
11
|
* layer: `file` container nodes, the `contains` ownership tree, and `exports`
|
|
12
|
-
* edges, plus
|
|
13
|
-
* Every tool call is then a lookup
|
|
14
|
-
* nothing recompiles.
|
|
12
|
+
* edges, plus class/interface member implementation edges and the refinement of
|
|
13
|
+
* a class-member `variable` to a `property`. Every tool call is then a lookup
|
|
14
|
+
* or a traversal over the indexes built here; nothing recompiles.
|
|
15
15
|
*/
|
|
16
16
|
export class TtscGraphMemory {
|
|
17
17
|
private readonly byId: Map<string, ITtscGraphNode>;
|
|
@@ -179,9 +179,11 @@ function synthesize(dump: ITtscGraphDump): {
|
|
|
179
179
|
// Ownership: a member is contained by its owner; a top-level declaration by
|
|
180
180
|
// its file. Exports: a file exports each of its public nodes.
|
|
181
181
|
const structural: ITtscGraphEdge[] = [];
|
|
182
|
+
const membersByOwner = new Map<string, ITtscGraphNode[]>();
|
|
182
183
|
for (const node of nodes) {
|
|
183
184
|
if (node.external || node.file === "") continue;
|
|
184
185
|
const parent = owner(node);
|
|
186
|
+
if (parent !== undefined) push(membersByOwner, parent.id, node);
|
|
185
187
|
const container = parent ? parent.id : fileNodeId(node.file);
|
|
186
188
|
structural.push({
|
|
187
189
|
from: container,
|
|
@@ -197,8 +199,48 @@ function synthesize(dump: ITtscGraphDump): {
|
|
|
197
199
|
}
|
|
198
200
|
}
|
|
199
201
|
|
|
202
|
+
const synthesized = [...edges, ...structural];
|
|
203
|
+
const edgeKeys = new Set(
|
|
204
|
+
synthesized.map((edge) => `${edge.kind}\0${edge.from}\0${edge.to}`),
|
|
205
|
+
);
|
|
206
|
+
const byId = new Map(nodes.map((node) => [node.id, node]));
|
|
207
|
+
for (const edge of edges) {
|
|
208
|
+
const kind: TtscGraphEdgeKind | undefined =
|
|
209
|
+
edge.kind === "implements"
|
|
210
|
+
? "implements"
|
|
211
|
+
: edge.kind === "extends"
|
|
212
|
+
? "overrides"
|
|
213
|
+
: undefined;
|
|
214
|
+
if (kind === undefined) continue;
|
|
215
|
+
const derived = byId.get(edge.from);
|
|
216
|
+
const base = byId.get(edge.to);
|
|
217
|
+
if (derived === undefined || base === undefined) continue;
|
|
218
|
+
const derivedMembers = membersByOwner.get(derived.id) ?? [];
|
|
219
|
+
const baseMembers = membersByOwner.get(base.id) ?? [];
|
|
220
|
+
for (const baseMember of baseMembers) {
|
|
221
|
+
const derivedMember = derivedMembers.find(
|
|
222
|
+
(member) =>
|
|
223
|
+
member.name === baseMember.name &&
|
|
224
|
+
implementationMemberKinds.has(member.kind) &&
|
|
225
|
+
implementationMemberKinds.has(baseMember.kind),
|
|
226
|
+
);
|
|
227
|
+
if (derivedMember === undefined) continue;
|
|
228
|
+
const key = `${kind}\0${derivedMember.id}\0${baseMember.id}`;
|
|
229
|
+
if (edgeKeys.has(key)) continue;
|
|
230
|
+
edgeKeys.add(key);
|
|
231
|
+
synthesized.push({
|
|
232
|
+
from: derivedMember.id,
|
|
233
|
+
to: baseMember.id,
|
|
234
|
+
kind,
|
|
235
|
+
evidence: derivedMember.implementation ?? derivedMember.evidence,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
200
240
|
return {
|
|
201
241
|
nodes: [...nodes, ...fileNodes.values()],
|
|
202
|
-
edges:
|
|
242
|
+
edges: synthesized,
|
|
203
243
|
};
|
|
204
244
|
}
|
|
245
|
+
|
|
246
|
+
const implementationMemberKinds = new Set(["method", "property"]);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ITtscGraphNode } from "../structures/ITtscGraphNode";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Derive stable access-path aliases for a member edge from its source
|
|
5
|
+
* expression. If a hop reaches `Owner.member` through `obj.path.member`, the
|
|
6
|
+
* alias `Owner.path.member` keeps both the resolved owner and the concrete
|
|
7
|
+
* access path visible without reopening source.
|
|
8
|
+
*/
|
|
9
|
+
export function accessAliasesFor(
|
|
10
|
+
node: ITtscGraphNode | undefined,
|
|
11
|
+
evidenceText: string | undefined,
|
|
12
|
+
): string[] | undefined {
|
|
13
|
+
if (
|
|
14
|
+
node === undefined ||
|
|
15
|
+
node.qualifiedName === undefined ||
|
|
16
|
+
evidenceText === undefined
|
|
17
|
+
) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const segments = dottedSegments(evidenceText);
|
|
21
|
+
if (segments.length < 2 || segments[segments.length - 1] !== node.name) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const dot = node.qualifiedName.lastIndexOf(".");
|
|
25
|
+
if (dot < 0) return undefined;
|
|
26
|
+
|
|
27
|
+
const owner = node.qualifiedName.slice(0, dot);
|
|
28
|
+
const suffix = segments.slice(1).join(".");
|
|
29
|
+
const aliases = new Set<string>();
|
|
30
|
+
for (const candidate of [...ownerDisplayAliases(owner), owner]) {
|
|
31
|
+
const alias = `${candidate}.${suffix}`;
|
|
32
|
+
if (alias !== node.qualifiedName) aliases.add(alias);
|
|
33
|
+
}
|
|
34
|
+
return aliases.size > 0 ? [...aliases] : undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function dottedSegments(text: string): string[] {
|
|
38
|
+
const normalized = text.trim().replace(/\?\./g, ".");
|
|
39
|
+
const parts = normalized.split(".");
|
|
40
|
+
if (parts.length < 2) return [];
|
|
41
|
+
return parts.every((part) => /^[A-Za-z_$][\w$]*$/.test(part)) ? parts : [];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function ownerDisplayAliases(owner: string): string[] {
|
|
45
|
+
const display = owner.replace(/^_+/, "");
|
|
46
|
+
const out = new Set<string>();
|
|
47
|
+
for (const suffix of ["Internals", "Internal"]) {
|
|
48
|
+
if (display.length > suffix.length && display.endsWith(suffix)) {
|
|
49
|
+
out.add(display.slice(0, -suffix.length));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (out.size === 0 && display !== owner) out.add(display);
|
|
53
|
+
out.delete(owner);
|
|
54
|
+
return [...out];
|
|
55
|
+
}
|
|
@@ -12,7 +12,7 @@ import { instructions } from "./instructions";
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Build the MCP server for a graph. `typia.llm.controller` reflects
|
|
15
|
-
* {@link ITtscGraphApplication} into a validated tool application
|
|
15
|
+
* {@link ITtscGraphApplication} into a validated tool application. Every tool's
|
|
16
16
|
* JSON schema and argument validator is generated from the method's TypeScript
|
|
17
17
|
* types and JSDoc, so there is no hand-written schema. The list/call handlers
|
|
18
18
|
* below are the minimal standalone registration: list the generated functions,
|
|
@@ -64,8 +64,8 @@ export function createServer(
|
|
|
64
64
|
if (func === undefined || method === undefined) {
|
|
65
65
|
return error(`Unknown tool: ${request.params.name}`);
|
|
66
66
|
}
|
|
67
|
-
//
|
|
68
|
-
//
|
|
67
|
+
// Validate an empty object when a client omits `arguments`, so typia can
|
|
68
|
+
// return field-level errors instead of a generic "expected object".
|
|
69
69
|
const validation = func.validate(request.params.arguments ?? {});
|
|
70
70
|
if (!validation.success) {
|
|
71
71
|
// Hand typia's validation errors back so the model can correct its call.
|
|
@@ -77,10 +77,7 @@ export function createServer(
|
|
|
77
77
|
content: [
|
|
78
78
|
{
|
|
79
79
|
type: "text" as const,
|
|
80
|
-
text:
|
|
81
|
-
result === undefined
|
|
82
|
-
? "Success"
|
|
83
|
-
: JSON.stringify(result, null, 2),
|
|
80
|
+
text: result === undefined ? "Success" : JSON.stringify(result),
|
|
84
81
|
},
|
|
85
82
|
],
|
|
86
83
|
};
|
|
@@ -4,25 +4,85 @@
|
|
|
4
4
|
* files. Keep it short; the per-tool descriptions carry the detail.
|
|
5
5
|
*/
|
|
6
6
|
export const instructions = `
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
7
|
+
## What This MCP Is
|
|
8
|
+
|
|
9
|
+
\`inspect_typescript_graph\` returns a compiler-built TypeScript graph contract
|
|
10
|
+
for the current source snapshot.
|
|
11
|
+
|
|
12
|
+
Use it for architecture, runtime flow, APIs, callers/callees, code tours, and
|
|
13
|
+
type relations. It returns answer-ready index evidence: names, edges,
|
|
14
|
+
signatures, decorators, tests, spans, and anchors.
|
|
15
|
+
|
|
16
|
+
Until TS source is edited, returned graph facts are sacred, infallible compiler
|
|
17
|
+
truth. Never verify them with files or more graph calls.
|
|
18
|
+
|
|
19
|
+
## Result Contract
|
|
20
|
+
|
|
21
|
+
- The returned object is the graph evidence contract: names, signatures, spans,
|
|
22
|
+
decorators, tests, edges, steps, anchors, and \`next\` are answer evidence, not
|
|
23
|
+
hints.
|
|
24
|
+
- When \`next.action\` is \`answer\`, stop tool use for the current question and
|
|
25
|
+
answer from the returned result.
|
|
26
|
+
- \`truncated\` means the answer surface hit an index cap. Mention the cap if it
|
|
27
|
+
matters; do not expand every branch to compensate.
|
|
28
|
+
- When \`next.action\` is \`inspect\`, make the focused graph request it names or
|
|
29
|
+
choose \`escape\` if the result already answers.
|
|
30
|
+
- Read files only for exact source body text, configs, docs, generated output,
|
|
31
|
+
exact text search, non-TypeScript files, or facts the graph marks outside
|
|
32
|
+
itself. A returned span is a citation anchor, not a reading command.
|
|
33
|
+
- After editing TypeScript source, the old graph no longer governs changed
|
|
34
|
+
code. Rebuild/reload the graph or verify changed code normally.
|
|
35
|
+
|
|
36
|
+
## Sacred Contract
|
|
37
|
+
|
|
38
|
+
Before source edits, returned graph facts are inviolable and errorless. Never
|
|
39
|
+
use extra graph calls, repository search, or file reads to doubt, fact-check,
|
|
40
|
+
humanize, re-derive, re-narrate, or re-confirm returned nodes, spans, edges,
|
|
41
|
+
signatures, decorators, tests, references, steps, or anchors.
|
|
42
|
+
|
|
43
|
+
## Tour Contract
|
|
44
|
+
|
|
45
|
+
Use \`tour\` for repository orientation, read-next, architecture tours, and
|
|
46
|
+
broad runtime flow, including questions that name several phases or subsystems.
|
|
47
|
+
A tour is the complete index-level answer surface: central entrypoints, primary
|
|
48
|
+
flow, nearby paths, tests, and anchors. Do not decompose a broad tour into
|
|
49
|
+
lookup/details loops unless the user later asks for a named missing symbol or
|
|
50
|
+
exact source text.
|
|
51
|
+
|
|
52
|
+
## Use Contract
|
|
53
|
+
|
|
54
|
+
1. Ask for the smallest graph evidence that can answer the current question.
|
|
55
|
+
2. Broad flow, repository-orientation, code-tour, or read-next question: start
|
|
56
|
+
with \`tour\`.
|
|
57
|
+
3. Concrete named symbol: use \`lookup\`, then \`details\` only if needed.
|
|
58
|
+
4. Known endpoint pair or one selected handle: use one \`trace\`.
|
|
59
|
+
5. Unknown narrow orientation: use \`entrypoints\` once.
|
|
60
|
+
6. Selected symbol shape: use \`details\` for one to three handles.
|
|
61
|
+
7. Follow the returned \`next\`: answer, inspect once more, leave graph, or
|
|
62
|
+
clarify.
|
|
63
|
+
8. Use \`escape\` when another graph call would repeat evidence or the remaining
|
|
64
|
+
evidence is outside the TypeScript graph.
|
|
65
|
+
|
|
66
|
+
Most TypeScript structure answers need one or two graph calls.
|
|
67
|
+
|
|
68
|
+
## Request Fields
|
|
69
|
+
|
|
70
|
+
Fill the visible checklist, then exactly one request.
|
|
71
|
+
|
|
72
|
+
- \`question\`: restate the code question being considered.
|
|
73
|
+
- \`draft\`: initial request type and why it seems smallest.
|
|
74
|
+
- \`review\`: correct a wrong, broad, stale, or duplicate draft. If graph facts
|
|
75
|
+
already answer, if prior \`next.action\` was \`answer\`, or if the next evidence
|
|
76
|
+
is outside the indexed TypeScript graph, say so here and make \`request.type\`
|
|
77
|
+
be \`escape\`. If a broad flow draft is not \`tour\`, correct it here.
|
|
78
|
+
- \`request\`: final request after review.
|
|
79
|
+
|
|
80
|
+
## How to answer from graph evidence
|
|
81
|
+
|
|
82
|
+
- Use returned node names, signatures, edges, references, evidence, and
|
|
83
|
+
\`sourceSpan\` ranges directly.
|
|
84
|
+
- Explain the central path first, then mention important branches.
|
|
85
|
+
- For tests, impact, or reading lists, returned nodes and ranges are the answer
|
|
86
|
+
evidence, not search keywords.
|
|
87
|
+
- A returned range is a sacred citation anchor, not permission to open the file.
|
|
28
88
|
`.trim();
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ITtscGraphNode } from "../structures/ITtscGraphNode";
|
|
2
|
+
|
|
3
|
+
/** True for dependency declarations outside the authored project graph. */
|
|
4
|
+
export function isExternalNode(node: ITtscGraphNode): boolean {
|
|
5
|
+
return (
|
|
6
|
+
node.external ||
|
|
7
|
+
node.file.startsWith("bundled://") ||
|
|
8
|
+
/(^|\/)node_modules\//.test(node.file)
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** True for tests, examples, fixtures, generated output, and build artifacts. */
|
|
13
|
+
export function isSupportPath(file: string): boolean {
|
|
14
|
+
return (
|
|
15
|
+
file === "" ||
|
|
16
|
+
file.startsWith("bundled://") ||
|
|
17
|
+
/(^|\/)node_modules\//.test(file) ||
|
|
18
|
+
/(^|\/)(test|tests|__tests__|spec|sample|samples|fixture|fixtures|__fixtures__|example|examples)\//.test(
|
|
19
|
+
file,
|
|
20
|
+
) ||
|
|
21
|
+
/\.(test|spec)\.[cm]?tsx?$/.test(file) ||
|
|
22
|
+
/(^|\/)typings\.[cm]?ts$/.test(file) ||
|
|
23
|
+
/\.d\.[cm]?ts$/.test(file) ||
|
|
24
|
+
/(^|\/)(dist|build|coverage|generated|__generated__)\//.test(file)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** True for source files whose declarations are tests or test helpers. */
|
|
29
|
+
export function isTestPath(file: string): boolean {
|
|
30
|
+
return (
|
|
31
|
+
/(^|\/)(test|tests|__tests__|spec)\//.test(file) ||
|
|
32
|
+
/\.(test|spec)\.[cm]?tsx?$/.test(file)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** True when exported symbols are unlikely to be authored public API. */
|
|
37
|
+
export function isPublicApiNoisePath(file: string): boolean {
|
|
38
|
+
return (
|
|
39
|
+
isSupportPath(file) ||
|
|
40
|
+
/(^|\/|\.)typings\.[cm]?ts$/.test(file) ||
|
|
41
|
+
/(^|\/)internal\//.test(file)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ITtscGraphNext } from "../structures/ITtscGraphNext";
|
|
2
|
+
|
|
3
|
+
const SOURCE_POLICY =
|
|
4
|
+
"The returned object is the graph evidence contract: names, edges, signatures, decorators, tests, ranges, anchors, steps, and next are the answer surface. If next.action is answer, stop tool use for this question and answer now. Truncated means capped index evidence, not a request to expand every branch. Until TypeScript source is edited, returned graph facts are sacred, infallible compiler truth. Never call graph again or read files to doubt, validate, fact-check, re-derive, re-confirm, re-narrate, or improve returned graph facts. Read source bodies only when the user explicitly asks for exact source text or changed code must be verified.";
|
|
5
|
+
|
|
6
|
+
export function resultGuide(action: string): string {
|
|
7
|
+
return `${action} ${SOURCE_POLICY}`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function resultNext(
|
|
11
|
+
action: ITtscGraphNext["action"],
|
|
12
|
+
reason: string,
|
|
13
|
+
request?: ITtscGraphNext["request"],
|
|
14
|
+
): ITtscGraphNext {
|
|
15
|
+
return {
|
|
16
|
+
action,
|
|
17
|
+
reason,
|
|
18
|
+
...(request !== undefined ? { request } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|