@ttsc/graph 0.18.3 → 0.18.4

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.
@@ -0,0 +1,503 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.TtscGraphSession = void 0;
40
+ const _a = __importStar(require("typia/lib/internal/_assertGuard"));
41
+ const node_child_process_1 = require("node:child_process");
42
+ const node_readline_1 = __importDefault(require("node:readline"));
43
+ const typia_1 = __importDefault(require("typia"));
44
+ const nativeExecutable_1 = require("../nativeExecutable");
45
+ const resolveGraphBinary_1 = require("../resolveGraphBinary");
46
+ const TtscGraphMemory_1 = require("./TtscGraphMemory");
47
+ /**
48
+ * Resident bridge to `ttscgraph serve`.
49
+ *
50
+ * Every graph request first asks the native session for the current disk
51
+ * snapshot. Unchanged requests reuse the existing {@link TtscGraphMemory}; an
52
+ * edited source reuses tsgo's resident Program through `driver.Session`, while
53
+ * config and root-file-set changes force a safe full reload.
54
+ */
55
+ class TtscGraphSession {
56
+ cwd;
57
+ tsconfig;
58
+ binary;
59
+ child;
60
+ stderr = "";
61
+ nextId = 0;
62
+ pending = new Map();
63
+ queue = Promise.resolve();
64
+ current;
65
+ closed = false;
66
+ constructor(options) {
67
+ const binary = options.binary ?? (0, resolveGraphBinary_1.resolveGraphBinary)();
68
+ if (binary === null) {
69
+ throw new Error("@ttsc/graph: could not resolve the ttscgraph binary. " +
70
+ "Install `ttsc` so its platform package is present, " +
71
+ "or set TTSC_GRAPH_BINARY to an absolute path.");
72
+ }
73
+ (0, nativeExecutable_1.ensureExecutable)(binary);
74
+ this.cwd = options.cwd;
75
+ this.tsconfig = options.tsconfig;
76
+ this.binary = binary;
77
+ }
78
+ /** Return a graph for the current disk snapshot, serialized per tool call. */
79
+ graph() {
80
+ let resolve;
81
+ let reject;
82
+ const result = new Promise((res, rej) => {
83
+ resolve = res;
84
+ reject = rej;
85
+ });
86
+ this.queue = this.queue
87
+ .catch(() => undefined)
88
+ .then(async () => {
89
+ try {
90
+ resolve(await this.refresh());
91
+ }
92
+ catch (error) {
93
+ reject(asError(error));
94
+ }
95
+ });
96
+ return result;
97
+ }
98
+ /** Close the native session. Safe to call more than once. */
99
+ close() {
100
+ this.closed = true;
101
+ const child = this.child;
102
+ this.child = undefined;
103
+ if (child !== undefined && !child.killed)
104
+ child.stdin.end();
105
+ this.failPending(new Error("@ttsc/graph: native session closed"));
106
+ }
107
+ async refresh() {
108
+ const response = await this.request();
109
+ if (response.error !== undefined) {
110
+ throw new Error(`@ttsc/graph: ${response.error}`);
111
+ }
112
+ if (response.changed) {
113
+ if (response.dump === undefined) {
114
+ throw new Error(`@ttsc/graph: native ${response.mode ?? "changed"} response omitted its dump`);
115
+ }
116
+ const dump = (() => {
117
+ const _iv0 = new Set(["class", "enum", "external_symbol", "file", "function", "interface", "method", "module", "namespace", "package", "parameter", "property", "type", "variable"]);
118
+ const _ip0 = input => "string" === typeof input["name"];
119
+ const _ip1 = input => "string" === typeof input["file"];
120
+ const _iv1 = new Set(["abstract", "async", "const", "declare", "default", "export", "optional", "private", "protected", "public", "readonly", "static"]);
121
+ const _ip2 = input => undefined === input["evidence"] || "object" === typeof input["evidence"] && null !== input["evidence"] && _io4(input["evidence"]);
122
+ const _iv2 = new Set(["accesses", "calls", "contains", "decorates", "exports", "extends", "implements", "imports", "instantiates", "overrides", "renders", "tests", "type_ref"]);
123
+ const _av0 = new Set(["class", "enum", "external_symbol", "file", "function", "interface", "method", "module", "namespace", "package", "parameter", "property", "type", "variable"]);
124
+ const _ae0 = "(\"class\" | \"enum\" | \"external_symbol\" | \"file\" | \"function\" | \"interface\" | \"method\" | \"module\" | \"namespace\" | \"package\" | \"parameter\" | \"property\" | \"type\" | \"variable\")";
125
+ const _ap0 = (input, _path, _exceptionable = true) => "string" === typeof input["name"] || _a._assertGuard(_exceptionable, {
126
+ method: "typia.assert",
127
+ path: _path + ".name",
128
+ expected: "string",
129
+ value: input["name"]
130
+ }, _errorFactory);
131
+ const _ap1 = (input, _path, _exceptionable = true) => "string" === typeof input["file"] || _a._assertGuard(_exceptionable, {
132
+ method: "typia.assert",
133
+ path: _path + ".file",
134
+ expected: "string",
135
+ value: input["file"]
136
+ }, _errorFactory);
137
+ const _av1 = new Set(["abstract", "async", "const", "declare", "default", "export", "optional", "private", "protected", "public", "readonly", "static"]);
138
+ const _ae1 = "(\"abstract\" | \"async\" | \"const\" | \"declare\" | \"default\" | \"export\" | \"optional\" | \"private\" | \"protected\" | \"public\" | \"readonly\" | \"static\")";
139
+ const _ap2 = (input, _path, _exceptionable = true) => undefined === input["evidence"] || ("object" === typeof input["evidence"] && null !== input["evidence"] || _a._assertGuard(_exceptionable, {
140
+ method: "typia.assert",
141
+ path: _path + ".evidence",
142
+ expected: "(ITtscGraphEvidence | undefined)",
143
+ value: input["evidence"]
144
+ }, _errorFactory)) && _ao4(input["evidence"], _path + ".evidence", true && _exceptionable) || _a._assertGuard(_exceptionable, {
145
+ method: "typia.assert",
146
+ path: _path + ".evidence",
147
+ expected: "(ITtscGraphEvidence | undefined)",
148
+ value: input["evidence"]
149
+ }, _errorFactory);
150
+ const _av2 = new Set(["accesses", "calls", "contains", "decorates", "exports", "extends", "implements", "imports", "instantiates", "overrides", "renders", "tests", "type_ref"]);
151
+ const _ae2 = "(\"accesses\" | \"calls\" | \"contains\" | \"decorates\" | \"exports\" | \"extends\" | \"implements\" | \"imports\" | \"instantiates\" | \"overrides\" | \"renders\" | \"tests\" | \"type_ref\")";
152
+ const _ao0 = (input, _path, _exceptionable = true) => ("string" === typeof input.project || _a._assertGuard(_exceptionable, {
153
+ method: "typia.assert",
154
+ path: _path + ".project",
155
+ expected: "string",
156
+ value: input.project
157
+ }, _errorFactory)) && ("string" === typeof input.tsconfig || _a._assertGuard(_exceptionable, {
158
+ method: "typia.assert",
159
+ path: _path + ".tsconfig",
160
+ expected: "string",
161
+ value: input.tsconfig
162
+ }, _errorFactory)) && ((Array.isArray(input.nodes) || _a._assertGuard(_exceptionable, {
163
+ method: "typia.assert",
164
+ path: _path + ".nodes",
165
+ expected: "Array<ITtscGraphNode>",
166
+ value: input.nodes
167
+ }, _errorFactory)) && input.nodes.every((elem, _index7) => ("object" === typeof elem && null !== elem || _a._assertGuard(_exceptionable, {
168
+ method: "typia.assert",
169
+ path: _path + ".nodes[" + _index7 + "]",
170
+ expected: "ITtscGraphNode",
171
+ value: elem
172
+ }, _errorFactory)) && _ao1(elem, _path + ".nodes[" + _index7 + "]", true && _exceptionable) || _a._assertGuard(_exceptionable, {
173
+ method: "typia.assert",
174
+ path: _path + ".nodes[" + _index7 + "]",
175
+ expected: "ITtscGraphNode",
176
+ value: elem
177
+ }, _errorFactory)) || _a._assertGuard(_exceptionable, {
178
+ method: "typia.assert",
179
+ path: _path + ".nodes",
180
+ expected: "Array<ITtscGraphNode>",
181
+ value: input.nodes
182
+ }, _errorFactory)) && ((Array.isArray(input.edges) || _a._assertGuard(_exceptionable, {
183
+ method: "typia.assert",
184
+ path: _path + ".edges",
185
+ expected: "Array<ITtscGraphEdge>",
186
+ value: input.edges
187
+ }, _errorFactory)) && input.edges.every((elem, _index8) => ("object" === typeof elem && null !== elem || _a._assertGuard(_exceptionable, {
188
+ method: "typia.assert",
189
+ path: _path + ".edges[" + _index8 + "]",
190
+ expected: "ITtscGraphEdge",
191
+ value: elem
192
+ }, _errorFactory)) && _ao5(elem, _path + ".edges[" + _index8 + "]", true && _exceptionable) || _a._assertGuard(_exceptionable, {
193
+ method: "typia.assert",
194
+ path: _path + ".edges[" + _index8 + "]",
195
+ expected: "ITtscGraphEdge",
196
+ value: elem
197
+ }, _errorFactory)) || _a._assertGuard(_exceptionable, {
198
+ method: "typia.assert",
199
+ path: _path + ".edges",
200
+ expected: "Array<ITtscGraphEdge>",
201
+ value: input.edges
202
+ }, _errorFactory)) && (undefined === input.diagnostics || (Array.isArray(input.diagnostics) || _a._assertGuard(_exceptionable, {
203
+ method: "typia.assert",
204
+ path: _path + ".diagnostics",
205
+ expected: "(Array<ITtscGraphDiagnostic> | undefined)",
206
+ value: input.diagnostics
207
+ }, _errorFactory)) && input.diagnostics.every((elem, _index9) => ("object" === typeof elem && null !== elem || _a._assertGuard(_exceptionable, {
208
+ method: "typia.assert",
209
+ path: _path + ".diagnostics[" + _index9 + "]",
210
+ expected: "ITtscGraphDiagnostic",
211
+ value: elem
212
+ }, _errorFactory)) && _ao6(elem, _path + ".diagnostics[" + _index9 + "]", true && _exceptionable) || _a._assertGuard(_exceptionable, {
213
+ method: "typia.assert",
214
+ path: _path + ".diagnostics[" + _index9 + "]",
215
+ expected: "ITtscGraphDiagnostic",
216
+ value: elem
217
+ }, _errorFactory)) || _a._assertGuard(_exceptionable, {
218
+ method: "typia.assert",
219
+ path: _path + ".diagnostics",
220
+ expected: "(Array<ITtscGraphDiagnostic> | undefined)",
221
+ value: input.diagnostics
222
+ }, _errorFactory));
223
+ const _ao1 = (input, _path, _exceptionable = true) => ("string" === typeof input.id || _a._assertGuard(_exceptionable, {
224
+ method: "typia.assert",
225
+ path: _path + ".id",
226
+ expected: "string",
227
+ value: input.id
228
+ }, _errorFactory)) && (true === _av0.has(input.kind) || _a._assertGuard(_exceptionable, {
229
+ method: "typia.assert",
230
+ path: _path + ".kind",
231
+ expected: _ae0,
232
+ value: input.kind
233
+ }, _errorFactory)) && _ap0(input, _path, true && _exceptionable) && (undefined === input.qualifiedName || "string" === typeof input.qualifiedName || _a._assertGuard(_exceptionable, {
234
+ method: "typia.assert",
235
+ path: _path + ".qualifiedName",
236
+ expected: "(string | undefined)",
237
+ value: input.qualifiedName
238
+ }, _errorFactory)) && _ap1(input, _path, true && _exceptionable) && ("boolean" === typeof input.external || _a._assertGuard(_exceptionable, {
239
+ method: "typia.assert",
240
+ path: _path + ".external",
241
+ expected: "boolean",
242
+ value: input.external
243
+ }, _errorFactory)) && (undefined === input.ignored || "boolean" === typeof input.ignored || _a._assertGuard(_exceptionable, {
244
+ method: "typia.assert",
245
+ path: _path + ".ignored",
246
+ expected: "(boolean | undefined)",
247
+ value: input.ignored
248
+ }, _errorFactory)) && (undefined === input.exported || "boolean" === typeof input.exported || _a._assertGuard(_exceptionable, {
249
+ method: "typia.assert",
250
+ path: _path + ".exported",
251
+ expected: "(boolean | undefined)",
252
+ value: input.exported
253
+ }, _errorFactory)) && (undefined === input.modifiers || (Array.isArray(input.modifiers) || _a._assertGuard(_exceptionable, {
254
+ method: "typia.assert",
255
+ path: _path + ".modifiers",
256
+ expected: "(Array<TtscGraphNodeModifier> | undefined)",
257
+ value: input.modifiers
258
+ }, _errorFactory)) && input.modifiers.every((elem, _index10) => true === _av1.has(elem) || _a._assertGuard(_exceptionable, {
259
+ method: "typia.assert",
260
+ path: _path + ".modifiers[" + _index10 + "]",
261
+ expected: _ae1,
262
+ value: elem
263
+ }, _errorFactory)) || _a._assertGuard(_exceptionable, {
264
+ method: "typia.assert",
265
+ path: _path + ".modifiers",
266
+ expected: "(Array<TtscGraphNodeModifier> | undefined)",
267
+ value: input.modifiers
268
+ }, _errorFactory)) && (undefined === input.decorators || (Array.isArray(input.decorators) || _a._assertGuard(_exceptionable, {
269
+ method: "typia.assert",
270
+ path: _path + ".decorators",
271
+ expected: "(Array<ITtscGraphDecorator> | undefined)",
272
+ value: input.decorators
273
+ }, _errorFactory)) && input.decorators.every((elem, _index11) => ("object" === typeof elem && null !== elem || _a._assertGuard(_exceptionable, {
274
+ method: "typia.assert",
275
+ path: _path + ".decorators[" + _index11 + "]",
276
+ expected: "ITtscGraphDecorator",
277
+ value: elem
278
+ }, _errorFactory)) && _ao2(elem, _path + ".decorators[" + _index11 + "]", true && _exceptionable) || _a._assertGuard(_exceptionable, {
279
+ method: "typia.assert",
280
+ path: _path + ".decorators[" + _index11 + "]",
281
+ expected: "ITtscGraphDecorator",
282
+ value: elem
283
+ }, _errorFactory)) || _a._assertGuard(_exceptionable, {
284
+ method: "typia.assert",
285
+ path: _path + ".decorators",
286
+ expected: "(Array<ITtscGraphDecorator> | undefined)",
287
+ value: input.decorators
288
+ }, _errorFactory)) && _ap2(input, _path, true && _exceptionable) && (undefined === input.implementation || ("object" === typeof input.implementation && null !== input.implementation || _a._assertGuard(_exceptionable, {
289
+ method: "typia.assert",
290
+ path: _path + ".implementation",
291
+ expected: "(ITtscGraphEvidence | undefined)",
292
+ value: input.implementation
293
+ }, _errorFactory)) && _ao4(input.implementation, _path + ".implementation", true && _exceptionable) || _a._assertGuard(_exceptionable, {
294
+ method: "typia.assert",
295
+ path: _path + ".implementation",
296
+ expected: "(ITtscGraphEvidence | undefined)",
297
+ value: input.implementation
298
+ }, _errorFactory));
299
+ const _ao2 = (input, _path, _exceptionable = true) => _ap0(input, _path, true && _exceptionable) && ((Array.isArray(input.arguments) || _a._assertGuard(_exceptionable, {
300
+ method: "typia.assert",
301
+ path: _path + ".arguments",
302
+ expected: "Array<ITtscGraphDecorator.IArgument>",
303
+ value: input.arguments
304
+ }, _errorFactory)) && input.arguments.every((elem, _index12) => ("object" === typeof elem && null !== elem && false === Array.isArray(elem) || _a._assertGuard(_exceptionable, {
305
+ method: "typia.assert",
306
+ path: _path + ".arguments[" + _index12 + "]",
307
+ expected: "ITtscGraphDecorator.IArgument",
308
+ value: elem
309
+ }, _errorFactory)) && _ao3(elem, _path + ".arguments[" + _index12 + "]", true && _exceptionable) || _a._assertGuard(_exceptionable, {
310
+ method: "typia.assert",
311
+ path: _path + ".arguments[" + _index12 + "]",
312
+ expected: "ITtscGraphDecorator.IArgument",
313
+ value: elem
314
+ }, _errorFactory)) || _a._assertGuard(_exceptionable, {
315
+ method: "typia.assert",
316
+ path: _path + ".arguments",
317
+ expected: "Array<ITtscGraphDecorator.IArgument>",
318
+ value: input.arguments
319
+ }, _errorFactory));
320
+ const _ao3 = (input, _path, _exceptionable = true) => undefined === input.literal || "string" === typeof input.literal || "number" === typeof input.literal || "boolean" === typeof input.literal || _a._assertGuard(_exceptionable, {
321
+ method: "typia.assert",
322
+ path: _path + ".literal",
323
+ expected: "(boolean | number | string | undefined)",
324
+ value: input.literal
325
+ }, _errorFactory);
326
+ const _ao4 = (input, _path, _exceptionable = true) => _ap1(input, _path, true && _exceptionable) && ("number" === typeof input.startLine || _a._assertGuard(_exceptionable, {
327
+ method: "typia.assert",
328
+ path: _path + ".startLine",
329
+ expected: "number",
330
+ value: input.startLine
331
+ }, _errorFactory)) && (undefined === input.startCol || "number" === typeof input.startCol || _a._assertGuard(_exceptionable, {
332
+ method: "typia.assert",
333
+ path: _path + ".startCol",
334
+ expected: "(number | undefined)",
335
+ value: input.startCol
336
+ }, _errorFactory)) && (undefined === input.endLine || "number" === typeof input.endLine || _a._assertGuard(_exceptionable, {
337
+ method: "typia.assert",
338
+ path: _path + ".endLine",
339
+ expected: "(number | undefined)",
340
+ value: input.endLine
341
+ }, _errorFactory)) && (undefined === input.endCol || "number" === typeof input.endCol || _a._assertGuard(_exceptionable, {
342
+ method: "typia.assert",
343
+ path: _path + ".endCol",
344
+ expected: "(number | undefined)",
345
+ value: input.endCol
346
+ }, _errorFactory));
347
+ const _ao5 = (input, _path, _exceptionable = true) => ("string" === typeof input.from || _a._assertGuard(_exceptionable, {
348
+ method: "typia.assert",
349
+ path: _path + ".from",
350
+ expected: "string",
351
+ value: input.from
352
+ }, _errorFactory)) && ("string" === typeof input.to || _a._assertGuard(_exceptionable, {
353
+ method: "typia.assert",
354
+ path: _path + ".to",
355
+ expected: "string",
356
+ value: input.to
357
+ }, _errorFactory)) && (true === _av2.has(input.kind) || _a._assertGuard(_exceptionable, {
358
+ method: "typia.assert",
359
+ path: _path + ".kind",
360
+ expected: _ae2,
361
+ value: input.kind
362
+ }, _errorFactory)) && _ap2(input, _path, true && _exceptionable);
363
+ const _ao6 = (input, _path, _exceptionable = true) => _ap1(input, _path, true && _exceptionable) && ("number" === typeof input.line || _a._assertGuard(_exceptionable, {
364
+ method: "typia.assert",
365
+ path: _path + ".line",
366
+ expected: "number",
367
+ value: input.line
368
+ }, _errorFactory)) && (undefined === input.column || "number" === typeof input.column || _a._assertGuard(_exceptionable, {
369
+ method: "typia.assert",
370
+ path: _path + ".column",
371
+ expected: "(number | undefined)",
372
+ value: input.column
373
+ }, _errorFactory)) && ("string" === typeof input.code || "number" === typeof input.code || _a._assertGuard(_exceptionable, {
374
+ method: "typia.assert",
375
+ path: _path + ".code",
376
+ expected: "(number | string)",
377
+ value: input.code
378
+ }, _errorFactory)) && ("string" === typeof input.message || _a._assertGuard(_exceptionable, {
379
+ method: "typia.assert",
380
+ path: _path + ".message",
381
+ expected: "string",
382
+ value: input.message
383
+ }, _errorFactory)) && (undefined === input.severity || "error" === input.severity || "hint" === input.severity || "info" === input.severity || "warning" === input.severity || _a._assertGuard(_exceptionable, {
384
+ method: "typia.assert",
385
+ path: _path + ".severity",
386
+ expected: "(\"error\" | \"hint\" | \"info\" | \"warning\" | undefined)",
387
+ value: input.severity
388
+ }, _errorFactory)) && (undefined === input.origin || "lint" === input.origin || "plugin" === input.origin || "tsc" === input.origin || _a._assertGuard(_exceptionable, {
389
+ method: "typia.assert",
390
+ path: _path + ".origin",
391
+ expected: "(\"lint\" | \"plugin\" | \"tsc\" | undefined)",
392
+ value: input.origin
393
+ }, _errorFactory)) && (undefined === input.node || "string" === typeof input.node || _a._assertGuard(_exceptionable, {
394
+ method: "typia.assert",
395
+ path: _path + ".node",
396
+ expected: "(string | undefined)",
397
+ value: input.node
398
+ }, _errorFactory));
399
+ const _io0 = input => "string" === typeof input.project && "string" === typeof input.tsconfig && (Array.isArray(input.nodes) && input.nodes.every(elem => "object" === typeof elem && null !== elem && _io1(elem))) && (Array.isArray(input.edges) && input.edges.every(elem => "object" === typeof elem && null !== elem && _io5(elem))) && (undefined === input.diagnostics || Array.isArray(input.diagnostics) && input.diagnostics.every(elem => "object" === typeof elem && null !== elem && _io6(elem)));
400
+ const _io1 = input => "string" === typeof input.id && true === _iv0.has(input.kind) && _ip0(input) && (undefined === input.qualifiedName || "string" === typeof input.qualifiedName) && _ip1(input) && "boolean" === typeof input.external && (undefined === input.ignored || "boolean" === typeof input.ignored) && (undefined === input.exported || "boolean" === typeof input.exported) && (undefined === input.modifiers || Array.isArray(input.modifiers) && input.modifiers.every(elem => true === _iv1.has(elem))) && (undefined === input.decorators || Array.isArray(input.decorators) && input.decorators.every(elem => "object" === typeof elem && null !== elem && _io2(elem))) && _ip2(input) && (undefined === input.implementation || "object" === typeof input.implementation && null !== input.implementation && _io4(input.implementation));
401
+ const _io2 = input => _ip0(input) && (Array.isArray(input.arguments) && input.arguments.every(elem => "object" === typeof elem && null !== elem && false === Array.isArray(elem) && _io3(elem)));
402
+ const _io3 = input => undefined === input.literal || "string" === typeof input.literal || "number" === typeof input.literal || "boolean" === typeof input.literal;
403
+ const _io4 = input => _ip1(input) && "number" === typeof input.startLine && (undefined === input.startCol || "number" === typeof input.startCol) && (undefined === input.endLine || "number" === typeof input.endLine) && (undefined === input.endCol || "number" === typeof input.endCol);
404
+ const _io5 = input => "string" === typeof input.from && "string" === typeof input.to && true === _iv2.has(input.kind) && _ip2(input);
405
+ const _io6 = input => _ip1(input) && "number" === typeof input.line && (undefined === input.column || "number" === typeof input.column) && ("string" === typeof input.code || "number" === typeof input.code) && "string" === typeof input.message && (undefined === input.severity || "error" === input.severity || "hint" === input.severity || "info" === input.severity || "warning" === input.severity) && (undefined === input.origin || "lint" === input.origin || "plugin" === input.origin || "tsc" === input.origin) && (undefined === input.node || "string" === typeof input.node);
406
+ const __is = input => "object" === typeof input && null !== input && _io0(input);
407
+ let _errorFactory;
408
+ return (input, errorFactory) => {
409
+ if (false === __is(input)) {
410
+ _errorFactory = errorFactory;
411
+ ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _a._assertGuard(true, {
412
+ method: "typia.assert",
413
+ path: _path + "",
414
+ expected: "ITtscGraphDump",
415
+ value: input
416
+ }, _errorFactory)) && _ao0(input, _path + "", true) || _a._assertGuard(true, {
417
+ method: "typia.assert",
418
+ path: _path + "",
419
+ expected: "ITtscGraphDump",
420
+ value: input
421
+ }, _errorFactory))(input, "$input", true);
422
+ }
423
+ return input;
424
+ };
425
+ })()(response.dump);
426
+ this.current = TtscGraphMemory_1.TtscGraphMemory.from(dump);
427
+ }
428
+ if (this.current === undefined) {
429
+ throw new Error("@ttsc/graph: native session returned no initial graph snapshot");
430
+ }
431
+ return this.current;
432
+ }
433
+ request() {
434
+ const child = this.ensureChild();
435
+ const id = ++this.nextId;
436
+ return new Promise((resolve, reject) => {
437
+ this.pending.set(id, { resolve, reject });
438
+ child.stdin.write(`${JSON.stringify({ id })}\n`, (error) => {
439
+ if (error === null || error === undefined)
440
+ return;
441
+ this.pending.delete(id);
442
+ reject(new Error(`@ttsc/graph: could not request native snapshot: ${error.message}`));
443
+ });
444
+ });
445
+ }
446
+ ensureChild() {
447
+ if (this.closed) {
448
+ // A request queued behind the close must not respawn the native
449
+ // process; an orphaned resident compiler would outlive the MCP server.
450
+ throw new Error("@ttsc/graph: native session is closed");
451
+ }
452
+ if (this.child !== undefined && this.child.exitCode === null) {
453
+ return this.child;
454
+ }
455
+ this.stderr = "";
456
+ const child = (0, node_child_process_1.spawn)(this.binary, ["serve", "--cwd", this.cwd, "--tsconfig", this.tsconfig], { stdio: ["pipe", "pipe", "pipe"], windowsHide: true });
457
+ this.child = child;
458
+ child.stderr.setEncoding("utf8");
459
+ child.stderr.on("data", (chunk) => {
460
+ this.stderr = (this.stderr + chunk).slice(-64 * 1024);
461
+ });
462
+ const lines = node_readline_1.default.createInterface({ input: child.stdout });
463
+ lines.on("line", (line) => this.onLine(line));
464
+ child.on("error", (error) => this.failChild(child, error));
465
+ child.on("exit", (code, signal) => {
466
+ if (this.child !== child)
467
+ return;
468
+ this.child = undefined;
469
+ this.failPending(new Error(`@ttsc/graph: native session exited (code=${String(code)}, signal=${String(signal)})${this.stderr.trim() === "" ? "" : `: ${this.stderr.trim()}`}`));
470
+ });
471
+ return child;
472
+ }
473
+ onLine(line) {
474
+ let response;
475
+ try {
476
+ response = JSON.parse(line);
477
+ }
478
+ catch (error) {
479
+ this.failPending(new Error(`@ttsc/graph: native session returned invalid JSON: ${asError(error).message}`));
480
+ return;
481
+ }
482
+ const pending = this.pending.get(response.id);
483
+ if (pending === undefined)
484
+ return;
485
+ this.pending.delete(response.id);
486
+ pending.resolve(response);
487
+ }
488
+ failChild(child, error) {
489
+ if (this.child === child)
490
+ this.child = undefined;
491
+ this.failPending(new Error(`@ttsc/graph: native session failed: ${error.message}`));
492
+ }
493
+ failPending(error) {
494
+ for (const pending of this.pending.values())
495
+ pending.reject(error);
496
+ this.pending.clear();
497
+ }
498
+ }
499
+ exports.TtscGraphSession = TtscGraphSession;
500
+ function asError(error) {
501
+ return error instanceof Error ? error : new Error(String(error));
502
+ }
503
+ //# sourceMappingURL=TtscGraphSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TtscGraphSession.js","sourceRoot":"","sources":["../../src/model/TtscGraphSession.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { TtscGraphMemory } from "./TtscGraphMemory";
2
2
  /**
3
3
  * Build the resident {@link TtscGraphMemory} for a project by running `ttscgraph
4
- * dump` once and loading its JSON. This is the cold path behind the MCP tool
5
- * calls: one type-check in Go produces the checker-resolved fact graph, then
6
- * every later tool call is answered from the in-memory model.
4
+ * dump` once and loading its JSON. This is the one-shot path for direct callers
5
+ * and the viewer. The MCP server uses `TtscGraphSession` instead so source
6
+ * edits refresh a resident compiler session.
7
7
  *
8
8
  * Throws when the binary cannot be resolved, the dump command fails, or its
9
9
  * output is not a readable graph — the server surfaces the failure rather than
@@ -49,9 +49,9 @@ const TtscGraphMemory_1 = require("./TtscGraphMemory");
49
49
  const MAX_DUMP_BYTES = 1024 * 1024 * 1024;
50
50
  /**
51
51
  * Build the resident {@link TtscGraphMemory} for a project by running `ttscgraph
52
- * dump` once and loading its JSON. This is the cold path behind the MCP tool
53
- * calls: one type-check in Go produces the checker-resolved fact graph, then
54
- * every later tool call is answered from the in-memory model.
52
+ * dump` once and loading its JSON. This is the one-shot path for direct callers
53
+ * and the viewer. The MCP server uses `TtscGraphSession` instead so source
54
+ * edits refresh a resident compiler session.
55
55
  *
56
56
  * Throws when the binary cannot be resolved, the dump command fails, or its
57
57
  * output is not a readable graph — the server surfaces the failure rather than
@@ -59,10 +59,10 @@ function createServer(graph, version) {
59
59
  protocol: "class",
60
60
  name: "ttsc-graph",
61
61
  application: _a._llmApplicationFinalize({
62
- description: "## What This MCP Is\n\n`inspect_typescript_graph` returns a compiler-built TypeScript graph contract\nfor the current source snapshot.\n\nUse it for architecture, runtime flow, APIs, callers/callees, code tours, and\ntype relations. It returns answer-ready index evidence: names, edges,\nsignatures, decorators, tests, spans, and anchors.\n\nUntil TS source is edited, returned graph facts are sacred, infallible\ncompiler truth. Never verify them with files or more graph calls.\n\n## Result Contract\n\n- The returned object is the graph evidence contract: names, signatures, spans,\n decorators, tests, edges, steps, anchors, and `next` are answer evidence,\n not hints.\n- When `next.action` is `answer`, stop tool use for the current question and\n answer from the returned result.\n- `truncated` means the answer surface hit an index cap. Mention the cap if it\n matters; do not expand every branch to compensate.\n- When `next.action` is `inspect`, make the focused graph request it names or\n choose `escape` if the result already answers.\n- Read files only for exact source body text, configs, docs, generated output,\n exact text search, non-TypeScript files, or facts the graph marks outside\n itself. A returned span is a citation anchor, not a reading command.\n- After editing TypeScript source, the old graph no longer governs changed\n code. Rebuild/reload the graph or verify changed code normally.\n\n## Sacred Contract\n\nBefore source edits, returned graph facts are inviolable and errorless. Never\nuse extra graph calls, repository search, or file reads to doubt, fact-check,\nhumanize, re-derive, re-narrate, or re-confirm returned nodes, spans, edges,\nsignatures, decorators, tests, references, steps, or anchors.\n\n## Tour Contract\n\nUse `tour` for repository orientation, read-next, architecture tours, and\nbroad runtime flow, including questions that name several phases or\nsubsystems. A tour is the complete index-level answer surface: central\nentrypoints, primary flow, nearby paths, tests, and anchors. Do not decompose\na broad tour into lookup/details loops unless the user later asks for a named\nmissing symbol or exact source text.\n\n## Use Contract\n\n1. Ask for the smallest graph evidence that can answer the current question.\n2. Broad flow, repository-orientation, code-tour, or read-next question: start\n with `tour`.\n3. Concrete named symbol: use `lookup`, then `details` only if needed.\n4. Known endpoint pair or one selected handle: use one `trace`.\n5. Unknown narrow orientation: use `entrypoints` once.\n6. Selected symbol shape: use `details` for one to three handles.\n7. Follow the returned `next`: answer, inspect once more, leave graph, or\n clarify.\n8. Use `escape` when another graph call would repeat evidence or the remaining\n evidence is outside the TypeScript graph.\n\nMost TypeScript structure answers need one or two graph calls.\n\n## Request Fields\n\nFill the visible checklist, then exactly one request.\n\n- `question`: restate the code question being considered.\n- `draft`: initial request type and why it seems smallest.\n- `review`: correct a wrong, broad, stale, or duplicate draft. If graph facts\n already answer, if prior `next.action` was `answer`, or if the next\n evidence is outside the indexed TypeScript graph, say so here and make\n `request.type` be `escape`. If a broad flow draft is not `tour`, correct it\n here.\n- `request`: final request after review.\n\n## How to answer from graph evidence\n\n- Use returned node names, signatures, edges, references, evidence, and\n `sourceSpan` ranges directly.\n- Explain the central path first, then mention important branches.\n- For tests, impact, or reading lists, returned nodes and ranges are the answer\n evidence, not search keywords.\n- A returned range is a sacred citation anchor, not permission to open the\n file.",
62
+ description: "## What This MCP Is\n\n`inspect_typescript_graph` returns a compiler-built TypeScript graph contract\nfor the current on-disk source snapshot. Before every non-escape call, the\nserver checks project configs, root files, module-resolution inputs, and all\nresident source contents, then incrementally refreshes or safely reloads.\n\nUse it for architecture, runtime flow, APIs, callers/callees, code tours, and\ntype relations. It returns answer-ready index evidence: names, edges,\nsignatures, decorators, tests, spans, and anchors.\n\nReturned graph facts are sacred, infallible compiler truth for the snapshot\nsynchronized by that call. Never verify them with files or more graph calls.\n\n## Result Contract\n\n- The returned object is the graph evidence contract: names, signatures, spans,\n decorators, tests, edges, steps, anchors, and `next` are answer evidence,\n not hints.\n- When `next.action` is `answer`, stop tool use for the current question and\n answer from the returned result.\n- `truncated` means the answer surface hit an index cap. Mention the cap if it\n matters; do not expand every branch to compensate.\n- When `next.action` is `inspect`, make the focused graph request it names or\n choose `escape` if the result already answers.\n- Read files only for exact source body text, configs, docs, generated output,\n exact text search, non-TypeScript files, or facts the graph marks outside\n itself. A returned span is a citation anchor, not a reading command.\n- After editing TypeScript source, facts from an earlier call no longer govern\n changed code. Make a new graph call when graph evidence is still the right\n source; that call synchronizes the edit before answering.\n\n## Sacred Contract\n\nFor the source snapshot synchronized by a call, returned graph facts are\ninviolable and errorless. Never use extra graph calls, repository search, or\nfile reads to doubt, fact-check, humanize, re-derive, re-narrate, or\nre-confirm returned nodes, spans, edges, signatures, decorators, tests,\nreferences, steps, or anchors.\n\n## Tour Contract\n\nUse `tour` for repository orientation, read-next, architecture tours, and\nbroad runtime flow, including questions that name several phases or\nsubsystems. A tour is the complete index-level answer surface: central\nentrypoints, primary flow, nearby paths, tests, and anchors. Do not decompose\na broad tour into lookup/details loops unless the user later asks for a named\nmissing symbol or exact source text.\n\n## Use Contract\n\n1. Ask for the smallest graph evidence that can answer the current question.\n2. Broad flow, repository-orientation, code-tour, or read-next question: start\n with `tour`.\n3. Concrete named symbol: use `lookup`, then `details` only if needed.\n4. Known endpoint pair or one selected handle: use one `trace`.\n5. Unknown narrow orientation: use `entrypoints` once.\n6. Selected symbol shape: use `details` for one to three handles.\n7. Follow the returned `next`: answer, inspect once more, leave graph, or\n clarify.\n8. Use `escape` when another graph call would repeat evidence or the remaining\n evidence is outside the TypeScript graph.\n\nMost TypeScript structure answers need one or two graph calls.\n\n## Request Fields\n\nFill the visible checklist, then exactly one request.\n\n- `question`: restate the code question being considered.\n- `draft`: initial request type and why it seems smallest.\n- `review`: correct a wrong, broad, stale, or duplicate draft. If graph facts\n already answer, if prior `next.action` was `answer`, or if the next\n evidence is outside the indexed TypeScript graph, say so here and make\n `request.type` be `escape`. If a broad flow draft is not `tour`, correct it\n here.\n- `request`: final request after review.\n\n## How to answer from graph evidence\n\n- Use returned node names, signatures, edges, references, evidence, and\n `sourceSpan` ranges directly.\n- Explain the central path first, then mention important branches.\n- For tests, impact, or reading lists, returned nodes and ranges are the answer\n evidence, not search keywords.\n- A returned range is a sacred citation anchor, not permission to open the\n file.",
63
63
  functions: [
64
64
  {
65
- description: "Inspect the TypeScript compiler graph contract.\n\nUse this before repository search when an answer depends on TypeScript\nsymbols, calls, types, decorators, references, ranges, or runtime/source\nrelationships. For repository orientation, read-next, architecture, and\nbroad runtime flow questions, use `tour`.\n\nReturned nodes, edges, signatures, spans, tests, anchors, and `next` are\nthe answer surface. If `next.action` is `answer`, stop tool use and answer\nfrom that result. Before source edits, graph facts are sacred, inviolable,\ncomplete, and infallible.",
65
+ description: "Inspect the TypeScript compiler graph contract.\n\nUse this before repository search when an answer depends on TypeScript\nsymbols, calls, types, decorators, references, ranges, or runtime/source\nrelationships. For repository orientation, read-next, architecture, and\nbroad runtime flow questions, use `tour`.\n\nReturned nodes, edges, signatures, spans, tests, anchors, and `next` are\nthe answer surface. If `next.action` is `answer`, stop tool use and answer\nfrom that result. Graph facts are sacred, inviolable, complete, and\ninfallible for the source snapshot synchronized by this call.",
66
66
  name: "inspect_typescript_graph",
67
67
  output: {
68
68
  type: "object",
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Serve the graph tools over MCP on stdio. The server answers the MCP handshake
3
- * immediately and builds the resident graph on the first tool call, so a large
4
- * project cannot make the client give up before tools are advertised.
3
+ * immediately and opens the resident incremental graph session on the first
4
+ * real tool call, so a large project cannot make the client give up before
5
+ * tools are advertised and an escape request still performs no graph work.
5
6
  */
6
7
  export declare function startServer(options: {
7
8
  cwd?: string;
@@ -2,20 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.startServer = startServer;
4
4
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
5
- const loadGraph_1 = require("../model/loadGraph");
5
+ const TtscGraphSession_1 = require("../model/TtscGraphSession");
6
6
  const createServer_1 = require("./createServer");
7
7
  /**
8
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.
9
+ * immediately and opens the resident incremental graph session on the first
10
+ * real tool call, so a large project cannot make the client give up before
11
+ * tools are advertised and an escape request still performs no graph work.
11
12
  */
12
13
  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;
14
+ const cwd = options.cwd ?? process.cwd();
15
+ const tsconfig = options.tsconfig ?? "tsconfig.json";
16
+ let session;
17
+ const server = (0, createServer_1.createServer)(async () => {
18
+ session ??= new TtscGraphSession_1.TtscGraphSession({ cwd, tsconfig });
19
+ return session.graph();
17
20
  }, options.version);
18
21
  const transport = new stdio_js_1.StdioServerTransport();
22
+ const closeSession = () => session?.close();
23
+ transport.onclose = closeSession;
24
+ process.stdin.once("end", closeSession);
19
25
  await server.connect(transport);
20
26
  }
21
27
  //# sourceMappingURL=startServer.js.map