@ttsc/graph 0.16.4 → 0.16.5
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/LICENSE +21 -21
- package/README.md +24 -53
- package/lib/TtscGraphApplication.js +46 -0
- package/lib/TtscGraphApplication.js.map +1 -0
- package/lib/index.js +31 -108
- package/lib/index.js.map +1 -1
- package/lib/model/TtscGraphMemory.js +185 -0
- package/lib/model/TtscGraphMemory.js.map +1 -0
- package/lib/model/loadGraph.js +418 -0
- package/lib/model/loadGraph.js.map +1 -0
- package/lib/reduce.js +101 -0
- package/lib/reduce.js.map +1 -0
- package/lib/resolveGraphBinary.js +42 -0
- package/lib/resolveGraphBinary.js.map +1 -0
- package/lib/server/createServer.js +1227 -0
- package/lib/server/createServer.js.map +1 -0
- package/lib/server/instructions.js +32 -0
- package/lib/server/instructions.js.map +1 -0
- package/lib/server/resolveHandle.js +25 -0
- package/lib/server/resolveHandle.js.map +1 -0
- package/lib/server/runExpand.js +177 -0
- package/lib/server/runExpand.js.map +1 -0
- package/lib/server/runIndex.js +146 -0
- package/lib/server/runIndex.js.map +1 -0
- package/lib/server/runOverview.js +150 -0
- package/lib/server/runOverview.js.map +1 -0
- package/lib/server/runQuery.js +147 -0
- package/lib/server/runQuery.js.map +1 -0
- package/lib/server/runTrace.js +219 -0
- package/lib/server/runTrace.js.map +1 -0
- package/lib/server/startServer.js +21 -0
- package/lib/server/startServer.js.map +1 -0
- package/lib/structures/ITtscGraphApplication.js +3 -0
- package/lib/structures/ITtscGraphApplication.js.map +1 -0
- package/lib/structures/ITtscGraphDecorator.js +3 -0
- package/lib/structures/ITtscGraphDecorator.js.map +1 -0
- package/lib/structures/ITtscGraphDiagnostic.js +3 -0
- package/lib/structures/ITtscGraphDiagnostic.js.map +1 -0
- package/lib/structures/ITtscGraphDump.js +3 -0
- package/lib/structures/ITtscGraphDump.js.map +1 -0
- package/lib/structures/ITtscGraphEdge.js +3 -0
- package/lib/structures/ITtscGraphEdge.js.map +1 -0
- package/lib/structures/ITtscGraphEvidence.js +3 -0
- package/lib/structures/ITtscGraphEvidence.js.map +1 -0
- package/lib/structures/ITtscGraphExpand.js +3 -0
- package/lib/structures/ITtscGraphExpand.js.map +1 -0
- package/lib/structures/ITtscGraphIndex.js +3 -0
- package/lib/structures/ITtscGraphIndex.js.map +1 -0
- package/lib/structures/ITtscGraphNode.js +3 -0
- package/lib/structures/ITtscGraphNode.js.map +1 -0
- package/lib/structures/ITtscGraphOverview.js +3 -0
- package/lib/structures/ITtscGraphOverview.js.map +1 -0
- package/lib/structures/ITtscGraphQuery.js +3 -0
- package/lib/structures/ITtscGraphQuery.js.map +1 -0
- package/lib/structures/ITtscGraphTrace.js +3 -0
- package/lib/structures/ITtscGraphTrace.js.map +1 -0
- package/lib/structures/TtscGraphEdgeKind.js +3 -0
- package/lib/structures/TtscGraphEdgeKind.js.map +1 -0
- package/lib/structures/TtscGraphNodeKind.js +3 -0
- package/lib/structures/TtscGraphNodeKind.js.map +1 -0
- package/lib/structures/TtscGraphNodeModifier.js +3 -0
- package/lib/structures/TtscGraphNodeModifier.js.map +1 -0
- package/lib/structures/index.js +37 -0
- package/lib/structures/index.js.map +1 -0
- package/lib/view.js +140 -0
- package/lib/view.js.map +1 -0
- package/lib/viewer/index.html +123 -0
- package/lib/viewer/viewer.js +4610 -0
- package/package.json +17 -4
- package/src/TtscGraphApplication.ts +57 -0
- package/src/index.ts +40 -126
- package/src/model/TtscGraphMemory.ts +204 -0
- package/src/model/loadGraph.ts +85 -0
- package/src/reduce.ts +165 -0
- package/src/resolveGraphBinary.ts +40 -0
- package/src/server/createServer.ts +104 -0
- package/src/server/instructions.ts +28 -0
- package/src/server/resolveHandle.ts +34 -0
- package/src/server/runExpand.ts +186 -0
- package/src/server/runIndex.ts +181 -0
- package/src/server/runOverview.ts +154 -0
- package/src/server/runQuery.ts +150 -0
- package/src/server/runTrace.ts +233 -0
- package/src/server/startServer.ts +25 -0
- package/src/structures/ITtscGraphApplication.ts +68 -0
- package/src/structures/ITtscGraphDecorator.ts +33 -0
- package/src/structures/ITtscGraphDiagnostic.ts +34 -0
- package/src/structures/ITtscGraphDump.ts +35 -0
- package/src/structures/ITtscGraphEdge.ts +24 -0
- package/src/structures/ITtscGraphEvidence.ts +29 -0
- package/src/structures/ITtscGraphExpand.ts +85 -0
- package/src/structures/ITtscGraphIndex.ts +100 -0
- package/src/structures/ITtscGraphNode.ts +64 -0
- package/src/structures/ITtscGraphOverview.ts +79 -0
- package/src/structures/ITtscGraphQuery.ts +49 -0
- package/src/structures/ITtscGraphTrace.ts +97 -0
- package/src/structures/TtscGraphEdgeKind.ts +23 -0
- package/src/structures/TtscGraphNodeKind.ts +26 -0
- package/src/structures/TtscGraphNodeModifier.ts +19 -0
- package/src/structures/index.ts +21 -0
- package/src/view.ts +155 -0
- package/src/viewer/index.html +123 -0
- package/src/viewer/main.ts +209 -0
- package/lib/bin.d.ts +0 -2
- package/lib/diagnostics.d.ts +0 -23
- package/lib/diagnostics.js +0 -84
- package/lib/diagnostics.js.map +0 -1
- package/lib/index.d.ts +0 -29
- package/src/diagnostics.ts +0 -93
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runQuery = runQuery;
|
|
4
|
+
const runExpand_1 = require("./runExpand");
|
|
5
|
+
// One file should not crowd out the rest of the ranking, so cap hits per file.
|
|
6
|
+
const PER_FILE = 3;
|
|
7
|
+
const DEFAULT_LIMIT = 12;
|
|
8
|
+
/**
|
|
9
|
+
* Rank the graph's symbols against a natural query. Scoring blends exact and
|
|
10
|
+
* dotted-name matches, CamelCase/subword coverage, file-path terms, a prefix
|
|
11
|
+
* bonus, and dependency centrality, then dampens external, generated, and test
|
|
12
|
+
* nodes and caps per file so the result is a diverse, relevant shortlist rather
|
|
13
|
+
* than one file's roster.
|
|
14
|
+
*/
|
|
15
|
+
function runQuery(graph, props) {
|
|
16
|
+
const terms = subwords(props.query);
|
|
17
|
+
const queryLc = props.query.trim().toLowerCase();
|
|
18
|
+
if (terms.length === 0)
|
|
19
|
+
return { hits: [], next: { expand: [] } };
|
|
20
|
+
const scored = [];
|
|
21
|
+
for (const node of graph.nodes) {
|
|
22
|
+
if (node.kind === "file")
|
|
23
|
+
continue;
|
|
24
|
+
const score = scoreNode(graph, node, queryLc, terms);
|
|
25
|
+
if (score <= 0)
|
|
26
|
+
continue;
|
|
27
|
+
scored.push({
|
|
28
|
+
id: node.id,
|
|
29
|
+
name: node.qualifiedName ?? node.name,
|
|
30
|
+
kind: node.kind,
|
|
31
|
+
file: node.file,
|
|
32
|
+
line: node.evidence?.startLine,
|
|
33
|
+
score: Math.round(score),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
scored.sort((a, b) => b.score - a.score);
|
|
37
|
+
// Diversity: keep at most PER_FILE hits per file while filling up to the limit.
|
|
38
|
+
const limit = Math.max(1, props.limit ?? DEFAULT_LIMIT);
|
|
39
|
+
const perFile = new Map();
|
|
40
|
+
const hits = [];
|
|
41
|
+
for (const hit of scored) {
|
|
42
|
+
const used = perFile.get(hit.file) ?? 0;
|
|
43
|
+
if (used >= PER_FILE)
|
|
44
|
+
continue;
|
|
45
|
+
perFile.set(hit.file, used + 1);
|
|
46
|
+
hits.push(hit);
|
|
47
|
+
if (hits.length >= limit)
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
// Attach each kept hit's signature — only the shortlist, so the read cost is
|
|
51
|
+
// bounded — so the model can often answer from the query alone, no expand.
|
|
52
|
+
for (const hit of hits) {
|
|
53
|
+
const node = graph.node(hit.id);
|
|
54
|
+
if (node === undefined)
|
|
55
|
+
continue;
|
|
56
|
+
const sig = (0, runExpand_1.signatureOf)(graph.project, node);
|
|
57
|
+
if (sig !== undefined)
|
|
58
|
+
hit.signature = sig;
|
|
59
|
+
}
|
|
60
|
+
return { hits, next: { expand: hits.map((hit) => hit.id) } };
|
|
61
|
+
}
|
|
62
|
+
/** Score one node against the query; 0 means no match. */
|
|
63
|
+
function scoreNode(graph, node, queryLc, terms) {
|
|
64
|
+
const name = node.name.toLowerCase();
|
|
65
|
+
const qualified = (node.qualifiedName ?? node.name).toLowerCase();
|
|
66
|
+
const nameSubs = subwords(node.name);
|
|
67
|
+
const qualifiedSubs = subwords(node.qualifiedName ?? node.name);
|
|
68
|
+
const pathSubs = subwords(node.file);
|
|
69
|
+
let score = 0;
|
|
70
|
+
if (queryLc === name || queryLc === qualified) {
|
|
71
|
+
score += 100;
|
|
72
|
+
}
|
|
73
|
+
else if (qualified.includes(".") && queryLc.includes(qualified)) {
|
|
74
|
+
score += 85;
|
|
75
|
+
}
|
|
76
|
+
else if (queryLc.includes(".") && qualified.includes(queryLc)) {
|
|
77
|
+
score += 60;
|
|
78
|
+
}
|
|
79
|
+
let covered = 0;
|
|
80
|
+
for (const term of terms) {
|
|
81
|
+
if (nameSubs.includes(term)) {
|
|
82
|
+
score += 12;
|
|
83
|
+
covered++;
|
|
84
|
+
}
|
|
85
|
+
else if (qualifiedSubs.includes(term)) {
|
|
86
|
+
score += 8;
|
|
87
|
+
covered++;
|
|
88
|
+
}
|
|
89
|
+
else if (name.includes(term)) {
|
|
90
|
+
score += 5;
|
|
91
|
+
covered++;
|
|
92
|
+
}
|
|
93
|
+
else if (pathSubs.includes(term)) {
|
|
94
|
+
score += 3;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Every query term landed somewhere in the name: a strong whole-query match.
|
|
98
|
+
if (covered === terms.length)
|
|
99
|
+
score += 10;
|
|
100
|
+
if (name.startsWith(terms[0]))
|
|
101
|
+
score += 4;
|
|
102
|
+
if (score <= 0)
|
|
103
|
+
return 0;
|
|
104
|
+
// Centrality: a symbol the codebase leans on is a likelier target.
|
|
105
|
+
const fan = degree(graph, node.id);
|
|
106
|
+
score += Math.min(8, Math.log2(1 + fan) * 2);
|
|
107
|
+
// Dampen what is rarely the intended target.
|
|
108
|
+
if (node.external)
|
|
109
|
+
score *= 0.5;
|
|
110
|
+
if (node.ignored)
|
|
111
|
+
score *= 0.3;
|
|
112
|
+
if (isTestFile(node.file))
|
|
113
|
+
score *= 0.7;
|
|
114
|
+
return score;
|
|
115
|
+
}
|
|
116
|
+
/** Non-structural in+out degree (code dependency, not nesting). */
|
|
117
|
+
function degree(graph, id) {
|
|
118
|
+
let n = 0;
|
|
119
|
+
for (const edge of graph.outgoing(id))
|
|
120
|
+
if (!isStructural(edge.kind))
|
|
121
|
+
n++;
|
|
122
|
+
for (const edge of graph.incoming(id))
|
|
123
|
+
if (!isStructural(edge.kind))
|
|
124
|
+
n++;
|
|
125
|
+
return n;
|
|
126
|
+
}
|
|
127
|
+
function isStructural(kind) {
|
|
128
|
+
return kind === "contains" || kind === "exports" || kind === "imports";
|
|
129
|
+
}
|
|
130
|
+
function isTestFile(file) {
|
|
131
|
+
return (/(^|\/)(test|tests|__tests__|spec)\//.test(file) ||
|
|
132
|
+
/\.(test|spec)\.[cm]?tsx?$/.test(file));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Split an identifier or phrase into lowercase subword tokens: CamelCase,
|
|
136
|
+
* snake, dotted, and space boundaries all break, so `getHTTPResponse`,
|
|
137
|
+
* `find_by_id`, and `OrderService.create` tokenize the way a query would.
|
|
138
|
+
*/
|
|
139
|
+
function subwords(text) {
|
|
140
|
+
return text
|
|
141
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
142
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2")
|
|
143
|
+
.split(/[^a-zA-Z0-9]+/)
|
|
144
|
+
.filter((w) => w.length > 0)
|
|
145
|
+
.map((w) => w.toLowerCase());
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=runQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runQuery.js","sourceRoot":"","sources":["../../src/server/runQuery.ts"],"names":[],"mappings":";;;AAGA,2CAA0C;AAE1C,+EAA+E;AAC/E,MAAM,QAAQ,GAAG,CAAC,CAAC;AACnB,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB;;;;;;GAMG;AACH,kBACE,KAAsB,EACtB,KAA6B;IAE7B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;IAElE,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QACnC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACrD,IAAI,KAAK,IAAI,CAAC;YAAE,SAAS;QACzB,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI;YACrC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS;YAC9B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;SACzB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAEzC,gFAAgF;IAChF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,IAAI,IAAI,QAAQ;YAAE,SAAS;QAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK;YAAE,MAAM;IAClC,CAAC;IAED,6EAA6E;IAC7E,2EAA2E;IAC3E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACjC,MAAM,GAAG,GAAG,IAAA,uBAAW,EAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7C,IAAI,GAAG,KAAK,SAAS;YAAE,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;AAC/D,CAAC;AAED,0DAA0D;AAC1D,SAAS,SAAS,CAChB,KAAsB,EACtB,IAAoB,EACpB,OAAe,EACf,KAAe;IAEf,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAClE,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC9C,KAAK,IAAI,GAAG,CAAC;IACf,CAAC;SAAM,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAClE,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAChE,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,KAAK,IAAI,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,6EAA6E;IAC7E,IAAI,OAAO,KAAK,KAAK,CAAC,MAAM;QAAE,KAAK,IAAI,EAAE,CAAC;IAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IAE3C,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAEzB,mEAAmE;IACnE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAE7C,6CAA6C;IAC7C,IAAI,IAAI,CAAC,QAAQ;QAAE,KAAK,IAAI,GAAG,CAAC;IAChC,IAAI,IAAI,CAAC,OAAO;QAAE,KAAK,IAAI,GAAG,CAAC;IAC/B,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,KAAK,IAAI,GAAG,CAAC;IACxC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mEAAmE;AACnE,SAAS,MAAM,CAAC,KAAsB,EAAE,EAAU;IAChD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,CAAC,EAAE,CAAC;IACzE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,CAAC,EAAE,CAAC;IACzE,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,CAAC;AACzE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,CACL,qCAAqC,CAAC,IAAI,CAAC,IAAI,CAAC;QAChD,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CACvC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI;SACR,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC;SACzC,KAAK,CAAC,eAAe,CAAC;SACtB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runTrace = runTrace;
|
|
4
|
+
const resolveHandle_1 = require("./resolveHandle");
|
|
5
|
+
const runExpand_1 = require("./runExpand");
|
|
6
|
+
const DEFAULT_DEPTH = 6;
|
|
7
|
+
const DEFAULT_MAX_NODES = 60;
|
|
8
|
+
/**
|
|
9
|
+
* Breadth-first trace along the dependency graph. Structural
|
|
10
|
+
* (contains/exports/imports) edges are excluded so the path is real call/type
|
|
11
|
+
* flow; forward walks callees, reverse and impact walk callers. Impact
|
|
12
|
+
* additionally tags each reached node's role so the blast radius on the public
|
|
13
|
+
* surface is legible.
|
|
14
|
+
*/
|
|
15
|
+
function runTrace(graph, props) {
|
|
16
|
+
const direction = props.direction ?? "forward";
|
|
17
|
+
const maxDepth = Math.max(1, props.maxDepth ?? DEFAULT_DEPTH);
|
|
18
|
+
const maxNodes = Math.max(1, props.maxNodes ?? DEFAULT_MAX_NODES);
|
|
19
|
+
const reverse = direction === "reverse" || direction === "impact";
|
|
20
|
+
// Only an impact trace tags reached nodes with their public-surface role; for
|
|
21
|
+
// forward/reverse the role is noise.
|
|
22
|
+
const withRoles = direction === "impact";
|
|
23
|
+
const start = (0, resolveHandle_1.resolveGraphHandle)(graph, props.from);
|
|
24
|
+
if (start.candidates) {
|
|
25
|
+
return {
|
|
26
|
+
direction,
|
|
27
|
+
hops: [],
|
|
28
|
+
reached: [],
|
|
29
|
+
truncated: false,
|
|
30
|
+
candidates: start.candidates.map((n) => summary(n)),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (start.node === undefined) {
|
|
34
|
+
return { direction, hops: [], reached: [], truncated: false };
|
|
35
|
+
}
|
|
36
|
+
// Path mode: with `to`, return the dependency path from `from` to `to` — the
|
|
37
|
+
// one-call answer for "how does A reach B" — instead of an open-ended trace.
|
|
38
|
+
if (props.to !== undefined && props.to !== "") {
|
|
39
|
+
const base = { direction: "path", hops: [], reached: [], truncated: false };
|
|
40
|
+
const target = (0, resolveHandle_1.resolveGraphHandle)(graph, props.to);
|
|
41
|
+
if (target.candidates) {
|
|
42
|
+
return {
|
|
43
|
+
...base,
|
|
44
|
+
start: summary(start.node),
|
|
45
|
+
candidates: target.candidates.map((n) => summary(n)),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (target.node === undefined) {
|
|
49
|
+
return { ...base, start: summary(start.node) };
|
|
50
|
+
}
|
|
51
|
+
const found = findPath(graph, start.node.id, target.node.id, Math.max(1, props.maxDepth ?? 12));
|
|
52
|
+
return {
|
|
53
|
+
...base,
|
|
54
|
+
start: summary(start.node),
|
|
55
|
+
target: summary(target.node),
|
|
56
|
+
hops: found?.hops ?? [],
|
|
57
|
+
path: (found?.path ?? []).map((node, i) => {
|
|
58
|
+
const node_ = summary(node, i);
|
|
59
|
+
const sig = (0, runExpand_1.signatureOf)(graph.project, node);
|
|
60
|
+
if (sig !== undefined)
|
|
61
|
+
node_.signature = sig;
|
|
62
|
+
return node_;
|
|
63
|
+
}),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const hops = [];
|
|
67
|
+
const reached = new Map();
|
|
68
|
+
const visited = new Set([start.node.id]);
|
|
69
|
+
let queue = [
|
|
70
|
+
{ id: start.node.id, depth: 0 },
|
|
71
|
+
];
|
|
72
|
+
let truncated = false;
|
|
73
|
+
while (queue.length > 0) {
|
|
74
|
+
const next = [];
|
|
75
|
+
for (const { id, depth } of queue) {
|
|
76
|
+
if (depth >= maxDepth) {
|
|
77
|
+
truncated = true;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const edges = reverse ? graph.incoming(id) : graph.outgoing(id);
|
|
81
|
+
for (const edge of edges) {
|
|
82
|
+
if (!traversable(edge.kind))
|
|
83
|
+
continue;
|
|
84
|
+
const otherId = reverse ? edge.from : edge.to;
|
|
85
|
+
const other = graph.node(otherId);
|
|
86
|
+
if (other === undefined || other.kind === "file")
|
|
87
|
+
continue;
|
|
88
|
+
const hop = {
|
|
89
|
+
from: edge.from,
|
|
90
|
+
to: edge.to,
|
|
91
|
+
kind: edge.kind,
|
|
92
|
+
depth: depth + 1,
|
|
93
|
+
};
|
|
94
|
+
// A back-edge to the start or an already-reached node: record the hop;
|
|
95
|
+
// its endpoints are already represented.
|
|
96
|
+
if (visited.has(otherId)) {
|
|
97
|
+
hops.push(hop);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
// A new node past the cap is left unrepresented, so drop its hop too —
|
|
101
|
+
// every hop's endpoints stay resolvable in `reached`/`start`.
|
|
102
|
+
if (reached.size >= maxNodes) {
|
|
103
|
+
truncated = true;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
visited.add(otherId);
|
|
107
|
+
reached.set(otherId, summary(other, depth + 1, withRoles));
|
|
108
|
+
next.push({ id: otherId, depth: depth + 1 });
|
|
109
|
+
hops.push(hop);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
queue = next;
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
start: summary(start.node),
|
|
116
|
+
direction,
|
|
117
|
+
hops,
|
|
118
|
+
reached: [...reached.values()],
|
|
119
|
+
truncated,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The shortest dependency path from `startId` to `targetId` over real (non-
|
|
124
|
+
* structural) forward edges, breadth-first, or null when `targetId` is not
|
|
125
|
+
* reachable within maxDepth. Returns the nodes in order and the hops between.
|
|
126
|
+
*/
|
|
127
|
+
function findPath(graph, startId, targetId, maxDepth) {
|
|
128
|
+
const startNode = graph.node(startId);
|
|
129
|
+
if (startNode === undefined)
|
|
130
|
+
return null;
|
|
131
|
+
if (startId === targetId)
|
|
132
|
+
return { path: [startNode], hops: [] };
|
|
133
|
+
const parent = new Map();
|
|
134
|
+
const visited = new Set([startId]);
|
|
135
|
+
let queue = [{ id: startId, depth: 0 }];
|
|
136
|
+
while (queue.length > 0) {
|
|
137
|
+
const next = [];
|
|
138
|
+
for (const { id, depth } of queue) {
|
|
139
|
+
if (depth >= maxDepth)
|
|
140
|
+
continue;
|
|
141
|
+
for (const edge of graph.outgoing(id)) {
|
|
142
|
+
if (!traversable(edge.kind))
|
|
143
|
+
continue;
|
|
144
|
+
const otherId = edge.to;
|
|
145
|
+
if (visited.has(otherId))
|
|
146
|
+
continue;
|
|
147
|
+
const other = graph.node(otherId);
|
|
148
|
+
if (other === undefined || other.kind === "file")
|
|
149
|
+
continue;
|
|
150
|
+
visited.add(otherId);
|
|
151
|
+
parent.set(otherId, { via: id, kind: edge.kind });
|
|
152
|
+
if (otherId === targetId) {
|
|
153
|
+
const ids = [otherId];
|
|
154
|
+
let cur = otherId;
|
|
155
|
+
while (cur !== startId) {
|
|
156
|
+
const p = parent.get(cur);
|
|
157
|
+
if (p === undefined)
|
|
158
|
+
break;
|
|
159
|
+
ids.unshift(p.via);
|
|
160
|
+
cur = p.via;
|
|
161
|
+
}
|
|
162
|
+
const path = [];
|
|
163
|
+
for (const nid of ids) {
|
|
164
|
+
const n = graph.node(nid);
|
|
165
|
+
if (n !== undefined)
|
|
166
|
+
path.push(n);
|
|
167
|
+
}
|
|
168
|
+
const hops = [];
|
|
169
|
+
for (let i = 1; i < path.length; i++) {
|
|
170
|
+
const node = path[i];
|
|
171
|
+
hops.push({
|
|
172
|
+
from: path[i - 1].id,
|
|
173
|
+
to: node.id,
|
|
174
|
+
kind: parent.get(node.id)?.kind ?? "calls",
|
|
175
|
+
depth: i,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return { path, hops };
|
|
179
|
+
}
|
|
180
|
+
next.push({ id: otherId, depth: depth + 1 });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
queue = next;
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Summarize a node for a trace result. With `withRoles`, tag the public-surface
|
|
189
|
+
* roles (exported / test) an impact trace reports; other directions omit them.
|
|
190
|
+
*/
|
|
191
|
+
function summary(node, depth, withRoles = false) {
|
|
192
|
+
const out = {
|
|
193
|
+
id: node.id,
|
|
194
|
+
name: node.qualifiedName ?? node.name,
|
|
195
|
+
kind: node.kind,
|
|
196
|
+
file: node.file,
|
|
197
|
+
};
|
|
198
|
+
if (depth !== undefined)
|
|
199
|
+
out.depth = depth;
|
|
200
|
+
if (withRoles) {
|
|
201
|
+
const roles = [];
|
|
202
|
+
if (node.exported)
|
|
203
|
+
roles.push("exported");
|
|
204
|
+
if (isTestFile(node.file))
|
|
205
|
+
roles.push("test");
|
|
206
|
+
if (roles.length > 0)
|
|
207
|
+
out.roles = roles;
|
|
208
|
+
}
|
|
209
|
+
return out;
|
|
210
|
+
}
|
|
211
|
+
/** An edge the trace should follow: a real dependency, not a structural edge. */
|
|
212
|
+
function traversable(kind) {
|
|
213
|
+
return kind !== "contains" && kind !== "exports" && kind !== "imports";
|
|
214
|
+
}
|
|
215
|
+
function isTestFile(file) {
|
|
216
|
+
return (/(^|\/)(test|tests|__tests__|spec)\//.test(file) ||
|
|
217
|
+
/\.(test|spec)\.[cm]?tsx?$/.test(file));
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=runTrace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runTrace.js","sourceRoot":"","sources":["../../src/server/runTrace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startServer = startServer;
|
|
4
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5
|
+
const loadGraph_1 = require("../model/loadGraph");
|
|
6
|
+
const createServer_1 = require("./createServer");
|
|
7
|
+
/**
|
|
8
|
+
* Serve the graph tools over MCP on stdio. The server answers the MCP handshake
|
|
9
|
+
* immediately and builds the resident graph on the first tool call, so a large
|
|
10
|
+
* project cannot make the client give up before tools are advertised.
|
|
11
|
+
*/
|
|
12
|
+
async function startServer(options) {
|
|
13
|
+
let graph;
|
|
14
|
+
const server = (0, createServer_1.createServer)(() => {
|
|
15
|
+
graph ??= (0, loadGraph_1.loadGraph)({ cwd: options.cwd, tsconfig: options.tsconfig });
|
|
16
|
+
return graph;
|
|
17
|
+
}, options.version);
|
|
18
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
19
|
+
await server.connect(transport);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=startServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startServer.js","sourceRoot":"","sources":["../../src/server/startServer.ts"],"names":[],"mappings":";;;AAAA,wEAAiF;AAGjF,kDAA+C;AAC/C,iDAA8C;AAE9C;;;;GAIG;AACI,KAAK,sBAAsB,OAKjC;IACC,IAAI,KAAkC,CAAC;IACvC,MAAM,MAAM,GAAG,IAAA,2BAAY,EAAC,GAAG,EAAE;QAC/B,KAAK,KAAK,IAAA,qBAAS,EAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtE,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphApplication.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphApplication.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphDecorator.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphDecorator.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphDiagnostic.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphDiagnostic.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphDump.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphDump.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphEdge.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphEdge.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphEvidence.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphEvidence.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphExpand.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphExpand.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphIndex.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphIndex.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphNode.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphNode.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphOverview.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphOverview.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphQuery.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphQuery.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITtscGraphTrace.js","sourceRoot":"","sources":["../../src/structures/ITtscGraphTrace.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TtscGraphEdgeKind.js","sourceRoot":"","sources":["../../src/structures/TtscGraphEdgeKind.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TtscGraphNodeKind.js","sourceRoot":"","sources":["../../src/structures/TtscGraphNodeKind.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TtscGraphNodeModifier.js","sourceRoot":"","sources":["../../src/structures/TtscGraphNodeModifier.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The canonical graph data model and tool I/O types: the wire contract
|
|
3
|
+
// `ttscgraph dump` emits and the MCP server loads, plus the schemas typia
|
|
4
|
+
// derives the tool surface from. Pure types so typia can build validators and
|
|
5
|
+
// tool schemas at build time, and so the Go `dump.go` writer has one TypeScript
|
|
6
|
+
// source of truth to mirror.
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
__exportStar(require("./ITtscGraphApplication"), exports);
|
|
23
|
+
__exportStar(require("./ITtscGraphDecorator"), exports);
|
|
24
|
+
__exportStar(require("./ITtscGraphDiagnostic"), exports);
|
|
25
|
+
__exportStar(require("./ITtscGraphDump"), exports);
|
|
26
|
+
__exportStar(require("./ITtscGraphEdge"), exports);
|
|
27
|
+
__exportStar(require("./ITtscGraphEvidence"), exports);
|
|
28
|
+
__exportStar(require("./ITtscGraphExpand"), exports);
|
|
29
|
+
__exportStar(require("./ITtscGraphIndex"), exports);
|
|
30
|
+
__exportStar(require("./ITtscGraphNode"), exports);
|
|
31
|
+
__exportStar(require("./ITtscGraphOverview"), exports);
|
|
32
|
+
__exportStar(require("./ITtscGraphQuery"), exports);
|
|
33
|
+
__exportStar(require("./ITtscGraphTrace"), exports);
|
|
34
|
+
__exportStar(require("./TtscGraphEdgeKind"), exports);
|
|
35
|
+
__exportStar(require("./TtscGraphNodeKind"), exports);
|
|
36
|
+
__exportStar(require("./TtscGraphNodeModifier"), exports);
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/structures/index.ts"],"names":[],"mappings":";AAAA,uEAAuE;AACvE,0EAA0E;AAC1E,8EAA8E;AAC9E,gFAAgF;AAChF,6BAA6B;;;;;;;;;;;;;;;;AAE7B,0DAAwC;AACxC,wDAAsC;AACtC,yDAAuC;AACvC,mDAAiC;AACjC,mDAAiC;AACjC,uDAAqC;AACrC,qDAAmC;AACnC,oDAAkC;AAClC,mDAAiC;AACjC,uDAAqC;AACrC,oDAAkC;AAClC,oDAAkC;AAClC,sDAAoC;AACpC,sDAAoC;AACpC,0DAAwC"}
|