bingocode 1.0.3 → 1.0.4

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 (184) hide show
  1. package/package.json +1 -1
  2. package/desktop/README.md +0 -30
  3. package/desktop/bunfig.toml +0 -1
  4. package/desktop/index.html +0 -17
  5. package/desktop/package.json +0 -55
  6. package/desktop/pnpm-lock.yaml +0 -3832
  7. package/desktop/public/app-icon.jpg +0 -0
  8. package/desktop/public/fonts/inter-latin-ext.woff2 +0 -0
  9. package/desktop/public/fonts/inter-latin.woff2 +0 -0
  10. package/desktop/public/fonts/jetbrains-mono-latin-ext.woff2 +0 -0
  11. package/desktop/public/fonts/jetbrains-mono-latin.woff2 +0 -0
  12. package/desktop/public/fonts/manrope-latin-ext.woff2 +0 -0
  13. package/desktop/public/fonts/manrope-latin.woff2 +0 -0
  14. package/desktop/public/fonts/material-symbols-outlined.woff2 +0 -0
  15. package/desktop/public/icons/bilibili.svg +0 -1
  16. package/desktop/public/icons/douyin.svg +0 -1
  17. package/desktop/public/icons/github.svg +0 -3
  18. package/desktop/public/icons/xiaohongshu.svg +0 -1
  19. package/desktop/scripts/build-macos-arm64.sh +0 -270
  20. package/desktop/scripts/build-sidecars.ts +0 -183
  21. package/desktop/scripts/build-windows-x64.ps1 +0 -295
  22. package/desktop/scripts/scan-missing-imports.ts +0 -235
  23. package/desktop/sidecars/claude-sidecar.ts +0 -156
  24. package/desktop/src/App.tsx +0 -5
  25. package/desktop/src/__tests__/agentsSettings.test.tsx +0 -349
  26. package/desktop/src/__tests__/pages.test.tsx +0 -290
  27. package/desktop/src/__tests__/skillsSettings.test.tsx +0 -205
  28. package/desktop/src/api/adapters.ts +0 -12
  29. package/desktop/src/api/agents.ts +0 -36
  30. package/desktop/src/api/cliTasks.ts +0 -28
  31. package/desktop/src/api/client.ts +0 -63
  32. package/desktop/src/api/computerUse.ts +0 -76
  33. package/desktop/src/api/filesystem.ts +0 -30
  34. package/desktop/src/api/hahaOAuth.ts +0 -38
  35. package/desktop/src/api/models.ts +0 -28
  36. package/desktop/src/api/providers.ts +0 -63
  37. package/desktop/src/api/search.ts +0 -29
  38. package/desktop/src/api/sessions.ts +0 -56
  39. package/desktop/src/api/settings.ts +0 -20
  40. package/desktop/src/api/skills.ts +0 -19
  41. package/desktop/src/api/tasks.ts +0 -36
  42. package/desktop/src/api/teams.ts +0 -44
  43. package/desktop/src/api/websocket.ts +0 -164
  44. package/desktop/src/components/chat/AskUserQuestion.tsx +0 -268
  45. package/desktop/src/components/chat/AssistantMessage.tsx +0 -29
  46. package/desktop/src/components/chat/AttachmentGallery.tsx +0 -113
  47. package/desktop/src/components/chat/ChatInput.tsx +0 -622
  48. package/desktop/src/components/chat/CodeViewer.tsx +0 -161
  49. package/desktop/src/components/chat/ComputerUsePermissionModal.test.tsx +0 -174
  50. package/desktop/src/components/chat/ComputerUsePermissionModal.tsx +0 -311
  51. package/desktop/src/components/chat/DiffViewer.tsx +0 -157
  52. package/desktop/src/components/chat/FileSearchMenu.tsx +0 -198
  53. package/desktop/src/components/chat/ImageGalleryModal.tsx +0 -91
  54. package/desktop/src/components/chat/InlineImageGallery.tsx +0 -106
  55. package/desktop/src/components/chat/InlineTaskSummary.tsx +0 -60
  56. package/desktop/src/components/chat/MermaidRenderer.test.tsx +0 -98
  57. package/desktop/src/components/chat/MermaidRenderer.tsx +0 -361
  58. package/desktop/src/components/chat/MessageActionBar.tsx +0 -27
  59. package/desktop/src/components/chat/MessageList.test.tsx +0 -313
  60. package/desktop/src/components/chat/MessageList.tsx +0 -249
  61. package/desktop/src/components/chat/PermissionDialog.tsx +0 -262
  62. package/desktop/src/components/chat/SessionTaskBar.test.tsx +0 -99
  63. package/desktop/src/components/chat/SessionTaskBar.tsx +0 -159
  64. package/desktop/src/components/chat/StreamingIndicator.tsx +0 -41
  65. package/desktop/src/components/chat/TerminalChrome.tsx +0 -35
  66. package/desktop/src/components/chat/ThinkingBlock.tsx +0 -87
  67. package/desktop/src/components/chat/ToolCallBlock.tsx +0 -247
  68. package/desktop/src/components/chat/ToolCallGroup.tsx +0 -617
  69. package/desktop/src/components/chat/ToolResultBlock.tsx +0 -107
  70. package/desktop/src/components/chat/UserMessage.tsx +0 -38
  71. package/desktop/src/components/chat/chatBlocks.test.tsx +0 -136
  72. package/desktop/src/components/chat/clipboard.ts +0 -25
  73. package/desktop/src/components/chat/composerUtils.test.ts +0 -55
  74. package/desktop/src/components/chat/composerUtils.ts +0 -149
  75. package/desktop/src/components/controls/ModelSelector.tsx +0 -156
  76. package/desktop/src/components/controls/PermissionModeSelector.tsx +0 -229
  77. package/desktop/src/components/layout/AppShell.tsx +0 -107
  78. package/desktop/src/components/layout/ContentRouter.tsx +0 -27
  79. package/desktop/src/components/layout/ProjectFilter.tsx +0 -126
  80. package/desktop/src/components/layout/Sidebar.test.tsx +0 -158
  81. package/desktop/src/components/layout/Sidebar.tsx +0 -384
  82. package/desktop/src/components/layout/StatusBar.tsx +0 -31
  83. package/desktop/src/components/layout/TabBar.test.tsx +0 -136
  84. package/desktop/src/components/layout/TabBar.tsx +0 -318
  85. package/desktop/src/components/layout/TitleBar.tsx +0 -96
  86. package/desktop/src/components/layout/WindowControls.test.tsx +0 -69
  87. package/desktop/src/components/layout/WindowControls.tsx +0 -89
  88. package/desktop/src/components/markdown/MarkdownRenderer.test.tsx +0 -100
  89. package/desktop/src/components/markdown/MarkdownRenderer.tsx +0 -229
  90. package/desktop/src/components/settings/ClaudeOfficialLogin.tsx +0 -107
  91. package/desktop/src/components/shared/Button.tsx +0 -63
  92. package/desktop/src/components/shared/CopyButton.tsx +0 -58
  93. package/desktop/src/components/shared/DirectoryPicker.tsx +0 -316
  94. package/desktop/src/components/shared/Dropdown.tsx +0 -91
  95. package/desktop/src/components/shared/Input.tsx +0 -38
  96. package/desktop/src/components/shared/Modal.tsx +0 -65
  97. package/desktop/src/components/shared/ProjectContextChip.tsx +0 -30
  98. package/desktop/src/components/shared/Spinner.tsx +0 -30
  99. package/desktop/src/components/shared/Textarea.tsx +0 -38
  100. package/desktop/src/components/shared/Toast.tsx +0 -47
  101. package/desktop/src/components/shared/UpdateChecker.tsx +0 -90
  102. package/desktop/src/components/skills/SkillDetail.test.tsx +0 -89
  103. package/desktop/src/components/skills/SkillDetail.tsx +0 -403
  104. package/desktop/src/components/skills/SkillList.tsx +0 -254
  105. package/desktop/src/components/tasks/DayOfWeekPicker.tsx +0 -57
  106. package/desktop/src/components/tasks/NewTaskModal.tsx +0 -407
  107. package/desktop/src/components/tasks/PromptEditor.tsx +0 -74
  108. package/desktop/src/components/tasks/TaskEmptyState.tsx +0 -30
  109. package/desktop/src/components/tasks/TaskList.tsx +0 -46
  110. package/desktop/src/components/tasks/TaskRow.tsx +0 -253
  111. package/desktop/src/components/tasks/TaskRunsPanel.tsx +0 -195
  112. package/desktop/src/components/teams/TeamStatusBar.tsx +0 -147
  113. package/desktop/src/config/providerPresets.ts +0 -78
  114. package/desktop/src/config/spinnerVerbs.ts +0 -193
  115. package/desktop/src/hooks/useKeyboardShortcuts.ts +0 -60
  116. package/desktop/src/i18n/index.ts +0 -54
  117. package/desktop/src/i18n/locales/en.ts +0 -670
  118. package/desktop/src/i18n/locales/zh.ts +0 -670
  119. package/desktop/src/lib/__tests__/cronDescribe.test.ts +0 -93
  120. package/desktop/src/lib/cronDescribe.ts +0 -188
  121. package/desktop/src/lib/desktopRuntime.ts +0 -54
  122. package/desktop/src/lib/parseRunOutput.ts +0 -79
  123. package/desktop/src/main.tsx +0 -13
  124. package/desktop/src/mocks/data.ts +0 -202
  125. package/desktop/src/pages/ActiveSession.test.tsx +0 -181
  126. package/desktop/src/pages/ActiveSession.tsx +0 -219
  127. package/desktop/src/pages/AdapterSettings.tsx +0 -375
  128. package/desktop/src/pages/AgentTeams.tsx +0 -200
  129. package/desktop/src/pages/ComputerUseSettings.tsx +0 -420
  130. package/desktop/src/pages/EmptySession.tsx +0 -518
  131. package/desktop/src/pages/NewTaskModal.tsx +0 -346
  132. package/desktop/src/pages/ScheduledTasks.tsx +0 -66
  133. package/desktop/src/pages/ScheduledTasksEmpty.tsx +0 -152
  134. package/desktop/src/pages/ScheduledTasksList.tsx +0 -416
  135. package/desktop/src/pages/SessionControls.tsx +0 -460
  136. package/desktop/src/pages/Settings.tsx +0 -1448
  137. package/desktop/src/pages/ToolInspection.tsx +0 -235
  138. package/desktop/src/stores/adapterStore.ts +0 -106
  139. package/desktop/src/stores/agentStore.ts +0 -34
  140. package/desktop/src/stores/chatStore.test.ts +0 -505
  141. package/desktop/src/stores/chatStore.ts +0 -850
  142. package/desktop/src/stores/cliTaskStore.ts +0 -152
  143. package/desktop/src/stores/hahaOAuthStore.test.ts +0 -77
  144. package/desktop/src/stores/hahaOAuthStore.ts +0 -97
  145. package/desktop/src/stores/providerStore.ts +0 -101
  146. package/desktop/src/stores/sessionStore.test.ts +0 -63
  147. package/desktop/src/stores/sessionStore.ts +0 -102
  148. package/desktop/src/stores/settingsStore.ts +0 -120
  149. package/desktop/src/stores/skillStore.ts +0 -51
  150. package/desktop/src/stores/tabStore.ts +0 -169
  151. package/desktop/src/stores/taskStore.ts +0 -68
  152. package/desktop/src/stores/teamStore.ts +0 -344
  153. package/desktop/src/stores/uiStore.ts +0 -100
  154. package/desktop/src/stores/updateStore.test.ts +0 -71
  155. package/desktop/src/stores/updateStore.ts +0 -221
  156. package/desktop/src/theme/globals.css +0 -465
  157. package/desktop/src/types/adapter.ts +0 -33
  158. package/desktop/src/types/chat.ts +0 -152
  159. package/desktop/src/types/cliTask.ts +0 -24
  160. package/desktop/src/types/provider.ts +0 -62
  161. package/desktop/src/types/session.ts +0 -27
  162. package/desktop/src/types/settings.ts +0 -22
  163. package/desktop/src/types/skill.ts +0 -38
  164. package/desktop/src/types/task.ts +0 -56
  165. package/desktop/src/types/team.ts +0 -38
  166. package/desktop/src-tauri/Cargo.lock +0 -5549
  167. package/desktop/src-tauri/Cargo.toml +0 -20
  168. package/desktop/src-tauri/app-icon.svg +0 -13
  169. package/desktop/src-tauri/build.rs +0 -3
  170. package/desktop/src-tauri/capabilities/default.json +0 -106
  171. package/desktop/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml +0 -5
  172. package/desktop/src-tauri/icons/android/values/ic_launcher_background.xml +0 -4
  173. package/desktop/src-tauri/icons/icon.icns +0 -0
  174. package/desktop/src-tauri/icons/icon.ico +0 -0
  175. package/desktop/src-tauri/src/lib.rs +0 -408
  176. package/desktop/src-tauri/src/main.rs +0 -6
  177. package/desktop/src-tauri/tauri.conf.json +0 -78
  178. package/desktop/src-tauri/tauri.macos.conf.json +0 -18
  179. package/desktop/src-tauri/tauri.release-ci.json +0 -5
  180. package/desktop/src-tauri/tauri.windows.conf.json +0 -16
  181. package/desktop/src-tauri/windows-installer-hooks.nsh +0 -17
  182. package/desktop/tsconfig.json +0 -25
  183. package/desktop/vite.config.ts +0 -26
  184. package/desktop/vitest.config.ts +0 -18
@@ -1,505 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from 'vitest'
2
- import type { MessageEntry } from '../types/session'
3
-
4
- const {
5
- sendMock,
6
- getMemberBySessionIdMock,
7
- sendMessageToMemberMock,
8
- handleTeamCreatedMock,
9
- handleTeamUpdateMock,
10
- handleTeamDeletedMock,
11
- } = vi.hoisted(() => ({
12
- sendMock: vi.fn(),
13
- getMemberBySessionIdMock: vi.fn<(sessionId: string) => any>(() => null),
14
- sendMessageToMemberMock: vi.fn(async () => {}),
15
- handleTeamCreatedMock: vi.fn(),
16
- handleTeamUpdateMock: vi.fn(),
17
- handleTeamDeletedMock: vi.fn(),
18
- }))
19
-
20
- vi.mock('../api/websocket', () => ({
21
- wsManager: {
22
- connect: vi.fn(),
23
- disconnect: vi.fn(),
24
- onMessage: vi.fn(() => () => {}),
25
- clearHandlers: vi.fn(),
26
- send: sendMock,
27
- },
28
- }))
29
-
30
- vi.mock('../api/sessions', () => ({
31
- sessionsApi: {
32
- getMessages: vi.fn(async () => ({ messages: [] })),
33
- getSlashCommands: vi.fn(async () => ({ commands: [] })),
34
- },
35
- }))
36
-
37
- vi.mock('./teamStore', () => ({
38
- useTeamStore: {
39
- getState: () => ({
40
- getMemberBySessionId: getMemberBySessionIdMock,
41
- sendMessageToMember: sendMessageToMemberMock,
42
- handleTeamCreated: handleTeamCreatedMock,
43
- handleTeamUpdate: handleTeamUpdateMock,
44
- handleTeamDeleted: handleTeamDeletedMock,
45
- }),
46
- },
47
- }))
48
-
49
- vi.mock('./tabStore', () => ({
50
- useTabStore: {
51
- getState: () => ({
52
- updateTabStatus: vi.fn(),
53
- updateTabTitle: vi.fn(),
54
- }),
55
- },
56
- }))
57
-
58
- vi.mock('./sessionStore', () => ({
59
- useSessionStore: {
60
- getState: () => ({
61
- updateSessionTitle: vi.fn(),
62
- }),
63
- },
64
- }))
65
-
66
- vi.mock('./cliTaskStore', () => ({
67
- useCLITaskStore: {
68
- getState: () => ({
69
- fetchSessionTasks: vi.fn(),
70
- tasks: [],
71
- clearTasks: vi.fn(),
72
- setTasksFromTodos: vi.fn(),
73
- markCompletedAndDismissed: vi.fn(),
74
- refreshTasks: vi.fn(),
75
- }),
76
- },
77
- }))
78
-
79
- import { mapHistoryMessagesToUiMessages, useChatStore } from './chatStore'
80
-
81
- const TEST_SESSION_ID = 'test-session-1'
82
- const initialState = useChatStore.getState()
83
-
84
- describe('chatStore history mapping', () => {
85
- beforeEach(() => {
86
- sendMock.mockReset()
87
- getMemberBySessionIdMock.mockReset()
88
- getMemberBySessionIdMock.mockReturnValue(null)
89
- sendMessageToMemberMock.mockReset()
90
- useChatStore.setState({
91
- ...initialState,
92
- sessions: {},
93
- })
94
- })
95
-
96
- it('preserves thinking blocks when restoring transcript history', () => {
97
- const messages: MessageEntry[] = [
98
- {
99
- id: 'assistant-1',
100
- type: 'assistant',
101
- timestamp: '2026-04-06T00:00:00.000Z',
102
- model: 'opus',
103
- parentToolUseId: 'agent-1',
104
- content: [
105
- { type: 'thinking', thinking: 'internal reasoning' },
106
- { type: 'text', text: '目录结构分析' },
107
- { type: 'tool_use', name: 'Read', id: 'tool-1', input: { file_path: 'src/App.tsx' } },
108
- ],
109
- },
110
- {
111
- id: 'user-1',
112
- type: 'user',
113
- timestamp: '2026-04-06T00:00:01.000Z',
114
- parentToolUseId: 'agent-1',
115
- content: [
116
- { type: 'tool_result', tool_use_id: 'tool-1', content: 'ok', is_error: false },
117
- ],
118
- },
119
- ]
120
-
121
- const mapped = mapHistoryMessagesToUiMessages(messages)
122
-
123
- expect(mapped.map((message) => message.type)).toEqual([
124
- 'thinking',
125
- 'assistant_text',
126
- 'tool_use',
127
- 'tool_result',
128
- ])
129
- expect(mapped[2]).toMatchObject({ parentToolUseId: 'agent-1' })
130
- expect(mapped[3]).toMatchObject({ parentToolUseId: 'agent-1' })
131
- })
132
-
133
- it('surfaces teammate prompt content when mapping member transcript history', () => {
134
- const messages: MessageEntry[] = [
135
- {
136
- id: 'user-1',
137
- type: 'user',
138
- timestamp: '2026-04-06T00:00:00.000Z',
139
- content: '<teammate-message teammate_id="security-reviewer">Review the auth diff and call out risks.</teammate-message>',
140
- },
141
- ]
142
-
143
- const mapped = mapHistoryMessagesToUiMessages(messages, {
144
- includeTeammateMessages: true,
145
- })
146
-
147
- expect(mapped).toMatchObject([
148
- {
149
- type: 'user_text',
150
- content: 'Review the auth diff and call out risks.',
151
- },
152
- ])
153
- })
154
-
155
- it('keeps parent tool linkage for live tool events', () => {
156
- // Initialize the session first
157
- useChatStore.setState({
158
- sessions: {
159
- [TEST_SESSION_ID]: {
160
- messages: [],
161
- chatState: 'idle',
162
- connectionState: 'connected',
163
- streamingText: '',
164
- streamingToolInput: '',
165
- activeToolUseId: null,
166
- activeToolName: null,
167
- activeThinkingId: null,
168
- pendingPermission: null,
169
- pendingComputerUsePermission: null,
170
- tokenUsage: { input_tokens: 0, output_tokens: 0 },
171
- elapsedSeconds: 0,
172
- statusVerb: '',
173
- slashCommands: [],
174
- agentTaskNotifications: {},
175
- elapsedTimer: null,
176
- },
177
- },
178
- })
179
-
180
- useChatStore.getState().handleServerMessage(TEST_SESSION_ID, {
181
- type: 'tool_use_complete',
182
- toolName: 'Read',
183
- toolUseId: 'tool-1',
184
- input: { file_path: 'src/App.tsx' },
185
- parentToolUseId: 'agent-1',
186
- })
187
-
188
- useChatStore.getState().handleServerMessage(TEST_SESSION_ID, {
189
- type: 'tool_result',
190
- toolUseId: 'tool-1',
191
- content: 'ok',
192
- isError: false,
193
- parentToolUseId: 'agent-1',
194
- })
195
-
196
- expect(useChatStore.getState().sessions[TEST_SESSION_ID]?.messages).toMatchObject([
197
- {
198
- type: 'tool_use',
199
- toolUseId: 'tool-1',
200
- parentToolUseId: 'agent-1',
201
- },
202
- {
203
- type: 'tool_result',
204
- toolUseId: 'tool-1',
205
- parentToolUseId: 'agent-1',
206
- },
207
- ])
208
- })
209
-
210
- it('sends permission mode updates to the active session only', () => {
211
- useChatStore.getState().setSessionPermissionMode('nonexistent-session', 'acceptEdits')
212
- expect(sendMock).not.toHaveBeenCalled()
213
-
214
- useChatStore.setState({
215
- sessions: {
216
- 'session-1': {
217
- messages: [],
218
- chatState: 'idle',
219
- connectionState: 'connected',
220
- streamingText: '',
221
- streamingToolInput: '',
222
- activeToolUseId: null,
223
- activeToolName: null,
224
- activeThinkingId: null,
225
- pendingPermission: null,
226
- pendingComputerUsePermission: null,
227
- tokenUsage: { input_tokens: 0, output_tokens: 0 },
228
- elapsedSeconds: 0,
229
- statusVerb: '',
230
- slashCommands: [],
231
- agentTaskNotifications: {},
232
- elapsedTimer: null,
233
- },
234
- },
235
- })
236
- useChatStore.getState().setSessionPermissionMode('session-1', 'acceptEdits')
237
-
238
- expect(sendMock).toHaveBeenCalledWith('session-1', {
239
- type: 'set_permission_mode',
240
- mode: 'acceptEdits',
241
- })
242
- })
243
-
244
- it('stores terminal task notifications for agent tool cards', () => {
245
- useChatStore.setState({
246
- sessions: {
247
- [TEST_SESSION_ID]: {
248
- messages: [],
249
- chatState: 'idle',
250
- connectionState: 'connected',
251
- streamingText: '',
252
- streamingToolInput: '',
253
- activeToolUseId: null,
254
- activeToolName: null,
255
- activeThinkingId: null,
256
- pendingPermission: null,
257
- pendingComputerUsePermission: null,
258
- tokenUsage: { input_tokens: 0, output_tokens: 0 },
259
- elapsedSeconds: 0,
260
- statusVerb: '',
261
- slashCommands: [],
262
- agentTaskNotifications: {},
263
- elapsedTimer: null,
264
- },
265
- },
266
- })
267
-
268
- useChatStore.getState().handleServerMessage(TEST_SESSION_ID, {
269
- type: 'system_notification',
270
- subtype: 'task_notification',
271
- data: {
272
- task_id: 'agent-task-1',
273
- tool_use_id: 'agent-tool-1',
274
- status: 'completed',
275
- summary: 'Agent "修复异常处理" completed',
276
- output_file: '/tmp/agent-output.txt',
277
- },
278
- })
279
-
280
- expect(
281
- useChatStore.getState().sessions[TEST_SESSION_ID]?.agentTaskNotifications[
282
- 'agent-tool-1'
283
- ],
284
- ).toMatchObject({
285
- taskId: 'agent-task-1',
286
- toolUseId: 'agent-tool-1',
287
- status: 'completed',
288
- summary: 'Agent "修复异常处理" completed',
289
- outputFile: '/tmp/agent-output.txt',
290
- })
291
- })
292
-
293
- it('flushes the previous assistant draft before starting a new user turn', () => {
294
- useChatStore.setState({
295
- sessions: {
296
- [TEST_SESSION_ID]: {
297
- messages: [],
298
- chatState: 'streaming',
299
- connectionState: 'connected',
300
- streamingText: '上一次分析结果 **还在流式区域**',
301
- streamingToolInput: '',
302
- activeToolUseId: null,
303
- activeToolName: null,
304
- activeThinkingId: null,
305
- pendingPermission: null,
306
- pendingComputerUsePermission: null,
307
- tokenUsage: { input_tokens: 0, output_tokens: 0 },
308
- elapsedSeconds: 0,
309
- statusVerb: '',
310
- slashCommands: [],
311
- agentTaskNotifications: {},
312
- elapsedTimer: null,
313
- },
314
- },
315
- })
316
-
317
- useChatStore.getState().sendMessage(TEST_SESSION_ID, '你是什么模型?')
318
-
319
- expect(useChatStore.getState().sessions[TEST_SESSION_ID]?.messages).toMatchObject([
320
- {
321
- type: 'assistant_text',
322
- content: '上一次分析结果 **还在流式区域**',
323
- },
324
- {
325
- type: 'user_text',
326
- content: '你是什么模型?',
327
- },
328
- ])
329
- expect(useChatStore.getState().sessions[TEST_SESSION_ID]?.streamingText).toBe('')
330
- })
331
-
332
- it('tracks Computer Use approval requests separately from generic tool permissions', () => {
333
- useChatStore.setState({
334
- sessions: {
335
- [TEST_SESSION_ID]: {
336
- messages: [],
337
- chatState: 'idle',
338
- connectionState: 'connected',
339
- streamingText: '',
340
- streamingToolInput: '',
341
- activeToolUseId: null,
342
- activeToolName: null,
343
- activeThinkingId: null,
344
- pendingPermission: null,
345
- pendingComputerUsePermission: null,
346
- tokenUsage: { input_tokens: 0, output_tokens: 0 },
347
- elapsedSeconds: 0,
348
- statusVerb: '',
349
- slashCommands: [],
350
- agentTaskNotifications: {},
351
- elapsedTimer: null,
352
- },
353
- },
354
- })
355
-
356
- useChatStore.getState().handleServerMessage(TEST_SESSION_ID, {
357
- type: 'computer_use_permission_request',
358
- requestId: 'cu-1',
359
- request: {
360
- requestId: 'cu-1',
361
- reason: 'Open Finder and inspect a file',
362
- apps: [
363
- {
364
- requestedName: 'Finder',
365
- resolved: {
366
- bundleId: 'com.apple.finder',
367
- displayName: 'Finder',
368
- },
369
- isSentinel: false,
370
- alreadyGranted: false,
371
- proposedTier: 'full',
372
- },
373
- ],
374
- requestedFlags: { clipboardRead: true },
375
- screenshotFiltering: 'native',
376
- },
377
- })
378
-
379
- expect(
380
- useChatStore.getState().sessions[TEST_SESSION_ID]?.pendingComputerUsePermission,
381
- ).toMatchObject({
382
- requestId: 'cu-1',
383
- request: {
384
- reason: 'Open Finder and inspect a file',
385
- },
386
- })
387
- expect(
388
- useChatStore.getState().sessions[TEST_SESSION_ID]?.chatState,
389
- ).toBe('permission_pending')
390
- })
391
-
392
- it('sends Computer Use approval payloads back over websocket', () => {
393
- useChatStore.setState({
394
- sessions: {
395
- [TEST_SESSION_ID]: {
396
- messages: [],
397
- chatState: 'permission_pending',
398
- connectionState: 'connected',
399
- streamingText: '',
400
- streamingToolInput: '',
401
- activeToolUseId: null,
402
- activeToolName: null,
403
- activeThinkingId: null,
404
- pendingPermission: null,
405
- pendingComputerUsePermission: {
406
- requestId: 'cu-1',
407
- request: {
408
- requestId: 'cu-1',
409
- reason: 'Open Finder',
410
- apps: [],
411
- requestedFlags: {},
412
- screenshotFiltering: 'native',
413
- },
414
- },
415
- tokenUsage: { input_tokens: 0, output_tokens: 0 },
416
- elapsedSeconds: 0,
417
- statusVerb: '',
418
- slashCommands: [],
419
- agentTaskNotifications: {},
420
- elapsedTimer: null,
421
- },
422
- },
423
- })
424
-
425
- useChatStore.getState().respondToComputerUsePermission(TEST_SESSION_ID, 'cu-1', {
426
- granted: [],
427
- denied: [],
428
- flags: {
429
- clipboardRead: true,
430
- clipboardWrite: false,
431
- systemKeyCombos: false,
432
- },
433
- userConsented: true,
434
- })
435
-
436
- expect(sendMock).toHaveBeenCalledWith(TEST_SESSION_ID, {
437
- type: 'computer_use_permission_response',
438
- requestId: 'cu-1',
439
- response: {
440
- granted: [],
441
- denied: [],
442
- flags: {
443
- clipboardRead: true,
444
- clipboardWrite: false,
445
- systemKeyCombos: false,
446
- },
447
- userConsented: true,
448
- },
449
- })
450
- expect(
451
- useChatStore.getState().sessions[TEST_SESSION_ID]?.pendingComputerUsePermission,
452
- ).toBeNull()
453
- expect(
454
- useChatStore.getState().sessions[TEST_SESSION_ID]?.chatState,
455
- ).toBe('tool_executing')
456
- })
457
-
458
- it('routes member-session messages through team mailbox delivery instead of websocket', async () => {
459
- const memberSessionId = 'team-member:security-reviewer@test-team'
460
- getMemberBySessionIdMock.mockReturnValue({
461
- agentId: 'security-reviewer@test-team',
462
- role: 'security-reviewer',
463
- status: 'running',
464
- })
465
-
466
- useChatStore.setState({
467
- sessions: {
468
- [memberSessionId]: {
469
- messages: [],
470
- chatState: 'idle',
471
- connectionState: 'connected',
472
- streamingText: '',
473
- streamingToolInput: '',
474
- activeToolUseId: null,
475
- activeToolName: null,
476
- activeThinkingId: null,
477
- pendingPermission: null,
478
- pendingComputerUsePermission: null,
479
- tokenUsage: { input_tokens: 0, output_tokens: 0 },
480
- elapsedSeconds: 0,
481
- statusVerb: '',
482
- slashCommands: [],
483
- agentTaskNotifications: {},
484
- elapsedTimer: null,
485
- },
486
- },
487
- })
488
-
489
- useChatStore.getState().sendMessage(memberSessionId, 'Check the latest regression')
490
- await Promise.resolve()
491
-
492
- expect(sendMessageToMemberMock).toHaveBeenCalledWith(
493
- memberSessionId,
494
- 'Check the latest regression',
495
- )
496
- expect(sendMock).not.toHaveBeenCalled()
497
- const sessionMessages = useChatStore.getState().sessions[memberSessionId]?.messages ?? []
498
-
499
- expect(sessionMessages[sessionMessages.length - 1]).toMatchObject({
500
- type: 'user_text',
501
- content: 'Check the latest regression',
502
- pending: true,
503
- })
504
- })
505
- })