@machina.ai/cell-cli 1.41.1-rc2 → 1.45.1-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 (560) hide show
  1. package/dist/index.js +17 -17
  2. package/dist/index.js.map +1 -1
  3. package/dist/package.json +4 -4
  4. package/dist/src/acp/README.md +81 -0
  5. package/dist/src/acp/{commandHandler.d.ts → acpCommandHandler.d.ts} +1 -1
  6. package/dist/src/acp/{commandHandler.js → acpCommandHandler.js} +2 -2
  7. package/dist/src/acp/acpCommandHandler.js.map +1 -0
  8. package/dist/src/acp/{commandHandler.test.js → acpCommandHandler.test.js} +4 -5
  9. package/dist/src/acp/acpCommandHandler.test.js.map +1 -0
  10. package/dist/src/acp/acpErrors.d.ts +1 -1
  11. package/dist/src/acp/acpErrors.js +1 -1
  12. package/dist/src/acp/acpErrors.test.d.ts +1 -1
  13. package/dist/src/acp/acpErrors.test.js +1 -1
  14. package/dist/src/acp/{fileSystemService.d.ts → acpFileSystemService.d.ts} +1 -1
  15. package/dist/src/acp/{fileSystemService.js → acpFileSystemService.js} +7 -4
  16. package/dist/src/acp/acpFileSystemService.js.map +1 -0
  17. package/dist/src/acp/{fileSystemService.test.js → acpFileSystemService.test.js} +3 -3
  18. package/dist/src/acp/acpFileSystemService.test.js.map +1 -0
  19. package/dist/src/acp/acpResume.test.d.ts +1 -1
  20. package/dist/src/acp/acpResume.test.js +12 -7
  21. package/dist/src/acp/acpResume.test.js.map +1 -1
  22. package/dist/src/acp/acpRpcDispatcher.d.ts +28 -0
  23. package/dist/src/acp/acpRpcDispatcher.js +177 -0
  24. package/dist/src/acp/acpRpcDispatcher.js.map +1 -0
  25. package/dist/src/acp/acpRpcDispatcher.test.d.ts +6 -0
  26. package/dist/src/acp/acpRpcDispatcher.test.js +238 -0
  27. package/dist/src/acp/acpRpcDispatcher.test.js.map +1 -0
  28. package/dist/src/acp/acpSession.d.ts +36 -0
  29. package/dist/src/acp/{acpClient.js → acpSession.js} +333 -781
  30. package/dist/src/acp/acpSession.js.map +1 -0
  31. package/dist/src/acp/acpSession.test.d.ts +6 -0
  32. package/dist/src/acp/acpSession.test.js +739 -0
  33. package/dist/src/acp/acpSession.test.js.map +1 -0
  34. package/dist/src/acp/acpSessionManager.d.ts +30 -0
  35. package/dist/src/acp/acpSessionManager.js +206 -0
  36. package/dist/src/acp/acpSessionManager.js.map +1 -0
  37. package/dist/src/acp/acpSessionManager.test.d.ts +6 -0
  38. package/dist/src/acp/acpSessionManager.test.js +283 -0
  39. package/dist/src/acp/acpSessionManager.test.js.map +1 -0
  40. package/dist/src/acp/acpStdioTransport.d.ts +9 -0
  41. package/dist/src/acp/acpStdioTransport.js +23 -0
  42. package/dist/src/acp/acpStdioTransport.js.map +1 -0
  43. package/dist/src/acp/acpUtils.d.ts +56 -0
  44. package/dist/src/acp/acpUtils.js +288 -0
  45. package/dist/src/acp/acpUtils.js.map +1 -0
  46. package/dist/src/acp/commands/commandRegistry.d.ts +1 -1
  47. package/dist/src/acp/commands/commandRegistry.js +1 -1
  48. package/dist/src/acp/commands/extensions.d.ts +1 -1
  49. package/dist/src/acp/commands/extensions.js +1 -1
  50. package/dist/src/acp/commands/extensions.test.d.ts +6 -0
  51. package/dist/src/acp/commands/extensions.test.js +70 -0
  52. package/dist/src/acp/commands/extensions.test.js.map +1 -0
  53. package/dist/src/acp/commands/init.d.ts +1 -1
  54. package/dist/src/acp/commands/init.js +1 -1
  55. package/dist/src/acp/commands/memory.d.ts +3 -8
  56. package/dist/src/acp/commands/memory.js +18 -47
  57. package/dist/src/acp/commands/memory.js.map +1 -1
  58. package/dist/src/acp/commands/restore.d.ts +1 -1
  59. package/dist/src/acp/commands/restore.js +1 -1
  60. package/dist/src/acp/commands/restore.test.js +7 -13
  61. package/dist/src/acp/commands/restore.test.js.map +1 -1
  62. package/dist/src/acp/commands/types.d.ts +1 -1
  63. package/dist/src/acp/commands/types.js +1 -1
  64. package/dist/src/commands/extensions/configure.test.js +6 -2
  65. package/dist/src/commands/extensions/configure.test.js.map +1 -1
  66. package/dist/src/commands/extensions/utils.d.ts +1 -1
  67. package/dist/src/commands/extensions/utils.js +1 -2
  68. package/dist/src/commands/extensions/utils.js.map +1 -1
  69. package/dist/src/commands/mcp/list.js +19 -5
  70. package/dist/src/commands/mcp/list.js.map +1 -1
  71. package/dist/src/commands/mcp/list.test.js +285 -100
  72. package/dist/src/commands/mcp/list.test.js.map +1 -1
  73. package/dist/src/config/auth.d.ts +1 -1
  74. package/dist/src/config/auth.js +4 -3
  75. package/dist/src/config/auth.js.map +1 -1
  76. package/dist/src/config/auth.test.js +11 -4
  77. package/dist/src/config/auth.test.js.map +1 -1
  78. package/dist/src/config/config.d.ts +4 -0
  79. package/dist/src/config/config.js +65 -47
  80. package/dist/src/config/config.js.map +1 -1
  81. package/dist/src/config/config.test.js +25 -106
  82. package/dist/src/config/config.test.js.map +1 -1
  83. package/dist/src/config/extension-manager-agents.test.js +2 -0
  84. package/dist/src/config/extension-manager-agents.test.js.map +1 -1
  85. package/dist/src/config/extension-manager-hydration.test.js +2 -0
  86. package/dist/src/config/extension-manager-hydration.test.js.map +1 -1
  87. package/dist/src/config/extension-manager-scope.test.js +4 -2
  88. package/dist/src/config/extension-manager-scope.test.js.map +1 -1
  89. package/dist/src/config/extension-manager-themes.spec.js +2 -0
  90. package/dist/src/config/extension-manager-themes.spec.js.map +1 -1
  91. package/dist/src/config/extension-manager.d.ts +2 -2
  92. package/dist/src/config/extension-manager.js +2 -1
  93. package/dist/src/config/extension-manager.js.map +1 -1
  94. package/dist/src/config/extensionRegistryClient.js +0 -1
  95. package/dist/src/config/extensionRegistryClient.js.map +1 -1
  96. package/dist/src/config/extensions/consent.d.ts +1 -1
  97. package/dist/src/config/extensions/consent.js +5 -4
  98. package/dist/src/config/extensions/consent.js.map +1 -1
  99. package/dist/src/config/extensions/consent.test.js +22 -0
  100. package/dist/src/config/extensions/consent.test.js.map +1 -1
  101. package/dist/src/config/extensions/extensionEnablement.js +4 -2
  102. package/dist/src/config/extensions/extensionEnablement.js.map +1 -1
  103. package/dist/src/config/extensions/extensionSettings.d.ts +3 -3
  104. package/dist/src/config/extensions/extensionSettings.js +7 -3
  105. package/dist/src/config/extensions/extensionSettings.js.map +1 -1
  106. package/dist/src/config/extensions/variables.js +1 -3
  107. package/dist/src/config/extensions/variables.js.map +1 -1
  108. package/dist/src/config/footerItems.d.ts +4 -0
  109. package/dist/src/config/footerItems.js +6 -0
  110. package/dist/src/config/footerItems.js.map +1 -1
  111. package/dist/src/config/footerItems.test.js +1 -0
  112. package/dist/src/config/footerItems.test.js.map +1 -1
  113. package/dist/src/config/mcp/mcpServerEnablement.js +1 -1
  114. package/dist/src/config/mcp/mcpServerEnablement.js.map +1 -1
  115. package/dist/src/config/mutual-exclusivity.test.js +33 -0
  116. package/dist/src/config/mutual-exclusivity.test.js.map +1 -0
  117. package/dist/src/config/settings-env-isolation.test.d.ts +6 -0
  118. package/dist/src/config/settings-env-isolation.test.js +188 -0
  119. package/dist/src/config/settings-env-isolation.test.js.map +1 -0
  120. package/dist/src/config/settings.d.ts +15 -1
  121. package/dist/src/config/settings.js +85 -10
  122. package/dist/src/config/settings.js.map +1 -1
  123. package/dist/src/config/settings.test.js +167 -0
  124. package/dist/src/config/settings.test.js.map +1 -1
  125. package/dist/src/config/settingsSchema.d.ts +56 -25
  126. package/dist/src/config/settingsSchema.js +66 -27
  127. package/dist/src/config/settingsSchema.js.map +1 -1
  128. package/dist/src/config/settingsSchema.test.js +8 -0
  129. package/dist/src/config/settingsSchema.test.js.map +1 -1
  130. package/dist/src/config/skipExtensions.test.d.ts +6 -0
  131. package/dist/src/config/skipExtensions.test.js +49 -0
  132. package/dist/src/config/skipExtensions.test.js.map +1 -0
  133. package/dist/src/config/workspace-policy-cli.test.js +0 -5
  134. package/dist/src/config/workspace-policy-cli.test.js.map +1 -1
  135. package/dist/src/gemini.d.ts +2 -2
  136. package/dist/src/gemini.js +108 -30
  137. package/dist/src/gemini.js.map +1 -1
  138. package/dist/src/gemini.test.js +147 -16
  139. package/dist/src/gemini.test.js.map +1 -1
  140. package/dist/src/gemini_cleanup.test.js +1 -1
  141. package/dist/src/gemini_cleanup.test.js.map +1 -1
  142. package/dist/src/generated/git-commit.d.ts +2 -2
  143. package/dist/src/generated/git-commit.js +2 -2
  144. package/dist/src/interactiveCli.js +1 -1
  145. package/dist/src/interactiveCli.js.map +1 -1
  146. package/dist/src/nonInteractiveCli.d.ts +7 -0
  147. package/dist/src/nonInteractiveCli.js +56 -6
  148. package/dist/src/nonInteractiveCli.js.map +1 -1
  149. package/dist/src/nonInteractiveCli.test.js +253 -18
  150. package/dist/src/nonInteractiveCli.test.js.map +1 -1
  151. package/dist/src/nonInteractiveCliAgentSession.d.ts +7 -0
  152. package/dist/src/nonInteractiveCliAgentSession.js +22 -3
  153. package/dist/src/nonInteractiveCliAgentSession.js.map +1 -1
  154. package/dist/src/nonInteractiveCliAgentSession.test.js +200 -20
  155. package/dist/src/nonInteractiveCliAgentSession.test.js.map +1 -1
  156. package/dist/src/output-redirection.test.d.ts +6 -0
  157. package/dist/src/output-redirection.test.js +77 -0
  158. package/dist/src/output-redirection.test.js.map +1 -0
  159. package/dist/src/patches/http-proxy-agent.d.ts +6 -0
  160. package/dist/src/patches/http-proxy-agent.js +8 -0
  161. package/dist/src/patches/http-proxy-agent.js.map +1 -0
  162. package/dist/src/patches/https-proxy-agent.d.ts +6 -0
  163. package/dist/src/patches/https-proxy-agent.js +8 -0
  164. package/dist/src/patches/https-proxy-agent.js.map +1 -0
  165. package/dist/src/services/BuiltinCommandLoader.js +5 -1
  166. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  167. package/dist/src/services/BuiltinCommandLoader.test.js +6 -1
  168. package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
  169. package/dist/src/services/FileCommandLoader.d.ts +21 -0
  170. package/dist/src/services/FileCommandLoader.js +58 -6
  171. package/dist/src/services/FileCommandLoader.js.map +1 -1
  172. package/dist/src/services/FileCommandLoader.test.js +27 -1
  173. package/dist/src/services/FileCommandLoader.test.js.map +1 -1
  174. package/dist/src/test-utils/mockCommandContext.js +6 -1
  175. package/dist/src/test-utils/mockCommandContext.js.map +1 -1
  176. package/dist/src/test-utils/mockConfig.js +0 -3
  177. package/dist/src/test-utils/mockConfig.js.map +1 -1
  178. package/dist/src/test-utils/render.js +1 -0
  179. package/dist/src/test-utils/render.js.map +1 -1
  180. package/dist/src/test-utils/settings.d.ts +1 -0
  181. package/dist/src/test-utils/settings.js.map +1 -1
  182. package/dist/src/ui/AppContainer.js +60 -73
  183. package/dist/src/ui/AppContainer.js.map +1 -1
  184. package/dist/src/ui/AppContainer.test.js +101 -1
  185. package/dist/src/ui/AppContainer.test.js.map +1 -1
  186. package/dist/src/ui/auth/AuthDialog.js +6 -3
  187. package/dist/src/ui/auth/AuthDialog.js.map +1 -1
  188. package/dist/src/ui/auth/AuthDialog.test.js +33 -10
  189. package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
  190. package/dist/src/ui/auth/LoginRestartDialog.d.ts +13 -0
  191. package/dist/src/ui/auth/{LoginWithGoogleRestartDialog.js → LoginRestartDialog.js} +7 -6
  192. package/dist/src/ui/auth/LoginRestartDialog.js.map +1 -0
  193. package/dist/src/ui/auth/LoginRestartDialog.test.d.ts +6 -0
  194. package/dist/src/ui/auth/{LoginWithGoogleRestartDialog.test.js → LoginRestartDialog.test.js} +13 -8
  195. package/dist/src/ui/auth/LoginRestartDialog.test.js.map +1 -0
  196. package/dist/src/ui/auth/useAuth.d.ts +1 -1
  197. package/dist/src/ui/auth/useAuth.js +2 -2
  198. package/dist/src/ui/auth/useAuth.js.map +1 -1
  199. package/dist/src/ui/auth/useAuth.test.js +10 -10
  200. package/dist/src/ui/auth/useAuth.test.js.map +1 -1
  201. package/dist/src/ui/commands/agentsCommand.js +19 -2
  202. package/dist/src/ui/commands/agentsCommand.js.map +1 -1
  203. package/dist/src/ui/commands/agentsCommand.test.js +34 -3
  204. package/dist/src/ui/commands/agentsCommand.test.js.map +1 -1
  205. package/dist/src/ui/commands/bugCommand.js +36 -0
  206. package/dist/src/ui/commands/bugCommand.js.map +1 -1
  207. package/dist/src/ui/commands/bugCommand.test.js +106 -1
  208. package/dist/src/ui/commands/bugCommand.test.js.map +1 -1
  209. package/dist/src/ui/commands/bugMemoryCommand.d.ts +7 -0
  210. package/dist/src/ui/commands/bugMemoryCommand.js +62 -0
  211. package/dist/src/ui/commands/bugMemoryCommand.js.map +1 -0
  212. package/dist/src/ui/commands/bugMemoryCommand.test.js +100 -0
  213. package/dist/src/ui/commands/bugMemoryCommand.test.js.map +1 -0
  214. package/dist/src/ui/commands/commandsCommand.js +52 -4
  215. package/dist/src/ui/commands/commandsCommand.js.map +1 -1
  216. package/dist/src/ui/commands/commandsCommand.test.js +75 -2
  217. package/dist/src/ui/commands/commandsCommand.test.js.map +1 -1
  218. package/dist/src/ui/commands/compressCommand.js +28 -26
  219. package/dist/src/ui/commands/compressCommand.js.map +1 -1
  220. package/dist/src/ui/commands/compressCommand.test.js +5 -0
  221. package/dist/src/ui/commands/compressCommand.test.js.map +1 -1
  222. package/dist/src/ui/commands/directoryCommand.js +2 -2
  223. package/dist/src/ui/commands/directoryCommand.js.map +1 -1
  224. package/dist/src/ui/commands/directoryCommand.test.js +1 -0
  225. package/dist/src/ui/commands/directoryCommand.test.js.map +1 -1
  226. package/dist/src/ui/commands/exportSessionCommand.d.ts +7 -0
  227. package/dist/src/ui/commands/exportSessionCommand.js +74 -0
  228. package/dist/src/ui/commands/exportSessionCommand.js.map +1 -0
  229. package/dist/src/ui/commands/exportSessionCommand.test.js +100 -0
  230. package/dist/src/ui/commands/exportSessionCommand.test.js.map +1 -0
  231. package/dist/src/ui/commands/extensionsCommand.js +1 -0
  232. package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
  233. package/dist/src/ui/commands/extensionsCommand.test.js +4 -0
  234. package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -1
  235. package/dist/src/ui/commands/memoryCommand.d.ts +2 -1
  236. package/dist/src/ui/commands/memoryCommand.js +110 -117
  237. package/dist/src/ui/commands/memoryCommand.js.map +1 -1
  238. package/dist/src/ui/commands/memoryCommand.test.js +18 -71
  239. package/dist/src/ui/commands/memoryCommand.test.js.map +1 -1
  240. package/dist/src/ui/commands/quitCommand.js +3 -1
  241. package/dist/src/ui/commands/quitCommand.js.map +1 -1
  242. package/dist/src/ui/commands/quitCommand.test.js +46 -1
  243. package/dist/src/ui/commands/quitCommand.test.js.map +1 -1
  244. package/dist/src/ui/commands/rewindCommand.js.map +1 -1
  245. package/dist/src/ui/commands/skillsCommand.js +1 -1
  246. package/dist/src/ui/commands/skillsCommand.js.map +1 -1
  247. package/dist/src/ui/commands/skillsCommand.test.js +19 -0
  248. package/dist/src/ui/commands/skillsCommand.test.js.map +1 -1
  249. package/dist/src/ui/commands/types.d.ts +3 -1
  250. package/dist/src/ui/commands/types.js.map +1 -1
  251. package/dist/src/ui/components/AsciiArt.d.ts +6 -6
  252. package/dist/src/ui/components/AsciiArt.js +6 -6
  253. package/dist/src/ui/components/AskUserDialog.js +3 -1
  254. package/dist/src/ui/components/AskUserDialog.js.map +1 -1
  255. package/dist/src/ui/components/AskUserDialog.test.js +43 -0
  256. package/dist/src/ui/components/AskUserDialog.test.js.map +1 -1
  257. package/dist/src/ui/components/Composer.js +1 -1
  258. package/dist/src/ui/components/Composer.js.map +1 -1
  259. package/dist/src/ui/components/DialogManager.js +4 -0
  260. package/dist/src/ui/components/DialogManager.js.map +1 -1
  261. package/dist/src/ui/components/EditorSettingsDialog.js +3 -6
  262. package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
  263. package/dist/src/ui/components/Footer.js +6 -0
  264. package/dist/src/ui/components/Footer.js.map +1 -1
  265. package/dist/src/ui/components/FooterConfigDialog.js +1 -0
  266. package/dist/src/ui/components/FooterConfigDialog.js.map +1 -1
  267. package/dist/src/ui/components/FooterConfigDialog.test.js +1 -1
  268. package/dist/src/ui/components/FooterConfigDialog.test.js.map +1 -1
  269. package/dist/src/ui/components/HistoryItemDisplay.js +3 -1
  270. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  271. package/dist/src/ui/components/HistoryItemDisplay.test.js +15 -0
  272. package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
  273. package/dist/src/ui/components/{SkillInboxDialog.d.ts → InboxDialog.d.ts} +3 -2
  274. package/dist/src/ui/components/InboxDialog.js +756 -0
  275. package/dist/src/ui/components/InboxDialog.js.map +1 -0
  276. package/dist/src/ui/components/InboxDialog.test.d.ts +6 -0
  277. package/dist/src/ui/components/InboxDialog.test.js +824 -0
  278. package/dist/src/ui/components/InboxDialog.test.js.map +1 -0
  279. package/dist/src/ui/components/InputPrompt.d.ts +3 -0
  280. package/dist/src/ui/components/InputPrompt.js +35 -17
  281. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  282. package/dist/src/ui/components/InputPrompt.test.js +95 -46
  283. package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
  284. package/dist/src/ui/components/ListeningIndicator.d.ts +10 -0
  285. package/dist/src/ui/components/ListeningIndicator.js +30 -0
  286. package/dist/src/ui/components/ListeningIndicator.js.map +1 -0
  287. package/dist/src/ui/components/MainContent.test.js +23 -3
  288. package/dist/src/ui/components/MainContent.test.js.map +1 -1
  289. package/dist/src/ui/components/ModelDialog.js +32 -37
  290. package/dist/src/ui/components/ModelDialog.js.map +1 -1
  291. package/dist/src/ui/components/ModelDialog.test.js +30 -27
  292. package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
  293. package/dist/src/ui/components/ModelStatsDisplay.js +1 -1
  294. package/dist/src/ui/components/ModelStatsDisplay.js.map +1 -1
  295. package/dist/src/ui/components/ModelStatsDisplay.test.js +41 -0
  296. package/dist/src/ui/components/ModelStatsDisplay.test.js.map +1 -1
  297. package/dist/src/ui/components/SessionBrowser.js +7 -0
  298. package/dist/src/ui/components/SessionBrowser.js.map +1 -1
  299. package/dist/src/ui/components/SessionSummaryDisplay.js +9 -4
  300. package/dist/src/ui/components/SessionSummaryDisplay.js.map +1 -1
  301. package/dist/src/ui/components/SessionSummaryDisplay.test.js +12 -23
  302. package/dist/src/ui/components/SessionSummaryDisplay.test.js.map +1 -1
  303. package/dist/src/ui/components/SettingsDialog.js +37 -17
  304. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  305. package/dist/src/ui/components/SettingsDialog.test.js +83 -1
  306. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  307. package/dist/src/ui/components/StatsDisplay.js +2 -2
  308. package/dist/src/ui/components/StatsDisplay.js.map +1 -1
  309. package/dist/src/ui/components/StatsDisplay.test.js +24 -0
  310. package/dist/src/ui/components/StatsDisplay.test.js.map +1 -1
  311. package/dist/src/ui/components/ThemeDialog.constants.d.ts +26 -0
  312. package/dist/src/ui/components/ThemeDialog.constants.js +27 -0
  313. package/dist/src/ui/components/ThemeDialog.constants.js.map +1 -0
  314. package/dist/src/ui/components/ThemeDialog.js +5 -15
  315. package/dist/src/ui/components/ThemeDialog.js.map +1 -1
  316. package/dist/src/ui/components/ToolConfirmationQueue.test.js +1 -1
  317. package/dist/src/ui/components/ToolConfirmationQueue.test.js.map +1 -1
  318. package/dist/src/ui/components/VoiceModelDialog.js +7 -2
  319. package/dist/src/ui/components/VoiceModelDialog.js.map +1 -1
  320. package/dist/src/ui/components/VoiceModelDialog.test.d.ts +6 -0
  321. package/dist/src/ui/components/VoiceModelDialog.test.js +68 -0
  322. package/dist/src/ui/components/VoiceModelDialog.test.js.map +1 -0
  323. package/dist/src/ui/components/messages/ExportSessionMessage.d.ts +11 -0
  324. package/dist/src/ui/components/messages/ExportSessionMessage.js +15 -0
  325. package/dist/src/ui/components/messages/ExportSessionMessage.js.map +1 -0
  326. package/dist/src/ui/components/messages/ExportSessionMessage.test.d.ts +6 -0
  327. package/dist/src/ui/components/messages/ExportSessionMessage.test.js +31 -0
  328. package/dist/src/ui/components/messages/ExportSessionMessage.test.js.map +1 -0
  329. package/dist/src/ui/components/messages/ShellToolMessage.js +6 -2
  330. package/dist/src/ui/components/messages/ShellToolMessage.js.map +1 -1
  331. package/dist/src/ui/components/messages/ShellToolMessage.test.js +33 -0
  332. package/dist/src/ui/components/messages/ShellToolMessage.test.js.map +1 -1
  333. package/dist/src/ui/components/messages/SubagentGroupDisplay.js +13 -13
  334. package/dist/src/ui/components/messages/SubagentGroupDisplay.js.map +1 -1
  335. package/dist/src/ui/components/messages/SubagentGroupDisplay.test.js +5 -5
  336. package/dist/src/ui/components/messages/SubagentGroupDisplay.test.js.map +1 -1
  337. package/dist/src/ui/components/messages/SubagentHistoryMessage.test.js +4 -3
  338. package/dist/src/ui/components/messages/SubagentHistoryMessage.test.js.map +1 -1
  339. package/dist/src/ui/components/messages/SubagentProgressDisplay.d.ts +1 -1
  340. package/dist/src/ui/components/messages/SubagentProgressDisplay.js +7 -6
  341. package/dist/src/ui/components/messages/SubagentProgressDisplay.js.map +1 -1
  342. package/dist/src/ui/components/messages/SubagentProgressDisplay.test.js +10 -9
  343. package/dist/src/ui/components/messages/SubagentProgressDisplay.test.js.map +1 -1
  344. package/dist/src/ui/components/messages/ToolConfirmationMessage.js +3 -9
  345. package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
  346. package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +60 -0
  347. package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -1
  348. package/dist/src/ui/components/messages/ToolGroupDisplay.d.ts +13 -0
  349. package/dist/src/ui/components/messages/ToolGroupDisplay.js +78 -0
  350. package/dist/src/ui/components/messages/ToolGroupDisplay.js.map +1 -0
  351. package/dist/src/ui/components/messages/ToolGroupDisplay.test.d.ts +6 -0
  352. package/dist/src/ui/components/messages/ToolGroupDisplay.test.js +210 -0
  353. package/dist/src/ui/components/messages/ToolGroupDisplay.test.js.map +1 -0
  354. package/dist/src/ui/components/messages/ToolGroupMessage.js +4 -2
  355. package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
  356. package/dist/src/ui/components/messages/ToolGroupMessage.test.js +28 -0
  357. package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
  358. package/dist/src/ui/components/messages/ToolGroupMessageRegression.test.js +3 -3
  359. package/dist/src/ui/components/messages/ToolGroupMessageRegression.test.js.map +1 -1
  360. package/dist/src/ui/components/messages/ToolMessage.js +6 -2
  361. package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
  362. package/dist/src/ui/components/messages/ToolShared.d.ts +1 -0
  363. package/dist/src/ui/components/messages/ToolShared.js +5 -3
  364. package/dist/src/ui/components/messages/ToolShared.js.map +1 -1
  365. package/dist/src/ui/components/messages/ToolShared.test.js +18 -1
  366. package/dist/src/ui/components/messages/ToolShared.test.js.map +1 -1
  367. package/dist/src/ui/components/shared/BaseSettingsDialog.d.ts +6 -1
  368. package/dist/src/ui/components/shared/BaseSettingsDialog.js +8 -8
  369. package/dist/src/ui/components/shared/BaseSettingsDialog.js.map +1 -1
  370. package/dist/src/ui/components/shared/performance.test.js +9 -0
  371. package/dist/src/ui/components/shared/performance.test.js.map +1 -1
  372. package/dist/src/ui/components/shared/text-buffer.js +22 -5
  373. package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
  374. package/dist/src/ui/components/shared/text-buffer.test.js +211 -0
  375. package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
  376. package/dist/src/ui/constants/tips.js +0 -1
  377. package/dist/src/ui/constants/tips.js.map +1 -1
  378. package/dist/src/ui/contexts/UIActionsContext.d.ts +1 -0
  379. package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
  380. package/dist/src/ui/contexts/UIStateContext.d.ts +2 -0
  381. package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
  382. package/dist/src/ui/hooks/atCommandProcessor.js +78 -69
  383. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  384. package/dist/src/ui/hooks/atCommandProcessor.test.js +128 -18
  385. package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
  386. package/dist/src/ui/hooks/slashCommandProcessor.js +13 -0
  387. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  388. package/dist/src/ui/hooks/slashCommandProcessor.test.js +85 -0
  389. package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
  390. package/dist/src/ui/hooks/useAgentStream.d.ts +2 -2
  391. package/dist/src/ui/hooks/useAgentStream.js +63 -30
  392. package/dist/src/ui/hooks/useAgentStream.js.map +1 -1
  393. package/dist/src/ui/hooks/useAgentStream.test.js +1 -1
  394. package/dist/src/ui/hooks/useAgentStream.test.js.map +1 -1
  395. package/dist/src/ui/hooks/useAtCompletion.js +0 -2
  396. package/dist/src/ui/hooks/useAtCompletion.js.map +1 -1
  397. package/dist/src/ui/hooks/useGeminiStream.d.ts +2 -2
  398. package/dist/src/ui/hooks/useGeminiStream.js +48 -29
  399. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  400. package/dist/src/ui/hooks/useGeminiStream.test.js +44 -82
  401. package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
  402. package/dist/src/ui/hooks/useGitBranchName.js +29 -16
  403. package/dist/src/ui/hooks/useGitBranchName.js.map +1 -1
  404. package/dist/src/ui/hooks/useGitBranchName.test.js +102 -51
  405. package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
  406. package/dist/src/ui/hooks/useIncludeDirsTrust.js +2 -2
  407. package/dist/src/ui/hooks/useIncludeDirsTrust.js.map +1 -1
  408. package/dist/src/ui/hooks/useIncludeDirsTrust.test.js +2 -0
  409. package/dist/src/ui/hooks/useIncludeDirsTrust.test.js.map +1 -1
  410. package/dist/src/ui/hooks/useMessageQueue.d.ts +2 -1
  411. package/dist/src/ui/hooks/useMessageQueue.js +3 -1
  412. package/dist/src/ui/hooks/useMessageQueue.js.map +1 -1
  413. package/dist/src/ui/hooks/useMessageQueue.test.js +38 -0
  414. package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
  415. package/dist/src/ui/hooks/useSessionBrowser.d.ts +3 -3
  416. package/dist/src/ui/hooks/useSessionBrowser.js.map +1 -1
  417. package/dist/src/ui/hooks/useSessionBrowser.test.js +44 -38
  418. package/dist/src/ui/hooks/useSessionBrowser.test.js.map +1 -1
  419. package/dist/src/ui/hooks/useSessionResume.d.ts +3 -3
  420. package/dist/src/ui/hooks/useSessionResume.js.map +1 -1
  421. package/dist/src/ui/hooks/useSessionResume.test.js +6 -4
  422. package/dist/src/ui/hooks/useSessionResume.test.js.map +1 -1
  423. package/dist/src/ui/hooks/useSuspend.d.ts +1 -3
  424. package/dist/src/ui/hooks/useSuspend.js +3 -17
  425. package/dist/src/ui/hooks/useSuspend.js.map +1 -1
  426. package/dist/src/ui/hooks/useSuspend.test.js +0 -14
  427. package/dist/src/ui/hooks/useSuspend.test.js.map +1 -1
  428. package/dist/src/ui/hooks/useToolScheduler.test.js +6 -6
  429. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  430. package/dist/src/ui/hooks/useVoiceMode.js +25 -19
  431. package/dist/src/ui/hooks/useVoiceMode.js.map +1 -1
  432. package/dist/src/ui/hooks/vim-passthrough.test.js +10 -0
  433. package/dist/src/ui/hooks/vim-passthrough.test.js.map +1 -1
  434. package/dist/src/ui/hooks/vim.js +8 -0
  435. package/dist/src/ui/hooks/vim.js.map +1 -1
  436. package/dist/src/ui/hooks/vim.test.js +61 -0
  437. package/dist/src/ui/hooks/vim.test.js.map +1 -1
  438. package/dist/src/ui/key/keyBindings.d.ts +2 -0
  439. package/dist/src/ui/key/keyBindings.js +26 -9
  440. package/dist/src/ui/key/keyBindings.js.map +1 -1
  441. package/dist/src/ui/key/keyBindings.test.js +24 -0
  442. package/dist/src/ui/key/keyBindings.test.js.map +1 -1
  443. package/dist/src/ui/key/keyMatchers.test.js +26 -5
  444. package/dist/src/ui/key/keyMatchers.test.js.map +1 -1
  445. package/dist/src/ui/themes/theme-manager.js +0 -2
  446. package/dist/src/ui/themes/theme-manager.js.map +1 -1
  447. package/dist/src/ui/types.d.ts +23 -2
  448. package/dist/src/ui/types.js +3 -2
  449. package/dist/src/ui/types.js.map +1 -1
  450. package/dist/src/ui/utils/TableRenderer.js +6 -6
  451. package/dist/src/ui/utils/TableRenderer.js.map +1 -1
  452. package/dist/src/ui/utils/TableRenderer.test.js +10 -0
  453. package/dist/src/ui/utils/TableRenderer.test.js.map +1 -1
  454. package/dist/src/ui/utils/directoryUtils.test.js +0 -5
  455. package/dist/src/ui/utils/directoryUtils.test.js.map +1 -1
  456. package/dist/src/ui/utils/editorUtils.d.ts +2 -1
  457. package/dist/src/ui/utils/editorUtils.js +75 -28
  458. package/dist/src/ui/utils/editorUtils.js.map +1 -1
  459. package/dist/src/ui/utils/latexToUnicode.d.ts +21 -0
  460. package/dist/src/ui/utils/latexToUnicode.js +538 -0
  461. package/dist/src/ui/utils/latexToUnicode.js.map +1 -0
  462. package/dist/src/ui/utils/latexToUnicode.test.d.ts +6 -0
  463. package/dist/src/ui/utils/latexToUnicode.test.js +222 -0
  464. package/dist/src/ui/utils/latexToUnicode.test.js.map +1 -0
  465. package/dist/src/ui/utils/markdownParsingUtils.d.ts +1 -5
  466. package/dist/src/ui/utils/markdownParsingUtils.js +36 -1
  467. package/dist/src/ui/utils/markdownParsingUtils.js.map +1 -1
  468. package/dist/src/ui/utils/markdownParsingUtils.test.js +35 -0
  469. package/dist/src/ui/utils/markdownParsingUtils.test.js.map +1 -1
  470. package/dist/src/ui/utils/memorySnapshot.d.ts +19 -0
  471. package/dist/src/ui/utils/memorySnapshot.js +28 -0
  472. package/dist/src/ui/utils/memorySnapshot.js.map +1 -0
  473. package/dist/src/ui/utils/memorySnapshot.test.d.ts +6 -0
  474. package/dist/src/ui/utils/memorySnapshot.test.js +62 -0
  475. package/dist/src/ui/utils/memorySnapshot.test.js.map +1 -0
  476. package/dist/src/ui/utils/updateCheck.js +11 -2
  477. package/dist/src/ui/utils/updateCheck.js.map +1 -1
  478. package/dist/src/ui/utils/updateCheck.test.js +73 -0
  479. package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
  480. package/dist/src/utils/commands.d.ts +1 -1
  481. package/dist/src/utils/commands.js +1 -1
  482. package/dist/src/utils/commands.test.js +14 -14
  483. package/dist/src/utils/commands.test.js.map +1 -1
  484. package/dist/src/utils/envVarResolver.js +10 -7
  485. package/dist/src/utils/envVarResolver.js.map +1 -1
  486. package/dist/src/utils/gitUtils.js +1 -2
  487. package/dist/src/utils/gitUtils.js.map +1 -1
  488. package/dist/src/utils/handleAutoUpdate.d.ts +1 -1
  489. package/dist/src/utils/handleAutoUpdate.js +15 -3
  490. package/dist/src/utils/handleAutoUpdate.js.map +1 -1
  491. package/dist/src/utils/handleAutoUpdate.test.js +45 -16
  492. package/dist/src/utils/handleAutoUpdate.test.js.map +1 -1
  493. package/dist/src/utils/installationInfo.d.ts +1 -0
  494. package/dist/src/utils/installationInfo.js +16 -1
  495. package/dist/src/utils/installationInfo.js.map +1 -1
  496. package/dist/src/utils/installationInfo.test.js +16 -0
  497. package/dist/src/utils/installationInfo.test.js.map +1 -1
  498. package/dist/src/utils/jsonoutput.js +0 -2
  499. package/dist/src/utils/jsonoutput.js.map +1 -1
  500. package/dist/src/utils/processUtils.d.ts +28 -0
  501. package/dist/src/utils/processUtils.js +71 -0
  502. package/dist/src/utils/processUtils.js.map +1 -1
  503. package/dist/src/utils/processUtils.test.js +122 -1
  504. package/dist/src/utils/processUtils.test.js.map +1 -1
  505. package/dist/src/utils/readStdin.js +22 -4
  506. package/dist/src/utils/readStdin.js.map +1 -1
  507. package/dist/src/utils/readStdin.test.js +32 -0
  508. package/dist/src/utils/readStdin.test.js.map +1 -1
  509. package/dist/src/utils/relaunch.js +6 -13
  510. package/dist/src/utils/relaunch.js.map +1 -1
  511. package/dist/src/utils/relaunch.test.js +82 -86
  512. package/dist/src/utils/relaunch.test.js.map +1 -1
  513. package/dist/src/utils/sandbox.js +34 -24
  514. package/dist/src/utils/sandbox.js.map +1 -1
  515. package/dist/src/utils/sandbox.test.js +108 -9
  516. package/dist/src/utils/sandbox.test.js.map +1 -1
  517. package/dist/src/utils/sandboxUtils.js +12 -7
  518. package/dist/src/utils/sandboxUtils.js.map +1 -1
  519. package/dist/src/utils/sandboxUtils.test.js +68 -0
  520. package/dist/src/utils/sandboxUtils.test.js.map +1 -1
  521. package/dist/src/utils/sessionCleanup.js +49 -14
  522. package/dist/src/utils/sessionCleanup.js.map +1 -1
  523. package/dist/src/utils/sessionCleanup.test.js +63 -0
  524. package/dist/src/utils/sessionCleanup.test.js.map +1 -1
  525. package/dist/src/utils/sessionUtils.js +22 -7
  526. package/dist/src/utils/sessionUtils.js.map +1 -1
  527. package/dist/src/utils/sessionUtils.test.js +99 -0
  528. package/dist/src/utils/sessionUtils.test.js.map +1 -1
  529. package/dist/src/utils/sessions.js +2 -4
  530. package/dist/src/utils/sessions.js.map +1 -1
  531. package/dist/src/utils/sessions.test.js +9 -12
  532. package/dist/src/utils/sessions.test.js.map +1 -1
  533. package/dist/src/utils/userStartupWarnings.js +4 -3
  534. package/dist/src/utils/userStartupWarnings.js.map +1 -1
  535. package/dist/src/utils/userStartupWarnings.test.js +40 -3
  536. package/dist/src/utils/userStartupWarnings.test.js.map +1 -1
  537. package/dist/src/validateNonInterActiveAuth.js +1 -1
  538. package/dist/src/validateNonInterActiveAuth.js.map +1 -1
  539. package/dist/tsconfig.tsbuildinfo +1 -1
  540. package/package.json +4 -4
  541. package/dist/src/acp/acpClient.d.ts +0 -56
  542. package/dist/src/acp/acpClient.js.map +0 -1
  543. package/dist/src/acp/acpClient.test.js +0 -1816
  544. package/dist/src/acp/acpClient.test.js.map +0 -1
  545. package/dist/src/acp/commandHandler.js.map +0 -1
  546. package/dist/src/acp/commandHandler.test.js.map +0 -1
  547. package/dist/src/acp/fileSystemService.js.map +0 -1
  548. package/dist/src/acp/fileSystemService.test.js.map +0 -1
  549. package/dist/src/ui/auth/LoginWithGoogleRestartDialog.d.ts +0 -12
  550. package/dist/src/ui/auth/LoginWithGoogleRestartDialog.js.map +0 -1
  551. package/dist/src/ui/auth/LoginWithGoogleRestartDialog.test.js.map +0 -1
  552. package/dist/src/ui/components/SkillInboxDialog.js +0 -420
  553. package/dist/src/ui/components/SkillInboxDialog.js.map +0 -1
  554. package/dist/src/ui/components/SkillInboxDialog.test.js +0 -467
  555. package/dist/src/ui/components/SkillInboxDialog.test.js.map +0 -1
  556. /package/dist/src/acp/{commandHandler.test.d.ts → acpCommandHandler.test.d.ts} +0 -0
  557. /package/dist/src/{ui/components/SkillInboxDialog.test.d.ts → acp/acpFileSystemService.test.d.ts} +0 -0
  558. /package/dist/src/{acp/acpClient.test.d.ts → config/mutual-exclusivity.test.d.ts} +0 -0
  559. /package/dist/src/{acp/fileSystemService.test.d.ts → ui/commands/bugMemoryCommand.test.d.ts} +0 -0
  560. /package/dist/src/ui/{auth/LoginWithGoogleRestartDialog.test.d.ts → commands/exportSessionCommand.test.d.ts} +0 -0
@@ -1,359 +1,21 @@
1
1
  /**
2
2
  * @license
3
- * Copyright 2025 Google LLC
3
+ * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { CoreToolCallStatus, AuthType, logToolCall, convertToFunctionResponse, ToolConfirmationOutcome, clearCachedCredentialFile, isNodeError, getErrorMessage, isWithinRoot, getErrorStatus, MCPServerConfig, DiscoveredMCPTool, StreamEventType, ToolCallEvent, debugLogger, ReadManyFilesTool, REFERENCE_CONTENT_START, createWorkingStdio, startupProfiler, Kind, partListUnionToString, LlmRole, ApprovalMode, getVersion, convertSessionToClientHistory, DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, PREVIEW_GEMINI_MODEL, PREVIEW_GEMINI_3_1_MODEL, PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL, PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, PREVIEW_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_MODEL_AUTO, PREVIEW_GEMINI_MODEL_AUTO, getDisplayString, processSingleFileContent, InvalidStreamError, updatePolicy, } from '@google/gemini-cli-core';
6
+ import { CoreToolCallStatus, coreEvents, CoreEvent, logToolCall, convertToFunctionResponse, ToolConfirmationOutcome, getErrorStatus, DiscoveredMCPTool, ToolCallEvent, debugLogger, ReadManyFilesTool, partListUnionToString, updatePolicy, getErrorMessage, isTextPart, GeminiEventType, isWithinRoot, processSingleFileContent, isNodeError, REFERENCE_CONTENT_START, InvalidStreamError, MessageBusType, PolicyDecision, resolveAtCommandPath, } from '@google/gemini-cli-core';
7
7
  import * as acp from '@agentclientprotocol/sdk';
8
- import { AcpFileSystemService } from './fileSystemService.js';
9
- import { getAcpErrorMessage } from './acpErrors.js';
10
- import { Readable, Writable } from 'node:stream';
11
- function hasMeta(obj) {
12
- return typeof obj === 'object' && obj !== null && '_meta' in obj;
13
- }
14
- import { SettingScope, loadSettings, } from '../config/settings.js';
15
- import { createPolicyUpdater } from '../config/policy.js';
16
8
  import * as fs from 'node:fs/promises';
17
9
  import * as path from 'node:path';
18
- import { z } from 'zod';
19
10
  import { randomUUID } from 'node:crypto';
20
- import { loadCliConfig } from '../config/config.js';
21
- import { runExitCleanup } from '../utils/cleanup.js';
22
- import { SessionSelector } from '../utils/sessionUtils.js';
23
- import { startAutoMemoryIfEnabled } from '../utils/autoMemory.js';
24
- import { CommandHandler } from './commandHandler.js';
25
- const RequestPermissionResponseSchema = z.object({
26
- outcome: z.discriminatedUnion('outcome', [
27
- z.object({ outcome: z.literal('cancelled') }),
28
- z.object({
29
- outcome: z.literal('selected'),
30
- optionId: z.string(),
31
- }),
32
- ]),
11
+ import { CommandHandler } from './acpCommandHandler.js';
12
+ import { toToolCallContent, toPermissionOptions, toAcpToolKind, buildAvailableModes, RequestPermissionResponseSchema, } from './acpUtils.js';
13
+ import { z } from 'zod';
14
+ import { getAcpErrorMessage } from './acpErrors.js';
15
+ const StructuredErrorSchema = z.object({
16
+ status: z.number().optional(),
17
+ message: z.string().optional(),
33
18
  });
34
- export async function runAcpClient(config, settings, argv) {
35
- // ... (skip unchanged lines) ...
36
- const { stdout: workingStdout } = createWorkingStdio();
37
- const stdout = Writable.toWeb(workingStdout);
38
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
39
- const stdin = Readable.toWeb(process.stdin);
40
- const stream = acp.ndJsonStream(stdout, stdin);
41
- const connection = new acp.AgentSideConnection((connection) => new GeminiAgent(config, settings, argv, connection), stream);
42
- // SIGTERM/SIGINT handlers (in sdk.ts) don't fire when stdin closes.
43
- // We must explicitly await the connection close to flush telemetry.
44
- // Use finally() to ensure cleanup runs even on stream errors.
45
- await connection.closed.finally(runExitCleanup);
46
- }
47
- export class GeminiAgent {
48
- context;
49
- settings;
50
- argv;
51
- connection;
52
- static callIdCounter = 0;
53
- static generateCallId(name) {
54
- return `${name}-${Date.now()}-${++GeminiAgent.callIdCounter}`;
55
- }
56
- sessions = new Map();
57
- clientCapabilities;
58
- apiKey;
59
- baseUrl;
60
- customHeaders;
61
- constructor(context, settings, argv, connection) {
62
- this.context = context;
63
- this.settings = settings;
64
- this.argv = argv;
65
- this.connection = connection;
66
- }
67
- async initialize(args) {
68
- this.clientCapabilities = args.clientCapabilities;
69
- const authMethods = [
70
- {
71
- id: AuthType.KEYCLOAK,
72
- name: 'Cell SSO',
73
- description: "Log in via your organization's single sign-on (Keycloak)",
74
- },
75
- {
76
- id: AuthType.LOGIN_WITH_GOOGLE,
77
- name: 'Log in with Google',
78
- description: 'Log in with your Google account',
79
- },
80
- {
81
- id: AuthType.USE_GEMINI,
82
- name: 'Gemini API key',
83
- description: 'Use an API key with Gemini Developer API',
84
- _meta: {
85
- 'api-key': {
86
- provider: 'google',
87
- },
88
- },
89
- },
90
- {
91
- id: AuthType.USE_VERTEX_AI,
92
- name: 'Vertex AI',
93
- description: 'Use an API key with Vertex AI GenAI API',
94
- },
95
- {
96
- id: AuthType.GATEWAY,
97
- name: 'AI API Gateway',
98
- description: 'Use a custom AI API Gateway',
99
- _meta: {
100
- gateway: {
101
- protocol: 'google',
102
- restartRequired: 'false',
103
- },
104
- },
105
- },
106
- ];
107
- await this.context.config.initialize();
108
- const version = await getVersion();
109
- return {
110
- protocolVersion: acp.PROTOCOL_VERSION,
111
- authMethods,
112
- agentInfo: {
113
- name: 'gemini-cli',
114
- title: 'Cell CLI',
115
- version,
116
- },
117
- agentCapabilities: {
118
- loadSession: true,
119
- promptCapabilities: {
120
- image: true,
121
- audio: true,
122
- embeddedContext: true,
123
- },
124
- mcpCapabilities: {
125
- http: true,
126
- sse: true,
127
- },
128
- },
129
- };
130
- }
131
- async authenticate(req) {
132
- const { methodId } = req;
133
- const method = z.nativeEnum(AuthType).parse(methodId);
134
- const selectedAuthType = this.settings.merged.security.auth.selectedType;
135
- // Only clear credentials when switching to a different auth method
136
- if (selectedAuthType && selectedAuthType !== method) {
137
- await clearCachedCredentialFile();
138
- }
139
- // Check for api-key in _meta
140
- const meta = hasMeta(req) ? req._meta : undefined;
141
- const apiKey = typeof meta?.['api-key'] === 'string' ? meta['api-key'] : undefined;
142
- // Refresh auth with the requested method
143
- // This will reuse existing credentials if they're valid,
144
- // or perform new authentication if needed
145
- try {
146
- if (apiKey) {
147
- this.apiKey = apiKey;
148
- }
149
- // Extract gateway details if present
150
- const gatewaySchema = z.object({
151
- baseUrl: z.string().optional(),
152
- headers: z.record(z.string()).optional(),
153
- });
154
- let baseUrl;
155
- let headers;
156
- if (meta?.['gateway']) {
157
- const result = gatewaySchema.safeParse(meta['gateway']);
158
- if (result.success) {
159
- baseUrl = result.data.baseUrl;
160
- headers = result.data.headers;
161
- }
162
- else {
163
- throw new acp.RequestError(-32602, `Malformed gateway payload: ${result.error.message}`);
164
- }
165
- }
166
- this.baseUrl = baseUrl;
167
- this.customHeaders = headers;
168
- await this.context.config.refreshAuth(method, (msg) => {
169
- process.stderr.write(`${msg}\n`);
170
- }, apiKey ?? this.apiKey, baseUrl, headers);
171
- }
172
- catch (e) {
173
- throw new acp.RequestError(-32000, getAcpErrorMessage(e));
174
- }
175
- this.settings.setValue(SettingScope.User, 'security.auth.selectedType', method);
176
- }
177
- async newSession({ cwd, mcpServers, }) {
178
- const sessionId = randomUUID();
179
- const loadedSettings = loadSettings(cwd);
180
- const config = await this.newSessionConfig(sessionId, cwd, mcpServers, loadedSettings);
181
- const authType = loadedSettings.merged.security.auth.selectedType || AuthType.USE_GEMINI;
182
- let isAuthenticated = false;
183
- let authErrorMessage = '';
184
- try {
185
- await config.refreshAuth(authType, undefined, this.apiKey, this.baseUrl, this.customHeaders);
186
- isAuthenticated = true;
187
- // Extra validation for Gemini API key
188
- const contentGeneratorConfig = config.getContentGeneratorConfig();
189
- if (authType === AuthType.USE_GEMINI &&
190
- (!contentGeneratorConfig || !contentGeneratorConfig.apiKey)) {
191
- isAuthenticated = false;
192
- authErrorMessage = 'Gemini API key is missing or not configured.';
193
- }
194
- }
195
- catch (e) {
196
- isAuthenticated = false;
197
- authErrorMessage = getAcpErrorMessage(e);
198
- debugLogger.error(`Authentication failed: ${e instanceof Error ? e.stack : e}`);
199
- }
200
- if (!isAuthenticated) {
201
- throw new acp.RequestError(-32000, authErrorMessage || 'Authentication required.');
202
- }
203
- if (this.clientCapabilities?.fs) {
204
- const acpFileSystemService = new AcpFileSystemService(this.connection, sessionId, this.clientCapabilities.fs, config.getFileSystemService(), cwd);
205
- config.setFileSystemService(acpFileSystemService);
206
- }
207
- await config.initialize();
208
- startupProfiler.flush(config);
209
- startAutoMemoryIfEnabled(config);
210
- const geminiClient = config.getGeminiClient();
211
- const chat = await geminiClient.startChat();
212
- const session = new Session(sessionId, chat, config, this.connection, this.settings);
213
- this.sessions.set(sessionId, session);
214
- setTimeout(() => {
215
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
216
- session.sendAvailableCommands();
217
- }, 0);
218
- const { availableModels, currentModelId } = buildAvailableModels(config, loadedSettings);
219
- const response = {
220
- sessionId,
221
- modes: {
222
- availableModes: buildAvailableModes(config.isPlanEnabled()),
223
- currentModeId: config.getApprovalMode(),
224
- },
225
- models: {
226
- availableModels,
227
- currentModelId,
228
- },
229
- };
230
- return response;
231
- }
232
- async loadSession({ sessionId, cwd, mcpServers, }) {
233
- const config = await this.initializeSessionConfig(sessionId, cwd, mcpServers);
234
- const sessionSelector = new SessionSelector(config.storage);
235
- const { sessionData, sessionPath } = await sessionSelector.resolveSession(sessionId);
236
- const clientHistory = convertSessionToClientHistory(sessionData.messages);
237
- const geminiClient = config.getGeminiClient();
238
- await geminiClient.initialize();
239
- await geminiClient.resumeChat(clientHistory, {
240
- conversation: sessionData,
241
- filePath: sessionPath,
242
- });
243
- const session = new Session(sessionId, geminiClient.getChat(), config, this.connection, this.settings);
244
- this.sessions.set(sessionId, session);
245
- // Stream history back to client
246
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
247
- session.streamHistory(sessionData.messages);
248
- setTimeout(() => {
249
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
250
- session.sendAvailableCommands();
251
- }, 0);
252
- const { availableModels, currentModelId } = buildAvailableModels(config, this.settings);
253
- const response = {
254
- modes: {
255
- availableModes: buildAvailableModes(config.isPlanEnabled()),
256
- currentModeId: config.getApprovalMode(),
257
- },
258
- models: {
259
- availableModels,
260
- currentModelId,
261
- },
262
- };
263
- return response;
264
- }
265
- async initializeSessionConfig(sessionId, cwd, mcpServers) {
266
- const selectedAuthType = this.settings.merged.security.auth.selectedType;
267
- if (!selectedAuthType) {
268
- throw acp.RequestError.authRequired();
269
- }
270
- // 1. Create config WITHOUT initializing it (no MCP servers started yet)
271
- const config = await this.newSessionConfig(sessionId, cwd, mcpServers);
272
- // 2. Authenticate BEFORE initializing configuration or starting MCP servers.
273
- // This satisfies the security requirement to verify the user before executing
274
- // potentially unsafe server definitions.
275
- try {
276
- await config.refreshAuth(selectedAuthType, undefined, this.apiKey, this.baseUrl, this.customHeaders);
277
- }
278
- catch (e) {
279
- debugLogger.error(`Authentication failed: ${e}`);
280
- throw acp.RequestError.authRequired();
281
- }
282
- // 3. Set the ACP FileSystemService (if supported) before config initialization
283
- if (this.clientCapabilities?.fs) {
284
- const acpFileSystemService = new AcpFileSystemService(this.connection, sessionId, this.clientCapabilities.fs, config.getFileSystemService(), cwd);
285
- config.setFileSystemService(acpFileSystemService);
286
- }
287
- // 4. Now that we are authenticated, it is safe to initialize the config
288
- // which starts the MCP servers and other heavy resources.
289
- await config.initialize();
290
- startupProfiler.flush(config);
291
- startAutoMemoryIfEnabled(config);
292
- return config;
293
- }
294
- async newSessionConfig(sessionId, cwd, mcpServers, loadedSettings) {
295
- const currentSettings = loadedSettings || this.settings;
296
- const mergedMcpServers = { ...currentSettings.merged.mcpServers };
297
- for (const server of mcpServers) {
298
- if ('type' in server &&
299
- (server.type === 'sse' || server.type === 'http')) {
300
- // HTTP or SSE MCP server
301
- const headers = Object.fromEntries(server.headers.map(({ name, value }) => [name, value]));
302
- mergedMcpServers[server.name] = new MCPServerConfig(undefined, // command
303
- undefined, // args
304
- undefined, // env
305
- undefined, // cwd
306
- server.type === 'sse', // isSse
307
- server.type === 'sse' ? server.url : undefined, // url (sse)
308
- server.type === 'http' ? server.url : undefined, // httpUrl
309
- headers);
310
- }
311
- else if ('command' in server) {
312
- // Stdio MCP server
313
- const env = {};
314
- for (const { name: envName, value } of server.env) {
315
- env[envName] = value;
316
- }
317
- mergedMcpServers[server.name] = new MCPServerConfig(server.command, server.args, env, cwd);
318
- }
319
- }
320
- const settings = {
321
- ...currentSettings.merged,
322
- mcpServers: mergedMcpServers,
323
- };
324
- const config = await loadCliConfig(settings, sessionId, this.argv, { cwd });
325
- createPolicyUpdater(config.getPolicyEngine(), config.messageBus, config.storage);
326
- return config;
327
- }
328
- async cancel(params) {
329
- const session = this.sessions.get(params.sessionId);
330
- if (!session) {
331
- throw new Error(`Session not found: ${params.sessionId}`);
332
- }
333
- await session.cancelPendingPrompt();
334
- }
335
- async prompt(params) {
336
- const session = this.sessions.get(params.sessionId);
337
- if (!session) {
338
- throw new Error(`Session not found: ${params.sessionId}`);
339
- }
340
- return session.prompt(params);
341
- }
342
- async setSessionMode(params) {
343
- const session = this.sessions.get(params.sessionId);
344
- if (!session) {
345
- throw new Error(`Session not found: ${params.sessionId}`);
346
- }
347
- return session.setMode(params.modeId);
348
- }
349
- async unstable_setSessionModel(params) {
350
- const session = this.sessions.get(params.sessionId);
351
- if (!session) {
352
- throw new Error(`Session not found: ${params.sessionId}`);
353
- }
354
- return session.setModel(params.modelId);
355
- }
356
- }
357
19
  export class Session {
358
20
  id;
359
21
  chat;
@@ -362,12 +24,97 @@ export class Session {
362
24
  settings;
363
25
  pendingPrompt = null;
364
26
  commandHandler = new CommandHandler();
27
+ callIdCounter = 0;
28
+ disposeController = new AbortController();
29
+ generateCallId(name) {
30
+ return `${name}-${Date.now()}-${++this.callIdCounter}`;
31
+ }
365
32
  constructor(id, chat, context, connection, settings) {
366
33
  this.id = id;
367
34
  this.chat = chat;
368
35
  this.context = context;
369
36
  this.connection = connection;
370
37
  this.settings = settings;
38
+ coreEvents.on(CoreEvent.ApprovalModeChanged, this.handleApprovalModeChanged);
39
+ // Subscribe to tool confirmation requests to handle policy checks (e.g. auto-allowing safe shell commands)
40
+ this.context.config
41
+ .getMessageBus()
42
+ ?.subscribe(MessageBusType.TOOL_CONFIRMATION_REQUEST, this.handleToolConfirmationRequest, { signal: this.disposeController.signal });
43
+ }
44
+ handleToolConfirmationRequest = async (request) => {
45
+ try {
46
+ const policyEngine = this.context.config.getPolicyEngine?.();
47
+ const messageBus = this.context.config.getMessageBus();
48
+ if (!messageBus) {
49
+ return;
50
+ }
51
+ if (!policyEngine) {
52
+ debugLogger.warn('Policy engine missing. Denying tool confirmation request.');
53
+ await messageBus.publish({
54
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
55
+ correlationId: request.correlationId,
56
+ confirmed: false,
57
+ requiresUserConfirmation: false,
58
+ });
59
+ return;
60
+ }
61
+ const toolName = request.toolCall.name?.trim();
62
+ if (!toolName) {
63
+ debugLogger.warn('Tool confirmation request missing tool name. Denying.');
64
+ await messageBus.publish({
65
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
66
+ correlationId: request.correlationId,
67
+ confirmed: false,
68
+ requiresUserConfirmation: false,
69
+ });
70
+ return;
71
+ }
72
+ const tool = this.context.toolRegistry.getTool(toolName);
73
+ if (!tool) {
74
+ debugLogger.warn(`Tool confirmation request for unknown tool: ${toolName}. Denying.`);
75
+ await messageBus.publish({
76
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
77
+ correlationId: request.correlationId,
78
+ confirmed: false,
79
+ requiresUserConfirmation: false,
80
+ });
81
+ return;
82
+ }
83
+ const serverName = tool instanceof DiscoveredMCPTool ? tool.serverName : undefined;
84
+ const toolAnnotations = tool.toolAnnotations;
85
+ const result = await policyEngine.check(request.toolCall, serverName, toolAnnotations, request.subagent);
86
+ await messageBus.publish({
87
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
88
+ correlationId: request.correlationId,
89
+ confirmed: result.decision === PolicyDecision.ALLOW,
90
+ requiresUserConfirmation: result.decision === PolicyDecision.ASK_USER,
91
+ });
92
+ }
93
+ catch (error) {
94
+ debugLogger.error('Error handling tool confirmation request:', error);
95
+ // Fail closed on exception
96
+ await this.context.config.getMessageBus()?.publish({
97
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
98
+ correlationId: request.correlationId,
99
+ confirmed: false,
100
+ requiresUserConfirmation: false,
101
+ });
102
+ }
103
+ };
104
+ handleApprovalModeChanged = (payload) => {
105
+ if (payload.sessionId === this.id) {
106
+ void this.sendUpdate({
107
+ sessionUpdate: 'agent_message_chunk',
108
+ content: {
109
+ type: 'text',
110
+ text: `[MODE_UPDATE] ${payload.mode}`,
111
+ },
112
+ });
113
+ }
114
+ };
115
+ dispose() {
116
+ coreEvents.off(CoreEvent.ApprovalModeChanged, this.handleApprovalModeChanged);
117
+ this.disposeController.abort();
371
118
  }
372
119
  async cancelPendingPrompt() {
373
120
  if (!this.pendingPrompt) {
@@ -474,19 +221,15 @@ export class Session {
474
221
  this.pendingPrompt = pendingSend;
475
222
  await this.context.config.waitForMcpInit();
476
223
  const promptId = Math.random().toString(16).slice(2);
477
- const chat = this.chat;
478
224
  const parts = await this.#resolvePrompt(params.prompt, pendingSend.signal);
479
225
  // Command interception
480
226
  let commandText = '';
481
227
  for (const part of parts) {
482
228
  if (typeof part === 'object' && part !== null) {
483
- if ('text' in part) {
229
+ if (isTextPart(part)) {
484
230
  // It is a text part
485
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-type-assertion
486
231
  const text = part.text;
487
- if (typeof text === 'string') {
488
- commandText += text;
489
- }
232
+ commandText += text;
490
233
  }
491
234
  else {
492
235
  // Non-text part (image, embedded resource)
@@ -517,78 +260,97 @@ export class Session {
517
260
  let totalInputTokens = 0;
518
261
  let totalOutputTokens = 0;
519
262
  const modelUsageMap = new Map();
520
- let nextMessage = { role: 'user', parts };
521
- while (nextMessage !== null) {
263
+ let currentParts = parts;
264
+ let turnCount = 0;
265
+ const maxTurns = this.context.config.getMaxSessionTurns();
266
+ while (true) {
267
+ turnCount++;
268
+ if (maxTurns >= 0 && turnCount > maxTurns) {
269
+ return {
270
+ stopReason: 'max_turn_requests',
271
+ _meta: {
272
+ quota: {
273
+ token_count: {
274
+ input_tokens: totalInputTokens,
275
+ output_tokens: totalOutputTokens,
276
+ },
277
+ model_usage: Array.from(modelUsageMap.entries()).map(([modelName, counts]) => ({
278
+ model: modelName,
279
+ token_count: {
280
+ input_tokens: counts.input,
281
+ output_tokens: counts.output,
282
+ },
283
+ })),
284
+ },
285
+ },
286
+ };
287
+ }
522
288
  if (pendingSend.signal.aborted) {
523
- chat.addHistory(nextMessage);
524
- return { stopReason: CoreToolCallStatus.Cancelled };
289
+ return { stopReason: 'cancelled' };
525
290
  }
526
- const functionCalls = [];
291
+ const toolCallRequests = [];
292
+ let stopReason = 'end_turn';
293
+ let turnModelId = this.context.config.getModel();
294
+ let turnInputTokens = 0;
295
+ let turnOutputTokens = 0;
527
296
  try {
528
- const routingContext = {
529
- history: chat.getHistory(/*curated=*/ true),
530
- request: nextMessage?.parts ?? [],
531
- signal: pendingSend.signal,
532
- requestedModel: this.context.config.getModel(),
533
- };
534
- const router = this.context.config.getModelRouterService();
535
- const { model } = await router.route(routingContext);
536
- const responseStream = await chat.sendMessageStream({ model }, nextMessage?.parts ?? [], promptId, pendingSend.signal, LlmRole.MAIN);
537
- nextMessage = null;
538
- let turnInputTokens = 0;
539
- let turnOutputTokens = 0;
540
- let turnModelId = model;
541
- for await (const resp of responseStream) {
297
+ const responseStream = this.context.geminiClient.sendMessageStream(currentParts, pendingSend.signal, promptId);
298
+ for await (const event of responseStream) {
542
299
  if (pendingSend.signal.aborted) {
543
- return { stopReason: CoreToolCallStatus.Cancelled };
544
- }
545
- if (resp.type === StreamEventType.CHUNK && resp.value.usageMetadata) {
546
- turnInputTokens =
547
- resp.value.usageMetadata.promptTokenCount ?? turnInputTokens;
548
- turnOutputTokens =
549
- resp.value.usageMetadata.candidatesTokenCount ?? turnOutputTokens;
550
- if (resp.value.modelVersion) {
551
- turnModelId = resp.value.modelVersion;
552
- }
300
+ return { stopReason: 'cancelled' };
553
301
  }
554
- if (resp.type === StreamEventType.CHUNK &&
555
- resp.value.candidates &&
556
- resp.value.candidates.length > 0) {
557
- const candidate = resp.value.candidates[0];
558
- for (const part of candidate.content?.parts ?? []) {
559
- if (!part.text) {
560
- continue;
561
- }
302
+ switch (event.type) {
303
+ case GeminiEventType.Content: {
562
304
  const content = {
563
305
  type: 'text',
564
- text: part.text,
306
+ text: event.value,
565
307
  };
566
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
567
- this.sendUpdate({
568
- sessionUpdate: part.thought
569
- ? 'agent_thought_chunk'
570
- : 'agent_message_chunk',
308
+ await this.sendUpdate({
309
+ sessionUpdate: 'agent_message_chunk',
571
310
  content,
572
311
  });
312
+ break;
573
313
  }
314
+ case GeminiEventType.Thought: {
315
+ const thoughtText = `**${event.value.subject}**\n${event.value.description}`;
316
+ await this.sendUpdate({
317
+ sessionUpdate: 'agent_thought_chunk',
318
+ content: { type: 'text', text: thoughtText },
319
+ });
320
+ break;
321
+ }
322
+ case GeminiEventType.ToolCallRequest:
323
+ toolCallRequests.push(event.value);
324
+ break;
325
+ case GeminiEventType.Finished: {
326
+ const usage = event.value.usageMetadata;
327
+ if (usage) {
328
+ turnInputTokens = usage.promptTokenCount ?? turnInputTokens;
329
+ turnOutputTokens =
330
+ usage.candidatesTokenCount ?? turnOutputTokens;
331
+ }
332
+ break;
333
+ }
334
+ case GeminiEventType.ModelInfo:
335
+ turnModelId = event.value;
336
+ break;
337
+ case GeminiEventType.MaxSessionTurns:
338
+ stopReason = 'max_turn_requests';
339
+ break;
340
+ case GeminiEventType.LoopDetected:
341
+ stopReason = 'max_turn_requests';
342
+ break;
343
+ case GeminiEventType.ContextWindowWillOverflow:
344
+ stopReason = 'max_tokens';
345
+ break;
346
+ case GeminiEventType.Error: {
347
+ const parseResult = StructuredErrorSchema.safeParse(event.value.error);
348
+ const errData = parseResult.success ? parseResult.data : {};
349
+ throw new acp.RequestError(errData.status ?? 500, errData.message ?? 'Unknown stream execution error.');
350
+ }
351
+ default:
352
+ break;
574
353
  }
575
- if (resp.type === StreamEventType.CHUNK && resp.value.functionCalls) {
576
- functionCalls.push(...resp.value.functionCalls);
577
- }
578
- }
579
- totalInputTokens += turnInputTokens;
580
- totalOutputTokens += turnOutputTokens;
581
- if (turnInputTokens > 0 || turnOutputTokens > 0) {
582
- const existing = modelUsageMap.get(turnModelId) ?? {
583
- input: 0,
584
- output: 0,
585
- };
586
- existing.input += turnInputTokens;
587
- existing.output += turnOutputTokens;
588
- modelUsageMap.set(turnModelId, existing);
589
- }
590
- if (pendingSend.signal.aborted) {
591
- return { stopReason: CoreToolCallStatus.Cancelled };
592
354
  }
593
355
  }
594
356
  catch (error) {
@@ -597,7 +359,10 @@ export class Session {
597
359
  }
598
360
  if (pendingSend.signal.aborted ||
599
361
  (error instanceof Error && error.name === 'AbortError')) {
600
- return { stopReason: CoreToolCallStatus.Cancelled };
362
+ return { stopReason: 'cancelled' };
363
+ }
364
+ if (error instanceof acp.RequestError) {
365
+ throw error;
601
366
  }
602
367
  if (error instanceof InvalidStreamError ||
603
368
  (error &&
@@ -630,14 +395,51 @@ export class Session {
630
395
  }
631
396
  throw new acp.RequestError(getErrorStatus(error) || 500, getAcpErrorMessage(error));
632
397
  }
633
- if (functionCalls.length > 0) {
634
- const toolResponseParts = [];
635
- for (const fc of functionCalls) {
636
- const response = await this.runTool(pendingSend.signal, promptId, fc);
637
- toolResponseParts.push(...response);
638
- }
639
- nextMessage = { role: 'user', parts: toolResponseParts };
398
+ totalInputTokens += turnInputTokens;
399
+ totalOutputTokens += turnOutputTokens;
400
+ if (turnInputTokens > 0 || turnOutputTokens > 0) {
401
+ const existing = modelUsageMap.get(turnModelId) ?? {
402
+ input: 0,
403
+ output: 0,
404
+ };
405
+ existing.input += turnInputTokens;
406
+ existing.output += turnOutputTokens;
407
+ modelUsageMap.set(turnModelId, existing);
408
+ }
409
+ if (stopReason !== 'end_turn') {
410
+ return {
411
+ stopReason,
412
+ _meta: {
413
+ quota: {
414
+ token_count: {
415
+ input_tokens: totalInputTokens,
416
+ output_tokens: totalOutputTokens,
417
+ },
418
+ model_usage: Array.from(modelUsageMap.entries()).map(([modelName, counts]) => ({
419
+ model: modelName,
420
+ token_count: {
421
+ input_tokens: counts.input,
422
+ output_tokens: counts.output,
423
+ },
424
+ })),
425
+ },
426
+ },
427
+ };
428
+ }
429
+ if (toolCallRequests.length === 0) {
430
+ break;
640
431
  }
432
+ const toolResponseParts = [];
433
+ for (const tReq of toolCallRequests) {
434
+ const fc = {
435
+ id: tReq.callId,
436
+ name: tReq.name,
437
+ args: tReq.args,
438
+ };
439
+ const response = await this.runTool(pendingSend.signal, promptId, fc);
440
+ toolResponseParts.push(...response);
441
+ }
442
+ currentParts = toolResponseParts;
641
443
  }
642
444
  const modelUsageArray = Array.from(modelUsageMap.entries()).map(([modelName, counts]) => ({
643
445
  model: modelName,
@@ -684,7 +486,7 @@ export class Session {
684
486
  await this.connection.sessionUpdate(params);
685
487
  }
686
488
  async runTool(abortSignal, promptId, fc) {
687
- const callId = fc.id ?? GeminiAgent.generateCallId(fc.name || 'unknown');
489
+ const callId = fc.id ?? this.generateCallId(fc.name || 'unknown');
688
490
  const args = fc.args ?? {};
689
491
  const startTime = Date.now();
690
492
  const errorResponse = (error) => {
@@ -718,12 +520,6 @@ export class Session {
718
520
  const explanation = typeof invocation.getExplanation === 'function'
719
521
  ? invocation.getExplanation()
720
522
  : '';
721
- if (explanation) {
722
- await this.sendUpdate({
723
- sessionUpdate: 'agent_thought_chunk',
724
- content: { type: 'text', text: explanation },
725
- });
726
- }
727
523
  const confirmationDetails = await invocation.shouldConfirmExecute(abortSignal);
728
524
  if (confirmationDetails) {
729
525
  const content = [];
@@ -742,6 +538,12 @@ export class Session {
742
538
  },
743
539
  });
744
540
  }
541
+ if (content.length === 0 && explanation) {
542
+ content.push({
543
+ type: 'content',
544
+ content: { type: 'text', text: explanation },
545
+ });
546
+ }
745
547
  const params = {
746
548
  sessionId: this.id,
747
549
  options: toPermissionOptions(confirmationDetails, this.context.config, this.settings.merged.security.enablePermanentToolApproval),
@@ -781,6 +583,12 @@ export class Session {
781
583
  }
782
584
  else {
783
585
  const content = [];
586
+ if (explanation) {
587
+ content.push({
588
+ type: 'content',
589
+ content: { type: 'text', text: explanation },
590
+ });
591
+ }
784
592
  await this.sendUpdate({
785
593
  sessionUpdate: 'tool_call',
786
594
  toolCallId: callId,
@@ -942,80 +750,101 @@ export class Session {
942
750
  let currentPathSpec = pathName;
943
751
  let resolvedSuccessfully = false;
944
752
  let readDirectly = false;
945
- try {
946
- const absolutePath = path.resolve(this.context.config.getTargetDir(), pathName);
947
- let validationError = this.context.config.validatePathAccess(absolutePath, 'read');
948
- // We ask the user for explicit permission to read them if outside sandboxed workspace boundaries (and not already authorized).
949
- if (validationError &&
950
- !isWithinRoot(absolutePath, this.context.config.getTargetDir())) {
951
- try {
952
- const stats = await fs.stat(absolutePath);
953
- if (stats.isFile()) {
954
- const syntheticCallId = `resolve-prompt-${pathName}-${randomUUID()}`;
955
- const params = {
956
- sessionId: this.id,
957
- options: [
958
- {
959
- optionId: ToolConfirmationOutcome.ProceedOnce,
960
- name: 'Allow once',
961
- kind: 'allow_once',
962
- },
753
+ const result = await resolveAtCommandPath(pathName, this.context.config, (msg) => this.debug(msg));
754
+ let validationError = null;
755
+ let absolutePath;
756
+ let resolved;
757
+ if (result.status === 'resolved') {
758
+ resolved = result.resolved;
759
+ absolutePath = resolved.absolutePath;
760
+ }
761
+ else if (result.status === 'unauthorized') {
762
+ absolutePath = result.absolutePath;
763
+ validationError = result.error;
764
+ }
765
+ else if (result.status === 'invalid') {
766
+ // Already logged in resolveAtCommandPath
767
+ continue;
768
+ }
769
+ else {
770
+ // Result is not_found.
771
+ // We still check if it's an unauthorized absolute path that we can ask permission for,
772
+ // specifically for paths that are completely outside the root and not even in any workspace directory.
773
+ // For relative paths not found anywhere, we resolve relative to targetDir for permission check.
774
+ absolutePath = path.resolve(this.context.config.getTargetDir(), pathName);
775
+ }
776
+ if (!resolved &&
777
+ validationError &&
778
+ !isWithinRoot(absolutePath, this.context.config.getTargetDir())) {
779
+ try {
780
+ const stats = await fs.stat(absolutePath);
781
+ if (stats.isFile()) {
782
+ const syntheticCallId = `resolve-prompt-${pathName}-${randomUUID()}`;
783
+ const params = {
784
+ sessionId: this.id,
785
+ options: [
786
+ {
787
+ optionId: ToolConfirmationOutcome.ProceedOnce,
788
+ name: 'Allow once',
789
+ kind: 'allow_once',
790
+ },
791
+ {
792
+ optionId: ToolConfirmationOutcome.Cancel,
793
+ name: 'Deny',
794
+ kind: 'reject_once',
795
+ },
796
+ ],
797
+ toolCall: {
798
+ toolCallId: syntheticCallId,
799
+ status: 'pending',
800
+ title: `Allow access to absolute path: ${pathName}`,
801
+ content: [
963
802
  {
964
- optionId: ToolConfirmationOutcome.Cancel,
965
- name: 'Deny',
966
- kind: 'reject_once',
803
+ type: 'content',
804
+ content: {
805
+ type: 'text',
806
+ text: `The Agent needs access to read an attached file outside your workspace: ${pathName}`,
807
+ },
967
808
  },
968
809
  ],
969
- toolCall: {
970
- toolCallId: syntheticCallId,
971
- status: 'pending',
972
- title: `Allow access to absolute path: ${pathName}`,
973
- content: [
974
- {
975
- type: 'content',
976
- content: {
977
- type: 'text',
978
- text: `The Agent needs access to read an attached file outside your workspace: ${pathName}`,
979
- },
980
- },
981
- ],
982
- locations: [],
983
- kind: 'read',
984
- },
985
- };
986
- const output = RequestPermissionResponseSchema.parse(await this.connection.requestPermission(params));
987
- const outcome = output.outcome.outcome === 'cancelled'
988
- ? ToolConfirmationOutcome.Cancel
989
- : z
990
- .nativeEnum(ToolConfirmationOutcome)
991
- .parse(output.outcome.optionId);
992
- if (outcome === ToolConfirmationOutcome.ProceedOnce) {
993
- this.context.config
994
- .getWorkspaceContext()
995
- .addReadOnlyPath(absolutePath);
996
- validationError = null;
997
- }
998
- else {
999
- this.debug(`Direct read authorization denied for absolute path ${pathName}`);
1000
- directContents.push({
1001
- spec: pathName,
1002
- content: `[Warning: Access to absolute path \`${pathName}\` denied by user.]`,
1003
- });
1004
- continue;
1005
- }
1006
- }
1007
- }
1008
- catch (error) {
1009
- this.debug(`Failed to request permission for absolute attachment ${pathName}: ${getErrorMessage(error)}`);
1010
- await this.sendUpdate({
1011
- sessionUpdate: 'agent_thought_chunk',
1012
- content: {
1013
- type: 'text',
1014
- text: `Warning: Failed to display permission dialog for \`${absolutePath}\`. Error: ${getErrorMessage(error)}`,
810
+ locations: [],
811
+ kind: 'read',
1015
812
  },
1016
- });
813
+ };
814
+ const output = RequestPermissionResponseSchema.parse(await this.connection.requestPermission(params));
815
+ const outcome = output.outcome.outcome === 'cancelled'
816
+ ? ToolConfirmationOutcome.Cancel
817
+ : z
818
+ .nativeEnum(ToolConfirmationOutcome)
819
+ .parse(output.outcome.optionId);
820
+ if (outcome === ToolConfirmationOutcome.ProceedOnce) {
821
+ this.context.config
822
+ .getWorkspaceContext()
823
+ .addReadOnlyPath(absolutePath);
824
+ validationError = null;
825
+ }
826
+ else {
827
+ this.debug(`Direct read authorization denied for absolute path ${pathName}`);
828
+ directContents.push({
829
+ spec: pathName,
830
+ content: `[Warning: Access to absolute path \`${pathName}\` denied by user.]`,
831
+ });
832
+ continue;
833
+ }
1017
834
  }
1018
835
  }
836
+ catch (error) {
837
+ this.debug(`Failed to request permission for absolute attachment ${pathName}: ${getErrorMessage(error)}`);
838
+ await this.sendUpdate({
839
+ sessionUpdate: 'agent_thought_chunk',
840
+ content: {
841
+ type: 'text',
842
+ text: `Warning: Failed to display permission dialog for \`${absolutePath}\`. Error: ${getErrorMessage(error)}`,
843
+ },
844
+ });
845
+ }
846
+ }
847
+ try {
1019
848
  if (!validationError) {
1020
849
  // If it's an absolute path that is authorized (e.g. added via readOnlyPaths),
1021
850
  // read it directly to avoid ReadManyFilesTool absolute path resolution issues.
@@ -1023,7 +852,9 @@ export class Session {
1023
852
  !isWithinRoot(absolutePath, this.context.config.getTargetDir())) &&
1024
853
  !readDirectly) {
1025
854
  try {
1026
- const stats = await fs.stat(absolutePath);
855
+ const stats = resolved
856
+ ? resolved.stats
857
+ : await fs.stat(absolutePath);
1027
858
  if (stats.isFile()) {
1028
859
  const fileReadResult = await processSingleFileContent(absolutePath, this.context.config.getTargetDir(), this.context.config.getFileSystemService());
1029
860
  if (!fileReadResult.error) {
@@ -1073,7 +904,9 @@ export class Session {
1073
904
  }
1074
905
  }
1075
906
  if (!readDirectly) {
1076
- const stats = await fs.stat(absolutePath);
907
+ const stats = resolved
908
+ ? resolved.stats
909
+ : await fs.stat(absolutePath);
1077
910
  if (stats.isDirectory()) {
1078
911
  currentPathSpec = pathName.endsWith('/')
1079
912
  ? `${pathName}**`
@@ -1202,7 +1035,7 @@ export class Session {
1202
1035
  const toolArgs = {
1203
1036
  include: pathSpecsToRead,
1204
1037
  };
1205
- const callId = GeminiAgent.generateCallId(readManyFilesTool.name);
1038
+ const callId = this.generateCallId(readManyFilesTool.name);
1206
1039
  try {
1207
1040
  const invocation = readManyFilesTool.build(toolArgs);
1208
1041
  await this.sendUpdate({
@@ -1332,285 +1165,4 @@ export class Session {
1332
1165
  }
1333
1166
  }
1334
1167
  }
1335
- function toToolCallContent(toolResult) {
1336
- if (toolResult.error?.message) {
1337
- throw new Error(toolResult.error.message);
1338
- }
1339
- if (toolResult.returnDisplay) {
1340
- if (typeof toolResult.returnDisplay === 'string') {
1341
- return {
1342
- type: 'content',
1343
- content: { type: 'text', text: toolResult.returnDisplay },
1344
- };
1345
- }
1346
- else {
1347
- if ('fileName' in toolResult.returnDisplay) {
1348
- return {
1349
- type: 'diff',
1350
- path: toolResult.returnDisplay.filePath ??
1351
- toolResult.returnDisplay.fileName,
1352
- oldText: toolResult.returnDisplay.originalContent,
1353
- newText: toolResult.returnDisplay.newContent,
1354
- _meta: {
1355
- kind: !toolResult.returnDisplay.originalContent
1356
- ? 'add'
1357
- : toolResult.returnDisplay.newContent === ''
1358
- ? 'delete'
1359
- : 'modify',
1360
- },
1361
- };
1362
- }
1363
- return null;
1364
- }
1365
- }
1366
- else {
1367
- return null;
1368
- }
1369
- }
1370
- const basicPermissionOptions = [
1371
- {
1372
- optionId: ToolConfirmationOutcome.ProceedOnce,
1373
- name: 'Allow',
1374
- kind: 'allow_once',
1375
- },
1376
- {
1377
- optionId: ToolConfirmationOutcome.Cancel,
1378
- name: 'Reject',
1379
- kind: 'reject_once',
1380
- },
1381
- ];
1382
- function toPermissionOptions(confirmation, config, enablePermanentToolApproval = false) {
1383
- const disableAlwaysAllow = config.getDisableAlwaysAllow();
1384
- const options = [];
1385
- if (!disableAlwaysAllow) {
1386
- switch (confirmation.type) {
1387
- case 'edit':
1388
- options.push({
1389
- optionId: ToolConfirmationOutcome.ProceedAlways,
1390
- name: 'Allow for this session',
1391
- kind: 'allow_always',
1392
- });
1393
- if (enablePermanentToolApproval) {
1394
- options.push({
1395
- optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
1396
- name: 'Allow for this file in all future sessions',
1397
- kind: 'allow_always',
1398
- });
1399
- }
1400
- break;
1401
- case 'exec':
1402
- options.push({
1403
- optionId: ToolConfirmationOutcome.ProceedAlways,
1404
- name: 'Allow for this session',
1405
- kind: 'allow_always',
1406
- });
1407
- if (enablePermanentToolApproval) {
1408
- options.push({
1409
- optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
1410
- name: 'Allow this command for all future sessions',
1411
- kind: 'allow_always',
1412
- });
1413
- }
1414
- break;
1415
- case 'mcp':
1416
- options.push({
1417
- optionId: ToolConfirmationOutcome.ProceedAlwaysServer,
1418
- name: 'Allow all server tools for this session',
1419
- kind: 'allow_always',
1420
- }, {
1421
- optionId: ToolConfirmationOutcome.ProceedAlwaysTool,
1422
- name: 'Allow tool for this session',
1423
- kind: 'allow_always',
1424
- });
1425
- if (enablePermanentToolApproval) {
1426
- options.push({
1427
- optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
1428
- name: 'Allow tool for all future sessions',
1429
- kind: 'allow_always',
1430
- });
1431
- }
1432
- break;
1433
- case 'info':
1434
- options.push({
1435
- optionId: ToolConfirmationOutcome.ProceedAlways,
1436
- name: 'Allow for this session',
1437
- kind: 'allow_always',
1438
- });
1439
- if (enablePermanentToolApproval) {
1440
- options.push({
1441
- optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
1442
- name: 'Allow for all future sessions',
1443
- kind: 'allow_always',
1444
- });
1445
- }
1446
- break;
1447
- case 'ask_user':
1448
- case 'exit_plan_mode':
1449
- // askuser and exit_plan_mode don't need "always allow" options
1450
- break;
1451
- default:
1452
- // No "always allow" options for other types
1453
- break;
1454
- }
1455
- }
1456
- options.push(...basicPermissionOptions);
1457
- // Exhaustive check
1458
- switch (confirmation.type) {
1459
- case 'edit':
1460
- case 'exec':
1461
- case 'mcp':
1462
- case 'info':
1463
- case 'ask_user':
1464
- case 'exit_plan_mode':
1465
- case 'sandbox_expansion':
1466
- break;
1467
- default: {
1468
- const unreachable = confirmation;
1469
- throw new Error(`Unexpected: ${unreachable}`);
1470
- }
1471
- }
1472
- return options;
1473
- }
1474
- /**
1475
- * Maps our internal tool kind to the ACP ToolKind.
1476
- * Fallback to 'other' for kinds that are not supported by the ACP protocol.
1477
- */
1478
- function toAcpToolKind(kind) {
1479
- switch (kind) {
1480
- case Kind.Read:
1481
- case Kind.Edit:
1482
- case Kind.Execute:
1483
- case Kind.Search:
1484
- case Kind.Delete:
1485
- case Kind.Move:
1486
- case Kind.Think:
1487
- case Kind.Fetch:
1488
- case Kind.SwitchMode:
1489
- case Kind.Other:
1490
- return kind;
1491
- case Kind.Agent:
1492
- return 'think';
1493
- case Kind.Plan:
1494
- case Kind.Communicate:
1495
- default:
1496
- return 'other';
1497
- }
1498
- }
1499
- function buildAvailableModes(isPlanEnabled) {
1500
- const modes = [
1501
- {
1502
- id: ApprovalMode.DEFAULT,
1503
- name: 'Default',
1504
- description: 'Prompts for approval',
1505
- },
1506
- {
1507
- id: ApprovalMode.AUTO_EDIT,
1508
- name: 'Auto Edit',
1509
- description: 'Auto-approves edit tools',
1510
- },
1511
- {
1512
- id: ApprovalMode.YOLO,
1513
- name: 'YOLO',
1514
- description: 'Auto-approves all tools',
1515
- },
1516
- ];
1517
- if (isPlanEnabled) {
1518
- modes.push({
1519
- id: ApprovalMode.PLAN,
1520
- name: 'Plan',
1521
- description: 'Read-only mode',
1522
- });
1523
- }
1524
- return modes;
1525
- }
1526
- function buildAvailableModels(config, settings) {
1527
- const preferredModel = config.getModel() || DEFAULT_GEMINI_MODEL_AUTO;
1528
- const shouldShowPreviewModels = config.getHasAccessToPreviewModel();
1529
- const useGemini31 = config.getGemini31LaunchedSync?.() ?? false;
1530
- const useGemini31FlashLite = config.getGemini31FlashLiteLaunchedSync?.() ?? false;
1531
- const selectedAuthType = settings.merged.security.auth.selectedType;
1532
- const useCustomToolModel = useGemini31 && selectedAuthType === AuthType.USE_GEMINI;
1533
- // --- DYNAMIC PATH ---
1534
- if (config.getExperimentalDynamicModelConfiguration?.() === true &&
1535
- config.getModelConfigService) {
1536
- const options = config.getModelConfigService().getAvailableModelOptions({
1537
- useGemini3_1: useGemini31,
1538
- useGemini3_1FlashLite: useGemini31FlashLite,
1539
- useCustomTools: useCustomToolModel,
1540
- hasAccessToPreview: shouldShowPreviewModels,
1541
- });
1542
- return {
1543
- availableModels: options,
1544
- currentModelId: preferredModel,
1545
- };
1546
- }
1547
- // --- LEGACY PATH ---
1548
- const mainOptions = [
1549
- {
1550
- value: DEFAULT_GEMINI_MODEL_AUTO,
1551
- title: getDisplayString(DEFAULT_GEMINI_MODEL_AUTO),
1552
- description: 'Let Cell CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash',
1553
- },
1554
- ];
1555
- if (shouldShowPreviewModels) {
1556
- mainOptions.unshift({
1557
- value: PREVIEW_GEMINI_MODEL_AUTO,
1558
- title: getDisplayString(PREVIEW_GEMINI_MODEL_AUTO),
1559
- description: useGemini31
1560
- ? 'Let Cell CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash'
1561
- : 'Let Cell CLI decide the best model for the task: gemini-3-pro, gemini-3-flash',
1562
- });
1563
- }
1564
- const manualOptions = [
1565
- {
1566
- value: DEFAULT_GEMINI_MODEL,
1567
- title: getDisplayString(DEFAULT_GEMINI_MODEL),
1568
- },
1569
- {
1570
- value: DEFAULT_GEMINI_FLASH_MODEL,
1571
- title: getDisplayString(DEFAULT_GEMINI_FLASH_MODEL),
1572
- },
1573
- {
1574
- value: DEFAULT_GEMINI_FLASH_LITE_MODEL,
1575
- title: getDisplayString(DEFAULT_GEMINI_FLASH_LITE_MODEL),
1576
- },
1577
- ];
1578
- if (shouldShowPreviewModels) {
1579
- const previewProModel = useGemini31
1580
- ? PREVIEW_GEMINI_3_1_MODEL
1581
- : PREVIEW_GEMINI_MODEL;
1582
- const previewProValue = useCustomToolModel
1583
- ? PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL
1584
- : previewProModel;
1585
- const previewOptions = [
1586
- {
1587
- value: previewProValue,
1588
- title: getDisplayString(previewProModel),
1589
- },
1590
- {
1591
- value: PREVIEW_GEMINI_FLASH_MODEL,
1592
- title: getDisplayString(PREVIEW_GEMINI_FLASH_MODEL),
1593
- },
1594
- ];
1595
- if (useGemini31FlashLite) {
1596
- previewOptions.push({
1597
- value: PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL,
1598
- title: getDisplayString(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL),
1599
- });
1600
- }
1601
- manualOptions.unshift(...previewOptions);
1602
- }
1603
- const scaleOptions = (options) => options.map((o) => ({
1604
- modelId: o.value,
1605
- name: o.title,
1606
- description: o.description,
1607
- }));
1608
- return {
1609
- availableModels: [
1610
- ...scaleOptions(mainOptions),
1611
- ...scaleOptions(manualOptions),
1612
- ],
1613
- currentModelId: preferredModel,
1614
- };
1615
- }
1616
- //# sourceMappingURL=acpClient.js.map
1168
+ //# sourceMappingURL=acpSession.js.map