@compilr-dev/agents-coding-ts 0.1.3 → 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.d.ts +8 -5
- package/dist/index.js +14 -4
- package/dist/parser/index.d.ts +2 -2
- package/dist/parser/index.js +1 -1
- package/dist/parser/typescript-parser.d.ts +2 -2
- package/dist/parser/typescript-parser.js +77 -54
- package/dist/skills/code-health.js +5 -5
- package/dist/skills/code-structure.js +5 -5
- package/dist/skills/dependency-audit.js +5 -5
- package/dist/skills/index.d.ts +7 -7
- package/dist/skills/index.js +11 -11
- package/dist/skills/refactor-impact.js +5 -5
- package/dist/skills/type-analysis.js +5 -5
- package/dist/tools/find-dead-code.d.ts +2 -2
- package/dist/tools/find-dead-code.js +82 -58
- package/dist/tools/find-duplicates.d.ts +2 -2
- package/dist/tools/find-duplicates.js +41 -38
- package/dist/tools/find-implementations.d.ts +2 -2
- package/dist/tools/find-implementations.js +44 -36
- package/dist/tools/find-patterns.d.ts +2 -2
- package/dist/tools/find-patterns.js +154 -148
- package/dist/tools/find-references.d.ts +2 -2
- package/dist/tools/find-references.js +76 -72
- package/dist/tools/find-symbol.d.ts +2 -2
- package/dist/tools/find-symbol.js +106 -96
- package/dist/tools/get-call-graph.d.ts +2 -2
- package/dist/tools/get-call-graph.js +52 -47
- package/dist/tools/get-complexity.d.ts +2 -2
- package/dist/tools/get-complexity.js +94 -46
- package/dist/tools/get-dependency-graph.d.ts +2 -2
- package/dist/tools/get-dependency-graph.js +66 -52
- package/dist/tools/get-documentation.d.ts +2 -2
- package/dist/tools/get-documentation.js +154 -122
- package/dist/tools/get-exports.d.ts +2 -2
- package/dist/tools/get-exports.js +73 -61
- package/dist/tools/get-file-structure.d.ts +2 -2
- package/dist/tools/get-file-structure.js +16 -16
- package/dist/tools/get-imports.d.ts +2 -2
- package/dist/tools/get-imports.js +46 -46
- package/dist/tools/get-signature.d.ts +2 -2
- package/dist/tools/get-signature.js +168 -124
- package/dist/tools/get-type-hierarchy.d.ts +2 -2
- package/dist/tools/get-type-hierarchy.js +53 -44
- package/dist/tools/index.d.ts +18 -16
- package/dist/tools/index.js +17 -15
- package/dist/tools/read-symbol.d.ts +62 -0
- package/dist/tools/read-symbol.js +464 -0
- package/dist/tools/types.d.ts +27 -27
- package/package.json +1 -1
|
@@ -4,41 +4,41 @@
|
|
|
4
4
|
* Get all exports from a module.
|
|
5
5
|
* Uses TypeScript Compiler API for accurate AST analysis.
|
|
6
6
|
*/
|
|
7
|
-
import * as fs from
|
|
8
|
-
import * as path from
|
|
9
|
-
import * as ts from
|
|
10
|
-
import { defineTool, createSuccessResult, createErrorResult } from
|
|
11
|
-
import { detectLanguage, isLanguageSupported } from
|
|
7
|
+
import * as fs from "node:fs/promises";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import * as ts from "typescript";
|
|
10
|
+
import { defineTool, createSuccessResult, createErrorResult, } from "@compilr-dev/agents";
|
|
11
|
+
import { detectLanguage, isLanguageSupported, } from "../parser/typescript-parser.js";
|
|
12
12
|
// Tool description
|
|
13
13
|
const TOOL_DESCRIPTION = `Get all exports from a module.
|
|
14
14
|
Returns structured JSON with default export, named exports, and re-exports.
|
|
15
15
|
Use this to understand what a module exposes to other modules.`;
|
|
16
16
|
// Tool input schema
|
|
17
17
|
const TOOL_INPUT_SCHEMA = {
|
|
18
|
-
type:
|
|
18
|
+
type: "object",
|
|
19
19
|
properties: {
|
|
20
20
|
path: {
|
|
21
|
-
type:
|
|
22
|
-
description:
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "File to analyze",
|
|
23
23
|
},
|
|
24
24
|
includeReExports: {
|
|
25
|
-
type:
|
|
26
|
-
description:
|
|
25
|
+
type: "boolean",
|
|
26
|
+
description: "Include re-exports (default: true)",
|
|
27
27
|
default: true,
|
|
28
28
|
},
|
|
29
29
|
resolveReExports: {
|
|
30
|
-
type:
|
|
31
|
-
description:
|
|
30
|
+
type: "boolean",
|
|
31
|
+
description: "Resolve re-exports to original source (default: false)",
|
|
32
32
|
default: false,
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
|
-
required: [
|
|
35
|
+
required: ["path"],
|
|
36
36
|
};
|
|
37
37
|
/**
|
|
38
38
|
* getExports tool - Get all exports from a module
|
|
39
39
|
*/
|
|
40
40
|
export const getExportsTool = defineTool({
|
|
41
|
-
name:
|
|
41
|
+
name: "get_exports",
|
|
42
42
|
description: TOOL_DESCRIPTION,
|
|
43
43
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
44
44
|
execute: executeGetExports,
|
|
@@ -47,10 +47,10 @@ export const getExportsTool = defineTool({
|
|
|
47
47
|
* Execute the getExports tool
|
|
48
48
|
*/
|
|
49
49
|
async function executeGetExports(input) {
|
|
50
|
-
const { path: inputPath, includeReExports = true, resolveReExports = false } = input;
|
|
50
|
+
const { path: inputPath, includeReExports = true, resolveReExports = false, } = input;
|
|
51
51
|
// Validate input
|
|
52
52
|
if (!inputPath || inputPath.trim().length === 0) {
|
|
53
|
-
return createErrorResult(
|
|
53
|
+
return createErrorResult("Path is required");
|
|
54
54
|
}
|
|
55
55
|
try {
|
|
56
56
|
// Check if path exists
|
|
@@ -74,17 +74,19 @@ async function executeGetExports(input) {
|
|
|
74
74
|
// Calculate statistics
|
|
75
75
|
const exportStats = {
|
|
76
76
|
totalExports: namedExports.length + (defaultExport ? 1 : 0),
|
|
77
|
-
functions: namedExports.filter((e) => e.kind ===
|
|
78
|
-
classes: namedExports.filter((e) => e.kind ===
|
|
79
|
-
types: namedExports.filter((e) => e.kind ===
|
|
80
|
-
variables: namedExports.filter((e) => e.kind ===
|
|
77
|
+
functions: namedExports.filter((e) => e.kind === "function").length,
|
|
78
|
+
classes: namedExports.filter((e) => e.kind === "class").length,
|
|
79
|
+
types: namedExports.filter((e) => e.kind === "type" || e.kind === "interface").length,
|
|
80
|
+
variables: namedExports.filter((e) => e.kind === "variable").length,
|
|
81
81
|
reExports: reExports?.length ?? 0,
|
|
82
82
|
};
|
|
83
83
|
const result = {
|
|
84
84
|
path: inputPath,
|
|
85
85
|
defaultExport,
|
|
86
86
|
namedExports,
|
|
87
|
-
reExports: includeReExports && reExports && reExports.length > 0
|
|
87
|
+
reExports: includeReExports && reExports && reExports.length > 0
|
|
88
|
+
? reExports
|
|
89
|
+
: undefined,
|
|
88
90
|
stats: exportStats,
|
|
89
91
|
};
|
|
90
92
|
return createSuccessResult(result);
|
|
@@ -102,7 +104,7 @@ async function analyzeFileExports(filePath, includeReExports, resolveReExports)
|
|
|
102
104
|
const reExports = [];
|
|
103
105
|
let defaultExport;
|
|
104
106
|
try {
|
|
105
|
-
const sourceCode = await fs.readFile(filePath,
|
|
107
|
+
const sourceCode = await fs.readFile(filePath, "utf-8");
|
|
106
108
|
const scriptKind = getScriptKind(filePath);
|
|
107
109
|
const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true, scriptKind);
|
|
108
110
|
const fileDir = path.dirname(filePath);
|
|
@@ -146,15 +148,19 @@ async function analyzeFileExports(filePath, includeReExports, resolveReExports)
|
|
|
146
148
|
* Check if a node has export modifier
|
|
147
149
|
*/
|
|
148
150
|
function hasExportModifier(node) {
|
|
149
|
-
const modifiers = ts.canHaveModifiers(node)
|
|
150
|
-
|
|
151
|
+
const modifiers = ts.canHaveModifiers(node)
|
|
152
|
+
? ts.getModifiers(node)
|
|
153
|
+
: undefined;
|
|
154
|
+
return (modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false);
|
|
151
155
|
}
|
|
152
156
|
/**
|
|
153
157
|
* Check if a node has default modifier
|
|
154
158
|
*/
|
|
155
159
|
function hasDefaultModifier(node) {
|
|
156
|
-
const modifiers = ts.canHaveModifiers(node)
|
|
157
|
-
|
|
160
|
+
const modifiers = ts.canHaveModifiers(node)
|
|
161
|
+
? ts.getModifiers(node)
|
|
162
|
+
: undefined;
|
|
163
|
+
return (modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword) ?? false);
|
|
158
164
|
}
|
|
159
165
|
/**
|
|
160
166
|
* Extract export declaration (export { ... } or export * from ...)
|
|
@@ -168,13 +174,15 @@ function extractExportDeclaration(node, sourceFile, fileDir, resolveReExports) {
|
|
|
168
174
|
// Re-export from another module
|
|
169
175
|
if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
170
176
|
const from = node.moduleSpecifier.text;
|
|
171
|
-
const resolvedFrom = resolveReExports
|
|
177
|
+
const resolvedFrom = resolveReExports
|
|
178
|
+
? resolveLocalImport(from, fileDir)
|
|
179
|
+
: undefined;
|
|
172
180
|
// export * from '...'
|
|
173
181
|
if (!node.exportClause) {
|
|
174
182
|
return {
|
|
175
183
|
exports: [],
|
|
176
184
|
reExport: {
|
|
177
|
-
symbols:
|
|
185
|
+
symbols: "*",
|
|
178
186
|
from,
|
|
179
187
|
resolvedFrom,
|
|
180
188
|
line: lineNum,
|
|
@@ -205,7 +213,7 @@ function extractExportDeclaration(node, sourceFile, fileDir, resolveReExports) {
|
|
|
205
213
|
return {
|
|
206
214
|
exports: [],
|
|
207
215
|
reExport: {
|
|
208
|
-
symbols:
|
|
216
|
+
symbols: "*",
|
|
209
217
|
from,
|
|
210
218
|
resolvedFrom,
|
|
211
219
|
line: lineNum,
|
|
@@ -220,7 +228,7 @@ function extractExportDeclaration(node, sourceFile, fileDir, resolveReExports) {
|
|
|
220
228
|
const name = element.name.text;
|
|
221
229
|
exports.push({
|
|
222
230
|
name,
|
|
223
|
-
kind:
|
|
231
|
+
kind: "unknown",
|
|
224
232
|
line: lineNum,
|
|
225
233
|
typeOnly,
|
|
226
234
|
});
|
|
@@ -234,19 +242,19 @@ function extractExportDeclaration(node, sourceFile, fileDir, resolveReExports) {
|
|
|
234
242
|
function extractExportAssignment(node, sourceFile) {
|
|
235
243
|
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
236
244
|
const expr = node.expression;
|
|
237
|
-
let name =
|
|
238
|
-
let kind =
|
|
245
|
+
let name = "default";
|
|
246
|
+
let kind = "unknown";
|
|
239
247
|
if (ts.isIdentifier(expr)) {
|
|
240
248
|
name = expr.text;
|
|
241
249
|
}
|
|
242
250
|
else if (ts.isClassExpression(expr)) {
|
|
243
|
-
kind =
|
|
251
|
+
kind = "class";
|
|
244
252
|
if (expr.name) {
|
|
245
253
|
name = expr.name.text;
|
|
246
254
|
}
|
|
247
255
|
}
|
|
248
256
|
else if (ts.isFunctionExpression(expr) || ts.isArrowFunction(expr)) {
|
|
249
|
-
kind =
|
|
257
|
+
kind = "function";
|
|
250
258
|
}
|
|
251
259
|
return {
|
|
252
260
|
name,
|
|
@@ -263,12 +271,12 @@ function extractExportedDeclaration(node, sourceFile) {
|
|
|
263
271
|
const isDefault = hasDefaultModifier(node);
|
|
264
272
|
// Function declaration
|
|
265
273
|
if (ts.isFunctionDeclaration(node)) {
|
|
266
|
-
const name = node.name?.text ??
|
|
274
|
+
const name = node.name?.text ?? "default";
|
|
267
275
|
const signature = extractFunctionSignature(node, sourceFile);
|
|
268
276
|
return {
|
|
269
277
|
symbol: {
|
|
270
278
|
name,
|
|
271
|
-
kind:
|
|
279
|
+
kind: "function",
|
|
272
280
|
line: lineNum,
|
|
273
281
|
signature,
|
|
274
282
|
},
|
|
@@ -277,11 +285,11 @@ function extractExportedDeclaration(node, sourceFile) {
|
|
|
277
285
|
}
|
|
278
286
|
// Class declaration
|
|
279
287
|
if (ts.isClassDeclaration(node)) {
|
|
280
|
-
const name = node.name?.text ??
|
|
288
|
+
const name = node.name?.text ?? "default";
|
|
281
289
|
return {
|
|
282
290
|
symbol: {
|
|
283
291
|
name,
|
|
284
|
-
kind:
|
|
292
|
+
kind: "class",
|
|
285
293
|
line: lineNum,
|
|
286
294
|
},
|
|
287
295
|
isDefault,
|
|
@@ -292,7 +300,7 @@ function extractExportedDeclaration(node, sourceFile) {
|
|
|
292
300
|
return {
|
|
293
301
|
symbol: {
|
|
294
302
|
name: node.name.text,
|
|
295
|
-
kind:
|
|
303
|
+
kind: "interface",
|
|
296
304
|
line: lineNum,
|
|
297
305
|
typeOnly: true,
|
|
298
306
|
},
|
|
@@ -304,7 +312,7 @@ function extractExportedDeclaration(node, sourceFile) {
|
|
|
304
312
|
return {
|
|
305
313
|
symbol: {
|
|
306
314
|
name: node.name.text,
|
|
307
|
-
kind:
|
|
315
|
+
kind: "type",
|
|
308
316
|
line: lineNum,
|
|
309
317
|
typeOnly: true,
|
|
310
318
|
},
|
|
@@ -316,7 +324,7 @@ function extractExportedDeclaration(node, sourceFile) {
|
|
|
316
324
|
return {
|
|
317
325
|
symbol: {
|
|
318
326
|
name: node.name.text,
|
|
319
|
-
kind:
|
|
327
|
+
kind: "enum",
|
|
320
328
|
line: lineNum,
|
|
321
329
|
},
|
|
322
330
|
isDefault: false,
|
|
@@ -328,7 +336,9 @@ function extractExportedDeclaration(node, sourceFile) {
|
|
|
328
336
|
if (decls.length > 0) {
|
|
329
337
|
const firstDecl = decls[0];
|
|
330
338
|
if (ts.isIdentifier(firstDecl.name)) {
|
|
331
|
-
const kind = node.declarationList.flags & ts.NodeFlags.Const
|
|
339
|
+
const kind = node.declarationList.flags & ts.NodeFlags.Const
|
|
340
|
+
? "variable"
|
|
341
|
+
: "variable";
|
|
332
342
|
return {
|
|
333
343
|
symbol: {
|
|
334
344
|
name: firstDecl.name.text,
|
|
@@ -345,7 +355,7 @@ function extractExportedDeclaration(node, sourceFile) {
|
|
|
345
355
|
return {
|
|
346
356
|
symbol: {
|
|
347
357
|
name: node.name.getText(sourceFile),
|
|
348
|
-
kind:
|
|
358
|
+
kind: "namespace",
|
|
349
359
|
line: lineNum,
|
|
350
360
|
},
|
|
351
361
|
isDefault: false,
|
|
@@ -357,22 +367,24 @@ function extractExportedDeclaration(node, sourceFile) {
|
|
|
357
367
|
* Extract function signature
|
|
358
368
|
*/
|
|
359
369
|
function extractFunctionSignature(node, sourceFile) {
|
|
360
|
-
const name = node.name?.text ??
|
|
370
|
+
const name = node.name?.text ?? "anonymous";
|
|
361
371
|
const params = node.parameters.map((p) => {
|
|
362
372
|
const paramName = p.name.getText(sourceFile);
|
|
363
|
-
const paramType = p.type ? p.type.getText(sourceFile) :
|
|
364
|
-
const optional = p.questionToken ?
|
|
373
|
+
const paramType = p.type ? p.type.getText(sourceFile) : "any";
|
|
374
|
+
const optional = p.questionToken ? "?" : "";
|
|
365
375
|
return `${paramName}${optional}: ${paramType}`;
|
|
366
376
|
});
|
|
367
|
-
const returnType = node.type ? node.type.getText(sourceFile) :
|
|
368
|
-
const async = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword)
|
|
369
|
-
|
|
377
|
+
const returnType = node.type ? node.type.getText(sourceFile) : "void";
|
|
378
|
+
const async = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword)
|
|
379
|
+
? "async "
|
|
380
|
+
: "";
|
|
381
|
+
return `${async}function ${name}(${params.join(", ")}): ${returnType}`;
|
|
370
382
|
}
|
|
371
383
|
/**
|
|
372
384
|
* Try to resolve a local import path
|
|
373
385
|
*/
|
|
374
386
|
function resolveLocalImport(source, fromDir) {
|
|
375
|
-
if (!source.startsWith(
|
|
387
|
+
if (!source.startsWith(".") && !source.startsWith("/")) {
|
|
376
388
|
return undefined; // External package
|
|
377
389
|
}
|
|
378
390
|
const basePath = path.resolve(fromDir, source);
|
|
@@ -381,27 +393,27 @@ function resolveLocalImport(source, fromDir) {
|
|
|
381
393
|
return basePath;
|
|
382
394
|
}
|
|
383
395
|
// Try with most likely TypeScript extensions first
|
|
384
|
-
return basePath +
|
|
396
|
+
return basePath + ".ts";
|
|
385
397
|
}
|
|
386
398
|
/**
|
|
387
399
|
* Get TypeScript script kind from file extension
|
|
388
400
|
*/
|
|
389
401
|
function getScriptKind(filePath) {
|
|
390
|
-
const ext = filePath.toLowerCase().split(
|
|
402
|
+
const ext = filePath.toLowerCase().split(".").pop();
|
|
391
403
|
switch (ext) {
|
|
392
|
-
case
|
|
404
|
+
case "ts":
|
|
393
405
|
return ts.ScriptKind.TS;
|
|
394
|
-
case
|
|
406
|
+
case "tsx":
|
|
395
407
|
return ts.ScriptKind.TSX;
|
|
396
|
-
case
|
|
408
|
+
case "js":
|
|
397
409
|
return ts.ScriptKind.JS;
|
|
398
|
-
case
|
|
410
|
+
case "jsx":
|
|
399
411
|
return ts.ScriptKind.JSX;
|
|
400
|
-
case
|
|
401
|
-
case
|
|
412
|
+
case "mts":
|
|
413
|
+
case "cts":
|
|
402
414
|
return ts.ScriptKind.TS;
|
|
403
|
-
case
|
|
404
|
-
case
|
|
415
|
+
case "mjs":
|
|
416
|
+
case "cjs":
|
|
405
417
|
return ts.ScriptKind.JS;
|
|
406
418
|
default:
|
|
407
419
|
return ts.ScriptKind.TS;
|
|
@@ -413,7 +425,7 @@ function getScriptKind(filePath) {
|
|
|
413
425
|
export function createGetExportsTool(options) {
|
|
414
426
|
const { defaultIncludeReExports = true, defaultResolveReExports = false } = options ?? {};
|
|
415
427
|
return defineTool({
|
|
416
|
-
name:
|
|
428
|
+
name: "get_exports",
|
|
417
429
|
description: TOOL_DESCRIPTION,
|
|
418
430
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
419
431
|
execute: async (input) => {
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Uses TypeScript Compiler API for accurate analysis.
|
|
12
12
|
*/
|
|
13
|
-
import type { Tool } from
|
|
14
|
-
import type { GetFileStructureInput } from
|
|
13
|
+
import type { Tool } from "@compilr-dev/agents";
|
|
14
|
+
import type { GetFileStructureInput } from "./types.js";
|
|
15
15
|
/**
|
|
16
16
|
* getFileStructure tool - Analyze source file structure
|
|
17
17
|
*/
|
|
@@ -10,40 +10,40 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Uses TypeScript Compiler API for accurate analysis.
|
|
12
12
|
*/
|
|
13
|
-
import * as fs from
|
|
14
|
-
import * as path from
|
|
15
|
-
import { defineTool, createSuccessResult, createErrorResult } from
|
|
16
|
-
import { parseTypeScript, detectLanguage, isLanguageSupported } from
|
|
13
|
+
import * as fs from "node:fs/promises";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import { defineTool, createSuccessResult, createErrorResult, } from "@compilr-dev/agents";
|
|
16
|
+
import { parseTypeScript, detectLanguage, isLanguageSupported, } from "../parser/typescript-parser.js";
|
|
17
17
|
// Tool description (shared between tool and factory)
|
|
18
18
|
const TOOL_DESCRIPTION = `Analyze a source file and return its structural overview including imports, exports, classes, functions, and types.
|
|
19
19
|
Use this instead of reading the full file when you need to understand what a file contains.
|
|
20
20
|
Returns structured JSON that's much more compact than raw source code.`;
|
|
21
21
|
// Tool input schema (shared between tool and factory)
|
|
22
22
|
const TOOL_INPUT_SCHEMA = {
|
|
23
|
-
type:
|
|
23
|
+
type: "object",
|
|
24
24
|
properties: {
|
|
25
25
|
path: {
|
|
26
|
-
type:
|
|
27
|
-
description:
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "Absolute path to the file to analyze",
|
|
28
28
|
},
|
|
29
29
|
maxDepth: {
|
|
30
|
-
type:
|
|
31
|
-
description:
|
|
30
|
+
type: "number",
|
|
31
|
+
description: "Maximum depth for nested structures (default: 2)",
|
|
32
32
|
default: 2,
|
|
33
33
|
},
|
|
34
34
|
includePrivate: {
|
|
35
|
-
type:
|
|
36
|
-
description:
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "Include private/internal symbols (default: true)",
|
|
37
37
|
default: true,
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
|
-
required: [
|
|
40
|
+
required: ["path"],
|
|
41
41
|
};
|
|
42
42
|
/**
|
|
43
43
|
* getFileStructure tool - Analyze source file structure
|
|
44
44
|
*/
|
|
45
45
|
export const getFileStructureTool = defineTool({
|
|
46
|
-
name:
|
|
46
|
+
name: "get_file_structure",
|
|
47
47
|
description: TOOL_DESCRIPTION,
|
|
48
48
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
49
49
|
execute: executeGetFileStructure,
|
|
@@ -55,7 +55,7 @@ async function executeGetFileStructure(input) {
|
|
|
55
55
|
const { path: filePath, maxDepth = 2, includePrivate = true } = input;
|
|
56
56
|
// Validate input
|
|
57
57
|
if (!filePath || filePath.trim().length === 0) {
|
|
58
|
-
return createErrorResult(
|
|
58
|
+
return createErrorResult("File path is required");
|
|
59
59
|
}
|
|
60
60
|
// Check if file exists
|
|
61
61
|
try {
|
|
@@ -80,7 +80,7 @@ async function executeGetFileStructure(input) {
|
|
|
80
80
|
}
|
|
81
81
|
try {
|
|
82
82
|
// Read file content
|
|
83
|
-
const sourceCode = await fs.readFile(filePath,
|
|
83
|
+
const sourceCode = await fs.readFile(filePath, "utf-8");
|
|
84
84
|
// Parse and extract structure
|
|
85
85
|
const structure = parseTypeScript(sourceCode, filePath, {
|
|
86
86
|
maxDepth,
|
|
@@ -106,7 +106,7 @@ async function executeGetFileStructure(input) {
|
|
|
106
106
|
export function createGetFileStructureTool(options) {
|
|
107
107
|
const { defaultMaxDepth = 2, defaultIncludePrivate = true } = options ?? {};
|
|
108
108
|
return defineTool({
|
|
109
|
-
name:
|
|
109
|
+
name: "get_file_structure",
|
|
110
110
|
description: TOOL_DESCRIPTION,
|
|
111
111
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
112
112
|
execute: async (input) => {
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Get detailed import information for a file or module.
|
|
5
5
|
* Uses TypeScript Compiler API for accurate AST analysis.
|
|
6
6
|
*/
|
|
7
|
-
import type { Tool } from
|
|
8
|
-
import type { GetImportsInput } from
|
|
7
|
+
import type { Tool } from "@compilr-dev/agents";
|
|
8
|
+
import type { GetImportsInput } from "./types.js";
|
|
9
9
|
/**
|
|
10
10
|
* getImports tool - Get detailed import information
|
|
11
11
|
*/
|
|
@@ -4,21 +4,21 @@
|
|
|
4
4
|
* Get detailed import information for a file or module.
|
|
5
5
|
* Uses TypeScript Compiler API for accurate AST analysis.
|
|
6
6
|
*/
|
|
7
|
-
import * as fs from
|
|
8
|
-
import * as path from
|
|
9
|
-
import * as ts from
|
|
10
|
-
import { defineTool, createSuccessResult, createErrorResult } from
|
|
11
|
-
import { detectLanguage, isLanguageSupported } from
|
|
7
|
+
import * as fs from "node:fs/promises";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import * as ts from "typescript";
|
|
10
|
+
import { defineTool, createSuccessResult, createErrorResult, } from "@compilr-dev/agents";
|
|
11
|
+
import { detectLanguage, isLanguageSupported, } from "../parser/typescript-parser.js";
|
|
12
12
|
// Supported file extensions for searching
|
|
13
13
|
const SUPPORTED_EXTENSIONS = new Set([
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
".ts",
|
|
15
|
+
".tsx",
|
|
16
|
+
".js",
|
|
17
|
+
".jsx",
|
|
18
|
+
".mts",
|
|
19
|
+
".mjs",
|
|
20
|
+
".cts",
|
|
21
|
+
".cjs",
|
|
22
22
|
]);
|
|
23
23
|
// Tool description
|
|
24
24
|
const TOOL_DESCRIPTION = `Get detailed import information for a file or module.
|
|
@@ -26,39 +26,39 @@ Returns structured JSON with import sources, symbols, and whether imports are ex
|
|
|
26
26
|
Use this to understand a file's dependencies and what it imports from other modules.`;
|
|
27
27
|
// Tool input schema
|
|
28
28
|
const TOOL_INPUT_SCHEMA = {
|
|
29
|
-
type:
|
|
29
|
+
type: "object",
|
|
30
30
|
properties: {
|
|
31
31
|
path: {
|
|
32
|
-
type:
|
|
33
|
-
description:
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "File or directory to analyze",
|
|
34
34
|
},
|
|
35
35
|
recursive: {
|
|
36
|
-
type:
|
|
37
|
-
description:
|
|
36
|
+
type: "boolean",
|
|
37
|
+
description: "Recursively analyze directory (default: false)",
|
|
38
38
|
default: false,
|
|
39
39
|
},
|
|
40
40
|
filterSource: {
|
|
41
|
-
type:
|
|
42
|
-
description:
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Filter to specific import sources (partial match)",
|
|
43
43
|
},
|
|
44
44
|
transitive: {
|
|
45
|
-
type:
|
|
46
|
-
description:
|
|
45
|
+
type: "boolean",
|
|
46
|
+
description: "Include transitive imports (default: false)",
|
|
47
47
|
default: false,
|
|
48
48
|
},
|
|
49
49
|
maxDepth: {
|
|
50
|
-
type:
|
|
51
|
-
description:
|
|
50
|
+
type: "number",
|
|
51
|
+
description: "Max depth for transitive imports (default: 3)",
|
|
52
52
|
default: 3,
|
|
53
53
|
},
|
|
54
54
|
},
|
|
55
|
-
required: [
|
|
55
|
+
required: ["path"],
|
|
56
56
|
};
|
|
57
57
|
/**
|
|
58
58
|
* getImports tool - Get detailed import information
|
|
59
59
|
*/
|
|
60
60
|
export const getImportsTool = defineTool({
|
|
61
|
-
name:
|
|
61
|
+
name: "get_imports",
|
|
62
62
|
description: TOOL_DESCRIPTION,
|
|
63
63
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
64
64
|
execute: executeGetImports,
|
|
@@ -70,7 +70,7 @@ async function executeGetImports(input) {
|
|
|
70
70
|
const { path: inputPath, recursive = false, filterSource, transitive = false, maxDepth = 3, } = input;
|
|
71
71
|
// Validate input
|
|
72
72
|
if (!inputPath || inputPath.trim().length === 0) {
|
|
73
|
-
return createErrorResult(
|
|
73
|
+
return createErrorResult("Path is required");
|
|
74
74
|
}
|
|
75
75
|
try {
|
|
76
76
|
// Check if path exists
|
|
@@ -144,11 +144,11 @@ async function collectFiles(dir, recursive) {
|
|
|
144
144
|
if (!recursive)
|
|
145
145
|
continue;
|
|
146
146
|
// Skip node_modules and common non-source directories
|
|
147
|
-
if (entry.name ===
|
|
148
|
-
entry.name.startsWith(
|
|
149
|
-
entry.name ===
|
|
150
|
-
entry.name ===
|
|
151
|
-
entry.name ===
|
|
147
|
+
if (entry.name === "node_modules" ||
|
|
148
|
+
entry.name.startsWith(".") ||
|
|
149
|
+
entry.name === "dist" ||
|
|
150
|
+
entry.name === "build" ||
|
|
151
|
+
entry.name === "coverage") {
|
|
152
152
|
continue;
|
|
153
153
|
}
|
|
154
154
|
await walk(fullPath);
|
|
@@ -170,7 +170,7 @@ async function collectFiles(dir, recursive) {
|
|
|
170
170
|
async function analyzeFileImports(filePath) {
|
|
171
171
|
const imports = [];
|
|
172
172
|
try {
|
|
173
|
-
const sourceCode = await fs.readFile(filePath,
|
|
173
|
+
const sourceCode = await fs.readFile(filePath, "utf-8");
|
|
174
174
|
const scriptKind = getScriptKind(filePath);
|
|
175
175
|
const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true, scriptKind);
|
|
176
176
|
const fileDir = path.dirname(filePath);
|
|
@@ -201,7 +201,7 @@ function extractImportInfo(node, sourceFile, fileDir) {
|
|
|
201
201
|
// phaseModifier is directly the SyntaxKind value (TypeKeyword or DeferKeyword), not a node
|
|
202
202
|
const typeOnly = node.importClause?.phaseModifier === ts.SyntaxKind.TypeKeyword;
|
|
203
203
|
// Determine if external (doesn't start with . or /)
|
|
204
|
-
const isExternal = !source.startsWith(
|
|
204
|
+
const isExternal = !source.startsWith(".") && !source.startsWith("/");
|
|
205
205
|
// Try to resolve local imports
|
|
206
206
|
let resolvedPath;
|
|
207
207
|
if (!isExternal) {
|
|
@@ -243,7 +243,7 @@ function extractImportInfo(node, sourceFile, fileDir) {
|
|
|
243
243
|
// Side-effect import (no symbols)
|
|
244
244
|
if (symbols.length === 0) {
|
|
245
245
|
symbols.push({
|
|
246
|
-
name:
|
|
246
|
+
name: "*",
|
|
247
247
|
isDefault: false,
|
|
248
248
|
isNamespace: false,
|
|
249
249
|
});
|
|
@@ -269,7 +269,7 @@ function resolveLocalImport(source, fromDir) {
|
|
|
269
269
|
// Try with most likely TypeScript extensions first
|
|
270
270
|
// We don't check if file exists to avoid async issues
|
|
271
271
|
// Just return the most likely path (.ts is most common)
|
|
272
|
-
return basePath +
|
|
272
|
+
return basePath + ".ts";
|
|
273
273
|
}
|
|
274
274
|
/**
|
|
275
275
|
* Get transitive imports (imports of imports)
|
|
@@ -309,21 +309,21 @@ async function getTransitiveImports(rootFile, directImports, maxDepth) {
|
|
|
309
309
|
* Get TypeScript script kind from file extension
|
|
310
310
|
*/
|
|
311
311
|
function getScriptKind(filePath) {
|
|
312
|
-
const ext = filePath.toLowerCase().split(
|
|
312
|
+
const ext = filePath.toLowerCase().split(".").pop();
|
|
313
313
|
switch (ext) {
|
|
314
|
-
case
|
|
314
|
+
case "ts":
|
|
315
315
|
return ts.ScriptKind.TS;
|
|
316
|
-
case
|
|
316
|
+
case "tsx":
|
|
317
317
|
return ts.ScriptKind.TSX;
|
|
318
|
-
case
|
|
318
|
+
case "js":
|
|
319
319
|
return ts.ScriptKind.JS;
|
|
320
|
-
case
|
|
320
|
+
case "jsx":
|
|
321
321
|
return ts.ScriptKind.JSX;
|
|
322
|
-
case
|
|
323
|
-
case
|
|
322
|
+
case "mts":
|
|
323
|
+
case "cts":
|
|
324
324
|
return ts.ScriptKind.TS;
|
|
325
|
-
case
|
|
326
|
-
case
|
|
325
|
+
case "mjs":
|
|
326
|
+
case "cjs":
|
|
327
327
|
return ts.ScriptKind.JS;
|
|
328
328
|
default:
|
|
329
329
|
return ts.ScriptKind.TS;
|
|
@@ -335,7 +335,7 @@ function getScriptKind(filePath) {
|
|
|
335
335
|
export function createGetImportsTool(options) {
|
|
336
336
|
const { defaultRecursive = false, defaultTransitive = false, defaultMaxDepth = 3, } = options ?? {};
|
|
337
337
|
return defineTool({
|
|
338
|
-
name:
|
|
338
|
+
name: "get_imports",
|
|
339
339
|
description: TOOL_DESCRIPTION,
|
|
340
340
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
341
341
|
execute: async (input) => {
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Get detailed signature information for a function, method, class, or type.
|
|
5
5
|
* Includes parameters, return types, generics, and documentation.
|
|
6
6
|
*/
|
|
7
|
-
import type { Tool } from
|
|
8
|
-
import type { GetSignatureInput } from
|
|
7
|
+
import type { Tool } from "@compilr-dev/agents";
|
|
8
|
+
import type { GetSignatureInput } from "./types.js";
|
|
9
9
|
/**
|
|
10
10
|
* getSignature tool
|
|
11
11
|
*/
|