@aiready/ast-mcp-server 0.1.2 → 0.1.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.
- package/dist/index.cjs +190 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +184 -83
- package/dist/index.js.map +1 -1
- package/dist/worker/ast-worker.cjs +158 -0
- package/dist/worker/ast-worker.cjs.map +1 -0
- package/dist/worker/ast-worker.d.cts +2 -0
- package/dist/worker/ast-worker.d.ts +2 -0
- package/dist/worker/ast-worker.js +156 -0
- package/dist/worker/ast-worker.js.map +1 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -31,9 +31,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
33
|
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js
|
|
34
|
+
var getImportMetaUrl, importMetaUrl;
|
|
34
35
|
var init_cjs_shims = __esm({
|
|
35
36
|
"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js"() {
|
|
36
37
|
"use strict";
|
|
38
|
+
getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
39
|
+
importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
37
40
|
}
|
|
38
41
|
});
|
|
39
42
|
|
|
@@ -381,7 +384,7 @@ var SymbolIndex = class {
|
|
|
381
384
|
process.memoryUsage().heapUsed / 1024 / 1024
|
|
382
385
|
);
|
|
383
386
|
}
|
|
384
|
-
} catch
|
|
387
|
+
} catch {
|
|
385
388
|
}
|
|
386
389
|
}
|
|
387
390
|
const tsconfigs = await projectManager.getProjectsForPath(safeRoot);
|
|
@@ -469,21 +472,99 @@ var symbolIndex = new SymbolIndex();
|
|
|
469
472
|
|
|
470
473
|
// src/adapters/typescript-adapter.ts
|
|
471
474
|
init_security();
|
|
475
|
+
|
|
476
|
+
// src/worker/pool.ts
|
|
477
|
+
init_cjs_shims();
|
|
478
|
+
var import_worker_threads = require("worker_threads");
|
|
479
|
+
var import_path4 = __toESM(require("path"), 1);
|
|
480
|
+
var import_url = require("url");
|
|
481
|
+
var WorkerPool = class {
|
|
482
|
+
constructor(poolSize) {
|
|
483
|
+
this.poolSize = poolSize;
|
|
484
|
+
}
|
|
485
|
+
workers = [];
|
|
486
|
+
available = [];
|
|
487
|
+
queue = [];
|
|
488
|
+
activeJobs = /* @__PURE__ */ new Map();
|
|
489
|
+
taskId = 0;
|
|
490
|
+
async init() {
|
|
491
|
+
const __dirname = import_path4.default.dirname((0, import_url.fileURLToPath)(importMetaUrl));
|
|
492
|
+
const workerPath = import_path4.default.join(__dirname, "ast-worker.js");
|
|
493
|
+
for (let i = 0; i < this.poolSize; i++) {
|
|
494
|
+
const worker = new import_worker_threads.Worker(workerPath);
|
|
495
|
+
worker.on("message", (msg) => this.handleResult(msg));
|
|
496
|
+
worker.on("error", (err) => this.handleWorkerError(worker, err));
|
|
497
|
+
this.workers.push(worker);
|
|
498
|
+
this.available.push(worker);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
async execute(type, payload) {
|
|
502
|
+
return new Promise((resolve, reject) => {
|
|
503
|
+
const id = String(++this.taskId);
|
|
504
|
+
const task = { id, type, payload, resolve, reject };
|
|
505
|
+
const worker = this.available.pop();
|
|
506
|
+
if (worker) {
|
|
507
|
+
this.dispatch(worker, task);
|
|
508
|
+
} else {
|
|
509
|
+
this.queue.push(task);
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
dispatch(worker, task) {
|
|
514
|
+
this.activeJobs.set(task.id, task);
|
|
515
|
+
worker.postMessage({ id: task.id, type: task.type, payload: task.payload });
|
|
516
|
+
}
|
|
517
|
+
handleResult(msg) {
|
|
518
|
+
const task = this.activeJobs.get(msg.id);
|
|
519
|
+
if (!task) return;
|
|
520
|
+
this.activeJobs.delete(msg.id);
|
|
521
|
+
if (msg.error) {
|
|
522
|
+
task.reject(new Error(msg.error));
|
|
523
|
+
} else {
|
|
524
|
+
task.resolve(msg.result);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
handleWorkerError(worker, err) {
|
|
528
|
+
const idx = this.workers.indexOf(worker);
|
|
529
|
+
if (idx !== -1) {
|
|
530
|
+
worker.terminate();
|
|
531
|
+
const __dirname = import_path4.default.dirname((0, import_url.fileURLToPath)(importMetaUrl));
|
|
532
|
+
const workerPath = import_path4.default.join(__dirname, "ast-worker.js");
|
|
533
|
+
const newWorker = new import_worker_threads.Worker(workerPath);
|
|
534
|
+
newWorker.on("message", (msg) => this.handleResult(msg));
|
|
535
|
+
newWorker.on("error", (_e) => this.handleWorkerError(newWorker, _e));
|
|
536
|
+
this.workers[idx] = newWorker;
|
|
537
|
+
this.available.push(newWorker);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
async terminate() {
|
|
541
|
+
await Promise.all(this.workers.map((w) => w.terminate()));
|
|
542
|
+
this.workers = [];
|
|
543
|
+
this.available = [];
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
// src/adapters/typescript-adapter.ts
|
|
472
548
|
var TypeScriptAdapter = class {
|
|
473
|
-
|
|
474
|
-
|
|
549
|
+
pool;
|
|
550
|
+
constructor() {
|
|
551
|
+
const poolSize = parseInt(process.env.AST_WORKER_POOL_SIZE || "2");
|
|
552
|
+
this.pool = new WorkerPool(poolSize);
|
|
553
|
+
}
|
|
554
|
+
async resolveDefinition(symbolName, path5) {
|
|
555
|
+
validateWorkspacePath(path5);
|
|
475
556
|
const indexHits = symbolIndex.lookup(symbolName);
|
|
476
557
|
if (indexHits.length > 0) {
|
|
477
558
|
const results = [];
|
|
478
559
|
for (const hit of indexHits) {
|
|
479
560
|
const tsconfig2 = await projectManager.findNearestTsConfig(hit.file);
|
|
480
561
|
if (tsconfig2) {
|
|
481
|
-
const
|
|
482
|
-
const
|
|
483
|
-
if (
|
|
484
|
-
const
|
|
485
|
-
if (
|
|
486
|
-
results.push(this.mapToDefinitionLocation(
|
|
562
|
+
const project = projectManager.ensureProject(tsconfig2);
|
|
563
|
+
const sourceFile = project.addSourceFileAtPathIfExists(hit.file);
|
|
564
|
+
if (sourceFile) {
|
|
565
|
+
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
566
|
+
if (exported && exported.length > 0) {
|
|
567
|
+
results.push(this.mapToDefinitionLocation(exported[0]));
|
|
487
568
|
continue;
|
|
488
569
|
}
|
|
489
570
|
}
|
|
@@ -499,20 +580,32 @@ var TypeScriptAdapter = class {
|
|
|
499
580
|
}
|
|
500
581
|
return results;
|
|
501
582
|
}
|
|
502
|
-
if (import_fs3.default.statSync(
|
|
583
|
+
if (import_fs3.default.statSync(path5).isDirectory()) {
|
|
503
584
|
return [];
|
|
504
585
|
}
|
|
505
|
-
const tsconfig = await projectManager.findNearestTsConfig(
|
|
586
|
+
const tsconfig = await projectManager.findNearestTsConfig(path5);
|
|
506
587
|
if (!tsconfig) return [];
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
588
|
+
try {
|
|
589
|
+
const result = await this.pool.execute(
|
|
590
|
+
"resolve_definition",
|
|
591
|
+
{
|
|
592
|
+
tsconfig,
|
|
593
|
+
file: path5,
|
|
594
|
+
symbol: symbolName
|
|
595
|
+
}
|
|
596
|
+
);
|
|
597
|
+
return result;
|
|
598
|
+
} catch {
|
|
599
|
+
const project = projectManager.ensureProject(tsconfig);
|
|
600
|
+
const sourceFile = project.addSourceFileAtPathIfExists(path5);
|
|
601
|
+
if (!sourceFile) return [];
|
|
602
|
+
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
603
|
+
if (!exported) return [];
|
|
604
|
+
return exported.map((decl) => this.mapToDefinitionLocation(decl));
|
|
605
|
+
}
|
|
513
606
|
}
|
|
514
|
-
async findReferences(symbolName,
|
|
515
|
-
validateWorkspacePath(
|
|
607
|
+
async findReferences(symbolName, path5, limit = 50, offset = 0) {
|
|
608
|
+
validateWorkspacePath(path5);
|
|
516
609
|
const hits = symbolIndex.lookup(symbolName);
|
|
517
610
|
if (hits.length === 0) return { references: [], total_count: 0 };
|
|
518
611
|
const hit = hits[0];
|
|
@@ -529,13 +622,12 @@ var TypeScriptAdapter = class {
|
|
|
529
622
|
const { searchCode: searchCode2 } = await Promise.resolve().then(() => (init_search_code(), search_code_exports));
|
|
530
623
|
const searchResults = await searchCode2(
|
|
531
624
|
symbolName,
|
|
532
|
-
|
|
625
|
+
path5,
|
|
533
626
|
"*.{ts,tsx,js,jsx}",
|
|
534
627
|
1e3,
|
|
535
628
|
false
|
|
536
629
|
);
|
|
537
630
|
const filesToLoad = [...new Set(searchResults.map((r) => r.file))];
|
|
538
|
-
console.log("Search code files to load:", filesToLoad);
|
|
539
631
|
for (const file of filesToLoad) {
|
|
540
632
|
project.addSourceFileAtPathIfExists(file);
|
|
541
633
|
}
|
|
@@ -562,57 +654,69 @@ var TypeScriptAdapter = class {
|
|
|
562
654
|
total_count: unique.length
|
|
563
655
|
};
|
|
564
656
|
}
|
|
565
|
-
async findImplementations(symbolName,
|
|
566
|
-
validateWorkspacePath(
|
|
657
|
+
async findImplementations(symbolName, path5, limit = 50, offset = 0) {
|
|
658
|
+
validateWorkspacePath(path5);
|
|
567
659
|
const hits = symbolIndex.lookup(symbolName);
|
|
568
660
|
if (hits.length === 0) return { implementations: [], total_count: 0 };
|
|
569
661
|
const hit = hits[0];
|
|
570
662
|
const tsconfig = await projectManager.findNearestTsConfig(hit.file);
|
|
571
663
|
if (!tsconfig) return { implementations: [], total_count: 0 };
|
|
572
|
-
const project = projectManager.ensureProject(tsconfig);
|
|
573
|
-
const sourceFile = project.addSourceFileAtPathIfExists(hit.file);
|
|
574
|
-
if (!sourceFile) return { implementations: [], total_count: 0 };
|
|
575
|
-
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
576
|
-
if (!exported || exported.length === 0)
|
|
577
|
-
return { implementations: [], total_count: 0 };
|
|
578
|
-
const targetNode = exported[0];
|
|
579
|
-
if (!import_ts_morph3.Node.isClassDeclaration(targetNode) && !import_ts_morph3.Node.isInterfaceDeclaration(targetNode)) {
|
|
580
|
-
return { implementations: [], total_count: 0 };
|
|
581
|
-
}
|
|
582
664
|
try {
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
665
|
+
const result = await this.pool.execute("find_implementations", {
|
|
666
|
+
tsconfig,
|
|
667
|
+
file: hit.file,
|
|
668
|
+
symbol: symbolName
|
|
669
|
+
});
|
|
670
|
+
return {
|
|
671
|
+
implementations: result.implementations.slice(offset, offset + limit),
|
|
672
|
+
total_count: result.total_count
|
|
673
|
+
};
|
|
674
|
+
} catch {
|
|
675
|
+
const project = projectManager.ensureProject(tsconfig);
|
|
676
|
+
const sourceFile = project.addSourceFileAtPathIfExists(hit.file);
|
|
677
|
+
if (!sourceFile) return { implementations: [], total_count: 0 };
|
|
678
|
+
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
679
|
+
if (!exported || exported.length === 0)
|
|
680
|
+
return { implementations: [], total_count: 0 };
|
|
681
|
+
const targetNode = exported[0];
|
|
682
|
+
if (!import_ts_morph3.Node.isClassDeclaration(targetNode) && !import_ts_morph3.Node.isInterfaceDeclaration(targetNode)) {
|
|
683
|
+
return { implementations: [], total_count: 0 };
|
|
594
684
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
685
|
+
try {
|
|
686
|
+
const { searchCode: searchCode2 } = await Promise.resolve().then(() => (init_search_code(), search_code_exports));
|
|
687
|
+
const searchResults = await searchCode2(
|
|
688
|
+
symbolName,
|
|
689
|
+
path5,
|
|
690
|
+
"*.{ts,tsx,js,jsx}",
|
|
691
|
+
1e3,
|
|
692
|
+
false
|
|
693
|
+
);
|
|
694
|
+
const filesToLoad = [...new Set(searchResults.map((r) => r.file))];
|
|
695
|
+
for (const file of filesToLoad) {
|
|
696
|
+
project.addSourceFileAtPathIfExists(file);
|
|
697
|
+
}
|
|
698
|
+
} catch (_e) {
|
|
699
|
+
}
|
|
700
|
+
const results = [];
|
|
701
|
+
const implementations = targetNode.getImplementations?.();
|
|
702
|
+
if (implementations) {
|
|
703
|
+
for (const impl of implementations) {
|
|
704
|
+
const sf = impl.getSourceFile();
|
|
705
|
+
const lc = sf.getLineAndColumnAtPos(impl.getTextSpan().getStart());
|
|
706
|
+
results.push({
|
|
707
|
+
file: sf.getFilePath(),
|
|
708
|
+
line: lc.line,
|
|
709
|
+
column: lc.column,
|
|
710
|
+
text: impl.getNode().getParent()?.getText() || impl.getNode().getText()
|
|
711
|
+
});
|
|
712
|
+
}
|
|
609
713
|
}
|
|
714
|
+
const unique = this.deduplicateLocations(results);
|
|
715
|
+
return {
|
|
716
|
+
implementations: unique.slice(offset, offset + limit),
|
|
717
|
+
total_count: unique.length
|
|
718
|
+
};
|
|
610
719
|
}
|
|
611
|
-
const unique = this.deduplicateLocations(results);
|
|
612
|
-
return {
|
|
613
|
-
implementations: unique.slice(offset, offset + limit),
|
|
614
|
-
total_count: unique.length
|
|
615
|
-
};
|
|
616
720
|
}
|
|
617
721
|
async getFileStructure(filePath) {
|
|
618
722
|
const safePath = validateWorkspacePath(filePath);
|
|
@@ -639,6 +743,9 @@ var TypeScriptAdapter = class {
|
|
|
639
743
|
};
|
|
640
744
|
return structure;
|
|
641
745
|
}
|
|
746
|
+
async shutdown() {
|
|
747
|
+
await this.pool.terminate();
|
|
748
|
+
}
|
|
642
749
|
mapToDefinitionLocation(node) {
|
|
643
750
|
const sourceFile = node.getSourceFile();
|
|
644
751
|
const lineAndColumn = sourceFile.getLineAndColumnAtPos(node.getStart());
|
|
@@ -754,22 +861,22 @@ var TypeScriptAdapter = class {
|
|
|
754
861
|
var typescriptAdapter = new TypeScriptAdapter();
|
|
755
862
|
|
|
756
863
|
// src/tools/resolve-definition.ts
|
|
757
|
-
async function resolveDefinition(symbol,
|
|
758
|
-
return await typescriptAdapter.resolveDefinition(symbol,
|
|
864
|
+
async function resolveDefinition(symbol, path5) {
|
|
865
|
+
return await typescriptAdapter.resolveDefinition(symbol, path5);
|
|
759
866
|
}
|
|
760
867
|
|
|
761
868
|
// src/tools/find-references.ts
|
|
762
869
|
init_cjs_shims();
|
|
763
|
-
async function findReferences(symbol,
|
|
764
|
-
return await typescriptAdapter.findReferences(symbol,
|
|
870
|
+
async function findReferences(symbol, path5, limit = 50, offset = 0) {
|
|
871
|
+
return await typescriptAdapter.findReferences(symbol, path5, limit, offset);
|
|
765
872
|
}
|
|
766
873
|
|
|
767
874
|
// src/tools/find-implementations.ts
|
|
768
875
|
init_cjs_shims();
|
|
769
|
-
async function findImplementations(symbol,
|
|
876
|
+
async function findImplementations(symbol, path5, limit = 50, offset = 0) {
|
|
770
877
|
return await typescriptAdapter.findImplementations(
|
|
771
878
|
symbol,
|
|
772
|
-
|
|
879
|
+
path5,
|
|
773
880
|
limit,
|
|
774
881
|
offset
|
|
775
882
|
);
|
|
@@ -816,8 +923,8 @@ async function getSymbolDocs(symbol, filePath) {
|
|
|
816
923
|
|
|
817
924
|
// src/tools/build-symbol-index.ts
|
|
818
925
|
init_cjs_shims();
|
|
819
|
-
async function buildSymbolIndex(
|
|
820
|
-
return await symbolIndex.buildIndex(
|
|
926
|
+
async function buildSymbolIndex(path5) {
|
|
927
|
+
return await symbolIndex.buildIndex(path5);
|
|
821
928
|
}
|
|
822
929
|
|
|
823
930
|
// src/index.ts
|
|
@@ -948,8 +1055,8 @@ var ASTExplorerServer = class {
|
|
|
948
1055
|
try {
|
|
949
1056
|
switch (name) {
|
|
950
1057
|
case "resolve_definition": {
|
|
951
|
-
const { symbol, path:
|
|
952
|
-
const results = await resolveDefinition(symbol,
|
|
1058
|
+
const { symbol, path: path5 } = ResolveDefinitionSchema.parse(args);
|
|
1059
|
+
const results = await resolveDefinition(symbol, path5);
|
|
953
1060
|
return {
|
|
954
1061
|
content: [
|
|
955
1062
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -957,8 +1064,8 @@ var ASTExplorerServer = class {
|
|
|
957
1064
|
};
|
|
958
1065
|
}
|
|
959
1066
|
case "find_references": {
|
|
960
|
-
const { symbol, path:
|
|
961
|
-
const results = await findReferences(symbol,
|
|
1067
|
+
const { symbol, path: path5, limit, offset } = FindReferencesSchema.parse(args);
|
|
1068
|
+
const results = await findReferences(symbol, path5, limit, offset);
|
|
962
1069
|
return {
|
|
963
1070
|
content: [
|
|
964
1071
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -966,10 +1073,10 @@ var ASTExplorerServer = class {
|
|
|
966
1073
|
};
|
|
967
1074
|
}
|
|
968
1075
|
case "find_implementations": {
|
|
969
|
-
const { symbol, path:
|
|
1076
|
+
const { symbol, path: path5, limit, offset } = FindImplementationsSchema.parse(args);
|
|
970
1077
|
const results = await findImplementations(
|
|
971
1078
|
symbol,
|
|
972
|
-
|
|
1079
|
+
path5,
|
|
973
1080
|
limit,
|
|
974
1081
|
offset
|
|
975
1082
|
);
|
|
@@ -989,10 +1096,10 @@ var ASTExplorerServer = class {
|
|
|
989
1096
|
};
|
|
990
1097
|
}
|
|
991
1098
|
case "search_code": {
|
|
992
|
-
const { pattern, path:
|
|
1099
|
+
const { pattern, path: path5, filePattern, limit, regex } = SearchCodeSchema.parse(args);
|
|
993
1100
|
const results = await searchCode(
|
|
994
1101
|
pattern,
|
|
995
|
-
|
|
1102
|
+
path5,
|
|
996
1103
|
filePattern,
|
|
997
1104
|
limit,
|
|
998
1105
|
regex
|
|
@@ -1004,15 +1111,15 @@ var ASTExplorerServer = class {
|
|
|
1004
1111
|
};
|
|
1005
1112
|
}
|
|
1006
1113
|
case "get_symbol_docs": {
|
|
1007
|
-
const { symbol, path:
|
|
1008
|
-
const docs = await getSymbolDocs(symbol,
|
|
1114
|
+
const { symbol, path: path5 } = GetSymbolDocsSchema.parse(args);
|
|
1115
|
+
const docs = await getSymbolDocs(symbol, path5);
|
|
1009
1116
|
return {
|
|
1010
1117
|
content: [{ type: "text", text: JSON.stringify(docs, null, 2) }]
|
|
1011
1118
|
};
|
|
1012
1119
|
}
|
|
1013
1120
|
case "build_symbol_index": {
|
|
1014
|
-
const { path:
|
|
1015
|
-
const stats = await buildSymbolIndex(
|
|
1121
|
+
const { path: path5 } = BuildSymbolIndexSchema.parse(args);
|
|
1122
|
+
const stats = await buildSymbolIndex(path5);
|
|
1016
1123
|
return {
|
|
1017
1124
|
content: [{ type: "text", text: JSON.stringify(stats, null, 2) }]
|
|
1018
1125
|
};
|