@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,186 +4,186 @@
|
|
|
4
4
|
* Find code patterns, anti-patterns, and code smells in the codebase.
|
|
5
5
|
* Uses regex and AST-based pattern matching.
|
|
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 = `Find code patterns, anti-patterns, and code smells.
|
|
14
14
|
Searches for common issues like security vulnerabilities, performance problems, and maintainability concerns.
|
|
15
15
|
Supports built-in patterns or custom pattern definitions.`;
|
|
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: "Directory to analyze",
|
|
23
23
|
},
|
|
24
24
|
patterns: {
|
|
25
|
-
type:
|
|
26
|
-
description:
|
|
25
|
+
type: "array",
|
|
26
|
+
description: "Custom patterns to search for (uses built-in if not specified)",
|
|
27
27
|
items: {
|
|
28
|
-
type:
|
|
28
|
+
type: "object",
|
|
29
29
|
properties: {
|
|
30
|
-
name: { type:
|
|
31
|
-
description: { type:
|
|
32
|
-
type: { type:
|
|
33
|
-
matcher: { type:
|
|
34
|
-
severity: { type:
|
|
30
|
+
name: { type: "string" },
|
|
31
|
+
description: { type: "string" },
|
|
32
|
+
type: { type: "string" },
|
|
33
|
+
matcher: { type: "string" },
|
|
34
|
+
severity: { type: "string" },
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
},
|
|
38
38
|
categories: {
|
|
39
|
-
type:
|
|
40
|
-
description:
|
|
39
|
+
type: "array",
|
|
40
|
+
description: "Pattern categories to include (default: all)",
|
|
41
41
|
items: {
|
|
42
|
-
type:
|
|
43
|
-
enum: [
|
|
42
|
+
type: "string",
|
|
43
|
+
enum: ["security", "performance", "maintainability", "all"],
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
46
|
maxFiles: {
|
|
47
|
-
type:
|
|
48
|
-
description:
|
|
47
|
+
type: "number",
|
|
48
|
+
description: "Maximum files to analyze (default: 100)",
|
|
49
49
|
default: 100,
|
|
50
50
|
},
|
|
51
51
|
},
|
|
52
|
-
required: [
|
|
52
|
+
required: ["path"],
|
|
53
53
|
};
|
|
54
54
|
// Default exclusions
|
|
55
|
-
const DEFAULT_EXCLUDE = [
|
|
55
|
+
const DEFAULT_EXCLUDE = ["node_modules", "dist", "build", ".git", "coverage"];
|
|
56
56
|
// Built-in patterns
|
|
57
57
|
const BUILTIN_PATTERNS = [
|
|
58
58
|
// Security patterns
|
|
59
59
|
{
|
|
60
|
-
name:
|
|
61
|
-
description:
|
|
62
|
-
type:
|
|
63
|
-
matcher:
|
|
64
|
-
severity:
|
|
65
|
-
category:
|
|
60
|
+
name: "eval-usage",
|
|
61
|
+
description: "Use of eval() can lead to code injection vulnerabilities",
|
|
62
|
+
type: "anti-pattern",
|
|
63
|
+
matcher: "\\beval\\s*\\(",
|
|
64
|
+
severity: "error",
|
|
65
|
+
category: "security",
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
|
-
name:
|
|
69
|
-
description:
|
|
70
|
-
type:
|
|
71
|
-
matcher:
|
|
72
|
-
severity:
|
|
73
|
-
category:
|
|
68
|
+
name: "innerHTML-usage",
|
|
69
|
+
description: "innerHTML can lead to XSS vulnerabilities",
|
|
70
|
+
type: "anti-pattern",
|
|
71
|
+
matcher: "\\.innerHTML\\s*=",
|
|
72
|
+
severity: "warning",
|
|
73
|
+
category: "security",
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
|
-
name:
|
|
77
|
-
description:
|
|
78
|
-
type:
|
|
79
|
-
matcher:
|
|
80
|
-
severity:
|
|
81
|
-
category:
|
|
76
|
+
name: "hardcoded-secret",
|
|
77
|
+
description: "Potential hardcoded secret or API key",
|
|
78
|
+
type: "anti-pattern",
|
|
79
|
+
matcher: "(password|secret|api_key|apikey|token)\\s*[=:]\\s*[\"'][^\"']+[\"']",
|
|
80
|
+
severity: "error",
|
|
81
|
+
category: "security",
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
|
-
name:
|
|
85
|
-
description:
|
|
86
|
-
type:
|
|
87
|
-
matcher:
|
|
88
|
-
severity:
|
|
89
|
-
category:
|
|
84
|
+
name: "sql-injection-risk",
|
|
85
|
+
description: "String concatenation in SQL query (potential injection)",
|
|
86
|
+
type: "anti-pattern",
|
|
87
|
+
matcher: "(query|execute)\\s*\\(\\s*[`\"'].*\\$\\{",
|
|
88
|
+
severity: "error",
|
|
89
|
+
category: "security",
|
|
90
90
|
},
|
|
91
91
|
// Performance patterns
|
|
92
92
|
{
|
|
93
|
-
name:
|
|
94
|
-
description:
|
|
95
|
-
type:
|
|
96
|
-
matcher:
|
|
97
|
-
severity:
|
|
98
|
-
category:
|
|
93
|
+
name: "console-log",
|
|
94
|
+
description: "console.log left in code (should be removed in production)",
|
|
95
|
+
type: "smell",
|
|
96
|
+
matcher: "\\bconsole\\.(log|debug|info)\\s*\\(",
|
|
97
|
+
severity: "info",
|
|
98
|
+
category: "performance",
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
|
-
name:
|
|
102
|
-
description:
|
|
103
|
-
type:
|
|
104
|
-
matcher:
|
|
105
|
-
severity:
|
|
106
|
-
category:
|
|
101
|
+
name: "sync-fs-operations",
|
|
102
|
+
description: "Synchronous file system operations block the event loop",
|
|
103
|
+
type: "anti-pattern",
|
|
104
|
+
matcher: "\\b(readFileSync|writeFileSync|existsSync|statSync|readdirSync)\\s*\\(",
|
|
105
|
+
severity: "warning",
|
|
106
|
+
category: "performance",
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
|
-
name:
|
|
110
|
-
description:
|
|
111
|
-
type:
|
|
112
|
-
matcher:
|
|
113
|
-
severity:
|
|
114
|
-
category:
|
|
109
|
+
name: "nested-loops",
|
|
110
|
+
description: "Deeply nested loops may indicate O(n²) or worse complexity",
|
|
111
|
+
type: "smell",
|
|
112
|
+
matcher: "for\\s*\\([^)]+\\)\\s*\\{[^}]*for\\s*\\([^)]+\\)\\s*\\{[^}]*for\\s*\\(",
|
|
113
|
+
severity: "warning",
|
|
114
|
+
category: "performance",
|
|
115
115
|
},
|
|
116
116
|
{
|
|
117
|
-
name:
|
|
118
|
-
description:
|
|
119
|
-
type:
|
|
120
|
-
matcher:
|
|
121
|
-
severity:
|
|
122
|
-
category:
|
|
117
|
+
name: "await-in-loop",
|
|
118
|
+
description: "await inside loop may cause sequential execution instead of parallel",
|
|
119
|
+
type: "smell",
|
|
120
|
+
matcher: "(for|while)\\s*\\([^)]*\\)\\s*\\{[^}]*await\\b",
|
|
121
|
+
severity: "info",
|
|
122
|
+
category: "performance",
|
|
123
123
|
},
|
|
124
124
|
// Maintainability patterns
|
|
125
125
|
{
|
|
126
|
-
name:
|
|
127
|
-
description:
|
|
128
|
-
type:
|
|
129
|
-
matcher:
|
|
130
|
-
severity:
|
|
131
|
-
category:
|
|
126
|
+
name: "magic-number",
|
|
127
|
+
description: "Magic numbers should be named constants",
|
|
128
|
+
type: "smell",
|
|
129
|
+
matcher: "(?<!\\.)\\b(?!(0|1|2|10|100|1000)\\b)\\d{2,}\\b(?!\\.)",
|
|
130
|
+
severity: "info",
|
|
131
|
+
category: "maintainability",
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
|
-
name:
|
|
135
|
-
description:
|
|
136
|
-
type:
|
|
137
|
-
matcher:
|
|
138
|
-
severity:
|
|
139
|
-
category:
|
|
134
|
+
name: "todo-fixme",
|
|
135
|
+
description: "TODO or FIXME comment indicating incomplete work",
|
|
136
|
+
type: "smell",
|
|
137
|
+
matcher: "(TODO|FIXME|HACK|XXX)\\s*:?",
|
|
138
|
+
severity: "info",
|
|
139
|
+
category: "maintainability",
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
|
-
name:
|
|
142
|
+
name: "any-type",
|
|
143
143
|
description: 'Use of "any" type defeats TypeScript type checking',
|
|
144
|
-
type:
|
|
145
|
-
matcher:
|
|
146
|
-
severity:
|
|
147
|
-
category:
|
|
144
|
+
type: "smell",
|
|
145
|
+
matcher: ":\\s*any\\b",
|
|
146
|
+
severity: "warning",
|
|
147
|
+
category: "maintainability",
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
|
-
name:
|
|
151
|
-
description:
|
|
152
|
-
type:
|
|
153
|
-
matcher:
|
|
154
|
-
severity:
|
|
155
|
-
category:
|
|
150
|
+
name: "ts-ignore",
|
|
151
|
+
description: "@ts-ignore suppresses TypeScript errors",
|
|
152
|
+
type: "smell",
|
|
153
|
+
matcher: "@ts-ignore",
|
|
154
|
+
severity: "warning",
|
|
155
|
+
category: "maintainability",
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
|
-
name:
|
|
159
|
-
description:
|
|
160
|
-
type:
|
|
161
|
-
matcher:
|
|
162
|
-
severity:
|
|
163
|
-
category:
|
|
158
|
+
name: "eslint-disable",
|
|
159
|
+
description: "eslint-disable suppresses linting rules",
|
|
160
|
+
type: "smell",
|
|
161
|
+
matcher: "eslint-disable(?!-next-line)",
|
|
162
|
+
severity: "info",
|
|
163
|
+
category: "maintainability",
|
|
164
164
|
},
|
|
165
165
|
{
|
|
166
|
-
name:
|
|
167
|
-
description:
|
|
168
|
-
type:
|
|
169
|
-
matcher:
|
|
170
|
-
severity:
|
|
171
|
-
category:
|
|
166
|
+
name: "long-function",
|
|
167
|
+
description: "Function body exceeds recommended length",
|
|
168
|
+
type: "smell",
|
|
169
|
+
matcher: "AST:long-function",
|
|
170
|
+
severity: "warning",
|
|
171
|
+
category: "maintainability",
|
|
172
172
|
},
|
|
173
173
|
{
|
|
174
|
-
name:
|
|
175
|
-
description:
|
|
176
|
-
type:
|
|
177
|
-
matcher:
|
|
178
|
-
severity:
|
|
179
|
-
category:
|
|
174
|
+
name: "many-parameters",
|
|
175
|
+
description: "Function has too many parameters (consider using options object)",
|
|
176
|
+
type: "smell",
|
|
177
|
+
matcher: "AST:many-parameters",
|
|
178
|
+
severity: "info",
|
|
179
|
+
category: "maintainability",
|
|
180
180
|
},
|
|
181
181
|
];
|
|
182
182
|
/**
|
|
183
183
|
* findPatterns tool
|
|
184
184
|
*/
|
|
185
185
|
export const findPatternsTool = defineTool({
|
|
186
|
-
name:
|
|
186
|
+
name: "find_patterns",
|
|
187
187
|
description: TOOL_DESCRIPTION,
|
|
188
188
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
189
189
|
execute: executeFindPatterns,
|
|
@@ -192,7 +192,7 @@ export const findPatternsTool = defineTool({
|
|
|
192
192
|
* Execute the findPatterns tool
|
|
193
193
|
*/
|
|
194
194
|
async function executeFindPatterns(input) {
|
|
195
|
-
const { path: inputPath, patterns, categories = [
|
|
195
|
+
const { path: inputPath, patterns, categories = ["all"], maxFiles = 100, } = input;
|
|
196
196
|
try {
|
|
197
197
|
const resolvedPath = path.resolve(inputPath);
|
|
198
198
|
// Check if path exists
|
|
@@ -204,7 +204,7 @@ async function executeFindPatterns(input) {
|
|
|
204
204
|
}
|
|
205
205
|
const stats = await fs.stat(resolvedPath);
|
|
206
206
|
if (!stats.isDirectory()) {
|
|
207
|
-
return createErrorResult(
|
|
207
|
+
return createErrorResult("findPatterns requires a directory path");
|
|
208
208
|
}
|
|
209
209
|
// Determine which patterns to use
|
|
210
210
|
const patternsToUse = patterns ?? getBuiltinPatterns(categories);
|
|
@@ -224,9 +224,9 @@ async function executeFindPatterns(input) {
|
|
|
224
224
|
// Count by pattern and severity
|
|
225
225
|
for (const match of allMatches) {
|
|
226
226
|
byPattern[match.pattern] = (byPattern[match.pattern] ?? 0) + 1;
|
|
227
|
-
if (match.severity ===
|
|
227
|
+
if (match.severity === "error")
|
|
228
228
|
errorCount++;
|
|
229
|
-
else if (match.severity ===
|
|
229
|
+
else if (match.severity === "warning")
|
|
230
230
|
warningCount++;
|
|
231
231
|
else
|
|
232
232
|
infoCount++;
|
|
@@ -262,7 +262,7 @@ async function executeFindPatterns(input) {
|
|
|
262
262
|
* Get built-in patterns filtered by category
|
|
263
263
|
*/
|
|
264
264
|
function getBuiltinPatterns(categories) {
|
|
265
|
-
if (categories.includes(
|
|
265
|
+
if (categories.includes("all")) {
|
|
266
266
|
return BUILTIN_PATTERNS;
|
|
267
267
|
}
|
|
268
268
|
return BUILTIN_PATTERNS.filter((p) => categories.includes(p.category));
|
|
@@ -286,7 +286,8 @@ async function collectFiles(dirPath, files, maxFiles, currentDepth = 0) {
|
|
|
286
286
|
}
|
|
287
287
|
else if (entry.isFile()) {
|
|
288
288
|
// Only include TypeScript/JavaScript files
|
|
289
|
-
if (/\.(ts|tsx|js|jsx)$/.test(entry.name) &&
|
|
289
|
+
if (/\.(ts|tsx|js|jsx)$/.test(entry.name) &&
|
|
290
|
+
!entry.name.endsWith(".d.ts")) {
|
|
290
291
|
files.push(fullPath);
|
|
291
292
|
}
|
|
292
293
|
}
|
|
@@ -301,18 +302,18 @@ async function collectFiles(dirPath, files, maxFiles, currentDepth = 0) {
|
|
|
301
302
|
*/
|
|
302
303
|
async function analyzeFileForPatterns(filePath, patterns) {
|
|
303
304
|
try {
|
|
304
|
-
const content = await fs.readFile(filePath,
|
|
305
|
-
const lines = content.split(
|
|
305
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
306
|
+
const lines = content.split("\n");
|
|
306
307
|
const matches = [];
|
|
307
308
|
// Separate regex patterns from AST patterns
|
|
308
|
-
const regexPatterns = patterns.filter((p) => !p.matcher.startsWith(
|
|
309
|
-
const astPatterns = patterns.filter((p) => p.matcher.startsWith(
|
|
309
|
+
const regexPatterns = patterns.filter((p) => !p.matcher.startsWith("AST:"));
|
|
310
|
+
const astPatterns = patterns.filter((p) => p.matcher.startsWith("AST:"));
|
|
310
311
|
// Check regex patterns line by line
|
|
311
312
|
for (let i = 0; i < lines.length; i++) {
|
|
312
313
|
const line = lines[i];
|
|
313
314
|
for (const pattern of regexPatterns) {
|
|
314
315
|
try {
|
|
315
|
-
const regex = new RegExp(pattern.matcher,
|
|
316
|
+
const regex = new RegExp(pattern.matcher, "gi");
|
|
316
317
|
if (regex.test(line)) {
|
|
317
318
|
matches.push({
|
|
318
319
|
pattern: pattern.name,
|
|
@@ -351,9 +352,9 @@ function analyzeFileForAstPatterns(filePath, content, patterns) {
|
|
|
351
352
|
}
|
|
352
353
|
const matches = [];
|
|
353
354
|
try {
|
|
354
|
-
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, filePath.endsWith(
|
|
355
|
-
const checkLongFunction = patterns.some((p) => p.matcher ===
|
|
356
|
-
const checkManyParameters = patterns.some((p) => p.matcher ===
|
|
355
|
+
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, filePath.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
|
|
356
|
+
const checkLongFunction = patterns.some((p) => p.matcher === "AST:long-function");
|
|
357
|
+
const checkManyParameters = patterns.some((p) => p.matcher === "AST:many-parameters");
|
|
357
358
|
const visit = (node) => {
|
|
358
359
|
// Check long functions (>50 lines)
|
|
359
360
|
if (checkLongFunction) {
|
|
@@ -365,21 +366,22 @@ function analyzeFileForAstPatterns(filePath, content, patterns) {
|
|
|
365
366
|
const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
|
|
366
367
|
const lines = endLine - startLine;
|
|
367
368
|
if (lines > 50) {
|
|
368
|
-
let name =
|
|
369
|
+
let name = "<anonymous>";
|
|
369
370
|
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
370
371
|
name = node.name.text;
|
|
371
372
|
}
|
|
372
|
-
else if (ts.isMethodDeclaration(node) &&
|
|
373
|
+
else if (ts.isMethodDeclaration(node) &&
|
|
374
|
+
ts.isIdentifier(node.name)) {
|
|
373
375
|
name = node.name.text;
|
|
374
376
|
}
|
|
375
377
|
matches.push({
|
|
376
|
-
pattern:
|
|
378
|
+
pattern: "long-function",
|
|
377
379
|
description: `Function "${name}" has ${String(lines)} lines (recommended: <50)`,
|
|
378
|
-
severity:
|
|
380
|
+
severity: "warning",
|
|
379
381
|
path: filePath,
|
|
380
382
|
line: startLine + 1,
|
|
381
383
|
snippet: `function ${name}(...) { /* ${String(lines)} lines */ }`,
|
|
382
|
-
suggestion:
|
|
384
|
+
suggestion: "Consider breaking this function into smaller functions",
|
|
383
385
|
});
|
|
384
386
|
}
|
|
385
387
|
}
|
|
@@ -393,21 +395,22 @@ function analyzeFileForAstPatterns(filePath, content, patterns) {
|
|
|
393
395
|
const paramCount = node.parameters.length;
|
|
394
396
|
if (paramCount > 5) {
|
|
395
397
|
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
396
|
-
let name =
|
|
398
|
+
let name = "<anonymous>";
|
|
397
399
|
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
398
400
|
name = node.name.text;
|
|
399
401
|
}
|
|
400
|
-
else if (ts.isMethodDeclaration(node) &&
|
|
402
|
+
else if (ts.isMethodDeclaration(node) &&
|
|
403
|
+
ts.isIdentifier(node.name)) {
|
|
401
404
|
name = node.name.text;
|
|
402
405
|
}
|
|
403
406
|
matches.push({
|
|
404
|
-
pattern:
|
|
407
|
+
pattern: "many-parameters",
|
|
405
408
|
description: `Function "${name}" has ${String(paramCount)} parameters (recommended: <5)`,
|
|
406
|
-
severity:
|
|
409
|
+
severity: "info",
|
|
407
410
|
path: filePath,
|
|
408
411
|
line: line + 1,
|
|
409
412
|
snippet: `function ${name}(${String(paramCount)} params...)`,
|
|
410
|
-
suggestion:
|
|
413
|
+
suggestion: "Consider using an options object instead of many parameters",
|
|
411
414
|
});
|
|
412
415
|
}
|
|
413
416
|
}
|
|
@@ -426,14 +429,14 @@ function analyzeFileForAstPatterns(filePath, content, patterns) {
|
|
|
426
429
|
*/
|
|
427
430
|
function getSuggestion(patternName) {
|
|
428
431
|
const suggestions = {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
432
|
+
"eval-usage": "Use safer alternatives like JSON.parse() or Function constructor",
|
|
433
|
+
"innerHTML-usage": "Use textContent or sanitize HTML before insertion",
|
|
434
|
+
"hardcoded-secret": "Use environment variables or a secrets manager",
|
|
435
|
+
"sql-injection-risk": "Use parameterized queries or an ORM",
|
|
436
|
+
"console-log": "Remove or replace with proper logging",
|
|
437
|
+
"sync-fs-operations": "Use async versions like readFile, writeFile",
|
|
438
|
+
"any-type": "Use a specific type or unknown if type is truly unknown",
|
|
439
|
+
"ts-ignore": "Fix the underlying type issue instead of suppressing",
|
|
437
440
|
};
|
|
438
441
|
return suggestions[patternName];
|
|
439
442
|
}
|
|
@@ -442,14 +445,17 @@ function getSuggestion(patternName) {
|
|
|
442
445
|
*/
|
|
443
446
|
export function createFindPatternsTool(options) {
|
|
444
447
|
return defineTool({
|
|
445
|
-
name: options?.name ??
|
|
448
|
+
name: options?.name ?? "find_patterns",
|
|
446
449
|
description: options?.description ?? TOOL_DESCRIPTION,
|
|
447
450
|
inputSchema: TOOL_INPUT_SCHEMA,
|
|
448
451
|
execute: async (input) => {
|
|
449
452
|
const modifiedInput = {
|
|
450
453
|
...input,
|
|
451
454
|
maxFiles: input.maxFiles ?? options?.defaultMaxFiles,
|
|
452
|
-
patterns: input.patterns ?? [
|
|
455
|
+
patterns: input.patterns ?? [
|
|
456
|
+
...BUILTIN_PATTERNS,
|
|
457
|
+
...(options?.additionalPatterns ?? []),
|
|
458
|
+
],
|
|
453
459
|
};
|
|
454
460
|
return executeFindPatterns(modifiedInput);
|
|
455
461
|
},
|
|
@@ -4,8 +4,8 @@
|
|
|
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 type { Tool } from
|
|
8
|
-
import type { FindReferencesInput } from
|
|
7
|
+
import type { Tool } from "@compilr-dev/agents";
|
|
8
|
+
import type { FindReferencesInput } from "./types.js";
|
|
9
9
|
/**
|
|
10
10
|
* findReferences tool - Find all usages of a symbol
|
|
11
11
|
*/
|