@navigation-agent/mcp-server 0.1.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/dist/app/createMcpServer.d.ts +18 -0
- package/dist/app/createMcpServer.js +152 -0
- package/dist/bin/navigation-mcp.d.ts +2 -0
- package/dist/bin/navigation-mcp.js +36 -0
- package/dist/contracts/public/code.d.ts +1106 -0
- package/dist/contracts/public/code.js +523 -0
- package/dist/contracts/public/common.d.ts +28 -0
- package/dist/contracts/public/common.js +23 -0
- package/dist/engine/protocol.d.ts +290 -0
- package/dist/engine/protocol.js +13 -0
- package/dist/engine/rustEngineClient.d.ts +16 -0
- package/dist/engine/rustEngineClient.js +138 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/services/findSymbolService.d.ts +11 -0
- package/dist/services/findSymbolService.js +224 -0
- package/dist/services/inspectTreeService.d.ts +11 -0
- package/dist/services/inspectTreeService.js +191 -0
- package/dist/services/listEndpointsService.d.ts +11 -0
- package/dist/services/listEndpointsService.js +233 -0
- package/dist/services/searchTextService.d.ts +11 -0
- package/dist/services/searchTextService.js +233 -0
- package/dist/services/traceCallersService.d.ts +11 -0
- package/dist/services/traceCallersService.js +256 -0
- package/dist/services/traceSymbolService.d.ts +11 -0
- package/dist/services/traceSymbolService.js +231 -0
- package/dist/tools/registerCodeTools.d.ts +20 -0
- package/dist/tools/registerCodeTools.js +188 -0
- package/package.json +51 -0
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
export const PUBLIC_LANGUAGES = ["typescript", "javascript", "java", "python", "rust"];
|
|
2
|
+
export const PUBLIC_FRAMEWORKS = ["react-router", "spring"];
|
|
3
|
+
export const PUBLIC_ENDPOINT_KINDS = ["any", "graphql", "rest", "route"];
|
|
4
|
+
export const PUBLIC_SYMBOL_KINDS = [
|
|
5
|
+
"any",
|
|
6
|
+
"class",
|
|
7
|
+
"interface",
|
|
8
|
+
"function",
|
|
9
|
+
"method",
|
|
10
|
+
"type",
|
|
11
|
+
"enum",
|
|
12
|
+
"constructor",
|
|
13
|
+
"annotation",
|
|
14
|
+
];
|
|
15
|
+
export const MATCH_MODES = ["exact", "fuzzy"];
|
|
16
|
+
export const CODE_TOOL_NAMES = [
|
|
17
|
+
"code.inspect_tree",
|
|
18
|
+
"code.list_endpoints",
|
|
19
|
+
"code.find_symbol",
|
|
20
|
+
"code.search_text",
|
|
21
|
+
"code.trace_symbol",
|
|
22
|
+
"code.trace_callers",
|
|
23
|
+
];
|
|
24
|
+
const sharedDefs = {
|
|
25
|
+
PublicLanguage: {
|
|
26
|
+
type: "string",
|
|
27
|
+
enum: [...PUBLIC_LANGUAGES],
|
|
28
|
+
},
|
|
29
|
+
PublicFramework: {
|
|
30
|
+
type: "string",
|
|
31
|
+
enum: [...PUBLIC_FRAMEWORKS],
|
|
32
|
+
},
|
|
33
|
+
PublicEndpointKind: {
|
|
34
|
+
type: "string",
|
|
35
|
+
enum: [...PUBLIC_ENDPOINT_KINDS],
|
|
36
|
+
},
|
|
37
|
+
PublicSymbolKind: {
|
|
38
|
+
type: "string",
|
|
39
|
+
enum: [...PUBLIC_SYMBOL_KINDS],
|
|
40
|
+
},
|
|
41
|
+
MatchMode: {
|
|
42
|
+
type: "string",
|
|
43
|
+
enum: [...MATCH_MODES],
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export const inspectTreeInputSchema = {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
path: {
|
|
50
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
51
|
+
default: null,
|
|
52
|
+
description: "Optional workspace-relative or absolute file/directory scope.",
|
|
53
|
+
},
|
|
54
|
+
max_depth: {
|
|
55
|
+
type: "integer",
|
|
56
|
+
default: 3,
|
|
57
|
+
minimum: 0,
|
|
58
|
+
maximum: 20,
|
|
59
|
+
description: "Maximum depth relative to the resolved scope root.",
|
|
60
|
+
},
|
|
61
|
+
extensions: {
|
|
62
|
+
anyOf: [
|
|
63
|
+
{
|
|
64
|
+
type: "array",
|
|
65
|
+
items: { type: "string" },
|
|
66
|
+
},
|
|
67
|
+
{ type: "null" },
|
|
68
|
+
],
|
|
69
|
+
default: null,
|
|
70
|
+
description: "Optional file extension filter such as ['.py', '.ts']. Directories remain visible.",
|
|
71
|
+
},
|
|
72
|
+
file_pattern: {
|
|
73
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
74
|
+
default: null,
|
|
75
|
+
description: "Optional filename glob such as '*.py'.",
|
|
76
|
+
},
|
|
77
|
+
include_stats: {
|
|
78
|
+
type: "boolean",
|
|
79
|
+
default: false,
|
|
80
|
+
description: "Include size, modified time, and symlink metadata.",
|
|
81
|
+
},
|
|
82
|
+
include_hidden: {
|
|
83
|
+
type: "boolean",
|
|
84
|
+
default: false,
|
|
85
|
+
description: "Include hidden entries except the hard ignore list.",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
required: [],
|
|
89
|
+
};
|
|
90
|
+
export const listEndpointsInputSchema = {
|
|
91
|
+
type: "object",
|
|
92
|
+
properties: {
|
|
93
|
+
path: {
|
|
94
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
95
|
+
default: null,
|
|
96
|
+
},
|
|
97
|
+
language: {
|
|
98
|
+
anyOf: [{ $ref: "#/$defs/PublicLanguage" }, { type: "null" }],
|
|
99
|
+
default: null,
|
|
100
|
+
},
|
|
101
|
+
framework: {
|
|
102
|
+
anyOf: [{ $ref: "#/$defs/PublicFramework" }, { type: "null" }],
|
|
103
|
+
default: null,
|
|
104
|
+
},
|
|
105
|
+
kind: {
|
|
106
|
+
allOf: [{ $ref: "#/$defs/PublicEndpointKind" }],
|
|
107
|
+
default: "any",
|
|
108
|
+
},
|
|
109
|
+
limit: {
|
|
110
|
+
type: "integer",
|
|
111
|
+
default: 50,
|
|
112
|
+
minimum: 1,
|
|
113
|
+
maximum: 200,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
required: [],
|
|
117
|
+
$defs: sharedDefs,
|
|
118
|
+
};
|
|
119
|
+
export const findSymbolInputSchema = {
|
|
120
|
+
type: "object",
|
|
121
|
+
properties: {
|
|
122
|
+
symbol: {
|
|
123
|
+
type: "string",
|
|
124
|
+
minLength: 1,
|
|
125
|
+
},
|
|
126
|
+
language: {
|
|
127
|
+
anyOf: [{ $ref: "#/$defs/PublicLanguage" }, { type: "null" }],
|
|
128
|
+
default: null,
|
|
129
|
+
},
|
|
130
|
+
framework: {
|
|
131
|
+
anyOf: [{ $ref: "#/$defs/PublicFramework" }, { type: "null" }],
|
|
132
|
+
default: null,
|
|
133
|
+
},
|
|
134
|
+
kind: {
|
|
135
|
+
allOf: [{ $ref: "#/$defs/PublicSymbolKind" }],
|
|
136
|
+
default: "any",
|
|
137
|
+
},
|
|
138
|
+
match: {
|
|
139
|
+
allOf: [{ $ref: "#/$defs/MatchMode" }],
|
|
140
|
+
default: "exact",
|
|
141
|
+
},
|
|
142
|
+
path: {
|
|
143
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
144
|
+
default: null,
|
|
145
|
+
},
|
|
146
|
+
limit: {
|
|
147
|
+
type: "integer",
|
|
148
|
+
default: 50,
|
|
149
|
+
minimum: 1,
|
|
150
|
+
maximum: 200,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
required: ["symbol"],
|
|
154
|
+
$defs: sharedDefs,
|
|
155
|
+
};
|
|
156
|
+
export const searchTextInputSchema = {
|
|
157
|
+
type: "object",
|
|
158
|
+
properties: {
|
|
159
|
+
query: {
|
|
160
|
+
type: "string",
|
|
161
|
+
minLength: 1,
|
|
162
|
+
},
|
|
163
|
+
path: {
|
|
164
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
165
|
+
default: null,
|
|
166
|
+
},
|
|
167
|
+
language: {
|
|
168
|
+
anyOf: [{ $ref: "#/$defs/PublicLanguage" }, { type: "null" }],
|
|
169
|
+
default: null,
|
|
170
|
+
},
|
|
171
|
+
framework: {
|
|
172
|
+
anyOf: [{ $ref: "#/$defs/PublicFramework" }, { type: "null" }],
|
|
173
|
+
default: null,
|
|
174
|
+
},
|
|
175
|
+
include: {
|
|
176
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
177
|
+
default: null,
|
|
178
|
+
},
|
|
179
|
+
regex: {
|
|
180
|
+
type: "boolean",
|
|
181
|
+
default: false,
|
|
182
|
+
},
|
|
183
|
+
context: {
|
|
184
|
+
type: "integer",
|
|
185
|
+
default: 1,
|
|
186
|
+
minimum: 0,
|
|
187
|
+
maximum: 10,
|
|
188
|
+
},
|
|
189
|
+
limit: {
|
|
190
|
+
type: "integer",
|
|
191
|
+
default: 50,
|
|
192
|
+
minimum: 1,
|
|
193
|
+
maximum: 200,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
required: ["query"],
|
|
197
|
+
$defs: sharedDefs,
|
|
198
|
+
};
|
|
199
|
+
export const traceSymbolInputSchema = {
|
|
200
|
+
type: "object",
|
|
201
|
+
properties: {
|
|
202
|
+
path: { type: "string", minLength: 1 },
|
|
203
|
+
symbol: { type: "string", minLength: 1 },
|
|
204
|
+
language: {
|
|
205
|
+
anyOf: [{ $ref: "#/$defs/PublicLanguage" }, { type: "null" }],
|
|
206
|
+
default: null,
|
|
207
|
+
},
|
|
208
|
+
framework: {
|
|
209
|
+
anyOf: [{ $ref: "#/$defs/PublicFramework" }, { type: "null" }],
|
|
210
|
+
default: null,
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
required: ["path", "symbol"],
|
|
214
|
+
$defs: sharedDefs,
|
|
215
|
+
};
|
|
216
|
+
export const traceCallersInputSchema = {
|
|
217
|
+
type: "object",
|
|
218
|
+
properties: {
|
|
219
|
+
path: { type: "string", minLength: 1 },
|
|
220
|
+
symbol: { type: "string", minLength: 1 },
|
|
221
|
+
language: {
|
|
222
|
+
anyOf: [{ $ref: "#/$defs/PublicLanguage" }, { type: "null" }],
|
|
223
|
+
default: null,
|
|
224
|
+
},
|
|
225
|
+
framework: {
|
|
226
|
+
anyOf: [{ $ref: "#/$defs/PublicFramework" }, { type: "null" }],
|
|
227
|
+
default: null,
|
|
228
|
+
},
|
|
229
|
+
recursive: {
|
|
230
|
+
type: "boolean",
|
|
231
|
+
default: false,
|
|
232
|
+
},
|
|
233
|
+
max_depth: {
|
|
234
|
+
anyOf: [
|
|
235
|
+
{
|
|
236
|
+
type: "integer",
|
|
237
|
+
minimum: 1,
|
|
238
|
+
maximum: 8,
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
type: "null"
|
|
242
|
+
}
|
|
243
|
+
],
|
|
244
|
+
default: null,
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
required: ["path", "symbol"],
|
|
248
|
+
$defs: sharedDefs,
|
|
249
|
+
};
|
|
250
|
+
export const codeToolSchemas = {
|
|
251
|
+
"code.inspect_tree": inspectTreeInputSchema,
|
|
252
|
+
"code.list_endpoints": listEndpointsInputSchema,
|
|
253
|
+
"code.find_symbol": findSymbolInputSchema,
|
|
254
|
+
"code.search_text": searchTextInputSchema,
|
|
255
|
+
"code.trace_symbol": traceSymbolInputSchema,
|
|
256
|
+
"code.trace_callers": traceCallersInputSchema,
|
|
257
|
+
};
|
|
258
|
+
export function normalizeInspectTreeInput(payload) {
|
|
259
|
+
const issues = [];
|
|
260
|
+
const path = normalizeOptionalString(payload.path, "path", issues);
|
|
261
|
+
const filePattern = normalizeOptionalString(payload.file_pattern, "file_pattern", issues);
|
|
262
|
+
const maxDepth = normalizeInteger(payload.max_depth, "max_depth", 3, 0, 20, issues);
|
|
263
|
+
const includeStats = normalizeBoolean(payload.include_stats, "include_stats", false, issues);
|
|
264
|
+
const includeHidden = normalizeBoolean(payload.include_hidden, "include_hidden", false, issues);
|
|
265
|
+
const extensions = normalizeExtensions(payload.extensions, issues);
|
|
266
|
+
if (issues.length > 0) {
|
|
267
|
+
return { ok: false, issues };
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
ok: true,
|
|
271
|
+
value: {
|
|
272
|
+
path,
|
|
273
|
+
max_depth: maxDepth,
|
|
274
|
+
extensions,
|
|
275
|
+
file_pattern: filePattern,
|
|
276
|
+
include_stats: includeStats,
|
|
277
|
+
include_hidden: includeHidden,
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
export function normalizeFindSymbolInput(payload) {
|
|
282
|
+
const issues = [];
|
|
283
|
+
const symbol = normalizeRequiredTrimmedString(payload.symbol, "symbol", issues);
|
|
284
|
+
const language = normalizeEnumValue(payload.language, "language", PUBLIC_LANGUAGES, issues);
|
|
285
|
+
const framework = normalizeEnumValue(payload.framework, "framework", PUBLIC_FRAMEWORKS, issues);
|
|
286
|
+
const kind = normalizeEnumValue(payload.kind, "kind", PUBLIC_SYMBOL_KINDS, issues) ?? "any";
|
|
287
|
+
const match = normalizeEnumValue(payload.match, "match", MATCH_MODES, issues) ?? "exact";
|
|
288
|
+
const scopedPath = normalizeOptionalString(payload.path, "path", issues);
|
|
289
|
+
const limit = normalizeInteger(payload.limit, "limit", 50, 1, 200, issues);
|
|
290
|
+
if (issues.length > 0) {
|
|
291
|
+
return { ok: false, issues };
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
ok: true,
|
|
295
|
+
value: {
|
|
296
|
+
symbol,
|
|
297
|
+
language,
|
|
298
|
+
framework,
|
|
299
|
+
kind,
|
|
300
|
+
match,
|
|
301
|
+
path: scopedPath,
|
|
302
|
+
limit,
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
export function normalizeListEndpointsInput(payload) {
|
|
307
|
+
const issues = [];
|
|
308
|
+
const scopedPath = normalizeOptionalString(payload.path, "path", issues);
|
|
309
|
+
const language = normalizeEnumValue(payload.language, "language", PUBLIC_LANGUAGES, issues);
|
|
310
|
+
const framework = normalizeEnumValue(payload.framework, "framework", PUBLIC_FRAMEWORKS, issues);
|
|
311
|
+
const kind = normalizeEnumValue(payload.kind, "kind", PUBLIC_ENDPOINT_KINDS, issues) ?? "any";
|
|
312
|
+
const limit = normalizeInteger(payload.limit, "limit", 50, 1, 200, issues);
|
|
313
|
+
if (issues.length > 0) {
|
|
314
|
+
return { ok: false, issues };
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
ok: true,
|
|
318
|
+
value: {
|
|
319
|
+
path: scopedPath,
|
|
320
|
+
language,
|
|
321
|
+
framework,
|
|
322
|
+
kind,
|
|
323
|
+
limit,
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
export function normalizeSearchTextInput(payload) {
|
|
328
|
+
const issues = [];
|
|
329
|
+
const query = normalizeRequiredTrimmedString(payload.query, "query", issues);
|
|
330
|
+
const scopedPath = normalizeOptionalString(payload.path, "path", issues);
|
|
331
|
+
const language = normalizeEnumValue(payload.language, "language", PUBLIC_LANGUAGES, issues);
|
|
332
|
+
const framework = normalizeEnumValue(payload.framework, "framework", PUBLIC_FRAMEWORKS, issues);
|
|
333
|
+
const include = normalizeOptionalString(payload.include, "include", issues);
|
|
334
|
+
const regex = normalizeBoolean(payload.regex, "regex", false, issues);
|
|
335
|
+
const context = normalizeInteger(payload.context, "context", 1, 0, 10, issues);
|
|
336
|
+
const limit = normalizeInteger(payload.limit, "limit", 50, 1, 200, issues);
|
|
337
|
+
if (issues.length > 0) {
|
|
338
|
+
return { ok: false, issues };
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
ok: true,
|
|
342
|
+
value: {
|
|
343
|
+
query,
|
|
344
|
+
path: scopedPath,
|
|
345
|
+
language,
|
|
346
|
+
framework,
|
|
347
|
+
include,
|
|
348
|
+
regex,
|
|
349
|
+
context,
|
|
350
|
+
limit,
|
|
351
|
+
},
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
export function normalizeTraceSymbolInput(payload) {
|
|
355
|
+
const issues = [];
|
|
356
|
+
const scopedPath = normalizeRequiredTrimmedString(payload.path, "path", issues);
|
|
357
|
+
const symbol = normalizeRequiredTrimmedString(payload.symbol, "symbol", issues);
|
|
358
|
+
const language = normalizeEnumValue(payload.language, "language", PUBLIC_LANGUAGES, issues);
|
|
359
|
+
const framework = normalizeEnumValue(payload.framework, "framework", PUBLIC_FRAMEWORKS, issues);
|
|
360
|
+
if (issues.length > 0) {
|
|
361
|
+
return { ok: false, issues };
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
ok: true,
|
|
365
|
+
value: {
|
|
366
|
+
path: scopedPath,
|
|
367
|
+
symbol,
|
|
368
|
+
language,
|
|
369
|
+
framework,
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
export function normalizeTraceCallersInput(payload) {
|
|
374
|
+
const issues = [];
|
|
375
|
+
const scopedPath = normalizeRequiredTrimmedString(payload.path, "path", issues);
|
|
376
|
+
const symbol = normalizeRequiredTrimmedString(payload.symbol, "symbol", issues);
|
|
377
|
+
const language = normalizeEnumValue(payload.language, "language", PUBLIC_LANGUAGES, issues);
|
|
378
|
+
const framework = normalizeEnumValue(payload.framework, "framework", PUBLIC_FRAMEWORKS, issues);
|
|
379
|
+
const recursive = normalizeBoolean(payload.recursive, "recursive", false, issues);
|
|
380
|
+
const maxDepth = normalizeNullableInteger(payload.max_depth, "max_depth", 1, 8, issues);
|
|
381
|
+
if (issues.length > 0) {
|
|
382
|
+
return { ok: false, issues };
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
ok: true,
|
|
386
|
+
value: {
|
|
387
|
+
path: scopedPath,
|
|
388
|
+
symbol,
|
|
389
|
+
language,
|
|
390
|
+
framework,
|
|
391
|
+
recursive,
|
|
392
|
+
max_depth: maxDepth,
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
function normalizeRequiredTrimmedString(value, field, issues) {
|
|
397
|
+
if (typeof value !== "string") {
|
|
398
|
+
issues.push({ field, message: "Input should be a valid string.", type: "string_type" });
|
|
399
|
+
return "";
|
|
400
|
+
}
|
|
401
|
+
const normalized = value.trim();
|
|
402
|
+
if (!normalized) {
|
|
403
|
+
issues.push({
|
|
404
|
+
field,
|
|
405
|
+
message: "String should have at least 1 character.",
|
|
406
|
+
type: "string_too_short",
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
return normalized;
|
|
410
|
+
}
|
|
411
|
+
function normalizeOptionalString(value, field, issues) {
|
|
412
|
+
if (value === undefined || value === null) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
if (typeof value !== "string") {
|
|
416
|
+
issues.push({ field, message: "Input should be a valid string.", type: "string_type" });
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
const normalized = value.trim();
|
|
420
|
+
return normalized.length > 0 ? normalized : null;
|
|
421
|
+
}
|
|
422
|
+
function normalizeInteger(value, field, fallback, min, max, issues) {
|
|
423
|
+
if (value === undefined || value === null) {
|
|
424
|
+
return fallback;
|
|
425
|
+
}
|
|
426
|
+
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
427
|
+
issues.push({ field, message: "Input should be a valid integer.", type: "int_type" });
|
|
428
|
+
return fallback;
|
|
429
|
+
}
|
|
430
|
+
if (value < min || value > max) {
|
|
431
|
+
issues.push({
|
|
432
|
+
field,
|
|
433
|
+
message: `Input should be greater than or equal to ${min} and less than or equal to ${max}.`,
|
|
434
|
+
type: "range_error",
|
|
435
|
+
});
|
|
436
|
+
return fallback;
|
|
437
|
+
}
|
|
438
|
+
return value;
|
|
439
|
+
}
|
|
440
|
+
function normalizeNullableInteger(value, field, min, max, issues) {
|
|
441
|
+
if (value === undefined || value === null) {
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
445
|
+
issues.push({ field, message: "Input should be a valid integer.", type: "int_type" });
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
448
|
+
if (value < min || value > max) {
|
|
449
|
+
issues.push({
|
|
450
|
+
field,
|
|
451
|
+
message: `Input should be greater than or equal to ${min} and less than or equal to ${max}.`,
|
|
452
|
+
type: "range_error",
|
|
453
|
+
});
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
return value;
|
|
457
|
+
}
|
|
458
|
+
function normalizeBoolean(value, field, fallback, issues) {
|
|
459
|
+
if (value === undefined || value === null) {
|
|
460
|
+
return fallback;
|
|
461
|
+
}
|
|
462
|
+
if (typeof value !== "boolean") {
|
|
463
|
+
issues.push({ field, message: "Input should be a valid boolean.", type: "bool_type" });
|
|
464
|
+
return fallback;
|
|
465
|
+
}
|
|
466
|
+
return value;
|
|
467
|
+
}
|
|
468
|
+
function normalizeEnumValue(value, field, allowed, issues) {
|
|
469
|
+
if (value === undefined || value === null) {
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
if (typeof value !== "string") {
|
|
473
|
+
issues.push({ field, message: "Input should be a valid string.", type: "string_type" });
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
if (!allowed.includes(value)) {
|
|
477
|
+
issues.push({
|
|
478
|
+
field,
|
|
479
|
+
message: `Input should be one of: ${allowed.join(", ")}.`,
|
|
480
|
+
type: "enum",
|
|
481
|
+
});
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
return value;
|
|
485
|
+
}
|
|
486
|
+
function normalizeExtensions(value, issues) {
|
|
487
|
+
if (value === undefined || value === null) {
|
|
488
|
+
return [];
|
|
489
|
+
}
|
|
490
|
+
if (!Array.isArray(value)) {
|
|
491
|
+
issues.push({
|
|
492
|
+
field: "extensions",
|
|
493
|
+
message: "extensions must be a list of strings",
|
|
494
|
+
type: "list_type",
|
|
495
|
+
});
|
|
496
|
+
return [];
|
|
497
|
+
}
|
|
498
|
+
const normalized = new Set();
|
|
499
|
+
for (const item of value) {
|
|
500
|
+
if (typeof item !== "string") {
|
|
501
|
+
issues.push({
|
|
502
|
+
field: "extensions",
|
|
503
|
+
message: "extensions must contain only strings",
|
|
504
|
+
type: "string_type",
|
|
505
|
+
});
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
const trimmed = item.trim().toLowerCase();
|
|
509
|
+
if (!trimmed) {
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
if (trimmed === ".") {
|
|
513
|
+
issues.push({
|
|
514
|
+
field: "extensions",
|
|
515
|
+
message: "extensions entries must not be '.'",
|
|
516
|
+
type: "value_error",
|
|
517
|
+
});
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
normalized.add(trimmed.startsWith(".") ? trimmed : `.${trimmed}`);
|
|
521
|
+
}
|
|
522
|
+
return [...normalized].sort();
|
|
523
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const RESPONSE_STATUSES: readonly ["ok", "partial", "error"];
|
|
2
|
+
export type ResponseStatus = (typeof RESPONSE_STATUSES)[number];
|
|
3
|
+
export declare const ERROR_CODES: readonly ["INVALID_INPUT", "PATH_OUTSIDE_WORKSPACE", "FILE_NOT_FOUND", "SYMBOL_NOT_FOUND", "UNSUPPORTED_FILE", "BACKEND_SCRIPT_NOT_FOUND", "BACKEND_DEPENDENCY_NOT_FOUND", "BACKEND_EXECUTION_FAILED", "BACKEND_INVALID_RESPONSE", "RESULT_TRUNCATED"];
|
|
4
|
+
export type ErrorCode = (typeof ERROR_CODES)[number];
|
|
5
|
+
export interface ErrorItem {
|
|
6
|
+
code: ErrorCode | string;
|
|
7
|
+
message: string;
|
|
8
|
+
retryable: boolean;
|
|
9
|
+
suggestion?: string | null;
|
|
10
|
+
target?: string | null;
|
|
11
|
+
details: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface ResponseMeta {
|
|
14
|
+
query: Record<string, unknown>;
|
|
15
|
+
resolvedPath: string | null;
|
|
16
|
+
truncated: boolean;
|
|
17
|
+
counts: Record<string, number | null>;
|
|
18
|
+
detection: Record<string, string | null>;
|
|
19
|
+
}
|
|
20
|
+
export interface ResponseEnvelope<TData> {
|
|
21
|
+
tool: string;
|
|
22
|
+
status: ResponseStatus;
|
|
23
|
+
summary: string;
|
|
24
|
+
data: TData;
|
|
25
|
+
errors: ErrorItem[];
|
|
26
|
+
meta: ResponseMeta;
|
|
27
|
+
}
|
|
28
|
+
export declare function createResponseMeta(overrides?: Partial<ResponseMeta>): ResponseMeta;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const RESPONSE_STATUSES = ["ok", "partial", "error"];
|
|
2
|
+
export const ERROR_CODES = [
|
|
3
|
+
"INVALID_INPUT",
|
|
4
|
+
"PATH_OUTSIDE_WORKSPACE",
|
|
5
|
+
"FILE_NOT_FOUND",
|
|
6
|
+
"SYMBOL_NOT_FOUND",
|
|
7
|
+
"UNSUPPORTED_FILE",
|
|
8
|
+
"BACKEND_SCRIPT_NOT_FOUND",
|
|
9
|
+
"BACKEND_DEPENDENCY_NOT_FOUND",
|
|
10
|
+
"BACKEND_EXECUTION_FAILED",
|
|
11
|
+
"BACKEND_INVALID_RESPONSE",
|
|
12
|
+
"RESULT_TRUNCATED",
|
|
13
|
+
];
|
|
14
|
+
export function createResponseMeta(overrides = {}) {
|
|
15
|
+
return {
|
|
16
|
+
query: {},
|
|
17
|
+
resolvedPath: null,
|
|
18
|
+
truncated: false,
|
|
19
|
+
counts: {},
|
|
20
|
+
detection: {},
|
|
21
|
+
...overrides,
|
|
22
|
+
};
|
|
23
|
+
}
|