@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 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
- async resolveDefinition(symbolName, path4) {
474
- validateWorkspacePath(path4);
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 project2 = projectManager.ensureProject(tsconfig2);
482
- const sourceFile2 = project2.addSourceFileAtPathIfExists(hit.file);
483
- if (sourceFile2) {
484
- const exported2 = sourceFile2.getExportedDeclarations().get(symbolName);
485
- if (exported2 && exported2.length > 0) {
486
- results.push(this.mapToDefinitionLocation(exported2[0]));
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(path4).isDirectory()) {
587
+ if (import_fs3.default.statSync(path5).isDirectory()) {
503
588
  return [];
504
589
  }
505
- const tsconfig = await projectManager.findNearestTsConfig(path4);
590
+ const tsconfig = await projectManager.findNearestTsConfig(path5);
506
591
  if (!tsconfig) return [];
507
- const project = projectManager.ensureProject(tsconfig);
508
- const sourceFile = project.addSourceFileAtPathIfExists(path4);
509
- if (!sourceFile) return [];
510
- const exported = sourceFile.getExportedDeclarations().get(symbolName);
511
- if (!exported) return [];
512
- return exported.map((decl) => this.mapToDefinitionLocation(decl));
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, path4, limit = 50, offset = 0) {
515
- validateWorkspacePath(path4);
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
- path4,
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, path4, limit = 50, offset = 0) {
566
- validateWorkspacePath(path4);
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 { searchCode: searchCode2 } = await Promise.resolve().then(() => (init_search_code(), search_code_exports));
584
- const searchResults = await searchCode2(
585
- symbolName,
586
- path4,
587
- "*.{ts,tsx,js,jsx}",
588
- 1e3,
589
- false
590
- );
591
- const filesToLoad = [...new Set(searchResults.map((r) => r.file))];
592
- for (const file of filesToLoad) {
593
- project.addSourceFileAtPathIfExists(file);
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
- } catch (_e) {
596
- }
597
- const results = [];
598
- const implementations = targetNode.getImplementations?.();
599
- if (implementations) {
600
- for (const impl of implementations) {
601
- const sf = impl.getSourceFile();
602
- const lc = sf.getLineAndColumnAtPos(impl.getTextSpan().getStart());
603
- results.push({
604
- file: sf.getFilePath(),
605
- line: lc.line,
606
- column: lc.column,
607
- text: impl.getNode().getParent()?.getText() || impl.getNode().getText()
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, path4) {
758
- return await typescriptAdapter.resolveDefinition(symbol, path4);
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, path4, limit = 50, offset = 0) {
764
- return await typescriptAdapter.findReferences(symbol, path4, limit, offset);
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, path4, limit = 50, offset = 0) {
880
+ async function findImplementations(symbol, path5, limit = 50, offset = 0) {
770
881
  return await typescriptAdapter.findImplementations(
771
882
  symbol,
772
- path4,
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(path4) {
820
- return await symbolIndex.buildIndex(path4);
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: path4 } = ResolveDefinitionSchema.parse(args);
952
- const results = await resolveDefinition(symbol, path4);
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: path4, limit, offset } = FindReferencesSchema.parse(args);
961
- const results = await findReferences(symbol, path4, limit, offset);
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: path4, limit, offset } = FindImplementationsSchema.parse(args);
1080
+ const { symbol, path: path5, limit, offset } = FindImplementationsSchema.parse(args);
970
1081
  const results = await findImplementations(
971
1082
  symbol,
972
- path4,
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: path4, filePattern, limit, regex } = SearchCodeSchema.parse(args);
1103
+ const { pattern, path: path5, filePattern, limit, regex } = SearchCodeSchema.parse(args);
993
1104
  const results = await searchCode(
994
1105
  pattern,
995
- path4,
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: path4 } = GetSymbolDocsSchema.parse(args);
1008
- const docs = await getSymbolDocs(symbol, path4);
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: path4 } = BuildSymbolIndexSchema.parse(args);
1015
- const stats = await buildSymbolIndex(path4);
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
  };