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.
Files changed (209) hide show
  1. package/bin/aegis.js +165 -0
  2. package/package.json +18 -86
  3. package/LICENSE +0 -21
  4. package/README.md +0 -394
  5. package/dist/main.js +0 -2171
  6. package/gui/run-gui.cjs +0 -13
  7. package/src/agent/Agent.ts +0 -903
  8. package/src/agent/SimpleAgent.ts +0 -48
  9. package/src/agent/index.ts +0 -54
  10. package/src/agent/orchestrator/AppBuilder.ts +0 -443
  11. package/src/agent/orchestrator/CouncilAgent.ts +0 -310
  12. package/src/agent/orchestrator/DiscussionRoom.ts +0 -462
  13. package/src/agent/orchestrator/OrchestratorAgent.ts +0 -637
  14. package/src/agent/orchestrator/index.ts +0 -38
  15. package/src/agent/orchestrator/utils.ts +0 -397
  16. package/src/agent/pricing.ts +0 -115
  17. package/src/agent/router.ts +0 -74
  18. package/src/agent/routerStats.ts +0 -121
  19. package/src/agent/types.ts +0 -318
  20. package/src/auth/login.ts +0 -383
  21. package/src/cli/config.ts +0 -189
  22. package/src/cli/index.ts +0 -17
  23. package/src/cli/middleware.ts +0 -119
  24. package/src/cli/types.ts +0 -75
  25. package/src/config/ConfigManager.ts +0 -587
  26. package/src/config/index.ts +0 -7
  27. package/src/config/types.ts +0 -584
  28. package/src/context/CompactionService.ts +0 -300
  29. package/src/context/ContextManager.ts +0 -450
  30. package/src/context/FileAnalyzer.ts +0 -267
  31. package/src/context/TokenCounter.ts +0 -265
  32. package/src/context/index.ts +0 -27
  33. package/src/context/storage/CacheStore.ts +0 -176
  34. package/src/context/storage/JSONLStore.ts +0 -201
  35. package/src/context/storage/MemoryStore.ts +0 -205
  36. package/src/context/storage/PersistentStore.ts +0 -327
  37. package/src/context/storage/index.ts +0 -9
  38. package/src/context/storage/pathUtils.ts +0 -114
  39. package/src/context/test.ts +0 -309
  40. package/src/context/types.ts +0 -268
  41. package/src/hooks/HookExecutor.ts +0 -434
  42. package/src/hooks/HookManager.ts +0 -596
  43. package/src/hooks/HookService.ts +0 -269
  44. package/src/hooks/Matcher.ts +0 -157
  45. package/src/hooks/index.ts +0 -63
  46. package/src/hooks/types.ts +0 -424
  47. package/src/main.tsx +0 -596
  48. package/src/mcp/HealthMonitor.ts +0 -150
  49. package/src/mcp/McpClient.ts +0 -491
  50. package/src/mcp/McpRegistry.ts +0 -321
  51. package/src/mcp/createMcpTool.ts +0 -251
  52. package/src/mcp/index.ts +0 -15
  53. package/src/mcp/server.ts +0 -334
  54. package/src/mcp/test-server.ts +0 -88
  55. package/src/mcp/test.ts +0 -372
  56. package/src/mcp/types.ts +0 -247
  57. package/src/memory/AgentMemoryBus.ts +0 -432
  58. package/src/memory/CloudSync.ts +0 -99
  59. package/src/memory/DriveSync.ts +0 -106
  60. package/src/memory/SharedMemory.ts +0 -951
  61. package/src/memory/index.ts +0 -14
  62. package/src/memory/machineFingerprint.ts +0 -40
  63. package/src/orchestrator/SubAgentMetadata.ts +0 -136
  64. package/src/prompts/builder.ts +0 -213
  65. package/src/prompts/default.ts +0 -144
  66. package/src/prompts/index.ts +0 -16
  67. package/src/prompts/plan.ts +0 -64
  68. package/src/prompts/test.ts +0 -78
  69. package/src/services/AnthropicChatService.ts +0 -341
  70. package/src/services/ChatService.ts +0 -347
  71. package/src/services/ClaudeCliChatService.ts +0 -256
  72. package/src/services/CloudSync.ts +0 -168
  73. package/src/services/CostLedger.ts +0 -211
  74. package/src/services/Heartbeat.ts +0 -135
  75. package/src/services/LearningCollector.ts +0 -291
  76. package/src/services/OllamaInstaller.ts +0 -342
  77. package/src/services/VersionChecker.ts +0 -445
  78. package/src/services/index.ts +0 -57
  79. package/src/services/streaming/OpenAIEventAdapter.ts +0 -126
  80. package/src/services/streaming/RenderingProfile.ts +0 -90
  81. package/src/services/streaming/StreamEventParser.ts +0 -181
  82. package/src/services/streaming/ThrottledRenderer.ts +0 -139
  83. package/src/services/streaming/TranscriptBuffer.ts +0 -574
  84. package/src/services/streaming/eventStatusMap.ts +0 -52
  85. package/src/services/streaming/index.ts +0 -46
  86. package/src/services/streaming/renderFormatting.ts +0 -79
  87. package/src/services/streaming/types.ts +0 -234
  88. package/src/skills/SkillLoader.ts +0 -126
  89. package/src/skills/SkillRegistry.ts +0 -366
  90. package/src/skills/index.ts +0 -48
  91. package/src/skills/types.ts +0 -146
  92. package/src/slash-commands/billing.ts +0 -70
  93. package/src/slash-commands/build.ts +0 -413
  94. package/src/slash-commands/builtinCommands.ts +0 -2733
  95. package/src/slash-commands/clone.ts +0 -242
  96. package/src/slash-commands/council.ts +0 -125
  97. package/src/slash-commands/custom/CustomCommandExecutor.ts +0 -143
  98. package/src/slash-commands/custom/CustomCommandLoader.ts +0 -251
  99. package/src/slash-commands/custom/CustomCommandRegistry.ts +0 -144
  100. package/src/slash-commands/custom/index.ts +0 -7
  101. package/src/slash-commands/debate.ts +0 -254
  102. package/src/slash-commands/gmail.ts +0 -105
  103. package/src/slash-commands/index.ts +0 -388
  104. package/src/slash-commands/mcpCommand.ts +0 -205
  105. package/src/slash-commands/types.ts +0 -201
  106. package/src/store/index.ts +0 -76
  107. package/src/store/selectors.ts +0 -246
  108. package/src/store/slices/appSlice.ts +0 -205
  109. package/src/store/slices/commandSlice.ts +0 -115
  110. package/src/store/slices/configSlice.ts +0 -46
  111. package/src/store/slices/focusSlice.ts +0 -64
  112. package/src/store/slices/index.ts +0 -9
  113. package/src/store/slices/sessionSlice.ts +0 -424
  114. package/src/store/streaming-buffer.ts +0 -425
  115. package/src/store/test.ts +0 -296
  116. package/src/store/types.ts +0 -274
  117. package/src/store/vanilla.ts +0 -186
  118. package/src/tools/builtin/bash.ts +0 -236
  119. package/src/tools/builtin/council.ts +0 -105
  120. package/src/tools/builtin/edit.ts +0 -213
  121. package/src/tools/builtin/glob.ts +0 -136
  122. package/src/tools/builtin/grep.ts +0 -263
  123. package/src/tools/builtin/index.ts +0 -61
  124. package/src/tools/builtin/memory.ts +0 -66
  125. package/src/tools/builtin/read.ts +0 -168
  126. package/src/tools/builtin/skill.ts +0 -97
  127. package/src/tools/builtin/snapshot.ts +0 -40
  128. package/src/tools/builtin/task.ts +0 -106
  129. package/src/tools/builtin/write.ts +0 -134
  130. package/src/tools/createTool.ts +0 -221
  131. package/src/tools/execution/ExecutionPipeline.ts +0 -263
  132. package/src/tools/execution/index.ts +0 -40
  133. package/src/tools/execution/stages/CacheStage.ts +0 -131
  134. package/src/tools/execution/stages/ConfirmationStage.ts +0 -203
  135. package/src/tools/execution/stages/DiscoveryStage.ts +0 -46
  136. package/src/tools/execution/stages/ExecutionStage.ts +0 -48
  137. package/src/tools/execution/stages/FormattingStage.ts +0 -44
  138. package/src/tools/execution/stages/HookStage.ts +0 -72
  139. package/src/tools/execution/stages/PermissionStage.ts +0 -287
  140. package/src/tools/execution/stages/PostHookStage.ts +0 -71
  141. package/src/tools/execution/stages/index.ts +0 -12
  142. package/src/tools/execution/test.ts +0 -266
  143. package/src/tools/execution/types.ts +0 -273
  144. package/src/tools/index.ts +0 -81
  145. package/src/tools/registry.ts +0 -304
  146. package/src/tools/schemas.ts +0 -109
  147. package/src/tools/test.ts +0 -220
  148. package/src/tools/types.ts +0 -175
  149. package/src/tools/validation/PermissionChecker.ts +0 -242
  150. package/src/tools/validation/SensitiveFileDetector.ts +0 -210
  151. package/src/tools/validation/index.ts +0 -11
  152. package/src/ui/App.tsx +0 -166
  153. package/src/ui/components/AegisInterface.tsx +0 -484
  154. package/src/ui/components/common/ChatSearch.tsx +0 -150
  155. package/src/ui/components/common/ErrorBoundary.tsx +0 -82
  156. package/src/ui/components/common/ExitMessage.tsx +0 -120
  157. package/src/ui/components/common/LoadingIndicator.tsx +0 -49
  158. package/src/ui/components/common/index.ts +0 -6
  159. package/src/ui/components/dialog/ConfirmationPrompt.tsx +0 -208
  160. package/src/ui/components/dialog/InteractiveSelector.tsx +0 -149
  161. package/src/ui/components/dialog/SetupWizard.tsx +0 -297
  162. package/src/ui/components/dialog/UpdatePrompt.tsx +0 -155
  163. package/src/ui/components/dialog/index.ts +0 -8
  164. package/src/ui/components/index.ts +0 -28
  165. package/src/ui/components/input/CommandSuggestions.tsx +0 -139
  166. package/src/ui/components/input/CustomTextInput.tsx +0 -220
  167. package/src/ui/components/input/InputArea.tsx +0 -361
  168. package/src/ui/components/input/PromptSuggestions.tsx +0 -66
  169. package/src/ui/components/input/index.ts +0 -6
  170. package/src/ui/components/layout/ChatStatusBar.tsx +0 -90
  171. package/src/ui/components/layout/ContextBar.tsx +0 -79
  172. package/src/ui/components/layout/MessageArea.tsx +0 -96
  173. package/src/ui/components/layout/MessageList.tsx +0 -647
  174. package/src/ui/components/layout/MessageSeparator.tsx +0 -26
  175. package/src/ui/components/layout/WelcomeMessage.tsx +0 -93
  176. package/src/ui/components/layout/index.ts +0 -7
  177. package/src/ui/components/markdown/CodeHighlighter.tsx +0 -292
  178. package/src/ui/components/markdown/MessageRenderer.tsx +0 -1211
  179. package/src/ui/components/markdown/index.ts +0 -8
  180. package/src/ui/components/markdown/parser.ts +0 -336
  181. package/src/ui/components/markdown/types.ts +0 -66
  182. package/src/ui/focus/FocusManager.ts +0 -137
  183. package/src/ui/focus/index.ts +0 -13
  184. package/src/ui/focus/types.ts +0 -54
  185. package/src/ui/focus/useFocus.ts +0 -75
  186. package/src/ui/hooks/index.ts +0 -11
  187. package/src/ui/hooks/useAgent.ts +0 -284
  188. package/src/ui/hooks/useCommandHistory.ts +0 -87
  189. package/src/ui/hooks/useCommandProcessor.ts +0 -443
  190. package/src/ui/hooks/useConfirmation.ts +0 -99
  191. package/src/ui/hooks/useCtrlCHandler.ts +0 -100
  192. package/src/ui/hooks/useInputBuffer.ts +0 -122
  193. package/src/ui/hooks/useTerminalSize.ts +0 -68
  194. package/src/ui/hooks/useTerminalWidth.ts +0 -5
  195. package/src/ui/hooks/useWindowedList.ts +0 -118
  196. package/src/ui/render-debugger.ts +0 -621
  197. package/src/ui/test.ts +0 -189
  198. package/src/ui/themes/ThemeManager.ts +0 -332
  199. package/src/ui/themes/aegisTheme.ts +0 -87
  200. package/src/ui/themes/darkTheme.ts +0 -87
  201. package/src/ui/themes/defaultTheme.ts +0 -85
  202. package/src/ui/themes/index.ts +0 -10
  203. package/src/ui/themes/lightTheme.ts +0 -89
  204. package/src/ui/themes/popularThemes.ts +0 -187
  205. package/src/ui/themes/types.ts +0 -130
  206. package/src/utils/clipboard.ts +0 -48
  207. package/src/utils/debug.ts +0 -43
  208. package/src/utils/environment.ts +0 -68
  209. 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
- }