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,186 +0,0 @@
1
- /**
2
- * Zustand Vanilla Store
3
- *
4
- *
5
- */
6
-
7
- import { createStore } from 'zustand/vanilla';
8
- import { devtools, subscribeWithSelector } from 'zustand/middleware';
9
-
10
- import type { ClawdStore } from './types.js';
11
- import type { RuntimeConfig } from '../config/types.js';
12
- import {
13
- createSessionSlice,
14
- createConfigSlice,
15
- createAppSlice,
16
- createFocusSlice,
17
- createCommandSlice,
18
- } from './slices/index.js';
19
-
20
- /**
21
- *
22
- *
23
- *
24
- * - devtools: 开发工具支持
25
- * - subscribeWithSelector: 支持选择器订阅
26
- */
27
- export const vanillaStore = createStore<ClawdStore>()(
28
- devtools(
29
- subscribeWithSelector((...a) => ({
30
- session: createSessionSlice(...a),
31
- config: createConfigSlice(...a),
32
- app: createAppSlice(...a),
33
- focus: createFocusSlice(...a),
34
- command: createCommandSlice(...a),
35
- })),
36
- {
37
- name: 'ClawdStore',
38
- enabled: process.env.NODE_ENV === 'development',
39
- }
40
- )
41
- );
42
-
43
- // ========== 便捷访问
44
-
45
- /**
46
- *
47
- */
48
- export const getState = () => vanillaStore.getState();
49
-
50
- /**
51
- *
52
- */
53
- export const subscribe = vanillaStore.subscribe;
54
-
55
- // ========== Actions 快捷访
56
-
57
- export const sessionActions = () => getState().session.actions;
58
- export const configActions = () => getState().config.actions;
59
- export const appActions = () => getState().app.actions;
60
- export const focusActions = () => getState().focus.actions;
61
- export const commandActions = () => getState().command.actions;
62
-
63
- // ========== 配置便捷访
64
-
65
- /**
66
- *
67
- */
68
- export const getConfig = (): RuntimeConfig | null => getState().config.config;
69
-
70
- /**
71
- *
72
- */
73
- export const getCurrentModel = () => {
74
- const config = getConfig();
75
- if (!config) return undefined;
76
-
77
- // 优先使用 currentModelId
78
- if (config.currentModelId && config.models) {
79
- const model = config.models.find((m) => m.id === config.currentModelId);
80
- if (model) return model;
81
- }
82
-
83
- // 回退:按 model 字段匹配(兼容 currentModelId 被设为 model name 的情况)
84
- if (config.currentModelId && config.models) {
85
- const model = config.models.find((m) => m.model === config.currentModelId);
86
- if (model) return model;
87
- }
88
-
89
- // 回退
90
- if (config.models && config.models.length > 0) {
91
- return config.models[0];
92
- }
93
-
94
- // 回退到 default
95
- return config.default;
96
- };
97
-
98
- /**
99
- *
100
- */
101
- export const getPermissionMode = () => {
102
- const config = getConfig();
103
- return config?.defaultPermissionMode || 'default';
104
- };
105
-
106
- // ========== 初始化机
107
-
108
- let initializationPromise: Promise<void> | null = null;
109
-
110
- /**
111
- *
112
- *
113
- *
114
- * - 幂等:已初始化直接返回
115
- * - 并发安全:共享 Promise
116
- * - 失败重试:下次调用重新尝试
117
- */
118
- export async function ensureStoreInitialized(): Promise<void> {
119
- // 1. 快速路径:已初始
120
- const config = getConfig();
121
- if (config !== null) {
122
- return;
123
- }
124
-
125
- // 2. 并发保护:等待共
126
- if (initializationPromise) {
127
- return initializationPromise;
128
- }
129
-
130
- // 3. 开始初始
131
- initializationPromise = (async () => {
132
- try {
133
- // 动态导入避免循环依
134
- const { ConfigManager } = await import('../config/ConfigManager.js');
135
- const configManager = ConfigManager.getInstance();
136
- const loadedConfig = await configManager.initialize();
137
- getState().config.actions.setConfig(loadedConfig as RuntimeConfig);
138
- } catch (error) {
139
- initializationPromise = null; // 允许重
140
- throw new Error(
141
- `❌ Store 初始化失败\n\n` +
142
- `原因: ${error instanceof Error ? error.message : '未知错误'}`
143
- );
144
- } finally {
145
- initializationPromise = null;
146
- }
147
- })();
148
-
149
- return initializationPromise;
150
- }
151
-
152
- // ========== 订阅工
153
-
154
- /**
155
- *
156
- */
157
- export function subscribeToState<T>(
158
- selector: (state: ClawdStore) => T,
159
- callback: (value: T, prevValue: T) => void
160
- ): () => void {
161
- return vanillaStore.subscribe((state, prevState) => {
162
- const value = selector(state);
163
- const prevValue = selector(prevState);
164
- if (value !== prevValue) {
165
- callback(value, prevValue);
166
- }
167
- });
168
- }
169
-
170
- /**
171
- *
172
- */
173
- export function subscribeToTodos(
174
- callback: (todos: ClawdStore['app']['todos']) => void
175
- ): () => void {
176
- return subscribeToState((state) => state.app.todos, callback);
177
- }
178
-
179
- /**
180
- *
181
- */
182
- export function subscribeToMessages(
183
- callback: (messages: ClawdStore['session']['messages']) => void
184
- ): () => void {
185
- return subscribeToState((state) => state.session.messages, callback);
186
- }
@@ -1,236 +0,0 @@
1
- /**
2
- * Bash 工具
3
- *
4
- *
5
- */
6
-
7
- import { exec, spawn } from 'child_process';
8
- import { promisify } from 'util';
9
- import { createWriteStream, mkdirSync } from 'fs';
10
- import path from 'path';
11
- import os from 'os';
12
- import { z } from 'zod';
13
- import { createTool } from '../createTool.js';
14
- import { ToolKind, ToolErrorType } from '../types.js';
15
-
16
- const BG_JOBS_DIR = path.join(os.homedir(), '.aegiscode', 'bg');
17
-
18
- const execAsync = promisify(exec);
19
-
20
- // ========== Schema 定
21
-
22
- const BashSchema = z.object({
23
- command: z.string()
24
- .min(1, '命令不能为空')
25
- .describe('The shell command to execute'),
26
- description: z.string()
27
- .optional()
28
- .describe('A brief description of what the command does (for logging)'),
29
- timeout: z.number()
30
- .max(600000)
31
- .default(120000)
32
- .describe('Timeout in milliseconds (max 10 minutes, default 2 minutes)'),
33
- working_directory: z.string()
34
- .optional()
35
- .describe('The working directory to execute the command in'),
36
- run_in_background: z.boolean()
37
- .default(false)
38
- .describe('Whether to run the command in the background'),
39
- });
40
-
41
- // ========== Bash 工
42
-
43
- export const bashTool = createTool({
44
- name: 'Bash',
45
- displayName: 'Shell Command',
46
- kind: ToolKind.Execute,
47
- schema: BashSchema,
48
-
49
- // Bash 不是并发安全的(可能修改共享状
50
- isConcurrencySafe: false,
51
-
52
- description: {
53
- short: 'Executes bash commands in a shell session',
54
- long: 'Executes shell commands and returns the output. Use this for system operations, git commands, package management, etc.',
55
- usageNotes: [
56
- 'Avoid using for file operations - use dedicated tools (Read, Write, Edit) instead',
57
- 'Do not use cat/head/tail to read files - use the Read tool',
58
- 'Do not use sed/awk to edit files - use the Edit tool',
59
- 'Use && to chain dependent commands',
60
- 'Use run_in_background for long-running dev servers',
61
- 'Always quote file paths that contain spaces',
62
- ],
63
- examples: [
64
- {
65
- description: 'Run npm install',
66
- params: {
67
- command: 'npm install',
68
- description: 'Install npm dependencies',
69
- },
70
- },
71
- {
72
- description: 'Check git status',
73
- params: {
74
- command: 'git status',
75
- },
76
- },
77
- {
78
- description: 'Run a build command with timeout',
79
- params: {
80
- command: 'npm run build',
81
- timeout: 300000,
82
- description: 'Build the project',
83
- },
84
- },
85
- ],
86
- important: [
87
- 'NEVER use git commands with -i flag (interactive mode)',
88
- 'NEVER run destructive commands like rm -rf / without explicit user request',
89
- 'NEVER use echo or printf to communicate - output text directly instead',
90
- 'Avoid long-running processes that block (like npm run dev) unless using run_in_background',
91
- ],
92
- },
93
-
94
- category: 'Shell',
95
- tags: ['shell', 'bash', 'command', 'execute'],
96
-
97
- // 提取签名内容(用于权限规
98
- extractSignatureContent: (params: unknown) => {
99
- const p = params as { command: string };
100
- return p.command;
101
- },
102
-
103
- async execute(params, context) {
104
- const { command, description, timeout, working_directory, run_in_background } = params;
105
-
106
- // 危险命令检
107
- const dangerousPatterns = [
108
- /rm\s+-rf\s+\/(?!\w)/, // rm -rf / (但允许 rm -rf /path/to/dir)
109
- />\s*\/dev\/sd[a-z]/, // 写入磁盘设
110
- /mkfs\./, // 格式化文件系
111
- /dd\s+if=.*of=\/dev/, // dd 写入设
112
- ];
113
-
114
- for (const pattern of dangerousPatterns) {
115
- if (pattern.test(command)) {
116
- return {
117
- success: false,
118
- llmContent: `Error: Potentially dangerous command detected: ${command}`,
119
- displayContent: `blocked: dangerous command`,
120
- error: {
121
- type: ToolErrorType.PERMISSION_ERROR,
122
- message: 'Dangerous command blocked',
123
- },
124
- };
125
- }
126
- }
127
-
128
- try {
129
- if (run_in_background) {
130
- const jobId = `bg-${Date.now()}`;
131
- const logPath = path.join(BG_JOBS_DIR, `${jobId}.log`);
132
- mkdirSync(BG_JOBS_DIR, { recursive: true });
133
-
134
- const logStream = createWriteStream(logPath, { flags: 'a' });
135
- logStream.write(`[${new Date().toISOString()}] $ ${command}\n\n`);
136
-
137
- const child = spawn(command, [], {
138
- shell: '/bin/bash',
139
- cwd: working_directory || context?.cwd || process.cwd(),
140
- stdio: ['ignore', 'pipe', 'pipe'],
141
- });
142
-
143
- child.stdout!.on('data', (chunk: Buffer) => logStream.write(chunk));
144
- child.stderr!.on('data', (chunk: Buffer) => logStream.write(chunk));
145
- child.on('close', (code: number | null) => {
146
- logStream.write(`\n[${new Date().toISOString()}] exited with code ${code}\n`);
147
- logStream.end();
148
- });
149
-
150
- return {
151
- success: true,
152
- llmContent: `Background process started.\nJob ID: ${jobId}\nPID: ${child.pid}\nLog file: ${logPath}\n\nMonitor with: tail -f ${logPath}\nCheck output: cat ${logPath}`,
153
- displayContent: `▶ bg: ${description || command.substring(0, 50)} (PID ${child.pid})`,
154
- metadata: { jobId, pid: child.pid, logPath, command },
155
- };
156
- }
157
-
158
- // 执行命
159
- const options = {
160
- timeout,
161
- cwd: working_directory || context?.cwd || process.cwd(),
162
- maxBuffer: 10 * 1024 * 1024, // 10MB
163
- shell: '/bin/bash',
164
- };
165
-
166
- const { stdout, stderr } = await execAsync(command, options);
167
-
168
- // 组合输
169
- const output = [
170
- stdout ? stdout.trim() : '',
171
- stderr ? `[stderr]\n${stderr.trim()}` : '',
172
- ].filter(Boolean).join('\n\n');
173
-
174
- return {
175
- success: true,
176
- llmContent: output || '(no output)',
177
- displayContent: description
178
- ? description
179
- : command.length > 60 ? command.substring(0, 60) + '…' : command,
180
- metadata: {
181
- command,
182
- exit_code: 0,
183
- working_directory: options.cwd,
184
- },
185
- };
186
- } catch (error: unknown) {
187
- // 处理执行错
188
- const execError = error as {
189
- code?: number | string;
190
- killed?: boolean;
191
- signal?: string;
192
- stdout?: string;
193
- stderr?: string;
194
- message?: string;
195
- };
196
-
197
- // 超时处
198
- if (execError.killed && execError.signal === 'SIGTERM') {
199
- return {
200
- success: false,
201
- llmContent: `Command timed out after ${timeout}ms: ${command}`,
202
- displayContent: `error: timeout (${timeout}ms)`,
203
- error: {
204
- type: ToolErrorType.TIMEOUT_ERROR,
205
- message: 'Command timed out',
206
- },
207
- };
208
- }
209
-
210
- // 命令执行失
211
- const exitCode = typeof execError.code === 'number' ? execError.code : 1;
212
- const stderr = execError.stderr || execError.message || 'unknown error';
213
- const stdout = execError.stdout || '';
214
-
215
- const output = [
216
- stdout ? stdout.trim() : '',
217
- stderr ? stderr.trim() : '',
218
- ].filter(Boolean).join('\n\n');
219
-
220
- return {
221
- success: false,
222
- llmContent: `Command failed with exit code ${exitCode}:\n${output}`,
223
- displayContent: `error: exit ${exitCode}`,
224
- error: {
225
- type: ToolErrorType.EXECUTION_ERROR,
226
- message: stderr,
227
- details: { exit_code: exitCode },
228
- },
229
- metadata: {
230
- command,
231
- exit_code: exitCode,
232
- },
233
- };
234
- }
235
- },
236
- });
@@ -1,105 +0,0 @@
1
- /**
2
- * Council tool — lets the running agent convene a multi-perspective
3
- * deliberation mid-conversation, without the user typing /research.
4
- * Mirrors the /research slash command (builtinCommands.ts) exactly:
5
- * fixed 4-member council, read-only tools, no confirmation needed.
6
- */
7
-
8
- import { z } from 'zod';
9
- import { createTool } from '../createTool.js';
10
- import { ToolKind } from '../types.js';
11
- import { CouncilAgent } from '../../agent/orchestrator/CouncilAgent.js';
12
- import { requireModelConfig, buildSourceContext } from '../../agent/orchestrator/utils.js';
13
-
14
- const CouncilSchema = z.object({
15
- question: z.string().describe('The question or decision to deliberate on'),
16
- });
17
-
18
- export const councilTool = createTool({
19
- name: 'Council',
20
- displayName: 'Convene Council',
21
- kind: ToolKind.ReadOnly,
22
- schema: CouncilSchema,
23
-
24
- description: {
25
- short: 'Convene a 4-perspective council to deliberate on a question',
26
- long: `Spawns a research council of read-only sub-agents with different perspectives —
27
- Analyst (data/empirical), Architect (systems/design), Ethicist (safety/fairness),
28
- Pragmatist (implementation reality) — who each vote and reason independently,
29
- then returns their views plus a synthesis.
30
-
31
- Use this for genuinely contested questions where multiple angles matter
32
- (architecture tradeoffs, risk calls, "should we do X" decisions) — not for
33
- straightforward lookups.`,
34
- },
35
-
36
- execute: async ({ question }, context) => {
37
- let modelConfig;
38
- try {
39
- modelConfig = requireModelConfig();
40
- } catch (e) {
41
- const msg = (e as Error).message;
42
- return { success: false, llmContent: msg, displayContent: msg };
43
- }
44
-
45
- const cwd = context?.cwd || process.cwd();
46
- const sourceCtx = buildSourceContext(cwd);
47
- const baseModelCfg = { model: modelConfig.model, baseURL: modelConfig.baseURL || undefined, apiKey: modelConfig.apiKey };
48
- const researchTools = ['Read', 'Grep', 'Glob'];
49
- const researchNote = `\n\nWorkspace context (project metadata + file tree + structure summaries + git changes):\n${sourceCtx}\n\nRead files with Read tool, search with Grep, browse with Glob.\nAlways state VOTE: approve, reject, or abstain and REASONING: with clear justification.`;
50
-
51
- try {
52
- const council = new CouncilAgent('council', modelConfig, {
53
- rule: 'majority',
54
- maxTokensPerAgent: 800,
55
- enableIteration: false,
56
- });
57
-
58
- council.addMember('analyst', 'Data Analyst',
59
- `You are a Data Analyst on a research council. You reason from data, statistics, and empirical evidence.\nYou value measurable outcomes and quantitative reasoning.${researchNote}`,
60
- 1, baseModelCfg, researchTools);
61
-
62
- council.addMember('architect', 'Systems Architect',
63
- `You are a Systems Architect on a research council. You evaluate designs, tradeoffs, and architectural decisions.\nYou focus on scalability, maintainability, and system coherence.${researchNote}`,
64
- 1, baseModelCfg, researchTools);
65
-
66
- council.addMember('ethicist', 'Ethics & Safety Officer',
67
- `You are an Ethics & Safety Officer on a research council. You evaluate safety, fairness, privacy, and societal impact.\nYou raise concerns others might miss and advocate for responsible practices.${researchNote}`,
68
- 1, baseModelCfg, researchTools);
69
-
70
- council.addMember('pragmatist', 'Pragmatic Engineer',
71
- `You are a Pragmatic Engineer on a research council. You evaluate practicality, implementation effort, and real-world constraints.\nYou balance idealism with what actually works in production.${researchNote}`,
72
- 1, baseModelCfg, researchTools);
73
-
74
- const result = await council.deliberate(question, context?.sessionId);
75
-
76
- const lines: string[] = [];
77
- for (const v of result.voteResults) {
78
- lines.push(`### ${v.role}`);
79
- lines.push(`VOTE: ${v.vote}`);
80
- lines.push(v.reasoning);
81
- lines.push('');
82
- }
83
- lines.push('### Synthesis');
84
- lines.push('');
85
- const summaryLines = result.summary.split('\n');
86
- const verdictIdx = summaryLines.findIndex(l => l.includes('APPROVED') || l.includes('REJECTED'));
87
- const synthesis = verdictIdx > -1
88
- ? summaryLines.slice(verdictIdx + 1).join('\n').trim()
89
- : result.summary;
90
- lines.push(synthesis || `${result.voteResults.length} perspectives gathered.`);
91
-
92
- const formatted = lines.join('\n').trim();
93
- return {
94
- success: true,
95
- llmContent: formatted,
96
- displayContent: `✓ Council deliberated (${result.voteResults.length} perspectives, ${result.rounds} round${result.rounds === 1 ? '' : 's'})`,
97
- };
98
- } catch (e) {
99
- const msg = `Council deliberation failed: ${(e as Error).message}`;
100
- return { success: false, llmContent: msg, displayContent: msg };
101
- }
102
- },
103
- });
104
-
105
- export default councilTool;