aegiscode 3.1.8 → 3.1.10

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 (206) hide show
  1. package/README.md +23 -15
  2. package/dist/main.js +549 -552
  3. package/package.json +4 -2
  4. package/src/agent/Agent.ts +903 -0
  5. package/src/agent/SimpleAgent.ts +48 -0
  6. package/src/agent/index.ts +54 -0
  7. package/src/agent/orchestrator/AppBuilder.ts +443 -0
  8. package/src/agent/orchestrator/CouncilAgent.ts +310 -0
  9. package/src/agent/orchestrator/DiscussionRoom.ts +462 -0
  10. package/src/agent/orchestrator/OrchestratorAgent.ts +637 -0
  11. package/src/agent/orchestrator/index.ts +38 -0
  12. package/src/agent/orchestrator/utils.ts +397 -0
  13. package/src/agent/pricing.ts +115 -0
  14. package/src/agent/router.ts +74 -0
  15. package/src/agent/routerStats.ts +121 -0
  16. package/src/agent/types.ts +318 -0
  17. package/src/auth/login.ts +383 -0
  18. package/src/cli/config.ts +189 -0
  19. package/src/cli/index.ts +17 -0
  20. package/src/cli/middleware.ts +119 -0
  21. package/src/cli/types.ts +75 -0
  22. package/src/config/ConfigManager.ts +587 -0
  23. package/src/config/index.ts +7 -0
  24. package/src/config/types.ts +584 -0
  25. package/src/context/CompactionService.ts +300 -0
  26. package/src/context/ContextManager.ts +450 -0
  27. package/src/context/FileAnalyzer.ts +267 -0
  28. package/src/context/TokenCounter.ts +265 -0
  29. package/src/context/index.ts +27 -0
  30. package/src/context/storage/CacheStore.ts +176 -0
  31. package/src/context/storage/JSONLStore.ts +201 -0
  32. package/src/context/storage/MemoryStore.ts +205 -0
  33. package/src/context/storage/PersistentStore.ts +327 -0
  34. package/src/context/storage/index.ts +9 -0
  35. package/src/context/storage/pathUtils.ts +114 -0
  36. package/src/context/test.ts +309 -0
  37. package/src/context/types.ts +268 -0
  38. package/src/hooks/HookExecutor.ts +434 -0
  39. package/src/hooks/HookManager.ts +596 -0
  40. package/src/hooks/HookService.ts +269 -0
  41. package/src/hooks/Matcher.ts +157 -0
  42. package/src/hooks/index.ts +63 -0
  43. package/src/hooks/types.ts +424 -0
  44. package/src/main.tsx +596 -0
  45. package/src/mcp/HealthMonitor.ts +150 -0
  46. package/src/mcp/McpClient.ts +491 -0
  47. package/src/mcp/McpRegistry.ts +321 -0
  48. package/src/mcp/createMcpTool.ts +251 -0
  49. package/src/mcp/index.ts +15 -0
  50. package/src/mcp/server.ts +334 -0
  51. package/src/mcp/test-server.ts +88 -0
  52. package/src/mcp/test.ts +372 -0
  53. package/src/mcp/types.ts +247 -0
  54. package/src/memory/AgentMemoryBus.ts +432 -0
  55. package/src/memory/CloudSync.ts +99 -0
  56. package/src/memory/DriveSync.ts +106 -0
  57. package/src/memory/SharedMemory.ts +951 -0
  58. package/src/memory/index.ts +14 -0
  59. package/src/memory/machineFingerprint.ts +40 -0
  60. package/src/orchestrator/SubAgentMetadata.ts +136 -0
  61. package/src/prompts/builder.ts +213 -0
  62. package/src/prompts/default.ts +144 -0
  63. package/src/prompts/index.ts +16 -0
  64. package/src/prompts/plan.ts +64 -0
  65. package/src/prompts/test.ts +78 -0
  66. package/src/services/AnthropicChatService.ts +341 -0
  67. package/src/services/ChatService.ts +347 -0
  68. package/src/services/ClaudeCliChatService.ts +256 -0
  69. package/src/services/CloudSync.ts +168 -0
  70. package/src/services/CostLedger.ts +211 -0
  71. package/src/services/Heartbeat.ts +135 -0
  72. package/src/services/LearningCollector.ts +291 -0
  73. package/src/services/OllamaInstaller.ts +342 -0
  74. package/src/services/VersionChecker.ts +445 -0
  75. package/src/services/index.ts +57 -0
  76. package/src/services/streaming/OpenAIEventAdapter.ts +126 -0
  77. package/src/services/streaming/RenderingProfile.ts +90 -0
  78. package/src/services/streaming/StreamEventParser.ts +181 -0
  79. package/src/services/streaming/ThrottledRenderer.ts +139 -0
  80. package/src/services/streaming/TranscriptBuffer.ts +574 -0
  81. package/src/services/streaming/eventStatusMap.ts +52 -0
  82. package/src/services/streaming/index.ts +46 -0
  83. package/src/services/streaming/renderFormatting.ts +79 -0
  84. package/src/services/streaming/types.ts +234 -0
  85. package/src/skills/SkillLoader.ts +126 -0
  86. package/src/skills/SkillRegistry.ts +366 -0
  87. package/src/skills/index.ts +48 -0
  88. package/src/skills/types.ts +146 -0
  89. package/src/slash-commands/billing.ts +70 -0
  90. package/src/slash-commands/build.ts +413 -0
  91. package/src/slash-commands/builtinCommands.ts +2733 -0
  92. package/src/slash-commands/clone.ts +242 -0
  93. package/src/slash-commands/council.ts +125 -0
  94. package/src/slash-commands/custom/CustomCommandExecutor.ts +143 -0
  95. package/src/slash-commands/custom/CustomCommandLoader.ts +251 -0
  96. package/src/slash-commands/custom/CustomCommandRegistry.ts +144 -0
  97. package/src/slash-commands/custom/index.ts +7 -0
  98. package/src/slash-commands/debate.ts +254 -0
  99. package/src/slash-commands/gmail.ts +105 -0
  100. package/src/slash-commands/index.ts +388 -0
  101. package/src/slash-commands/mcpCommand.ts +205 -0
  102. package/src/slash-commands/types.ts +201 -0
  103. package/src/store/index.ts +76 -0
  104. package/src/store/selectors.ts +246 -0
  105. package/src/store/slices/appSlice.ts +205 -0
  106. package/src/store/slices/commandSlice.ts +115 -0
  107. package/src/store/slices/configSlice.ts +46 -0
  108. package/src/store/slices/focusSlice.ts +64 -0
  109. package/src/store/slices/index.ts +9 -0
  110. package/src/store/slices/sessionSlice.ts +424 -0
  111. package/src/store/streaming-buffer.ts +425 -0
  112. package/src/store/test.ts +296 -0
  113. package/src/store/types.ts +274 -0
  114. package/src/store/vanilla.ts +186 -0
  115. package/src/tools/builtin/bash.ts +236 -0
  116. package/src/tools/builtin/council.ts +105 -0
  117. package/src/tools/builtin/edit.ts +213 -0
  118. package/src/tools/builtin/glob.ts +136 -0
  119. package/src/tools/builtin/grep.ts +263 -0
  120. package/src/tools/builtin/index.ts +61 -0
  121. package/src/tools/builtin/memory.ts +66 -0
  122. package/src/tools/builtin/read.ts +168 -0
  123. package/src/tools/builtin/skill.ts +97 -0
  124. package/src/tools/builtin/snapshot.ts +40 -0
  125. package/src/tools/builtin/task.ts +106 -0
  126. package/src/tools/builtin/write.ts +134 -0
  127. package/src/tools/createTool.ts +221 -0
  128. package/src/tools/execution/ExecutionPipeline.ts +263 -0
  129. package/src/tools/execution/index.ts +40 -0
  130. package/src/tools/execution/stages/CacheStage.ts +131 -0
  131. package/src/tools/execution/stages/ConfirmationStage.ts +203 -0
  132. package/src/tools/execution/stages/DiscoveryStage.ts +46 -0
  133. package/src/tools/execution/stages/ExecutionStage.ts +48 -0
  134. package/src/tools/execution/stages/FormattingStage.ts +44 -0
  135. package/src/tools/execution/stages/HookStage.ts +72 -0
  136. package/src/tools/execution/stages/PermissionStage.ts +287 -0
  137. package/src/tools/execution/stages/PostHookStage.ts +71 -0
  138. package/src/tools/execution/stages/index.ts +12 -0
  139. package/src/tools/execution/test.ts +266 -0
  140. package/src/tools/execution/types.ts +273 -0
  141. package/src/tools/index.ts +81 -0
  142. package/src/tools/registry.ts +304 -0
  143. package/src/tools/schemas.ts +109 -0
  144. package/src/tools/test.ts +220 -0
  145. package/src/tools/types.ts +175 -0
  146. package/src/tools/validation/PermissionChecker.ts +242 -0
  147. package/src/tools/validation/SensitiveFileDetector.ts +210 -0
  148. package/src/tools/validation/index.ts +11 -0
  149. package/src/ui/App.tsx +166 -0
  150. package/src/ui/components/AegisInterface.tsx +484 -0
  151. package/src/ui/components/common/ChatSearch.tsx +150 -0
  152. package/src/ui/components/common/ErrorBoundary.tsx +82 -0
  153. package/src/ui/components/common/ExitMessage.tsx +120 -0
  154. package/src/ui/components/common/LoadingIndicator.tsx +49 -0
  155. package/src/ui/components/common/index.ts +6 -0
  156. package/src/ui/components/dialog/ConfirmationPrompt.tsx +208 -0
  157. package/src/ui/components/dialog/InteractiveSelector.tsx +149 -0
  158. package/src/ui/components/dialog/SetupWizard.tsx +297 -0
  159. package/src/ui/components/dialog/UpdatePrompt.tsx +155 -0
  160. package/src/ui/components/dialog/index.ts +8 -0
  161. package/src/ui/components/index.ts +28 -0
  162. package/src/ui/components/input/CommandSuggestions.tsx +139 -0
  163. package/src/ui/components/input/CustomTextInput.tsx +220 -0
  164. package/src/ui/components/input/InputArea.tsx +361 -0
  165. package/src/ui/components/input/PromptSuggestions.tsx +66 -0
  166. package/src/ui/components/input/index.ts +6 -0
  167. package/src/ui/components/layout/ChatStatusBar.tsx +90 -0
  168. package/src/ui/components/layout/ContextBar.tsx +79 -0
  169. package/src/ui/components/layout/MessageArea.tsx +96 -0
  170. package/src/ui/components/layout/MessageList.tsx +647 -0
  171. package/src/ui/components/layout/MessageSeparator.tsx +26 -0
  172. package/src/ui/components/layout/WelcomeMessage.tsx +93 -0
  173. package/src/ui/components/layout/index.ts +7 -0
  174. package/src/ui/components/markdown/CodeHighlighter.tsx +292 -0
  175. package/src/ui/components/markdown/MessageRenderer.tsx +1211 -0
  176. package/src/ui/components/markdown/index.ts +8 -0
  177. package/src/ui/components/markdown/parser.ts +336 -0
  178. package/src/ui/components/markdown/types.ts +66 -0
  179. package/src/ui/focus/FocusManager.ts +137 -0
  180. package/src/ui/focus/index.ts +13 -0
  181. package/src/ui/focus/types.ts +54 -0
  182. package/src/ui/focus/useFocus.ts +75 -0
  183. package/src/ui/hooks/index.ts +11 -0
  184. package/src/ui/hooks/useAgent.ts +284 -0
  185. package/src/ui/hooks/useCommandHistory.ts +87 -0
  186. package/src/ui/hooks/useCommandProcessor.ts +443 -0
  187. package/src/ui/hooks/useConfirmation.ts +99 -0
  188. package/src/ui/hooks/useCtrlCHandler.ts +100 -0
  189. package/src/ui/hooks/useInputBuffer.ts +122 -0
  190. package/src/ui/hooks/useTerminalSize.ts +68 -0
  191. package/src/ui/hooks/useTerminalWidth.ts +5 -0
  192. package/src/ui/hooks/useWindowedList.ts +118 -0
  193. package/src/ui/render-debugger.ts +621 -0
  194. package/src/ui/test.ts +189 -0
  195. package/src/ui/themes/ThemeManager.ts +332 -0
  196. package/src/ui/themes/aegisTheme.ts +87 -0
  197. package/src/ui/themes/darkTheme.ts +87 -0
  198. package/src/ui/themes/defaultTheme.ts +85 -0
  199. package/src/ui/themes/index.ts +10 -0
  200. package/src/ui/themes/lightTheme.ts +89 -0
  201. package/src/ui/themes/popularThemes.ts +187 -0
  202. package/src/ui/themes/types.ts +130 -0
  203. package/src/utils/clipboard.ts +48 -0
  204. package/src/utils/debug.ts +43 -0
  205. package/src/utils/environment.ts +68 -0
  206. package/src/utils/index.ts +10 -0
@@ -0,0 +1,273 @@
1
+ /**
2
+ *
3
+ */
4
+
5
+ import type { Tool, ToolResult, ToolInvocation } from '../types.js';
6
+
7
+ // ========== 权限模
8
+
9
+ /**
10
+ *
11
+ */
12
+ export enum PermissionMode {
13
+ /** 默认模式:写操作需确认 */
14
+ DEFAULT = 'default',
15
+ /** 自动批准编辑 */
16
+ AUTO_EDIT = 'autoEdit',
17
+ /** 自动批准所有 */
18
+ YOLO = 'yolo',
19
+ /** 只读调研模式 */
20
+ PLAN = 'plan',
21
+ }
22
+
23
+ // ========== 权限检
24
+
25
+ /**
26
+ *
27
+ */
28
+ export enum PermissionResult {
29
+ ALLOW = 'allow',
30
+ ASK = 'ask',
31
+ DENY = 'deny',
32
+ }
33
+
34
+ /**
35
+ *
36
+ */
37
+ export interface PermissionCheckResult {
38
+ result: PermissionResult;
39
+ matchedRule?: string;
40
+ reason?: string;
41
+ }
42
+
43
+ /**
44
+ *
45
+ */
46
+ export interface PermissionConfig {
47
+ allow: string[];
48
+ deny: string[];
49
+ ask: string[];
50
+ }
51
+
52
+ /**
53
+ *
54
+ */
55
+ export interface ToolInvocationDescriptor {
56
+ toolName: string;
57
+ params: Record<string, unknown>;
58
+ affectedPaths?: string[];
59
+ tool?: Tool;
60
+ }
61
+
62
+ // ========== 确认机
63
+
64
+ /**
65
+ *
66
+ */
67
+ export interface ConfirmationDetails {
68
+ title: string;
69
+ message: string;
70
+ details?: string;
71
+ risks?: string[];
72
+ affectedFiles?: string[];
73
+ }
74
+
75
+ /**
76
+ *
77
+ */
78
+ export interface ConfirmationResponse {
79
+ approved: boolean;
80
+ reason?: string;
81
+ scope?: 'once' | 'session';
82
+ }
83
+
84
+ /**
85
+ *
86
+ */
87
+ export interface ConfirmationHandler {
88
+ requestConfirmation(details: ConfirmationDetails): Promise<ConfirmationResponse>;
89
+ }
90
+
91
+ // ========== 执行上下
92
+
93
+ /**
94
+ *
95
+ */
96
+ export interface PipelineExecutionContext {
97
+ sessionId: string;
98
+ workspaceRoot: string;
99
+ permissionMode: PermissionMode;
100
+ signal?: AbortSignal;
101
+ onProgress?: (progress: ToolProgress) => void;
102
+ confirmationHandler?: ConfirmationHandler;
103
+ messageId?: string;
104
+ /** Per-model setting: false skips confirmation prompts entirely. Defaults to true. */
105
+ requireConfirmation?: boolean;
106
+ }
107
+
108
+ /**
109
+ *
110
+ */
111
+ export interface ToolProgress {
112
+ stage: string;
113
+ message: string;
114
+ percent?: number;
115
+ }
116
+
117
+ // ========== 工具执
118
+
119
+ /**
120
+ *
121
+ */
122
+ export interface ToolExecutionInternal {
123
+ tool?: Tool;
124
+ invocation?: ToolInvocation;
125
+ needsConfirmation?: boolean;
126
+ confirmationReason?: string;
127
+ permissionSignature?: string;
128
+ hookToolUseId?: string;
129
+ /**
130
+ * Set when the command pilots another terminal session (tmux send-keys,
131
+ * screen -X stuff, etc.) — a vector for a model to mutate shared state
132
+ * (config.json, files) by typing into a second instance's stdin as if it
133
+ * were a real user, bypassing both per-model requireConfirmation and any
134
+ * session "always allow" approval. When true, ConfirmationStage must show
135
+ * the prompt regardless of either.
136
+ */
137
+ forceConfirmation?: boolean;
138
+
139
+ /** Cache key set by CacheStage — ExecutionStage uses it to store results */
140
+ cacheKey?: string;
141
+ }
142
+
143
+ /**
144
+ *
145
+ */
146
+ export class ToolExecution {
147
+ private result?: ToolResult;
148
+ private aborted = false;
149
+ private abortReason?: string;
150
+
151
+ readonly _internal: ToolExecutionInternal = {};
152
+
153
+ constructor(
154
+ public readonly toolName: string,
155
+ public params: Record<string, unknown>,
156
+ public readonly context: PipelineExecutionContext
157
+ ) {}
158
+
159
+ /**
160
+ *
161
+ */
162
+ abort(reason: string): void {
163
+ this.aborted = true;
164
+ this.abortReason = reason;
165
+ }
166
+
167
+ /**
168
+ *
169
+ */
170
+ isAborted(): boolean {
171
+ return this.aborted;
172
+ }
173
+
174
+ /**
175
+ *
176
+ */
177
+ getAbortReason(): string | undefined {
178
+ return this.abortReason;
179
+ }
180
+
181
+ /**
182
+ *
183
+ */
184
+ setResult(result: ToolResult): void {
185
+ this.result = result;
186
+ }
187
+
188
+ /**
189
+ *
190
+ */
191
+ getResult(): ToolResult | undefined {
192
+ return this.result;
193
+ }
194
+ }
195
+
196
+ // ========== 管道阶
197
+
198
+ /**
199
+ *
200
+ */
201
+ export interface PipelineStage {
202
+ readonly name: string;
203
+ process(execution: ToolExecution): Promise<void>;
204
+ }
205
+
206
+ // ========== 管道配
207
+
208
+ /**
209
+ *
210
+ */
211
+ export interface ExecutionPipelineConfig {
212
+ permissions?: PermissionConfig;
213
+ defaultMode?: PermissionMode;
214
+ /** Per-model allowed tools — overrides global whitelist for the current model */
215
+ allowedTools?: string[];
216
+ /** Per-model disallowed tools — overrides global blacklist for the current model */
217
+ disallowedTools?: string[];
218
+ }
219
+
220
+ // ========== 执行历
221
+
222
+ /**
223
+ *
224
+ */
225
+ export interface ExecutionHistoryEntry {
226
+ toolName: string;
227
+ params: Record<string, unknown>;
228
+ result: ToolResult;
229
+ timestamp: number;
230
+ duration: number;
231
+ permissionMode: PermissionMode;
232
+ stages: string[];
233
+ }
234
+
235
+ // ========== Hook 相
236
+
237
+ /**
238
+ * Pre-Tool Hook 结果
239
+ */
240
+ export interface PreToolHookResult {
241
+ decision: 'allow' | 'ask' | 'deny';
242
+ modifiedInput?: Record<string, unknown>;
243
+ reason?: string;
244
+ warning?: string;
245
+ }
246
+
247
+ /**
248
+ * Post-Tool Hook 参数
249
+ */
250
+ export interface PostToolHookParams {
251
+ toolName: string;
252
+ params: Record<string, unknown>;
253
+ result?: ToolResult;
254
+ context: PipelineExecutionContext;
255
+ }
256
+
257
+ // ========== 管道事
258
+
259
+ /**
260
+ *
261
+ */
262
+ export interface StageStartEvent {
263
+ stage: string;
264
+ execution: ToolExecution;
265
+ }
266
+
267
+ /**
268
+ *
269
+ */
270
+ export interface StageCompleteEvent {
271
+ stage: string;
272
+ execution: ToolExecution;
273
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ *
3
+ */
4
+
5
+ // 类
6
+ export {
7
+ ToolKind,
8
+ ToolErrorType,
9
+ } from './types.js';
10
+
11
+ export type {
12
+ Tool,
13
+ ToolResult,
14
+ ToolError,
15
+ ToolDescription,
16
+ ToolExample,
17
+ ExecutionContext,
18
+ FunctionDeclaration,
19
+ ToolInvocation,
20
+ } from './types.js';
21
+
22
+ // 工厂函
23
+ export { createTool } from './createTool.js';
24
+ export type { ToolConfig } from './createTool.js';
25
+
26
+ // Schema
27
+ export { ToolSchemas, optional } from './schemas.js';
28
+
29
+ // 注册
30
+ export { ToolRegistry, createToolRegistry } from './registry.js';
31
+
32
+ // 注册表事
33
+ export type { ToolRegisteredEvent } from './registry.js';
34
+
35
+ // 内置工
36
+ export {
37
+ readTool,
38
+ editTool,
39
+ writeTool,
40
+ grepTool,
41
+ bashTool,
42
+ getBuiltinTools,
43
+ } from './builtin/index.js';
44
+
45
+ // 执行管
46
+ export {
47
+ ExecutionPipeline,
48
+ PermissionMode,
49
+ PermissionResult,
50
+ ToolExecution,
51
+ } from './execution/index.js';
52
+
53
+ export type {
54
+ ExecutionPipelineEvents,
55
+ PipelineStage,
56
+ PipelineExecutionContext,
57
+ ExecutionPipelineConfig,
58
+ ExecutionHistoryEntry,
59
+ PermissionCheckResult,
60
+ PermissionConfig,
61
+ ToolInvocationDescriptor,
62
+ ConfirmationDetails,
63
+ ConfirmationResponse,
64
+ ConfirmationHandler,
65
+ ToolProgress,
66
+ PreToolHookResult,
67
+ PostToolHookParams,
68
+ } from './execution/index.js';
69
+
70
+ // 验
71
+ export {
72
+ PermissionChecker,
73
+ DEFAULT_PERMISSION_CONFIG,
74
+ SensitiveFileDetector,
75
+ SensitivityLevel,
76
+ } from './validation/index.js';
77
+
78
+ export type {
79
+ SensitivityResult,
80
+ SensitivityResultWithPath,
81
+ } from './validation/index.js';
@@ -0,0 +1,304 @@
1
+ /**
2
+ *
3
+ *
4
+ *
5
+ */
6
+
7
+ import { EventEmitter } from 'events';
8
+ import type { Tool, FunctionDeclaration } from './types.js';
9
+
10
+ /**
11
+ *
12
+ */
13
+ export interface ToolRegisteredEvent {
14
+ type: 'builtin' | 'mcp';
15
+ tool: Tool;
16
+ }
17
+
18
+ /**
19
+ *
20
+ */
21
+ export class ToolRegistry extends EventEmitter {
22
+ /** 内置工具 */
23
+ private tools = new Map<string, Tool>();
24
+
25
+ /** MCP 工具 */
26
+ private mcpTools = new Map<string, Tool>();
27
+
28
+ /** 分类索引 */
29
+ private categories = new Map<string, Set<string>>();
30
+
31
+ /** 标签索引 */
32
+ private tagIndex = new Map<string, Set<string>>();
33
+
34
+ /**
35
+ *
36
+ */
37
+ register(tool: Tool): void {
38
+ if (this.tools.has(tool.name) || this.mcpTools.has(tool.name)) {
39
+ throw new Error(`工具 '${tool.name}' 已注册`);
40
+ }
41
+
42
+ this.tools.set(tool.name, tool);
43
+ this.updateIndexes(tool);
44
+ this.emit('toolRegistered', { type: 'builtin', tool } as ToolRegisteredEvent);
45
+ }
46
+
47
+ /**
48
+ *
49
+ */
50
+ registerMcpTool(tool: Tool): void {
51
+ if (this.tools.has(tool.name) || this.mcpTools.has(tool.name)) {
52
+ throw new Error(`工具 '${tool.name}' 已注册`);
53
+ }
54
+
55
+ this.mcpTools.set(tool.name, tool);
56
+ this.updateIndexes(tool);
57
+ this.emit('toolRegistered', { type: 'mcp', tool } as ToolRegisteredEvent);
58
+ }
59
+
60
+ /**
61
+ *
62
+ */
63
+ registerMcpTools(tools: Tool[]): void {
64
+ for (const tool of tools) {
65
+ this.registerMcpTool(tool);
66
+ }
67
+ }
68
+
69
+ /**
70
+ *
71
+ */
72
+ unregisterMcpTool(name: string): boolean {
73
+ const tool = this.mcpTools.get(name);
74
+ if (!tool) return false;
75
+
76
+ this.mcpTools.delete(name);
77
+ this.removeFromIndexes(tool);
78
+ this.emit('toolUnregistered', { type: 'mcp', tool });
79
+ return true;
80
+ }
81
+
82
+ /**
83
+ *
84
+ */
85
+ clearMcpTools(): void {
86
+ for (const tool of this.mcpTools.values()) {
87
+ this.removeFromIndexes(tool);
88
+ }
89
+ this.mcpTools.clear();
90
+ }
91
+
92
+ /**
93
+ *
94
+ */
95
+ registerAll(tools: Tool[]): void {
96
+ for (const tool of tools) {
97
+ this.register(tool);
98
+ }
99
+ }
100
+
101
+ /**
102
+ *
103
+ */
104
+ get(name: string): Tool | undefined {
105
+ return this.tools.get(name) || this.mcpTools.get(name);
106
+ }
107
+
108
+ /**
109
+ *
110
+ */
111
+ has(name: string): boolean {
112
+ return this.tools.has(name) || this.mcpTools.has(name);
113
+ }
114
+
115
+ /**
116
+ *
117
+ */
118
+ getAll(): Tool[] {
119
+ return [...this.tools.values(), ...this.mcpTools.values()];
120
+ }
121
+
122
+ /**
123
+ *
124
+ */
125
+ getBuiltinTools(): Tool[] {
126
+ return [...this.tools.values()];
127
+ }
128
+
129
+ /**
130
+ *
131
+ */
132
+ getMcpTools(): Tool[] {
133
+ return [...this.mcpTools.values()];
134
+ }
135
+
136
+ /**
137
+ *
138
+ */
139
+ getNames(): string[] {
140
+ return [...this.tools.keys(), ...this.mcpTools.keys()];
141
+ }
142
+
143
+ /**
144
+ *
145
+ */
146
+ getReadOnlyTools(): Tool[] {
147
+ return this.getAll().filter(tool => tool.isReadOnly);
148
+ }
149
+
150
+ /**
151
+ *
152
+ */
153
+ getWriteTools(): Tool[] {
154
+ return this.getAll().filter(tool => !tool.isReadOnly);
155
+ }
156
+
157
+ /**
158
+ *
159
+ */
160
+ getByCategory(category: string): Tool[] {
161
+ const names = this.categories.get(category);
162
+ if (!names) return [];
163
+ return [...names].map(name => this.tools.get(name)!).filter(Boolean);
164
+ }
165
+
166
+ /**
167
+ *
168
+ */
169
+ getByTag(tag: string): Tool[] {
170
+ const names = this.tagIndex.get(tag);
171
+ if (!names) return [];
172
+ return [...names].map(name => this.tools.get(name)!).filter(Boolean);
173
+ }
174
+
175
+ /**
176
+ *
177
+ */
178
+ getCategories(): string[] {
179
+ return [...this.categories.keys()];
180
+ }
181
+
182
+ /**
183
+ *
184
+ */
185
+ getTags(): string[] {
186
+ return [...this.tagIndex.keys()];
187
+ }
188
+
189
+ /**
190
+ *
191
+ */
192
+ getFunctionDeclarations(): FunctionDeclaration[] {
193
+ return this.getAll().map(tool => tool.getFunctionDeclaration());
194
+ }
195
+
196
+ /**
197
+ *
198
+ */
199
+ getFunctionDeclarationsByMode(mode?: string): FunctionDeclaration[] {
200
+ if (mode === 'plan') {
201
+ // Plan 模式只返回只读工
202
+ return this.getReadOnlyTools().map(t => t.getFunctionDeclaration());
203
+ }
204
+ return this.getFunctionDeclarations();
205
+ }
206
+
207
+ /**
208
+ *
209
+ */
210
+ search(query: string): Tool[] {
211
+ const lowerQuery = query.toLowerCase();
212
+ return this.getAll().filter(tool =>
213
+ tool.name.toLowerCase().includes(lowerQuery) ||
214
+ tool.displayName.toLowerCase().includes(lowerQuery) ||
215
+ tool.description.short.toLowerCase().includes(lowerQuery)
216
+ );
217
+ }
218
+
219
+ /**
220
+ *
221
+ */
222
+ get size(): number {
223
+ return this.tools.size + this.mcpTools.size;
224
+ }
225
+
226
+ /**
227
+ *
228
+ */
229
+ get builtinSize(): number {
230
+ return this.tools.size;
231
+ }
232
+
233
+ /**
234
+ *
235
+ */
236
+ get mcpSize(): number {
237
+ return this.mcpTools.size;
238
+ }
239
+
240
+ /**
241
+ *
242
+ */
243
+ clear(): void {
244
+ this.tools.clear();
245
+ this.mcpTools.clear();
246
+ this.categories.clear();
247
+ this.tagIndex.clear();
248
+ }
249
+
250
+ /**
251
+ *
252
+ */
253
+ private updateIndexes(tool: Tool): void {
254
+ // 更新分类索
255
+ if (tool.category) {
256
+ if (!this.categories.has(tool.category)) {
257
+ this.categories.set(tool.category, new Set());
258
+ }
259
+ this.categories.get(tool.category)!.add(tool.name);
260
+ }
261
+
262
+ // 更新标签索
263
+ for (const tag of tool.tags) {
264
+ if (!this.tagIndex.has(tag)) {
265
+ this.tagIndex.set(tag, new Set());
266
+ }
267
+ this.tagIndex.get(tag)!.add(tool.name);
268
+ }
269
+ }
270
+
271
+ /**
272
+ *
273
+ */
274
+ private removeFromIndexes(tool: Tool): void {
275
+ // 从分类索引中移
276
+ if (tool.category) {
277
+ const categorySet = this.categories.get(tool.category);
278
+ if (categorySet) {
279
+ categorySet.delete(tool.name);
280
+ if (categorySet.size === 0) {
281
+ this.categories.delete(tool.category);
282
+ }
283
+ }
284
+ }
285
+
286
+ // 从标签索引中移
287
+ for (const tag of tool.tags) {
288
+ const tagSet = this.tagIndex.get(tag);
289
+ if (tagSet) {
290
+ tagSet.delete(tool.name);
291
+ if (tagSet.size === 0) {
292
+ this.tagIndex.delete(tag);
293
+ }
294
+ }
295
+ }
296
+ }
297
+ }
298
+
299
+ /**
300
+ *
301
+ */
302
+ export function createToolRegistry(): ToolRegistry {
303
+ return new ToolRegistry();
304
+ }