@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 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 (e) {
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
- async resolveDefinition(symbolName, path4) {
474
- validateWorkspacePath(path4);
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 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]));
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(path4).isDirectory()) {
583
+ if (import_fs3.default.statSync(path5).isDirectory()) {
503
584
  return [];
504
585
  }
505
- const tsconfig = await projectManager.findNearestTsConfig(path4);
586
+ const tsconfig = await projectManager.findNearestTsConfig(path5);
506
587
  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));
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, path4, limit = 50, offset = 0) {
515
- validateWorkspacePath(path4);
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
- path4,
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, path4, limit = 50, offset = 0) {
566
- validateWorkspacePath(path4);
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 { 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);
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
- } 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
- });
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, path4) {
758
- return await typescriptAdapter.resolveDefinition(symbol, path4);
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, path4, limit = 50, offset = 0) {
764
- return await typescriptAdapter.findReferences(symbol, path4, limit, offset);
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, path4, limit = 50, offset = 0) {
876
+ async function findImplementations(symbol, path5, limit = 50, offset = 0) {
770
877
  return await typescriptAdapter.findImplementations(
771
878
  symbol,
772
- path4,
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(path4) {
820
- return await symbolIndex.buildIndex(path4);
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: path4 } = ResolveDefinitionSchema.parse(args);
952
- const results = await resolveDefinition(symbol, path4);
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: path4, limit, offset } = FindReferencesSchema.parse(args);
961
- const results = await findReferences(symbol, path4, limit, offset);
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: path4, limit, offset } = FindImplementationsSchema.parse(args);
1076
+ const { symbol, path: path5, limit, offset } = FindImplementationsSchema.parse(args);
970
1077
  const results = await findImplementations(
971
1078
  symbol,
972
- path4,
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: path4, filePattern, limit, regex } = SearchCodeSchema.parse(args);
1099
+ const { pattern, path: path5, filePattern, limit, regex } = SearchCodeSchema.parse(args);
993
1100
  const results = await searchCode(
994
1101
  pattern,
995
- path4,
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: path4 } = GetSymbolDocsSchema.parse(args);
1008
- const docs = await getSymbolDocs(symbol, path4);
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: path4 } = BuildSymbolIndexSchema.parse(args);
1015
- const stats = await buildSymbolIndex(path4);
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
  };