bluera-knowledge 0.10.1 → 0.11.0
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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +13 -0
- package/README.md +25 -0
- package/dist/{chunk-6U45VP5Z.js → chunk-2WBITQWZ.js} +2 -2
- package/dist/{chunk-DP5XBPQV.js → chunk-565OVW3C.js} +629 -2
- package/dist/chunk-565OVW3C.js.map +1 -0
- package/dist/{chunk-UE4ZIJYA.js → chunk-TRDMYKGC.js} +117 -1
- package/dist/chunk-TRDMYKGC.js.map +1 -0
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +2 -2
- package/dist/workers/background-worker-cli.js +2 -2
- package/package.json +1 -1
- package/src/analysis/adapter-registry.test.ts +211 -0
- package/src/analysis/adapter-registry.ts +155 -0
- package/src/analysis/language-adapter.ts +127 -0
- package/src/analysis/parser-factory.test.ts +79 -1
- package/src/analysis/parser-factory.ts +8 -0
- package/src/analysis/zil/index.ts +34 -0
- package/src/analysis/zil/zil-adapter.test.ts +187 -0
- package/src/analysis/zil/zil-adapter.ts +121 -0
- package/src/analysis/zil/zil-lexer.test.ts +222 -0
- package/src/analysis/zil/zil-lexer.ts +239 -0
- package/src/analysis/zil/zil-parser.test.ts +210 -0
- package/src/analysis/zil/zil-parser.ts +360 -0
- package/src/analysis/zil/zil-special-forms.ts +193 -0
- package/src/index.ts +6 -0
- package/src/mcp/server.ts +9 -1
- package/dist/chunk-DP5XBPQV.js.map +0 -1
- package/dist/chunk-UE4ZIJYA.js.map +0 -1
- /package/dist/{chunk-6U45VP5Z.js.map → chunk-2WBITQWZ.js.map} +0 -0
|
@@ -1,17 +1,639 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AdapterRegistry,
|
|
2
3
|
JobService,
|
|
3
4
|
ProjectRootService,
|
|
4
5
|
createLogger,
|
|
5
6
|
createServices,
|
|
6
7
|
createStoreId,
|
|
7
8
|
summarizePayload
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TRDMYKGC.js";
|
|
9
10
|
|
|
10
11
|
// src/mcp/server.ts
|
|
11
12
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
12
13
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
14
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
14
15
|
|
|
16
|
+
// src/analysis/zil/zil-lexer.ts
|
|
17
|
+
var ZilLexer = class {
|
|
18
|
+
input = "";
|
|
19
|
+
pos = 0;
|
|
20
|
+
line = 1;
|
|
21
|
+
column = 1;
|
|
22
|
+
tokens = [];
|
|
23
|
+
/**
|
|
24
|
+
* Tokenize ZIL source code
|
|
25
|
+
*
|
|
26
|
+
* @param input - Source code string
|
|
27
|
+
* @returns Array of tokens
|
|
28
|
+
* @throws On unterminated strings
|
|
29
|
+
*/
|
|
30
|
+
tokenize(input) {
|
|
31
|
+
this.input = input;
|
|
32
|
+
this.pos = 0;
|
|
33
|
+
this.line = 1;
|
|
34
|
+
this.column = 1;
|
|
35
|
+
this.tokens = [];
|
|
36
|
+
while (!this.isAtEnd()) {
|
|
37
|
+
this.scanToken();
|
|
38
|
+
}
|
|
39
|
+
return this.tokens;
|
|
40
|
+
}
|
|
41
|
+
isAtEnd() {
|
|
42
|
+
return this.pos >= this.input.length;
|
|
43
|
+
}
|
|
44
|
+
peek() {
|
|
45
|
+
if (this.isAtEnd()) return "\0";
|
|
46
|
+
return this.input[this.pos] ?? "\0";
|
|
47
|
+
}
|
|
48
|
+
advance() {
|
|
49
|
+
const char = this.input[this.pos] ?? "\0";
|
|
50
|
+
this.pos++;
|
|
51
|
+
if (char === "\n") {
|
|
52
|
+
this.line++;
|
|
53
|
+
this.column = 1;
|
|
54
|
+
} else {
|
|
55
|
+
this.column++;
|
|
56
|
+
}
|
|
57
|
+
return char;
|
|
58
|
+
}
|
|
59
|
+
addToken(type, value, startLine, startColumn) {
|
|
60
|
+
this.tokens.push({
|
|
61
|
+
type,
|
|
62
|
+
value,
|
|
63
|
+
line: startLine,
|
|
64
|
+
column: startColumn
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
scanToken() {
|
|
68
|
+
const startLine = this.line;
|
|
69
|
+
const startColumn = this.column;
|
|
70
|
+
const char = this.advance();
|
|
71
|
+
switch (char) {
|
|
72
|
+
case "<":
|
|
73
|
+
this.addToken("LANGLE" /* LANGLE */, "<", startLine, startColumn);
|
|
74
|
+
break;
|
|
75
|
+
case ">":
|
|
76
|
+
this.addToken("RANGLE" /* RANGLE */, ">", startLine, startColumn);
|
|
77
|
+
break;
|
|
78
|
+
case "(":
|
|
79
|
+
this.addToken("LPAREN" /* LPAREN */, "(", startLine, startColumn);
|
|
80
|
+
break;
|
|
81
|
+
case ")":
|
|
82
|
+
this.addToken("RPAREN" /* RPAREN */, ")", startLine, startColumn);
|
|
83
|
+
break;
|
|
84
|
+
case '"':
|
|
85
|
+
this.scanString(startLine, startColumn);
|
|
86
|
+
break;
|
|
87
|
+
case ";":
|
|
88
|
+
this.skipComment();
|
|
89
|
+
break;
|
|
90
|
+
case " ":
|
|
91
|
+
case " ":
|
|
92
|
+
case "\r":
|
|
93
|
+
case "\n":
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
if (this.isDigit(char) || char === "-" && this.isDigit(this.peek())) {
|
|
97
|
+
this.scanNumber(char, startLine, startColumn);
|
|
98
|
+
} else if (this.isAtomStart(char)) {
|
|
99
|
+
this.scanAtom(char, startLine, startColumn);
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
scanString(startLine, startColumn) {
|
|
105
|
+
let value = "";
|
|
106
|
+
while (!this.isAtEnd() && this.peek() !== '"') {
|
|
107
|
+
const char = this.peek();
|
|
108
|
+
if (char === "\\") {
|
|
109
|
+
this.advance();
|
|
110
|
+
const escaped = this.advance();
|
|
111
|
+
switch (escaped) {
|
|
112
|
+
case '"':
|
|
113
|
+
value += '"';
|
|
114
|
+
break;
|
|
115
|
+
case "\\":
|
|
116
|
+
value += "\\";
|
|
117
|
+
break;
|
|
118
|
+
case "n":
|
|
119
|
+
value += "\n";
|
|
120
|
+
break;
|
|
121
|
+
case "t":
|
|
122
|
+
value += " ";
|
|
123
|
+
break;
|
|
124
|
+
default:
|
|
125
|
+
value += escaped;
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
value += this.advance();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (this.isAtEnd()) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Unterminated string at line ${String(startLine)}, column ${String(startColumn)}`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
this.advance();
|
|
138
|
+
this.addToken("STRING" /* STRING */, value, startLine, startColumn);
|
|
139
|
+
}
|
|
140
|
+
scanNumber(firstChar, startLine, startColumn) {
|
|
141
|
+
let value = firstChar;
|
|
142
|
+
while (this.isDigit(this.peek())) {
|
|
143
|
+
value += this.advance();
|
|
144
|
+
}
|
|
145
|
+
this.addToken("NUMBER" /* NUMBER */, value, startLine, startColumn);
|
|
146
|
+
}
|
|
147
|
+
scanAtom(firstChar, startLine, startColumn) {
|
|
148
|
+
let value = firstChar;
|
|
149
|
+
while (this.isAtomChar(this.peek())) {
|
|
150
|
+
value += this.advance();
|
|
151
|
+
}
|
|
152
|
+
this.addToken("ATOM" /* ATOM */, value, startLine, startColumn);
|
|
153
|
+
}
|
|
154
|
+
skipComment() {
|
|
155
|
+
while (!this.isAtEnd() && this.peek() !== "\n") {
|
|
156
|
+
this.advance();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
isDigit(char) {
|
|
160
|
+
return char >= "0" && char <= "9";
|
|
161
|
+
}
|
|
162
|
+
isAtomStart(char) {
|
|
163
|
+
return char >= "A" && char <= "Z" || char >= "a" && char <= "z" || char === "_" || char === "," || // Global reference prefix
|
|
164
|
+
char === "." || // Local reference prefix
|
|
165
|
+
char === "%" || // Sometimes used in ZIL
|
|
166
|
+
char === "#";
|
|
167
|
+
}
|
|
168
|
+
isAtomChar(char) {
|
|
169
|
+
return char >= "A" && char <= "Z" || char >= "a" && char <= "z" || char >= "0" && char <= "9" || char === "_" || char === "-" || char === "?" || char === "!" || char === "," || char === "." || char === "%" || char === "#";
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// src/analysis/zil/zil-special-forms.ts
|
|
174
|
+
var ZIL_SPECIAL_FORMS = /* @__PURE__ */ new Set([
|
|
175
|
+
// Conditionals
|
|
176
|
+
"COND",
|
|
177
|
+
"AND",
|
|
178
|
+
"OR",
|
|
179
|
+
"NOT",
|
|
180
|
+
"IF",
|
|
181
|
+
"ELSE",
|
|
182
|
+
// Assignment
|
|
183
|
+
"SET",
|
|
184
|
+
"SETG",
|
|
185
|
+
"BIND",
|
|
186
|
+
"PROG",
|
|
187
|
+
// Loops
|
|
188
|
+
"REPEAT",
|
|
189
|
+
"DO",
|
|
190
|
+
"MAP",
|
|
191
|
+
"MAPF",
|
|
192
|
+
"MAPR",
|
|
193
|
+
"MAPRET",
|
|
194
|
+
"MAPLEAVE",
|
|
195
|
+
// Output
|
|
196
|
+
"TELL",
|
|
197
|
+
"PRINT",
|
|
198
|
+
"PRINTN",
|
|
199
|
+
"PRINTD",
|
|
200
|
+
"PRINTC",
|
|
201
|
+
"PRINTR",
|
|
202
|
+
"CRLF",
|
|
203
|
+
// Control flow
|
|
204
|
+
"RETURN",
|
|
205
|
+
"AGAIN",
|
|
206
|
+
"RTRUE",
|
|
207
|
+
"RFALSE",
|
|
208
|
+
"QUIT",
|
|
209
|
+
// Predicates (end with ?)
|
|
210
|
+
"EQUAL?",
|
|
211
|
+
"ZERO?",
|
|
212
|
+
"LESS?",
|
|
213
|
+
"GRTR?",
|
|
214
|
+
"FSET?",
|
|
215
|
+
"IN?",
|
|
216
|
+
"VERB?",
|
|
217
|
+
"PRSO?",
|
|
218
|
+
"PRSI?",
|
|
219
|
+
"HELD?",
|
|
220
|
+
"HERE?",
|
|
221
|
+
"ACCESSIBLE?",
|
|
222
|
+
"VISIBLE?",
|
|
223
|
+
"FIRST?",
|
|
224
|
+
"NEXT?",
|
|
225
|
+
"PROB?",
|
|
226
|
+
"RANDOM",
|
|
227
|
+
// Property/flag manipulation
|
|
228
|
+
"FSET",
|
|
229
|
+
"FCLEAR",
|
|
230
|
+
"GETP",
|
|
231
|
+
"PUTP",
|
|
232
|
+
"GETPT",
|
|
233
|
+
"PTSIZE",
|
|
234
|
+
// Object manipulation
|
|
235
|
+
"MOVE",
|
|
236
|
+
"REMOVE",
|
|
237
|
+
"LOC",
|
|
238
|
+
"FIRST",
|
|
239
|
+
"NEXT",
|
|
240
|
+
// Arithmetic
|
|
241
|
+
"ADD",
|
|
242
|
+
"SUB",
|
|
243
|
+
"MUL",
|
|
244
|
+
"DIV",
|
|
245
|
+
"MOD",
|
|
246
|
+
"BAND",
|
|
247
|
+
"BOR",
|
|
248
|
+
"BCOM",
|
|
249
|
+
"LSH",
|
|
250
|
+
// Table operations
|
|
251
|
+
"GET",
|
|
252
|
+
"PUT",
|
|
253
|
+
"GETB",
|
|
254
|
+
"PUTB",
|
|
255
|
+
"TABLE",
|
|
256
|
+
"ITABLE",
|
|
257
|
+
"LTABLE",
|
|
258
|
+
"PTABLE",
|
|
259
|
+
// Stack operations
|
|
260
|
+
"PUSH",
|
|
261
|
+
"POP",
|
|
262
|
+
"FSTACK",
|
|
263
|
+
// Input
|
|
264
|
+
"READ",
|
|
265
|
+
"INPUT",
|
|
266
|
+
"READLINE",
|
|
267
|
+
// Definition forms (handled separately for symbol extraction)
|
|
268
|
+
"ROUTINE",
|
|
269
|
+
"OBJECT",
|
|
270
|
+
"ROOM",
|
|
271
|
+
"GLOBAL",
|
|
272
|
+
"CONSTANT",
|
|
273
|
+
"SYNTAX",
|
|
274
|
+
"INSERT-FILE",
|
|
275
|
+
// Misc builtins
|
|
276
|
+
"VERSION?",
|
|
277
|
+
"ASCII",
|
|
278
|
+
"USL",
|
|
279
|
+
"APPLY",
|
|
280
|
+
"EVAL",
|
|
281
|
+
"FORM",
|
|
282
|
+
"REST",
|
|
283
|
+
"LENGTH",
|
|
284
|
+
"NTH",
|
|
285
|
+
"ZGET",
|
|
286
|
+
"ZPUT",
|
|
287
|
+
"ZWSTR",
|
|
288
|
+
"DIROUT",
|
|
289
|
+
"DIRIN",
|
|
290
|
+
"BUFOUT",
|
|
291
|
+
"HLIGHT",
|
|
292
|
+
"COLOR",
|
|
293
|
+
"FONT",
|
|
294
|
+
"SPLIT",
|
|
295
|
+
"SCREEN",
|
|
296
|
+
"WINGET",
|
|
297
|
+
"WINPUT",
|
|
298
|
+
"WINATTR",
|
|
299
|
+
"PICINF",
|
|
300
|
+
"DISPLAY",
|
|
301
|
+
"DCLEAR",
|
|
302
|
+
"SOUND",
|
|
303
|
+
"INTBL?",
|
|
304
|
+
"CATCH",
|
|
305
|
+
"THROW",
|
|
306
|
+
"LEGAL?",
|
|
307
|
+
"COPYT",
|
|
308
|
+
"VALUE",
|
|
309
|
+
"GASSIGNED?",
|
|
310
|
+
"ASSIGNED?",
|
|
311
|
+
"DEFINE",
|
|
312
|
+
"DEFMAC"
|
|
313
|
+
]);
|
|
314
|
+
function isSpecialForm(name) {
|
|
315
|
+
return ZIL_SPECIAL_FORMS.has(name.toUpperCase());
|
|
316
|
+
}
|
|
317
|
+
var ZIL_DEFINITION_FORMS = /* @__PURE__ */ new Set([
|
|
318
|
+
"ROUTINE",
|
|
319
|
+
"OBJECT",
|
|
320
|
+
"ROOM",
|
|
321
|
+
"GLOBAL",
|
|
322
|
+
"CONSTANT",
|
|
323
|
+
"SYNTAX",
|
|
324
|
+
"VERB",
|
|
325
|
+
"DEFINE",
|
|
326
|
+
"DEFMAC"
|
|
327
|
+
]);
|
|
328
|
+
function isDefinitionForm(name) {
|
|
329
|
+
return ZIL_DEFINITION_FORMS.has(name.toUpperCase());
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// src/analysis/zil/zil-parser.ts
|
|
333
|
+
var ZilParser = class {
|
|
334
|
+
lexer = new ZilLexer();
|
|
335
|
+
tokens = [];
|
|
336
|
+
pos = 0;
|
|
337
|
+
/**
|
|
338
|
+
* Parse ZIL source code
|
|
339
|
+
*/
|
|
340
|
+
parse(input) {
|
|
341
|
+
this.tokens = this.lexer.tokenize(input);
|
|
342
|
+
this.pos = 0;
|
|
343
|
+
const forms = [];
|
|
344
|
+
const symbols = [];
|
|
345
|
+
const imports = [];
|
|
346
|
+
const calls = [];
|
|
347
|
+
while (!this.isAtEnd()) {
|
|
348
|
+
if (this.check("LANGLE" /* LANGLE */)) {
|
|
349
|
+
const form = this.parseForm();
|
|
350
|
+
if (form !== void 0) {
|
|
351
|
+
forms.push(form);
|
|
352
|
+
const symbol = this.extractSymbol(form);
|
|
353
|
+
if (symbol !== void 0) {
|
|
354
|
+
symbols.push(symbol);
|
|
355
|
+
}
|
|
356
|
+
const imp = this.extractImport(form);
|
|
357
|
+
if (imp !== void 0) {
|
|
358
|
+
imports.push(imp);
|
|
359
|
+
}
|
|
360
|
+
if (form.head.toUpperCase() === "ROUTINE") {
|
|
361
|
+
const routineName = this.getRoutineName(form);
|
|
362
|
+
if (routineName !== void 0) {
|
|
363
|
+
this.extractCalls(form, routineName, calls);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
} else {
|
|
368
|
+
this.advance();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return { forms, symbols, imports, calls };
|
|
372
|
+
}
|
|
373
|
+
isAtEnd() {
|
|
374
|
+
return this.pos >= this.tokens.length;
|
|
375
|
+
}
|
|
376
|
+
peek() {
|
|
377
|
+
return this.tokens[this.pos];
|
|
378
|
+
}
|
|
379
|
+
check(type) {
|
|
380
|
+
if (this.isAtEnd()) return false;
|
|
381
|
+
return this.peek()?.type === type;
|
|
382
|
+
}
|
|
383
|
+
advance() {
|
|
384
|
+
if (!this.isAtEnd()) {
|
|
385
|
+
const token = this.tokens[this.pos];
|
|
386
|
+
this.pos++;
|
|
387
|
+
return token;
|
|
388
|
+
}
|
|
389
|
+
return void 0;
|
|
390
|
+
}
|
|
391
|
+
parseForm() {
|
|
392
|
+
if (!this.check("LANGLE" /* LANGLE */)) return void 0;
|
|
393
|
+
const startToken = this.advance();
|
|
394
|
+
const startLine = startToken?.line ?? 1;
|
|
395
|
+
let endLine = startLine;
|
|
396
|
+
let head = "";
|
|
397
|
+
if (this.check("ATOM" /* ATOM */)) {
|
|
398
|
+
head = this.advance()?.value ?? "";
|
|
399
|
+
}
|
|
400
|
+
const children = [];
|
|
401
|
+
while (!this.isAtEnd() && !this.check("RANGLE" /* RANGLE */)) {
|
|
402
|
+
const child = this.parseNode();
|
|
403
|
+
if (child !== void 0) {
|
|
404
|
+
children.push(child);
|
|
405
|
+
endLine = this.getNodeEndLine(child);
|
|
406
|
+
} else {
|
|
407
|
+
this.advance();
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (this.check("RANGLE" /* RANGLE */)) {
|
|
411
|
+
const closeToken = this.advance();
|
|
412
|
+
endLine = closeToken?.line ?? endLine;
|
|
413
|
+
}
|
|
414
|
+
return { head, children, startLine, endLine };
|
|
415
|
+
}
|
|
416
|
+
parseGroup() {
|
|
417
|
+
if (!this.check("LPAREN" /* LPAREN */)) return void 0;
|
|
418
|
+
const startToken = this.advance();
|
|
419
|
+
const startLine = startToken?.line ?? 1;
|
|
420
|
+
let endLine = startLine;
|
|
421
|
+
const children = [];
|
|
422
|
+
while (!this.isAtEnd() && !this.check("RPAREN" /* RPAREN */)) {
|
|
423
|
+
const child = this.parseNode();
|
|
424
|
+
if (child !== void 0) {
|
|
425
|
+
children.push(child);
|
|
426
|
+
endLine = this.getNodeEndLine(child);
|
|
427
|
+
} else {
|
|
428
|
+
this.advance();
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (this.check("RPAREN" /* RPAREN */)) {
|
|
432
|
+
const closeToken = this.advance();
|
|
433
|
+
endLine = closeToken?.line ?? endLine;
|
|
434
|
+
}
|
|
435
|
+
return { type: "group", children, startLine, endLine };
|
|
436
|
+
}
|
|
437
|
+
parseNode() {
|
|
438
|
+
const token = this.peek();
|
|
439
|
+
if (token === void 0) return void 0;
|
|
440
|
+
switch (token.type) {
|
|
441
|
+
case "LANGLE" /* LANGLE */:
|
|
442
|
+
return this.parseForm();
|
|
443
|
+
case "LPAREN" /* LPAREN */:
|
|
444
|
+
return this.parseGroup();
|
|
445
|
+
case "ATOM" /* ATOM */:
|
|
446
|
+
this.advance();
|
|
447
|
+
return { type: "atom", value: token.value, line: token.line };
|
|
448
|
+
case "STRING" /* STRING */:
|
|
449
|
+
this.advance();
|
|
450
|
+
return { type: "string", value: token.value, line: token.line };
|
|
451
|
+
case "NUMBER" /* NUMBER */:
|
|
452
|
+
this.advance();
|
|
453
|
+
return { type: "number", value: token.value, line: token.line };
|
|
454
|
+
default:
|
|
455
|
+
return void 0;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
getNodeEndLine(node) {
|
|
459
|
+
if ("endLine" in node) {
|
|
460
|
+
return node.endLine;
|
|
461
|
+
}
|
|
462
|
+
return node.line;
|
|
463
|
+
}
|
|
464
|
+
extractSymbol(form) {
|
|
465
|
+
const headUpper = form.head.toUpperCase();
|
|
466
|
+
if (!isDefinitionForm(headUpper)) {
|
|
467
|
+
return void 0;
|
|
468
|
+
}
|
|
469
|
+
const nameNode = form.children.find((c) => "type" in c && c.type === "atom");
|
|
470
|
+
if (nameNode === void 0) {
|
|
471
|
+
return void 0;
|
|
472
|
+
}
|
|
473
|
+
const kindMap = {
|
|
474
|
+
ROUTINE: "routine",
|
|
475
|
+
OBJECT: "object",
|
|
476
|
+
ROOM: "room",
|
|
477
|
+
GLOBAL: "global",
|
|
478
|
+
CONSTANT: "constant",
|
|
479
|
+
SYNTAX: "syntax",
|
|
480
|
+
VERB: "verb",
|
|
481
|
+
DEFINE: "routine",
|
|
482
|
+
DEFMAC: "routine"
|
|
483
|
+
};
|
|
484
|
+
const kind = kindMap[headUpper];
|
|
485
|
+
if (kind === void 0) {
|
|
486
|
+
return void 0;
|
|
487
|
+
}
|
|
488
|
+
const result = {
|
|
489
|
+
name: nameNode.value,
|
|
490
|
+
kind,
|
|
491
|
+
startLine: form.startLine,
|
|
492
|
+
endLine: form.endLine
|
|
493
|
+
};
|
|
494
|
+
if (headUpper === "ROUTINE" || headUpper === "DEFINE" || headUpper === "DEFMAC") {
|
|
495
|
+
result.signature = this.extractRoutineSignature(form, nameNode.value);
|
|
496
|
+
}
|
|
497
|
+
return result;
|
|
498
|
+
}
|
|
499
|
+
extractRoutineSignature(form, name) {
|
|
500
|
+
const argsGroup = form.children.find((c) => "type" in c && c.type === "group");
|
|
501
|
+
if (argsGroup === void 0) {
|
|
502
|
+
return `ROUTINE ${name} ()`;
|
|
503
|
+
}
|
|
504
|
+
const args = argsGroup.children.filter((c) => "type" in c && c.type === "atom").map((c) => c.value).join(" ");
|
|
505
|
+
return `ROUTINE ${name} (${args})`;
|
|
506
|
+
}
|
|
507
|
+
extractImport(form) {
|
|
508
|
+
if (form.head.toUpperCase() !== "INSERT-FILE") {
|
|
509
|
+
return void 0;
|
|
510
|
+
}
|
|
511
|
+
const fileNode = form.children.find((c) => "type" in c && c.type === "string");
|
|
512
|
+
if (fileNode === void 0) {
|
|
513
|
+
return void 0;
|
|
514
|
+
}
|
|
515
|
+
return {
|
|
516
|
+
source: fileNode.value,
|
|
517
|
+
specifiers: [],
|
|
518
|
+
isType: false
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
getRoutineName(form) {
|
|
522
|
+
const nameNode = form.children.find((c) => "type" in c && c.type === "atom");
|
|
523
|
+
return nameNode?.value;
|
|
524
|
+
}
|
|
525
|
+
extractCalls(node, caller, calls) {
|
|
526
|
+
if ("head" in node) {
|
|
527
|
+
const headUpper = node.head.toUpperCase();
|
|
528
|
+
if (node.head !== "" && !isSpecialForm(headUpper)) {
|
|
529
|
+
calls.push({
|
|
530
|
+
caller,
|
|
531
|
+
callee: node.head,
|
|
532
|
+
line: node.startLine
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
for (const child of node.children) {
|
|
536
|
+
this.extractCalls(child, caller, calls);
|
|
537
|
+
}
|
|
538
|
+
} else if ("type" in node && node.type === "group") {
|
|
539
|
+
for (const child of node.children) {
|
|
540
|
+
this.extractCalls(child, caller, calls);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
// src/analysis/zil/zil-adapter.ts
|
|
547
|
+
var ZilAdapter = class {
|
|
548
|
+
languageId = "zil";
|
|
549
|
+
extensions = [".zil", ".mud"];
|
|
550
|
+
displayName = "ZIL (Zork Implementation Language)";
|
|
551
|
+
parser = new ZilParser();
|
|
552
|
+
/**
|
|
553
|
+
* Parse ZIL code and extract symbols as CodeNode[]
|
|
554
|
+
*/
|
|
555
|
+
parse(content, _filePath) {
|
|
556
|
+
const result = this.parser.parse(content);
|
|
557
|
+
return result.symbols.map((symbol) => {
|
|
558
|
+
const node = {
|
|
559
|
+
type: this.mapSymbolKindToNodeType(symbol.kind),
|
|
560
|
+
name: symbol.name,
|
|
561
|
+
exported: true,
|
|
562
|
+
// ZIL doesn't have export concept, treat all as exported
|
|
563
|
+
startLine: symbol.startLine,
|
|
564
|
+
endLine: symbol.endLine
|
|
565
|
+
};
|
|
566
|
+
if (symbol.signature !== void 0) {
|
|
567
|
+
node.signature = symbol.signature;
|
|
568
|
+
}
|
|
569
|
+
return node;
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Extract imports from INSERT-FILE directives
|
|
574
|
+
*/
|
|
575
|
+
extractImports(content, _filePath) {
|
|
576
|
+
const result = this.parser.parse(content);
|
|
577
|
+
return result.imports;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Chunk ZIL code by top-level forms
|
|
581
|
+
*/
|
|
582
|
+
chunk(content, _filePath) {
|
|
583
|
+
const result = this.parser.parse(content);
|
|
584
|
+
const lines = content.split("\n");
|
|
585
|
+
return result.forms.filter((form) => form.head !== "").map((form) => {
|
|
586
|
+
const chunkLines = lines.slice(form.startLine - 1, form.endLine);
|
|
587
|
+
const chunkContent = chunkLines.join("\n");
|
|
588
|
+
const symbol = result.symbols.find(
|
|
589
|
+
(s) => s.startLine === form.startLine && s.endLine === form.endLine
|
|
590
|
+
);
|
|
591
|
+
const chunk = {
|
|
592
|
+
content: chunkContent,
|
|
593
|
+
startLine: form.startLine,
|
|
594
|
+
endLine: form.endLine
|
|
595
|
+
};
|
|
596
|
+
if (symbol !== void 0) {
|
|
597
|
+
chunk.symbolName = symbol.name;
|
|
598
|
+
chunk.symbolKind = symbol.kind;
|
|
599
|
+
}
|
|
600
|
+
return chunk;
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Analyze call relationships within ZIL code
|
|
605
|
+
*/
|
|
606
|
+
analyzeCallRelationships(content, filePath) {
|
|
607
|
+
const result = this.parser.parse(content);
|
|
608
|
+
return result.calls.map((call) => ({
|
|
609
|
+
from: `${filePath}:${call.caller}`,
|
|
610
|
+
to: `${filePath}:${call.callee}`,
|
|
611
|
+
type: "calls",
|
|
612
|
+
confidence: 0.9
|
|
613
|
+
// High confidence for ZIL - calls are explicit
|
|
614
|
+
}));
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Map ZIL symbol kinds to CodeNode types
|
|
618
|
+
*/
|
|
619
|
+
mapSymbolKindToNodeType(kind) {
|
|
620
|
+
switch (kind) {
|
|
621
|
+
case "routine":
|
|
622
|
+
return "function";
|
|
623
|
+
case "object":
|
|
624
|
+
case "room":
|
|
625
|
+
case "global":
|
|
626
|
+
case "constant":
|
|
627
|
+
return "const";
|
|
628
|
+
case "syntax":
|
|
629
|
+
case "verb":
|
|
630
|
+
return "const";
|
|
631
|
+
default:
|
|
632
|
+
return "const";
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
|
|
15
637
|
// src/mcp/commands/job.commands.ts
|
|
16
638
|
import { z as z2 } from "zod";
|
|
17
639
|
|
|
@@ -1293,6 +1915,10 @@ var tools = [
|
|
|
1293
1915
|
|
|
1294
1916
|
// src/mcp/server.ts
|
|
1295
1917
|
var logger2 = createLogger("mcp-server");
|
|
1918
|
+
var registry = AdapterRegistry.getInstance();
|
|
1919
|
+
if (!registry.hasExtension(".zil")) {
|
|
1920
|
+
registry.register(new ZilAdapter());
|
|
1921
|
+
}
|
|
1296
1922
|
function createMCPServer(options) {
|
|
1297
1923
|
const server = new Server(
|
|
1298
1924
|
{
|
|
@@ -1458,6 +2084,7 @@ if (isMCPServerEntry) {
|
|
|
1458
2084
|
}
|
|
1459
2085
|
|
|
1460
2086
|
export {
|
|
2087
|
+
ZilAdapter,
|
|
1461
2088
|
isFileStoreDefinition,
|
|
1462
2089
|
isRepoStoreDefinition,
|
|
1463
2090
|
isWebStoreDefinition,
|
|
@@ -1465,4 +2092,4 @@ export {
|
|
|
1465
2092
|
createMCPServer,
|
|
1466
2093
|
runMCPServer
|
|
1467
2094
|
};
|
|
1468
|
-
//# sourceMappingURL=chunk-
|
|
2095
|
+
//# sourceMappingURL=chunk-565OVW3C.js.map
|