centaurus-cli 2.5.3 → 2.6.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/dist/cli-adapter.d.ts +6 -0
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +215 -29
- package/dist/cli-adapter.js.map +1 -1
- package/dist/commands/CommandParser.js +2 -2
- package/dist/commands/CommandParser.js.map +1 -1
- package/dist/config/defaultConfig.js +1 -1
- package/dist/config/defaultConfig.js.map +1 -1
- package/dist/config/models.d.ts +50 -5
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +144 -22
- package/dist/config/models.js.map +1 -1
- package/dist/config/types.d.ts +3 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +3 -1
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/services/ai-service-client.d.ts +8 -2
- package/dist/services/ai-service-client.d.ts.map +1 -1
- package/dist/services/ai-service-client.js +2 -1
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/services/environment-context-injector.d.ts +69 -0
- package/dist/services/environment-context-injector.d.ts.map +1 -0
- package/dist/services/environment-context-injector.js +198 -0
- package/dist/services/environment-context-injector.js.map +1 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -1
- package/dist/tools/ToolRegistry.js +120 -26
- package/dist/tools/ToolRegistry.js.map +1 -1
- package/dist/tools/command.d.ts.map +1 -1
- package/dist/tools/command.js +30 -6
- package/dist/tools/command.js.map +1 -1
- package/dist/tools/file-ops.d.ts.map +1 -1
- package/dist/tools/file-ops.js +70 -23
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/find-files.d.ts +47 -0
- package/dist/tools/find-files.d.ts.map +1 -0
- package/dist/tools/find-files.js +190 -0
- package/dist/tools/find-files.js.map +1 -0
- package/dist/tools/get-diff.d.ts +45 -0
- package/dist/tools/get-diff.d.ts.map +1 -0
- package/dist/tools/get-diff.js +138 -0
- package/dist/tools/get-diff.js.map +1 -0
- package/dist/tools/grep-search.d.ts +85 -0
- package/dist/tools/grep-search.d.ts.map +1 -0
- package/dist/tools/grep-search.js +497 -0
- package/dist/tools/grep-search.js.map +1 -0
- package/dist/tools/inspect-symbol.d.ts +27 -0
- package/dist/tools/inspect-symbol.d.ts.map +1 -0
- package/dist/tools/inspect-symbol.js +259 -0
- package/dist/tools/inspect-symbol.js.map +1 -0
- package/dist/tools/validation.d.ts +49 -0
- package/dist/tools/validation.d.ts.map +1 -0
- package/dist/tools/validation.js +125 -0
- package/dist/tools/validation.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui/components/App.d.ts +3 -0
- package/dist/ui/components/App.d.ts.map +1 -1
- package/dist/ui/components/App.js +173 -15
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/ContextWindowIndicator.d.ts +8 -0
- package/dist/ui/components/ContextWindowIndicator.d.ts.map +1 -0
- package/dist/ui/components/ContextWindowIndicator.js +34 -0
- package/dist/ui/components/ContextWindowIndicator.js.map +1 -0
- package/dist/ui/components/InputBox.d.ts +2 -0
- package/dist/ui/components/InputBox.d.ts.map +1 -1
- package/dist/ui/components/InputBox.js +6 -2
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/MessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/MessageDisplay.js +7 -0
- package/dist/ui/components/MessageDisplay.js.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.js +9 -1
- package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
- package/dist/ui/components/ThinkingDisplay.d.ts +2 -3
- package/dist/ui/components/ThinkingDisplay.d.ts.map +1 -1
- package/dist/ui/components/ThinkingDisplay.js +19 -19
- package/dist/ui/components/ThinkingDisplay.js.map +1 -1
- package/dist/utils/markdown-parser.d.ts +4 -0
- package/dist/utils/markdown-parser.d.ts.map +1 -1
- package/dist/utils/markdown-parser.js +15 -1
- package/dist/utils/markdown-parser.js.map +1 -1
- package/package.json +2 -1
- package/AUTH_FLOW.md +0 -138
- package/CONFIG_GUIDE.md +0 -249
- package/README.md +0 -501
package/dist/tools/file-ops.js
CHANGED
|
@@ -2,24 +2,31 @@ import * as path from 'path';
|
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as fileUtils from '../utils/file.js';
|
|
4
4
|
import * as Diff from 'diff';
|
|
5
|
+
import { ToolValidator } from './validation.js';
|
|
5
6
|
export const readFileTool = {
|
|
6
7
|
schema: {
|
|
7
8
|
name: 'read_file',
|
|
8
|
-
description:
|
|
9
|
+
description: `Read the contents of a file at the specified path. Supports optional line range parameters.
|
|
10
|
+
|
|
11
|
+
USAGE GUIDELINES:
|
|
12
|
+
- Always read a file before attempting to edit it
|
|
13
|
+
- Use this to verify file contents and get exact text for search patterns
|
|
14
|
+
- Line numbers are 1-indexed (first line is 1, not 0)
|
|
15
|
+
- Reading the file shows you the exact whitespace and formatting`,
|
|
9
16
|
parameters: {
|
|
10
17
|
type: 'object',
|
|
11
18
|
properties: {
|
|
12
19
|
file_path: {
|
|
13
20
|
type: 'string',
|
|
14
|
-
description: 'The path to the file to read (relative to current working directory)',
|
|
21
|
+
description: 'The path to the file to read (relative to current working directory). Required parameter.',
|
|
15
22
|
},
|
|
16
23
|
start_line: {
|
|
17
24
|
type: 'number',
|
|
18
|
-
description: 'Optional: Starting line number (1-indexed)',
|
|
25
|
+
description: 'Optional: Starting line number (1-indexed). If omitted, reads from the beginning of the file.',
|
|
19
26
|
},
|
|
20
27
|
end_line: {
|
|
21
28
|
type: 'number',
|
|
22
|
-
description: 'Optional: Ending line number (1-indexed)',
|
|
29
|
+
description: 'Optional: Ending line number (1-indexed). If omitted, reads to the end of the file.',
|
|
23
30
|
},
|
|
24
31
|
},
|
|
25
32
|
required: ['file_path'],
|
|
@@ -58,17 +65,23 @@ export const readFileTool = {
|
|
|
58
65
|
export const writeFileTool = {
|
|
59
66
|
schema: {
|
|
60
67
|
name: 'write_file',
|
|
61
|
-
description:
|
|
68
|
+
description: `Create a new file or overwrite an existing file with the provided content.
|
|
69
|
+
|
|
70
|
+
USAGE GUIDELINES:
|
|
71
|
+
- Use this for creating new files from scratch
|
|
72
|
+
- For modifying existing files, prefer edit_file to make targeted changes
|
|
73
|
+
- The entire file content must be provided
|
|
74
|
+
- User approval is required before overwriting existing files`,
|
|
62
75
|
parameters: {
|
|
63
76
|
type: 'object',
|
|
64
77
|
properties: {
|
|
65
78
|
file_path: {
|
|
66
79
|
type: 'string',
|
|
67
|
-
description: 'The path where the file should be created/written',
|
|
80
|
+
description: 'The path where the file should be created/written (relative to current working directory). Required parameter.',
|
|
68
81
|
},
|
|
69
82
|
content: {
|
|
70
83
|
type: 'string',
|
|
71
|
-
description: 'The complete content to write to the file',
|
|
84
|
+
description: 'The complete content to write to the file. This will replace any existing content. Required parameter.',
|
|
72
85
|
},
|
|
73
86
|
},
|
|
74
87
|
required: ['file_path', 'content'],
|
|
@@ -140,21 +153,39 @@ export const writeFileTool = {
|
|
|
140
153
|
export const editFileTool = {
|
|
141
154
|
schema: {
|
|
142
155
|
name: 'edit_file',
|
|
143
|
-
description:
|
|
156
|
+
description: `Search for a specific pattern in a file and replace it with new content. Shows a diff preview before applying.
|
|
157
|
+
|
|
158
|
+
CRITICAL REQUIREMENTS:
|
|
159
|
+
- 'search_pattern' must match the file content EXACTLY, including all whitespace, indentation, and newlines
|
|
160
|
+
- The pattern must be UNIQUE in the file (appear exactly once)
|
|
161
|
+
- You MUST have read the file in a previous turn to know the exact content
|
|
162
|
+
- Copy the search_pattern directly from the read_file output to ensure exact matching
|
|
163
|
+
- Include surrounding context (2-3 lines) to ensure uniqueness
|
|
164
|
+
|
|
165
|
+
COMMON MISTAKES TO AVOID:
|
|
166
|
+
- Guessing indentation (always read the file first)
|
|
167
|
+
- Using patterns that appear multiple times
|
|
168
|
+
- Forgetting trailing newlines or spaces
|
|
169
|
+
- Not including enough context for uniqueness
|
|
170
|
+
- Modifying whitespace when copying the pattern`,
|
|
144
171
|
parameters: {
|
|
145
172
|
type: 'object',
|
|
146
173
|
properties: {
|
|
147
174
|
file_path: {
|
|
148
175
|
type: 'string',
|
|
149
|
-
description: 'The path to the file to edit',
|
|
176
|
+
description: 'The path to the file to edit (relative to current working directory)',
|
|
150
177
|
},
|
|
151
178
|
search_pattern: {
|
|
152
179
|
type: 'string',
|
|
153
|
-
description:
|
|
180
|
+
description: `The EXACT block of text to replace. Must match character-for-character including:
|
|
181
|
+
- All spaces and tabs (indentation)
|
|
182
|
+
- All newlines
|
|
183
|
+
- All special characters
|
|
184
|
+
Copy this directly from a recent read_file output. Do not guess or modify the content.`,
|
|
154
185
|
},
|
|
155
186
|
replacement: {
|
|
156
187
|
type: 'string',
|
|
157
|
-
description: 'The text to
|
|
188
|
+
description: 'The new text to insert in place of search_pattern. Use the same indentation style as the surrounding code.',
|
|
158
189
|
},
|
|
159
190
|
},
|
|
160
191
|
required: ['file_path', 'search_pattern', 'replacement'],
|
|
@@ -164,6 +195,18 @@ export const editFileTool = {
|
|
|
164
195
|
const { file_path, search_pattern, replacement } = args;
|
|
165
196
|
const contextManager = context.contextManager;
|
|
166
197
|
const currentContext = contextManager.getCurrentContext();
|
|
198
|
+
// Validate edit operation for local files
|
|
199
|
+
if (currentContext.type === 'local') {
|
|
200
|
+
const validator = new ToolValidator();
|
|
201
|
+
const validationResult = await validator.validateEditFile(file_path, search_pattern, replacement, context.cwd);
|
|
202
|
+
if (!validationResult.valid) {
|
|
203
|
+
const errorMessage = [
|
|
204
|
+
validationResult.error,
|
|
205
|
+
validationResult.suggestion ? `\nSuggestion: ${validationResult.suggestion}` : '',
|
|
206
|
+
].join('');
|
|
207
|
+
throw new Error(errorMessage);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
167
210
|
// Read the current content
|
|
168
211
|
let oldContent;
|
|
169
212
|
if (currentContext.type === 'local') {
|
|
@@ -175,15 +218,14 @@ export const editFileTool = {
|
|
|
175
218
|
}
|
|
176
219
|
else {
|
|
177
220
|
oldContent = await contextManager.readFile(file_path);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
throw new Error(`Pattern appears ${occurrences} times. Please use a more specific pattern.`);
|
|
221
|
+
// For remote contexts, perform basic validation
|
|
222
|
+
if (!oldContent.includes(search_pattern)) {
|
|
223
|
+
throw new Error(`Pattern not found in file: ${search_pattern.substring(0, 100)}`);
|
|
224
|
+
}
|
|
225
|
+
const occurrences = oldContent.split(search_pattern).length - 1;
|
|
226
|
+
if (occurrences > 1) {
|
|
227
|
+
throw new Error(`Pattern appears ${occurrences} times. Please use a more specific pattern.`);
|
|
228
|
+
}
|
|
187
229
|
}
|
|
188
230
|
// Create the new content
|
|
189
231
|
const newContent = oldContent.replace(search_pattern, replacement);
|
|
@@ -211,17 +253,22 @@ export const editFileTool = {
|
|
|
211
253
|
export const listDirectoryTool = {
|
|
212
254
|
schema: {
|
|
213
255
|
name: 'list_directory',
|
|
214
|
-
description:
|
|
256
|
+
description: `List the contents of a directory.
|
|
257
|
+
|
|
258
|
+
USAGE GUIDELINES:
|
|
259
|
+
- Use this to explore project structure before making changes
|
|
260
|
+
- Recursive listing helps understand nested directory structures
|
|
261
|
+
- Check directory contents before creating new files to avoid conflicts`,
|
|
215
262
|
parameters: {
|
|
216
263
|
type: 'object',
|
|
217
264
|
properties: {
|
|
218
265
|
directory_path: {
|
|
219
266
|
type: 'string',
|
|
220
|
-
description: 'The path to the directory to list (relative to
|
|
267
|
+
description: 'The path to the directory to list (relative to current working directory). Required parameter.',
|
|
221
268
|
},
|
|
222
269
|
recursive: {
|
|
223
270
|
type: 'boolean',
|
|
224
|
-
description: 'Whether to list subdirectories recursively',
|
|
271
|
+
description: 'Optional: Whether to list subdirectories recursively. Defaults to false.',
|
|
225
272
|
},
|
|
226
273
|
},
|
|
227
274
|
required: ['directory_path'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-ops.js","sourceRoot":"","sources":["../../src/tools/file-ops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"file-ops.js","sourceRoot":"","sources":["../../src/tools/file-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Tool } from './types.js';
|
|
2
|
+
export interface FindFilesParams {
|
|
3
|
+
pattern: string;
|
|
4
|
+
maxResults?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface FindFilesResult {
|
|
7
|
+
files: string[];
|
|
8
|
+
totalFound: number;
|
|
9
|
+
truncated: boolean;
|
|
10
|
+
searchPattern: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* FindFilesTool - Find files by name using fuzzy matching
|
|
14
|
+
*
|
|
15
|
+
* This tool uses fast-glob for efficient, cross-platform file searching
|
|
16
|
+
* with gitignore support and smart result sorting.
|
|
17
|
+
*/
|
|
18
|
+
export declare class FindFilesTool {
|
|
19
|
+
private static readonly DEFAULT_MAX_RESULTS;
|
|
20
|
+
private static readonly EXCLUDE_PATTERNS;
|
|
21
|
+
/**
|
|
22
|
+
* Normalize file path to use forward slashes
|
|
23
|
+
*/
|
|
24
|
+
private normalizePath;
|
|
25
|
+
/**
|
|
26
|
+
* Validate glob pattern
|
|
27
|
+
*/
|
|
28
|
+
private validatePattern;
|
|
29
|
+
/**
|
|
30
|
+
* Calculate relevance score for sorting
|
|
31
|
+
* Lower score = more relevant
|
|
32
|
+
*/
|
|
33
|
+
private calculateRelevance;
|
|
34
|
+
/**
|
|
35
|
+
* Sort files by relevance
|
|
36
|
+
*/
|
|
37
|
+
private sortByRelevance;
|
|
38
|
+
/**
|
|
39
|
+
* Execute the file search
|
|
40
|
+
*/
|
|
41
|
+
execute(params: FindFilesParams, cwd: string): Promise<FindFilesResult>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Find files tool for the tool registry
|
|
45
|
+
*/
|
|
46
|
+
export declare const findFilesTool: Tool;
|
|
47
|
+
//# sourceMappingURL=find-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-files.d.ts","sourceRoot":"","sources":["../../src/tools/find-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAwB,MAAM,YAAY,CAAC;AAIxD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAM;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAYtC;IAEF;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmBvB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAwC9E;AA0BD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,IA8C3B,CAAC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import fg from 'fast-glob';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* FindFilesTool - Find files by name using fuzzy matching
|
|
5
|
+
*
|
|
6
|
+
* This tool uses fast-glob for efficient, cross-platform file searching
|
|
7
|
+
* with gitignore support and smart result sorting.
|
|
8
|
+
*/
|
|
9
|
+
export class FindFilesTool {
|
|
10
|
+
static DEFAULT_MAX_RESULTS = 10;
|
|
11
|
+
static EXCLUDE_PATTERNS = [
|
|
12
|
+
'node_modules/**',
|
|
13
|
+
'dist/**',
|
|
14
|
+
'build/**',
|
|
15
|
+
'.git/**',
|
|
16
|
+
'.next/**',
|
|
17
|
+
'.nuxt/**',
|
|
18
|
+
'coverage/**',
|
|
19
|
+
'.cache/**',
|
|
20
|
+
'out/**',
|
|
21
|
+
'target/**',
|
|
22
|
+
'vendor/**',
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Normalize file path to use forward slashes
|
|
26
|
+
*/
|
|
27
|
+
normalizePath(filePath) {
|
|
28
|
+
return filePath.replace(/\\/g, '/');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validate glob pattern
|
|
32
|
+
*/
|
|
33
|
+
validatePattern(pattern) {
|
|
34
|
+
// Check for common invalid patterns
|
|
35
|
+
if (pattern.includes('[') && !pattern.includes(']')) {
|
|
36
|
+
return {
|
|
37
|
+
valid: false,
|
|
38
|
+
error: `Invalid glob pattern: "${pattern}"\nSuggestion: Use valid glob syntax. Examples: "*.ts", "**/*.py", "*user*"`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
if (pattern.includes('{') && !pattern.includes('}')) {
|
|
42
|
+
return {
|
|
43
|
+
valid: false,
|
|
44
|
+
error: `Invalid glob pattern: "${pattern}"\nSuggestion: Use valid glob syntax. Examples: "*.ts", "**/*.py", "*user*"`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return { valid: true };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Calculate relevance score for sorting
|
|
51
|
+
* Lower score = more relevant
|
|
52
|
+
*/
|
|
53
|
+
calculateRelevance(filePath, pattern) {
|
|
54
|
+
const fileName = path.basename(filePath);
|
|
55
|
+
const normalizedPattern = pattern.replace(/\*/g, '').toLowerCase();
|
|
56
|
+
const normalizedFileName = fileName.toLowerCase();
|
|
57
|
+
// Exact match gets highest priority
|
|
58
|
+
if (fileName === pattern || normalizedFileName === normalizedPattern) {
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
// Exact match without extension
|
|
62
|
+
const fileNameWithoutExt = fileName.replace(/\.[^.]+$/, '');
|
|
63
|
+
if (fileNameWithoutExt === pattern || fileNameWithoutExt.toLowerCase() === normalizedPattern) {
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
// Calculate path depth (shallower is better)
|
|
67
|
+
const depth = filePath.split('/').length;
|
|
68
|
+
// Combine factors: depth + position of match in filename
|
|
69
|
+
const matchIndex = normalizedFileName.indexOf(normalizedPattern);
|
|
70
|
+
const positionScore = matchIndex >= 0 ? matchIndex : 1000;
|
|
71
|
+
return depth * 10 + positionScore;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Sort files by relevance
|
|
75
|
+
*/
|
|
76
|
+
sortByRelevance(files, pattern) {
|
|
77
|
+
return files.sort((a, b) => {
|
|
78
|
+
const scoreA = this.calculateRelevance(a, pattern);
|
|
79
|
+
const scoreB = this.calculateRelevance(b, pattern);
|
|
80
|
+
return scoreA - scoreB;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Execute the file search
|
|
85
|
+
*/
|
|
86
|
+
async execute(params, cwd) {
|
|
87
|
+
// Validate pattern
|
|
88
|
+
const validation = this.validatePattern(params.pattern);
|
|
89
|
+
if (!validation.valid) {
|
|
90
|
+
throw new Error(validation.error);
|
|
91
|
+
}
|
|
92
|
+
const maxResults = params.maxResults ?? FindFilesTool.DEFAULT_MAX_RESULTS;
|
|
93
|
+
try {
|
|
94
|
+
// Execute fast-glob search
|
|
95
|
+
const files = await fg(params.pattern, {
|
|
96
|
+
cwd,
|
|
97
|
+
ignore: FindFilesTool.EXCLUDE_PATTERNS,
|
|
98
|
+
caseSensitiveMatch: false,
|
|
99
|
+
onlyFiles: true,
|
|
100
|
+
dot: false, // Don't include hidden files by default
|
|
101
|
+
});
|
|
102
|
+
// Normalize paths
|
|
103
|
+
const normalizedFiles = files.map(f => this.normalizePath(String(f)));
|
|
104
|
+
// Sort by relevance
|
|
105
|
+
const sortedFiles = this.sortByRelevance(normalizedFiles, params.pattern);
|
|
106
|
+
// Truncate results
|
|
107
|
+
const totalFound = sortedFiles.length;
|
|
108
|
+
const truncated = totalFound > maxResults;
|
|
109
|
+
const resultFiles = sortedFiles.slice(0, maxResults);
|
|
110
|
+
return {
|
|
111
|
+
files: resultFiles,
|
|
112
|
+
totalFound,
|
|
113
|
+
truncated,
|
|
114
|
+
searchPattern: params.pattern,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
throw new Error(`File search failed: ${error.message}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Format find files results for display
|
|
124
|
+
*/
|
|
125
|
+
function formatFindFilesResults(result) {
|
|
126
|
+
if (result.files.length === 0) {
|
|
127
|
+
return `No files found matching pattern "${result.searchPattern}"\nSuggestion: Try a broader pattern like "*${result.searchPattern}*" or check if the file exists in the project.`;
|
|
128
|
+
}
|
|
129
|
+
const lines = [];
|
|
130
|
+
lines.push(`Found ${result.totalFound} file${result.totalFound === 1 ? '' : 's'} matching pattern "${result.searchPattern}"`);
|
|
131
|
+
if (result.truncated) {
|
|
132
|
+
lines.push(`(showing first ${result.files.length} matches)`);
|
|
133
|
+
}
|
|
134
|
+
lines.push('');
|
|
135
|
+
for (const file of result.files) {
|
|
136
|
+
lines.push(` ${file}`);
|
|
137
|
+
}
|
|
138
|
+
return lines.join('\n');
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Find files tool for the tool registry
|
|
142
|
+
*/
|
|
143
|
+
export const findFilesTool = {
|
|
144
|
+
schema: {
|
|
145
|
+
name: 'find_files',
|
|
146
|
+
description: `Find files by name using glob patterns without knowing exact paths.
|
|
147
|
+
|
|
148
|
+
USE THIS TOOL WHEN:
|
|
149
|
+
- User mentions a file name without providing the full path
|
|
150
|
+
- You need to locate a file but don't know which directory it's in
|
|
151
|
+
- You want to find all files matching a pattern (e.g., all test files)
|
|
152
|
+
|
|
153
|
+
EXAMPLES:
|
|
154
|
+
- Find user controller: pattern="*user*controller*"
|
|
155
|
+
- Find specific file: pattern="database.ts"
|
|
156
|
+
- Find all test files: pattern="**/*.test.ts"
|
|
157
|
+
- Find Python models: pattern="**/models/*.py"
|
|
158
|
+
|
|
159
|
+
Use this BEFORE trying to read a file when you don't know its exact path.`,
|
|
160
|
+
parameters: {
|
|
161
|
+
type: 'object',
|
|
162
|
+
properties: {
|
|
163
|
+
pattern: {
|
|
164
|
+
type: 'string',
|
|
165
|
+
description: 'Glob pattern to match file names. Use * for wildcards, ** for recursive search.',
|
|
166
|
+
},
|
|
167
|
+
maxResults: {
|
|
168
|
+
type: 'number',
|
|
169
|
+
description: 'Maximum number of results to return. Default: 10',
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
required: ['pattern'],
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
async execute(args, context) {
|
|
176
|
+
const tool = new FindFilesTool();
|
|
177
|
+
const params = {
|
|
178
|
+
pattern: args.pattern,
|
|
179
|
+
maxResults: args.maxResults,
|
|
180
|
+
};
|
|
181
|
+
try {
|
|
182
|
+
const result = await tool.execute(params, context.cwd);
|
|
183
|
+
return formatFindFilesResults(result);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
throw new Error(`Find files failed: ${error.message}`);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
//# sourceMappingURL=find-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-files.js","sourceRoot":"","sources":["../../src/tools/find-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface GetDiffParams {
|
|
2
|
+
filePath?: string;
|
|
3
|
+
staged?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface GetDiffResult {
|
|
6
|
+
diff: string;
|
|
7
|
+
filesChanged: string[];
|
|
8
|
+
hasChanges: boolean;
|
|
9
|
+
truncated: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare class GetDiffTool {
|
|
12
|
+
/**
|
|
13
|
+
* Execute git diff to show changes in the working directory
|
|
14
|
+
*/
|
|
15
|
+
execute(params: GetDiffParams, cwd: string): Promise<GetDiffResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Check if git command is available
|
|
18
|
+
*/
|
|
19
|
+
private checkGitAvailable;
|
|
20
|
+
/**
|
|
21
|
+
* Check if the current directory is a git repository
|
|
22
|
+
*/
|
|
23
|
+
private checkGitRepository;
|
|
24
|
+
/**
|
|
25
|
+
* Get list of changed files
|
|
26
|
+
*/
|
|
27
|
+
private getChangedFiles;
|
|
28
|
+
/**
|
|
29
|
+
* Get the full diff output
|
|
30
|
+
*/
|
|
31
|
+
private getDiffOutput;
|
|
32
|
+
/**
|
|
33
|
+
* Truncate diff output to 500 lines maximum
|
|
34
|
+
*/
|
|
35
|
+
private truncateDiff;
|
|
36
|
+
/**
|
|
37
|
+
* Normalize file paths to use forward slashes
|
|
38
|
+
*/
|
|
39
|
+
private normalizeFilePaths;
|
|
40
|
+
/**
|
|
41
|
+
* Handle errors with helpful messages
|
|
42
|
+
*/
|
|
43
|
+
private handleError;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=get-diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-diff.d.ts","sourceRoot":"","sources":["../../src/tools/get-diff.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,WAAW;IACtB;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAwCzE;;OAEG;YACW,iBAAiB;IAW/B;;OAEG;YACW,kBAAkB;IAWhC;;OAEG;YACW,eAAe;IAqB7B;;OAEG;YACW,aAAa;IAoB3B;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,WAAW;CAUpB"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
const execAsync = promisify(exec);
|
|
4
|
+
export class GetDiffTool {
|
|
5
|
+
/**
|
|
6
|
+
* Execute git diff to show changes in the working directory
|
|
7
|
+
*/
|
|
8
|
+
async execute(params, cwd) {
|
|
9
|
+
const { filePath, staged = false } = params;
|
|
10
|
+
try {
|
|
11
|
+
// Check if git is available
|
|
12
|
+
await this.checkGitAvailable();
|
|
13
|
+
// Check if directory is a git repository
|
|
14
|
+
await this.checkGitRepository(cwd);
|
|
15
|
+
// Get list of changed files
|
|
16
|
+
const filesChanged = await this.getChangedFiles(cwd, staged, filePath);
|
|
17
|
+
// If no changes, return early
|
|
18
|
+
if (filesChanged.length === 0) {
|
|
19
|
+
return {
|
|
20
|
+
diff: 'No changes detected in the working directory.',
|
|
21
|
+
filesChanged: [],
|
|
22
|
+
hasChanges: false,
|
|
23
|
+
truncated: false,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// Get the diff output
|
|
27
|
+
const diff = await this.getDiffOutput(cwd, staged, filePath);
|
|
28
|
+
// Truncate if necessary
|
|
29
|
+
const { truncatedDiff, wasTruncated } = this.truncateDiff(diff);
|
|
30
|
+
return {
|
|
31
|
+
diff: truncatedDiff,
|
|
32
|
+
filesChanged: this.normalizeFilePaths(filesChanged),
|
|
33
|
+
hasChanges: true,
|
|
34
|
+
truncated: wasTruncated,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
throw this.handleError(error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if git command is available
|
|
43
|
+
*/
|
|
44
|
+
async checkGitAvailable() {
|
|
45
|
+
try {
|
|
46
|
+
await execAsync('git --version');
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw new Error('Git command not found\n' +
|
|
50
|
+
'Suggestion: Install git to use diff functionality: https://git-scm.com/downloads');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if the current directory is a git repository
|
|
55
|
+
*/
|
|
56
|
+
async checkGitRepository(cwd) {
|
|
57
|
+
try {
|
|
58
|
+
await execAsync('git rev-parse --git-dir', { cwd });
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new Error('Not a git repository\n' +
|
|
62
|
+
'Suggestion: This directory is not under git version control. Initialize with \'git init\' to use diff functionality.');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get list of changed files
|
|
67
|
+
*/
|
|
68
|
+
async getChangedFiles(cwd, staged, filePath) {
|
|
69
|
+
const stagedFlag = staged ? '--staged' : '';
|
|
70
|
+
const fileArg = filePath ? `-- "${filePath}"` : '';
|
|
71
|
+
const command = `git diff --name-only ${stagedFlag} ${fileArg}`.trim();
|
|
72
|
+
try {
|
|
73
|
+
const { stdout } = await execAsync(command, { cwd });
|
|
74
|
+
return stdout
|
|
75
|
+
.trim()
|
|
76
|
+
.split('\n')
|
|
77
|
+
.filter(line => line.length > 0);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
// If the command fails, return empty array (no changes)
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get the full diff output
|
|
86
|
+
*/
|
|
87
|
+
async getDiffOutput(cwd, staged, filePath) {
|
|
88
|
+
const stagedFlag = staged ? '--staged' : '';
|
|
89
|
+
const fileArg = filePath ? `-- "${filePath}"` : '';
|
|
90
|
+
const command = `git diff ${stagedFlag} ${fileArg}`.trim();
|
|
91
|
+
try {
|
|
92
|
+
const { stdout } = await execAsync(command, { cwd, maxBuffer: 10 * 1024 * 1024 });
|
|
93
|
+
return stdout;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (error.code === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER') {
|
|
97
|
+
throw new Error('Diff output too large. Try specifying a specific file with filePath parameter.');
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Truncate diff output to 500 lines maximum
|
|
104
|
+
*/
|
|
105
|
+
truncateDiff(diff) {
|
|
106
|
+
const lines = diff.split('\n');
|
|
107
|
+
const maxLines = 500;
|
|
108
|
+
if (lines.length <= maxLines) {
|
|
109
|
+
return { truncatedDiff: diff, wasTruncated: false };
|
|
110
|
+
}
|
|
111
|
+
const truncatedLines = lines.slice(0, maxLines);
|
|
112
|
+
const remainingLines = lines.length - maxLines;
|
|
113
|
+
truncatedLines.push('');
|
|
114
|
+
truncatedLines.push(`[Diff truncated: ${remainingLines} more lines not shown]`);
|
|
115
|
+
truncatedLines.push(`Total lines: ${lines.length}`);
|
|
116
|
+
return {
|
|
117
|
+
truncatedDiff: truncatedLines.join('\n'),
|
|
118
|
+
wasTruncated: true,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Normalize file paths to use forward slashes
|
|
123
|
+
*/
|
|
124
|
+
normalizeFilePaths(files) {
|
|
125
|
+
return files.map(file => file.replace(/\\/g, '/'));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Handle errors with helpful messages
|
|
129
|
+
*/
|
|
130
|
+
handleError(error) {
|
|
131
|
+
if (error.message) {
|
|
132
|
+
return error;
|
|
133
|
+
}
|
|
134
|
+
return new Error(`Failed to get diff: ${error.toString()}\n` +
|
|
135
|
+
'Suggestion: Ensure you are in a git repository and git is installed.');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=get-diff.js.map
|