@aiready/ast-mcp-server 0.7.0 → 0.8.1
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/index.cjs +85 -157
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +85 -155
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -587,9 +587,9 @@ var TypeScriptAdapter = class {
|
|
|
587
587
|
await symbolIndex.buildIndex(searchPath);
|
|
588
588
|
}
|
|
589
589
|
}
|
|
590
|
-
async resolveDefinition(symbolName,
|
|
591
|
-
validateWorkspacePath(
|
|
592
|
-
await this.ensureIndex(
|
|
590
|
+
async resolveDefinition(symbolName, path6) {
|
|
591
|
+
validateWorkspacePath(path6);
|
|
592
|
+
await this.ensureIndex(path6);
|
|
593
593
|
const indexHits = symbolIndex.lookup(symbolName);
|
|
594
594
|
if (indexHits.length > 0) {
|
|
595
595
|
const results = [];
|
|
@@ -617,33 +617,33 @@ var TypeScriptAdapter = class {
|
|
|
617
617
|
}
|
|
618
618
|
return results;
|
|
619
619
|
}
|
|
620
|
-
if (import_fs3.default.statSync(
|
|
620
|
+
if (import_fs3.default.statSync(path6).isDirectory()) {
|
|
621
621
|
return [];
|
|
622
622
|
}
|
|
623
|
-
const tsconfig = await projectManager.findNearestTsConfig(
|
|
623
|
+
const tsconfig = await projectManager.findNearestTsConfig(path6);
|
|
624
624
|
if (!tsconfig) return [];
|
|
625
625
|
try {
|
|
626
626
|
const result = await this.pool.execute(
|
|
627
627
|
"resolve_definition",
|
|
628
628
|
{
|
|
629
629
|
tsconfig,
|
|
630
|
-
file:
|
|
630
|
+
file: path6,
|
|
631
631
|
symbol: symbolName
|
|
632
632
|
}
|
|
633
633
|
);
|
|
634
634
|
return result;
|
|
635
635
|
} catch {
|
|
636
636
|
const project = projectManager.ensureProject(tsconfig);
|
|
637
|
-
const sourceFile = project.addSourceFileAtPathIfExists(
|
|
637
|
+
const sourceFile = project.addSourceFileAtPathIfExists(path6);
|
|
638
638
|
if (!sourceFile) return [];
|
|
639
639
|
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
640
640
|
if (!exported) return [];
|
|
641
641
|
return exported.map((decl) => this.mapToDefinitionLocation(decl));
|
|
642
642
|
}
|
|
643
643
|
}
|
|
644
|
-
async findReferences(symbolName,
|
|
645
|
-
validateWorkspacePath(
|
|
646
|
-
await this.ensureIndex(
|
|
644
|
+
async findReferences(symbolName, path6, limit = 50, offset = 0) {
|
|
645
|
+
validateWorkspacePath(path6);
|
|
646
|
+
await this.ensureIndex(path6);
|
|
647
647
|
const hits = symbolIndex.lookup(symbolName);
|
|
648
648
|
if (hits.length === 0) return { references: [], total_count: 0 };
|
|
649
649
|
const hit = hits[0];
|
|
@@ -656,7 +656,7 @@ var TypeScriptAdapter = class {
|
|
|
656
656
|
const { searchCode: searchCode2 } = await Promise.resolve().then(() => (init_search_code(), search_code_exports));
|
|
657
657
|
const searchResults = await searchCode2(
|
|
658
658
|
symbolName,
|
|
659
|
-
|
|
659
|
+
path6,
|
|
660
660
|
"**/*.{ts,tsx,js,jsx}",
|
|
661
661
|
1e3,
|
|
662
662
|
false
|
|
@@ -693,9 +693,9 @@ var TypeScriptAdapter = class {
|
|
|
693
693
|
total_count: unique.length
|
|
694
694
|
};
|
|
695
695
|
}
|
|
696
|
-
async findImplementations(symbolName,
|
|
697
|
-
validateWorkspacePath(
|
|
698
|
-
await this.ensureIndex(
|
|
696
|
+
async findImplementations(symbolName, path6, limit = 50, offset = 0) {
|
|
697
|
+
validateWorkspacePath(path6);
|
|
698
|
+
await this.ensureIndex(path6);
|
|
699
699
|
const hits = symbolIndex.lookup(symbolName);
|
|
700
700
|
if (hits.length === 0) return { implementations: [], total_count: 0 };
|
|
701
701
|
const hit = hits[0];
|
|
@@ -726,7 +726,7 @@ var TypeScriptAdapter = class {
|
|
|
726
726
|
const { searchCode: searchCode2 } = await Promise.resolve().then(() => (init_search_code(), search_code_exports));
|
|
727
727
|
const searchResults = await searchCode2(
|
|
728
728
|
symbolName,
|
|
729
|
-
|
|
729
|
+
path6,
|
|
730
730
|
"**/*.{ts,tsx,js,jsx}",
|
|
731
731
|
1e3,
|
|
732
732
|
false
|
|
@@ -905,33 +905,33 @@ var TypeScriptAdapter = class {
|
|
|
905
905
|
var typescriptAdapter = new TypeScriptAdapter();
|
|
906
906
|
|
|
907
907
|
// src/utils/tool-utils.ts
|
|
908
|
-
async function wrapAdapterCall(methodName, symbol,
|
|
908
|
+
async function wrapAdapterCall(methodName, symbol, path6, ...args) {
|
|
909
909
|
const method = typescriptAdapter[methodName];
|
|
910
|
-
return await method.apply(typescriptAdapter, [symbol,
|
|
910
|
+
return await method.apply(typescriptAdapter, [symbol, path6, ...args]);
|
|
911
911
|
}
|
|
912
912
|
|
|
913
913
|
// src/tools/resolve-definition.ts
|
|
914
|
-
async function resolveDefinition(symbol,
|
|
914
|
+
async function resolveDefinition(symbol, path6) {
|
|
915
915
|
return await wrapAdapterCall(
|
|
916
916
|
"resolveDefinition",
|
|
917
917
|
symbol,
|
|
918
|
-
|
|
918
|
+
path6
|
|
919
919
|
);
|
|
920
920
|
}
|
|
921
921
|
|
|
922
922
|
// src/tools/find-references.ts
|
|
923
923
|
init_cjs_shims();
|
|
924
|
-
async function findReferences(symbol,
|
|
925
|
-
return await wrapAdapterCall("findReferences", symbol,
|
|
924
|
+
async function findReferences(symbol, path6, limit = 50, offset = 0) {
|
|
925
|
+
return await wrapAdapterCall("findReferences", symbol, path6, limit, offset);
|
|
926
926
|
}
|
|
927
927
|
|
|
928
928
|
// src/tools/find-implementations.ts
|
|
929
929
|
init_cjs_shims();
|
|
930
|
-
async function findImplementations(symbol,
|
|
930
|
+
async function findImplementations(symbol, path6, limit = 50, offset = 0) {
|
|
931
931
|
return await wrapAdapterCall(
|
|
932
932
|
"findImplementations",
|
|
933
933
|
symbol,
|
|
934
|
-
|
|
934
|
+
path6,
|
|
935
935
|
limit,
|
|
936
936
|
offset
|
|
937
937
|
);
|
|
@@ -978,8 +978,8 @@ async function getSymbolDocs(symbol, filePath) {
|
|
|
978
978
|
|
|
979
979
|
// src/tools/build-symbol-index.ts
|
|
980
980
|
init_cjs_shims();
|
|
981
|
-
async function buildSymbolIndex(
|
|
982
|
-
return await symbolIndex.buildIndex(
|
|
981
|
+
async function buildSymbolIndex(path6) {
|
|
982
|
+
return await symbolIndex.buildIndex(path6);
|
|
983
983
|
}
|
|
984
984
|
|
|
985
985
|
// src/tools/call-hierarchy.ts
|
|
@@ -1139,117 +1139,6 @@ async function checkSymbolGrounding(symbol, filePath) {
|
|
|
1139
1139
|
};
|
|
1140
1140
|
}
|
|
1141
1141
|
|
|
1142
|
-
// src/tools/codebase-audit.ts
|
|
1143
|
-
init_cjs_shims();
|
|
1144
|
-
var import_child_process2 = require("child_process");
|
|
1145
|
-
var import_util2 = require("util");
|
|
1146
|
-
var import_ripgrep2 = require("@vscode/ripgrep");
|
|
1147
|
-
var fs4 = __toESM(require("fs"), 1);
|
|
1148
|
-
var path6 = __toESM(require("path"), 1);
|
|
1149
|
-
init_security();
|
|
1150
|
-
var execFileAsync2 = (0, import_util2.promisify)(import_child_process2.execFile);
|
|
1151
|
-
async function codebaseAudit(rootDir) {
|
|
1152
|
-
const safePath = validateWorkspacePath(rootDir);
|
|
1153
|
-
let debtMarkers = 0;
|
|
1154
|
-
try {
|
|
1155
|
-
const { stdout } = await execFileAsync2(import_ripgrep2.rgPath, [
|
|
1156
|
-
"--count-matches",
|
|
1157
|
-
"--fixed-strings",
|
|
1158
|
-
"-e",
|
|
1159
|
-
"TODO",
|
|
1160
|
-
"-e",
|
|
1161
|
-
"FIXME",
|
|
1162
|
-
"--glob",
|
|
1163
|
-
"!**/node_modules/**",
|
|
1164
|
-
"--glob",
|
|
1165
|
-
"!**/.git/**",
|
|
1166
|
-
"--glob",
|
|
1167
|
-
"!**/dist/**",
|
|
1168
|
-
safePath
|
|
1169
|
-
]);
|
|
1170
|
-
const lines = stdout.split("\n").filter(Boolean);
|
|
1171
|
-
for (const line of lines) {
|
|
1172
|
-
const match = line.match(/:(\d+)$/);
|
|
1173
|
-
if (match) {
|
|
1174
|
-
debtMarkers += parseInt(match[1], 10);
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
} catch (error) {
|
|
1178
|
-
if (error.code !== 1) {
|
|
1179
|
-
console.error("[Audit] Error counting debt markers:", error);
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
const emptyDirs = [];
|
|
1183
|
-
const scanEmpty = (dir) => {
|
|
1184
|
-
const files = fs4.readdirSync(dir);
|
|
1185
|
-
if (files.length === 0) {
|
|
1186
|
-
emptyDirs.push(path6.relative(safePath, dir));
|
|
1187
|
-
return;
|
|
1188
|
-
}
|
|
1189
|
-
for (const file of files) {
|
|
1190
|
-
const fullPath = path6.join(dir, file);
|
|
1191
|
-
if (fs4.statSync(fullPath).isDirectory()) {
|
|
1192
|
-
if (["node_modules", ".git", "dist", ".sst", ".turbo", ".next"].includes(
|
|
1193
|
-
file
|
|
1194
|
-
))
|
|
1195
|
-
continue;
|
|
1196
|
-
scanEmpty(fullPath);
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
};
|
|
1200
|
-
scanEmpty(safePath);
|
|
1201
|
-
const orphanedFiles = [];
|
|
1202
|
-
const allFiles = [];
|
|
1203
|
-
const collectFiles = (dir) => {
|
|
1204
|
-
const files = fs4.readdirSync(dir);
|
|
1205
|
-
for (const file of files) {
|
|
1206
|
-
const fullPath = path6.join(dir, file);
|
|
1207
|
-
if (fs4.statSync(fullPath).isDirectory()) {
|
|
1208
|
-
if (["node_modules", ".git", "dist", ".sst", ".turbo", ".next"].includes(
|
|
1209
|
-
file
|
|
1210
|
-
))
|
|
1211
|
-
continue;
|
|
1212
|
-
collectFiles(fullPath);
|
|
1213
|
-
} else if (file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".tsx") || file.endsWith(".jsx")) {
|
|
1214
|
-
allFiles.push(fullPath);
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
};
|
|
1218
|
-
collectFiles(safePath);
|
|
1219
|
-
for (const file of allFiles) {
|
|
1220
|
-
const base = path6.basename(file, path6.extname(file));
|
|
1221
|
-
if (base === "index" || base.endsWith(".test") || base.endsWith(".spec") || base === "sst.config")
|
|
1222
|
-
continue;
|
|
1223
|
-
let referenced = false;
|
|
1224
|
-
try {
|
|
1225
|
-
const { status } = await execFileAsync2(import_ripgrep2.rgPath, [
|
|
1226
|
-
"--quiet",
|
|
1227
|
-
"--fixed-strings",
|
|
1228
|
-
"--word-regexp",
|
|
1229
|
-
"--glob",
|
|
1230
|
-
`!${path6.relative(safePath, file)}`,
|
|
1231
|
-
"--glob",
|
|
1232
|
-
"!**/node_modules/**",
|
|
1233
|
-
"--glob",
|
|
1234
|
-
"!**/.git/**",
|
|
1235
|
-
base,
|
|
1236
|
-
safePath
|
|
1237
|
-
]);
|
|
1238
|
-
if (status === 0) referenced = true;
|
|
1239
|
-
} catch (e) {
|
|
1240
|
-
if (e.code === 0) referenced = true;
|
|
1241
|
-
}
|
|
1242
|
-
if (!referenced) {
|
|
1243
|
-
orphanedFiles.push(path6.relative(safePath, file));
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
return {
|
|
1247
|
-
debtMarkers,
|
|
1248
|
-
emptyDirs,
|
|
1249
|
-
orphanedFiles
|
|
1250
|
-
};
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
1142
|
// src/index.ts
|
|
1254
1143
|
var import_types2 = require("@modelcontextprotocol/sdk/types.js");
|
|
1255
1144
|
var ASTExplorerServer = class {
|
|
@@ -1437,8 +1326,8 @@ var ASTExplorerServer = class {
|
|
|
1437
1326
|
}
|
|
1438
1327
|
},
|
|
1439
1328
|
{
|
|
1440
|
-
name: "
|
|
1441
|
-
description: "Performs a codebase-level
|
|
1329
|
+
name: "hygiene_audit",
|
|
1330
|
+
description: "Performs a codebase-level hygiene check for technical debt (TODOs) and waste (empty dirs, orphans).",
|
|
1442
1331
|
inputSchema: {
|
|
1443
1332
|
type: "object",
|
|
1444
1333
|
properties: {
|
|
@@ -1449,6 +1338,28 @@ var ASTExplorerServer = class {
|
|
|
1449
1338
|
},
|
|
1450
1339
|
required: ["path"]
|
|
1451
1340
|
}
|
|
1341
|
+
},
|
|
1342
|
+
{
|
|
1343
|
+
name: "metabolism_audit",
|
|
1344
|
+
description: "Alias for hygiene_audit (Serverless Claw compat).",
|
|
1345
|
+
inputSchema: {
|
|
1346
|
+
type: "object",
|
|
1347
|
+
properties: {
|
|
1348
|
+
path: { type: "string" }
|
|
1349
|
+
},
|
|
1350
|
+
required: ["path"]
|
|
1351
|
+
}
|
|
1352
|
+
},
|
|
1353
|
+
{
|
|
1354
|
+
name: "codebase_audit",
|
|
1355
|
+
description: "Alias for hygiene_audit.",
|
|
1356
|
+
inputSchema: {
|
|
1357
|
+
type: "object",
|
|
1358
|
+
properties: {
|
|
1359
|
+
path: { type: "string" }
|
|
1360
|
+
},
|
|
1361
|
+
required: ["path"]
|
|
1362
|
+
}
|
|
1452
1363
|
}
|
|
1453
1364
|
]
|
|
1454
1365
|
};
|
|
@@ -1458,8 +1369,8 @@ var ASTExplorerServer = class {
|
|
|
1458
1369
|
try {
|
|
1459
1370
|
switch (name) {
|
|
1460
1371
|
case "resolve_definition": {
|
|
1461
|
-
const { symbol, path:
|
|
1462
|
-
const results = await resolveDefinition(symbol,
|
|
1372
|
+
const { symbol, path: path6 } = ResolveDefinitionSchema.parse(args);
|
|
1373
|
+
const results = await resolveDefinition(symbol, path6);
|
|
1463
1374
|
return {
|
|
1464
1375
|
content: [
|
|
1465
1376
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -1467,8 +1378,8 @@ var ASTExplorerServer = class {
|
|
|
1467
1378
|
};
|
|
1468
1379
|
}
|
|
1469
1380
|
case "find_references": {
|
|
1470
|
-
const { symbol, path:
|
|
1471
|
-
const results = await findReferences(symbol,
|
|
1381
|
+
const { symbol, path: path6, limit, offset } = FindReferencesSchema.parse(args);
|
|
1382
|
+
const results = await findReferences(symbol, path6, limit, offset);
|
|
1472
1383
|
return {
|
|
1473
1384
|
content: [
|
|
1474
1385
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -1476,10 +1387,10 @@ var ASTExplorerServer = class {
|
|
|
1476
1387
|
};
|
|
1477
1388
|
}
|
|
1478
1389
|
case "find_implementations": {
|
|
1479
|
-
const { symbol, path:
|
|
1390
|
+
const { symbol, path: path6, limit, offset } = FindImplementationsSchema.parse(args);
|
|
1480
1391
|
const results = await findImplementations(
|
|
1481
1392
|
symbol,
|
|
1482
|
-
|
|
1393
|
+
path6,
|
|
1483
1394
|
limit,
|
|
1484
1395
|
offset
|
|
1485
1396
|
);
|
|
@@ -1499,10 +1410,10 @@ var ASTExplorerServer = class {
|
|
|
1499
1410
|
};
|
|
1500
1411
|
}
|
|
1501
1412
|
case "search_code": {
|
|
1502
|
-
const { pattern, path:
|
|
1413
|
+
const { pattern, path: path6, filePattern, limit, offset, regex } = SearchCodeSchema.parse(args);
|
|
1503
1414
|
const results = await searchCode(
|
|
1504
1415
|
pattern,
|
|
1505
|
-
|
|
1416
|
+
path6,
|
|
1506
1417
|
filePattern,
|
|
1507
1418
|
limit,
|
|
1508
1419
|
regex,
|
|
@@ -1515,22 +1426,22 @@ var ASTExplorerServer = class {
|
|
|
1515
1426
|
};
|
|
1516
1427
|
}
|
|
1517
1428
|
case "get_symbol_docs": {
|
|
1518
|
-
const { symbol, path:
|
|
1519
|
-
const docs = await getSymbolDocs(symbol,
|
|
1429
|
+
const { symbol, path: path6 } = GetSymbolDocsSchema.parse(args);
|
|
1430
|
+
const docs = await getSymbolDocs(symbol, path6);
|
|
1520
1431
|
return {
|
|
1521
1432
|
content: [{ type: "text", text: JSON.stringify(docs, null, 2) }]
|
|
1522
1433
|
};
|
|
1523
1434
|
}
|
|
1524
1435
|
case "build_symbol_index": {
|
|
1525
|
-
const { path:
|
|
1526
|
-
const stats = await buildSymbolIndex(
|
|
1436
|
+
const { path: path6 } = BuildSymbolIndexSchema.parse(args);
|
|
1437
|
+
const stats = await buildSymbolIndex(path6);
|
|
1527
1438
|
return {
|
|
1528
1439
|
content: [{ type: "text", text: JSON.stringify(stats, null, 2) }]
|
|
1529
1440
|
};
|
|
1530
1441
|
}
|
|
1531
1442
|
case "get_call_hierarchy": {
|
|
1532
|
-
const { symbol, path:
|
|
1533
|
-
const hierarchy = await getCallHierarchy(symbol,
|
|
1443
|
+
const { symbol, path: path6, direction } = GetCallHierarchySchema.parse(args);
|
|
1444
|
+
const hierarchy = await getCallHierarchy(symbol, path6, direction);
|
|
1534
1445
|
return {
|
|
1535
1446
|
content: [
|
|
1536
1447
|
{ type: "text", text: JSON.stringify(hierarchy, null, 2) }
|
|
@@ -1538,21 +1449,38 @@ var ASTExplorerServer = class {
|
|
|
1538
1449
|
};
|
|
1539
1450
|
}
|
|
1540
1451
|
case "check_symbol_grounding": {
|
|
1541
|
-
const { symbol, path:
|
|
1542
|
-
const result = await checkSymbolGrounding(symbol,
|
|
1452
|
+
const { symbol, path: path6 } = CheckSymbolGroundingSchema.parse(args);
|
|
1453
|
+
const result = await checkSymbolGrounding(symbol, path6);
|
|
1543
1454
|
return {
|
|
1544
1455
|
content: [
|
|
1545
1456
|
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
1546
1457
|
]
|
|
1547
1458
|
};
|
|
1548
1459
|
}
|
|
1460
|
+
case "hygiene_audit":
|
|
1461
|
+
case "metabolism_audit":
|
|
1549
1462
|
case "codebase_audit": {
|
|
1550
|
-
const { path:
|
|
1551
|
-
const
|
|
1463
|
+
const { path: rootDir } = CodebaseAuditSchema.parse(args);
|
|
1464
|
+
const { HygieneAuditProvider } = await import("@aiready/hygiene-audit");
|
|
1465
|
+
const provider = new HygieneAuditProvider();
|
|
1466
|
+
const result = await provider.analyze({ rootDir });
|
|
1467
|
+
const allIssues = result.results.flatMap((r) => r.issues);
|
|
1468
|
+
const metadata = {
|
|
1469
|
+
debtMarkers: result.metadata?.debtMarkers || 0,
|
|
1470
|
+
emptyDirs: result.metadata?.emptyDirs || [],
|
|
1471
|
+
orphanedFiles: result.metadata?.orphanedFiles || [],
|
|
1472
|
+
findings: allIssues.map((i) => ({
|
|
1473
|
+
expected: i.recommendation || i.suggestion || "",
|
|
1474
|
+
actual: i.message,
|
|
1475
|
+
severity: i.severity === "critical" ? "P0" : i.severity === "major" ? "P1" : "P2",
|
|
1476
|
+
recommendation: i.recommendation || i.suggestion || ""
|
|
1477
|
+
}))
|
|
1478
|
+
};
|
|
1552
1479
|
return {
|
|
1553
1480
|
content: [
|
|
1554
1481
|
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
1555
|
-
]
|
|
1482
|
+
],
|
|
1483
|
+
metadata
|
|
1556
1484
|
};
|
|
1557
1485
|
}
|
|
1558
1486
|
default:
|