@aiready/ast-mcp-server 0.1.2 → 0.1.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/dist/index.cjs +193 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +187 -82
- 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 +1 -1
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
|
|
|
@@ -469,21 +472,103 @@ 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
|
+
const worker = this.workers.find(
|
|
527
|
+
(w) => !this.available.includes(w) && ![...this.activeJobs.values()].some((t) => t.id === msg.id)
|
|
528
|
+
// simplistic
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
handleWorkerError(worker, err) {
|
|
532
|
+
const idx = this.workers.indexOf(worker);
|
|
533
|
+
if (idx !== -1) {
|
|
534
|
+
worker.terminate();
|
|
535
|
+
const __dirname = import_path4.default.dirname((0, import_url.fileURLToPath)(importMetaUrl));
|
|
536
|
+
const workerPath = import_path4.default.join(__dirname, "ast-worker.js");
|
|
537
|
+
const newWorker = new import_worker_threads.Worker(workerPath);
|
|
538
|
+
newWorker.on("message", (msg) => this.handleResult(msg));
|
|
539
|
+
newWorker.on("error", (e) => this.handleWorkerError(newWorker, e));
|
|
540
|
+
this.workers[idx] = newWorker;
|
|
541
|
+
this.available.push(newWorker);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
async terminate() {
|
|
545
|
+
await Promise.all(this.workers.map((w) => w.terminate()));
|
|
546
|
+
this.workers = [];
|
|
547
|
+
this.available = [];
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
// src/adapters/typescript-adapter.ts
|
|
472
552
|
var TypeScriptAdapter = class {
|
|
473
|
-
|
|
474
|
-
|
|
553
|
+
pool;
|
|
554
|
+
constructor() {
|
|
555
|
+
const poolSize = parseInt(process.env.AST_WORKER_POOL_SIZE || "2");
|
|
556
|
+
this.pool = new WorkerPool(poolSize);
|
|
557
|
+
}
|
|
558
|
+
async resolveDefinition(symbolName, path5) {
|
|
559
|
+
validateWorkspacePath(path5);
|
|
475
560
|
const indexHits = symbolIndex.lookup(symbolName);
|
|
476
561
|
if (indexHits.length > 0) {
|
|
477
562
|
const results = [];
|
|
478
563
|
for (const hit of indexHits) {
|
|
479
564
|
const tsconfig2 = await projectManager.findNearestTsConfig(hit.file);
|
|
480
565
|
if (tsconfig2) {
|
|
481
|
-
const
|
|
482
|
-
const
|
|
483
|
-
if (
|
|
484
|
-
const
|
|
485
|
-
if (
|
|
486
|
-
results.push(this.mapToDefinitionLocation(
|
|
566
|
+
const project = projectManager.ensureProject(tsconfig2);
|
|
567
|
+
const sourceFile = project.addSourceFileAtPathIfExists(hit.file);
|
|
568
|
+
if (sourceFile) {
|
|
569
|
+
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
570
|
+
if (exported && exported.length > 0) {
|
|
571
|
+
results.push(this.mapToDefinitionLocation(exported[0]));
|
|
487
572
|
continue;
|
|
488
573
|
}
|
|
489
574
|
}
|
|
@@ -499,20 +584,32 @@ var TypeScriptAdapter = class {
|
|
|
499
584
|
}
|
|
500
585
|
return results;
|
|
501
586
|
}
|
|
502
|
-
if (import_fs3.default.statSync(
|
|
587
|
+
if (import_fs3.default.statSync(path5).isDirectory()) {
|
|
503
588
|
return [];
|
|
504
589
|
}
|
|
505
|
-
const tsconfig = await projectManager.findNearestTsConfig(
|
|
590
|
+
const tsconfig = await projectManager.findNearestTsConfig(path5);
|
|
506
591
|
if (!tsconfig) return [];
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
592
|
+
try {
|
|
593
|
+
const result = await this.pool.execute(
|
|
594
|
+
"resolve_definition",
|
|
595
|
+
{
|
|
596
|
+
tsconfig,
|
|
597
|
+
file: path5,
|
|
598
|
+
symbol: symbolName
|
|
599
|
+
}
|
|
600
|
+
);
|
|
601
|
+
return result;
|
|
602
|
+
} catch {
|
|
603
|
+
const project = projectManager.ensureProject(tsconfig);
|
|
604
|
+
const sourceFile = project.addSourceFileAtPathIfExists(path5);
|
|
605
|
+
if (!sourceFile) return [];
|
|
606
|
+
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
607
|
+
if (!exported) return [];
|
|
608
|
+
return exported.map((decl) => this.mapToDefinitionLocation(decl));
|
|
609
|
+
}
|
|
513
610
|
}
|
|
514
|
-
async findReferences(symbolName,
|
|
515
|
-
validateWorkspacePath(
|
|
611
|
+
async findReferences(symbolName, path5, limit = 50, offset = 0) {
|
|
612
|
+
validateWorkspacePath(path5);
|
|
516
613
|
const hits = symbolIndex.lookup(symbolName);
|
|
517
614
|
if (hits.length === 0) return { references: [], total_count: 0 };
|
|
518
615
|
const hit = hits[0];
|
|
@@ -529,13 +626,12 @@ var TypeScriptAdapter = class {
|
|
|
529
626
|
const { searchCode: searchCode2 } = await Promise.resolve().then(() => (init_search_code(), search_code_exports));
|
|
530
627
|
const searchResults = await searchCode2(
|
|
531
628
|
symbolName,
|
|
532
|
-
|
|
629
|
+
path5,
|
|
533
630
|
"*.{ts,tsx,js,jsx}",
|
|
534
631
|
1e3,
|
|
535
632
|
false
|
|
536
633
|
);
|
|
537
634
|
const filesToLoad = [...new Set(searchResults.map((r) => r.file))];
|
|
538
|
-
console.log("Search code files to load:", filesToLoad);
|
|
539
635
|
for (const file of filesToLoad) {
|
|
540
636
|
project.addSourceFileAtPathIfExists(file);
|
|
541
637
|
}
|
|
@@ -562,57 +658,69 @@ var TypeScriptAdapter = class {
|
|
|
562
658
|
total_count: unique.length
|
|
563
659
|
};
|
|
564
660
|
}
|
|
565
|
-
async findImplementations(symbolName,
|
|
566
|
-
validateWorkspacePath(
|
|
661
|
+
async findImplementations(symbolName, path5, limit = 50, offset = 0) {
|
|
662
|
+
validateWorkspacePath(path5);
|
|
567
663
|
const hits = symbolIndex.lookup(symbolName);
|
|
568
664
|
if (hits.length === 0) return { implementations: [], total_count: 0 };
|
|
569
665
|
const hit = hits[0];
|
|
570
666
|
const tsconfig = await projectManager.findNearestTsConfig(hit.file);
|
|
571
667
|
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
668
|
try {
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
669
|
+
const result = await this.pool.execute("find_implementations", {
|
|
670
|
+
tsconfig,
|
|
671
|
+
file: hit.file,
|
|
672
|
+
symbol: symbolName
|
|
673
|
+
});
|
|
674
|
+
return {
|
|
675
|
+
implementations: result.implementations.slice(offset, offset + limit),
|
|
676
|
+
total_count: result.total_count
|
|
677
|
+
};
|
|
678
|
+
} catch {
|
|
679
|
+
const project = projectManager.ensureProject(tsconfig);
|
|
680
|
+
const sourceFile = project.addSourceFileAtPathIfExists(hit.file);
|
|
681
|
+
if (!sourceFile) return { implementations: [], total_count: 0 };
|
|
682
|
+
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
683
|
+
if (!exported || exported.length === 0)
|
|
684
|
+
return { implementations: [], total_count: 0 };
|
|
685
|
+
const targetNode = exported[0];
|
|
686
|
+
if (!import_ts_morph3.Node.isClassDeclaration(targetNode) && !import_ts_morph3.Node.isInterfaceDeclaration(targetNode)) {
|
|
687
|
+
return { implementations: [], total_count: 0 };
|
|
594
688
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
689
|
+
try {
|
|
690
|
+
const { searchCode: searchCode2 } = await Promise.resolve().then(() => (init_search_code(), search_code_exports));
|
|
691
|
+
const searchResults = await searchCode2(
|
|
692
|
+
symbolName,
|
|
693
|
+
path5,
|
|
694
|
+
"*.{ts,tsx,js,jsx}",
|
|
695
|
+
1e3,
|
|
696
|
+
false
|
|
697
|
+
);
|
|
698
|
+
const filesToLoad = [...new Set(searchResults.map((r) => r.file))];
|
|
699
|
+
for (const file of filesToLoad) {
|
|
700
|
+
project.addSourceFileAtPathIfExists(file);
|
|
701
|
+
}
|
|
702
|
+
} catch (_e) {
|
|
703
|
+
}
|
|
704
|
+
const results = [];
|
|
705
|
+
const implementations = targetNode.getImplementations?.();
|
|
706
|
+
if (implementations) {
|
|
707
|
+
for (const impl of implementations) {
|
|
708
|
+
const sf = impl.getSourceFile();
|
|
709
|
+
const lc = sf.getLineAndColumnAtPos(impl.getTextSpan().getStart());
|
|
710
|
+
results.push({
|
|
711
|
+
file: sf.getFilePath(),
|
|
712
|
+
line: lc.line,
|
|
713
|
+
column: lc.column,
|
|
714
|
+
text: impl.getNode().getParent()?.getText() || impl.getNode().getText()
|
|
715
|
+
});
|
|
716
|
+
}
|
|
609
717
|
}
|
|
718
|
+
const unique = this.deduplicateLocations(results);
|
|
719
|
+
return {
|
|
720
|
+
implementations: unique.slice(offset, offset + limit),
|
|
721
|
+
total_count: unique.length
|
|
722
|
+
};
|
|
610
723
|
}
|
|
611
|
-
const unique = this.deduplicateLocations(results);
|
|
612
|
-
return {
|
|
613
|
-
implementations: unique.slice(offset, offset + limit),
|
|
614
|
-
total_count: unique.length
|
|
615
|
-
};
|
|
616
724
|
}
|
|
617
725
|
async getFileStructure(filePath) {
|
|
618
726
|
const safePath = validateWorkspacePath(filePath);
|
|
@@ -639,6 +747,9 @@ var TypeScriptAdapter = class {
|
|
|
639
747
|
};
|
|
640
748
|
return structure;
|
|
641
749
|
}
|
|
750
|
+
async shutdown() {
|
|
751
|
+
await this.pool.terminate();
|
|
752
|
+
}
|
|
642
753
|
mapToDefinitionLocation(node) {
|
|
643
754
|
const sourceFile = node.getSourceFile();
|
|
644
755
|
const lineAndColumn = sourceFile.getLineAndColumnAtPos(node.getStart());
|
|
@@ -754,22 +865,22 @@ var TypeScriptAdapter = class {
|
|
|
754
865
|
var typescriptAdapter = new TypeScriptAdapter();
|
|
755
866
|
|
|
756
867
|
// src/tools/resolve-definition.ts
|
|
757
|
-
async function resolveDefinition(symbol,
|
|
758
|
-
return await typescriptAdapter.resolveDefinition(symbol,
|
|
868
|
+
async function resolveDefinition(symbol, path5) {
|
|
869
|
+
return await typescriptAdapter.resolveDefinition(symbol, path5);
|
|
759
870
|
}
|
|
760
871
|
|
|
761
872
|
// src/tools/find-references.ts
|
|
762
873
|
init_cjs_shims();
|
|
763
|
-
async function findReferences(symbol,
|
|
764
|
-
return await typescriptAdapter.findReferences(symbol,
|
|
874
|
+
async function findReferences(symbol, path5, limit = 50, offset = 0) {
|
|
875
|
+
return await typescriptAdapter.findReferences(symbol, path5, limit, offset);
|
|
765
876
|
}
|
|
766
877
|
|
|
767
878
|
// src/tools/find-implementations.ts
|
|
768
879
|
init_cjs_shims();
|
|
769
|
-
async function findImplementations(symbol,
|
|
880
|
+
async function findImplementations(symbol, path5, limit = 50, offset = 0) {
|
|
770
881
|
return await typescriptAdapter.findImplementations(
|
|
771
882
|
symbol,
|
|
772
|
-
|
|
883
|
+
path5,
|
|
773
884
|
limit,
|
|
774
885
|
offset
|
|
775
886
|
);
|
|
@@ -816,8 +927,8 @@ async function getSymbolDocs(symbol, filePath) {
|
|
|
816
927
|
|
|
817
928
|
// src/tools/build-symbol-index.ts
|
|
818
929
|
init_cjs_shims();
|
|
819
|
-
async function buildSymbolIndex(
|
|
820
|
-
return await symbolIndex.buildIndex(
|
|
930
|
+
async function buildSymbolIndex(path5) {
|
|
931
|
+
return await symbolIndex.buildIndex(path5);
|
|
821
932
|
}
|
|
822
933
|
|
|
823
934
|
// src/index.ts
|
|
@@ -948,8 +1059,8 @@ var ASTExplorerServer = class {
|
|
|
948
1059
|
try {
|
|
949
1060
|
switch (name) {
|
|
950
1061
|
case "resolve_definition": {
|
|
951
|
-
const { symbol, path:
|
|
952
|
-
const results = await resolveDefinition(symbol,
|
|
1062
|
+
const { symbol, path: path5 } = ResolveDefinitionSchema.parse(args);
|
|
1063
|
+
const results = await resolveDefinition(symbol, path5);
|
|
953
1064
|
return {
|
|
954
1065
|
content: [
|
|
955
1066
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -957,8 +1068,8 @@ var ASTExplorerServer = class {
|
|
|
957
1068
|
};
|
|
958
1069
|
}
|
|
959
1070
|
case "find_references": {
|
|
960
|
-
const { symbol, path:
|
|
961
|
-
const results = await findReferences(symbol,
|
|
1071
|
+
const { symbol, path: path5, limit, offset } = FindReferencesSchema.parse(args);
|
|
1072
|
+
const results = await findReferences(symbol, path5, limit, offset);
|
|
962
1073
|
return {
|
|
963
1074
|
content: [
|
|
964
1075
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -966,10 +1077,10 @@ var ASTExplorerServer = class {
|
|
|
966
1077
|
};
|
|
967
1078
|
}
|
|
968
1079
|
case "find_implementations": {
|
|
969
|
-
const { symbol, path:
|
|
1080
|
+
const { symbol, path: path5, limit, offset } = FindImplementationsSchema.parse(args);
|
|
970
1081
|
const results = await findImplementations(
|
|
971
1082
|
symbol,
|
|
972
|
-
|
|
1083
|
+
path5,
|
|
973
1084
|
limit,
|
|
974
1085
|
offset
|
|
975
1086
|
);
|
|
@@ -989,10 +1100,10 @@ var ASTExplorerServer = class {
|
|
|
989
1100
|
};
|
|
990
1101
|
}
|
|
991
1102
|
case "search_code": {
|
|
992
|
-
const { pattern, path:
|
|
1103
|
+
const { pattern, path: path5, filePattern, limit, regex } = SearchCodeSchema.parse(args);
|
|
993
1104
|
const results = await searchCode(
|
|
994
1105
|
pattern,
|
|
995
|
-
|
|
1106
|
+
path5,
|
|
996
1107
|
filePattern,
|
|
997
1108
|
limit,
|
|
998
1109
|
regex
|
|
@@ -1004,15 +1115,15 @@ var ASTExplorerServer = class {
|
|
|
1004
1115
|
};
|
|
1005
1116
|
}
|
|
1006
1117
|
case "get_symbol_docs": {
|
|
1007
|
-
const { symbol, path:
|
|
1008
|
-
const docs = await getSymbolDocs(symbol,
|
|
1118
|
+
const { symbol, path: path5 } = GetSymbolDocsSchema.parse(args);
|
|
1119
|
+
const docs = await getSymbolDocs(symbol, path5);
|
|
1009
1120
|
return {
|
|
1010
1121
|
content: [{ type: "text", text: JSON.stringify(docs, null, 2) }]
|
|
1011
1122
|
};
|
|
1012
1123
|
}
|
|
1013
1124
|
case "build_symbol_index": {
|
|
1014
|
-
const { path:
|
|
1015
|
-
const stats = await buildSymbolIndex(
|
|
1125
|
+
const { path: path5 } = BuildSymbolIndexSchema.parse(args);
|
|
1126
|
+
const stats = await buildSymbolIndex(path5);
|
|
1016
1127
|
return {
|
|
1017
1128
|
content: [{ type: "text", text: JSON.stringify(stats, null, 2) }]
|
|
1018
1129
|
};
|