@compilr-dev/agents-coding-ts 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.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 +18 -5
- package/dist/skills/code-structure.js +15 -5
- package/dist/skills/dependency-audit.js +16 -5
- package/dist/skills/index.d.ts +7 -7
- package/dist/skills/index.js +11 -11
- package/dist/skills/refactor-impact.js +16 -5
- package/dist/skills/type-analysis.js +16 -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 +3 -3
|
@@ -4,21 +4,21 @@
|
|
|
4
4
|
* Find all usages of a symbol across the codebase.
|
|
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
|
// Helper to check for a specific modifier kind
|
|
24
24
|
function hasModifierKind(modifiers, kind) {
|
|
@@ -30,47 +30,47 @@ Returns structured JSON with file paths, line numbers, and reference types.
|
|
|
30
30
|
Use this to understand how a function, class, or variable is used throughout the project.`;
|
|
31
31
|
// Tool input schema
|
|
32
32
|
const TOOL_INPUT_SCHEMA = {
|
|
33
|
-
type:
|
|
33
|
+
type: "object",
|
|
34
34
|
properties: {
|
|
35
35
|
symbol: {
|
|
36
|
-
type:
|
|
37
|
-
description:
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Symbol name to find references for",
|
|
38
38
|
},
|
|
39
39
|
definitionFile: {
|
|
40
|
-
type:
|
|
41
|
-
description:
|
|
40
|
+
type: "string",
|
|
41
|
+
description: "File where the symbol is defined (improves accuracy)",
|
|
42
42
|
},
|
|
43
43
|
definitionLine: {
|
|
44
|
-
type:
|
|
45
|
-
description:
|
|
44
|
+
type: "number",
|
|
45
|
+
description: "Line where symbol is defined (improves accuracy)",
|
|
46
46
|
},
|
|
47
47
|
scope: {
|
|
48
|
-
type:
|
|
49
|
-
description:
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "Scope the search to a specific file or directory",
|
|
50
50
|
},
|
|
51
51
|
limit: {
|
|
52
|
-
type:
|
|
53
|
-
description:
|
|
52
|
+
type: "number",
|
|
53
|
+
description: "Maximum results to return (default: 50)",
|
|
54
54
|
default: 50,
|
|
55
55
|
},
|
|
56
56
|
includeDefinition: {
|
|
57
|
-
type:
|
|
58
|
-
description:
|
|
57
|
+
type: "boolean",
|
|
58
|
+
description: "Include the definition itself (default: false)",
|
|
59
59
|
default: false,
|
|
60
60
|
},
|
|
61
61
|
groupByFile: {
|
|
62
|
-
type:
|
|
63
|
-
description:
|
|
62
|
+
type: "boolean",
|
|
63
|
+
description: "Group results by file (default: true)",
|
|
64
64
|
default: true,
|
|
65
65
|
},
|
|
66
66
|
},
|
|
67
|
-
required: [
|
|
67
|
+
required: ["symbol"],
|
|
68
68
|
};
|
|
69
69
|
/**
|
|
70
70
|
* findReferences tool - Find all usages of a symbol
|
|
71
71
|
*/
|
|
72
72
|
export const findReferencesTool = defineTool({
|
|
73
|
-
name:
|
|
73
|
+
name: "find_references",
|
|
74
74
|
description: TOOL_DESCRIPTION,
|
|
75
75
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
76
76
|
execute: executeFindReferences,
|
|
@@ -82,7 +82,7 @@ async function executeFindReferences(input) {
|
|
|
82
82
|
const { symbol, definitionFile, definitionLine, scope, limit = 50, includeDefinition = false, groupByFile = true, } = input;
|
|
83
83
|
// Validate input
|
|
84
84
|
if (!symbol || symbol.trim().length === 0) {
|
|
85
|
-
return createErrorResult(
|
|
85
|
+
return createErrorResult("Symbol name is required");
|
|
86
86
|
}
|
|
87
87
|
const startTime = Date.now();
|
|
88
88
|
const allReferences = [];
|
|
@@ -172,11 +172,11 @@ async function collectFiles(dir) {
|
|
|
172
172
|
const fullPath = path.join(currentDir, entry.name);
|
|
173
173
|
if (entry.isDirectory()) {
|
|
174
174
|
// Skip node_modules and common non-source directories
|
|
175
|
-
if (entry.name ===
|
|
176
|
-
entry.name.startsWith(
|
|
177
|
-
entry.name ===
|
|
178
|
-
entry.name ===
|
|
179
|
-
entry.name ===
|
|
175
|
+
if (entry.name === "node_modules" ||
|
|
176
|
+
entry.name.startsWith(".") ||
|
|
177
|
+
entry.name === "dist" ||
|
|
178
|
+
entry.name === "build" ||
|
|
179
|
+
entry.name === "coverage") {
|
|
180
180
|
continue;
|
|
181
181
|
}
|
|
182
182
|
await walk(fullPath);
|
|
@@ -197,7 +197,7 @@ async function collectFiles(dir) {
|
|
|
197
197
|
*/
|
|
198
198
|
async function findDefinitionInFile(filePath, symbolName, targetLine) {
|
|
199
199
|
try {
|
|
200
|
-
const sourceCode = await fs.readFile(filePath,
|
|
200
|
+
const sourceCode = await fs.readFile(filePath, "utf-8");
|
|
201
201
|
const scriptKind = getScriptKind(filePath);
|
|
202
202
|
const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true, scriptKind);
|
|
203
203
|
let foundDef;
|
|
@@ -227,33 +227,35 @@ async function findDefinitionInFile(filePath, symbolName, targetLine) {
|
|
|
227
227
|
function tryExtractDefinition(node, sourceFile, symbolName, filePath) {
|
|
228
228
|
let name;
|
|
229
229
|
let kind;
|
|
230
|
-
const modifiers = ts.canHaveModifiers(node)
|
|
230
|
+
const modifiers = ts.canHaveModifiers(node)
|
|
231
|
+
? ts.getModifiers(node)
|
|
232
|
+
: undefined;
|
|
231
233
|
const exported = hasModifierKind(modifiers, ts.SyntaxKind.ExportKeyword);
|
|
232
234
|
if (ts.isFunctionDeclaration(node) && node.name?.text === symbolName) {
|
|
233
235
|
name = node.name.text;
|
|
234
|
-
kind =
|
|
236
|
+
kind = "function";
|
|
235
237
|
}
|
|
236
238
|
else if (ts.isClassDeclaration(node) && node.name?.text === symbolName) {
|
|
237
239
|
name = node.name.text;
|
|
238
|
-
kind =
|
|
240
|
+
kind = "class";
|
|
239
241
|
}
|
|
240
242
|
else if (ts.isInterfaceDeclaration(node) && node.name.text === symbolName) {
|
|
241
243
|
name = node.name.text;
|
|
242
|
-
kind =
|
|
244
|
+
kind = "interface";
|
|
243
245
|
}
|
|
244
246
|
else if (ts.isTypeAliasDeclaration(node) && node.name.text === symbolName) {
|
|
245
247
|
name = node.name.text;
|
|
246
|
-
kind =
|
|
248
|
+
kind = "type";
|
|
247
249
|
}
|
|
248
250
|
else if (ts.isEnumDeclaration(node) && node.name.text === symbolName) {
|
|
249
251
|
name = node.name.text;
|
|
250
|
-
kind =
|
|
252
|
+
kind = "enum";
|
|
251
253
|
}
|
|
252
254
|
else if (ts.isVariableDeclaration(node) &&
|
|
253
255
|
ts.isIdentifier(node.name) &&
|
|
254
256
|
node.name.text === symbolName) {
|
|
255
257
|
name = node.name.text;
|
|
256
|
-
kind =
|
|
258
|
+
kind = "variable";
|
|
257
259
|
}
|
|
258
260
|
if (name && kind) {
|
|
259
261
|
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
@@ -275,8 +277,8 @@ function tryExtractDefinition(node, sourceFile, symbolName, filePath) {
|
|
|
275
277
|
async function searchFileForReferences(filePath, symbolName, definition, includeDefinition) {
|
|
276
278
|
const references = [];
|
|
277
279
|
try {
|
|
278
|
-
const sourceCode = await fs.readFile(filePath,
|
|
279
|
-
const lines = sourceCode.split(
|
|
280
|
+
const sourceCode = await fs.readFile(filePath, "utf-8");
|
|
281
|
+
const lines = sourceCode.split("\n");
|
|
280
282
|
const scriptKind = getScriptKind(filePath);
|
|
281
283
|
const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true, scriptKind);
|
|
282
284
|
// Track current containing function for context
|
|
@@ -339,7 +341,7 @@ function tryExtractReference(node, sourceFile, symbolName, filePath, lines, cont
|
|
|
339
341
|
}
|
|
340
342
|
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
341
343
|
const lineIndex = line;
|
|
342
|
-
const context = lineIndex < lines.length ? lines[lineIndex].trim() :
|
|
344
|
+
const context = lineIndex < lines.length ? lines[lineIndex].trim() : "";
|
|
343
345
|
return {
|
|
344
346
|
path: filePath,
|
|
345
347
|
line: line + 1,
|
|
@@ -355,35 +357,37 @@ function tryExtractReference(node, sourceFile, symbolName, filePath, lines, cont
|
|
|
355
357
|
function determineReferenceType(node) {
|
|
356
358
|
const parent = node.parent;
|
|
357
359
|
// Import statement
|
|
358
|
-
if (ts.isImportSpecifier(parent) ||
|
|
359
|
-
|
|
360
|
+
if (ts.isImportSpecifier(parent) ||
|
|
361
|
+
ts.isImportClause(parent) ||
|
|
362
|
+
ts.isNamespaceImport(parent)) {
|
|
363
|
+
return "import";
|
|
360
364
|
}
|
|
361
365
|
// Export statement
|
|
362
366
|
if (ts.isExportSpecifier(parent) || ts.isExportAssignment(parent)) {
|
|
363
|
-
return
|
|
367
|
+
return "export";
|
|
364
368
|
}
|
|
365
369
|
// Type reference (in type annotations)
|
|
366
370
|
if (ts.isTypeReferenceNode(parent)) {
|
|
367
|
-
return
|
|
371
|
+
return "type";
|
|
368
372
|
}
|
|
369
373
|
// Extends clause
|
|
370
374
|
if (ts.isExpressionWithTypeArguments(parent)) {
|
|
371
375
|
const grandparent = parent.parent;
|
|
372
376
|
if (ts.isHeritageClause(grandparent)) {
|
|
373
377
|
if (grandparent.token === ts.SyntaxKind.ExtendsKeyword) {
|
|
374
|
-
return
|
|
378
|
+
return "extend";
|
|
375
379
|
}
|
|
376
380
|
// Use else for implements to avoid the "always true" comparison error
|
|
377
|
-
return
|
|
381
|
+
return "implement";
|
|
378
382
|
}
|
|
379
383
|
}
|
|
380
384
|
// Call expression
|
|
381
385
|
if (ts.isCallExpression(parent) && parent.expression === node) {
|
|
382
|
-
return
|
|
386
|
+
return "call";
|
|
383
387
|
}
|
|
384
388
|
// New expression
|
|
385
389
|
if (ts.isNewExpression(parent) && parent.expression === node) {
|
|
386
|
-
return
|
|
390
|
+
return "call";
|
|
387
391
|
}
|
|
388
392
|
// Property access (reading)
|
|
389
393
|
if (ts.isPropertyAccessExpression(parent) && parent.name === node) {
|
|
@@ -392,23 +396,23 @@ function determineReferenceType(node) {
|
|
|
392
396
|
if (ts.isBinaryExpression(grandparent) &&
|
|
393
397
|
grandparent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
394
398
|
grandparent.left === parent) {
|
|
395
|
-
return
|
|
399
|
+
return "write";
|
|
396
400
|
}
|
|
397
|
-
return
|
|
401
|
+
return "read";
|
|
398
402
|
}
|
|
399
403
|
// Variable declaration (definition, but also a "write")
|
|
400
404
|
if (ts.isVariableDeclaration(parent) && parent.name === node) {
|
|
401
|
-
return
|
|
405
|
+
return "write";
|
|
402
406
|
}
|
|
403
407
|
// Assignment expression
|
|
404
408
|
if (ts.isBinaryExpression(parent) &&
|
|
405
409
|
parent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
406
410
|
parent.left === node) {
|
|
407
|
-
return
|
|
411
|
+
return "write";
|
|
408
412
|
}
|
|
409
413
|
// Parameter declaration
|
|
410
414
|
if (ts.isParameter(parent)) {
|
|
411
|
-
return
|
|
415
|
+
return "write";
|
|
412
416
|
}
|
|
413
417
|
// Function/class/interface declaration (this is a definition)
|
|
414
418
|
if (ts.isFunctionDeclaration(parent) ||
|
|
@@ -419,10 +423,10 @@ function determineReferenceType(node) {
|
|
|
419
423
|
ts.isMethodDeclaration(parent) ||
|
|
420
424
|
ts.isPropertyDeclaration(parent)) {
|
|
421
425
|
// This is a definition, we'll include it based on includeDefinition flag
|
|
422
|
-
return
|
|
426
|
+
return "write";
|
|
423
427
|
}
|
|
424
428
|
// Default to read for other usages
|
|
425
|
-
return
|
|
429
|
+
return "read";
|
|
426
430
|
}
|
|
427
431
|
/**
|
|
428
432
|
* Group references by file
|
|
@@ -447,21 +451,21 @@ function groupReferencesByFile(references) {
|
|
|
447
451
|
* Get TypeScript script kind from file extension
|
|
448
452
|
*/
|
|
449
453
|
function getScriptKind(filePath) {
|
|
450
|
-
const ext = filePath.toLowerCase().split(
|
|
454
|
+
const ext = filePath.toLowerCase().split(".").pop();
|
|
451
455
|
switch (ext) {
|
|
452
|
-
case
|
|
456
|
+
case "ts":
|
|
453
457
|
return ts.ScriptKind.TS;
|
|
454
|
-
case
|
|
458
|
+
case "tsx":
|
|
455
459
|
return ts.ScriptKind.TSX;
|
|
456
|
-
case
|
|
460
|
+
case "js":
|
|
457
461
|
return ts.ScriptKind.JS;
|
|
458
|
-
case
|
|
462
|
+
case "jsx":
|
|
459
463
|
return ts.ScriptKind.JSX;
|
|
460
|
-
case
|
|
461
|
-
case
|
|
464
|
+
case "mts":
|
|
465
|
+
case "cts":
|
|
462
466
|
return ts.ScriptKind.TS;
|
|
463
|
-
case
|
|
464
|
-
case
|
|
467
|
+
case "mjs":
|
|
468
|
+
case "cjs":
|
|
465
469
|
return ts.ScriptKind.JS;
|
|
466
470
|
default:
|
|
467
471
|
return ts.ScriptKind.TS;
|
|
@@ -473,7 +477,7 @@ function getScriptKind(filePath) {
|
|
|
473
477
|
export function createFindReferencesTool(options) {
|
|
474
478
|
const { defaultLimit = 50, defaultGroupByFile = true, defaultIncludeDefinition = false, } = options ?? {};
|
|
475
479
|
return defineTool({
|
|
476
|
-
name:
|
|
480
|
+
name: "find_references",
|
|
477
481
|
description: TOOL_DESCRIPTION,
|
|
478
482
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
479
483
|
execute: async (input) => {
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Find the definition location of a symbol across the codebase.
|
|
5
5
|
* Uses TypeScript Compiler API for accurate AST analysis.
|
|
6
6
|
*/
|
|
7
|
-
import type { Tool } from
|
|
8
|
-
import type { FindSymbolInput } from
|
|
7
|
+
import type { Tool } from "@compilr-dev/agents";
|
|
8
|
+
import type { FindSymbolInput } from "./types.js";
|
|
9
9
|
/**
|
|
10
10
|
* findSymbol tool - Find symbol definitions
|
|
11
11
|
*/
|