@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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +34 -0
  3. package/dist/index.js +66 -0
  4. package/dist/parser/index.d.ts +7 -0
  5. package/dist/parser/index.js +6 -0
  6. package/dist/parser/typescript-parser.d.ts +22 -0
  7. package/dist/parser/typescript-parser.js +423 -0
  8. package/dist/skills/code-health.d.ts +9 -0
  9. package/dist/skills/code-health.js +167 -0
  10. package/dist/skills/code-structure.d.ts +9 -0
  11. package/dist/skills/code-structure.js +97 -0
  12. package/dist/skills/dependency-audit.d.ts +9 -0
  13. package/dist/skills/dependency-audit.js +110 -0
  14. package/dist/skills/index.d.ts +16 -0
  15. package/dist/skills/index.js +27 -0
  16. package/dist/skills/refactor-impact.d.ts +9 -0
  17. package/dist/skills/refactor-impact.js +135 -0
  18. package/dist/skills/type-analysis.d.ts +9 -0
  19. package/dist/skills/type-analysis.js +150 -0
  20. package/dist/tools/find-dead-code.d.ts +20 -0
  21. package/dist/tools/find-dead-code.js +375 -0
  22. package/dist/tools/find-duplicates.d.ts +21 -0
  23. package/dist/tools/find-duplicates.js +274 -0
  24. package/dist/tools/find-implementations.d.ts +21 -0
  25. package/dist/tools/find-implementations.js +436 -0
  26. package/dist/tools/find-patterns.d.ts +21 -0
  27. package/dist/tools/find-patterns.js +457 -0
  28. package/dist/tools/find-references.d.ts +23 -0
  29. package/dist/tools/find-references.js +488 -0
  30. package/dist/tools/find-symbol.d.ts +21 -0
  31. package/dist/tools/find-symbol.js +458 -0
  32. package/dist/tools/get-call-graph.d.ts +23 -0
  33. package/dist/tools/get-call-graph.js +469 -0
  34. package/dist/tools/get-complexity.d.ts +21 -0
  35. package/dist/tools/get-complexity.js +394 -0
  36. package/dist/tools/get-dependency-graph.d.ts +23 -0
  37. package/dist/tools/get-dependency-graph.js +482 -0
  38. package/dist/tools/get-documentation.d.ts +21 -0
  39. package/dist/tools/get-documentation.js +613 -0
  40. package/dist/tools/get-exports.d.ts +21 -0
  41. package/dist/tools/get-exports.js +427 -0
  42. package/dist/tools/get-file-structure.d.ts +27 -0
  43. package/dist/tools/get-file-structure.js +120 -0
  44. package/dist/tools/get-imports.d.ts +23 -0
  45. package/dist/tools/get-imports.js +350 -0
  46. package/dist/tools/get-signature.d.ts +20 -0
  47. package/dist/tools/get-signature.js +758 -0
  48. package/dist/tools/get-type-hierarchy.d.ts +22 -0
  49. package/dist/tools/get-type-hierarchy.js +485 -0
  50. package/dist/tools/index.d.ts +23 -0
  51. package/dist/tools/index.js +25 -0
  52. package/dist/tools/types.d.ts +1302 -0
  53. package/dist/tools/types.js +7 -0
  54. package/package.json +84 -0
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Type Analysis Skill
3
+ *
4
+ * Analyze type hierarchies, interfaces, and their implementations.
5
+ */
6
+ import { defineSkill } from '@compilr-dev/agents';
7
+ /**
8
+ * Type analysis skill - Analyze type hierarchies and implementations
9
+ */
10
+ export const typeAnalysisSkill = defineSkill({
11
+ name: 'type-analysis',
12
+ description: 'Analyze type hierarchies, interfaces, and their implementations',
13
+ prompt: `You are in TYPE ANALYSIS mode. Analyze type relationships in the codebase.
14
+
15
+ ## TOOLS TO USE
16
+
17
+ 1. **get_type_hierarchy**: Analyze inheritance relationships
18
+ - Find what a class/interface extends
19
+ - Find what extends/implements a class/interface
20
+ - Trace the full inheritance chain
21
+ - Identify abstract vs concrete types
22
+
23
+ 2. **find_implementations**: Find concrete implementations
24
+ - Find all classes implementing an interface
25
+ - Find all classes extending an abstract class
26
+ - See which methods are implemented
27
+ - Identify partial implementations
28
+
29
+ ## ANALYSIS WORKFLOW
30
+
31
+ ### For Interfaces
32
+ \`\`\`
33
+ // Step 1: Get the interface hierarchy
34
+ get_type_hierarchy({
35
+ path: "/path/to/file.ts",
36
+ typeName: "IMyInterface",
37
+ direction: "descendants" // Find implementors
38
+ })
39
+
40
+ // Step 2: Find all implementations
41
+ find_implementations({
42
+ name: "IMyInterface",
43
+ scope: "/path/to/project",
44
+ includeAbstract: false // Only concrete implementations
45
+ })
46
+ \`\`\`
47
+
48
+ ### For Abstract Classes
49
+ \`\`\`
50
+ // Step 1: Get class hierarchy
51
+ get_type_hierarchy({
52
+ path: "/path/to/file.ts",
53
+ typeName: "AbstractBase",
54
+ direction: "both" // See parents and children
55
+ })
56
+
57
+ // Step 2: Find concrete implementations
58
+ find_implementations({
59
+ name: "AbstractBase",
60
+ scope: "/path/to/project",
61
+ includeAbstract: true // Include abstract subclasses too
62
+ })
63
+ \`\`\`
64
+
65
+ ### For Concrete Classes
66
+ \`\`\`
67
+ // Understand what it inherits from
68
+ get_type_hierarchy({
69
+ path: "/path/to/file.ts",
70
+ typeName: "MyClass",
71
+ direction: "ancestors" // See parent chain
72
+ })
73
+ \`\`\`
74
+
75
+ ## OUTPUT FORMAT
76
+
77
+ ### Type Overview
78
+ | Property | Value |
79
+ |----------|-------|
80
+ | Name | \`TypeName\` |
81
+ | Kind | interface / abstract class / class |
82
+ | Defined in | path/to/file.ts:42 |
83
+ | Exported | Yes / No |
84
+ | Generic | Yes (T, K) / No |
85
+
86
+ ### Inheritance Chain (ancestors)
87
+ \`\`\`
88
+ TypeName
89
+ └── extends ParentClass
90
+ └── extends GrandparentClass
91
+ └── implements IBaseInterface
92
+ \`\`\`
93
+
94
+ ### Implementations (descendants)
95
+ | Class | File | Status | Missing Methods |
96
+ |-------|------|--------|-----------------|
97
+ | ConcreteA | src/a.ts:10 | ✅ Complete | - |
98
+ | ConcreteB | src/b.ts:25 | ⚠️ Partial | method1, method2 |
99
+ | AbstractC | src/c.ts:5 | 🔷 Abstract | method3 |
100
+
101
+ ### Interface Contract
102
+ | Method | Implementations | Notes |
103
+ |--------|-----------------|-------|
104
+ | \`doSomething()\` | 5/5 | All implement |
105
+ | \`optionalMethod?()\` | 2/5 | Optional, partially implemented |
106
+
107
+ ### Type Relationships Diagram
108
+ \`\`\`
109
+ ISerializable
110
+
111
+ ┌────────────┼────────────┐
112
+ │ │ │
113
+ IEntity IDocument IMessage
114
+ │ │
115
+ ┌────┴────┐ │
116
+ │ │ │
117
+ User Product Report
118
+ \`\`\`
119
+
120
+ ### Analysis Summary
121
+ - **Total implementations**: N classes implement this interface
122
+ - **Complete implementations**: X (Y%)
123
+ - **Partial implementations**: Z (list missing methods)
124
+ - **Abstract subclasses**: W
125
+
126
+ ### Recommendations
127
+ 1. Classes with missing methods that need attention
128
+ 2. Potential interface segregation opportunities
129
+ 3. Deep inheritance chains that could be simplified
130
+
131
+ ## COMMON QUESTIONS THIS SKILL ANSWERS
132
+
133
+ - "What implements IRepository?" → find_implementations
134
+ - "What does UserService extend?" → get_type_hierarchy (ancestors)
135
+ - "What are all the event handlers?" → find_implementations for IEventHandler
136
+ - "Show me the class hierarchy" → get_type_hierarchy (both)
137
+ - "Which classes are missing method X?" → find_implementations (check missingMethods)
138
+
139
+ ## RULES
140
+
141
+ - Always identify the type kind first (interface, abstract, concrete)
142
+ - For interfaces: focus on implementations
143
+ - For abstract classes: show both hierarchy and implementations
144
+ - For concrete classes: focus on what they inherit
145
+ - Highlight incomplete implementations
146
+ - Note generic type parameters when present
147
+ - Keep diagrams simple - expand on request`,
148
+ tags: ['types', 'analysis', 'inheritance', 'interfaces', 'architecture'],
149
+ version: '1.0.0',
150
+ });
@@ -0,0 +1,20 @@
1
+ /**
2
+ * findDeadCode Tool
3
+ *
4
+ * Find potentially unused exports, functions, and variables across a codebase.
5
+ * Uses static analysis to identify code that may be dead.
6
+ */
7
+ import type { Tool } from '@compilr-dev/agents';
8
+ import type { FindDeadCodeInput } from './types.js';
9
+ /**
10
+ * findDeadCode tool
11
+ */
12
+ export declare const findDeadCodeTool: Tool<FindDeadCodeInput>;
13
+ /**
14
+ * Create customizable findDeadCode tool
15
+ */
16
+ export declare function createFindDeadCodeTool(options?: {
17
+ name?: string;
18
+ description?: string;
19
+ defaultMaxFiles?: number;
20
+ }): Tool<FindDeadCodeInput>;
@@ -0,0 +1,375 @@
1
+ /**
2
+ * findDeadCode Tool
3
+ *
4
+ * Find potentially unused exports, functions, and variables across a codebase.
5
+ * Uses static analysis to identify code that may be dead.
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 = `Find potentially unused exports, functions, and variables.
14
+ Analyzes the codebase to identify code that may be dead (never used).
15
+ Useful for cleanup and reducing bundle size.`;
16
+ // Tool input schema
17
+ const TOOL_INPUT_SCHEMA = {
18
+ type: 'object',
19
+ properties: {
20
+ path: {
21
+ type: 'string',
22
+ description: 'Directory to analyze',
23
+ },
24
+ includeTests: {
25
+ type: 'boolean',
26
+ description: 'Include test files in analysis (default: false)',
27
+ default: false,
28
+ },
29
+ checkExports: {
30
+ type: 'boolean',
31
+ description: 'Check for unused exports (default: true)',
32
+ default: true,
33
+ },
34
+ checkFunctions: {
35
+ type: 'boolean',
36
+ description: 'Check for unused functions (default: true)',
37
+ default: true,
38
+ },
39
+ checkVariables: {
40
+ type: 'boolean',
41
+ description: 'Check for unused variables (default: false)',
42
+ default: false,
43
+ },
44
+ maxFiles: {
45
+ type: 'number',
46
+ description: 'Maximum files to analyze (default: 100)',
47
+ default: 100,
48
+ },
49
+ },
50
+ required: ['path'],
51
+ };
52
+ // Default exclusions
53
+ const DEFAULT_EXCLUDE = ['node_modules', 'dist', 'build', '.git', 'coverage'];
54
+ const TEST_PATTERNS = ['.test.', '.spec.', '__tests__', '__mocks__'];
55
+ /**
56
+ * findDeadCode tool
57
+ */
58
+ export const findDeadCodeTool = defineTool({
59
+ name: 'find_dead_code',
60
+ description: TOOL_DESCRIPTION,
61
+ inputSchema: TOOL_INPUT_SCHEMA,
62
+ execute: executeFindDeadCode,
63
+ });
64
+ /**
65
+ * Execute the findDeadCode tool
66
+ */
67
+ async function executeFindDeadCode(input) {
68
+ const { path: inputPath, includeTests = false, checkExports = true, checkFunctions = true, checkVariables = false, maxFiles = 100, } = input;
69
+ try {
70
+ const resolvedPath = path.resolve(inputPath);
71
+ // Check if path exists
72
+ try {
73
+ await fs.access(resolvedPath);
74
+ }
75
+ catch {
76
+ return createErrorResult(`Path not found: ${resolvedPath}`);
77
+ }
78
+ const stats = await fs.stat(resolvedPath);
79
+ if (!stats.isDirectory()) {
80
+ return createErrorResult('findDeadCode requires a directory path');
81
+ }
82
+ // Collect files
83
+ const files = [];
84
+ await collectFiles(resolvedPath, files, includeTests, maxFiles);
85
+ // Build symbol index
86
+ const definitions = [];
87
+ const usages = new Set();
88
+ const importedSymbols = new Set();
89
+ // First pass: collect all definitions and usages
90
+ for (const file of files) {
91
+ await analyzeFile(file, definitions, usages, importedSymbols);
92
+ }
93
+ // Find dead code
94
+ const deadCode = [];
95
+ // Stats
96
+ let totalExports = 0;
97
+ let unusedExports = 0;
98
+ let totalFunctions = 0;
99
+ let unusedFunctions = 0;
100
+ let totalVariables = 0;
101
+ let unusedVariables = 0;
102
+ for (const def of definitions) {
103
+ // Skip index files (re-exports)
104
+ if (def.path.endsWith('index.ts') || def.path.endsWith('index.js')) {
105
+ continue;
106
+ }
107
+ const isUsed = usages.has(def.name) || importedSymbols.has(def.name);
108
+ // Check exports
109
+ if (def.exported && checkExports) {
110
+ totalExports++;
111
+ if (!importedSymbols.has(def.name)) {
112
+ // Check if it's a main entry point
113
+ const isEntryPoint = isLikelyEntryPoint(def.path, def.name);
114
+ if (!isEntryPoint) {
115
+ unusedExports++;
116
+ deadCode.push({
117
+ name: def.name,
118
+ path: def.path,
119
+ line: def.line,
120
+ kind: 'export',
121
+ exported: true,
122
+ confidence: 'medium',
123
+ reason: 'Export is not imported anywhere in the codebase',
124
+ });
125
+ }
126
+ }
127
+ }
128
+ // Check functions
129
+ if (def.kind === 'function' && checkFunctions) {
130
+ totalFunctions++;
131
+ if (!isUsed && !def.exported) {
132
+ unusedFunctions++;
133
+ deadCode.push({
134
+ name: def.name,
135
+ path: def.path,
136
+ line: def.line,
137
+ kind: 'function',
138
+ exported: false,
139
+ confidence: 'high',
140
+ reason: 'Function is not called anywhere in the file',
141
+ });
142
+ }
143
+ }
144
+ // Check variables
145
+ if (def.kind === 'variable' && checkVariables) {
146
+ totalVariables++;
147
+ if (!isUsed && !def.exported) {
148
+ unusedVariables++;
149
+ deadCode.push({
150
+ name: def.name,
151
+ path: def.path,
152
+ line: def.line,
153
+ kind: 'variable',
154
+ exported: false,
155
+ confidence: 'medium',
156
+ reason: 'Variable is not referenced after declaration',
157
+ });
158
+ }
159
+ }
160
+ }
161
+ const result = {
162
+ path: resolvedPath,
163
+ deadCode,
164
+ stats: {
165
+ filesAnalyzed: files.length,
166
+ totalExports,
167
+ unusedExports,
168
+ totalFunctions,
169
+ unusedFunctions,
170
+ totalVariables,
171
+ unusedVariables,
172
+ },
173
+ };
174
+ return createSuccessResult(result);
175
+ }
176
+ catch (error) {
177
+ return createErrorResult(`Failed to find dead code: ${error instanceof Error ? error.message : String(error)}`);
178
+ }
179
+ }
180
+ /**
181
+ * Collect files to analyze
182
+ */
183
+ async function collectFiles(dirPath, files, includeTests, maxFiles, currentDepth = 0) {
184
+ if (currentDepth > 10 || files.length >= maxFiles)
185
+ return;
186
+ try {
187
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
188
+ for (const entry of entries) {
189
+ if (files.length >= maxFiles)
190
+ break;
191
+ const fullPath = path.join(dirPath, entry.name);
192
+ // Skip excluded directories
193
+ if (entry.isDirectory()) {
194
+ if (DEFAULT_EXCLUDE.includes(entry.name))
195
+ continue;
196
+ if (!includeTests && entry.name === '__tests__')
197
+ continue;
198
+ await collectFiles(fullPath, files, includeTests, maxFiles, currentDepth + 1);
199
+ }
200
+ else if (entry.isFile()) {
201
+ // Only include TypeScript/JavaScript files
202
+ if (/\.(ts|tsx|js|jsx)$/.test(entry.name) && !entry.name.endsWith('.d.ts')) {
203
+ // Skip test files if not including tests
204
+ if (!includeTests && TEST_PATTERNS.some((p) => fullPath.includes(p))) {
205
+ continue;
206
+ }
207
+ files.push(fullPath);
208
+ }
209
+ }
210
+ }
211
+ }
212
+ catch {
213
+ // Ignore permission errors
214
+ }
215
+ }
216
+ /**
217
+ * Analyze a file for definitions and usages
218
+ */
219
+ async function analyzeFile(filePath, definitions, usages, importedSymbols) {
220
+ try {
221
+ const content = await fs.readFile(filePath, 'utf-8');
222
+ const detection = detectLanguage(filePath);
223
+ if (!detection.language || !isLanguageSupported(detection.language)) {
224
+ return;
225
+ }
226
+ const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, filePath.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
227
+ // Collect definitions
228
+ const visit = (node) => {
229
+ const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
230
+ // Function declarations
231
+ if (ts.isFunctionDeclaration(node) && node.name) {
232
+ const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
233
+ definitions.push({
234
+ name: node.name.text,
235
+ path: filePath,
236
+ line: line + 1,
237
+ kind: 'function',
238
+ exported: isExported,
239
+ });
240
+ }
241
+ // Class declarations
242
+ if (ts.isClassDeclaration(node) && node.name) {
243
+ const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
244
+ definitions.push({
245
+ name: node.name.text,
246
+ path: filePath,
247
+ line: line + 1,
248
+ kind: 'class',
249
+ exported: isExported,
250
+ });
251
+ }
252
+ // Variable declarations (const, let, var)
253
+ if (ts.isVariableStatement(node)) {
254
+ const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
255
+ for (const decl of node.declarationList.declarations) {
256
+ if (ts.isIdentifier(decl.name)) {
257
+ // Check if it's a function expression
258
+ const kind = decl.initializer &&
259
+ (ts.isFunctionExpression(decl.initializer) || ts.isArrowFunction(decl.initializer))
260
+ ? 'function'
261
+ : 'variable';
262
+ definitions.push({
263
+ name: decl.name.text,
264
+ path: filePath,
265
+ line: line + 1,
266
+ kind,
267
+ exported: isExported,
268
+ });
269
+ }
270
+ }
271
+ }
272
+ // Interface declarations
273
+ if (ts.isInterfaceDeclaration(node)) {
274
+ const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
275
+ definitions.push({
276
+ name: node.name.text,
277
+ path: filePath,
278
+ line: line + 1,
279
+ kind: 'interface',
280
+ exported: isExported,
281
+ });
282
+ }
283
+ // Type alias declarations
284
+ if (ts.isTypeAliasDeclaration(node)) {
285
+ const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
286
+ definitions.push({
287
+ name: node.name.text,
288
+ path: filePath,
289
+ line: line + 1,
290
+ kind: 'type',
291
+ exported: isExported,
292
+ });
293
+ }
294
+ // Enum declarations
295
+ if (ts.isEnumDeclaration(node)) {
296
+ const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
297
+ definitions.push({
298
+ name: node.name.text,
299
+ path: filePath,
300
+ line: line + 1,
301
+ kind: 'enum',
302
+ exported: isExported,
303
+ });
304
+ }
305
+ // Import declarations - track what's imported
306
+ if (ts.isImportDeclaration(node) && node.importClause) {
307
+ // Named imports
308
+ if (node.importClause.namedBindings && ts.isNamedImports(node.importClause.namedBindings)) {
309
+ for (const specifier of node.importClause.namedBindings.elements) {
310
+ importedSymbols.add(specifier.name.text);
311
+ }
312
+ }
313
+ // Default import
314
+ if (node.importClause.name) {
315
+ importedSymbols.add(node.importClause.name.text);
316
+ }
317
+ }
318
+ // Track usages (identifiers)
319
+ if (ts.isIdentifier(node)) {
320
+ // Skip if it's a declaration name
321
+ const parent = node.parent;
322
+ if (!((ts.isFunctionDeclaration(parent) && parent.name === node) ||
323
+ (ts.isClassDeclaration(parent) && parent.name === node) ||
324
+ (ts.isVariableDeclaration(parent) && parent.name === node) ||
325
+ (ts.isInterfaceDeclaration(parent) && parent.name === node) ||
326
+ (ts.isTypeAliasDeclaration(parent) && parent.name === node) ||
327
+ (ts.isEnumDeclaration(parent) && parent.name === node) ||
328
+ (ts.isParameter(parent) && parent.name === node) ||
329
+ ts.isImportSpecifier(parent) ||
330
+ ts.isExportSpecifier(parent))) {
331
+ usages.add(node.text);
332
+ }
333
+ }
334
+ ts.forEachChild(node, visit);
335
+ };
336
+ visit(sourceFile);
337
+ }
338
+ catch {
339
+ // Ignore errors
340
+ }
341
+ }
342
+ /**
343
+ * Check if a symbol is likely an entry point
344
+ */
345
+ function isLikelyEntryPoint(filePath, symbolName) {
346
+ // Main entry files
347
+ const entryPatterns = ['index.ts', 'index.js', 'main.ts', 'main.js', 'app.ts', 'app.js'];
348
+ const fileName = path.basename(filePath);
349
+ if (entryPatterns.includes(fileName)) {
350
+ return true;
351
+ }
352
+ // Common exported names that are likely entry points
353
+ const entrySymbols = ['default', 'main', 'app', 'handler', 'server', 'client'];
354
+ if (entrySymbols.includes(symbolName.toLowerCase())) {
355
+ return true;
356
+ }
357
+ return false;
358
+ }
359
+ /**
360
+ * Create customizable findDeadCode tool
361
+ */
362
+ export function createFindDeadCodeTool(options) {
363
+ return defineTool({
364
+ name: options?.name ?? 'find_dead_code',
365
+ description: options?.description ?? TOOL_DESCRIPTION,
366
+ inputSchema: TOOL_INPUT_SCHEMA,
367
+ execute: async (input) => {
368
+ const modifiedInput = {
369
+ ...input,
370
+ maxFiles: input.maxFiles ?? options?.defaultMaxFiles,
371
+ };
372
+ return executeFindDeadCode(modifiedInput);
373
+ },
374
+ });
375
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * findDuplicates Tool
3
+ *
4
+ * Detect duplicate code blocks across the codebase using content hashing.
5
+ * Helps identify opportunities for refactoring and code reuse.
6
+ */
7
+ import type { Tool } from '@compilr-dev/agents';
8
+ import type { FindDuplicatesInput } from './types.js';
9
+ /**
10
+ * findDuplicates tool
11
+ */
12
+ export declare const findDuplicatesTool: Tool<FindDuplicatesInput>;
13
+ /**
14
+ * Create customizable findDuplicates tool
15
+ */
16
+ export declare function createFindDuplicatesTool(options?: {
17
+ name?: string;
18
+ description?: string;
19
+ defaultMinLines?: number;
20
+ defaultMaxFiles?: number;
21
+ }): Tool<FindDuplicatesInput>;