@sashabogi/argus-mcp 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/cli.mjs +15 -10
- package/dist/cli.mjs.map +1 -1
- package/dist/mcp.mjs +281 -25
- package/dist/mcp.mjs.map +1 -1
- package/package.json +1 -1
package/dist/mcp.mjs
CHANGED
|
@@ -79,6 +79,10 @@ function validateConfig(config2) {
|
|
|
79
79
|
return errors;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
// src/core/enhanced-snapshot.ts
|
|
83
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
84
|
+
import { join as join3, dirname, extname as extname2 } from "path";
|
|
85
|
+
|
|
82
86
|
// src/core/snapshot.ts
|
|
83
87
|
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
84
88
|
import { join as join2, relative, extname } from "path";
|
|
@@ -203,8 +207,253 @@ function createSnapshot(projectPath, outputPath, options = {}) {
|
|
|
203
207
|
};
|
|
204
208
|
}
|
|
205
209
|
|
|
210
|
+
// src/core/enhanced-snapshot.ts
|
|
211
|
+
function parseImports(content, filePath) {
|
|
212
|
+
const imports = [];
|
|
213
|
+
const lines = content.split("\n");
|
|
214
|
+
const patterns = [
|
|
215
|
+
// import { a, b } from 'module'
|
|
216
|
+
/import\s+(?:type\s+)?{([^}]+)}\s+from\s+['"]([^'"]+)['"]/g,
|
|
217
|
+
// import * as name from 'module'
|
|
218
|
+
/import\s+\*\s+as\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g,
|
|
219
|
+
// import defaultExport from 'module'
|
|
220
|
+
/import\s+(?:type\s+)?(\w+)\s+from\s+['"]([^'"]+)['"]/g,
|
|
221
|
+
// import 'module' (side-effect)
|
|
222
|
+
/import\s+['"]([^'"]+)['"]/g,
|
|
223
|
+
// require('module')
|
|
224
|
+
/(?:const|let|var)\s+(?:{([^}]+)}|(\w+))\s*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/g
|
|
225
|
+
];
|
|
226
|
+
for (const line of lines) {
|
|
227
|
+
const trimmed = line.trim();
|
|
228
|
+
if (!trimmed.startsWith("import") && !trimmed.includes("require(")) continue;
|
|
229
|
+
let match = /import\s+(type\s+)?{([^}]+)}\s+from\s+['"]([^'"]+)['"]/.exec(trimmed);
|
|
230
|
+
if (match) {
|
|
231
|
+
const isType = !!match[1];
|
|
232
|
+
const symbols = match[2].split(",").map((s) => s.trim().split(/\s+as\s+/)[0].trim()).filter(Boolean);
|
|
233
|
+
const target = match[3];
|
|
234
|
+
imports.push({
|
|
235
|
+
source: filePath,
|
|
236
|
+
target,
|
|
237
|
+
symbols,
|
|
238
|
+
isDefault: false,
|
|
239
|
+
isType
|
|
240
|
+
});
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
match = /import\s+\*\s+as\s+(\w+)\s+from\s+['"]([^'"]+)['"]/.exec(trimmed);
|
|
244
|
+
if (match) {
|
|
245
|
+
imports.push({
|
|
246
|
+
source: filePath,
|
|
247
|
+
target: match[2],
|
|
248
|
+
symbols: ["*"],
|
|
249
|
+
isDefault: false,
|
|
250
|
+
isType: false
|
|
251
|
+
});
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
match = /import\s+(type\s+)?(\w+)\s+from\s+['"]([^'"]+)['"]/.exec(trimmed);
|
|
255
|
+
if (match && !trimmed.includes("{")) {
|
|
256
|
+
imports.push({
|
|
257
|
+
source: filePath,
|
|
258
|
+
target: match[3],
|
|
259
|
+
symbols: [match[2]],
|
|
260
|
+
isDefault: true,
|
|
261
|
+
isType: !!match[1]
|
|
262
|
+
});
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
match = /^import\s+['"]([^'"]+)['"]/.exec(trimmed);
|
|
266
|
+
if (match) {
|
|
267
|
+
imports.push({
|
|
268
|
+
source: filePath,
|
|
269
|
+
target: match[1],
|
|
270
|
+
symbols: [],
|
|
271
|
+
isDefault: false,
|
|
272
|
+
isType: false
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return imports;
|
|
277
|
+
}
|
|
278
|
+
function parseExports(content, filePath) {
|
|
279
|
+
const exports = [];
|
|
280
|
+
const lines = content.split("\n");
|
|
281
|
+
for (let i = 0; i < lines.length; i++) {
|
|
282
|
+
const line = lines[i];
|
|
283
|
+
const trimmed = line.trim();
|
|
284
|
+
let match = /export\s+(?:async\s+)?function\s+(\w+)\s*(\([^)]*\))/.exec(trimmed);
|
|
285
|
+
if (match) {
|
|
286
|
+
exports.push({
|
|
287
|
+
file: filePath,
|
|
288
|
+
symbol: match[1],
|
|
289
|
+
type: "function",
|
|
290
|
+
signature: `function ${match[1]}${match[2]}`,
|
|
291
|
+
line: i + 1
|
|
292
|
+
});
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
match = /export\s+class\s+(\w+)/.exec(trimmed);
|
|
296
|
+
if (match) {
|
|
297
|
+
exports.push({
|
|
298
|
+
file: filePath,
|
|
299
|
+
symbol: match[1],
|
|
300
|
+
type: "class",
|
|
301
|
+
line: i + 1
|
|
302
|
+
});
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
match = /export\s+(const|let|var)\s+(\w+)/.exec(trimmed);
|
|
306
|
+
if (match) {
|
|
307
|
+
exports.push({
|
|
308
|
+
file: filePath,
|
|
309
|
+
symbol: match[2],
|
|
310
|
+
type: match[1],
|
|
311
|
+
line: i + 1
|
|
312
|
+
});
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
match = /export\s+(type|interface)\s+(\w+)/.exec(trimmed);
|
|
316
|
+
if (match) {
|
|
317
|
+
exports.push({
|
|
318
|
+
file: filePath,
|
|
319
|
+
symbol: match[2],
|
|
320
|
+
type: match[1],
|
|
321
|
+
line: i + 1
|
|
322
|
+
});
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
match = /export\s+enum\s+(\w+)/.exec(trimmed);
|
|
326
|
+
if (match) {
|
|
327
|
+
exports.push({
|
|
328
|
+
file: filePath,
|
|
329
|
+
symbol: match[1],
|
|
330
|
+
type: "enum",
|
|
331
|
+
line: i + 1
|
|
332
|
+
});
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
if (/export\s+default/.test(trimmed)) {
|
|
336
|
+
match = /export\s+default\s+(?:function\s+)?(\w+)?/.exec(trimmed);
|
|
337
|
+
exports.push({
|
|
338
|
+
file: filePath,
|
|
339
|
+
symbol: match?.[1] || "default",
|
|
340
|
+
type: "default",
|
|
341
|
+
line: i + 1
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return exports;
|
|
346
|
+
}
|
|
347
|
+
function resolveImportPath(importPath, fromFile, projectFiles) {
|
|
348
|
+
if (!importPath.startsWith(".")) return void 0;
|
|
349
|
+
const fromDir = dirname(fromFile);
|
|
350
|
+
let resolved = join3(fromDir, importPath);
|
|
351
|
+
const extensions = [".ts", ".tsx", ".js", ".jsx", "", "/index.ts", "/index.tsx", "/index.js", "/index.jsx"];
|
|
352
|
+
for (const ext of extensions) {
|
|
353
|
+
const candidate = resolved + ext;
|
|
354
|
+
if (projectFiles.includes(candidate) || projectFiles.includes("./" + candidate)) {
|
|
355
|
+
return candidate;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return void 0;
|
|
359
|
+
}
|
|
360
|
+
function createEnhancedSnapshot(projectPath, outputPath, options = {}) {
|
|
361
|
+
const baseResult = createSnapshot(projectPath, outputPath, options);
|
|
362
|
+
const allImports = [];
|
|
363
|
+
const allExports = [];
|
|
364
|
+
const fileIndex = {};
|
|
365
|
+
const projectFiles = baseResult.files.map((f) => "./" + f);
|
|
366
|
+
for (const relPath of baseResult.files) {
|
|
367
|
+
const fullPath = join3(projectPath, relPath);
|
|
368
|
+
const ext = extname2(relPath).toLowerCase();
|
|
369
|
+
if (![".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
try {
|
|
373
|
+
const content = readFileSync3(fullPath, "utf-8");
|
|
374
|
+
const imports = parseImports(content, relPath);
|
|
375
|
+
const exports = parseExports(content, relPath);
|
|
376
|
+
for (const imp of imports) {
|
|
377
|
+
imp.resolved = resolveImportPath(imp.target, relPath, projectFiles);
|
|
378
|
+
}
|
|
379
|
+
allImports.push(...imports);
|
|
380
|
+
allExports.push(...exports);
|
|
381
|
+
fileIndex[relPath] = {
|
|
382
|
+
path: relPath,
|
|
383
|
+
imports,
|
|
384
|
+
exports,
|
|
385
|
+
size: content.length,
|
|
386
|
+
lines: content.split("\n").length
|
|
387
|
+
};
|
|
388
|
+
} catch {
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
const importGraph = {};
|
|
392
|
+
for (const imp of allImports) {
|
|
393
|
+
if (imp.resolved) {
|
|
394
|
+
if (!importGraph[imp.source]) importGraph[imp.source] = [];
|
|
395
|
+
if (!importGraph[imp.source].includes(imp.resolved)) {
|
|
396
|
+
importGraph[imp.source].push(imp.resolved);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const exportGraph = {};
|
|
401
|
+
for (const imp of allImports) {
|
|
402
|
+
if (imp.resolved) {
|
|
403
|
+
if (!exportGraph[imp.resolved]) exportGraph[imp.resolved] = [];
|
|
404
|
+
if (!exportGraph[imp.resolved].includes(imp.source)) {
|
|
405
|
+
exportGraph[imp.resolved].push(imp.source);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
const symbolIndex = {};
|
|
410
|
+
for (const exp of allExports) {
|
|
411
|
+
if (!symbolIndex[exp.symbol]) symbolIndex[exp.symbol] = [];
|
|
412
|
+
if (!symbolIndex[exp.symbol].includes(exp.file)) {
|
|
413
|
+
symbolIndex[exp.symbol].push(exp.file);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const metadataSection = `
|
|
417
|
+
|
|
418
|
+
================================================================================
|
|
419
|
+
METADATA: IMPORT GRAPH
|
|
420
|
+
================================================================================
|
|
421
|
+
${Object.entries(importGraph).map(([file, imports]) => `${file}:
|
|
422
|
+
${imports.map((i) => ` \u2192 ${i}`).join("\n")}`).join("\n\n")}
|
|
423
|
+
|
|
424
|
+
================================================================================
|
|
425
|
+
METADATA: EXPORT INDEX
|
|
426
|
+
================================================================================
|
|
427
|
+
${Object.entries(symbolIndex).map(([symbol, files]) => `${symbol}: ${files.join(", ")}`).join("\n")}
|
|
428
|
+
|
|
429
|
+
================================================================================
|
|
430
|
+
METADATA: FILE EXPORTS
|
|
431
|
+
================================================================================
|
|
432
|
+
${allExports.map((e) => `${e.file}:${e.line} - ${e.type} ${e.symbol}${e.signature ? ` ${e.signature}` : ""}`).join("\n")}
|
|
433
|
+
|
|
434
|
+
================================================================================
|
|
435
|
+
METADATA: WHO IMPORTS WHOM
|
|
436
|
+
================================================================================
|
|
437
|
+
${Object.entries(exportGraph).map(([file, importers]) => `${file} is imported by:
|
|
438
|
+
${importers.map((i) => ` \u2190 ${i}`).join("\n")}`).join("\n\n")}
|
|
439
|
+
`;
|
|
440
|
+
const existingContent = readFileSync3(outputPath, "utf-8");
|
|
441
|
+
writeFileSync3(outputPath, existingContent + metadataSection);
|
|
442
|
+
return {
|
|
443
|
+
...baseResult,
|
|
444
|
+
metadata: {
|
|
445
|
+
imports: allImports,
|
|
446
|
+
exports: allExports,
|
|
447
|
+
fileIndex,
|
|
448
|
+
importGraph,
|
|
449
|
+
exportGraph,
|
|
450
|
+
symbolIndex
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
206
455
|
// src/core/engine.ts
|
|
207
|
-
import { readFileSync as
|
|
456
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
208
457
|
|
|
209
458
|
// src/core/prompts.ts
|
|
210
459
|
var NUCLEUS_COMMANDS = `
|
|
@@ -562,7 +811,7 @@ async function analyze(provider2, documentPath, query, options = {}) {
|
|
|
562
811
|
onProgress
|
|
563
812
|
} = options;
|
|
564
813
|
const dynamicLimit = Math.min(getTurnLimit(query), maxTurns);
|
|
565
|
-
const content =
|
|
814
|
+
const content = readFileSync4(documentPath, "utf-8");
|
|
566
815
|
const fileCount = (content.match(/^FILE:/gm) || []).length;
|
|
567
816
|
const lineCount = content.split("\n").length;
|
|
568
817
|
const bindings = /* @__PURE__ */ new Map();
|
|
@@ -676,7 +925,7 @@ ${truncatedResult}`;
|
|
|
676
925
|
};
|
|
677
926
|
}
|
|
678
927
|
function searchDocument(documentPath, pattern, options = {}) {
|
|
679
|
-
const content =
|
|
928
|
+
const content = readFileSync4(documentPath, "utf-8");
|
|
680
929
|
const flags = options.caseInsensitive ? "gi" : "g";
|
|
681
930
|
const regex = new RegExp(pattern, flags);
|
|
682
931
|
const lines = content.split("\n");
|
|
@@ -960,9 +1209,9 @@ function createProviderByType(type, config2) {
|
|
|
960
1209
|
}
|
|
961
1210
|
|
|
962
1211
|
// src/mcp.ts
|
|
963
|
-
import { existsSync as
|
|
1212
|
+
import { existsSync as existsSync4, statSync as statSync2, mkdtempSync, unlinkSync, readFileSync as readFileSync5 } from "fs";
|
|
964
1213
|
import { tmpdir } from "os";
|
|
965
|
-
import { join as
|
|
1214
|
+
import { join as join4, resolve } from "path";
|
|
966
1215
|
var TOOLS = [
|
|
967
1216
|
{
|
|
968
1217
|
name: "find_importers",
|
|
@@ -973,7 +1222,7 @@ Use when you need to know:
|
|
|
973
1222
|
- Who uses this function/component?
|
|
974
1223
|
- Impact analysis before refactoring
|
|
975
1224
|
|
|
976
|
-
|
|
1225
|
+
Snapshots are enhanced by default and include this metadata.`,
|
|
977
1226
|
inputSchema: {
|
|
978
1227
|
type: "object",
|
|
979
1228
|
properties: {
|
|
@@ -998,7 +1247,7 @@ Use when you need to know:
|
|
|
998
1247
|
- Which file exports this component?
|
|
999
1248
|
- Find the source of a type
|
|
1000
1249
|
|
|
1001
|
-
|
|
1250
|
+
Snapshots are enhanced by default and include this metadata.`,
|
|
1002
1251
|
inputSchema: {
|
|
1003
1252
|
type: "object",
|
|
1004
1253
|
properties: {
|
|
@@ -1023,7 +1272,7 @@ Use when you need to understand:
|
|
|
1023
1272
|
- What modules need to be loaded?
|
|
1024
1273
|
- Trace the dependency chain
|
|
1025
1274
|
|
|
1026
|
-
|
|
1275
|
+
Snapshots are enhanced by default and include this metadata.`,
|
|
1027
1276
|
inputSchema: {
|
|
1028
1277
|
type: "object",
|
|
1029
1278
|
properties: {
|
|
@@ -1112,9 +1361,10 @@ Returns matching lines with line numbers - much faster than grep across many fil
|
|
|
1112
1361
|
},
|
|
1113
1362
|
{
|
|
1114
1363
|
name: "create_snapshot",
|
|
1115
|
-
description: `Create
|
|
1364
|
+
description: `Create an enhanced codebase snapshot for analysis. Run this ONCE per project, then use the snapshot for all queries.
|
|
1116
1365
|
|
|
1117
1366
|
The snapshot compiles all source files into a single optimized file that survives context compaction.
|
|
1367
|
+
Includes structural metadata (import graph, exports index) for zero-cost dependency queries.
|
|
1118
1368
|
Store at .argus/snapshot.txt so other tools can find it.
|
|
1119
1369
|
|
|
1120
1370
|
Run this when:
|
|
@@ -1202,10 +1452,10 @@ async function handleToolCall(name, args) {
|
|
|
1202
1452
|
case "find_importers": {
|
|
1203
1453
|
const path = resolve(args.path);
|
|
1204
1454
|
const target = args.target;
|
|
1205
|
-
if (!
|
|
1455
|
+
if (!existsSync4(path)) {
|
|
1206
1456
|
throw new Error(`File not found: ${path}`);
|
|
1207
1457
|
}
|
|
1208
|
-
const content =
|
|
1458
|
+
const content = readFileSync5(path, "utf-8");
|
|
1209
1459
|
const metadata = parseSnapshotMetadata(content);
|
|
1210
1460
|
if (!metadata) {
|
|
1211
1461
|
throw new Error("This snapshot does not have metadata. Create with: argus snapshot --enhanced");
|
|
@@ -1236,10 +1486,10 @@ async function handleToolCall(name, args) {
|
|
|
1236
1486
|
case "find_symbol": {
|
|
1237
1487
|
const path = resolve(args.path);
|
|
1238
1488
|
const symbol = args.symbol;
|
|
1239
|
-
if (!
|
|
1489
|
+
if (!existsSync4(path)) {
|
|
1240
1490
|
throw new Error(`File not found: ${path}`);
|
|
1241
1491
|
}
|
|
1242
|
-
const content =
|
|
1492
|
+
const content = readFileSync5(path, "utf-8");
|
|
1243
1493
|
const metadata = parseSnapshotMetadata(content);
|
|
1244
1494
|
if (!metadata) {
|
|
1245
1495
|
throw new Error("This snapshot does not have metadata. Create with: argus snapshot --enhanced");
|
|
@@ -1256,10 +1506,10 @@ async function handleToolCall(name, args) {
|
|
|
1256
1506
|
case "get_file_deps": {
|
|
1257
1507
|
const path = resolve(args.path);
|
|
1258
1508
|
const file = args.file;
|
|
1259
|
-
if (!
|
|
1509
|
+
if (!existsSync4(path)) {
|
|
1260
1510
|
throw new Error(`File not found: ${path}`);
|
|
1261
1511
|
}
|
|
1262
|
-
const content =
|
|
1512
|
+
const content = readFileSync5(path, "utf-8");
|
|
1263
1513
|
const metadata = parseSnapshotMetadata(content);
|
|
1264
1514
|
if (!metadata) {
|
|
1265
1515
|
throw new Error("This snapshot does not have metadata. Create with: argus snapshot --enhanced");
|
|
@@ -1286,16 +1536,16 @@ async function handleToolCall(name, args) {
|
|
|
1286
1536
|
const path = resolve(args.path);
|
|
1287
1537
|
const query = args.query;
|
|
1288
1538
|
const maxTurns = args.maxTurns || 15;
|
|
1289
|
-
if (!
|
|
1539
|
+
if (!existsSync4(path)) {
|
|
1290
1540
|
throw new Error(`Path not found: ${path}`);
|
|
1291
1541
|
}
|
|
1292
1542
|
let snapshotPath = path;
|
|
1293
1543
|
let tempSnapshot = false;
|
|
1294
1544
|
const stats = statSync2(path);
|
|
1295
1545
|
if (stats.isDirectory()) {
|
|
1296
|
-
const tempDir = mkdtempSync(
|
|
1297
|
-
snapshotPath =
|
|
1298
|
-
|
|
1546
|
+
const tempDir = mkdtempSync(join4(tmpdir(), "argus-"));
|
|
1547
|
+
snapshotPath = join4(tempDir, "snapshot.txt");
|
|
1548
|
+
createEnhancedSnapshot(path, snapshotPath, {
|
|
1299
1549
|
extensions: config.defaults.snapshotExtensions,
|
|
1300
1550
|
excludePatterns: config.defaults.excludePatterns
|
|
1301
1551
|
});
|
|
@@ -1310,7 +1560,7 @@ async function handleToolCall(name, args) {
|
|
|
1310
1560
|
commands: result.commands
|
|
1311
1561
|
};
|
|
1312
1562
|
} finally {
|
|
1313
|
-
if (tempSnapshot &&
|
|
1563
|
+
if (tempSnapshot && existsSync4(snapshotPath)) {
|
|
1314
1564
|
unlinkSync(snapshotPath);
|
|
1315
1565
|
}
|
|
1316
1566
|
}
|
|
@@ -1320,7 +1570,7 @@ async function handleToolCall(name, args) {
|
|
|
1320
1570
|
const pattern = args.pattern;
|
|
1321
1571
|
const caseInsensitive = args.caseInsensitive || false;
|
|
1322
1572
|
const maxResults = args.maxResults || 50;
|
|
1323
|
-
if (!
|
|
1573
|
+
if (!existsSync4(path)) {
|
|
1324
1574
|
throw new Error(`File not found: ${path}`);
|
|
1325
1575
|
}
|
|
1326
1576
|
const matches = searchDocument(path, pattern, { caseInsensitive, maxResults });
|
|
@@ -1335,12 +1585,12 @@ async function handleToolCall(name, args) {
|
|
|
1335
1585
|
}
|
|
1336
1586
|
case "create_snapshot": {
|
|
1337
1587
|
const path = resolve(args.path);
|
|
1338
|
-
const outputPath = args.outputPath ? resolve(args.outputPath) :
|
|
1588
|
+
const outputPath = args.outputPath ? resolve(args.outputPath) : join4(tmpdir(), `argus-snapshot-${Date.now()}.txt`);
|
|
1339
1589
|
const extensions = args.extensions || config.defaults.snapshotExtensions;
|
|
1340
|
-
if (!
|
|
1590
|
+
if (!existsSync4(path)) {
|
|
1341
1591
|
throw new Error(`Path not found: ${path}`);
|
|
1342
1592
|
}
|
|
1343
|
-
const result =
|
|
1593
|
+
const result = createEnhancedSnapshot(path, outputPath, {
|
|
1344
1594
|
extensions,
|
|
1345
1595
|
excludePatterns: config.defaults.excludePatterns
|
|
1346
1596
|
});
|
|
@@ -1348,7 +1598,13 @@ async function handleToolCall(name, args) {
|
|
|
1348
1598
|
outputPath: result.outputPath,
|
|
1349
1599
|
fileCount: result.fileCount,
|
|
1350
1600
|
totalLines: result.totalLines,
|
|
1351
|
-
totalSize: result.totalSize
|
|
1601
|
+
totalSize: result.totalSize,
|
|
1602
|
+
enhanced: true,
|
|
1603
|
+
metadata: "metadata" in result ? {
|
|
1604
|
+
imports: result.metadata.imports.length,
|
|
1605
|
+
exports: result.metadata.exports.length,
|
|
1606
|
+
symbols: Object.keys(result.metadata.symbolIndex).length
|
|
1607
|
+
} : void 0
|
|
1352
1608
|
};
|
|
1353
1609
|
}
|
|
1354
1610
|
default:
|