@compilr-dev/agents-coding-ts 0.1.0
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/LICENSE +21 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +66 -0
- package/dist/parser/index.d.ts +7 -0
- package/dist/parser/index.js +6 -0
- package/dist/parser/typescript-parser.d.ts +22 -0
- package/dist/parser/typescript-parser.js +423 -0
- package/dist/skills/code-health.d.ts +9 -0
- package/dist/skills/code-health.js +167 -0
- package/dist/skills/code-structure.d.ts +9 -0
- package/dist/skills/code-structure.js +97 -0
- package/dist/skills/dependency-audit.d.ts +9 -0
- package/dist/skills/dependency-audit.js +110 -0
- package/dist/skills/index.d.ts +16 -0
- package/dist/skills/index.js +27 -0
- package/dist/skills/refactor-impact.d.ts +9 -0
- package/dist/skills/refactor-impact.js +135 -0
- package/dist/skills/type-analysis.d.ts +9 -0
- package/dist/skills/type-analysis.js +150 -0
- package/dist/tools/find-dead-code.d.ts +20 -0
- package/dist/tools/find-dead-code.js +375 -0
- package/dist/tools/find-duplicates.d.ts +21 -0
- package/dist/tools/find-duplicates.js +274 -0
- package/dist/tools/find-implementations.d.ts +21 -0
- package/dist/tools/find-implementations.js +436 -0
- package/dist/tools/find-patterns.d.ts +21 -0
- package/dist/tools/find-patterns.js +457 -0
- package/dist/tools/find-references.d.ts +23 -0
- package/dist/tools/find-references.js +488 -0
- package/dist/tools/find-symbol.d.ts +21 -0
- package/dist/tools/find-symbol.js +458 -0
- package/dist/tools/get-call-graph.d.ts +23 -0
- package/dist/tools/get-call-graph.js +469 -0
- package/dist/tools/get-complexity.d.ts +21 -0
- package/dist/tools/get-complexity.js +394 -0
- package/dist/tools/get-dependency-graph.d.ts +23 -0
- package/dist/tools/get-dependency-graph.js +482 -0
- package/dist/tools/get-documentation.d.ts +21 -0
- package/dist/tools/get-documentation.js +613 -0
- package/dist/tools/get-exports.d.ts +21 -0
- package/dist/tools/get-exports.js +427 -0
- package/dist/tools/get-file-structure.d.ts +27 -0
- package/dist/tools/get-file-structure.js +120 -0
- package/dist/tools/get-imports.d.ts +23 -0
- package/dist/tools/get-imports.js +350 -0
- package/dist/tools/get-signature.d.ts +20 -0
- package/dist/tools/get-signature.js +758 -0
- package/dist/tools/get-type-hierarchy.d.ts +22 -0
- package/dist/tools/get-type-hierarchy.js +485 -0
- package/dist/tools/index.d.ts +23 -0
- package/dist/tools/index.js +25 -0
- package/dist/tools/types.d.ts +1302 -0
- package/dist/tools/types.js +7 -0
- package/package.json +84 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* getComplexity Tool
|
|
3
|
+
*
|
|
4
|
+
* Calculate code complexity metrics including cyclomatic complexity,
|
|
5
|
+
* cognitive complexity, nesting depth, and identify complexity hotspots.
|
|
6
|
+
*/
|
|
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
|
+
// Tool description
|
|
13
|
+
const TOOL_DESCRIPTION = `Calculate code complexity metrics for files or directories.
|
|
14
|
+
Returns cyclomatic complexity, cognitive complexity, nesting depth, and identifies hotspots.
|
|
15
|
+
Useful for finding functions that may need refactoring.`;
|
|
16
|
+
// Tool input schema
|
|
17
|
+
const TOOL_INPUT_SCHEMA = {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
path: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
description: 'File or directory to analyze',
|
|
23
|
+
},
|
|
24
|
+
recursive: {
|
|
25
|
+
type: 'boolean',
|
|
26
|
+
description: 'Recursive analysis for directories (default: false)',
|
|
27
|
+
default: false,
|
|
28
|
+
},
|
|
29
|
+
threshold: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
description: 'Complexity threshold for warnings (default: 10)',
|
|
32
|
+
default: 10,
|
|
33
|
+
},
|
|
34
|
+
onlyAboveThreshold: {
|
|
35
|
+
type: 'boolean',
|
|
36
|
+
description: 'Only return items above threshold (default: false)',
|
|
37
|
+
default: false,
|
|
38
|
+
},
|
|
39
|
+
maxFiles: {
|
|
40
|
+
type: 'number',
|
|
41
|
+
description: 'Maximum files to analyze (default: 50)',
|
|
42
|
+
default: 50,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
required: ['path'],
|
|
46
|
+
};
|
|
47
|
+
// Default exclusions
|
|
48
|
+
const DEFAULT_EXCLUDE = ['node_modules', 'dist', 'build', '.git', 'coverage'];
|
|
49
|
+
/**
|
|
50
|
+
* getComplexity tool
|
|
51
|
+
*/
|
|
52
|
+
export const getComplexityTool = defineTool({
|
|
53
|
+
name: 'get_complexity',
|
|
54
|
+
description: TOOL_DESCRIPTION,
|
|
55
|
+
inputSchema: TOOL_INPUT_SCHEMA,
|
|
56
|
+
execute: executeGetComplexity,
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* Execute the getComplexity tool
|
|
60
|
+
*/
|
|
61
|
+
async function executeGetComplexity(input) {
|
|
62
|
+
const { path: inputPath, recursive = false, threshold = 10, onlyAboveThreshold = false, maxFiles = 50, } = input;
|
|
63
|
+
try {
|
|
64
|
+
const resolvedPath = path.resolve(inputPath);
|
|
65
|
+
// Check if path exists
|
|
66
|
+
try {
|
|
67
|
+
await fs.access(resolvedPath);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return createErrorResult(`Path not found: ${resolvedPath}`);
|
|
71
|
+
}
|
|
72
|
+
const stats = await fs.stat(resolvedPath);
|
|
73
|
+
const files = [];
|
|
74
|
+
if (stats.isDirectory()) {
|
|
75
|
+
await collectFiles(resolvedPath, files, recursive ? 10 : 1, maxFiles);
|
|
76
|
+
}
|
|
77
|
+
else if (stats.isFile()) {
|
|
78
|
+
files.push(resolvedPath);
|
|
79
|
+
}
|
|
80
|
+
// Analyze each file
|
|
81
|
+
const fileResults = [];
|
|
82
|
+
let totalFunctions = 0;
|
|
83
|
+
let totalComplexity = 0;
|
|
84
|
+
let maxComplexity = 0;
|
|
85
|
+
let aboveThresholdCount = 0;
|
|
86
|
+
const hotspots = [];
|
|
87
|
+
for (const file of files) {
|
|
88
|
+
const fileResult = await analyzeFile(file, threshold);
|
|
89
|
+
if (fileResult) {
|
|
90
|
+
// Filter if onlyAboveThreshold
|
|
91
|
+
if (onlyAboveThreshold) {
|
|
92
|
+
fileResult.functions = fileResult.functions.filter((f) => f.aboveThreshold);
|
|
93
|
+
if (fileResult.functions.length === 0)
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
fileResults.push(fileResult);
|
|
97
|
+
// Update stats
|
|
98
|
+
totalFunctions += fileResult.functions.length;
|
|
99
|
+
for (const func of fileResult.functions) {
|
|
100
|
+
totalComplexity += func.cyclomatic;
|
|
101
|
+
if (func.cyclomatic > maxComplexity) {
|
|
102
|
+
maxComplexity = func.cyclomatic;
|
|
103
|
+
}
|
|
104
|
+
if (func.aboveThreshold) {
|
|
105
|
+
aboveThresholdCount++;
|
|
106
|
+
}
|
|
107
|
+
// Track hotspots
|
|
108
|
+
hotspots.push({
|
|
109
|
+
name: func.name,
|
|
110
|
+
path: file,
|
|
111
|
+
line: func.line,
|
|
112
|
+
cyclomatic: func.cyclomatic,
|
|
113
|
+
cognitive: func.cognitive,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Sort hotspots by complexity and take top 5
|
|
119
|
+
hotspots.sort((a, b) => b.cyclomatic - a.cyclomatic);
|
|
120
|
+
const topHotspots = hotspots.slice(0, 5);
|
|
121
|
+
const result = {
|
|
122
|
+
path: resolvedPath,
|
|
123
|
+
files: fileResults,
|
|
124
|
+
summary: {
|
|
125
|
+
totalFiles: fileResults.length,
|
|
126
|
+
totalFunctions,
|
|
127
|
+
averageComplexity: totalFunctions > 0 ? Math.round((totalComplexity / totalFunctions) * 100) / 100 : 0,
|
|
128
|
+
maxComplexity,
|
|
129
|
+
aboveThreshold: aboveThresholdCount,
|
|
130
|
+
threshold,
|
|
131
|
+
},
|
|
132
|
+
hotspots: topHotspots,
|
|
133
|
+
};
|
|
134
|
+
return createSuccessResult(result);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return createErrorResult(`Failed to analyze complexity: ${error instanceof Error ? error.message : String(error)}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Collect files to analyze
|
|
142
|
+
*/
|
|
143
|
+
async function collectFiles(dirPath, files, maxDepth, maxFiles, currentDepth = 0) {
|
|
144
|
+
if (currentDepth > maxDepth || files.length >= maxFiles)
|
|
145
|
+
return;
|
|
146
|
+
try {
|
|
147
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
148
|
+
for (const entry of entries) {
|
|
149
|
+
if (files.length >= maxFiles)
|
|
150
|
+
break;
|
|
151
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
152
|
+
// Skip excluded directories
|
|
153
|
+
if (entry.isDirectory()) {
|
|
154
|
+
if (DEFAULT_EXCLUDE.includes(entry.name))
|
|
155
|
+
continue;
|
|
156
|
+
await collectFiles(fullPath, files, maxDepth, maxFiles, currentDepth + 1);
|
|
157
|
+
}
|
|
158
|
+
else if (entry.isFile()) {
|
|
159
|
+
// Only include TypeScript/JavaScript files
|
|
160
|
+
if (/\.(ts|tsx|js|jsx)$/.test(entry.name) && !entry.name.endsWith('.d.ts')) {
|
|
161
|
+
files.push(fullPath);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Ignore permission errors
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Analyze complexity of a single file
|
|
172
|
+
*/
|
|
173
|
+
async function analyzeFile(filePath, threshold) {
|
|
174
|
+
try {
|
|
175
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
176
|
+
const detection = detectLanguage(filePath);
|
|
177
|
+
if (!detection.language || !isLanguageSupported(detection.language)) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, filePath.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
|
|
181
|
+
const functions = [];
|
|
182
|
+
let classCount = 0;
|
|
183
|
+
// Visit all nodes
|
|
184
|
+
const visit = (node) => {
|
|
185
|
+
// Track classes
|
|
186
|
+
if (ts.isClassDeclaration(node)) {
|
|
187
|
+
classCount++;
|
|
188
|
+
}
|
|
189
|
+
// Analyze functions
|
|
190
|
+
if (ts.isFunctionDeclaration(node) ||
|
|
191
|
+
ts.isMethodDeclaration(node) ||
|
|
192
|
+
ts.isFunctionExpression(node) ||
|
|
193
|
+
ts.isArrowFunction(node)) {
|
|
194
|
+
const funcComplexity = analyzeFunctionComplexity(node, sourceFile, threshold);
|
|
195
|
+
if (funcComplexity) {
|
|
196
|
+
functions.push(funcComplexity);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
ts.forEachChild(node, visit);
|
|
200
|
+
};
|
|
201
|
+
visit(sourceFile);
|
|
202
|
+
// Calculate file metrics
|
|
203
|
+
const lines = content.split('\n');
|
|
204
|
+
const totalLines = lines.length;
|
|
205
|
+
const blankLines = lines.filter((l) => l.trim() === '').length;
|
|
206
|
+
const linesOfCode = totalLines - blankLines;
|
|
207
|
+
const avgComplexity = functions.length > 0
|
|
208
|
+
? Math.round((functions.reduce((sum, f) => sum + f.cyclomatic, 0) / functions.length) * 100) / 100
|
|
209
|
+
: 0;
|
|
210
|
+
const maxComplexity = functions.length > 0 ? Math.max(...functions.map((f) => f.cyclomatic)) : 0;
|
|
211
|
+
return {
|
|
212
|
+
path: filePath,
|
|
213
|
+
metrics: {
|
|
214
|
+
lines: totalLines,
|
|
215
|
+
linesOfCode,
|
|
216
|
+
functions: functions.length,
|
|
217
|
+
classes: classCount,
|
|
218
|
+
avgComplexity,
|
|
219
|
+
maxComplexity,
|
|
220
|
+
},
|
|
221
|
+
functions,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Analyze complexity of a single function
|
|
230
|
+
*/
|
|
231
|
+
function analyzeFunctionComplexity(node, sourceFile, threshold) {
|
|
232
|
+
// Get function name
|
|
233
|
+
let name = '<anonymous>';
|
|
234
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
235
|
+
name = node.name.text;
|
|
236
|
+
}
|
|
237
|
+
else if (ts.isMethodDeclaration(node)) {
|
|
238
|
+
name = ts.isIdentifier(node.name) ? node.name.text : '<computed>';
|
|
239
|
+
}
|
|
240
|
+
else if (ts.isFunctionExpression(node) && node.name) {
|
|
241
|
+
name = node.name.text;
|
|
242
|
+
}
|
|
243
|
+
else if (ts.isArrowFunction(node)) {
|
|
244
|
+
// Try to get name from parent variable declaration
|
|
245
|
+
const parent = node.parent;
|
|
246
|
+
if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
|
|
247
|
+
name = parent.name.text;
|
|
248
|
+
}
|
|
249
|
+
else if (ts.isPropertyAssignment(parent) && ts.isIdentifier(parent.name)) {
|
|
250
|
+
name = parent.name.text;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Skip anonymous functions in certain contexts
|
|
254
|
+
if (name === '<anonymous>') {
|
|
255
|
+
// Only include top-level anonymous functions or named expressions
|
|
256
|
+
const parent = node.parent;
|
|
257
|
+
if (!ts.isVariableDeclaration(parent) && !ts.isPropertyAssignment(parent)) {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const body = ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isFunctionExpression(node)
|
|
262
|
+
? node.body
|
|
263
|
+
: node.body;
|
|
264
|
+
if (!body)
|
|
265
|
+
return null;
|
|
266
|
+
// Get position info
|
|
267
|
+
const { line: startLine } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
268
|
+
const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
|
|
269
|
+
// Calculate complexities
|
|
270
|
+
const contributors = [];
|
|
271
|
+
let cyclomatic = 1; // Start at 1
|
|
272
|
+
let cognitive = 0;
|
|
273
|
+
let maxNesting = 0;
|
|
274
|
+
const analyzeNode = (n, nestingLevel) => {
|
|
275
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(n.getStart());
|
|
276
|
+
// Track max nesting
|
|
277
|
+
if (nestingLevel > maxNesting) {
|
|
278
|
+
maxNesting = nestingLevel;
|
|
279
|
+
}
|
|
280
|
+
// Cyclomatic complexity contributors
|
|
281
|
+
if (ts.isIfStatement(n)) {
|
|
282
|
+
cyclomatic++;
|
|
283
|
+
cognitive += 1 + nestingLevel; // Cognitive adds nesting penalty
|
|
284
|
+
contributors.push({ type: 'if', line: line + 1, contribution: 1 + nestingLevel });
|
|
285
|
+
}
|
|
286
|
+
else if (ts.isConditionalExpression(n)) {
|
|
287
|
+
cyclomatic++;
|
|
288
|
+
cognitive += 1 + nestingLevel;
|
|
289
|
+
contributors.push({ type: 'ternary', line: line + 1, contribution: 1 + nestingLevel });
|
|
290
|
+
}
|
|
291
|
+
else if (ts.isForStatement(n) || ts.isForInStatement(n) || ts.isForOfStatement(n)) {
|
|
292
|
+
cyclomatic++;
|
|
293
|
+
cognitive += 1 + nestingLevel;
|
|
294
|
+
contributors.push({ type: 'for', line: line + 1, contribution: 1 + nestingLevel });
|
|
295
|
+
}
|
|
296
|
+
else if (ts.isWhileStatement(n)) {
|
|
297
|
+
cyclomatic++;
|
|
298
|
+
cognitive += 1 + nestingLevel;
|
|
299
|
+
contributors.push({ type: 'while', line: line + 1, contribution: 1 + nestingLevel });
|
|
300
|
+
}
|
|
301
|
+
else if (ts.isDoStatement(n)) {
|
|
302
|
+
cyclomatic++;
|
|
303
|
+
cognitive += 1 + nestingLevel;
|
|
304
|
+
contributors.push({ type: 'do', line: line + 1, contribution: 1 + nestingLevel });
|
|
305
|
+
}
|
|
306
|
+
else if (ts.isSwitchStatement(n)) {
|
|
307
|
+
cyclomatic++;
|
|
308
|
+
cognitive += 1 + nestingLevel;
|
|
309
|
+
contributors.push({ type: 'switch', line: line + 1, contribution: 1 + nestingLevel });
|
|
310
|
+
}
|
|
311
|
+
else if (ts.isCaseClause(n)) {
|
|
312
|
+
cyclomatic++;
|
|
313
|
+
contributors.push({ type: 'case', line: line + 1, contribution: 1 });
|
|
314
|
+
}
|
|
315
|
+
else if (ts.isCatchClause(n)) {
|
|
316
|
+
cyclomatic++;
|
|
317
|
+
cognitive += 1 + nestingLevel;
|
|
318
|
+
contributors.push({ type: 'catch', line: line + 1, contribution: 1 + nestingLevel });
|
|
319
|
+
}
|
|
320
|
+
else if (ts.isBinaryExpression(n)) {
|
|
321
|
+
if (n.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
322
|
+
cyclomatic++;
|
|
323
|
+
cognitive++;
|
|
324
|
+
contributors.push({ type: 'logical_and', line: line + 1, contribution: 1 });
|
|
325
|
+
}
|
|
326
|
+
else if (n.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
|
|
327
|
+
cyclomatic++;
|
|
328
|
+
cognitive++;
|
|
329
|
+
contributors.push({ type: 'logical_or', line: line + 1, contribution: 1 });
|
|
330
|
+
}
|
|
331
|
+
else if (n.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
332
|
+
cyclomatic++;
|
|
333
|
+
cognitive++;
|
|
334
|
+
contributors.push({ type: 'nullish', line: line + 1, contribution: 1 });
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// Increase nesting for blocks
|
|
338
|
+
const newNesting = isNestingNode(n) ? nestingLevel + 1 : nestingLevel;
|
|
339
|
+
ts.forEachChild(n, (child) => {
|
|
340
|
+
analyzeNode(child, newNesting);
|
|
341
|
+
});
|
|
342
|
+
};
|
|
343
|
+
analyzeNode(body, 0);
|
|
344
|
+
// Calculate LOC
|
|
345
|
+
const bodyText = body.getText(sourceFile);
|
|
346
|
+
const bodyLines = bodyText.split('\n').filter((l) => l.trim() !== '').length;
|
|
347
|
+
// Parameter count
|
|
348
|
+
const parameterCount = node.parameters.length;
|
|
349
|
+
const aboveThreshold = cyclomatic >= threshold;
|
|
350
|
+
return {
|
|
351
|
+
name,
|
|
352
|
+
line: startLine + 1,
|
|
353
|
+
endLine: endLine + 1,
|
|
354
|
+
cyclomatic,
|
|
355
|
+
cognitive,
|
|
356
|
+
maxNesting,
|
|
357
|
+
loc: bodyLines,
|
|
358
|
+
parameterCount,
|
|
359
|
+
aboveThreshold,
|
|
360
|
+
contributors: aboveThreshold ? contributors : undefined,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Check if a node increases nesting level
|
|
365
|
+
*/
|
|
366
|
+
function isNestingNode(node) {
|
|
367
|
+
return (ts.isIfStatement(node) ||
|
|
368
|
+
ts.isForStatement(node) ||
|
|
369
|
+
ts.isForInStatement(node) ||
|
|
370
|
+
ts.isForOfStatement(node) ||
|
|
371
|
+
ts.isWhileStatement(node) ||
|
|
372
|
+
ts.isDoStatement(node) ||
|
|
373
|
+
ts.isSwitchStatement(node) ||
|
|
374
|
+
ts.isTryStatement(node) ||
|
|
375
|
+
ts.isCatchClause(node));
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Create customizable getComplexity tool
|
|
379
|
+
*/
|
|
380
|
+
export function createGetComplexityTool(options) {
|
|
381
|
+
return defineTool({
|
|
382
|
+
name: options?.name ?? 'get_complexity',
|
|
383
|
+
description: options?.description ?? TOOL_DESCRIPTION,
|
|
384
|
+
inputSchema: TOOL_INPUT_SCHEMA,
|
|
385
|
+
execute: async (input) => {
|
|
386
|
+
const modifiedInput = {
|
|
387
|
+
...input,
|
|
388
|
+
threshold: input.threshold ?? options?.defaultThreshold,
|
|
389
|
+
maxFiles: input.maxFiles ?? options?.defaultMaxFiles,
|
|
390
|
+
};
|
|
391
|
+
return executeGetComplexity(modifiedInput);
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* getDependencyGraph Tool
|
|
3
|
+
*
|
|
4
|
+
* Analyze module-level dependencies across a directory.
|
|
5
|
+
* Builds a dependency graph and detects circular dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import type { Tool } from '@compilr-dev/agents';
|
|
8
|
+
import type { GetDependencyGraphInput } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* getDependencyGraph tool - Analyze module dependencies
|
|
11
|
+
*/
|
|
12
|
+
export declare const getDependencyGraphTool: Tool<GetDependencyGraphInput>;
|
|
13
|
+
/**
|
|
14
|
+
* Factory function to create a customized getDependencyGraph tool
|
|
15
|
+
*/
|
|
16
|
+
export declare function createGetDependencyGraphTool(options?: {
|
|
17
|
+
/** Default includeExternal */
|
|
18
|
+
defaultIncludeExternal?: boolean;
|
|
19
|
+
/** Default includeTypeOnly */
|
|
20
|
+
defaultIncludeTypeOnly?: boolean;
|
|
21
|
+
/** Default maxDepth */
|
|
22
|
+
defaultMaxDepth?: number;
|
|
23
|
+
}): Tool<GetDependencyGraphInput>;
|