@umsai/ums-code 0.1.4-v2 → 0.3.0-v2

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 (382) hide show
  1. package/dist/package.json +11 -3
  2. package/dist/src/config/config.d.ts +6 -0
  3. package/dist/src/config/config.js +102 -11
  4. package/dist/src/config/config.js.map +1 -1
  5. package/dist/src/config/settings.d.ts +5 -0
  6. package/dist/src/config/settings.js +15 -1
  7. package/dist/src/config/settings.js.map +1 -1
  8. package/dist/src/config/settingsSchema.d.ts +75 -17
  9. package/dist/src/config/settingsSchema.js +57 -17
  10. package/dist/src/config/settingsSchema.js.map +1 -1
  11. package/dist/src/config/webSearch.d.ts +35 -0
  12. package/dist/src/config/webSearch.js +87 -0
  13. package/dist/src/config/webSearch.js.map +1 -0
  14. package/dist/src/core/auth.d.ts +1 -1
  15. package/dist/src/core/auth.js +19 -3
  16. package/dist/src/core/auth.js.map +1 -1
  17. package/dist/src/core/initializer.js +13 -2
  18. package/dist/src/core/initializer.js.map +1 -1
  19. package/dist/src/core/theme.js +4 -1
  20. package/dist/src/core/theme.js.map +1 -1
  21. package/dist/src/gemini.d.ts +1 -1
  22. package/dist/src/gemini.js +53 -44
  23. package/dist/src/gemini.js.map +1 -1
  24. package/dist/src/gemini.test.js +117 -0
  25. package/dist/src/gemini.test.js.map +1 -1
  26. package/dist/src/generated/git-commit.d.ts +2 -2
  27. package/dist/src/generated/git-commit.js +2 -2
  28. package/dist/src/i18n/index.d.ts +18 -0
  29. package/dist/src/i18n/index.js +184 -0
  30. package/dist/src/i18n/index.js.map +1 -0
  31. package/dist/src/i18n/locales/en.js +1129 -0
  32. package/dist/src/i18n/locales/zh.js +1052 -0
  33. package/dist/src/nonInteractive/control/ControlContext.d.ts +63 -0
  34. package/dist/src/nonInteractive/control/ControlContext.js +31 -0
  35. package/dist/src/nonInteractive/control/ControlContext.js.map +1 -0
  36. package/dist/src/nonInteractive/control/ControlDispatcher.d.ts +86 -0
  37. package/dist/src/nonInteractive/control/ControlDispatcher.js +238 -0
  38. package/dist/src/nonInteractive/control/ControlDispatcher.js.map +1 -0
  39. package/dist/src/nonInteractive/control/ControlDispatcher.test.d.ts +6 -0
  40. package/dist/src/nonInteractive/control/ControlDispatcher.test.js +549 -0
  41. package/dist/src/nonInteractive/control/ControlDispatcher.test.js.map +1 -0
  42. package/dist/src/nonInteractive/control/ControlService.d.ts +78 -0
  43. package/dist/src/nonInteractive/control/ControlService.js +154 -0
  44. package/dist/src/nonInteractive/control/ControlService.js.map +1 -0
  45. package/dist/src/nonInteractive/control/controllers/baseController.d.ts +50 -0
  46. package/dist/src/nonInteractive/control/controllers/baseController.js +102 -0
  47. package/dist/src/nonInteractive/control/controllers/baseController.js.map +1 -0
  48. package/dist/src/nonInteractive/control/controllers/hookController.d.ts +25 -0
  49. package/dist/src/nonInteractive/control/controllers/hookController.js +42 -0
  50. package/dist/src/nonInteractive/control/controllers/hookController.js.map +1 -0
  51. package/dist/src/nonInteractive/control/controllers/mcpController.d.ts +42 -0
  52. package/dist/src/nonInteractive/control/controllers/mcpController.js +205 -0
  53. package/dist/src/nonInteractive/control/controllers/mcpController.js.map +1 -0
  54. package/dist/src/nonInteractive/control/controllers/permissionController.d.ts +78 -0
  55. package/dist/src/nonInteractive/control/controllers/permissionController.js +358 -0
  56. package/dist/src/nonInteractive/control/controllers/permissionController.js.map +1 -0
  57. package/dist/src/nonInteractive/control/controllers/systemController.d.ts +56 -0
  58. package/dist/src/nonInteractive/control/controllers/systemController.js +166 -0
  59. package/dist/src/nonInteractive/control/controllers/systemController.js.map +1 -0
  60. package/dist/src/nonInteractive/control/types/serviceAPIs.d.ts +120 -0
  61. package/dist/src/nonInteractive/control/types/serviceAPIs.js +7 -0
  62. package/dist/src/nonInteractive/control/types/serviceAPIs.js.map +1 -0
  63. package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.d.ts +446 -0
  64. package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.js +891 -0
  65. package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.js.map +1 -0
  66. package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.test.d.ts +6 -0
  67. package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.test.js +1197 -0
  68. package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.test.js.map +1 -0
  69. package/dist/src/nonInteractive/io/JsonOutputAdapter.d.ts +29 -0
  70. package/dist/src/nonInteractive/io/JsonOutputAdapter.js +56 -0
  71. package/dist/src/nonInteractive/io/JsonOutputAdapter.js.map +1 -0
  72. package/dist/src/nonInteractive/io/JsonOutputAdapter.test.d.ts +6 -0
  73. package/dist/src/nonInteractive/io/JsonOutputAdapter.test.js +624 -0
  74. package/dist/src/nonInteractive/io/JsonOutputAdapter.test.js.map +1 -0
  75. package/dist/src/nonInteractive/io/StreamJsonInputReader.d.ts +16 -0
  76. package/dist/src/nonInteractive/io/StreamJsonInputReader.js +54 -0
  77. package/dist/src/nonInteractive/io/StreamJsonInputReader.js.map +1 -0
  78. package/dist/src/nonInteractive/io/StreamJsonInputReader.test.d.ts +6 -0
  79. package/dist/src/nonInteractive/io/StreamJsonInputReader.test.js +178 -0
  80. package/dist/src/nonInteractive/io/StreamJsonInputReader.test.js.map +1 -0
  81. package/dist/src/nonInteractive/io/StreamJsonOutputAdapter.d.ts +69 -0
  82. package/dist/src/nonInteractive/io/StreamJsonOutputAdapter.js +185 -0
  83. package/dist/src/nonInteractive/io/StreamJsonOutputAdapter.js.map +1 -0
  84. package/dist/src/nonInteractive/io/StreamJsonOutputAdapter.test.d.ts +6 -0
  85. package/dist/src/nonInteractive/io/StreamJsonOutputAdapter.test.js +808 -0
  86. package/dist/src/nonInteractive/io/StreamJsonOutputAdapter.test.js.map +1 -0
  87. package/dist/src/nonInteractive/session.d.ts +23 -0
  88. package/dist/src/nonInteractive/session.js +549 -0
  89. package/dist/src/nonInteractive/session.js.map +1 -0
  90. package/dist/src/nonInteractive/session.test.d.ts +6 -0
  91. package/dist/src/nonInteractive/session.test.js +407 -0
  92. package/dist/src/nonInteractive/session.test.js.map +1 -0
  93. package/dist/src/nonInteractive/types.d.ts +344 -0
  94. package/dist/src/nonInteractive/types.js +78 -0
  95. package/dist/src/nonInteractive/types.js.map +1 -0
  96. package/dist/src/nonInteractiveCli.d.ts +21 -1
  97. package/dist/src/nonInteractiveCli.js +204 -57
  98. package/dist/src/nonInteractiveCli.js.map +1 -1
  99. package/dist/src/nonInteractiveCliCommands.d.ts +19 -1
  100. package/dist/src/nonInteractiveCliCommands.js +69 -4
  101. package/dist/src/nonInteractiveCliCommands.js.map +1 -1
  102. package/dist/src/services/BuiltinCommandLoader.js +2 -0
  103. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  104. package/dist/src/services/FileCommandLoader.js +4 -1
  105. package/dist/src/services/FileCommandLoader.js.map +1 -1
  106. package/dist/src/ui/AppContainer.js +41 -38
  107. package/dist/src/ui/AppContainer.js.map +1 -1
  108. package/dist/src/ui/auth/AuthDialog.d.ts +1 -13
  109. package/dist/src/ui/auth/AuthDialog.js +41 -111
  110. package/dist/src/ui/auth/AuthDialog.js.map +1 -1
  111. package/dist/src/ui/auth/AuthDialog.test.js +49 -19
  112. package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
  113. package/dist/src/ui/auth/AuthInProgress.js +2 -1
  114. package/dist/src/ui/auth/AuthInProgress.js.map +1 -1
  115. package/dist/src/ui/auth/useAuth.d.ts +9 -8
  116. package/dist/src/ui/auth/useAuth.js +135 -63
  117. package/dist/src/ui/auth/useAuth.js.map +1 -1
  118. package/dist/src/ui/commands/aboutCommand.js +7 -31
  119. package/dist/src/ui/commands/aboutCommand.js.map +1 -1
  120. package/dist/src/ui/commands/agentsCommand.js +10 -3
  121. package/dist/src/ui/commands/agentsCommand.js.map +1 -1
  122. package/dist/src/ui/commands/approvalModeCommand.js +8 -329
  123. package/dist/src/ui/commands/approvalModeCommand.js.map +1 -1
  124. package/dist/src/ui/commands/approvalModeCommand.test.js +19 -263
  125. package/dist/src/ui/commands/approvalModeCommand.test.js.map +1 -1
  126. package/dist/src/ui/commands/authCommand.js +4 -1
  127. package/dist/src/ui/commands/authCommand.js.map +1 -1
  128. package/dist/src/ui/commands/bugCommand.js +13 -47
  129. package/dist/src/ui/commands/bugCommand.js.map +1 -1
  130. package/dist/src/ui/commands/chatCommand.js +51 -25
  131. package/dist/src/ui/commands/chatCommand.js.map +1 -1
  132. package/dist/src/ui/commands/clearCommand.js +6 -3
  133. package/dist/src/ui/commands/clearCommand.js.map +1 -1
  134. package/dist/src/ui/commands/compressCommand.js +9 -4
  135. package/dist/src/ui/commands/compressCommand.js.map +1 -1
  136. package/dist/src/ui/commands/copyCommand.js +4 -1
  137. package/dist/src/ui/commands/copyCommand.js.map +1 -1
  138. package/dist/src/ui/commands/directoryCommand.js +30 -12
  139. package/dist/src/ui/commands/directoryCommand.js.map +1 -1
  140. package/dist/src/ui/commands/docsCommand.js +9 -3
  141. package/dist/src/ui/commands/docsCommand.js.map +1 -1
  142. package/dist/src/ui/commands/editorCommand.js +4 -1
  143. package/dist/src/ui/commands/editorCommand.js.map +1 -1
  144. package/dist/src/ui/commands/extensionsCommand.js +10 -3
  145. package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
  146. package/dist/src/ui/commands/helpCommand.js +4 -1
  147. package/dist/src/ui/commands/helpCommand.js.map +1 -1
  148. package/dist/src/ui/commands/ideCommand.js +23 -7
  149. package/dist/src/ui/commands/ideCommand.js.map +1 -1
  150. package/dist/src/ui/commands/initCommand.js +5 -3
  151. package/dist/src/ui/commands/initCommand.js.map +1 -1
  152. package/dist/src/ui/commands/languageCommand.d.ts +7 -0
  153. package/dist/src/ui/commands/languageCommand.js +386 -0
  154. package/dist/src/ui/commands/languageCommand.js.map +1 -0
  155. package/dist/src/ui/commands/mcpCommand.js +38 -18
  156. package/dist/src/ui/commands/mcpCommand.js.map +1 -1
  157. package/dist/src/ui/commands/memoryCommand.js +54 -25
  158. package/dist/src/ui/commands/memoryCommand.js.map +1 -1
  159. package/dist/src/ui/commands/modelCommand.js +9 -4
  160. package/dist/src/ui/commands/modelCommand.js.map +1 -1
  161. package/dist/src/ui/commands/permissionsCommand.js +4 -1
  162. package/dist/src/ui/commands/permissionsCommand.js.map +1 -1
  163. package/dist/src/ui/commands/quitCommand.js +7 -2
  164. package/dist/src/ui/commands/quitCommand.js.map +1 -1
  165. package/dist/src/ui/commands/settingsCommand.js +4 -1
  166. package/dist/src/ui/commands/settingsCommand.js.map +1 -1
  167. package/dist/src/ui/commands/setupGithubCommand.js +4 -1
  168. package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
  169. package/dist/src/ui/commands/statsCommand.js +11 -4
  170. package/dist/src/ui/commands/statsCommand.js.map +1 -1
  171. package/dist/src/ui/commands/summaryCommand.js +15 -8
  172. package/dist/src/ui/commands/summaryCommand.js.map +1 -1
  173. package/dist/src/ui/commands/terminalSetupCommand.js +9 -3
  174. package/dist/src/ui/commands/terminalSetupCommand.js.map +1 -1
  175. package/dist/src/ui/commands/themeCommand.js +4 -1
  176. package/dist/src/ui/commands/themeCommand.js.map +1 -1
  177. package/dist/src/ui/commands/toolsCommand.js +5 -2
  178. package/dist/src/ui/commands/toolsCommand.js.map +1 -1
  179. package/dist/src/ui/commands/types.d.ts +1 -1
  180. package/dist/src/ui/commands/types.js.map +1 -1
  181. package/dist/src/ui/commands/vimCommand.js +4 -1
  182. package/dist/src/ui/commands/vimCommand.js.map +1 -1
  183. package/dist/src/ui/components/AboutBox.d.ts +2 -9
  184. package/dist/src/ui/components/AboutBox.js +6 -2
  185. package/dist/src/ui/components/AboutBox.js.map +1 -1
  186. package/dist/src/ui/components/ApprovalModeDialog.d.ts +21 -0
  187. package/dist/src/ui/components/ApprovalModeDialog.js +68 -0
  188. package/dist/src/ui/components/ApprovalModeDialog.js.map +1 -0
  189. package/dist/src/ui/components/AutoAcceptIndicator.js +7 -6
  190. package/dist/src/ui/components/AutoAcceptIndicator.js.map +1 -1
  191. package/dist/src/ui/components/Composer.js +4 -3
  192. package/dist/src/ui/components/Composer.js.map +1 -1
  193. package/dist/src/ui/components/ConfigInitDisplay.js +7 -3
  194. package/dist/src/ui/components/ConfigInitDisplay.js.map +1 -1
  195. package/dist/src/ui/components/ContextSummaryDisplay.js +33 -9
  196. package/dist/src/ui/components/ContextSummaryDisplay.js.map +1 -1
  197. package/dist/src/ui/components/DialogManager.js +60 -13
  198. package/dist/src/ui/components/DialogManager.js.map +1 -1
  199. package/dist/src/ui/components/EditorSettingsDialog.js +8 -3
  200. package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
  201. package/dist/src/ui/components/Help.js +14 -4
  202. package/dist/src/ui/components/Help.js.map +1 -1
  203. package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
  204. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  205. package/dist/src/ui/components/HistoryItemDisplay.test.js +17 -8
  206. package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
  207. package/dist/src/ui/components/InputPrompt.js +10 -136
  208. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  209. package/dist/src/ui/components/LoadingIndicator.js +6 -1
  210. package/dist/src/ui/components/LoadingIndicator.js.map +1 -1
  211. package/dist/src/ui/components/ModelDialog.js +2 -1
  212. package/dist/src/ui/components/ModelDialog.js.map +1 -1
  213. package/dist/src/ui/components/ModelStatsDisplay.js +6 -5
  214. package/dist/src/ui/components/ModelStatsDisplay.js.map +1 -1
  215. package/dist/src/ui/components/OpenAIKeyPrompt.d.ts +19 -1
  216. package/dist/src/ui/components/OpenAIKeyPrompt.js +38 -6
  217. package/dist/src/ui/components/OpenAIKeyPrompt.js.map +1 -1
  218. package/dist/src/ui/components/ProQuotaDialog.js +5 -4
  219. package/dist/src/ui/components/ProQuotaDialog.js.map +1 -1
  220. package/dist/src/ui/components/QuitConfirmationDialog.js +6 -5
  221. package/dist/src/ui/components/QuitConfirmationDialog.js.map +1 -1
  222. package/dist/src/ui/components/QwenOAuthProgress.d.ts +2 -2
  223. package/dist/src/ui/components/QwenOAuthProgress.js +14 -7
  224. package/dist/src/ui/components/QwenOAuthProgress.js.map +1 -1
  225. package/dist/src/ui/components/QwenOAuthProgress.test.js +1 -0
  226. package/dist/src/ui/components/QwenOAuthProgress.test.js.map +1 -1
  227. package/dist/src/ui/components/SessionSummaryDisplay.js +2 -1
  228. package/dist/src/ui/components/SessionSummaryDisplay.js.map +1 -1
  229. package/dist/src/ui/components/SettingsDialog.d.ts +3 -1
  230. package/dist/src/ui/components/SettingsDialog.js +35 -12
  231. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  232. package/dist/src/ui/components/SettingsDialog.test.js +5 -4
  233. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  234. package/dist/src/ui/components/ShellConfirmationDialog.js +5 -4
  235. package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
  236. package/dist/src/ui/components/StatsDisplay.js +5 -4
  237. package/dist/src/ui/components/StatsDisplay.js.map +1 -1
  238. package/dist/src/ui/components/ThemeDialog.js +5 -2
  239. package/dist/src/ui/components/ThemeDialog.js.map +1 -1
  240. package/dist/src/ui/components/ToolStatsDisplay.js +3 -2
  241. package/dist/src/ui/components/ToolStatsDisplay.js.map +1 -1
  242. package/dist/src/ui/components/WelcomeBackDialog.js +13 -4
  243. package/dist/src/ui/components/WelcomeBackDialog.js.map +1 -1
  244. package/dist/src/ui/components/messages/CompressionMessage.js +10 -6
  245. package/dist/src/ui/components/messages/CompressionMessage.js.map +1 -1
  246. package/dist/src/ui/components/messages/ToolConfirmationMessage.js +40 -29
  247. package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
  248. package/dist/src/ui/components/shared/BaseSelectionList.test.js +1 -1
  249. package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -1
  250. package/dist/src/ui/components/shared/ScopeSelector.js +3 -1
  251. package/dist/src/ui/components/shared/ScopeSelector.js.map +1 -1
  252. package/dist/src/ui/components/subagents/create/AgentCreationWizard.js +39 -26
  253. package/dist/src/ui/components/subagents/create/AgentCreationWizard.js.map +1 -1
  254. package/dist/src/ui/components/subagents/create/CreationSummary.js +20 -10
  255. package/dist/src/ui/components/subagents/create/CreationSummary.js.map +1 -1
  256. package/dist/src/ui/components/subagents/create/DescriptionInput.js +6 -3
  257. package/dist/src/ui/components/subagents/create/DescriptionInput.js.map +1 -1
  258. package/dist/src/ui/components/subagents/create/GenerationMethodSelector.js +7 -2
  259. package/dist/src/ui/components/subagents/create/GenerationMethodSelector.js.map +1 -1
  260. package/dist/src/ui/components/subagents/create/LocationSelector.js +7 -2
  261. package/dist/src/ui/components/subagents/create/LocationSelector.js.map +1 -1
  262. package/dist/src/ui/components/subagents/create/ToolSelector.js +8 -7
  263. package/dist/src/ui/components/subagents/create/ToolSelector.js.map +1 -1
  264. package/dist/src/ui/components/subagents/manage/ActionSelectionStep.js +29 -4
  265. package/dist/src/ui/components/subagents/manage/ActionSelectionStep.js.map +1 -1
  266. package/dist/src/ui/components/subagents/manage/AgentDeleteStep.js +6 -3
  267. package/dist/src/ui/components/subagents/manage/AgentDeleteStep.js.map +1 -1
  268. package/dist/src/ui/components/subagents/manage/AgentEditStep.js +14 -5
  269. package/dist/src/ui/components/subagents/manage/AgentEditStep.js.map +1 -1
  270. package/dist/src/ui/components/subagents/manage/AgentSelectionStep.js +13 -6
  271. package/dist/src/ui/components/subagents/manage/AgentSelectionStep.js.map +1 -1
  272. package/dist/src/ui/components/subagents/manage/AgentViewerStep.js +3 -2
  273. package/dist/src/ui/components/subagents/manage/AgentViewerStep.js.map +1 -1
  274. package/dist/src/ui/components/subagents/manage/AgentsManagerDialog.js +14 -13
  275. package/dist/src/ui/components/subagents/manage/AgentsManagerDialog.js.map +1 -1
  276. package/dist/src/ui/components/subagents/runtime/AgentExecutionDisplay.js +8 -8
  277. package/dist/src/ui/components/views/McpStatus.js +28 -15
  278. package/dist/src/ui/components/views/McpStatus.js.map +1 -1
  279. package/dist/src/ui/components/views/ToolsList.js +2 -1
  280. package/dist/src/ui/components/views/ToolsList.js.map +1 -1
  281. package/dist/src/ui/contexts/UIActionsContext.d.ts +5 -4
  282. package/dist/src/ui/contexts/UIActionsContext.js +1 -0
  283. package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
  284. package/dist/src/ui/contexts/UIStateContext.d.ts +5 -7
  285. package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
  286. package/dist/src/ui/editors/editorSettingsManager.js +1 -0
  287. package/dist/src/ui/editors/editorSettingsManager.js.map +1 -1
  288. package/dist/src/ui/hooks/atCommandProcessor.test.js +2 -0
  289. package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
  290. package/dist/src/ui/hooks/slashCommandProcessor.d.ts +1 -0
  291. package/dist/src/ui/hooks/slashCommandProcessor.js +4 -7
  292. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  293. package/dist/src/ui/hooks/useApprovalModeCommand.d.ts +14 -0
  294. package/dist/src/ui/hooks/useApprovalModeCommand.js +33 -0
  295. package/dist/src/ui/hooks/useApprovalModeCommand.js.map +1 -0
  296. package/dist/src/ui/hooks/useAttentionNotifications.d.ts +14 -0
  297. package/dist/src/ui/hooks/useAttentionNotifications.js +41 -0
  298. package/dist/src/ui/hooks/useAttentionNotifications.js.map +1 -0
  299. package/dist/src/ui/hooks/useAttentionNotifications.test.d.ts +6 -0
  300. package/dist/src/ui/hooks/useAttentionNotifications.test.js +113 -0
  301. package/dist/src/ui/hooks/useAttentionNotifications.test.js.map +1 -0
  302. package/dist/src/ui/hooks/useCommandCompletion.d.ts +1 -4
  303. package/dist/src/ui/hooks/useCommandCompletion.js +1 -23
  304. package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
  305. package/dist/src/ui/hooks/useDialogClose.d.ts +6 -3
  306. package/dist/src/ui/hooks/useDialogClose.js +5 -0
  307. package/dist/src/ui/hooks/useDialogClose.js.map +1 -1
  308. package/dist/src/ui/hooks/useGitBranchName.js +6 -3
  309. package/dist/src/ui/hooks/useGitBranchName.js.map +1 -1
  310. package/dist/src/ui/hooks/useGitBranchName.test.js +39 -21
  311. package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
  312. package/dist/src/ui/hooks/useInitializationAuthError.d.ts +22 -0
  313. package/dist/src/ui/hooks/useInitializationAuthError.js +40 -0
  314. package/dist/src/ui/hooks/useInitializationAuthError.js.map +1 -0
  315. package/dist/src/ui/hooks/usePhraseCycler.js +6 -4
  316. package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
  317. package/dist/src/ui/hooks/useQwenAuth.d.ts +7 -12
  318. package/dist/src/ui/hooks/useQwenAuth.js +4 -8
  319. package/dist/src/ui/hooks/useQwenAuth.js.map +1 -1
  320. package/dist/src/ui/hooks/useQwenAuth.test.js +72 -98
  321. package/dist/src/ui/hooks/useQwenAuth.test.js.map +1 -1
  322. package/dist/src/ui/hooks/useThemeCommand.js +8 -3
  323. package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
  324. package/dist/src/ui/models/availableModels.js +7 -2
  325. package/dist/src/ui/models/availableModels.js.map +1 -1
  326. package/dist/src/ui/types.d.ts +32 -14
  327. package/dist/src/ui/types.js.map +1 -1
  328. package/dist/src/ui/utils/clipboardUtils.js +3 -3
  329. package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
  330. package/dist/src/ui/utils/commandUtils.d.ts +16 -0
  331. package/dist/src/ui/utils/commandUtils.js +16 -1
  332. package/dist/src/ui/utils/commandUtils.js.map +1 -1
  333. package/dist/src/ui/utils/commandUtils.test.js +5 -2
  334. package/dist/src/ui/utils/commandUtils.test.js.map +1 -1
  335. package/dist/src/ui/utils/terminalSetup.js +45 -18
  336. package/dist/src/ui/utils/terminalSetup.js.map +1 -1
  337. package/dist/src/utils/attentionNotification.d.ts +20 -0
  338. package/dist/src/utils/attentionNotification.js +34 -0
  339. package/dist/src/utils/attentionNotification.js.map +1 -0
  340. package/dist/src/utils/attentionNotification.test.d.ts +6 -0
  341. package/dist/src/utils/attentionNotification.test.js +46 -0
  342. package/dist/src/utils/attentionNotification.test.js.map +1 -0
  343. package/dist/src/utils/dialogScopeUtils.d.ts +0 -4
  344. package/dist/src/utils/dialogScopeUtils.js +5 -2
  345. package/dist/src/utils/dialogScopeUtils.js.map +1 -1
  346. package/dist/src/utils/errors.d.ts +10 -2
  347. package/dist/src/utils/errors.js +14 -13
  348. package/dist/src/utils/errors.js.map +1 -1
  349. package/dist/src/utils/errors.test.js +91 -54
  350. package/dist/src/utils/errors.test.js.map +1 -1
  351. package/dist/src/utils/nonInteractiveHelpers.d.ts +88 -0
  352. package/dist/src/utils/nonInteractiveHelpers.js +470 -0
  353. package/dist/src/utils/nonInteractiveHelpers.js.map +1 -0
  354. package/dist/src/utils/nonInteractiveHelpers.test.d.ts +6 -0
  355. package/dist/src/utils/nonInteractiveHelpers.test.js +945 -0
  356. package/dist/src/utils/nonInteractiveHelpers.test.js.map +1 -0
  357. package/dist/src/utils/sandbox.js +1 -1
  358. package/dist/src/utils/sandbox.js.map +1 -1
  359. package/dist/src/utils/settingsUtils.js +7 -1
  360. package/dist/src/utils/settingsUtils.js.map +1 -1
  361. package/dist/src/utils/systemInfo.d.ts +66 -0
  362. package/dist/src/utils/systemInfo.js +125 -0
  363. package/dist/src/utils/systemInfo.js.map +1 -0
  364. package/dist/src/utils/systemInfo.test.d.ts +6 -0
  365. package/dist/src/utils/systemInfo.test.js +259 -0
  366. package/dist/src/utils/systemInfo.test.js.map +1 -0
  367. package/dist/src/utils/systemInfoFields.d.ts +22 -0
  368. package/dist/src/utils/systemInfoFields.js +96 -0
  369. package/dist/src/utils/systemInfoFields.js.map +1 -0
  370. package/dist/src/utils/userStartupWarnings.js +9 -4
  371. package/dist/src/utils/userStartupWarnings.js.map +1 -1
  372. package/dist/src/validateNonInterActiveAuth.js +27 -6
  373. package/dist/src/validateNonInterActiveAuth.js.map +1 -1
  374. package/dist/src/zed-integration/acp.js +1 -2
  375. package/dist/src/zed-integration/acp.js.map +1 -1
  376. package/dist/src/zed-integration/schema.d.ts +506 -264
  377. package/dist/src/zed-integration/schema.js +13 -0
  378. package/dist/src/zed-integration/schema.js.map +1 -1
  379. package/dist/src/zed-integration/zedIntegration.js +376 -32
  380. package/dist/src/zed-integration/zedIntegration.js.map +1 -1
  381. package/dist/tsconfig.tsbuildinfo +1 -1
  382. package/package.json +12 -4
@@ -0,0 +1,945 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
7
+ import { ToolErrorType, MCPServerStatus, getMCPServerStatus, OutputFormat, } from '@umsai/ums-code-core';
8
+ import { normalizePartList, extractPartsFromUserMessage, extractUsageFromGeminiClient, computeUsageFromMetrics, buildSystemMessage, createTaskToolProgressHandler, functionResponsePartsToString, toolResultContent, } from './nonInteractiveHelpers.js';
9
+ // Mock dependencies
10
+ vi.mock('../services/CommandService.js', () => ({
11
+ CommandService: {
12
+ create: vi.fn().mockResolvedValue({
13
+ getCommands: vi
14
+ .fn()
15
+ .mockReturnValue([
16
+ { name: 'help' },
17
+ { name: 'commit' },
18
+ { name: 'memory' },
19
+ ]),
20
+ }),
21
+ },
22
+ }));
23
+ vi.mock('../services/BuiltinCommandLoader.js', () => ({
24
+ BuiltinCommandLoader: vi.fn().mockImplementation(() => ({})),
25
+ }));
26
+ vi.mock('../ui/utils/computeStats.js', () => ({
27
+ computeSessionStats: vi.fn().mockReturnValue({
28
+ totalPromptTokens: 100,
29
+ totalCachedTokens: 20,
30
+ }),
31
+ }));
32
+ vi.mock('@umsai/ums-code-core', async (importOriginal) => {
33
+ const actual = await importOriginal();
34
+ return {
35
+ ...actual,
36
+ getMCPServerStatus: vi.fn(),
37
+ };
38
+ });
39
+ describe('normalizePartList', () => {
40
+ it('should return empty array for null input', () => {
41
+ expect(normalizePartList(null)).toEqual([]);
42
+ });
43
+ it('should return empty array for undefined input', () => {
44
+ expect(normalizePartList(undefined)).toEqual([]);
45
+ });
46
+ it('should convert string to Part array', () => {
47
+ const result = normalizePartList('test string');
48
+ expect(result).toEqual([{ text: 'test string' }]);
49
+ });
50
+ it('should convert array of strings to Part array', () => {
51
+ const result = normalizePartList(['hello', 'world']);
52
+ expect(result).toEqual([{ text: 'hello' }, { text: 'world' }]);
53
+ });
54
+ it('should convert array of mixed strings and Parts to Part array', () => {
55
+ const part = { text: 'existing' };
56
+ const result = normalizePartList(['new', part]);
57
+ expect(result).toEqual([{ text: 'new' }, part]);
58
+ });
59
+ it('should convert single Part object to array', () => {
60
+ const part = { text: 'single part' };
61
+ const result = normalizePartList(part);
62
+ expect(result).toEqual([part]);
63
+ });
64
+ it('should handle empty array', () => {
65
+ expect(normalizePartList([])).toEqual([]);
66
+ });
67
+ });
68
+ describe('extractPartsFromUserMessage', () => {
69
+ it('should return null for undefined message', () => {
70
+ expect(extractPartsFromUserMessage(undefined)).toBeNull();
71
+ });
72
+ it('should return null for null message', () => {
73
+ expect(extractPartsFromUserMessage(null)).toBeNull();
74
+ });
75
+ it('should extract string content', () => {
76
+ const message = {
77
+ type: 'user',
78
+ session_id: 'test-session',
79
+ message: {
80
+ role: 'user',
81
+ content: 'test message',
82
+ },
83
+ parent_tool_use_id: null,
84
+ };
85
+ expect(extractPartsFromUserMessage(message)).toBe('test message');
86
+ });
87
+ it('should extract text blocks from content array', () => {
88
+ const message = {
89
+ type: 'user',
90
+ session_id: 'test-session',
91
+ message: {
92
+ role: 'user',
93
+ content: [
94
+ { type: 'text', text: 'hello' },
95
+ { type: 'text', text: 'world' },
96
+ ],
97
+ },
98
+ parent_tool_use_id: null,
99
+ };
100
+ const result = extractPartsFromUserMessage(message);
101
+ expect(result).toEqual([{ text: 'hello' }, { text: 'world' }]);
102
+ });
103
+ it('should skip invalid blocks in content array', () => {
104
+ const message = {
105
+ type: 'user',
106
+ session_id: 'test-session',
107
+ message: {
108
+ role: 'user',
109
+ content: [
110
+ { type: 'text', text: 'valid' },
111
+ null,
112
+ { type: 'text', text: 'also valid' },
113
+ ],
114
+ },
115
+ parent_tool_use_id: null,
116
+ };
117
+ const result = extractPartsFromUserMessage(message);
118
+ expect(result).toEqual([{ text: 'valid' }, { text: 'also valid' }]);
119
+ });
120
+ it('should convert non-text blocks to JSON strings', () => {
121
+ const message = {
122
+ type: 'user',
123
+ session_id: 'test-session',
124
+ message: {
125
+ role: 'user',
126
+ content: [
127
+ { type: 'text', text: 'text block' },
128
+ { type: 'tool_use', id: '123', name: 'tool', input: {} },
129
+ ],
130
+ },
131
+ parent_tool_use_id: null,
132
+ };
133
+ const result = extractPartsFromUserMessage(message);
134
+ expect(result).toEqual([
135
+ { text: 'text block' },
136
+ {
137
+ text: JSON.stringify({
138
+ type: 'tool_use',
139
+ id: '123',
140
+ name: 'tool',
141
+ input: {},
142
+ }),
143
+ },
144
+ ]);
145
+ });
146
+ it('should return null for empty content array', () => {
147
+ const message = {
148
+ type: 'user',
149
+ session_id: 'test-session',
150
+ message: {
151
+ role: 'user',
152
+ content: [],
153
+ },
154
+ parent_tool_use_id: null,
155
+ };
156
+ expect(extractPartsFromUserMessage(message)).toBeNull();
157
+ });
158
+ it('should return null when message has no content', () => {
159
+ const message = {
160
+ type: 'user',
161
+ session_id: 'test-session',
162
+ message: {
163
+ role: 'user',
164
+ content: undefined,
165
+ },
166
+ parent_tool_use_id: null,
167
+ };
168
+ expect(extractPartsFromUserMessage(message)).toBeNull();
169
+ });
170
+ });
171
+ describe('extractUsageFromGeminiClient', () => {
172
+ it('should return undefined for null client', () => {
173
+ expect(extractUsageFromGeminiClient(null)).toBeUndefined();
174
+ });
175
+ it('should return undefined for non-object client', () => {
176
+ expect(extractUsageFromGeminiClient('not an object')).toBeUndefined();
177
+ });
178
+ it('should return undefined when getChat is not a function', () => {
179
+ const client = { getChat: 'not a function' };
180
+ expect(extractUsageFromGeminiClient(client)).toBeUndefined();
181
+ });
182
+ it('should return undefined when chat does not have getDebugResponses', () => {
183
+ const client = {
184
+ getChat: vi.fn().mockReturnValue({}),
185
+ };
186
+ expect(extractUsageFromGeminiClient(client)).toBeUndefined();
187
+ });
188
+ it('should extract usage from latest response with usageMetadata', () => {
189
+ const client = {
190
+ getChat: vi.fn().mockReturnValue({
191
+ getDebugResponses: vi.fn().mockReturnValue([
192
+ { usageMetadata: { promptTokenCount: 50 } },
193
+ {
194
+ usageMetadata: {
195
+ promptTokenCount: 100,
196
+ candidatesTokenCount: 200,
197
+ totalTokenCount: 300,
198
+ cachedContentTokenCount: 10,
199
+ },
200
+ },
201
+ ]),
202
+ }),
203
+ };
204
+ const result = extractUsageFromGeminiClient(client);
205
+ expect(result).toEqual({
206
+ input_tokens: 100,
207
+ output_tokens: 200,
208
+ total_tokens: 300,
209
+ cache_read_input_tokens: 10,
210
+ });
211
+ });
212
+ it('should return default values when metadata values are not numbers', () => {
213
+ const client = {
214
+ getChat: vi.fn().mockReturnValue({
215
+ getDebugResponses: vi.fn().mockReturnValue([
216
+ {
217
+ usageMetadata: {
218
+ promptTokenCount: 'not a number',
219
+ candidatesTokenCount: null,
220
+ },
221
+ },
222
+ ]),
223
+ }),
224
+ };
225
+ const result = extractUsageFromGeminiClient(client);
226
+ expect(result).toEqual({
227
+ input_tokens: 0,
228
+ output_tokens: 0,
229
+ });
230
+ });
231
+ it('should handle errors gracefully', () => {
232
+ const client = {
233
+ getChat: vi.fn().mockImplementation(() => {
234
+ throw new Error('Test error');
235
+ }),
236
+ };
237
+ const consoleSpy = vi.spyOn(console, 'debug').mockImplementation(() => { });
238
+ const result = extractUsageFromGeminiClient(client);
239
+ expect(result).toBeUndefined();
240
+ expect(consoleSpy).toHaveBeenCalled();
241
+ consoleSpy.mockRestore();
242
+ });
243
+ it('should skip responses without usageMetadata', () => {
244
+ const client = {
245
+ getChat: vi.fn().mockReturnValue({
246
+ getDebugResponses: vi.fn().mockReturnValue([
247
+ { someOtherData: 'value' },
248
+ {
249
+ usageMetadata: {
250
+ promptTokenCount: 50,
251
+ candidatesTokenCount: 75,
252
+ },
253
+ },
254
+ ]),
255
+ }),
256
+ };
257
+ const result = extractUsageFromGeminiClient(client);
258
+ expect(result).toEqual({
259
+ input_tokens: 50,
260
+ output_tokens: 75,
261
+ });
262
+ });
263
+ });
264
+ describe('computeUsageFromMetrics', () => {
265
+ it('should compute usage from SessionMetrics with single model', () => {
266
+ const metrics = {
267
+ models: {
268
+ 'model-1': {
269
+ api: { totalRequests: 1, totalErrors: 0, totalLatencyMs: 100 },
270
+ tokens: {
271
+ prompt: 50,
272
+ candidates: 100,
273
+ total: 150,
274
+ cached: 10,
275
+ thoughts: 0,
276
+ tool: 0,
277
+ },
278
+ },
279
+ },
280
+ tools: {
281
+ totalCalls: 0,
282
+ totalSuccess: 0,
283
+ totalFail: 0,
284
+ totalDurationMs: 0,
285
+ totalDecisions: {
286
+ accept: 0,
287
+ reject: 0,
288
+ modify: 0,
289
+ auto_accept: 0,
290
+ },
291
+ byName: {},
292
+ },
293
+ files: {
294
+ totalLinesAdded: 0,
295
+ totalLinesRemoved: 0,
296
+ },
297
+ };
298
+ const result = computeUsageFromMetrics(metrics);
299
+ expect(result).toEqual({
300
+ input_tokens: 100,
301
+ output_tokens: 100,
302
+ cache_read_input_tokens: 20,
303
+ total_tokens: 150,
304
+ });
305
+ });
306
+ it('should aggregate usage across multiple models', () => {
307
+ const metrics = {
308
+ models: {
309
+ 'model-1': {
310
+ api: { totalRequests: 1, totalErrors: 0, totalLatencyMs: 100 },
311
+ tokens: {
312
+ prompt: 50,
313
+ candidates: 100,
314
+ total: 150,
315
+ cached: 10,
316
+ thoughts: 0,
317
+ tool: 0,
318
+ },
319
+ },
320
+ 'model-2': {
321
+ api: { totalRequests: 1, totalErrors: 0, totalLatencyMs: 100 },
322
+ tokens: {
323
+ prompt: 75,
324
+ candidates: 125,
325
+ total: 200,
326
+ cached: 15,
327
+ thoughts: 0,
328
+ tool: 0,
329
+ },
330
+ },
331
+ },
332
+ tools: {
333
+ totalCalls: 0,
334
+ totalSuccess: 0,
335
+ totalFail: 0,
336
+ totalDurationMs: 0,
337
+ totalDecisions: {
338
+ accept: 0,
339
+ reject: 0,
340
+ modify: 0,
341
+ auto_accept: 0,
342
+ },
343
+ byName: {},
344
+ },
345
+ files: {
346
+ totalLinesAdded: 0,
347
+ totalLinesRemoved: 0,
348
+ },
349
+ };
350
+ const result = computeUsageFromMetrics(metrics);
351
+ expect(result).toEqual({
352
+ input_tokens: 100,
353
+ output_tokens: 225,
354
+ cache_read_input_tokens: 20,
355
+ total_tokens: 350,
356
+ });
357
+ });
358
+ it('should not include total_tokens when it is 0', () => {
359
+ const metrics = {
360
+ models: {
361
+ 'model-1': {
362
+ api: { totalRequests: 1, totalErrors: 0, totalLatencyMs: 100 },
363
+ tokens: {
364
+ prompt: 50,
365
+ candidates: 100,
366
+ total: 0,
367
+ cached: 10,
368
+ thoughts: 0,
369
+ tool: 0,
370
+ },
371
+ },
372
+ },
373
+ tools: {
374
+ totalCalls: 0,
375
+ totalSuccess: 0,
376
+ totalFail: 0,
377
+ totalDurationMs: 0,
378
+ totalDecisions: {
379
+ accept: 0,
380
+ reject: 0,
381
+ modify: 0,
382
+ auto_accept: 0,
383
+ },
384
+ byName: {},
385
+ },
386
+ files: {
387
+ totalLinesAdded: 0,
388
+ totalLinesRemoved: 0,
389
+ },
390
+ };
391
+ const result = computeUsageFromMetrics(metrics);
392
+ expect(result).not.toHaveProperty('total_tokens');
393
+ expect(result).toEqual({
394
+ input_tokens: 100,
395
+ output_tokens: 100,
396
+ cache_read_input_tokens: 20,
397
+ });
398
+ });
399
+ it('should handle empty models', () => {
400
+ const metrics = {
401
+ models: {},
402
+ tools: {
403
+ totalCalls: 0,
404
+ totalSuccess: 0,
405
+ totalFail: 0,
406
+ totalDurationMs: 0,
407
+ totalDecisions: {
408
+ accept: 0,
409
+ reject: 0,
410
+ modify: 0,
411
+ auto_accept: 0,
412
+ },
413
+ byName: {},
414
+ },
415
+ files: {
416
+ totalLinesAdded: 0,
417
+ totalLinesRemoved: 0,
418
+ },
419
+ };
420
+ const result = computeUsageFromMetrics(metrics);
421
+ expect(result).toEqual({
422
+ input_tokens: 100,
423
+ output_tokens: 0,
424
+ cache_read_input_tokens: 20,
425
+ });
426
+ });
427
+ });
428
+ describe('buildSystemMessage', () => {
429
+ let mockConfig;
430
+ beforeEach(() => {
431
+ vi.clearAllMocks();
432
+ // Mock getMCPServerStatus to return CONNECTED by default
433
+ vi.mocked(getMCPServerStatus).mockReturnValue(MCPServerStatus.CONNECTED);
434
+ mockConfig = {
435
+ getToolRegistry: vi.fn().mockReturnValue({
436
+ getAllToolNames: vi.fn().mockReturnValue(['tool1', 'tool2']),
437
+ }),
438
+ getMcpServers: vi.fn().mockReturnValue({
439
+ 'mcp-server-1': {},
440
+ 'mcp-server-2': {},
441
+ }),
442
+ getTargetDir: vi.fn().mockReturnValue('/test/dir'),
443
+ getModel: vi.fn().mockReturnValue('test-model'),
444
+ getCliVersion: vi.fn().mockReturnValue('1.0.0'),
445
+ getDebugMode: vi.fn().mockReturnValue(false),
446
+ };
447
+ });
448
+ it('should build system message with all fields', async () => {
449
+ const result = await buildSystemMessage(mockConfig, 'test-session-id', 'auto');
450
+ expect(result).toEqual({
451
+ type: 'system',
452
+ subtype: 'init',
453
+ uuid: 'test-session-id',
454
+ session_id: 'test-session-id',
455
+ cwd: '/test/dir',
456
+ tools: ['tool1', 'tool2'],
457
+ mcp_servers: [
458
+ { name: 'mcp-server-1', status: 'connected' },
459
+ { name: 'mcp-server-2', status: 'connected' },
460
+ ],
461
+ model: 'test-model',
462
+ permissionMode: 'auto',
463
+ slash_commands: ['commit', 'help', 'memory'],
464
+ qwen_code_version: '1.0.0',
465
+ agents: [],
466
+ });
467
+ });
468
+ it('should handle empty tool registry', async () => {
469
+ const config = {
470
+ ...mockConfig,
471
+ getToolRegistry: vi.fn().mockReturnValue(null),
472
+ };
473
+ const result = await buildSystemMessage(config, 'test-session-id', 'auto');
474
+ expect(result.tools).toEqual([]);
475
+ });
476
+ it('should handle empty MCP servers', async () => {
477
+ const config = {
478
+ ...mockConfig,
479
+ getMcpServers: vi.fn().mockReturnValue(null),
480
+ };
481
+ const result = await buildSystemMessage(config, 'test-session-id', 'auto');
482
+ expect(result.mcp_servers).toEqual([]);
483
+ });
484
+ it('should use unknown version when getCliVersion returns null', async () => {
485
+ const config = {
486
+ ...mockConfig,
487
+ getCliVersion: vi.fn().mockReturnValue(null),
488
+ };
489
+ const result = await buildSystemMessage(config, 'test-session-id', 'auto');
490
+ expect(result.qwen_code_version).toBe('unknown');
491
+ });
492
+ });
493
+ describe('createTaskToolProgressHandler', () => {
494
+ let mockAdapter;
495
+ let mockConfig;
496
+ beforeEach(() => {
497
+ mockConfig = {
498
+ getDebugMode: vi.fn().mockReturnValue(false),
499
+ isInteractive: vi.fn().mockReturnValue(false),
500
+ getOutputFormat: vi.fn().mockReturnValue(OutputFormat.JSON),
501
+ };
502
+ mockAdapter = {
503
+ processSubagentToolCall: vi.fn(),
504
+ emitSubagentErrorResult: vi.fn(),
505
+ emitToolResult: vi.fn(),
506
+ emitUserMessage: vi.fn(),
507
+ };
508
+ });
509
+ it('should create handler that processes task tool calls', () => {
510
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
511
+ const taskDisplay = {
512
+ type: 'task_execution',
513
+ subagentName: 'test-agent',
514
+ taskDescription: 'Test task',
515
+ taskPrompt: 'Test prompt',
516
+ status: 'running',
517
+ toolCalls: [
518
+ {
519
+ callId: 'tool-1',
520
+ name: 'test_tool',
521
+ args: { arg1: 'value1' },
522
+ status: 'executing',
523
+ },
524
+ ],
525
+ };
526
+ handler('task-call-id', taskDisplay);
527
+ expect(mockAdapter.processSubagentToolCall).toHaveBeenCalledWith(expect.objectContaining({
528
+ callId: 'tool-1',
529
+ name: 'test_tool',
530
+ status: 'executing',
531
+ }), 'parent-tool-id');
532
+ });
533
+ it('should emit tool_result when tool call completes', () => {
534
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
535
+ const taskDisplay = {
536
+ type: 'task_execution',
537
+ subagentName: 'test-agent',
538
+ taskDescription: 'Test task',
539
+ taskPrompt: 'Test prompt',
540
+ status: 'running',
541
+ toolCalls: [
542
+ {
543
+ callId: 'tool-1',
544
+ name: 'test_tool',
545
+ args: { arg1: 'value1' },
546
+ status: 'success',
547
+ resultDisplay: 'Success result',
548
+ },
549
+ ],
550
+ };
551
+ handler('task-call-id', taskDisplay);
552
+ expect(mockAdapter.emitToolResult).toHaveBeenCalledWith(expect.objectContaining({
553
+ callId: 'tool-1',
554
+ name: 'test_tool',
555
+ }), expect.objectContaining({
556
+ callId: 'tool-1',
557
+ resultDisplay: 'Success result',
558
+ }), 'parent-tool-id');
559
+ });
560
+ it('should not duplicate tool_use emissions', () => {
561
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
562
+ const taskDisplay = {
563
+ type: 'task_execution',
564
+ subagentName: 'test-agent',
565
+ taskDescription: 'Test task',
566
+ taskPrompt: 'Test prompt',
567
+ status: 'running',
568
+ toolCalls: [
569
+ {
570
+ callId: 'tool-1',
571
+ name: 'test_tool',
572
+ args: {},
573
+ status: 'executing',
574
+ },
575
+ ],
576
+ };
577
+ // Call handler twice with same tool call
578
+ handler('task-call-id', taskDisplay);
579
+ handler('task-call-id', taskDisplay);
580
+ expect(mockAdapter.processSubagentToolCall).toHaveBeenCalledTimes(1);
581
+ });
582
+ it('should not duplicate tool_result emissions', () => {
583
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
584
+ const taskDisplay = {
585
+ type: 'task_execution',
586
+ subagentName: 'test-agent',
587
+ taskDescription: 'Test task',
588
+ taskPrompt: 'Test prompt',
589
+ status: 'running',
590
+ toolCalls: [
591
+ {
592
+ callId: 'tool-1',
593
+ name: 'test_tool',
594
+ args: {},
595
+ status: 'success',
596
+ resultDisplay: 'Result',
597
+ },
598
+ ],
599
+ };
600
+ // Call handler twice with same completed tool call
601
+ handler('task-call-id', taskDisplay);
602
+ handler('task-call-id', taskDisplay);
603
+ expect(mockAdapter.emitToolResult).toHaveBeenCalledTimes(1);
604
+ });
605
+ it('should handle status transitions from executing to completed', () => {
606
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
607
+ // First: executing state
608
+ const executingDisplay = {
609
+ type: 'task_execution',
610
+ subagentName: 'test-agent',
611
+ taskDescription: 'Test task',
612
+ taskPrompt: 'Test prompt',
613
+ status: 'running',
614
+ toolCalls: [
615
+ {
616
+ callId: 'tool-1',
617
+ name: 'test_tool',
618
+ args: {},
619
+ status: 'executing',
620
+ },
621
+ ],
622
+ };
623
+ // Second: completed state
624
+ const completedDisplay = {
625
+ type: 'task_execution',
626
+ subagentName: 'test-agent',
627
+ taskDescription: 'Test task',
628
+ taskPrompt: 'Test prompt',
629
+ status: 'running',
630
+ toolCalls: [
631
+ {
632
+ callId: 'tool-1',
633
+ name: 'test_tool',
634
+ args: {},
635
+ status: 'success',
636
+ resultDisplay: 'Done',
637
+ },
638
+ ],
639
+ };
640
+ handler('task-call-id', executingDisplay);
641
+ handler('task-call-id', completedDisplay);
642
+ expect(mockAdapter.processSubagentToolCall).toHaveBeenCalledTimes(1);
643
+ expect(mockAdapter.emitToolResult).toHaveBeenCalledTimes(1);
644
+ });
645
+ it('should emit error result for failed task status', () => {
646
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
647
+ const runningDisplay = {
648
+ type: 'task_execution',
649
+ subagentName: 'test-agent',
650
+ taskDescription: 'Test task',
651
+ taskPrompt: 'Test prompt',
652
+ status: 'running',
653
+ toolCalls: [],
654
+ };
655
+ const failedDisplay = {
656
+ type: 'task_execution',
657
+ subagentName: 'test-agent',
658
+ taskDescription: 'Test task',
659
+ taskPrompt: 'Test prompt',
660
+ status: 'failed',
661
+ terminateReason: 'Task failed with error',
662
+ toolCalls: [],
663
+ };
664
+ handler('task-call-id', runningDisplay);
665
+ handler('task-call-id', failedDisplay);
666
+ expect(mockAdapter.emitSubagentErrorResult).toHaveBeenCalledWith('Task failed with error', 0, 'parent-tool-id');
667
+ });
668
+ it('should emit error result for cancelled task status', () => {
669
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
670
+ const runningDisplay = {
671
+ type: 'task_execution',
672
+ subagentName: 'test-agent',
673
+ taskDescription: 'Test task',
674
+ taskPrompt: 'Test prompt',
675
+ status: 'running',
676
+ toolCalls: [],
677
+ };
678
+ const cancelledDisplay = {
679
+ type: 'task_execution',
680
+ subagentName: 'test-agent',
681
+ taskDescription: 'Test task',
682
+ taskPrompt: 'Test prompt',
683
+ status: 'cancelled',
684
+ toolCalls: [],
685
+ };
686
+ handler('task-call-id', runningDisplay);
687
+ handler('task-call-id', cancelledDisplay);
688
+ expect(mockAdapter.emitSubagentErrorResult).toHaveBeenCalledWith('Task was cancelled', 0, 'parent-tool-id');
689
+ });
690
+ it('should not process non-task-execution displays', () => {
691
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
692
+ const nonTaskDisplay = {
693
+ type: 'other',
694
+ content: 'some content',
695
+ };
696
+ handler('call-id', nonTaskDisplay);
697
+ expect(mockAdapter.processSubagentToolCall).not.toHaveBeenCalled();
698
+ expect(mockAdapter.emitToolResult).not.toHaveBeenCalled();
699
+ });
700
+ it('should handle tool calls with failed status', () => {
701
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
702
+ const taskDisplay = {
703
+ type: 'task_execution',
704
+ subagentName: 'test-agent',
705
+ taskDescription: 'Test task',
706
+ taskPrompt: 'Test prompt',
707
+ status: 'running',
708
+ toolCalls: [
709
+ {
710
+ callId: 'tool-1',
711
+ name: 'test_tool',
712
+ args: {},
713
+ status: 'failed',
714
+ error: 'Tool execution failed',
715
+ },
716
+ ],
717
+ };
718
+ handler('task-call-id', taskDisplay);
719
+ expect(mockAdapter.emitToolResult).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({
720
+ callId: 'tool-1',
721
+ error: expect.any(Error),
722
+ errorType: ToolErrorType.EXECUTION_FAILED,
723
+ }), 'parent-tool-id');
724
+ });
725
+ it('should handle tool calls without result content', () => {
726
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', mockAdapter);
727
+ const taskDisplay = {
728
+ type: 'task_execution',
729
+ subagentName: 'test-agent',
730
+ taskDescription: 'Test task',
731
+ taskPrompt: 'Test prompt',
732
+ status: 'running',
733
+ toolCalls: [
734
+ {
735
+ callId: 'tool-1',
736
+ name: 'test_tool',
737
+ args: {},
738
+ status: 'success',
739
+ resultDisplay: '',
740
+ responseParts: [],
741
+ },
742
+ ],
743
+ };
744
+ handler('task-call-id', taskDisplay);
745
+ // Should not emit tool_result if no content
746
+ expect(mockAdapter.emitToolResult).not.toHaveBeenCalled();
747
+ });
748
+ it('should work without adapter (non-JSON mode)', () => {
749
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', undefined);
750
+ const taskDisplay = {
751
+ type: 'task_execution',
752
+ subagentName: 'test-agent',
753
+ taskDescription: 'Test task',
754
+ taskPrompt: 'Test prompt',
755
+ status: 'running',
756
+ toolCalls: [],
757
+ };
758
+ // Should not throw
759
+ expect(() => handler('task-call-id', taskDisplay)).not.toThrow();
760
+ });
761
+ it('should work with adapter that does not support subagent APIs', () => {
762
+ const limitedAdapter = {
763
+ emitToolResult: vi.fn(),
764
+ };
765
+ const { handler } = createTaskToolProgressHandler(mockConfig, 'parent-tool-id', limitedAdapter);
766
+ const taskDisplay = {
767
+ type: 'task_execution',
768
+ subagentName: 'test-agent',
769
+ taskDescription: 'Test task',
770
+ taskPrompt: 'Test prompt',
771
+ status: 'running',
772
+ toolCalls: [],
773
+ };
774
+ // Should not throw
775
+ expect(() => handler('task-call-id', taskDisplay)).not.toThrow();
776
+ });
777
+ });
778
+ describe('functionResponsePartsToString', () => {
779
+ it('should extract output from functionResponse parts', () => {
780
+ const parts = [
781
+ {
782
+ functionResponse: {
783
+ response: {
784
+ output: 'function output',
785
+ },
786
+ },
787
+ },
788
+ ];
789
+ expect(functionResponsePartsToString(parts)).toBe('function output');
790
+ });
791
+ it('should handle multiple functionResponse parts', () => {
792
+ const parts = [
793
+ {
794
+ functionResponse: {
795
+ response: {
796
+ output: 'output1',
797
+ },
798
+ },
799
+ },
800
+ {
801
+ functionResponse: {
802
+ response: {
803
+ output: 'output2',
804
+ },
805
+ },
806
+ },
807
+ ];
808
+ expect(functionResponsePartsToString(parts)).toBe('output1output2');
809
+ });
810
+ it('should return empty string for missing output', () => {
811
+ const parts = [
812
+ {
813
+ functionResponse: {
814
+ response: {},
815
+ },
816
+ },
817
+ ];
818
+ expect(functionResponsePartsToString(parts)).toBe('');
819
+ });
820
+ it('should JSON.stringify non-functionResponse parts', () => {
821
+ const parts = [
822
+ { text: 'text part' },
823
+ {
824
+ functionResponse: {
825
+ response: {
826
+ output: 'function output',
827
+ },
828
+ },
829
+ },
830
+ ];
831
+ const result = functionResponsePartsToString(parts);
832
+ expect(result).toContain('function output');
833
+ expect(result).toContain('text part');
834
+ });
835
+ it('should handle empty array', () => {
836
+ expect(functionResponsePartsToString([])).toBe('');
837
+ });
838
+ it('should handle functionResponse with null response', () => {
839
+ const parts = [
840
+ {
841
+ functionResponse: {
842
+ response: null,
843
+ },
844
+ },
845
+ ];
846
+ expect(functionResponsePartsToString(parts)).toBe('');
847
+ });
848
+ });
849
+ describe('toolResultContent', () => {
850
+ it('should return resultDisplay string when available', () => {
851
+ const response = {
852
+ callId: 'test-call',
853
+ resultDisplay: 'Result content',
854
+ responseParts: [],
855
+ error: undefined,
856
+ errorType: undefined,
857
+ };
858
+ expect(toolResultContent(response)).toBe('Result content');
859
+ });
860
+ it('should return undefined for empty resultDisplay string', () => {
861
+ const response = {
862
+ callId: 'test-call',
863
+ resultDisplay: ' ',
864
+ responseParts: [],
865
+ error: undefined,
866
+ errorType: undefined,
867
+ };
868
+ expect(toolResultContent(response)).toBeUndefined();
869
+ });
870
+ it('should use functionResponsePartsToString for responseParts', () => {
871
+ const response = {
872
+ callId: 'test-call',
873
+ resultDisplay: undefined,
874
+ responseParts: [
875
+ {
876
+ functionResponse: {
877
+ response: {
878
+ output: 'function output',
879
+ },
880
+ },
881
+ },
882
+ ],
883
+ error: undefined,
884
+ errorType: undefined,
885
+ };
886
+ expect(toolResultContent(response)).toBe('function output');
887
+ });
888
+ it('should return error message when error is present', () => {
889
+ const response = {
890
+ callId: 'test-call',
891
+ resultDisplay: undefined,
892
+ responseParts: [],
893
+ error: new Error('Test error message'),
894
+ errorType: undefined,
895
+ };
896
+ expect(toolResultContent(response)).toBe('Test error message');
897
+ });
898
+ it('should prefer resultDisplay over responseParts', () => {
899
+ const response = {
900
+ callId: 'test-call',
901
+ resultDisplay: 'Direct result',
902
+ responseParts: [
903
+ {
904
+ functionResponse: {
905
+ response: {
906
+ output: 'function output',
907
+ },
908
+ },
909
+ },
910
+ ],
911
+ error: undefined,
912
+ errorType: undefined,
913
+ };
914
+ expect(toolResultContent(response)).toBe('Direct result');
915
+ });
916
+ it('should prefer responseParts over error', () => {
917
+ const response = {
918
+ callId: 'test-call',
919
+ resultDisplay: undefined,
920
+ error: new Error('Error message'),
921
+ responseParts: [
922
+ {
923
+ functionResponse: {
924
+ response: {
925
+ output: 'function output',
926
+ },
927
+ },
928
+ },
929
+ ],
930
+ errorType: undefined,
931
+ };
932
+ expect(toolResultContent(response)).toBe('function output');
933
+ });
934
+ it('should return undefined when no content is available', () => {
935
+ const response = {
936
+ callId: 'test-call',
937
+ resultDisplay: undefined,
938
+ responseParts: [],
939
+ error: undefined,
940
+ errorType: undefined,
941
+ };
942
+ expect(toolResultContent(response)).toBeUndefined();
943
+ });
944
+ });
945
+ //# sourceMappingURL=nonInteractiveHelpers.test.js.map