@machina.ai/cell-cli 1.11.0-rc1 → 1.13.0-rc1

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 (538) hide show
  1. package/dist/package.json +12 -10
  2. package/dist/src/commands/extensions/disable.d.ts +1 -1
  3. package/dist/src/commands/extensions/disable.js +15 -7
  4. package/dist/src/commands/extensions/disable.js.map +1 -1
  5. package/dist/src/commands/extensions/enable.d.ts +1 -1
  6. package/dist/src/commands/extensions/enable.js +15 -7
  7. package/dist/src/commands/extensions/enable.js.map +1 -1
  8. package/dist/src/commands/extensions/install.js +14 -3
  9. package/dist/src/commands/extensions/install.js.map +1 -1
  10. package/dist/src/commands/extensions/install.test.js +39 -19
  11. package/dist/src/commands/extensions/install.test.js.map +1 -1
  12. package/dist/src/commands/extensions/link.js +14 -3
  13. package/dist/src/commands/extensions/link.js.map +1 -1
  14. package/dist/src/commands/extensions/list.js +13 -4
  15. package/dist/src/commands/extensions/list.js.map +1 -1
  16. package/dist/src/commands/extensions/uninstall.js +13 -2
  17. package/dist/src/commands/extensions/uninstall.js.map +1 -1
  18. package/dist/src/commands/extensions/update.js +18 -13
  19. package/dist/src/commands/extensions/update.js.map +1 -1
  20. package/dist/src/commands/extensions/validate.d.ts +12 -0
  21. package/dist/src/commands/extensions/validate.js +83 -0
  22. package/dist/src/commands/extensions/validate.js.map +1 -0
  23. package/dist/src/commands/extensions/validate.test.js +93 -0
  24. package/dist/src/commands/extensions/validate.test.js.map +1 -0
  25. package/dist/src/commands/extensions.js +3 -0
  26. package/dist/src/commands/extensions.js.map +1 -1
  27. package/dist/src/commands/mcp/add.test.js +3 -0
  28. package/dist/src/commands/mcp/add.test.js.map +1 -1
  29. package/dist/src/commands/mcp/list.js +10 -3
  30. package/dist/src/commands/mcp/list.js.map +1 -1
  31. package/dist/src/commands/mcp/list.test.js +37 -27
  32. package/dist/src/commands/mcp/list.test.js.map +1 -1
  33. package/dist/src/config/auth.js +0 -5
  34. package/dist/src/config/auth.js.map +1 -1
  35. package/dist/src/config/config.d.ts +6 -3
  36. package/dist/src/config/config.js +65 -80
  37. package/dist/src/config/config.js.map +1 -1
  38. package/dist/src/config/config.test.js +235 -212
  39. package/dist/src/config/config.test.js.map +1 -1
  40. package/dist/src/config/extension-manager.d.ts +63 -0
  41. package/dist/src/config/extension-manager.js +450 -0
  42. package/dist/src/config/extension-manager.js.map +1 -0
  43. package/dist/src/config/extension.d.ts +4 -51
  44. package/dist/src/config/extension.js +1 -535
  45. package/dist/src/config/extension.js.map +1 -1
  46. package/dist/src/config/extension.test.js +525 -201
  47. package/dist/src/config/extension.test.js.map +1 -1
  48. package/dist/src/config/extensions/consent.d.ts +38 -0
  49. package/dist/src/config/extensions/consent.js +123 -0
  50. package/dist/src/config/extensions/consent.js.map +1 -0
  51. package/dist/src/config/extensions/extensionEnablement.d.ts +1 -1
  52. package/dist/src/config/extensions/extensionEnablement.js +4 -3
  53. package/dist/src/config/extensions/extensionEnablement.js.map +1 -1
  54. package/dist/src/config/extensions/extensionEnablement.test.js +10 -10
  55. package/dist/src/config/extensions/extensionEnablement.test.js.map +1 -1
  56. package/dist/src/config/extensions/extensionSettings.d.ts +15 -0
  57. package/dist/src/config/extensions/extensionSettings.js +113 -0
  58. package/dist/src/config/extensions/extensionSettings.js.map +1 -0
  59. package/dist/src/config/extensions/extensionSettings.test.d.ts +6 -0
  60. package/dist/src/config/extensions/extensionSettings.test.js +254 -0
  61. package/dist/src/config/extensions/extensionSettings.test.js.map +1 -0
  62. package/dist/src/config/extensions/github.d.ts +2 -2
  63. package/dist/src/config/extensions/github.js +5 -10
  64. package/dist/src/config/extensions/github.js.map +1 -1
  65. package/dist/src/config/extensions/github.test.js +153 -167
  66. package/dist/src/config/extensions/github.test.js.map +1 -1
  67. package/dist/src/config/extensions/github_fetch.d.ts +1 -1
  68. package/dist/src/config/extensions/github_fetch.js +13 -1
  69. package/dist/src/config/extensions/github_fetch.js.map +1 -1
  70. package/dist/src/config/extensions/github_fetch.test.d.ts +6 -0
  71. package/dist/src/config/extensions/github_fetch.test.js +169 -0
  72. package/dist/src/config/extensions/github_fetch.test.js.map +1 -0
  73. package/dist/src/config/extensions/storage.d.ts +14 -0
  74. package/dist/src/config/extensions/storage.js +32 -0
  75. package/dist/src/config/extensions/storage.js.map +1 -0
  76. package/dist/src/config/extensions/update.d.ts +4 -4
  77. package/dist/src/config/extensions/update.js +39 -39
  78. package/dist/src/config/extensions/update.js.map +1 -1
  79. package/dist/src/config/extensions/update.test.js +72 -74
  80. package/dist/src/config/extensions/update.test.js.map +1 -1
  81. package/dist/src/config/extensions/variableSchema.d.ts +0 -6
  82. package/dist/src/config/extensions/variableSchema.js.map +1 -1
  83. package/dist/src/config/extensions/variables.d.ts +4 -0
  84. package/dist/src/config/extensions/variables.js +6 -0
  85. package/dist/src/config/extensions/variables.js.map +1 -1
  86. package/dist/src/config/keyBindings.d.ts +3 -0
  87. package/dist/src/config/keyBindings.js +30 -8
  88. package/dist/src/config/keyBindings.js.map +1 -1
  89. package/dist/src/config/keyBindings.test.js +17 -0
  90. package/dist/src/config/keyBindings.test.js.map +1 -1
  91. package/dist/src/config/policies/read-only.toml +56 -0
  92. package/dist/src/config/policies/write.toml +63 -0
  93. package/dist/src/config/policies/yolo.toml +31 -0
  94. package/dist/src/config/policy-engine.integration.test.js +41 -38
  95. package/dist/src/config/policy-engine.integration.test.js.map +1 -1
  96. package/dist/src/config/policy.d.ts +2 -2
  97. package/dist/src/config/policy.js +10 -148
  98. package/dist/src/config/policy.js.map +1 -1
  99. package/dist/src/config/sandboxConfig.d.ts +1 -1
  100. package/dist/src/config/sandboxConfig.js +6 -3
  101. package/dist/src/config/sandboxConfig.js.map +1 -1
  102. package/dist/src/config/settings.d.ts +2 -1
  103. package/dist/src/config/settings.js +58 -18
  104. package/dist/src/config/settings.js.map +1 -1
  105. package/dist/src/config/settings.test.js +128 -69
  106. package/dist/src/config/settings.test.js.map +1 -1
  107. package/dist/src/config/settingsSchema.d.ts +170 -28
  108. package/dist/src/config/settingsSchema.js +418 -27
  109. package/dist/src/config/settingsSchema.js.map +1 -1
  110. package/dist/src/config/settingsSchema.test.js +42 -1
  111. package/dist/src/config/settingsSchema.test.js.map +1 -1
  112. package/dist/src/config/trustedFolders.d.ts +1 -1
  113. package/dist/src/config/trustedFolders.js +4 -2
  114. package/dist/src/config/trustedFolders.js.map +1 -1
  115. package/dist/src/core/initializer.js +2 -1
  116. package/dist/src/core/initializer.js.map +1 -1
  117. package/dist/src/gemini.d.ts +1 -1
  118. package/dist/src/gemini.js +46 -16
  119. package/dist/src/gemini.js.map +1 -1
  120. package/dist/src/gemini.test.js +88 -30
  121. package/dist/src/gemini.test.js.map +1 -1
  122. package/dist/src/generated/git-commit.d.ts +2 -2
  123. package/dist/src/generated/git-commit.js +2 -2
  124. package/dist/src/nonInteractiveCli.d.ts +9 -1
  125. package/dist/src/nonInteractiveCli.js +114 -7
  126. package/dist/src/nonInteractiveCli.js.map +1 -1
  127. package/dist/src/nonInteractiveCli.test.js +355 -112
  128. package/dist/src/nonInteractiveCli.test.js.map +1 -1
  129. package/dist/src/services/BuiltinCommandLoader.js +4 -0
  130. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  131. package/dist/src/services/BuiltinCommandLoader.test.js +22 -0
  132. package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
  133. package/dist/src/services/FeedbackService.js +2 -2
  134. package/dist/src/services/FeedbackService.js.map +1 -1
  135. package/dist/src/services/McpPromptLoader.js +2 -2
  136. package/dist/src/services/McpPromptLoader.js.map +1 -1
  137. package/dist/src/services/McpPromptLoader.test.js +4 -2
  138. package/dist/src/services/McpPromptLoader.test.js.map +1 -1
  139. package/dist/src/test-utils/async.d.ts +9 -0
  140. package/dist/src/test-utils/async.js +29 -0
  141. package/dist/src/test-utils/async.js.map +1 -0
  142. package/dist/src/test-utils/createExtension.d.ts +3 -1
  143. package/dist/src/test-utils/createExtension.js +3 -3
  144. package/dist/src/test-utils/createExtension.js.map +1 -1
  145. package/dist/src/test-utils/render.d.ts +16 -2
  146. package/dist/src/test-utils/render.js +66 -4
  147. package/dist/src/test-utils/render.js.map +1 -1
  148. package/dist/src/test-utils/render.test.d.ts +6 -0
  149. package/dist/src/test-utils/render.test.js +79 -0
  150. package/dist/src/test-utils/render.test.js.map +1 -0
  151. package/dist/src/ui/App.test.js +1 -1
  152. package/dist/src/ui/App.test.js.map +1 -1
  153. package/dist/src/ui/AppContainer.js +181 -65
  154. package/dist/src/ui/AppContainer.js.map +1 -1
  155. package/dist/src/ui/AppContainer.test.js +505 -147
  156. package/dist/src/ui/AppContainer.test.js.map +1 -1
  157. package/dist/src/ui/IdeIntegrationNudge.js +1 -1
  158. package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
  159. package/dist/src/ui/auth/ApiAuthDialog.d.ts +14 -0
  160. package/dist/src/ui/auth/ApiAuthDialog.js +26 -0
  161. package/dist/src/ui/auth/ApiAuthDialog.js.map +1 -0
  162. package/dist/src/ui/auth/ApiAuthDialog.test.d.ts +6 -0
  163. package/dist/src/ui/auth/ApiAuthDialog.test.js +91 -0
  164. package/dist/src/ui/auth/ApiAuthDialog.test.js.map +1 -0
  165. package/dist/src/ui/auth/AuthDialog.js +7 -3
  166. package/dist/src/ui/auth/AuthDialog.js.map +1 -1
  167. package/dist/src/ui/auth/useAuth.d.ts +2 -0
  168. package/dist/src/ui/auth/useAuth.js +31 -2
  169. package/dist/src/ui/auth/useAuth.js.map +1 -1
  170. package/dist/src/ui/colors.js +3 -0
  171. package/dist/src/ui/colors.js.map +1 -1
  172. package/dist/src/ui/commands/directoryCommand.js +1 -1
  173. package/dist/src/ui/commands/directoryCommand.js.map +1 -1
  174. package/dist/src/ui/commands/extensionsCommand.js +64 -11
  175. package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
  176. package/dist/src/ui/commands/extensionsCommand.test.js +72 -1
  177. package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -1
  178. package/dist/src/ui/commands/mcpCommand.js +14 -14
  179. package/dist/src/ui/commands/mcpCommand.js.map +1 -1
  180. package/dist/src/ui/commands/mcpCommand.test.js +4 -0
  181. package/dist/src/ui/commands/mcpCommand.test.js.map +1 -1
  182. package/dist/src/ui/commands/memoryCommand.js +1 -1
  183. package/dist/src/ui/commands/memoryCommand.js.map +1 -1
  184. package/dist/src/ui/commands/memoryCommand.test.js +3 -1
  185. package/dist/src/ui/commands/memoryCommand.test.js.map +1 -1
  186. package/dist/src/ui/commands/policiesCommand.d.ts +7 -0
  187. package/dist/src/ui/commands/policiesCommand.js +59 -0
  188. package/dist/src/ui/commands/policiesCommand.js.map +1 -0
  189. package/dist/src/ui/commands/policiesCommand.test.d.ts +6 -0
  190. package/dist/src/ui/commands/policiesCommand.test.js +83 -0
  191. package/dist/src/ui/commands/policiesCommand.test.js.map +1 -0
  192. package/dist/src/ui/components/AnsiOutput.test.js +1 -1
  193. package/dist/src/ui/components/AnsiOutput.test.js.map +1 -1
  194. package/dist/src/ui/components/AsciiArt.d.ts +3 -3
  195. package/dist/src/ui/components/AsciiArt.js +3 -3
  196. package/dist/src/ui/components/Composer.js +1 -1
  197. package/dist/src/ui/components/Composer.js.map +1 -1
  198. package/dist/src/ui/components/Composer.test.js +5 -2
  199. package/dist/src/ui/components/Composer.test.js.map +1 -1
  200. package/dist/src/ui/components/ConfigInitDisplay.js +4 -6
  201. package/dist/src/ui/components/ConfigInitDisplay.js.map +1 -1
  202. package/dist/src/ui/components/ConsentPrompt.test.js +18 -8
  203. package/dist/src/ui/components/ConsentPrompt.test.js.map +1 -1
  204. package/dist/src/ui/components/ConsoleSummaryDisplay.js +1 -1
  205. package/dist/src/ui/components/ConsoleSummaryDisplay.js.map +1 -1
  206. package/dist/src/ui/components/ContextSummaryDisplay.test.js +11 -6
  207. package/dist/src/ui/components/ContextSummaryDisplay.test.js.map +1 -1
  208. package/dist/src/ui/components/DetailedMessagesDisplay.js +1 -1
  209. package/dist/src/ui/components/DetailedMessagesDisplay.js.map +1 -1
  210. package/dist/src/ui/components/DialogManager.js +4 -0
  211. package/dist/src/ui/components/DialogManager.js.map +1 -1
  212. package/dist/src/ui/components/FolderTrustDialog.test.js +2 -1
  213. package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
  214. package/dist/src/ui/components/Footer.js +4 -3
  215. package/dist/src/ui/components/Footer.js.map +1 -1
  216. package/dist/src/ui/components/Footer.test.js +83 -0
  217. package/dist/src/ui/components/Footer.test.js.map +1 -1
  218. package/dist/src/ui/components/Header.test.js +13 -5
  219. package/dist/src/ui/components/Header.test.js.map +1 -1
  220. package/dist/src/ui/components/Help.test.js +5 -4
  221. package/dist/src/ui/components/Help.test.js.map +1 -1
  222. package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
  223. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  224. package/dist/src/ui/components/InputPrompt.js +27 -8
  225. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  226. package/dist/src/ui/components/InputPrompt.test.js +776 -727
  227. package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
  228. package/dist/src/ui/components/LoadingIndicator.js +2 -2
  229. package/dist/src/ui/components/LoadingIndicator.js.map +1 -1
  230. package/dist/src/ui/components/LoadingIndicator.test.js +28 -15
  231. package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -1
  232. package/dist/src/ui/components/LoopDetectionConfirmation.js +1 -1
  233. package/dist/src/ui/components/LoopDetectionConfirmation.js.map +1 -1
  234. package/dist/src/ui/components/LoopDetectionConfirmation.test.js +2 -2
  235. package/dist/src/ui/components/LoopDetectionConfirmation.test.js.map +1 -1
  236. package/dist/src/ui/components/MainContent.js +15 -4
  237. package/dist/src/ui/components/MainContent.js.map +1 -1
  238. package/dist/src/ui/components/ModelDialog.js +1 -1
  239. package/dist/src/ui/components/ModelDialog.js.map +1 -1
  240. package/dist/src/ui/components/ModelDialog.test.js +23 -13
  241. package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
  242. package/dist/src/ui/components/ModelStatsDisplay.test.js +1 -1
  243. package/dist/src/ui/components/ModelStatsDisplay.test.js.map +1 -1
  244. package/dist/src/ui/components/Notifications.js +38 -5
  245. package/dist/src/ui/components/Notifications.js.map +1 -1
  246. package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js +2 -2
  247. package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js.map +1 -1
  248. package/dist/src/ui/components/PrepareLabel.test.js +14 -8
  249. package/dist/src/ui/components/PrepareLabel.test.js.map +1 -1
  250. package/dist/src/ui/components/ProQuotaDialog.test.js +14 -6
  251. package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -1
  252. package/dist/src/ui/components/QueuedMessageDisplay.test.js +11 -6
  253. package/dist/src/ui/components/QueuedMessageDisplay.test.js.map +1 -1
  254. package/dist/src/ui/components/SessionSummaryDisplay.test.js +1 -1
  255. package/dist/src/ui/components/SessionSummaryDisplay.test.js.map +1 -1
  256. package/dist/src/ui/components/SettingsDialog.js +32 -25
  257. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  258. package/dist/src/ui/components/SettingsDialog.test.js +428 -532
  259. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  260. package/dist/src/ui/components/ShellConfirmationDialog.js +1 -1
  261. package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
  262. package/dist/src/ui/components/ShellConfirmationDialog.test.js +2 -2
  263. package/dist/src/ui/components/ShellConfirmationDialog.test.js.map +1 -1
  264. package/dist/src/ui/components/StatsDisplay.test.js +1 -1
  265. package/dist/src/ui/components/StatsDisplay.test.js.map +1 -1
  266. package/dist/src/ui/components/SuggestionsDisplay.js +1 -1
  267. package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
  268. package/dist/src/ui/components/ThemeDialog.test.js +2 -2
  269. package/dist/src/ui/components/ThemeDialog.test.js.map +1 -1
  270. package/dist/src/ui/components/ToolStatsDisplay.test.js +1 -1
  271. package/dist/src/ui/components/ToolStatsDisplay.test.js.map +1 -1
  272. package/dist/src/ui/components/messages/CompressionMessage.test.js +25 -17
  273. package/dist/src/ui/components/messages/CompressionMessage.test.js.map +1 -1
  274. package/dist/src/ui/components/messages/DiffRenderer.test.js +1 -1
  275. package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -1
  276. package/dist/src/ui/components/messages/InfoMessage.js +1 -1
  277. package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
  278. package/dist/src/ui/components/messages/Todo.js +27 -5
  279. package/dist/src/ui/components/messages/Todo.js.map +1 -1
  280. package/dist/src/ui/components/messages/Todo.test.js +20 -8
  281. package/dist/src/ui/components/messages/Todo.test.js.map +1 -1
  282. package/dist/src/ui/components/messages/ToolConfirmationMessage.js +1 -1
  283. package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
  284. package/dist/src/ui/components/messages/ToolGroupMessage.test.js +29 -15
  285. package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
  286. package/dist/src/ui/components/messages/WarningMessage.js +2 -2
  287. package/dist/src/ui/components/messages/WarningMessage.js.map +1 -1
  288. package/dist/src/ui/components/shared/BaseSelectionList.test.js +1 -1
  289. package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -1
  290. package/dist/src/ui/components/shared/MaxSizedBox.test.js +43 -22
  291. package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +1 -1
  292. package/dist/src/ui/components/shared/TextInput.d.ts +15 -0
  293. package/dist/src/ui/components/shared/TextInput.js +38 -0
  294. package/dist/src/ui/components/shared/TextInput.js.map +1 -0
  295. package/dist/src/ui/components/shared/TextInput.test.d.ts +6 -0
  296. package/dist/src/ui/components/shared/TextInput.test.js +242 -0
  297. package/dist/src/ui/components/shared/TextInput.test.js.map +1 -0
  298. package/dist/src/ui/components/shared/text-buffer.d.ts +9 -2
  299. package/dist/src/ui/components/shared/text-buffer.js +51 -13
  300. package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
  301. package/dist/src/ui/components/shared/text-buffer.test.js +385 -202
  302. package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
  303. package/dist/src/ui/components/views/ChatList.test.js +7 -4
  304. package/dist/src/ui/components/views/ChatList.test.js.map +1 -1
  305. package/dist/src/ui/components/views/ExtensionsList.d.ts +7 -1
  306. package/dist/src/ui/components/views/ExtensionsList.js +9 -11
  307. package/dist/src/ui/components/views/ExtensionsList.js.map +1 -1
  308. package/dist/src/ui/components/views/ExtensionsList.test.js +43 -22
  309. package/dist/src/ui/components/views/ExtensionsList.test.js.map +1 -1
  310. package/dist/src/ui/components/views/McpStatus.test.js +23 -12
  311. package/dist/src/ui/components/views/McpStatus.test.js.map +1 -1
  312. package/dist/src/ui/contexts/KeypressContext.d.ts +3 -2
  313. package/dist/src/ui/contexts/KeypressContext.js +610 -540
  314. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  315. package/dist/src/ui/contexts/KeypressContext.test.js +438 -718
  316. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  317. package/dist/src/ui/contexts/MouseContext.d.ts +21 -0
  318. package/dist/src/ui/contexts/MouseContext.js +89 -0
  319. package/dist/src/ui/contexts/MouseContext.js.map +1 -0
  320. package/dist/src/ui/contexts/MouseContext.test.d.ts +6 -0
  321. package/dist/src/ui/contexts/MouseContext.test.js +164 -0
  322. package/dist/src/ui/contexts/MouseContext.test.js.map +1 -0
  323. package/dist/src/ui/contexts/SessionContext.test.js +35 -17
  324. package/dist/src/ui/contexts/SessionContext.test.js.map +1 -1
  325. package/dist/src/ui/contexts/UIActionsContext.d.ts +2 -0
  326. package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
  327. package/dist/src/ui/contexts/UIStateContext.d.ts +2 -0
  328. package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
  329. package/dist/src/ui/hooks/atCommandProcessor.js +31 -9
  330. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  331. package/dist/src/ui/hooks/atCommandProcessor.test.js +163 -64
  332. package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
  333. package/dist/src/ui/hooks/shellCommandProcessor.test.js +64 -35
  334. package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
  335. package/dist/src/ui/hooks/slashCommandProcessor.test.js +193 -165
  336. package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
  337. package/dist/src/ui/hooks/useAtCompletion.test.js +16 -5
  338. package/dist/src/ui/hooks/useAtCompletion.test.js.map +1 -1
  339. package/dist/src/ui/hooks/useAutoAcceptIndicator.js +10 -0
  340. package/dist/src/ui/hooks/useAutoAcceptIndicator.js.map +1 -1
  341. package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +32 -1
  342. package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -1
  343. package/dist/src/ui/hooks/useCommandCompletion.test.js +66 -64
  344. package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
  345. package/dist/src/ui/hooks/useConsoleMessages.test.js +26 -9
  346. package/dist/src/ui/hooks/useConsoleMessages.test.js.map +1 -1
  347. package/dist/src/ui/hooks/useEditorSettings.test.js +40 -34
  348. package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
  349. package/dist/src/ui/hooks/useExtensionUpdates.d.ts +14 -5
  350. package/dist/src/ui/hooks/useExtensionUpdates.js +18 -13
  351. package/dist/src/ui/hooks/useExtensionUpdates.js.map +1 -1
  352. package/dist/src/ui/hooks/useExtensionUpdates.test.js +49 -44
  353. package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -1
  354. package/dist/src/ui/hooks/useFlickerDetector.test.js +9 -5
  355. package/dist/src/ui/hooks/useFlickerDetector.test.js.map +1 -1
  356. package/dist/src/ui/hooks/useFocus.test.js +25 -9
  357. package/dist/src/ui/hooks/useFocus.test.js.map +1 -1
  358. package/dist/src/ui/hooks/useFolderTrust.test.js +46 -22
  359. package/dist/src/ui/hooks/useFolderTrust.test.js.map +1 -1
  360. package/dist/src/ui/hooks/useGeminiStream.js +56 -19
  361. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  362. package/dist/src/ui/hooks/useGeminiStream.test.js +260 -411
  363. package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
  364. package/dist/src/ui/hooks/useGitBranchName.js +4 -0
  365. package/dist/src/ui/hooks/useGitBranchName.js.map +1 -1
  366. package/dist/src/ui/hooks/useGitBranchName.test.js +46 -34
  367. package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
  368. package/dist/src/ui/hooks/useHistoryManager.test.js +2 -1
  369. package/dist/src/ui/hooks/useHistoryManager.test.js.map +1 -1
  370. package/dist/src/ui/hooks/useIdeTrustListener.test.js +40 -9
  371. package/dist/src/ui/hooks/useIdeTrustListener.test.js.map +1 -1
  372. package/dist/src/ui/hooks/useInputHistory.test.js +2 -1
  373. package/dist/src/ui/hooks/useInputHistory.test.js.map +1 -1
  374. package/dist/src/ui/hooks/useInputHistoryStore.test.js +2 -1
  375. package/dist/src/ui/hooks/useInputHistoryStore.test.js.map +1 -1
  376. package/dist/src/ui/hooks/useKeypress.test.js +103 -114
  377. package/dist/src/ui/hooks/useKeypress.test.js.map +1 -1
  378. package/dist/src/ui/hooks/useLoadingIndicator.test.js +24 -6
  379. package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
  380. package/dist/src/ui/hooks/useMemoryMonitor.test.js +10 -5
  381. package/dist/src/ui/hooks/useMemoryMonitor.test.js.map +1 -1
  382. package/dist/src/ui/hooks/useMessageQueue.test.js +62 -45
  383. package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
  384. package/dist/src/ui/hooks/useModelCommand.test.js +21 -11
  385. package/dist/src/ui/hooks/useModelCommand.test.js.map +1 -1
  386. package/dist/src/ui/hooks/useMouse.d.ts +17 -0
  387. package/dist/src/ui/hooks/useMouse.js +27 -0
  388. package/dist/src/ui/hooks/useMouse.js.map +1 -0
  389. package/dist/src/ui/hooks/useMouse.test.d.ts +6 -0
  390. package/dist/src/ui/hooks/useMouse.test.js +57 -0
  391. package/dist/src/ui/hooks/useMouse.test.js.map +1 -0
  392. package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js +2 -2
  393. package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js.map +1 -1
  394. package/dist/src/ui/hooks/usePhraseCycler.js +1 -1
  395. package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
  396. package/dist/src/ui/hooks/usePhraseCycler.test.js +109 -106
  397. package/dist/src/ui/hooks/usePhraseCycler.test.js.map +1 -1
  398. package/dist/src/ui/hooks/usePrivacySettings.test.js +26 -6
  399. package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -1
  400. package/dist/src/ui/hooks/usePromptCompletion.js +2 -2
  401. package/dist/src/ui/hooks/usePromptCompletion.js.map +1 -1
  402. package/dist/src/ui/hooks/useQuotaAndFallback.js +13 -14
  403. package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -1
  404. package/dist/src/ui/hooks/useQuotaAndFallback.test.js +55 -48
  405. package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
  406. package/dist/src/ui/hooks/useReactToolScheduler.d.ts +8 -1
  407. package/dist/src/ui/hooks/useReactToolScheduler.js +59 -34
  408. package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
  409. package/dist/src/ui/hooks/useReactToolScheduler.test.d.ts +6 -0
  410. package/dist/src/ui/hooks/useReactToolScheduler.test.js +65 -0
  411. package/dist/src/ui/hooks/useReactToolScheduler.test.js.map +1 -0
  412. package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +2 -2
  413. package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -1
  414. package/dist/src/ui/hooks/useSelectionList.js +5 -4
  415. package/dist/src/ui/hooks/useSelectionList.js.map +1 -1
  416. package/dist/src/ui/hooks/useSelectionList.test.js +272 -183
  417. package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
  418. package/dist/src/ui/hooks/useShellHistory.test.js +52 -20
  419. package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -1
  420. package/dist/src/ui/hooks/useSlashCompletion.js +18 -7
  421. package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
  422. package/dist/src/ui/hooks/useSlashCompletion.test.js +275 -137
  423. package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
  424. package/dist/src/ui/hooks/useTimer.test.js +43 -14
  425. package/dist/src/ui/hooks/useTimer.test.js.map +1 -1
  426. package/dist/src/ui/hooks/useToolScheduler.test.js +226 -242
  427. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  428. package/dist/src/ui/hooks/vim.test.js +235 -355
  429. package/dist/src/ui/hooks/vim.test.js.map +1 -1
  430. package/dist/src/ui/keyMatchers.test.js +30 -3
  431. package/dist/src/ui/keyMatchers.test.js.map +1 -1
  432. package/dist/src/ui/state/extensions.d.ts +1 -0
  433. package/dist/src/ui/state/extensions.js +1 -0
  434. package/dist/src/ui/state/extensions.js.map +1 -1
  435. package/dist/src/ui/themes/ansi-light.js +1 -0
  436. package/dist/src/ui/themes/ansi-light.js.map +1 -1
  437. package/dist/src/ui/themes/ansi.js +1 -0
  438. package/dist/src/ui/themes/ansi.js.map +1 -1
  439. package/dist/src/ui/themes/atom-one-dark.js +2 -0
  440. package/dist/src/ui/themes/atom-one-dark.js.map +1 -1
  441. package/dist/src/ui/themes/ayu-light.js +2 -0
  442. package/dist/src/ui/themes/ayu-light.js.map +1 -1
  443. package/dist/src/ui/themes/ayu.js +2 -0
  444. package/dist/src/ui/themes/ayu.js.map +1 -1
  445. package/dist/src/ui/themes/color-utils.d.ts +1 -0
  446. package/dist/src/ui/themes/color-utils.js +6 -0
  447. package/dist/src/ui/themes/color-utils.js.map +1 -1
  448. package/dist/src/ui/themes/color-utils.test.js +13 -1
  449. package/dist/src/ui/themes/color-utils.test.js.map +1 -1
  450. package/dist/src/ui/themes/dracula.js +2 -0
  451. package/dist/src/ui/themes/dracula.js.map +1 -1
  452. package/dist/src/ui/themes/github-dark.js +2 -0
  453. package/dist/src/ui/themes/github-dark.js.map +1 -1
  454. package/dist/src/ui/themes/github-light.js +2 -0
  455. package/dist/src/ui/themes/github-light.js.map +1 -1
  456. package/dist/src/ui/themes/googlecode.js +2 -0
  457. package/dist/src/ui/themes/googlecode.js.map +1 -1
  458. package/dist/src/ui/themes/no-color.js +3 -0
  459. package/dist/src/ui/themes/no-color.js.map +1 -1
  460. package/dist/src/ui/themes/semantic-tokens.d.ts +2 -0
  461. package/dist/src/ui/themes/semantic-tokens.js +6 -0
  462. package/dist/src/ui/themes/semantic-tokens.js.map +1 -1
  463. package/dist/src/ui/themes/shades-of-purple.js +2 -0
  464. package/dist/src/ui/themes/shades-of-purple.js.map +1 -1
  465. package/dist/src/ui/themes/theme.d.ts +3 -0
  466. package/dist/src/ui/themes/theme.js +14 -3
  467. package/dist/src/ui/themes/theme.js.map +1 -1
  468. package/dist/src/ui/themes/theme.test.js +67 -1
  469. package/dist/src/ui/themes/theme.test.js.map +1 -1
  470. package/dist/src/ui/themes/xcode.js +2 -0
  471. package/dist/src/ui/themes/xcode.js.map +1 -1
  472. package/dist/src/ui/types.d.ts +3 -1
  473. package/dist/src/ui/types.js +2 -0
  474. package/dist/src/ui/types.js.map +1 -1
  475. package/dist/src/ui/utils/CodeColorizer.js +2 -1
  476. package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
  477. package/dist/src/ui/utils/InlineMarkdownRenderer.d.ts +1 -0
  478. package/dist/src/ui/utils/InlineMarkdownRenderer.js +11 -10
  479. package/dist/src/ui/utils/InlineMarkdownRenderer.js.map +1 -1
  480. package/dist/src/ui/utils/MarkdownDisplay.js +11 -9
  481. package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
  482. package/dist/src/ui/utils/clipboardUtils.js +2 -2
  483. package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
  484. package/dist/src/ui/utils/input.d.ts +17 -0
  485. package/dist/src/ui/utils/input.js +51 -0
  486. package/dist/src/ui/utils/input.js.map +1 -0
  487. package/dist/src/ui/utils/input.test.d.ts +6 -0
  488. package/dist/src/ui/utils/input.test.js +44 -0
  489. package/dist/src/ui/utils/input.test.js.map +1 -0
  490. package/dist/src/ui/utils/kittyProtocolDetector.js +13 -4
  491. package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -1
  492. package/dist/src/ui/utils/mouse.d.ts +31 -0
  493. package/dist/src/ui/utils/mouse.js +164 -0
  494. package/dist/src/ui/utils/mouse.js.map +1 -0
  495. package/dist/src/ui/utils/mouse.test.d.ts +6 -0
  496. package/dist/src/ui/utils/mouse.test.js +131 -0
  497. package/dist/src/ui/utils/mouse.test.js.map +1 -0
  498. package/dist/src/ui/utils/textOutput.d.ts +25 -0
  499. package/dist/src/ui/utils/textOutput.js +49 -0
  500. package/dist/src/ui/utils/textOutput.js.map +1 -0
  501. package/dist/src/ui/utils/textOutput.test.d.ts +6 -0
  502. package/dist/src/ui/utils/textOutput.test.js +79 -0
  503. package/dist/src/ui/utils/textOutput.test.js.map +1 -0
  504. package/dist/src/ui/utils/updateCheck.d.ts +7 -1
  505. package/dist/src/ui/utils/updateCheck.js +33 -29
  506. package/dist/src/ui/utils/updateCheck.js.map +1 -1
  507. package/dist/src/ui/utils/updateCheck.test.js +24 -50
  508. package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
  509. package/dist/src/utils/commentJson.js +2 -2
  510. package/dist/src/utils/commentJson.js.map +1 -1
  511. package/dist/src/utils/commentJson.test.js +7 -6
  512. package/dist/src/utils/commentJson.test.js.map +1 -1
  513. package/dist/src/utils/envVarResolver.d.ts +2 -2
  514. package/dist/src/utils/envVarResolver.js +10 -7
  515. package/dist/src/utils/envVarResolver.js.map +1 -1
  516. package/dist/src/utils/events.d.ts +11 -2
  517. package/dist/src/utils/events.js +1 -0
  518. package/dist/src/utils/events.js.map +1 -1
  519. package/dist/src/utils/handleAutoUpdate.js +9 -3
  520. package/dist/src/utils/handleAutoUpdate.js.map +1 -1
  521. package/dist/src/utils/sandbox.js +16 -18
  522. package/dist/src/utils/sandbox.js.map +1 -1
  523. package/dist/src/utils/version.js +6 -2
  524. package/dist/src/utils/version.js.map +1 -1
  525. package/dist/src/zed-integration/acp.js +2 -1
  526. package/dist/src/zed-integration/acp.js.map +1 -1
  527. package/dist/src/zed-integration/schema.d.ts +4 -4
  528. package/dist/src/zed-integration/zedIntegration.d.ts +2 -2
  529. package/dist/src/zed-integration/zedIntegration.js +12 -19
  530. package/dist/src/zed-integration/zedIntegration.js.map +1 -1
  531. package/dist/tsconfig.tsbuildinfo +1 -1
  532. package/package.json +14 -14
  533. package/dist/src/config/policy.test.js +0 -360
  534. package/dist/src/config/policy.test.js.map +0 -1
  535. package/dist/src/utils/package.d.ts +0 -12
  536. package/dist/src/utils/package.js +0 -24
  537. package/dist/src/utils/package.js.map +0 -1
  538. /package/dist/src/{config/policy.test.d.ts → commands/extensions/validate.test.d.ts} +0 -0
@@ -3,11 +3,17 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { executeToolCall, ToolErrorType, shutdownTelemetry, GeminiEventType, OutputFormat, uiTelemetryService, FatalInputError, } from '@google/gemini-cli-core';
6
+ import { executeToolCall, ToolErrorType, shutdownTelemetry, GeminiEventType, OutputFormat, uiTelemetryService, FatalInputError, CoreEvent, } from '@google/gemini-cli-core';
7
7
  import { runNonInteractive } from './nonInteractiveCli.js';
8
- import { vi } from 'vitest';
8
+ import { describe, it, expect, beforeEach, afterEach, vi, } from 'vitest';
9
9
  // Mock core modules
10
10
  vi.mock('./ui/hooks/atCommandProcessor.js');
11
+ const mockCoreEvents = vi.hoisted(() => ({
12
+ on: vi.fn(),
13
+ off: vi.fn(),
14
+ drainFeedbackBacklog: vi.fn(),
15
+ emit: vi.fn(),
16
+ }));
11
17
  vi.mock('@google/gemini-cli-core', async (importOriginal) => {
12
18
  const original = await importOriginal();
13
19
  class MockChatRecordingService {
@@ -25,6 +31,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
25
31
  uiTelemetryService: {
26
32
  getMetrics: vi.fn(),
27
33
  },
34
+ coreEvents: mockCoreEvents,
28
35
  };
29
36
  });
30
37
  const mockGetCommands = vi.hoisted(() => vi.fn());
@@ -44,7 +51,28 @@ describe('runNonInteractive', () => {
44
51
  let mockShutdownTelemetry;
45
52
  let consoleErrorSpy;
46
53
  let processStdoutSpy;
54
+ let processStderrSpy;
47
55
  let mockGeminiClient;
56
+ const MOCK_SESSION_METRICS = {
57
+ models: {},
58
+ tools: {
59
+ totalCalls: 0,
60
+ totalSuccess: 0,
61
+ totalFail: 0,
62
+ totalDurationMs: 0,
63
+ totalDecisions: {
64
+ accept: 0,
65
+ reject: 0,
66
+ modify: 0,
67
+ auto_accept: 0,
68
+ },
69
+ byName: {},
70
+ },
71
+ files: {
72
+ totalLinesAdded: 0,
73
+ totalLinesRemoved: 0,
74
+ },
75
+ };
48
76
  beforeEach(async () => {
49
77
  mockCoreExecuteToolCall = vi.mocked(executeToolCall);
50
78
  mockShutdownTelemetry = vi.mocked(shutdownTelemetry);
@@ -55,6 +83,9 @@ describe('runNonInteractive', () => {
55
83
  processStdoutSpy = vi
56
84
  .spyOn(process.stdout, 'write')
57
85
  .mockImplementation(() => true);
86
+ processStderrSpy = vi
87
+ .spyOn(process.stderr, 'write')
88
+ .mockImplementation(() => true);
58
89
  vi.spyOn(process, 'exit').mockImplementation((code) => {
59
90
  throw new Error(`process.exit(${code}) called`);
60
91
  });
@@ -123,6 +154,7 @@ describe('runNonInteractive', () => {
123
154
  yield event;
124
155
  }
125
156
  }
157
+ const getWrittenOutput = () => processStdoutSpy.mock.calls.map((c) => c[0]).join('');
126
158
  it('should process input and write text output', async () => {
127
159
  const events = [
128
160
  { type: GeminiEventType.Content, value: 'Hello' },
@@ -133,11 +165,14 @@ describe('runNonInteractive', () => {
133
165
  },
134
166
  ];
135
167
  mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
136
- await runNonInteractive(mockConfig, mockSettings, 'Test input', 'prompt-id-1');
168
+ await runNonInteractive({
169
+ config: mockConfig,
170
+ settings: mockSettings,
171
+ input: 'Test input',
172
+ prompt_id: 'prompt-id-1',
173
+ });
137
174
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: 'Test input' }], expect.any(AbortSignal), 'prompt-id-1');
138
- expect(processStdoutSpy).toHaveBeenCalledWith('Hello');
139
- expect(processStdoutSpy).toHaveBeenCalledWith(' World');
140
- expect(processStdoutSpy).toHaveBeenCalledWith('\n');
175
+ expect(getWrittenOutput()).toBe('Hello World\n');
141
176
  expect(mockShutdownTelemetry).toHaveBeenCalled();
142
177
  });
143
178
  it('should handle a single tool call and respond', async () => {
@@ -182,12 +217,78 @@ describe('runNonInteractive', () => {
182
217
  mockGeminiClient.sendMessageStream
183
218
  .mockReturnValueOnce(createStreamFromEvents(firstCallEvents))
184
219
  .mockReturnValueOnce(createStreamFromEvents(secondCallEvents));
185
- await runNonInteractive(mockConfig, mockSettings, 'Use a tool', 'prompt-id-2');
220
+ await runNonInteractive({
221
+ config: mockConfig,
222
+ settings: mockSettings,
223
+ input: 'Use a tool',
224
+ prompt_id: 'prompt-id-2',
225
+ });
186
226
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
187
227
  expect(mockCoreExecuteToolCall).toHaveBeenCalledWith(mockConfig, expect.objectContaining({ name: 'testTool' }), expect.any(AbortSignal));
188
228
  expect(mockGeminiClient.sendMessageStream).toHaveBeenNthCalledWith(2, [{ text: 'Tool response' }], expect.any(AbortSignal), 'prompt-id-2');
189
- expect(processStdoutSpy).toHaveBeenCalledWith('Final answer');
190
- expect(processStdoutSpy).toHaveBeenCalledWith('\n');
229
+ expect(getWrittenOutput()).toBe('Final answer\n');
230
+ });
231
+ it('should write a single newline between sequential text outputs from the model', async () => {
232
+ // This test simulates a multi-turn conversation to ensure that a single newline
233
+ // is printed between each block of text output from the model.
234
+ // 1. Define the tool requests that the model will ask the CLI to run.
235
+ const toolCallEvent = {
236
+ type: GeminiEventType.ToolCallRequest,
237
+ value: {
238
+ callId: 'mock-tool',
239
+ name: 'mockTool',
240
+ args: {},
241
+ isClientInitiated: false,
242
+ prompt_id: 'prompt-id-multi',
243
+ },
244
+ };
245
+ // 2. Mock the execution of the tools. We just need them to succeed.
246
+ mockCoreExecuteToolCall.mockResolvedValue({
247
+ status: 'success',
248
+ request: toolCallEvent.value, // This is generic enough for both calls
249
+ tool: {},
250
+ invocation: {},
251
+ response: {
252
+ responseParts: [],
253
+ callId: 'mock-tool',
254
+ },
255
+ });
256
+ // 3. Define the sequence of events streamed from the mock model.
257
+ // Turn 1: Model outputs text, then requests a tool call.
258
+ const modelTurn1 = [
259
+ { type: GeminiEventType.Content, value: 'Use mock tool' },
260
+ toolCallEvent,
261
+ ];
262
+ // Turn 2: Model outputs more text, then requests another tool call.
263
+ const modelTurn2 = [
264
+ { type: GeminiEventType.Content, value: 'Use mock tool again' },
265
+ toolCallEvent,
266
+ ];
267
+ // Turn 3: Model outputs a final answer.
268
+ const modelTurn3 = [
269
+ { type: GeminiEventType.Content, value: 'Finished.' },
270
+ {
271
+ type: GeminiEventType.Finished,
272
+ value: { reason: undefined, usageMetadata: { totalTokenCount: 10 } },
273
+ },
274
+ ];
275
+ mockGeminiClient.sendMessageStream
276
+ .mockReturnValueOnce(createStreamFromEvents(modelTurn1))
277
+ .mockReturnValueOnce(createStreamFromEvents(modelTurn2))
278
+ .mockReturnValueOnce(createStreamFromEvents(modelTurn3));
279
+ // 4. Run the command.
280
+ await runNonInteractive({
281
+ config: mockConfig,
282
+ settings: mockSettings,
283
+ input: 'Use mock tool multiple times',
284
+ prompt_id: 'prompt-id-multi',
285
+ });
286
+ // 5. Verify the output.
287
+ // The rendered output should contain the text from each turn, separated by a
288
+ // single newline, with a final newline at the end.
289
+ expect(getWrittenOutput()).toMatchSnapshot();
290
+ // Also verify the tools were called as expected.
291
+ expect(mockCoreExecuteToolCall).toHaveBeenCalledTimes(2);
191
292
  });
192
293
  it('should handle error during tool execution and should send error back to the model', async () => {
193
294
  const toolCallEvent = {
@@ -241,7 +342,12 @@ describe('runNonInteractive', () => {
241
342
  mockGeminiClient.sendMessageStream
242
343
  .mockReturnValueOnce(createStreamFromEvents([toolCallEvent]))
243
344
  .mockReturnValueOnce(createStreamFromEvents(finalResponse));
244
- await runNonInteractive(mockConfig, mockSettings, 'Trigger tool error', 'prompt-id-3');
345
+ await runNonInteractive({
346
+ config: mockConfig,
347
+ settings: mockSettings,
348
+ input: 'Trigger tool error',
349
+ prompt_id: 'prompt-id-3',
350
+ });
245
351
  expect(mockCoreExecuteToolCall).toHaveBeenCalled();
246
352
  expect(consoleErrorSpy).toHaveBeenCalledWith('Error executing tool errorTool: Execution failed');
247
353
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
@@ -255,14 +361,19 @@ describe('runNonInteractive', () => {
255
361
  },
256
362
  },
257
363
  ], expect.any(AbortSignal), 'prompt-id-3');
258
- expect(processStdoutSpy).toHaveBeenCalledWith('Sorry, let me try again.');
364
+ expect(getWrittenOutput()).toBe('Sorry, let me try again.\n');
259
365
  });
260
366
  it('should exit with error if sendMessageStream throws initially', async () => {
261
367
  const apiError = new Error('API connection failed');
262
368
  mockGeminiClient.sendMessageStream.mockImplementation(() => {
263
369
  throw apiError;
264
370
  });
265
- await expect(runNonInteractive(mockConfig, mockSettings, 'Initial fail', 'prompt-id-4')).rejects.toThrow(apiError);
371
+ await expect(runNonInteractive({
372
+ config: mockConfig,
373
+ settings: mockSettings,
374
+ input: 'Initial fail',
375
+ prompt_id: 'prompt-id-4',
376
+ })).rejects.toThrow(apiError);
266
377
  });
267
378
  it('should not exit if a tool is not found, and should send error back to model', async () => {
268
379
  const toolCallEvent = {
@@ -306,15 +417,25 @@ describe('runNonInteractive', () => {
306
417
  mockGeminiClient.sendMessageStream
307
418
  .mockReturnValueOnce(createStreamFromEvents([toolCallEvent]))
308
419
  .mockReturnValueOnce(createStreamFromEvents(finalResponse));
309
- await runNonInteractive(mockConfig, mockSettings, 'Trigger tool not found', 'prompt-id-5');
420
+ await runNonInteractive({
421
+ config: mockConfig,
422
+ settings: mockSettings,
423
+ input: 'Trigger tool not found',
424
+ prompt_id: 'prompt-id-5',
425
+ });
310
426
  expect(mockCoreExecuteToolCall).toHaveBeenCalled();
311
427
  expect(consoleErrorSpy).toHaveBeenCalledWith('Error executing tool nonexistentTool: Tool "nonexistentTool" not found in registry.');
312
428
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
313
- expect(processStdoutSpy).toHaveBeenCalledWith("Sorry, I can't find that tool.");
429
+ expect(getWrittenOutput()).toBe("Sorry, I can't find that tool.\n");
314
430
  });
315
431
  it('should exit when max session turns are exceeded', async () => {
316
432
  vi.mocked(mockConfig.getMaxSessionTurns).mockReturnValue(0);
317
- await expect(runNonInteractive(mockConfig, mockSettings, 'Trigger loop', 'prompt-id-6')).rejects.toThrow('process.exit(53) called');
433
+ await expect(runNonInteractive({
434
+ config: mockConfig,
435
+ settings: mockSettings,
436
+ input: 'Trigger loop',
437
+ prompt_id: 'prompt-id-6',
438
+ })).rejects.toThrow('process.exit(53) called');
318
439
  });
319
440
  it('should preprocess @include commands before sending to the model', async () => {
320
441
  // 1. Mock the imported atCommandProcessor
@@ -343,11 +464,16 @@ describe('runNonInteractive', () => {
343
464
  ];
344
465
  mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
345
466
  // 4. Run the non-interactive mode with the raw input
346
- await runNonInteractive(mockConfig, mockSettings, rawInput, 'prompt-id-7');
467
+ await runNonInteractive({
468
+ config: mockConfig,
469
+ settings: mockSettings,
470
+ input: rawInput,
471
+ prompt_id: 'prompt-id-7',
472
+ });
347
473
  // 5. Assert that sendMessageStream was called with the PROCESSED parts, not the raw input
348
474
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(processedParts, expect.any(AbortSignal), 'prompt-id-7');
349
475
  // 6. Assert the final output is correct
350
- expect(processStdoutSpy).toHaveBeenCalledWith('Summary complete.');
476
+ expect(getWrittenOutput()).toBe('Summary complete.\n');
351
477
  });
352
478
  it('should process input and write JSON output with stats', async () => {
353
479
  const events = [
@@ -359,30 +485,15 @@ describe('runNonInteractive', () => {
359
485
  ];
360
486
  mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
361
487
  vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
362
- const mockMetrics = {
363
- models: {},
364
- tools: {
365
- totalCalls: 0,
366
- totalSuccess: 0,
367
- totalFail: 0,
368
- totalDurationMs: 0,
369
- totalDecisions: {
370
- accept: 0,
371
- reject: 0,
372
- modify: 0,
373
- auto_accept: 0,
374
- },
375
- byName: {},
376
- },
377
- files: {
378
- totalLinesAdded: 0,
379
- totalLinesRemoved: 0,
380
- },
381
- };
382
- vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(mockMetrics);
383
- await runNonInteractive(mockConfig, mockSettings, 'Test input', 'prompt-id-1');
488
+ vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(MOCK_SESSION_METRICS);
489
+ await runNonInteractive({
490
+ config: mockConfig,
491
+ settings: mockSettings,
492
+ input: 'Test input',
493
+ prompt_id: 'prompt-id-1',
494
+ });
384
495
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: 'Test input' }], expect.any(AbortSignal), 'prompt-id-1');
385
- expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: 'Hello World', stats: mockMetrics }, null, 2));
496
+ expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: 'Hello World', stats: MOCK_SESSION_METRICS }, null, 2));
386
497
  });
387
498
  it('should write JSON output with stats for tool-only commands (no text response)', async () => {
388
499
  // Test the scenario where a command completes successfully with only tool calls
@@ -436,45 +547,17 @@ describe('runNonInteractive', () => {
436
547
  .mockReturnValueOnce(createStreamFromEvents(firstCallEvents))
437
548
  .mockReturnValueOnce(createStreamFromEvents(secondCallEvents));
438
549
  vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
439
- const mockMetrics = {
440
- models: {},
441
- tools: {
442
- totalCalls: 1,
443
- totalSuccess: 1,
444
- totalFail: 0,
445
- totalDurationMs: 100,
446
- totalDecisions: {
447
- accept: 1,
448
- reject: 0,
449
- modify: 0,
450
- auto_accept: 0,
451
- },
452
- byName: {
453
- testTool: {
454
- count: 1,
455
- success: 1,
456
- fail: 0,
457
- durationMs: 100,
458
- decisions: {
459
- accept: 1,
460
- reject: 0,
461
- modify: 0,
462
- auto_accept: 0,
463
- },
464
- },
465
- },
466
- },
467
- files: {
468
- totalLinesAdded: 0,
469
- totalLinesRemoved: 0,
470
- },
471
- };
472
- vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(mockMetrics);
473
- await runNonInteractive(mockConfig, mockSettings, 'Execute tool only', 'prompt-id-tool-only');
550
+ vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(MOCK_SESSION_METRICS);
551
+ await runNonInteractive({
552
+ config: mockConfig,
553
+ settings: mockSettings,
554
+ input: 'Execute tool only',
555
+ prompt_id: 'prompt-id-tool-only',
556
+ });
474
557
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
475
558
  expect(mockCoreExecuteToolCall).toHaveBeenCalledWith(mockConfig, expect.objectContaining({ name: 'testTool' }), expect.any(AbortSignal));
476
559
  // This should output JSON with empty response but include stats
477
- expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: '', stats: mockMetrics }, null, 2));
560
+ expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: '', stats: MOCK_SESSION_METRICS }, null, 2));
478
561
  });
479
562
  it('should write JSON output with stats for empty response commands', async () => {
480
563
  // Test the scenario where a command completes but produces no content at all
@@ -486,31 +569,16 @@ describe('runNonInteractive', () => {
486
569
  ];
487
570
  mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
488
571
  vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
489
- const mockMetrics = {
490
- models: {},
491
- tools: {
492
- totalCalls: 0,
493
- totalSuccess: 0,
494
- totalFail: 0,
495
- totalDurationMs: 0,
496
- totalDecisions: {
497
- accept: 0,
498
- reject: 0,
499
- modify: 0,
500
- auto_accept: 0,
501
- },
502
- byName: {},
503
- },
504
- files: {
505
- totalLinesAdded: 0,
506
- totalLinesRemoved: 0,
507
- },
508
- };
509
- vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(mockMetrics);
510
- await runNonInteractive(mockConfig, mockSettings, 'Empty response test', 'prompt-id-empty');
572
+ vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(MOCK_SESSION_METRICS);
573
+ await runNonInteractive({
574
+ config: mockConfig,
575
+ settings: mockSettings,
576
+ input: 'Empty response test',
577
+ prompt_id: 'prompt-id-empty',
578
+ });
511
579
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: 'Empty response test' }], expect.any(AbortSignal), 'prompt-id-empty');
512
580
  // This should output JSON with empty response but include stats
513
- expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: '', stats: mockMetrics }, null, 2));
581
+ expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: '', stats: MOCK_SESSION_METRICS }, null, 2));
514
582
  });
515
583
  it('should handle errors in JSON format', async () => {
516
584
  vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
@@ -524,7 +592,12 @@ describe('runNonInteractive', () => {
524
592
  .mockImplementation(() => { });
525
593
  let thrownError = null;
526
594
  try {
527
- await runNonInteractive(mockConfig, mockSettings, 'Test input', 'prompt-id-error');
595
+ await runNonInteractive({
596
+ config: mockConfig,
597
+ settings: mockSettings,
598
+ input: 'Test input',
599
+ prompt_id: 'prompt-id-error',
600
+ });
528
601
  // Should not reach here
529
602
  expect.fail('Expected process.exit to be called');
530
603
  }
@@ -553,7 +626,12 @@ describe('runNonInteractive', () => {
553
626
  .mockImplementation(() => { });
554
627
  let thrownError = null;
555
628
  try {
556
- await runNonInteractive(mockConfig, mockSettings, 'Invalid syntax', 'prompt-id-fatal');
629
+ await runNonInteractive({
630
+ config: mockConfig,
631
+ settings: mockSettings,
632
+ input: 'Invalid syntax',
633
+ prompt_id: 'prompt-id-fatal',
634
+ });
557
635
  // Should not reach here
558
636
  expect.fail('Expected process.exit to be called');
559
637
  }
@@ -588,10 +666,15 @@ describe('runNonInteractive', () => {
588
666
  },
589
667
  ];
590
668
  mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
591
- await runNonInteractive(mockConfig, mockSettings, '/testcommand', 'prompt-id-slash');
669
+ await runNonInteractive({
670
+ config: mockConfig,
671
+ settings: mockSettings,
672
+ input: '/testcommand',
673
+ prompt_id: 'prompt-id-slash',
674
+ });
592
675
  // Ensure the prompt sent to the model is from the command, not the raw input
593
676
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: 'Prompt from command' }], expect.any(AbortSignal), 'prompt-id-slash');
594
- expect(processStdoutSpy).toHaveBeenCalledWith('Response from command');
677
+ expect(getWrittenOutput()).toBe('Response from command\n');
595
678
  });
596
679
  it('should throw FatalInputError if a command requires confirmation', async () => {
597
680
  const mockCommand = {
@@ -603,7 +686,12 @@ describe('runNonInteractive', () => {
603
686
  }),
604
687
  };
605
688
  mockGetCommands.mockReturnValue([mockCommand]);
606
- await expect(runNonInteractive(mockConfig, mockSettings, '/confirm', 'prompt-id-confirm')).rejects.toThrow('Exiting due to a confirmation prompt requested by the command.');
689
+ await expect(runNonInteractive({
690
+ config: mockConfig,
691
+ settings: mockSettings,
692
+ input: '/confirm',
693
+ prompt_id: 'prompt-id-confirm',
694
+ })).rejects.toThrow('Exiting due to a confirmation prompt requested by the command.');
607
695
  });
608
696
  it('should treat an unknown slash command as a regular prompt', async () => {
609
697
  // No commands are mocked, so any slash command is "unknown"
@@ -616,10 +704,15 @@ describe('runNonInteractive', () => {
616
704
  },
617
705
  ];
618
706
  mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
619
- await runNonInteractive(mockConfig, mockSettings, '/unknowncommand', 'prompt-id-unknown');
707
+ await runNonInteractive({
708
+ config: mockConfig,
709
+ settings: mockSettings,
710
+ input: '/unknowncommand',
711
+ prompt_id: 'prompt-id-unknown',
712
+ });
620
713
  // Ensure the raw input is sent to the model
621
714
  expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: '/unknowncommand' }], expect.any(AbortSignal), 'prompt-id-unknown');
622
- expect(processStdoutSpy).toHaveBeenCalledWith('Response to unknown');
715
+ expect(getWrittenOutput()).toBe('Response to unknown\n');
623
716
  });
624
717
  it('should throw for unhandled command result types', async () => {
625
718
  const mockCommand = {
@@ -630,7 +723,12 @@ describe('runNonInteractive', () => {
630
723
  }),
631
724
  };
632
725
  mockGetCommands.mockReturnValue([mockCommand]);
633
- await expect(runNonInteractive(mockConfig, mockSettings, '/noaction', 'prompt-id-unhandled')).rejects.toThrow('Exiting due to command result that is not supported in non-interactive mode.');
726
+ await expect(runNonInteractive({
727
+ config: mockConfig,
728
+ settings: mockSettings,
729
+ input: '/noaction',
730
+ prompt_id: 'prompt-id-unhandled',
731
+ })).rejects.toThrow('Exiting due to command result that is not supported in non-interactive mode.');
634
732
  });
635
733
  it('should pass arguments to the slash command action', async () => {
636
734
  const mockAction = vi.fn().mockResolvedValue({
@@ -651,9 +749,14 @@ describe('runNonInteractive', () => {
651
749
  },
652
750
  ];
653
751
  mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
654
- await runNonInteractive(mockConfig, mockSettings, '/testargs arg1 arg2', 'prompt-id-args');
752
+ await runNonInteractive({
753
+ config: mockConfig,
754
+ settings: mockSettings,
755
+ input: '/testargs arg1 arg2',
756
+ prompt_id: 'prompt-id-args',
757
+ });
655
758
  expect(mockAction).toHaveBeenCalledWith(expect.any(Object), 'arg1 arg2');
656
- expect(processStdoutSpy).toHaveBeenCalledWith('Acknowledged');
759
+ expect(getWrittenOutput()).toBe('Acknowledged\n');
657
760
  });
658
761
  it('should instantiate CommandService with correct loaders for slash commands', async () => {
659
762
  // This test indirectly checks that handleSlashCommand is using the right loaders.
@@ -668,7 +771,12 @@ describe('runNonInteractive', () => {
668
771
  },
669
772
  ];
670
773
  mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
671
- await runNonInteractive(mockConfig, mockSettings, '/mycommand', 'prompt-id-loaders');
774
+ await runNonInteractive({
775
+ config: mockConfig,
776
+ settings: mockSettings,
777
+ input: '/mycommand',
778
+ prompt_id: 'prompt-id-loaders',
779
+ });
672
780
  // Check that loaders were instantiated with the config
673
781
  expect(FileCommandLoader).toHaveBeenCalledTimes(1);
674
782
  expect(FileCommandLoader).toHaveBeenCalledWith(mockConfig);
@@ -733,9 +841,144 @@ describe('runNonInteractive', () => {
733
841
  mockGeminiClient.sendMessageStream
734
842
  .mockReturnValueOnce(createStreamFromEvents(firstCallEvents))
735
843
  .mockReturnValueOnce(createStreamFromEvents(secondCallEvents));
736
- await runNonInteractive(mockConfig, mockSettings, 'List the files', 'prompt-id-allowed');
844
+ await runNonInteractive({
845
+ config: mockConfig,
846
+ settings: mockSettings,
847
+ input: 'List the files',
848
+ prompt_id: 'prompt-id-allowed',
849
+ });
737
850
  expect(mockCoreExecuteToolCall).toHaveBeenCalledWith(mockConfig, expect.objectContaining({ name: 'ShellTool' }), expect.any(AbortSignal));
738
- expect(processStdoutSpy).toHaveBeenCalledWith('file.txt');
851
+ expect(getWrittenOutput()).toBe('file.txt\n');
852
+ });
853
+ describe('CoreEvents Integration', () => {
854
+ it('subscribes to UserFeedback and drains backlog on start', async () => {
855
+ const events = [
856
+ {
857
+ type: GeminiEventType.Finished,
858
+ value: { reason: undefined, usageMetadata: { totalTokenCount: 0 } },
859
+ },
860
+ ];
861
+ mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
862
+ await runNonInteractive({
863
+ config: mockConfig,
864
+ settings: mockSettings,
865
+ input: 'test',
866
+ prompt_id: 'prompt-id-events',
867
+ });
868
+ expect(mockCoreEvents.on).toHaveBeenCalledWith(CoreEvent.UserFeedback, expect.any(Function));
869
+ expect(mockCoreEvents.drainFeedbackBacklog).toHaveBeenCalledTimes(1);
870
+ });
871
+ it('unsubscribes from UserFeedback on finish', async () => {
872
+ const events = [
873
+ {
874
+ type: GeminiEventType.Finished,
875
+ value: { reason: undefined, usageMetadata: { totalTokenCount: 0 } },
876
+ },
877
+ ];
878
+ mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
879
+ await runNonInteractive({
880
+ config: mockConfig,
881
+ settings: mockSettings,
882
+ input: 'test',
883
+ prompt_id: 'prompt-id-events',
884
+ });
885
+ expect(mockCoreEvents.off).toHaveBeenCalledWith(CoreEvent.UserFeedback, expect.any(Function));
886
+ });
887
+ it('logs to process.stderr when UserFeedback event is received', async () => {
888
+ const events = [
889
+ {
890
+ type: GeminiEventType.Finished,
891
+ value: { reason: undefined, usageMetadata: { totalTokenCount: 0 } },
892
+ },
893
+ ];
894
+ mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
895
+ await runNonInteractive({
896
+ config: mockConfig,
897
+ settings: mockSettings,
898
+ input: 'test',
899
+ prompt_id: 'prompt-id-events',
900
+ });
901
+ // Get the registered handler
902
+ const handler = mockCoreEvents.on.mock.calls.find((call) => call[0] === CoreEvent.UserFeedback)?.[1];
903
+ expect(handler).toBeDefined();
904
+ // Simulate an event
905
+ const payload = {
906
+ severity: 'error',
907
+ message: 'Test error message',
908
+ };
909
+ handler(payload);
910
+ expect(processStderrSpy).toHaveBeenCalledWith('[ERROR] Test error message\n');
911
+ });
912
+ it('logs optional error object to process.stderr in debug mode', async () => {
913
+ vi.mocked(mockConfig.getDebugMode).mockReturnValue(true);
914
+ const events = [
915
+ {
916
+ type: GeminiEventType.Finished,
917
+ value: { reason: undefined, usageMetadata: { totalTokenCount: 0 } },
918
+ },
919
+ ];
920
+ mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
921
+ await runNonInteractive({
922
+ config: mockConfig,
923
+ settings: mockSettings,
924
+ input: 'test',
925
+ prompt_id: 'prompt-id-events',
926
+ });
927
+ // Get the registered handler
928
+ const handler = mockCoreEvents.on.mock.calls.find((call) => call[0] === CoreEvent.UserFeedback)?.[1];
929
+ expect(handler).toBeDefined();
930
+ // Simulate an event with error object
931
+ const errorObj = new Error('Original error');
932
+ // Mock stack for deterministic testing
933
+ errorObj.stack = 'Error: Original error\n at test';
934
+ const payload = {
935
+ severity: 'warning',
936
+ message: 'Test warning message',
937
+ error: errorObj,
938
+ };
939
+ handler(payload);
940
+ expect(processStderrSpy).toHaveBeenCalledWith('[WARNING] Test warning message\n');
941
+ expect(processStderrSpy).toHaveBeenCalledWith('Error: Original error\n at test\n');
942
+ });
943
+ });
944
+ it('should display a deprecation warning if hasDeprecatedPromptArg is true', async () => {
945
+ const events = [
946
+ { type: GeminiEventType.Content, value: 'Final Answer' },
947
+ {
948
+ type: GeminiEventType.Finished,
949
+ value: { reason: undefined, usageMetadata: { totalTokenCount: 10 } },
950
+ },
951
+ ];
952
+ mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
953
+ await runNonInteractive({
954
+ config: mockConfig,
955
+ settings: mockSettings,
956
+ input: 'Test input',
957
+ prompt_id: 'prompt-id-deprecated',
958
+ hasDeprecatedPromptArg: true,
959
+ });
960
+ expect(processStderrSpy).toHaveBeenCalledWith('The --prompt (-p) flag has been deprecated and will be removed in a future version. Please use a positional argument for your prompt. See gemini --help for more information.\n');
961
+ expect(processStdoutSpy).toHaveBeenCalledWith('Final Answer');
962
+ });
963
+ it('should display a deprecation warning for JSON format', async () => {
964
+ const events = [
965
+ { type: GeminiEventType.Content, value: 'Final Answer' },
966
+ {
967
+ type: GeminiEventType.Finished,
968
+ value: { reason: undefined, usageMetadata: { totalTokenCount: 10 } },
969
+ },
970
+ ];
971
+ mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
972
+ vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
973
+ await runNonInteractive({
974
+ config: mockConfig,
975
+ settings: mockSettings,
976
+ input: 'Test input',
977
+ prompt_id: 'prompt-id-deprecated-json',
978
+ hasDeprecatedPromptArg: true,
979
+ });
980
+ const deprecateText = 'The --prompt (-p) flag has been deprecated and will be removed in a future version. Please use a positional argument for your prompt. See gemini --help for more information.\n';
981
+ expect(processStderrSpy).toHaveBeenCalledWith(deprecateText);
739
982
  });
740
983
  });
741
984
  //# sourceMappingURL=nonInteractiveCli.test.js.map