@aiready/ast-mcp-server 0.1.1 → 0.1.2
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/README.md +45 -99
- package/dist/chunk-PRWMQQYW.js +80 -0
- package/dist/chunk-PRWMQQYW.js.map +1 -0
- package/dist/index.cjs +538 -263
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +418 -263
- package/dist/index.js.map +1 -1
- package/dist/search-code-V3LACKQ6.js +7 -0
- package/dist/search-code-V3LACKQ6.js.map +1 -0
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __export = (target, all) => {
|
|
9
12
|
for (var name in all)
|
|
10
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -27,17 +30,118 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
30
|
));
|
|
28
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
32
|
|
|
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 init_cjs_shims = __esm({
|
|
35
|
+
"../../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
|
+
"use strict";
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// src/security.ts
|
|
41
|
+
function resolveWorkspaceRoot() {
|
|
42
|
+
return process.env.AST_WORKSPACE_ROOT || process.cwd();
|
|
43
|
+
}
|
|
44
|
+
function validateWorkspacePath(inputPath) {
|
|
45
|
+
const root = resolveWorkspaceRoot();
|
|
46
|
+
const resolved = import_path.default.resolve(root, inputPath);
|
|
47
|
+
const normalized = import_path.default.normalize(resolved);
|
|
48
|
+
if (!normalized.startsWith(root)) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Path traversal detected: ${inputPath} escapes workspace root`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
if (normalized.includes("\0")) {
|
|
54
|
+
throw new Error("Path contains null bytes");
|
|
55
|
+
}
|
|
56
|
+
return normalized;
|
|
57
|
+
}
|
|
58
|
+
var import_path;
|
|
59
|
+
var init_security = __esm({
|
|
60
|
+
"src/security.ts"() {
|
|
61
|
+
"use strict";
|
|
62
|
+
init_cjs_shims();
|
|
63
|
+
import_path = __toESM(require("path"), 1);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// src/tools/search-code.ts
|
|
68
|
+
var search_code_exports = {};
|
|
69
|
+
__export(search_code_exports, {
|
|
70
|
+
searchCode: () => searchCode
|
|
71
|
+
});
|
|
72
|
+
async function searchCode(pattern, searchPath, filePattern, limit = 50, regex = true) {
|
|
73
|
+
const safePath = validateWorkspacePath(searchPath);
|
|
74
|
+
const args = [
|
|
75
|
+
"--json",
|
|
76
|
+
"--max-count",
|
|
77
|
+
limit.toString(),
|
|
78
|
+
"--max-columns",
|
|
79
|
+
"500"
|
|
80
|
+
];
|
|
81
|
+
if (!regex) {
|
|
82
|
+
args.push("--fixed-strings");
|
|
83
|
+
}
|
|
84
|
+
args.push(pattern, safePath);
|
|
85
|
+
if (filePattern) {
|
|
86
|
+
args.push("--glob", filePattern);
|
|
87
|
+
}
|
|
88
|
+
args.push("--glob", "!**/node_modules/**");
|
|
89
|
+
args.push("--glob", "!**/dist/**");
|
|
90
|
+
args.push("--glob", "!**/.git/**");
|
|
91
|
+
try {
|
|
92
|
+
const { stdout } = await execFileAsync(import_ripgrep.rgPath, args);
|
|
93
|
+
const lines = stdout.split("\n").filter(Boolean);
|
|
94
|
+
const results = [];
|
|
95
|
+
for (const line of lines) {
|
|
96
|
+
const data = JSON.parse(line);
|
|
97
|
+
if (data.type === "match") {
|
|
98
|
+
const file = data.data.path.text;
|
|
99
|
+
const lineNumber = data.data.line_number;
|
|
100
|
+
const submatches = data.data.submatches;
|
|
101
|
+
for (const submatch of submatches) {
|
|
102
|
+
results.push({
|
|
103
|
+
file,
|
|
104
|
+
line: lineNumber,
|
|
105
|
+
column: submatch.start,
|
|
106
|
+
text: data.data.lines.text.trim()
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return results.slice(0, limit);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (error.code === 1) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
var import_child_process, import_util, import_ripgrep, execFileAsync;
|
|
120
|
+
var init_search_code = __esm({
|
|
121
|
+
"src/tools/search-code.ts"() {
|
|
122
|
+
"use strict";
|
|
123
|
+
init_cjs_shims();
|
|
124
|
+
import_child_process = require("child_process");
|
|
125
|
+
import_util = require("util");
|
|
126
|
+
import_ripgrep = require("@vscode/ripgrep");
|
|
127
|
+
init_security();
|
|
128
|
+
execFileAsync = (0, import_util.promisify)(import_child_process.execFile);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
30
132
|
// src/index.ts
|
|
31
133
|
var index_exports = {};
|
|
32
134
|
__export(index_exports, {
|
|
33
135
|
ASTExplorerServer: () => ASTExplorerServer
|
|
34
136
|
});
|
|
35
137
|
module.exports = __toCommonJS(index_exports);
|
|
138
|
+
init_cjs_shims();
|
|
36
139
|
var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
37
140
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
38
141
|
var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
39
142
|
|
|
40
143
|
// src/schemas.ts
|
|
144
|
+
init_cjs_shims();
|
|
41
145
|
var import_zod = require("zod");
|
|
42
146
|
var ResolveDefinitionSchema = import_zod.z.object({
|
|
43
147
|
symbol: import_zod.z.string().describe(
|
|
@@ -61,10 +165,11 @@ var GetFileStructureSchema = import_zod.z.object({
|
|
|
61
165
|
file: import_zod.z.string().describe("Absolute path to the file to analyze")
|
|
62
166
|
});
|
|
63
167
|
var SearchCodeSchema = import_zod.z.object({
|
|
64
|
-
pattern: import_zod.z.string().describe("Search pattern (regex)"),
|
|
168
|
+
pattern: import_zod.z.string().describe("Search pattern (regex by default)"),
|
|
65
169
|
path: import_zod.z.string().describe("Directory to search in"),
|
|
66
170
|
filePattern: import_zod.z.string().optional().describe('Glob filter (e.g., "*.ts")'),
|
|
67
|
-
limit: import_zod.z.number().optional().default(50).describe("Max matches to return")
|
|
171
|
+
limit: import_zod.z.number().optional().default(50).describe("Max matches to return"),
|
|
172
|
+
regex: import_zod.z.boolean().optional().default(true).describe("Use regex mode (default true)")
|
|
68
173
|
});
|
|
69
174
|
var GetSymbolDocsSchema = import_zod.z.object({
|
|
70
175
|
symbol: import_zod.z.string().describe("Symbol name to get documentation for"),
|
|
@@ -74,189 +179,450 @@ var BuildSymbolIndexSchema = import_zod.z.object({
|
|
|
74
179
|
path: import_zod.z.string().describe("Project root directory to index")
|
|
75
180
|
});
|
|
76
181
|
|
|
182
|
+
// src/tools/resolve-definition.ts
|
|
183
|
+
init_cjs_shims();
|
|
184
|
+
|
|
77
185
|
// src/adapters/typescript-adapter.ts
|
|
78
|
-
|
|
186
|
+
init_cjs_shims();
|
|
187
|
+
var import_ts_morph3 = require("ts-morph");
|
|
188
|
+
var import_fs3 = __toESM(require("fs"), 1);
|
|
79
189
|
|
|
80
190
|
// src/project-manager.ts
|
|
191
|
+
init_cjs_shims();
|
|
81
192
|
var import_ts_morph = require("ts-morph");
|
|
82
|
-
var
|
|
193
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
83
194
|
var import_fs = __toESM(require("fs"), 1);
|
|
84
195
|
var import_glob = require("glob");
|
|
196
|
+
init_security();
|
|
85
197
|
var ProjectManager = class {
|
|
86
198
|
projects = /* @__PURE__ */ new Map();
|
|
87
199
|
tsconfigCache = /* @__PURE__ */ new Map();
|
|
200
|
+
accessOrder = [];
|
|
201
|
+
// MRU at front
|
|
202
|
+
maxProjects = 4;
|
|
88
203
|
/**
|
|
89
204
|
* Find all tsconfig.json files in a directory (recursive)
|
|
90
205
|
*/
|
|
91
206
|
async findTsConfigs(rootDir) {
|
|
92
|
-
|
|
93
|
-
|
|
207
|
+
const safeRoot = validateWorkspacePath(rootDir);
|
|
208
|
+
if (this.tsconfigCache.has(safeRoot)) {
|
|
209
|
+
return this.tsconfigCache.get(safeRoot);
|
|
94
210
|
}
|
|
95
211
|
const configs = await (0, import_glob.glob)("**/tsconfig.json", {
|
|
96
|
-
cwd:
|
|
212
|
+
cwd: safeRoot,
|
|
97
213
|
absolute: true,
|
|
98
214
|
ignore: ["**/node_modules/**", "**/dist/**"]
|
|
99
215
|
});
|
|
100
|
-
this.tsconfigCache.set(
|
|
216
|
+
this.tsconfigCache.set(safeRoot, configs);
|
|
101
217
|
return configs;
|
|
102
218
|
}
|
|
103
219
|
/**
|
|
104
|
-
*
|
|
105
|
-
*/
|
|
106
|
-
async getProjectForFile(filePath) {
|
|
107
|
-
const tsconfigPath = await this.findNearestTsConfig(filePath);
|
|
108
|
-
if (!tsconfigPath) return void 0;
|
|
109
|
-
return this.getOrCreateProject(tsconfigPath);
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Get or create a Project for a tsconfig path
|
|
220
|
+
* Ensure a Project exists for a given tsconfig path, managing LRU cache
|
|
113
221
|
*/
|
|
114
|
-
|
|
222
|
+
ensureProject(tsconfigPath) {
|
|
223
|
+
this.checkMemoryPressure();
|
|
115
224
|
if (this.projects.has(tsconfigPath)) {
|
|
225
|
+
this.moveToFront(tsconfigPath);
|
|
116
226
|
return this.projects.get(tsconfigPath);
|
|
117
227
|
}
|
|
228
|
+
while (this.projects.size >= this.maxProjects) {
|
|
229
|
+
const oldest = this.accessOrder.pop();
|
|
230
|
+
this.disposeProject(oldest);
|
|
231
|
+
}
|
|
118
232
|
const project = new import_ts_morph.Project({
|
|
119
233
|
tsConfigFilePath: tsconfigPath,
|
|
120
|
-
skipAddingFilesFromTsConfig:
|
|
234
|
+
skipAddingFilesFromTsConfig: true
|
|
235
|
+
// KEY: don't load all files
|
|
121
236
|
});
|
|
122
237
|
this.projects.set(tsconfigPath, project);
|
|
238
|
+
this.accessOrder.unshift(tsconfigPath);
|
|
123
239
|
return project;
|
|
124
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Move a tsconfig path to the front of the access order (MRU)
|
|
243
|
+
*/
|
|
244
|
+
moveToFront(tsconfigPath) {
|
|
245
|
+
const index = this.accessOrder.indexOf(tsconfigPath);
|
|
246
|
+
if (index > -1) {
|
|
247
|
+
this.accessOrder.splice(index, 1);
|
|
248
|
+
this.accessOrder.unshift(tsconfigPath);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
checkMemoryPressure() {
|
|
252
|
+
const heapUsed = process.memoryUsage().heapUsed / 1024 / 1024;
|
|
253
|
+
const maxHeap = parseInt(process.env.AST_MAX_HEAP_MB || "1536", 10);
|
|
254
|
+
while (heapUsed > maxHeap && this.projects.size > 1) {
|
|
255
|
+
const oldest = this.accessOrder.pop();
|
|
256
|
+
this.disposeProject(oldest);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
disposeProject(tsconfigPath) {
|
|
260
|
+
const project = this.projects.get(tsconfigPath);
|
|
261
|
+
if (project) {
|
|
262
|
+
for (const sourceFile of project.getSourceFiles()) {
|
|
263
|
+
project.removeSourceFile(sourceFile);
|
|
264
|
+
}
|
|
265
|
+
this.projects.delete(tsconfigPath);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
125
268
|
/**
|
|
126
269
|
* Find the nearest tsconfig.json for a file
|
|
127
270
|
*/
|
|
128
271
|
async findNearestTsConfig(filePath) {
|
|
129
|
-
|
|
130
|
-
|
|
272
|
+
const safePath = validateWorkspacePath(filePath);
|
|
273
|
+
let currentDir = import_path2.default.dirname(safePath);
|
|
274
|
+
const root = import_path2.default.parse(currentDir).root;
|
|
131
275
|
while (currentDir !== root) {
|
|
132
|
-
const tsconfigPath =
|
|
276
|
+
const tsconfigPath = import_path2.default.join(currentDir, "tsconfig.json");
|
|
133
277
|
if (import_fs.default.existsSync(tsconfigPath)) {
|
|
134
278
|
return tsconfigPath;
|
|
135
279
|
}
|
|
136
|
-
currentDir =
|
|
280
|
+
currentDir = import_path2.default.dirname(currentDir);
|
|
137
281
|
}
|
|
138
282
|
return void 0;
|
|
139
283
|
}
|
|
140
284
|
/**
|
|
141
|
-
* Get all
|
|
285
|
+
* Get all tsconfigs for a path
|
|
142
286
|
*/
|
|
143
287
|
async getProjectsForPath(rootDir) {
|
|
144
|
-
|
|
145
|
-
return configs.map((config) => this.getOrCreateProject(config));
|
|
288
|
+
return this.findTsConfigs(rootDir);
|
|
146
289
|
}
|
|
147
290
|
/**
|
|
148
291
|
* Dispose all projects to free memory
|
|
149
292
|
*/
|
|
150
293
|
disposeAll() {
|
|
151
|
-
for (const
|
|
152
|
-
|
|
294
|
+
for (const [key] of this.projects) {
|
|
295
|
+
this.disposeProject(key);
|
|
153
296
|
}
|
|
154
|
-
this.
|
|
297
|
+
this.accessOrder = [];
|
|
155
298
|
}
|
|
156
299
|
};
|
|
157
300
|
var projectManager = new ProjectManager();
|
|
158
301
|
|
|
159
|
-
// src/
|
|
160
|
-
|
|
302
|
+
// src/index/symbol-index.ts
|
|
303
|
+
init_cjs_shims();
|
|
304
|
+
init_security();
|
|
305
|
+
var import_fs2 = __toESM(require("fs"), 1);
|
|
306
|
+
var import_crypto = __toESM(require("crypto"), 1);
|
|
307
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
308
|
+
var import_ts_morph2 = require("ts-morph");
|
|
309
|
+
var SymbolIndex = class {
|
|
310
|
+
index = {};
|
|
311
|
+
getCachePath(rootDir) {
|
|
312
|
+
const hash = import_crypto.default.createHash("sha256").update(rootDir).digest("hex").slice(0, 12);
|
|
313
|
+
return import_path3.default.join(
|
|
314
|
+
process.platform === "win32" ? process.env.TEMP || "c:/temp" : "/tmp",
|
|
315
|
+
`ast-index-${hash}.json`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
isCacheValid(cached, rootDir) {
|
|
319
|
+
if (cached.rootDir !== rootDir) return false;
|
|
320
|
+
for (const [file, cachedMtime] of Object.entries(cached.fileHashes)) {
|
|
321
|
+
if (!import_fs2.default.existsSync(file)) return false;
|
|
322
|
+
if (import_fs2.default.statSync(file).mtimeMs !== cachedMtime) return false;
|
|
323
|
+
}
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
computeStats(cache, duration_ms, memory_mb) {
|
|
327
|
+
const files = Object.keys(cache.fileHashes).length;
|
|
328
|
+
let functions = 0;
|
|
329
|
+
let classes = 0;
|
|
330
|
+
let interfaces = 0;
|
|
331
|
+
let types = 0;
|
|
332
|
+
for (const entries of Object.values(cache.symbols)) {
|
|
333
|
+
for (const entry of entries) {
|
|
334
|
+
if (entry.kind === "function" || entry.kind === "method") functions++;
|
|
335
|
+
if (entry.kind === "class") classes++;
|
|
336
|
+
if (entry.kind === "interface") interfaces++;
|
|
337
|
+
if (entry.kind === "type_alias") types++;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
indexed: {
|
|
342
|
+
files,
|
|
343
|
+
functions,
|
|
344
|
+
classes,
|
|
345
|
+
interfaces,
|
|
346
|
+
types
|
|
347
|
+
},
|
|
348
|
+
duration_ms: duration_ms || 0,
|
|
349
|
+
memory_mb: memory_mb || 0
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
mapKind(node) {
|
|
353
|
+
if (import_ts_morph2.Node.isClassDeclaration(node)) return "class";
|
|
354
|
+
if (import_ts_morph2.Node.isFunctionDeclaration(node)) return "function";
|
|
355
|
+
if (import_ts_morph2.Node.isInterfaceDeclaration(node)) return "interface";
|
|
356
|
+
if (import_ts_morph2.Node.isTypeAliasDeclaration(node)) return "type_alias";
|
|
357
|
+
if (import_ts_morph2.Node.isEnumDeclaration(node)) return "enum";
|
|
358
|
+
if (import_ts_morph2.Node.isVariableDeclaration(node)) return "variable";
|
|
359
|
+
if (import_ts_morph2.Node.isMethodDeclaration(node)) return "method";
|
|
360
|
+
if (import_ts_morph2.Node.isPropertyDeclaration(node)) return "property";
|
|
361
|
+
if (import_ts_morph2.Node.isParameterDeclaration(node)) return "parameter";
|
|
362
|
+
return "variable";
|
|
363
|
+
}
|
|
161
364
|
/**
|
|
162
|
-
*
|
|
365
|
+
* Build/Warm the index for a given path
|
|
163
366
|
*/
|
|
164
|
-
async
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
367
|
+
async buildIndex(rootDir) {
|
|
368
|
+
const startTime = Date.now();
|
|
369
|
+
const safeRoot = validateWorkspacePath(rootDir);
|
|
370
|
+
const cachePath = this.getCachePath(safeRoot);
|
|
371
|
+
if (import_fs2.default.existsSync(cachePath)) {
|
|
372
|
+
try {
|
|
373
|
+
const cached = JSON.parse(
|
|
374
|
+
import_fs2.default.readFileSync(cachePath, "utf-8")
|
|
375
|
+
);
|
|
376
|
+
if (this.isCacheValid(cached, safeRoot)) {
|
|
377
|
+
this.index = cached.symbols;
|
|
378
|
+
return this.computeStats(
|
|
379
|
+
cached,
|
|
380
|
+
Date.now() - startTime,
|
|
381
|
+
process.memoryUsage().heapUsed / 1024 / 1024
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
} catch (e) {
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const tsconfigs = await projectManager.getProjectsForPath(safeRoot);
|
|
388
|
+
const symbols = {};
|
|
389
|
+
const fileHashes = {};
|
|
390
|
+
for (const config of tsconfigs) {
|
|
391
|
+
const project = projectManager.ensureProject(config);
|
|
392
|
+
project.addSourceFilesFromTsConfig(config);
|
|
393
|
+
for (const sourceFile of project.getSourceFiles()) {
|
|
394
|
+
const filePath = sourceFile.getFilePath();
|
|
395
|
+
try {
|
|
396
|
+
fileHashes[filePath] = import_fs2.default.statSync(filePath).mtimeMs;
|
|
397
|
+
} catch {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
for (const [name, decls] of sourceFile.getExportedDeclarations()) {
|
|
401
|
+
for (const decl of decls) {
|
|
402
|
+
const entry = {
|
|
403
|
+
name,
|
|
404
|
+
kind: this.mapKind(decl),
|
|
405
|
+
file: filePath,
|
|
406
|
+
line: decl.getStartLineNumber(),
|
|
407
|
+
column: decl.getStart() - decl.getStartLinePos(),
|
|
408
|
+
exported: true
|
|
409
|
+
};
|
|
410
|
+
(symbols[name] ||= []).push(entry);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
for (const fn of sourceFile.getFunctions()) {
|
|
414
|
+
const name = fn.getName();
|
|
415
|
+
if (name && !symbols[name]?.some(
|
|
416
|
+
(s) => s.file === filePath && s.line === fn.getStartLineNumber()
|
|
417
|
+
)) {
|
|
418
|
+
const entry = {
|
|
419
|
+
name,
|
|
420
|
+
kind: "function",
|
|
421
|
+
file: filePath,
|
|
422
|
+
line: fn.getStartLineNumber(),
|
|
423
|
+
column: fn.getStart() - fn.getStartLinePos(),
|
|
424
|
+
exported: false
|
|
425
|
+
};
|
|
426
|
+
(symbols[name] ||= []).push(entry);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
for (const cls of sourceFile.getClasses()) {
|
|
430
|
+
const name = cls.getName();
|
|
431
|
+
if (name && !symbols[name]?.some(
|
|
432
|
+
(s) => s.file === filePath && s.line === cls.getStartLineNumber()
|
|
433
|
+
)) {
|
|
434
|
+
const entry = {
|
|
435
|
+
name,
|
|
436
|
+
kind: "class",
|
|
437
|
+
file: filePath,
|
|
438
|
+
line: cls.getStartLineNumber(),
|
|
439
|
+
column: cls.getStart() - cls.getStartLinePos(),
|
|
440
|
+
exported: false
|
|
441
|
+
};
|
|
442
|
+
(symbols[name] ||= []).push(entry);
|
|
175
443
|
}
|
|
176
444
|
}
|
|
177
445
|
}
|
|
178
446
|
}
|
|
179
|
-
|
|
447
|
+
const cache = {
|
|
448
|
+
version: 1,
|
|
449
|
+
rootDir: safeRoot,
|
|
450
|
+
builtAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
451
|
+
fileHashes,
|
|
452
|
+
symbols
|
|
453
|
+
};
|
|
454
|
+
import_fs2.default.mkdirSync(import_path3.default.dirname(cachePath), { recursive: true });
|
|
455
|
+
import_fs2.default.writeFileSync(cachePath, JSON.stringify(cache));
|
|
456
|
+
this.index = symbols;
|
|
457
|
+
const duration = Date.now() - startTime;
|
|
458
|
+
const memoryUsage = process.memoryUsage().heapUsed / 1024 / 1024;
|
|
459
|
+
return this.computeStats(cache, duration, Math.round(memoryUsage));
|
|
180
460
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
461
|
+
lookup(name) {
|
|
462
|
+
return this.index[name] || [];
|
|
463
|
+
}
|
|
464
|
+
lookupByFile(file) {
|
|
465
|
+
return Object.values(this.index).flat().filter((e) => e.file === file);
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
var symbolIndex = new SymbolIndex();
|
|
469
|
+
|
|
470
|
+
// src/adapters/typescript-adapter.ts
|
|
471
|
+
init_security();
|
|
472
|
+
var TypeScriptAdapter = class {
|
|
473
|
+
async resolveDefinition(symbolName, path4) {
|
|
474
|
+
validateWorkspacePath(path4);
|
|
475
|
+
const indexHits = symbolIndex.lookup(symbolName);
|
|
476
|
+
if (indexHits.length > 0) {
|
|
477
|
+
const results = [];
|
|
478
|
+
for (const hit of indexHits) {
|
|
479
|
+
const tsconfig2 = await projectManager.findNearestTsConfig(hit.file);
|
|
480
|
+
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]));
|
|
487
|
+
continue;
|
|
206
488
|
}
|
|
207
489
|
}
|
|
208
490
|
}
|
|
491
|
+
results.push({
|
|
492
|
+
file: hit.file,
|
|
493
|
+
line: hit.line,
|
|
494
|
+
column: hit.column,
|
|
495
|
+
kind: hit.kind,
|
|
496
|
+
snippet: "",
|
|
497
|
+
documentation: void 0
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
return results;
|
|
501
|
+
}
|
|
502
|
+
if (import_fs3.default.statSync(path4).isDirectory()) {
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
const tsconfig = await projectManager.findNearestTsConfig(path4);
|
|
506
|
+
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));
|
|
513
|
+
}
|
|
514
|
+
async findReferences(symbolName, path4, limit = 50, offset = 0) {
|
|
515
|
+
validateWorkspacePath(path4);
|
|
516
|
+
const hits = symbolIndex.lookup(symbolName);
|
|
517
|
+
if (hits.length === 0) return { references: [], total_count: 0 };
|
|
518
|
+
const hit = hits[0];
|
|
519
|
+
const tsconfig = await projectManager.findNearestTsConfig(hit.file);
|
|
520
|
+
if (!tsconfig) return { references: [], total_count: 0 };
|
|
521
|
+
const project = projectManager.ensureProject(tsconfig);
|
|
522
|
+
const sourceFile = project.addSourceFileAtPathIfExists(hit.file);
|
|
523
|
+
if (!sourceFile) return { references: [], total_count: 0 };
|
|
524
|
+
const exported = sourceFile.getExportedDeclarations().get(symbolName);
|
|
525
|
+
if (!exported || exported.length === 0)
|
|
526
|
+
return { references: [], total_count: 0 };
|
|
527
|
+
const targetNode = exported[0];
|
|
528
|
+
try {
|
|
529
|
+
const { searchCode: searchCode2 } = await Promise.resolve().then(() => (init_search_code(), search_code_exports));
|
|
530
|
+
const searchResults = await searchCode2(
|
|
531
|
+
symbolName,
|
|
532
|
+
path4,
|
|
533
|
+
"*.{ts,tsx,js,jsx}",
|
|
534
|
+
1e3,
|
|
535
|
+
false
|
|
536
|
+
);
|
|
537
|
+
const filesToLoad = [...new Set(searchResults.map((r) => r.file))];
|
|
538
|
+
console.log("Search code files to load:", filesToLoad);
|
|
539
|
+
for (const file of filesToLoad) {
|
|
540
|
+
project.addSourceFileAtPathIfExists(file);
|
|
541
|
+
}
|
|
542
|
+
} catch (_e) {
|
|
543
|
+
}
|
|
544
|
+
const refSymbols = targetNode.findReferences?.();
|
|
545
|
+
if (!refSymbols) return { references: [], total_count: 0 };
|
|
546
|
+
const results = [];
|
|
547
|
+
for (const refSymbol of refSymbols) {
|
|
548
|
+
for (const ref of refSymbol.getReferences()) {
|
|
549
|
+
const sf = ref.getSourceFile();
|
|
550
|
+
const lc = sf.getLineAndColumnAtPos(ref.getTextSpan().getStart());
|
|
551
|
+
results.push({
|
|
552
|
+
file: sf.getFilePath(),
|
|
553
|
+
line: lc.line,
|
|
554
|
+
column: lc.column,
|
|
555
|
+
text: ref.getNode().getParent()?.getText() || ref.getNode().getText()
|
|
556
|
+
});
|
|
209
557
|
}
|
|
210
558
|
}
|
|
211
|
-
const
|
|
559
|
+
const unique = this.deduplicateLocations(results);
|
|
212
560
|
return {
|
|
213
|
-
references:
|
|
214
|
-
total_count:
|
|
561
|
+
references: unique.slice(offset, offset + limit),
|
|
562
|
+
total_count: unique.length
|
|
215
563
|
};
|
|
216
564
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const
|
|
565
|
+
async findImplementations(symbolName, path4, limit = 50, offset = 0) {
|
|
566
|
+
validateWorkspacePath(path4);
|
|
567
|
+
const hits = symbolIndex.lookup(symbolName);
|
|
568
|
+
if (hits.length === 0) return { implementations: [], total_count: 0 };
|
|
569
|
+
const hit = hits[0];
|
|
570
|
+
const tsconfig = await projectManager.findNearestTsConfig(hit.file);
|
|
571
|
+
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
|
+
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);
|
|
594
|
+
}
|
|
595
|
+
} catch (_e) {
|
|
596
|
+
}
|
|
222
597
|
const results = [];
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
for (const
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
results.push({
|
|
235
|
-
file: sourceFile2.getFilePath(),
|
|
236
|
-
line: lineAndColumn.line,
|
|
237
|
-
column: lineAndColumn.column,
|
|
238
|
-
text: impl.getNode().getParent()?.getText() || impl.getNode().getText()
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
}
|
|
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
|
+
});
|
|
242
609
|
}
|
|
243
610
|
}
|
|
244
|
-
const
|
|
611
|
+
const unique = this.deduplicateLocations(results);
|
|
245
612
|
return {
|
|
246
|
-
implementations:
|
|
247
|
-
total_count:
|
|
613
|
+
implementations: unique.slice(offset, offset + limit),
|
|
614
|
+
total_count: unique.length
|
|
248
615
|
};
|
|
249
616
|
}
|
|
250
|
-
/**
|
|
251
|
-
* Get file structure overview
|
|
252
|
-
*/
|
|
253
617
|
async getFileStructure(filePath) {
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
618
|
+
const safePath = validateWorkspacePath(filePath);
|
|
619
|
+
const tsconfig = await projectManager.findNearestTsConfig(safePath);
|
|
620
|
+
if (!tsconfig) return void 0;
|
|
621
|
+
const project = projectManager.ensureProject(tsconfig);
|
|
622
|
+
const sourceFile = project.addSourceFileAtPathIfExists(safePath);
|
|
257
623
|
if (!sourceFile) return void 0;
|
|
258
624
|
const structure = {
|
|
259
|
-
file:
|
|
625
|
+
file: safePath,
|
|
260
626
|
imports: sourceFile.getImportDeclarations().map((imp) => ({
|
|
261
627
|
module: imp.getModuleSpecifierValue(),
|
|
262
628
|
names: imp.getNamedImports().map((ni) => ni.getName())
|
|
@@ -273,9 +639,6 @@ var TypeScriptAdapter = class {
|
|
|
273
639
|
};
|
|
274
640
|
return structure;
|
|
275
641
|
}
|
|
276
|
-
/**
|
|
277
|
-
* Helper: Map ts-morph Node (Declaration) to DefinitionLocation
|
|
278
|
-
*/
|
|
279
642
|
mapToDefinitionLocation(node) {
|
|
280
643
|
const sourceFile = node.getSourceFile();
|
|
281
644
|
const lineAndColumn = sourceFile.getLineAndColumnAtPos(node.getStart());
|
|
@@ -288,34 +651,25 @@ var TypeScriptAdapter = class {
|
|
|
288
651
|
documentation: this.getJsDoc(node)
|
|
289
652
|
};
|
|
290
653
|
}
|
|
291
|
-
/**
|
|
292
|
-
* Helper: Map ts-morph Node to SymbolKind
|
|
293
|
-
*/
|
|
294
654
|
mapNodeToSymbolKind(node) {
|
|
295
|
-
if (
|
|
296
|
-
if (
|
|
297
|
-
if (
|
|
298
|
-
if (
|
|
299
|
-
if (
|
|
300
|
-
if (
|
|
301
|
-
if (
|
|
302
|
-
if (
|
|
303
|
-
if (
|
|
655
|
+
if (import_ts_morph3.Node.isClassDeclaration(node)) return "class";
|
|
656
|
+
if (import_ts_morph3.Node.isFunctionDeclaration(node)) return "function";
|
|
657
|
+
if (import_ts_morph3.Node.isInterfaceDeclaration(node)) return "interface";
|
|
658
|
+
if (import_ts_morph3.Node.isTypeAliasDeclaration(node)) return "type_alias";
|
|
659
|
+
if (import_ts_morph3.Node.isEnumDeclaration(node)) return "enum";
|
|
660
|
+
if (import_ts_morph3.Node.isVariableDeclaration(node)) return "variable";
|
|
661
|
+
if (import_ts_morph3.Node.isMethodDeclaration(node)) return "method";
|
|
662
|
+
if (import_ts_morph3.Node.isPropertyDeclaration(node)) return "property";
|
|
663
|
+
if (import_ts_morph3.Node.isParameterDeclaration(node)) return "parameter";
|
|
304
664
|
return "variable";
|
|
305
665
|
}
|
|
306
|
-
/**
|
|
307
|
-
* Helper: Map Symbol to SymbolKind
|
|
308
|
-
*/
|
|
309
666
|
mapSymbolKind(symbol) {
|
|
310
667
|
const decls = symbol.getDeclarations();
|
|
311
668
|
if (decls.length > 0) return this.mapNodeToSymbolKind(decls[0]);
|
|
312
669
|
return "variable";
|
|
313
670
|
}
|
|
314
|
-
/**
|
|
315
|
-
* Helper: Get JSDoc from Node
|
|
316
|
-
*/
|
|
317
671
|
getJsDoc(node) {
|
|
318
|
-
if (
|
|
672
|
+
if (import_ts_morph3.Node.isJSDocable(node)) {
|
|
319
673
|
const docs = node.getJsDocs();
|
|
320
674
|
if (docs.length > 0) {
|
|
321
675
|
return docs[0].getCommentText();
|
|
@@ -323,11 +677,8 @@ var TypeScriptAdapter = class {
|
|
|
323
677
|
}
|
|
324
678
|
return void 0;
|
|
325
679
|
}
|
|
326
|
-
/**
|
|
327
|
-
* Helper: Get full JSDoc info (with tags)
|
|
328
|
-
*/
|
|
329
680
|
getSymbolDocs(node) {
|
|
330
|
-
if (
|
|
681
|
+
if (import_ts_morph3.Node.isJSDocable(node)) {
|
|
331
682
|
const docs = node.getJsDocs();
|
|
332
683
|
if (docs.length > 0) {
|
|
333
684
|
const doc = docs[0];
|
|
@@ -390,9 +741,6 @@ var TypeScriptAdapter = class {
|
|
|
390
741
|
members: enm.getMembers().map((m) => m.getName())
|
|
391
742
|
};
|
|
392
743
|
}
|
|
393
|
-
/**
|
|
394
|
-
* Helper: Deduplicate locations
|
|
395
|
-
*/
|
|
396
744
|
deduplicateLocations(locations) {
|
|
397
745
|
const seen = /* @__PURE__ */ new Set();
|
|
398
746
|
return locations.filter((loc) => {
|
|
@@ -406,100 +754,59 @@ var TypeScriptAdapter = class {
|
|
|
406
754
|
var typescriptAdapter = new TypeScriptAdapter();
|
|
407
755
|
|
|
408
756
|
// src/tools/resolve-definition.ts
|
|
409
|
-
async function resolveDefinition(symbol,
|
|
410
|
-
return await typescriptAdapter.resolveDefinition(symbol,
|
|
757
|
+
async function resolveDefinition(symbol, path4) {
|
|
758
|
+
return await typescriptAdapter.resolveDefinition(symbol, path4);
|
|
411
759
|
}
|
|
412
760
|
|
|
413
761
|
// src/tools/find-references.ts
|
|
414
|
-
|
|
415
|
-
|
|
762
|
+
init_cjs_shims();
|
|
763
|
+
async function findReferences(symbol, path4, limit = 50, offset = 0) {
|
|
764
|
+
return await typescriptAdapter.findReferences(symbol, path4, limit, offset);
|
|
416
765
|
}
|
|
417
766
|
|
|
418
767
|
// src/tools/find-implementations.ts
|
|
419
|
-
|
|
768
|
+
init_cjs_shims();
|
|
769
|
+
async function findImplementations(symbol, path4, limit = 50, offset = 0) {
|
|
420
770
|
return await typescriptAdapter.findImplementations(
|
|
421
771
|
symbol,
|
|
422
|
-
|
|
772
|
+
path4,
|
|
423
773
|
limit,
|
|
424
774
|
offset
|
|
425
775
|
);
|
|
426
776
|
}
|
|
427
777
|
|
|
428
778
|
// src/tools/get-file-structure.ts
|
|
779
|
+
init_cjs_shims();
|
|
429
780
|
async function getFileStructure(file) {
|
|
430
781
|
return await typescriptAdapter.getFileStructure(file);
|
|
431
782
|
}
|
|
432
783
|
|
|
433
|
-
// src/
|
|
434
|
-
|
|
435
|
-
var import_util = require("util");
|
|
436
|
-
var import_ripgrep = require("@vscode/ripgrep");
|
|
437
|
-
var execFileAsync = (0, import_util.promisify)(import_child_process.execFile);
|
|
438
|
-
async function searchCode(pattern, searchPath, filePattern, limit = 50) {
|
|
439
|
-
const args = [
|
|
440
|
-
"--json",
|
|
441
|
-
"--max-count",
|
|
442
|
-
limit.toString(),
|
|
443
|
-
"--fixed-strings",
|
|
444
|
-
// Default to fixed strings unless we want regex
|
|
445
|
-
pattern,
|
|
446
|
-
searchPath
|
|
447
|
-
];
|
|
448
|
-
if (filePattern) {
|
|
449
|
-
args.push("--glob", filePattern);
|
|
450
|
-
}
|
|
451
|
-
args.push("--glob", "!**/node_modules/**");
|
|
452
|
-
args.push("--glob", "!**/dist/**");
|
|
453
|
-
args.push("--glob", "!**/.git/**");
|
|
454
|
-
try {
|
|
455
|
-
const { stdout } = await execFileAsync(import_ripgrep.rgPath, args);
|
|
456
|
-
const lines = stdout.split("\n").filter(Boolean);
|
|
457
|
-
const results = [];
|
|
458
|
-
for (const line of lines) {
|
|
459
|
-
const data = JSON.parse(line);
|
|
460
|
-
if (data.type === "match") {
|
|
461
|
-
const file = data.data.path.text;
|
|
462
|
-
const lineNumber = data.data.line_number;
|
|
463
|
-
const submatches = data.data.submatches;
|
|
464
|
-
for (const submatch of submatches) {
|
|
465
|
-
results.push({
|
|
466
|
-
file,
|
|
467
|
-
line: lineNumber,
|
|
468
|
-
column: submatch.start,
|
|
469
|
-
text: data.data.lines.text.trim()
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
return results.slice(0, limit);
|
|
475
|
-
} catch (error) {
|
|
476
|
-
if (error.code === 1) {
|
|
477
|
-
return [];
|
|
478
|
-
}
|
|
479
|
-
throw error;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
784
|
+
// src/index.ts
|
|
785
|
+
init_search_code();
|
|
482
786
|
|
|
483
787
|
// src/tools/get-symbol-docs.ts
|
|
484
|
-
|
|
788
|
+
init_cjs_shims();
|
|
789
|
+
var import_ts_morph4 = require("ts-morph");
|
|
790
|
+
init_security();
|
|
485
791
|
async function getSymbolDocs(symbol, filePath) {
|
|
486
|
-
const
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
792
|
+
const safePath = validateWorkspacePath(filePath);
|
|
793
|
+
const tsconfig = await projectManager.findNearestTsConfig(safePath);
|
|
794
|
+
if (!tsconfig) return void 0;
|
|
795
|
+
const project = projectManager.ensureProject(tsconfig);
|
|
796
|
+
const sourceFile = project.addSourceFileAtPathIfExists(safePath);
|
|
797
|
+
if (sourceFile) {
|
|
798
|
+
const node = sourceFile.getDescendantsOfKind(import_ts_morph4.SyntaxKind.Identifier).find((id) => id.getText() === symbol);
|
|
799
|
+
if (node) {
|
|
800
|
+
const decls = node.getSymbol()?.getDeclarations();
|
|
801
|
+
if (decls && decls.length > 0) {
|
|
802
|
+
const docs = typescriptAdapter.getSymbolDocs(decls[0]);
|
|
803
|
+
if (docs) {
|
|
804
|
+
return {
|
|
805
|
+
symbol,
|
|
806
|
+
file: sourceFile.getFilePath(),
|
|
807
|
+
line: sourceFile.getLineAndColumnAtPos(decls[0].getStart()).line,
|
|
808
|
+
...docs
|
|
809
|
+
};
|
|
503
810
|
}
|
|
504
811
|
}
|
|
505
812
|
}
|
|
@@ -507,49 +814,10 @@ async function getSymbolDocs(symbol, filePath) {
|
|
|
507
814
|
return void 0;
|
|
508
815
|
}
|
|
509
816
|
|
|
510
|
-
// src/index/symbol-index.ts
|
|
511
|
-
var SymbolIndex = class {
|
|
512
|
-
/**
|
|
513
|
-
* Build/Warm the index for a given path
|
|
514
|
-
*/
|
|
515
|
-
async buildIndex(rootDir) {
|
|
516
|
-
const startTime = Date.now();
|
|
517
|
-
const projects = await projectManager.getProjectsForPath(rootDir);
|
|
518
|
-
let fileCount = 0;
|
|
519
|
-
let functionCount = 0;
|
|
520
|
-
let classCount = 0;
|
|
521
|
-
let interfaceCount = 0;
|
|
522
|
-
let typeCount = 0;
|
|
523
|
-
for (const project of projects) {
|
|
524
|
-
const sourceFiles = project.getSourceFiles();
|
|
525
|
-
fileCount += sourceFiles.length;
|
|
526
|
-
for (const sourceFile of sourceFiles) {
|
|
527
|
-
functionCount += sourceFile.getFunctions().length;
|
|
528
|
-
classCount += sourceFile.getClasses().length;
|
|
529
|
-
interfaceCount += sourceFile.getInterfaces().length;
|
|
530
|
-
typeCount += sourceFile.getTypeAliases().length;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
const duration = Date.now() - startTime;
|
|
534
|
-
const memoryUsage = process.memoryUsage().heapUsed / 1024 / 1024;
|
|
535
|
-
return {
|
|
536
|
-
indexed: {
|
|
537
|
-
files: fileCount,
|
|
538
|
-
functions: functionCount,
|
|
539
|
-
classes: classCount,
|
|
540
|
-
interfaces: interfaceCount,
|
|
541
|
-
types: typeCount
|
|
542
|
-
},
|
|
543
|
-
duration_ms: duration,
|
|
544
|
-
memory_mb: Math.round(memoryUsage)
|
|
545
|
-
};
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
var symbolIndex = new SymbolIndex();
|
|
549
|
-
|
|
550
817
|
// src/tools/build-symbol-index.ts
|
|
551
|
-
|
|
552
|
-
|
|
818
|
+
init_cjs_shims();
|
|
819
|
+
async function buildSymbolIndex(path4) {
|
|
820
|
+
return await symbolIndex.buildIndex(path4);
|
|
553
821
|
}
|
|
554
822
|
|
|
555
823
|
// src/index.ts
|
|
@@ -643,7 +911,8 @@ var ASTExplorerServer = class {
|
|
|
643
911
|
pattern: { type: "string", description: "Search pattern" },
|
|
644
912
|
path: { type: "string", description: "Directory to search" },
|
|
645
913
|
filePattern: { type: "string", description: "Glob filter" },
|
|
646
|
-
limit: { type: "number", default: 50 }
|
|
914
|
+
limit: { type: "number", default: 50 },
|
|
915
|
+
regex: { type: "boolean", default: true }
|
|
647
916
|
},
|
|
648
917
|
required: ["pattern", "path"]
|
|
649
918
|
}
|
|
@@ -679,8 +948,8 @@ var ASTExplorerServer = class {
|
|
|
679
948
|
try {
|
|
680
949
|
switch (name) {
|
|
681
950
|
case "resolve_definition": {
|
|
682
|
-
const { symbol, path:
|
|
683
|
-
const results = await resolveDefinition(symbol,
|
|
951
|
+
const { symbol, path: path4 } = ResolveDefinitionSchema.parse(args);
|
|
952
|
+
const results = await resolveDefinition(symbol, path4);
|
|
684
953
|
return {
|
|
685
954
|
content: [
|
|
686
955
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -688,8 +957,8 @@ var ASTExplorerServer = class {
|
|
|
688
957
|
};
|
|
689
958
|
}
|
|
690
959
|
case "find_references": {
|
|
691
|
-
const { symbol, path:
|
|
692
|
-
const results = await findReferences(symbol,
|
|
960
|
+
const { symbol, path: path4, limit, offset } = FindReferencesSchema.parse(args);
|
|
961
|
+
const results = await findReferences(symbol, path4, limit, offset);
|
|
693
962
|
return {
|
|
694
963
|
content: [
|
|
695
964
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -697,10 +966,10 @@ var ASTExplorerServer = class {
|
|
|
697
966
|
};
|
|
698
967
|
}
|
|
699
968
|
case "find_implementations": {
|
|
700
|
-
const { symbol, path:
|
|
969
|
+
const { symbol, path: path4, limit, offset } = FindImplementationsSchema.parse(args);
|
|
701
970
|
const results = await findImplementations(
|
|
702
971
|
symbol,
|
|
703
|
-
|
|
972
|
+
path4,
|
|
704
973
|
limit,
|
|
705
974
|
offset
|
|
706
975
|
);
|
|
@@ -720,8 +989,14 @@ var ASTExplorerServer = class {
|
|
|
720
989
|
};
|
|
721
990
|
}
|
|
722
991
|
case "search_code": {
|
|
723
|
-
const { pattern, path:
|
|
724
|
-
const results = await searchCode(
|
|
992
|
+
const { pattern, path: path4, filePattern, limit, regex } = SearchCodeSchema.parse(args);
|
|
993
|
+
const results = await searchCode(
|
|
994
|
+
pattern,
|
|
995
|
+
path4,
|
|
996
|
+
filePattern,
|
|
997
|
+
limit,
|
|
998
|
+
regex
|
|
999
|
+
);
|
|
725
1000
|
return {
|
|
726
1001
|
content: [
|
|
727
1002
|
{ type: "text", text: JSON.stringify(results, null, 2) }
|
|
@@ -729,15 +1004,15 @@ var ASTExplorerServer = class {
|
|
|
729
1004
|
};
|
|
730
1005
|
}
|
|
731
1006
|
case "get_symbol_docs": {
|
|
732
|
-
const { symbol, path:
|
|
733
|
-
const docs = await getSymbolDocs(symbol,
|
|
1007
|
+
const { symbol, path: path4 } = GetSymbolDocsSchema.parse(args);
|
|
1008
|
+
const docs = await getSymbolDocs(symbol, path4);
|
|
734
1009
|
return {
|
|
735
1010
|
content: [{ type: "text", text: JSON.stringify(docs, null, 2) }]
|
|
736
1011
|
};
|
|
737
1012
|
}
|
|
738
1013
|
case "build_symbol_index": {
|
|
739
|
-
const { path:
|
|
740
|
-
const stats = await buildSymbolIndex(
|
|
1014
|
+
const { path: path4 } = BuildSymbolIndexSchema.parse(args);
|
|
1015
|
+
const stats = await buildSymbolIndex(path4);
|
|
741
1016
|
return {
|
|
742
1017
|
content: [{ type: "text", text: JSON.stringify(stats, null, 2) }]
|
|
743
1018
|
};
|