aegiscode 3.1.10 → 3.4.2
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/bin/aegis.js +165 -0
- package/package.json +18 -86
- package/LICENSE +0 -21
- package/README.md +0 -394
- package/dist/main.js +0 -2171
- package/gui/run-gui.cjs +0 -13
- package/src/agent/Agent.ts +0 -903
- package/src/agent/SimpleAgent.ts +0 -48
- package/src/agent/index.ts +0 -54
- package/src/agent/orchestrator/AppBuilder.ts +0 -443
- package/src/agent/orchestrator/CouncilAgent.ts +0 -310
- package/src/agent/orchestrator/DiscussionRoom.ts +0 -462
- package/src/agent/orchestrator/OrchestratorAgent.ts +0 -637
- package/src/agent/orchestrator/index.ts +0 -38
- package/src/agent/orchestrator/utils.ts +0 -397
- package/src/agent/pricing.ts +0 -115
- package/src/agent/router.ts +0 -74
- package/src/agent/routerStats.ts +0 -121
- package/src/agent/types.ts +0 -318
- package/src/auth/login.ts +0 -383
- package/src/cli/config.ts +0 -189
- package/src/cli/index.ts +0 -17
- package/src/cli/middleware.ts +0 -119
- package/src/cli/types.ts +0 -75
- package/src/config/ConfigManager.ts +0 -587
- package/src/config/index.ts +0 -7
- package/src/config/types.ts +0 -584
- package/src/context/CompactionService.ts +0 -300
- package/src/context/ContextManager.ts +0 -450
- package/src/context/FileAnalyzer.ts +0 -267
- package/src/context/TokenCounter.ts +0 -265
- package/src/context/index.ts +0 -27
- package/src/context/storage/CacheStore.ts +0 -176
- package/src/context/storage/JSONLStore.ts +0 -201
- package/src/context/storage/MemoryStore.ts +0 -205
- package/src/context/storage/PersistentStore.ts +0 -327
- package/src/context/storage/index.ts +0 -9
- package/src/context/storage/pathUtils.ts +0 -114
- package/src/context/test.ts +0 -309
- package/src/context/types.ts +0 -268
- package/src/hooks/HookExecutor.ts +0 -434
- package/src/hooks/HookManager.ts +0 -596
- package/src/hooks/HookService.ts +0 -269
- package/src/hooks/Matcher.ts +0 -157
- package/src/hooks/index.ts +0 -63
- package/src/hooks/types.ts +0 -424
- package/src/main.tsx +0 -596
- package/src/mcp/HealthMonitor.ts +0 -150
- package/src/mcp/McpClient.ts +0 -491
- package/src/mcp/McpRegistry.ts +0 -321
- package/src/mcp/createMcpTool.ts +0 -251
- package/src/mcp/index.ts +0 -15
- package/src/mcp/server.ts +0 -334
- package/src/mcp/test-server.ts +0 -88
- package/src/mcp/test.ts +0 -372
- package/src/mcp/types.ts +0 -247
- package/src/memory/AgentMemoryBus.ts +0 -432
- package/src/memory/CloudSync.ts +0 -99
- package/src/memory/DriveSync.ts +0 -106
- package/src/memory/SharedMemory.ts +0 -951
- package/src/memory/index.ts +0 -14
- package/src/memory/machineFingerprint.ts +0 -40
- package/src/orchestrator/SubAgentMetadata.ts +0 -136
- package/src/prompts/builder.ts +0 -213
- package/src/prompts/default.ts +0 -144
- package/src/prompts/index.ts +0 -16
- package/src/prompts/plan.ts +0 -64
- package/src/prompts/test.ts +0 -78
- package/src/services/AnthropicChatService.ts +0 -341
- package/src/services/ChatService.ts +0 -347
- package/src/services/ClaudeCliChatService.ts +0 -256
- package/src/services/CloudSync.ts +0 -168
- package/src/services/CostLedger.ts +0 -211
- package/src/services/Heartbeat.ts +0 -135
- package/src/services/LearningCollector.ts +0 -291
- package/src/services/OllamaInstaller.ts +0 -342
- package/src/services/VersionChecker.ts +0 -445
- package/src/services/index.ts +0 -57
- package/src/services/streaming/OpenAIEventAdapter.ts +0 -126
- package/src/services/streaming/RenderingProfile.ts +0 -90
- package/src/services/streaming/StreamEventParser.ts +0 -181
- package/src/services/streaming/ThrottledRenderer.ts +0 -139
- package/src/services/streaming/TranscriptBuffer.ts +0 -574
- package/src/services/streaming/eventStatusMap.ts +0 -52
- package/src/services/streaming/index.ts +0 -46
- package/src/services/streaming/renderFormatting.ts +0 -79
- package/src/services/streaming/types.ts +0 -234
- package/src/skills/SkillLoader.ts +0 -126
- package/src/skills/SkillRegistry.ts +0 -366
- package/src/skills/index.ts +0 -48
- package/src/skills/types.ts +0 -146
- package/src/slash-commands/billing.ts +0 -70
- package/src/slash-commands/build.ts +0 -413
- package/src/slash-commands/builtinCommands.ts +0 -2733
- package/src/slash-commands/clone.ts +0 -242
- package/src/slash-commands/council.ts +0 -125
- package/src/slash-commands/custom/CustomCommandExecutor.ts +0 -143
- package/src/slash-commands/custom/CustomCommandLoader.ts +0 -251
- package/src/slash-commands/custom/CustomCommandRegistry.ts +0 -144
- package/src/slash-commands/custom/index.ts +0 -7
- package/src/slash-commands/debate.ts +0 -254
- package/src/slash-commands/gmail.ts +0 -105
- package/src/slash-commands/index.ts +0 -388
- package/src/slash-commands/mcpCommand.ts +0 -205
- package/src/slash-commands/types.ts +0 -201
- package/src/store/index.ts +0 -76
- package/src/store/selectors.ts +0 -246
- package/src/store/slices/appSlice.ts +0 -205
- package/src/store/slices/commandSlice.ts +0 -115
- package/src/store/slices/configSlice.ts +0 -46
- package/src/store/slices/focusSlice.ts +0 -64
- package/src/store/slices/index.ts +0 -9
- package/src/store/slices/sessionSlice.ts +0 -424
- package/src/store/streaming-buffer.ts +0 -425
- package/src/store/test.ts +0 -296
- package/src/store/types.ts +0 -274
- package/src/store/vanilla.ts +0 -186
- package/src/tools/builtin/bash.ts +0 -236
- package/src/tools/builtin/council.ts +0 -105
- package/src/tools/builtin/edit.ts +0 -213
- package/src/tools/builtin/glob.ts +0 -136
- package/src/tools/builtin/grep.ts +0 -263
- package/src/tools/builtin/index.ts +0 -61
- package/src/tools/builtin/memory.ts +0 -66
- package/src/tools/builtin/read.ts +0 -168
- package/src/tools/builtin/skill.ts +0 -97
- package/src/tools/builtin/snapshot.ts +0 -40
- package/src/tools/builtin/task.ts +0 -106
- package/src/tools/builtin/write.ts +0 -134
- package/src/tools/createTool.ts +0 -221
- package/src/tools/execution/ExecutionPipeline.ts +0 -263
- package/src/tools/execution/index.ts +0 -40
- package/src/tools/execution/stages/CacheStage.ts +0 -131
- package/src/tools/execution/stages/ConfirmationStage.ts +0 -203
- package/src/tools/execution/stages/DiscoveryStage.ts +0 -46
- package/src/tools/execution/stages/ExecutionStage.ts +0 -48
- package/src/tools/execution/stages/FormattingStage.ts +0 -44
- package/src/tools/execution/stages/HookStage.ts +0 -72
- package/src/tools/execution/stages/PermissionStage.ts +0 -287
- package/src/tools/execution/stages/PostHookStage.ts +0 -71
- package/src/tools/execution/stages/index.ts +0 -12
- package/src/tools/execution/test.ts +0 -266
- package/src/tools/execution/types.ts +0 -273
- package/src/tools/index.ts +0 -81
- package/src/tools/registry.ts +0 -304
- package/src/tools/schemas.ts +0 -109
- package/src/tools/test.ts +0 -220
- package/src/tools/types.ts +0 -175
- package/src/tools/validation/PermissionChecker.ts +0 -242
- package/src/tools/validation/SensitiveFileDetector.ts +0 -210
- package/src/tools/validation/index.ts +0 -11
- package/src/ui/App.tsx +0 -166
- package/src/ui/components/AegisInterface.tsx +0 -484
- package/src/ui/components/common/ChatSearch.tsx +0 -150
- package/src/ui/components/common/ErrorBoundary.tsx +0 -82
- package/src/ui/components/common/ExitMessage.tsx +0 -120
- package/src/ui/components/common/LoadingIndicator.tsx +0 -49
- package/src/ui/components/common/index.ts +0 -6
- package/src/ui/components/dialog/ConfirmationPrompt.tsx +0 -208
- package/src/ui/components/dialog/InteractiveSelector.tsx +0 -149
- package/src/ui/components/dialog/SetupWizard.tsx +0 -297
- package/src/ui/components/dialog/UpdatePrompt.tsx +0 -155
- package/src/ui/components/dialog/index.ts +0 -8
- package/src/ui/components/index.ts +0 -28
- package/src/ui/components/input/CommandSuggestions.tsx +0 -139
- package/src/ui/components/input/CustomTextInput.tsx +0 -220
- package/src/ui/components/input/InputArea.tsx +0 -361
- package/src/ui/components/input/PromptSuggestions.tsx +0 -66
- package/src/ui/components/input/index.ts +0 -6
- package/src/ui/components/layout/ChatStatusBar.tsx +0 -90
- package/src/ui/components/layout/ContextBar.tsx +0 -79
- package/src/ui/components/layout/MessageArea.tsx +0 -96
- package/src/ui/components/layout/MessageList.tsx +0 -647
- package/src/ui/components/layout/MessageSeparator.tsx +0 -26
- package/src/ui/components/layout/WelcomeMessage.tsx +0 -93
- package/src/ui/components/layout/index.ts +0 -7
- package/src/ui/components/markdown/CodeHighlighter.tsx +0 -292
- package/src/ui/components/markdown/MessageRenderer.tsx +0 -1211
- package/src/ui/components/markdown/index.ts +0 -8
- package/src/ui/components/markdown/parser.ts +0 -336
- package/src/ui/components/markdown/types.ts +0 -66
- package/src/ui/focus/FocusManager.ts +0 -137
- package/src/ui/focus/index.ts +0 -13
- package/src/ui/focus/types.ts +0 -54
- package/src/ui/focus/useFocus.ts +0 -75
- package/src/ui/hooks/index.ts +0 -11
- package/src/ui/hooks/useAgent.ts +0 -284
- package/src/ui/hooks/useCommandHistory.ts +0 -87
- package/src/ui/hooks/useCommandProcessor.ts +0 -443
- package/src/ui/hooks/useConfirmation.ts +0 -99
- package/src/ui/hooks/useCtrlCHandler.ts +0 -100
- package/src/ui/hooks/useInputBuffer.ts +0 -122
- package/src/ui/hooks/useTerminalSize.ts +0 -68
- package/src/ui/hooks/useTerminalWidth.ts +0 -5
- package/src/ui/hooks/useWindowedList.ts +0 -118
- package/src/ui/render-debugger.ts +0 -621
- package/src/ui/test.ts +0 -189
- package/src/ui/themes/ThemeManager.ts +0 -332
- package/src/ui/themes/aegisTheme.ts +0 -87
- package/src/ui/themes/darkTheme.ts +0 -87
- package/src/ui/themes/defaultTheme.ts +0 -85
- package/src/ui/themes/index.ts +0 -10
- package/src/ui/themes/lightTheme.ts +0 -89
- package/src/ui/themes/popularThemes.ts +0 -187
- package/src/ui/themes/types.ts +0 -130
- package/src/utils/clipboard.ts +0 -48
- package/src/utils/debug.ts +0 -43
- package/src/utils/environment.ts +0 -68
- package/src/utils/index.ts +0 -10
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Edit 工具
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import fs from 'fs/promises';
|
|
8
|
-
import path from 'path';
|
|
9
|
-
import { z } from 'zod';
|
|
10
|
-
import { createTool } from '../createTool.js';
|
|
11
|
-
import { ToolKind, ToolErrorType } from '../types.js';
|
|
12
|
-
import { createSnapshot } from './snapshot.js';
|
|
13
|
-
|
|
14
|
-
// ========== Schema 定
|
|
15
|
-
|
|
16
|
-
const EditSchema = z.object({
|
|
17
|
-
file_path: z.string()
|
|
18
|
-
.min(1, '文件路径不能为空')
|
|
19
|
-
.describe('The absolute path to the file to modify'),
|
|
20
|
-
old_string: z.string()
|
|
21
|
-
.describe('The text to replace (must be unique in the file unless replace_all is true)'),
|
|
22
|
-
new_string: z.string()
|
|
23
|
-
.describe('The text to replace it with'),
|
|
24
|
-
replace_all: z.boolean()
|
|
25
|
-
.default(false)
|
|
26
|
-
.describe('If true, replace all occurrences of old_string'),
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// ========== Edit 工
|
|
30
|
-
|
|
31
|
-
export const editTool = createTool({
|
|
32
|
-
name: 'Edit',
|
|
33
|
-
displayName: 'File Edit',
|
|
34
|
-
kind: ToolKind.Write,
|
|
35
|
-
schema: EditSchema,
|
|
36
|
-
|
|
37
|
-
description: {
|
|
38
|
-
short: 'Performs exact string replacements in files',
|
|
39
|
-
long: 'Edits files by replacing specified text with new text. Requires the old_string to be unique unless replace_all is true.',
|
|
40
|
-
usageNotes: [
|
|
41
|
-
'You MUST use the Read tool first before editing a file',
|
|
42
|
-
'The edit will FAIL if old_string is not unique in the file',
|
|
43
|
-
'Use replace_all=true for renaming variables across the file',
|
|
44
|
-
'Preserve exact indentation (tabs/spaces) as it appears',
|
|
45
|
-
'If you want to create a new file, use the Write tool instead',
|
|
46
|
-
],
|
|
47
|
-
examples: [
|
|
48
|
-
{
|
|
49
|
-
description: 'Replace a function name',
|
|
50
|
-
params: {
|
|
51
|
-
file_path: '/path/to/file.ts',
|
|
52
|
-
old_string: 'function oldName(',
|
|
53
|
-
new_string: 'function newName(',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
description: 'Replace all occurrences of a variable',
|
|
58
|
-
params: {
|
|
59
|
-
file_path: '/path/to/file.ts',
|
|
60
|
-
old_string: 'oldVar',
|
|
61
|
-
new_string: 'newVar',
|
|
62
|
-
replace_all: true,
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
important: [
|
|
67
|
-
'NEVER guess file contents - always Read first',
|
|
68
|
-
'If old_string is not found, the edit will fail',
|
|
69
|
-
'If multiple matches found without replace_all, provide more context',
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
category: '文件操作',
|
|
74
|
-
tags: ['file', 'io', 'write', 'edit'],
|
|
75
|
-
|
|
76
|
-
// 提取签名内容(用于权限规
|
|
77
|
-
extractSignatureContent: (params: unknown) => {
|
|
78
|
-
const p = params as { file_path: string };
|
|
79
|
-
return p.file_path;
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
// 抽象权限规
|
|
83
|
-
abstractPermissionRule: (params: unknown) => {
|
|
84
|
-
const p = params as { file_path: string };
|
|
85
|
-
const dir = path.dirname(p.file_path);
|
|
86
|
-
return `Edit:${dir}/*`;
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
async execute(params, context) {
|
|
90
|
-
const { file_path, old_string, new_string, replace_all } = params;
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
// 1. 检查文件是否存
|
|
94
|
-
try {
|
|
95
|
-
const stat = await fs.stat(file_path);
|
|
96
|
-
if (stat.isDirectory()) {
|
|
97
|
-
return {
|
|
98
|
-
success: false,
|
|
99
|
-
llmContent: `Error: ${file_path} is a directory, not a file`,
|
|
100
|
-
displayContent: `error: ${file_path} is a directory`,
|
|
101
|
-
error: {
|
|
102
|
-
type: ToolErrorType.VALIDATION_ERROR,
|
|
103
|
-
message: 'Path is a directory',
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
} catch (error) {
|
|
108
|
-
return {
|
|
109
|
-
success: false,
|
|
110
|
-
llmContent: `Error: File not found: ${file_path}`,
|
|
111
|
-
displayContent: `error: file not found: ${file_path}`,
|
|
112
|
-
error: {
|
|
113
|
-
type: ToolErrorType.VALIDATION_ERROR,
|
|
114
|
-
message: 'File not found',
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// 2. 读取文件内
|
|
120
|
-
const content = await fs.readFile(file_path, 'utf8');
|
|
121
|
-
|
|
122
|
-
// 3. old_string 和 new_string 相同检
|
|
123
|
-
if (old_string === new_string) {
|
|
124
|
-
return {
|
|
125
|
-
success: false,
|
|
126
|
-
llmContent: 'Error: old_string and new_string are identical',
|
|
127
|
-
displayContent: 'error: old_string and new_string are identical',
|
|
128
|
-
error: {
|
|
129
|
-
type: ToolErrorType.VALIDATION_ERROR,
|
|
130
|
-
message: 'old_string and new_string are identical',
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// 4. 检查 old_string 是否存
|
|
136
|
-
const matchCount = content.split(old_string).length - 1;
|
|
137
|
-
|
|
138
|
-
if (matchCount === 0) {
|
|
139
|
-
return {
|
|
140
|
-
success: false,
|
|
141
|
-
llmContent: `Error: old_string not found in file. Make sure you have read the file first and the content is up to date.`,
|
|
142
|
-
displayContent: `error: old_string not found in file`,
|
|
143
|
-
error: {
|
|
144
|
-
type: ToolErrorType.VALIDATION_ERROR,
|
|
145
|
-
message: 'old_string not found in file',
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// 5. 多重匹配检查(非 replace_all 模
|
|
151
|
-
if (matchCount > 1 && !replace_all) {
|
|
152
|
-
return {
|
|
153
|
-
success: false,
|
|
154
|
-
llmContent: `Error: Multiple matches (${matchCount}) found for old_string. Either:
|
|
155
|
-
1. Provide more context in old_string to make it unique
|
|
156
|
-
2. Set replace_all=true to replace all occurrences`,
|
|
157
|
-
displayContent: `error: ${matchCount} matches found — use replace_all or add more context`,
|
|
158
|
-
error: {
|
|
159
|
-
type: ToolErrorType.VALIDATION_ERROR,
|
|
160
|
-
message: `Multiple matches (${matchCount}) found`,
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// 6. 快照原始文件(支持 undo)
|
|
166
|
-
const snapshotPath = await createSnapshot(file_path);
|
|
167
|
-
|
|
168
|
-
// 7. 执行替
|
|
169
|
-
const newContent = replace_all
|
|
170
|
-
? content.replaceAll(old_string, new_string)
|
|
171
|
-
: content.replace(old_string, new_string);
|
|
172
|
-
|
|
173
|
-
// 8. 写入文
|
|
174
|
-
await fs.writeFile(file_path, newContent, 'utf8');
|
|
175
|
-
|
|
176
|
-
// 9. 计算替换数
|
|
177
|
-
const replacements = replace_all ? matchCount : 1;
|
|
178
|
-
|
|
179
|
-
// Render as a unified-style diff: old_string lines removed, new_string lines
|
|
180
|
-
// added. The renderer (MessageRenderer's ToolUseBlock) detects +/- prefixed
|
|
181
|
-
// lines and colors them, deriving the "+N -M lines" tally from the counts.
|
|
182
|
-
const diffLines = [
|
|
183
|
-
...old_string.split('\n').map(l => `-${l}`),
|
|
184
|
-
...new_string.split('\n').map(l => `+${l}`),
|
|
185
|
-
];
|
|
186
|
-
|
|
187
|
-
return {
|
|
188
|
-
success: true,
|
|
189
|
-
llmContent: `Successfully edited ${file_path} (${replacements} replacement${replacements > 1 ? 's' : ''})`,
|
|
190
|
-
displayContent: diffLines.join('\n'),
|
|
191
|
-
metadata: {
|
|
192
|
-
file_path,
|
|
193
|
-
replacements,
|
|
194
|
-
snapshot: snapshotPath,
|
|
195
|
-
old_string_preview: old_string.length > 50
|
|
196
|
-
? old_string.substring(0, 50) + '...'
|
|
197
|
-
: old_string,
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
} catch (error) {
|
|
201
|
-
const errorMessage = error instanceof Error ? error.message : 'unknown error';
|
|
202
|
-
return {
|
|
203
|
-
success: false,
|
|
204
|
-
llmContent: `Error editing file: ${errorMessage}`,
|
|
205
|
-
displayContent: `error: ${errorMessage}`,
|
|
206
|
-
error: {
|
|
207
|
-
type: ToolErrorType.EXECUTION_ERROR,
|
|
208
|
-
message: errorMessage,
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
});
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Glob 工具 - 文件搜索
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { glob } from 'glob';
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import { z } from 'zod';
|
|
8
|
-
import { createTool } from '../createTool.js';
|
|
9
|
-
import { ToolKind, ToolErrorType } from '../types.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
*/
|
|
14
|
-
const DEFAULT_IGNORE = [
|
|
15
|
-
'**/node_modules/**',
|
|
16
|
-
'**/.git/**',
|
|
17
|
-
'**/dist/**',
|
|
18
|
-
'**/build/**',
|
|
19
|
-
'**/.next/**',
|
|
20
|
-
'**/coverage/**',
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Glob 工具 Schema
|
|
25
|
-
*/
|
|
26
|
-
const GlobSchema = z.object({
|
|
27
|
-
pattern: z.string()
|
|
28
|
-
.min(1, '模式不能为空')
|
|
29
|
-
.describe('The glob pattern to match files against'),
|
|
30
|
-
|
|
31
|
-
path: z.string()
|
|
32
|
-
.optional()
|
|
33
|
-
.describe('Directory to search in (defaults to current working directory)'),
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Glob 工具
|
|
38
|
-
*/
|
|
39
|
-
export const globTool = createTool({
|
|
40
|
-
name: 'Glob',
|
|
41
|
-
displayName: 'File Search',
|
|
42
|
-
kind: ToolKind.ReadOnly,
|
|
43
|
-
schema: GlobSchema,
|
|
44
|
-
|
|
45
|
-
description: {
|
|
46
|
-
short: 'Find files matching a glob pattern',
|
|
47
|
-
long: `Search for files matching a glob pattern. Returns matching file paths sorted by modification time.
|
|
48
|
-
Use this tool when you need to find files by name patterns.`,
|
|
49
|
-
usageNotes: [
|
|
50
|
-
'Patterns not starting with "**/" are automatically prepended with "**/" to enable recursive searching',
|
|
51
|
-
'Common patterns: "*.ts" for TypeScript files, "*.test.ts" for test files',
|
|
52
|
-
'Results are sorted by modification time (newest first)',
|
|
53
|
-
'Automatically ignores node_modules, .git, dist, build directories',
|
|
54
|
-
],
|
|
55
|
-
examples: [
|
|
56
|
-
{
|
|
57
|
-
description: 'Find all TypeScript files',
|
|
58
|
-
params: { pattern: '*.ts' },
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
description: 'Find all test files',
|
|
62
|
-
params: { pattern: '**/*.test.ts' },
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
description: 'Find files in specific directory',
|
|
66
|
-
params: { pattern: '*.json', path: '/project/config' },
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
category: '搜索',
|
|
72
|
-
tags: ['search', 'file', 'glob'],
|
|
73
|
-
|
|
74
|
-
async execute(params, context) {
|
|
75
|
-
let { pattern, path: searchPath } = params;
|
|
76
|
-
|
|
77
|
-
// 默认搜索目
|
|
78
|
-
const cwd = searchPath || context?.cwd || process.cwd();
|
|
79
|
-
|
|
80
|
-
// 自动添
|
|
81
|
-
if (!pattern.startsWith('**/') && !pattern.startsWith('/')) {
|
|
82
|
-
pattern = `**/${pattern}`;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
// 执行 glob 搜
|
|
87
|
-
const files = await glob(pattern, {
|
|
88
|
-
cwd,
|
|
89
|
-
ignore: DEFAULT_IGNORE,
|
|
90
|
-
nodir: true,
|
|
91
|
-
absolute: true,
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
if (files.length === 0) {
|
|
95
|
-
return {
|
|
96
|
-
success: true,
|
|
97
|
-
llmContent: 'No files found matching the pattern.',
|
|
98
|
-
displayContent: `no files: ${pattern}`,
|
|
99
|
-
metadata: {
|
|
100
|
-
pattern,
|
|
101
|
-
cwd,
|
|
102
|
-
count: 0,
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// 格式化输
|
|
108
|
-
const formattedFiles = files
|
|
109
|
-
.map(f => path.relative(cwd, f))
|
|
110
|
-
.join('\n');
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
success: true,
|
|
114
|
-
llmContent: formattedFiles,
|
|
115
|
-
displayContent: `${files.length} file${files.length === 1 ? '' : 's'}`,
|
|
116
|
-
metadata: {
|
|
117
|
-
pattern,
|
|
118
|
-
cwd,
|
|
119
|
-
count: files.length,
|
|
120
|
-
files: files.slice(0, 100), // 只存储前 100
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
} catch (error) {
|
|
124
|
-
const errorMessage = error instanceof Error ? error.message : '未知错误';
|
|
125
|
-
return {
|
|
126
|
-
success: false,
|
|
127
|
-
llmContent: `Glob search failed: ${errorMessage}`,
|
|
128
|
-
displayContent: `error: ${errorMessage}`,
|
|
129
|
-
error: {
|
|
130
|
-
type: ToolErrorType.EXECUTION_ERROR,
|
|
131
|
-
message: errorMessage,
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
});
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Grep 工具 - 内容搜索
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import fs from 'fs/promises';
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import { glob } from 'glob';
|
|
8
|
-
import { z } from 'zod';
|
|
9
|
-
import { createTool } from '../createTool.js';
|
|
10
|
-
import { ToolKind, ToolErrorType } from '../types.js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
*/
|
|
15
|
-
const DEFAULT_IGNORE = [
|
|
16
|
-
'**/node_modules/**',
|
|
17
|
-
'**/.git/**',
|
|
18
|
-
'**/dist/**',
|
|
19
|
-
'**/build/**',
|
|
20
|
-
'**/.next/**',
|
|
21
|
-
'**/coverage/**',
|
|
22
|
-
'**/*.min.js',
|
|
23
|
-
'**/*.bundle.js',
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
*
|
|
28
|
-
*/
|
|
29
|
-
const MAX_RESULTS = 100;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Grep 工具 Schema
|
|
33
|
-
*/
|
|
34
|
-
const GrepSchema = z.object({
|
|
35
|
-
pattern: z.string()
|
|
36
|
-
.min(1, '搜索模式不能为空')
|
|
37
|
-
.describe('The regular expression pattern to search for'),
|
|
38
|
-
|
|
39
|
-
path: z.string()
|
|
40
|
-
.optional()
|
|
41
|
-
.describe('Directory to search in (defaults to current working directory)'),
|
|
42
|
-
|
|
43
|
-
include: z.string()
|
|
44
|
-
.optional()
|
|
45
|
-
.describe('Glob pattern to filter files (e.g., "*.ts" for TypeScript files)'),
|
|
46
|
-
|
|
47
|
-
case_sensitive: z.boolean()
|
|
48
|
-
.default(true)
|
|
49
|
-
.describe('Whether the search is case sensitive'),
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
*
|
|
54
|
-
*/
|
|
55
|
-
interface SearchMatch {
|
|
56
|
-
file: string;
|
|
57
|
-
line: number;
|
|
58
|
-
content: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
*/
|
|
64
|
-
async function searchInFile(
|
|
65
|
-
filePath: string,
|
|
66
|
-
regex: RegExp
|
|
67
|
-
): Promise<SearchMatch[]> {
|
|
68
|
-
try {
|
|
69
|
-
const content = await fs.readFile(filePath, 'utf-8');
|
|
70
|
-
const lines = content.split('\n');
|
|
71
|
-
const matches: SearchMatch[] = [];
|
|
72
|
-
|
|
73
|
-
for (let i = 0; i < lines.length; i++) {
|
|
74
|
-
if (regex.test(lines[i])) {
|
|
75
|
-
matches.push({
|
|
76
|
-
file: filePath,
|
|
77
|
-
line: i + 1,
|
|
78
|
-
content: lines[i].trim(),
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return matches;
|
|
84
|
-
} catch {
|
|
85
|
-
// 忽略无法读取的文
|
|
86
|
-
return [];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Grep 工具
|
|
92
|
-
*/
|
|
93
|
-
export const grepTool = createTool({
|
|
94
|
-
name: 'Grep',
|
|
95
|
-
displayName: 'Content Search',
|
|
96
|
-
kind: ToolKind.ReadOnly,
|
|
97
|
-
schema: GrepSchema,
|
|
98
|
-
|
|
99
|
-
description: {
|
|
100
|
-
short: 'Search file contents using regular expressions',
|
|
101
|
-
long: `A powerful search tool for finding patterns in file contents.
|
|
102
|
-
Supports full regex syntax and can filter files by glob pattern.`,
|
|
103
|
-
usageNotes: [
|
|
104
|
-
'Uses JavaScript regex syntax',
|
|
105
|
-
'Common patterns: "function\\s+\\w+" for function definitions',
|
|
106
|
-
'Use include parameter to filter files: "*.ts" for TypeScript only',
|
|
107
|
-
'Results are limited to 100 matches for performance',
|
|
108
|
-
'Automatically ignores node_modules, .git, dist directories',
|
|
109
|
-
],
|
|
110
|
-
examples: [
|
|
111
|
-
{
|
|
112
|
-
description: 'Search for function definitions',
|
|
113
|
-
params: { pattern: 'function\\s+\\w+' },
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
description: 'Search in TypeScript files only',
|
|
117
|
-
params: { pattern: 'export', include: '*.ts' },
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
description: 'Case-insensitive search',
|
|
121
|
-
params: { pattern: 'todo', case_sensitive: false },
|
|
122
|
-
},
|
|
123
|
-
],
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
category: '搜索',
|
|
127
|
-
tags: ['search', 'grep', 'regex'],
|
|
128
|
-
|
|
129
|
-
async execute(params, context) {
|
|
130
|
-
const { pattern, path: searchPath, include, case_sensitive } = params;
|
|
131
|
-
|
|
132
|
-
// 默认搜索目
|
|
133
|
-
const cwd = searchPath || context?.cwd || process.cwd();
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
// 创建正则表达
|
|
137
|
-
// 验证正则表达式是否包含未闭合的字符类或分组
|
|
138
|
-
const unclosedBracket = (pattern.match(/\[/g) || []).length !== (pattern.match(/\]/g) || []).length;
|
|
139
|
-
const unclosedParen = (pattern.match(/\(/g) || []).length !== (pattern.match(/\)/g) || []).length;
|
|
140
|
-
|
|
141
|
-
if (unclosedBracket || unclosedParen) {
|
|
142
|
-
return {
|
|
143
|
-
success: false,
|
|
144
|
-
llmContent: `Invalid regex pattern: ${pattern} — unclosed bracket or parenthesis`,
|
|
145
|
-
displayContent: `error: invalid regex — unclosed bracket or parenthesis`,
|
|
146
|
-
error: {
|
|
147
|
-
type: ToolErrorType.VALIDATION_ERROR,
|
|
148
|
-
message: 'Invalid regex pattern — unclosed bracket or parenthesis',
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
let regex: RegExp;
|
|
154
|
-
try {
|
|
155
|
-
regex = new RegExp(pattern, case_sensitive ? 'g' : 'gi');
|
|
156
|
-
} catch (e) {
|
|
157
|
-
return {
|
|
158
|
-
success: false,
|
|
159
|
-
llmContent: `Invalid regex pattern: ${pattern}`,
|
|
160
|
-
displayContent: `error: invalid regex: ${pattern}`,
|
|
161
|
-
error: {
|
|
162
|
-
type: ToolErrorType.VALIDATION_ERROR,
|
|
163
|
-
message: 'Invalid regex pattern',
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// 获取要搜索的文件列
|
|
169
|
-
const filePattern = include
|
|
170
|
-
? (include.startsWith('**/') ? include : `**/${include}`)
|
|
171
|
-
: '**/*';
|
|
172
|
-
|
|
173
|
-
const files = await glob(filePattern, {
|
|
174
|
-
cwd,
|
|
175
|
-
ignore: DEFAULT_IGNORE,
|
|
176
|
-
nodir: true,
|
|
177
|
-
absolute: true,
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
// 过滤二进制文件(简单判
|
|
181
|
-
const textExtensions = [
|
|
182
|
-
'.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
|
|
183
|
-
'.json', '.md', '.txt', '.yaml', '.yml',
|
|
184
|
-
'.html', '.css', '.scss', '.less',
|
|
185
|
-
'.py', '.rb', '.go', '.rs', '.java',
|
|
186
|
-
'.c', '.cpp', '.h', '.hpp',
|
|
187
|
-
'.sh', '.bash', '.zsh',
|
|
188
|
-
'.xml', '.svg',
|
|
189
|
-
];
|
|
190
|
-
|
|
191
|
-
const textFiles = files.filter(f =>
|
|
192
|
-
textExtensions.some(ext => f.endsWith(ext))
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
// 搜索所有文
|
|
196
|
-
const allMatches: SearchMatch[] = [];
|
|
197
|
-
|
|
198
|
-
for (const file of textFiles) {
|
|
199
|
-
if (allMatches.length >= MAX_RESULTS) break;
|
|
200
|
-
|
|
201
|
-
const matches = await searchInFile(file, regex);
|
|
202
|
-
allMatches.push(...matches);
|
|
203
|
-
|
|
204
|
-
if (allMatches.length >= MAX_RESULTS) {
|
|
205
|
-
allMatches.length = MAX_RESULTS;
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (allMatches.length === 0) {
|
|
211
|
-
return {
|
|
212
|
-
success: true,
|
|
213
|
-
llmContent: 'No matches found.',
|
|
214
|
-
displayContent: `no matches: ${pattern}`,
|
|
215
|
-
metadata: {
|
|
216
|
-
pattern,
|
|
217
|
-
cwd,
|
|
218
|
-
files_searched: textFiles.length,
|
|
219
|
-
matches: 0,
|
|
220
|
-
},
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// 格式化输
|
|
225
|
-
const formattedMatches = allMatches
|
|
226
|
-
.map(m => {
|
|
227
|
-
const relPath = path.relative(cwd, m.file);
|
|
228
|
-
return `${relPath}:${m.line}: ${m.content}`;
|
|
229
|
-
})
|
|
230
|
-
.join('\n');
|
|
231
|
-
|
|
232
|
-
const truncated = allMatches.length >= MAX_RESULTS;
|
|
233
|
-
let summary = `${allMatches.length} match${allMatches.length === 1 ? '' : 'es'}`;
|
|
234
|
-
if (truncated) {
|
|
235
|
-
summary += ` (truncated)`;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return {
|
|
239
|
-
success: true,
|
|
240
|
-
llmContent: formattedMatches,
|
|
241
|
-
displayContent: summary,
|
|
242
|
-
metadata: {
|
|
243
|
-
pattern,
|
|
244
|
-
cwd,
|
|
245
|
-
files_searched: textFiles.length,
|
|
246
|
-
matches: allMatches.length,
|
|
247
|
-
truncated,
|
|
248
|
-
},
|
|
249
|
-
};
|
|
250
|
-
} catch (error) {
|
|
251
|
-
const errorMessage = error instanceof Error ? error.message : 'unknown error';
|
|
252
|
-
return {
|
|
253
|
-
success: false,
|
|
254
|
-
llmContent: `Grep search failed: ${errorMessage}`,
|
|
255
|
-
displayContent: `error: ${errorMessage}`,
|
|
256
|
-
error: {
|
|
257
|
-
type: ToolErrorType.EXECUTION_ERROR,
|
|
258
|
-
message: errorMessage,
|
|
259
|
-
},
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
},
|
|
263
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// 文件工
|
|
6
|
-
export { readTool } from './read.js';
|
|
7
|
-
export { editTool } from './edit.js';
|
|
8
|
-
export { writeTool } from './write.js';
|
|
9
|
-
|
|
10
|
-
// 搜索工
|
|
11
|
-
export { grepTool } from './grep.js';
|
|
12
|
-
export { globTool } from './glob.js';
|
|
13
|
-
|
|
14
|
-
// Shell 工
|
|
15
|
-
export { bashTool } from './bash.js';
|
|
16
|
-
|
|
17
|
-
// Skills 工
|
|
18
|
-
export { skillTool } from './skill.js';
|
|
19
|
-
|
|
20
|
-
// Memory 工
|
|
21
|
-
export { memoryTool } from './memory.js';
|
|
22
|
-
|
|
23
|
-
// Multi-agent orchestration 工
|
|
24
|
-
export { taskTool } from './task.js';
|
|
25
|
-
export { councilTool } from './council.js';
|
|
26
|
-
|
|
27
|
-
import { readTool } from './read.js';
|
|
28
|
-
import { editTool } from './edit.js';
|
|
29
|
-
import { writeTool } from './write.js';
|
|
30
|
-
import { grepTool } from './grep.js';
|
|
31
|
-
import { globTool } from './glob.js';
|
|
32
|
-
import { bashTool } from './bash.js';
|
|
33
|
-
import { skillTool } from './skill.js';
|
|
34
|
-
import { memoryTool } from './memory.js';
|
|
35
|
-
import { taskTool } from './task.js';
|
|
36
|
-
import { councilTool } from './council.js';
|
|
37
|
-
import type { Tool } from '../types.js';
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
*
|
|
41
|
-
*/
|
|
42
|
-
export function getBuiltinTools(): Tool[] {
|
|
43
|
-
return [
|
|
44
|
-
// 文件工
|
|
45
|
-
readTool,
|
|
46
|
-
editTool,
|
|
47
|
-
writeTool,
|
|
48
|
-
// 搜索工
|
|
49
|
-
grepTool,
|
|
50
|
-
globTool,
|
|
51
|
-
// Shell 工
|
|
52
|
-
bashTool,
|
|
53
|
-
// Skills 工
|
|
54
|
-
skillTool,
|
|
55
|
-
// Memory 工
|
|
56
|
-
memoryTool,
|
|
57
|
-
// Multi-agent orchestration 工
|
|
58
|
-
taskTool,
|
|
59
|
-
councilTool,
|
|
60
|
-
];
|
|
61
|
-
}
|