@machina.ai/cell-cli 1.13.0-rc5 → 1.16.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 (443) hide show
  1. package/dist/package.json +4 -4
  2. package/dist/src/commands/extensions/disable.js +2 -2
  3. package/dist/src/commands/extensions/disable.js.map +1 -1
  4. package/dist/src/commands/extensions/enable.js +4 -4
  5. package/dist/src/commands/extensions/enable.js.map +1 -1
  6. package/dist/src/commands/extensions/examples/mcp-server/package.json +1 -1
  7. package/dist/src/commands/extensions.js +1 -1
  8. package/dist/src/commands/extensions.js.map +1 -1
  9. package/dist/src/config/config.d.ts +4 -8
  10. package/dist/src/config/config.js +37 -24
  11. package/dist/src/config/config.js.map +1 -1
  12. package/dist/src/config/config.test.js +31 -11
  13. package/dist/src/config/config.test.js.map +1 -1
  14. package/dist/src/config/extension-manager.js +39 -14
  15. package/dist/src/config/extension-manager.js.map +1 -1
  16. package/dist/src/config/extension.test.js +65 -0
  17. package/dist/src/config/extension.test.js.map +1 -1
  18. package/dist/src/config/extensions/extensionSettings.js +3 -2
  19. package/dist/src/config/extensions/extensionSettings.js.map +1 -1
  20. package/dist/src/config/extensions/github.d.ts +1 -1
  21. package/dist/src/config/extensions/github.js +8 -2
  22. package/dist/src/config/extensions/github.js.map +1 -1
  23. package/dist/src/config/extensions/github.test.js +8 -10
  24. package/dist/src/config/extensions/github.test.js.map +1 -1
  25. package/dist/src/config/keyBindings.d.ts +19 -0
  26. package/dist/src/config/keyBindings.js +151 -0
  27. package/dist/src/config/keyBindings.js.map +1 -1
  28. package/dist/src/config/keyBindings.test.js +26 -1
  29. package/dist/src/config/keyBindings.test.js.map +1 -1
  30. package/dist/src/config/policy-engine.integration.test.js +62 -44
  31. package/dist/src/config/policy-engine.integration.test.js.map +1 -1
  32. package/dist/src/config/settingPaths.d.ts +10 -0
  33. package/dist/src/config/settingPaths.js +11 -0
  34. package/dist/src/config/settingPaths.js.map +1 -0
  35. package/dist/src/config/settings.d.ts +15 -5
  36. package/dist/src/config/settings.js +28 -8
  37. package/dist/src/config/settings.js.map +1 -1
  38. package/dist/src/config/settingsSchema.d.ts +64 -7
  39. package/dist/src/config/settingsSchema.js +68 -11
  40. package/dist/src/config/settingsSchema.js.map +1 -1
  41. package/dist/src/config/settingsSchema.test.js +9 -0
  42. package/dist/src/config/settingsSchema.test.js.map +1 -1
  43. package/dist/src/gemini.d.ts +2 -2
  44. package/dist/src/gemini.js +56 -27
  45. package/dist/src/gemini.js.map +1 -1
  46. package/dist/src/gemini.test.js +18 -7
  47. package/dist/src/gemini.test.js.map +1 -1
  48. package/dist/src/generated/git-commit.d.ts +2 -2
  49. package/dist/src/generated/git-commit.js +2 -2
  50. package/dist/src/nonInteractiveCli.d.ts +3 -2
  51. package/dist/src/nonInteractiveCli.js +6 -1
  52. package/dist/src/nonInteractiveCli.js.map +1 -1
  53. package/dist/src/nonInteractiveCli.test.js +2 -1
  54. package/dist/src/nonInteractiveCli.test.js.map +1 -1
  55. package/dist/src/services/BuiltinCommandLoader.d.ts +1 -1
  56. package/dist/src/services/BuiltinCommandLoader.js +2 -2
  57. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  58. package/dist/src/services/BuiltinCommandLoader.test.js +3 -1
  59. package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
  60. package/dist/src/services/FileCommandLoader.js +9 -6
  61. package/dist/src/services/FileCommandLoader.js.map +1 -1
  62. package/dist/src/services/FileCommandLoader.test.js +76 -1
  63. package/dist/src/services/FileCommandLoader.test.js.map +1 -1
  64. package/dist/src/test-utils/render.d.ts +2 -2
  65. package/dist/src/test-utils/render.js +18 -3
  66. package/dist/src/test-utils/render.js.map +1 -1
  67. package/dist/src/ui/App.js +9 -1
  68. package/dist/src/ui/App.js.map +1 -1
  69. package/dist/src/ui/App.test.js +37 -1
  70. package/dist/src/ui/App.test.js.map +1 -1
  71. package/dist/src/ui/AppContainer.d.ts +2 -3
  72. package/dist/src/ui/AppContainer.js +126 -29
  73. package/dist/src/ui/AppContainer.js.map +1 -1
  74. package/dist/src/ui/AppContainer.test.js +356 -48
  75. package/dist/src/ui/AppContainer.test.js.map +1 -1
  76. package/dist/src/ui/auth/AuthDialog.js +1 -1
  77. package/dist/src/ui/auth/AuthDialog.js.map +1 -1
  78. package/dist/src/ui/auth/AuthDialog.test.js +1 -1
  79. package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
  80. package/dist/src/ui/commands/chatCommand.js +15 -3
  81. package/dist/src/ui/commands/chatCommand.js.map +1 -1
  82. package/dist/src/ui/commands/chatCommand.test.js +44 -5
  83. package/dist/src/ui/commands/chatCommand.test.js.map +1 -1
  84. package/dist/src/ui/commands/directoryCommand.js +2 -10
  85. package/dist/src/ui/commands/directoryCommand.js.map +1 -1
  86. package/dist/src/ui/commands/docsCommand.js +1 -1
  87. package/dist/src/ui/commands/docsCommand.js.map +1 -1
  88. package/dist/src/ui/commands/extensionsCommand.d.ts +7 -2
  89. package/dist/src/ui/commands/extensionsCommand.js +238 -24
  90. package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
  91. package/dist/src/ui/commands/extensionsCommand.test.js +323 -82
  92. package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -1
  93. package/dist/src/ui/commands/ideCommand.js +6 -4
  94. package/dist/src/ui/commands/ideCommand.js.map +1 -1
  95. package/dist/src/ui/commands/memoryCommand.js +2 -10
  96. package/dist/src/ui/commands/memoryCommand.js.map +1 -1
  97. package/dist/src/ui/commands/memoryCommand.test.js +11 -28
  98. package/dist/src/ui/commands/memoryCommand.test.js.map +1 -1
  99. package/dist/src/ui/commands/settingsCommand.js +1 -1
  100. package/dist/src/ui/commands/settingsCommand.js.map +1 -1
  101. package/dist/src/ui/commands/settingsCommand.test.js +1 -1
  102. package/dist/src/ui/commands/settingsCommand.test.js.map +1 -1
  103. package/dist/src/ui/commands/setupGithubCommand.js +1 -1
  104. package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
  105. package/dist/src/ui/commands/toolsCommand.js +1 -1
  106. package/dist/src/ui/commands/toolsCommand.js.map +1 -1
  107. package/dist/src/ui/commands/types.d.ts +1 -2
  108. package/dist/src/ui/commands/types.js.map +1 -1
  109. package/dist/src/ui/components/AboutBox.js +1 -1
  110. package/dist/src/ui/components/AboutBox.js.map +1 -1
  111. package/dist/src/ui/components/AlternateBufferQuittingDisplay.d.ts +6 -0
  112. package/dist/src/ui/components/AlternateBufferQuittingDisplay.js +24 -0
  113. package/dist/src/ui/components/AlternateBufferQuittingDisplay.js.map +1 -0
  114. package/dist/src/ui/components/AlternateBufferQuittingDisplay.test.d.ts +6 -0
  115. package/dist/src/ui/components/AlternateBufferQuittingDisplay.test.js +110 -0
  116. package/dist/src/ui/components/AlternateBufferQuittingDisplay.test.js.map +1 -0
  117. package/dist/src/ui/components/AppHeader.js +25 -3
  118. package/dist/src/ui/components/AppHeader.js.map +1 -1
  119. package/dist/src/ui/components/AppHeader.test.d.ts +6 -0
  120. package/dist/src/ui/components/AppHeader.test.js +138 -0
  121. package/dist/src/ui/components/AppHeader.test.js.map +1 -0
  122. package/dist/src/ui/components/AsciiArt.d.ts +6 -3
  123. package/dist/src/ui/components/AsciiArt.js +39 -3
  124. package/dist/src/ui/components/AsciiArt.js.map +1 -1
  125. package/dist/src/ui/components/Banner.d.ts +12 -0
  126. package/dist/src/ui/components/Banner.js +14 -0
  127. package/dist/src/ui/components/Banner.js.map +1 -0
  128. package/dist/src/ui/components/CliSpinner.d.ts +0 -1
  129. package/dist/src/ui/components/CliSpinner.js +3 -4
  130. package/dist/src/ui/components/CliSpinner.js.map +1 -1
  131. package/dist/src/ui/components/CliSpinner.test.d.ts +6 -0
  132. package/dist/src/ui/components/CliSpinner.test.js +23 -0
  133. package/dist/src/ui/components/CliSpinner.test.js.map +1 -0
  134. package/dist/src/ui/components/Composer.js +11 -4
  135. package/dist/src/ui/components/Composer.js.map +1 -1
  136. package/dist/src/ui/components/CopyModeWarning.d.ts +7 -0
  137. package/dist/src/ui/components/CopyModeWarning.js +12 -0
  138. package/dist/src/ui/components/CopyModeWarning.js.map +1 -0
  139. package/dist/src/ui/components/DebugProfiler.js +2 -2
  140. package/dist/src/ui/components/DebugProfiler.js.map +1 -1
  141. package/dist/src/ui/components/DebugProfiler.test.js +15 -0
  142. package/dist/src/ui/components/DebugProfiler.test.js.map +1 -1
  143. package/dist/src/ui/components/DetailedMessagesDisplay.d.ts +1 -0
  144. package/dist/src/ui/components/DetailedMessagesDisplay.js +47 -27
  145. package/dist/src/ui/components/DetailedMessagesDisplay.js.map +1 -1
  146. package/dist/src/ui/components/DialogManager.js +1 -1
  147. package/dist/src/ui/components/DialogManager.js.map +1 -1
  148. package/dist/src/ui/components/EditorSettingsDialog.d.ts +3 -4
  149. package/dist/src/ui/components/EditorSettingsDialog.js +2 -2
  150. package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
  151. package/dist/src/ui/components/FolderTrustDialog.js +1 -1
  152. package/dist/src/ui/components/FolderTrustDialog.js.map +1 -1
  153. package/dist/src/ui/components/FolderTrustDialog.test.js +1 -1
  154. package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
  155. package/dist/src/ui/components/Footer.js +2 -2
  156. package/dist/src/ui/components/Footer.js.map +1 -1
  157. package/dist/src/ui/components/GradientRegression.test.d.ts +6 -0
  158. package/dist/src/ui/components/GradientRegression.test.js +84 -0
  159. package/dist/src/ui/components/GradientRegression.test.js.map +1 -0
  160. package/dist/src/ui/components/Header.js +9 -8
  161. package/dist/src/ui/components/Header.js.map +1 -1
  162. package/dist/src/ui/components/Header.test.js +102 -34
  163. package/dist/src/ui/components/Header.test.js.map +1 -1
  164. package/dist/src/ui/components/Help.js +1 -1
  165. package/dist/src/ui/components/Help.js.map +1 -1
  166. package/dist/src/ui/components/Help.test.js +9 -0
  167. package/dist/src/ui/components/Help.test.js.map +1 -1
  168. package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
  169. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  170. package/dist/src/ui/components/HistoryItemDisplay.test.js +51 -40
  171. package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
  172. package/dist/src/ui/components/InputPrompt.d.ts +3 -0
  173. package/dist/src/ui/components/InputPrompt.js +18 -8
  174. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  175. package/dist/src/ui/components/InputPrompt.test.js +99 -116
  176. package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
  177. package/dist/src/ui/components/MainContent.js +52 -15
  178. package/dist/src/ui/components/MainContent.js.map +1 -1
  179. package/dist/src/ui/components/ModelDialog.js +38 -29
  180. package/dist/src/ui/components/ModelDialog.js.map +1 -1
  181. package/dist/src/ui/components/ModelDialog.test.js +22 -11
  182. package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
  183. package/dist/src/ui/components/PermissionsModifyTrustDialog.js +1 -1
  184. package/dist/src/ui/components/PermissionsModifyTrustDialog.js.map +1 -1
  185. package/dist/src/ui/components/ProQuotaDialog.d.ts +7 -2
  186. package/dist/src/ui/components/ProQuotaDialog.js +80 -15
  187. package/dist/src/ui/components/ProQuotaDialog.js.map +1 -1
  188. package/dist/src/ui/components/ProQuotaDialog.test.js +146 -40
  189. package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -1
  190. package/dist/src/ui/components/SettingsDialog.js +1 -1
  191. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  192. package/dist/src/ui/components/SettingsDialog.test.js +12 -12
  193. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  194. package/dist/src/ui/components/StatsDisplay.js +2 -2
  195. package/dist/src/ui/components/StatsDisplay.js.map +1 -1
  196. package/dist/src/ui/components/StickyHeader.d.ts +14 -0
  197. package/dist/src/ui/components/StickyHeader.js +5 -0
  198. package/dist/src/ui/components/StickyHeader.js.map +1 -0
  199. package/dist/src/ui/components/StickyHeader.test.d.ts +6 -0
  200. package/dist/src/ui/components/StickyHeader.test.js +17 -0
  201. package/dist/src/ui/components/StickyHeader.test.js.map +1 -0
  202. package/dist/src/ui/components/ThemeDialog.d.ts +2 -3
  203. package/dist/src/ui/components/ThemeDialog.js +11 -3
  204. package/dist/src/ui/components/ThemeDialog.js.map +1 -1
  205. package/dist/src/ui/components/ThemeDialog.test.js +3 -3
  206. package/dist/src/ui/components/ThemeDialog.test.js.map +1 -1
  207. package/dist/src/ui/components/ThemedGradient.d.ts +8 -0
  208. package/dist/src/ui/components/ThemedGradient.js +15 -0
  209. package/dist/src/ui/components/ThemedGradient.js.map +1 -0
  210. package/dist/src/ui/components/messages/DiffRenderer.js +129 -89
  211. package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
  212. package/dist/src/ui/components/messages/DiffRenderer.test.js +107 -115
  213. package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -1
  214. package/dist/src/ui/components/messages/GeminiMessage.js +3 -1
  215. package/dist/src/ui/components/messages/GeminiMessage.js.map +1 -1
  216. package/dist/src/ui/components/messages/GeminiMessageContent.js +3 -1
  217. package/dist/src/ui/components/messages/GeminiMessageContent.js.map +1 -1
  218. package/dist/src/ui/components/messages/InfoMessage.d.ts +2 -0
  219. package/dist/src/ui/components/messages/InfoMessage.js +4 -3
  220. package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
  221. package/dist/src/ui/components/messages/Todo.test.js +1 -1
  222. package/dist/src/ui/components/messages/Todo.test.js.map +1 -1
  223. package/dist/src/ui/components/messages/ToolConfirmationMessage.js +151 -122
  224. package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
  225. package/dist/src/ui/components/messages/ToolGroupMessage.js +18 -14
  226. package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
  227. package/dist/src/ui/components/messages/ToolGroupMessage.test.js +57 -32
  228. package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
  229. package/dist/src/ui/components/messages/ToolMessage.d.ts +3 -0
  230. package/dist/src/ui/components/messages/ToolMessage.js +36 -17
  231. package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
  232. package/dist/src/ui/components/messages/ToolMessage.test.js +3 -0
  233. package/dist/src/ui/components/messages/ToolMessage.test.js.map +1 -1
  234. package/dist/src/ui/components/messages/ToolMessageRawMarkdown.test.js +36 -4
  235. package/dist/src/ui/components/messages/ToolMessageRawMarkdown.test.js.map +1 -1
  236. package/dist/src/ui/components/messages/UserMessage.d.ts +1 -0
  237. package/dist/src/ui/components/messages/UserMessage.js +2 -2
  238. package/dist/src/ui/components/messages/UserMessage.js.map +1 -1
  239. package/dist/src/ui/components/shared/ScopeSelector.d.ts +4 -4
  240. package/dist/src/ui/components/shared/Scrollable.d.ts +18 -0
  241. package/dist/src/ui/components/shared/Scrollable.js +84 -0
  242. package/dist/src/ui/components/shared/Scrollable.js.map +1 -0
  243. package/dist/src/ui/components/shared/Scrollable.test.d.ts +6 -0
  244. package/dist/src/ui/components/shared/Scrollable.test.js +74 -0
  245. package/dist/src/ui/components/shared/Scrollable.test.js.map +1 -0
  246. package/dist/src/ui/components/shared/ScrollableList.d.ts +26 -0
  247. package/dist/src/ui/components/shared/ScrollableList.js +152 -0
  248. package/dist/src/ui/components/shared/ScrollableList.js.map +1 -0
  249. package/dist/src/ui/components/shared/ScrollableList.test.d.ts +6 -0
  250. package/dist/src/ui/components/shared/ScrollableList.test.js +228 -0
  251. package/dist/src/ui/components/shared/ScrollableList.test.js.map +1 -0
  252. package/dist/src/ui/components/shared/VirtualizedList.d.ts +44 -0
  253. package/dist/src/ui/components/shared/VirtualizedList.js +312 -0
  254. package/dist/src/ui/components/shared/VirtualizedList.js.map +1 -0
  255. package/dist/src/ui/components/shared/VirtualizedList.test.d.ts +6 -0
  256. package/dist/src/ui/components/shared/VirtualizedList.test.js +171 -0
  257. package/dist/src/ui/components/shared/VirtualizedList.test.js.map +1 -0
  258. package/dist/src/ui/components/shared/text-buffer.d.ts +2 -8
  259. package/dist/src/ui/components/shared/text-buffer.js +1 -1
  260. package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
  261. package/dist/src/ui/components/shared/text-buffer.test.js +35 -0
  262. package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
  263. package/dist/src/ui/components/views/ToolsList.js +1 -1
  264. package/dist/src/ui/components/views/ToolsList.js.map +1 -1
  265. package/dist/src/ui/constants.d.ts +1 -0
  266. package/dist/src/ui/constants.js +5 -0
  267. package/dist/src/ui/constants.js.map +1 -1
  268. package/dist/src/ui/contexts/KeypressContext.d.ts +6 -11
  269. package/dist/src/ui/contexts/KeypressContext.js +456 -756
  270. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  271. package/dist/src/ui/contexts/KeypressContext.test.js +103 -334
  272. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  273. package/dist/src/ui/contexts/MouseContext.js +16 -1
  274. package/dist/src/ui/contexts/MouseContext.js.map +1 -1
  275. package/dist/src/ui/contexts/MouseContext.test.js +34 -0
  276. package/dist/src/ui/contexts/MouseContext.test.js.map +1 -1
  277. package/dist/src/ui/contexts/ScrollProvider.d.ts +25 -0
  278. package/dist/src/ui/contexts/ScrollProvider.drag.test.d.ts +6 -0
  279. package/dist/src/ui/contexts/ScrollProvider.drag.test.js +319 -0
  280. package/dist/src/ui/contexts/ScrollProvider.drag.test.js.map +1 -0
  281. package/dist/src/ui/contexts/ScrollProvider.js +242 -0
  282. package/dist/src/ui/contexts/ScrollProvider.js.map +1 -0
  283. package/dist/src/ui/contexts/ScrollProvider.test.d.ts +6 -0
  284. package/dist/src/ui/contexts/ScrollProvider.test.js +377 -0
  285. package/dist/src/ui/contexts/ScrollProvider.test.js.map +1 -0
  286. package/dist/src/ui/contexts/UIActionsContext.d.ts +6 -5
  287. package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
  288. package/dist/src/ui/contexts/UIStateContext.d.ts +10 -0
  289. package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
  290. package/dist/src/ui/debug.d.ts +8 -0
  291. package/dist/src/ui/debug.js +11 -0
  292. package/dist/src/ui/debug.js.map +1 -0
  293. package/dist/src/ui/editors/editorSettingsManager.d.ts +0 -1
  294. package/dist/src/ui/editors/editorSettingsManager.js +1 -11
  295. package/dist/src/ui/editors/editorSettingsManager.js.map +1 -1
  296. package/dist/src/ui/hooks/atCommandProcessor.js +3 -3
  297. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  298. package/dist/src/ui/hooks/atCommandProcessor.test.js +2 -1
  299. package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
  300. package/dist/src/ui/hooks/slashCommandProcessor.d.ts +1 -1
  301. package/dist/src/ui/hooks/slashCommandProcessor.js +23 -5
  302. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  303. package/dist/src/ui/hooks/slashCommandProcessor.test.js +103 -68
  304. package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
  305. package/dist/src/ui/hooks/useAlternateBuffer.d.ts +8 -0
  306. package/dist/src/ui/hooks/useAlternateBuffer.js +12 -0
  307. package/dist/src/ui/hooks/useAlternateBuffer.js.map +1 -0
  308. package/dist/src/ui/hooks/useAnimatedScrollbar.d.ts +10 -0
  309. package/dist/src/ui/hooks/useAnimatedScrollbar.js +91 -0
  310. package/dist/src/ui/hooks/useAnimatedScrollbar.js.map +1 -0
  311. package/dist/src/ui/hooks/useAnimatedScrollbar.test.d.ts +6 -0
  312. package/dist/src/ui/hooks/useAnimatedScrollbar.test.js +85 -0
  313. package/dist/src/ui/hooks/useAnimatedScrollbar.test.js.map +1 -0
  314. package/dist/src/ui/hooks/useBatchedScroll.d.ts +14 -0
  315. package/dist/src/ui/hooks/useBatchedScroll.js +27 -0
  316. package/dist/src/ui/hooks/useBatchedScroll.js.map +1 -0
  317. package/dist/src/ui/hooks/useBatchedScroll.test.d.ts +6 -0
  318. package/dist/src/ui/hooks/useBatchedScroll.test.js +62 -0
  319. package/dist/src/ui/hooks/useBatchedScroll.test.js.map +1 -0
  320. package/dist/src/ui/hooks/useEditorSettings.d.ts +2 -2
  321. package/dist/src/ui/hooks/useEditorSettings.js +4 -3
  322. package/dist/src/ui/hooks/useEditorSettings.js.map +1 -1
  323. package/dist/src/ui/hooks/useEditorSettings.test.js +17 -8
  324. package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
  325. package/dist/src/ui/hooks/useFocus.test.js +10 -10
  326. package/dist/src/ui/hooks/useFocus.test.js.map +1 -1
  327. package/dist/src/ui/hooks/useGeminiStream.js +2 -2
  328. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  329. package/dist/src/ui/hooks/useGeminiStream.test.js +4 -0
  330. package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
  331. package/dist/src/ui/hooks/useKeypress.test.js +9 -32
  332. package/dist/src/ui/hooks/useKeypress.test.js.map +1 -1
  333. package/dist/src/ui/hooks/usePhraseCycler.js +2 -2
  334. package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
  335. package/dist/src/ui/hooks/usePromptCompletion.js +2 -9
  336. package/dist/src/ui/hooks/usePromptCompletion.js.map +1 -1
  337. package/dist/src/ui/hooks/useQuotaAndFallback.d.ts +3 -5
  338. package/dist/src/ui/hooks/useQuotaAndFallback.js +62 -77
  339. package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -1
  340. package/dist/src/ui/hooks/useQuotaAndFallback.test.js +142 -106
  341. package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
  342. package/dist/src/ui/hooks/useSelectionList.test.js +3 -0
  343. package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
  344. package/dist/src/ui/hooks/useSessionBrowser.d.ts +18 -0
  345. package/dist/src/ui/hooks/useSessionBrowser.js +152 -0
  346. package/dist/src/ui/hooks/useSessionBrowser.js.map +1 -0
  347. package/dist/src/ui/hooks/useSessionBrowser.test.d.ts +6 -0
  348. package/dist/src/ui/hooks/useSessionBrowser.test.js +544 -0
  349. package/dist/src/ui/hooks/useSessionBrowser.test.js.map +1 -0
  350. package/dist/src/ui/hooks/useSessionResume.d.ts +30 -0
  351. package/dist/src/ui/hooks/useSessionResume.js +56 -0
  352. package/dist/src/ui/hooks/useSessionResume.js.map +1 -0
  353. package/dist/src/ui/hooks/useSessionResume.test.d.ts +6 -0
  354. package/dist/src/ui/hooks/useSessionResume.test.js +325 -0
  355. package/dist/src/ui/hooks/useSessionResume.test.js.map +1 -0
  356. package/dist/src/ui/hooks/useThemeCommand.d.ts +2 -2
  357. package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
  358. package/dist/src/ui/hooks/useToolScheduler.test.js +1 -0
  359. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  360. package/dist/src/ui/hooks/vim.js +1 -0
  361. package/dist/src/ui/hooks/vim.js.map +1 -1
  362. package/dist/src/ui/hooks/vim.test.js +1 -0
  363. package/dist/src/ui/hooks/vim.test.js.map +1 -1
  364. package/dist/src/ui/keyMatchers.test.js +38 -0
  365. package/dist/src/ui/keyMatchers.test.js.map +1 -1
  366. package/dist/src/ui/layouts/DefaultAppLayout.js +9 -1
  367. package/dist/src/ui/layouts/DefaultAppLayout.js.map +1 -1
  368. package/dist/src/ui/noninteractive/nonInteractiveUi.js +0 -1
  369. package/dist/src/ui/noninteractive/nonInteractiveUi.js.map +1 -1
  370. package/dist/src/ui/privacy/CloudFreePrivacyNotice.js +1 -1
  371. package/dist/src/ui/privacy/CloudFreePrivacyNotice.js.map +1 -1
  372. package/dist/src/ui/state/extensions.d.ts +5 -0
  373. package/dist/src/ui/state/extensions.js +12 -0
  374. package/dist/src/ui/state/extensions.js.map +1 -1
  375. package/dist/src/ui/state/extensions.test.d.ts +6 -0
  376. package/dist/src/ui/state/extensions.test.js +62 -0
  377. package/dist/src/ui/state/extensions.test.js.map +1 -0
  378. package/dist/src/ui/themes/color-utils.js +9 -0
  379. package/dist/src/ui/themes/color-utils.js.map +1 -1
  380. package/dist/src/ui/themes/color-utils.test.js +17 -0
  381. package/dist/src/ui/themes/color-utils.test.js.map +1 -1
  382. package/dist/src/ui/types.d.ts +6 -0
  383. package/dist/src/ui/types.js +4 -0
  384. package/dist/src/ui/types.js.map +1 -1
  385. package/dist/src/ui/utils/CodeColorizer.d.ts +11 -3
  386. package/dist/src/ui/utils/CodeColorizer.js +18 -9
  387. package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
  388. package/dist/src/ui/utils/CodeColorizer.test.d.ts +6 -0
  389. package/dist/src/ui/utils/CodeColorizer.test.js +38 -0
  390. package/dist/src/ui/utils/CodeColorizer.test.js.map +1 -0
  391. package/dist/src/ui/utils/MarkdownDisplay.js +32 -6
  392. package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
  393. package/dist/src/ui/utils/mouse.d.ts +2 -1
  394. package/dist/src/ui/utils/mouse.js +27 -1
  395. package/dist/src/ui/utils/mouse.js.map +1 -1
  396. package/dist/src/ui/utils/mouse.test.js +5 -0
  397. package/dist/src/ui/utils/mouse.test.js.map +1 -1
  398. package/dist/src/ui/utils/terminalSetup.d.ts +4 -0
  399. package/dist/src/ui/utils/terminalSetup.js +10 -3
  400. package/dist/src/ui/utils/terminalSetup.js.map +1 -1
  401. package/dist/src/ui/utils/textUtils.d.ts +1 -0
  402. package/dist/src/ui/utils/textUtils.js +3 -2
  403. package/dist/src/ui/utils/textUtils.js.map +1 -1
  404. package/dist/src/ui/utils/textUtils.test.js +7 -1
  405. package/dist/src/ui/utils/textUtils.test.js.map +1 -1
  406. package/dist/src/ui/utils/ui-sizing.js +10 -3
  407. package/dist/src/ui/utils/ui-sizing.js.map +1 -1
  408. package/dist/src/utils/cleanup.test.js +1 -1
  409. package/dist/src/utils/cleanup.test.js.map +1 -1
  410. package/dist/src/utils/dialogScopeUtils.d.ts +6 -13
  411. package/dist/src/utils/dialogScopeUtils.js +4 -2
  412. package/dist/src/utils/dialogScopeUtils.js.map +1 -1
  413. package/dist/src/utils/events.d.ts +5 -1
  414. package/dist/src/utils/events.js +2 -0
  415. package/dist/src/utils/events.js.map +1 -1
  416. package/dist/src/utils/persistentState.d.ts +19 -0
  417. package/dist/src/utils/persistentState.js +65 -0
  418. package/dist/src/utils/persistentState.js.map +1 -0
  419. package/dist/src/utils/sessionCleanup.test.js +76 -0
  420. package/dist/src/utils/sessionCleanup.test.js.map +1 -1
  421. package/dist/src/utils/sessionUtils.d.ts +54 -0
  422. package/dist/src/utils/sessionUtils.js +141 -1
  423. package/dist/src/utils/sessionUtils.js.map +1 -1
  424. package/dist/src/utils/sessionUtils.test.d.ts +6 -0
  425. package/dist/src/utils/sessionUtils.test.js +260 -0
  426. package/dist/src/utils/sessionUtils.test.js.map +1 -0
  427. package/dist/src/utils/sessions.d.ts +8 -0
  428. package/dist/src/utils/sessions.js +64 -0
  429. package/dist/src/utils/sessions.js.map +1 -0
  430. package/dist/src/utils/settingsUtils.d.ts +2 -2
  431. package/dist/src/utils/settingsUtils.js.map +1 -1
  432. package/dist/src/utils/userStartupWarnings.js +2 -2
  433. package/dist/src/utils/userStartupWarnings.js.map +1 -1
  434. package/dist/src/utils/windowTitle.d.ts +1 -1
  435. package/dist/src/utils/windowTitle.js +1 -1
  436. package/dist/tsconfig.tsbuildinfo +1 -1
  437. package/package.json +4 -4
  438. package/dist/src/config/policies/read-only.toml +0 -56
  439. package/dist/src/config/policies/write.toml +0 -63
  440. package/dist/src/config/policies/yolo.toml +0 -31
  441. package/dist/src/ui/utils/platformConstants.d.ts +0 -75
  442. package/dist/src/ui/utils/platformConstants.js +0 -78
  443. package/dist/src/ui/utils/platformConstants.js.map +0 -1
@@ -9,6 +9,7 @@ import { render } from '../test-utils/render.js';
9
9
  import { cleanup } from 'ink-testing-library';
10
10
  import { act, useContext } from 'react';
11
11
  import { AppContainer } from './AppContainer.js';
12
+ import { SettingsContext } from './contexts/SettingsContext.js';
12
13
  import { makeFakeConfig, CoreEvent, } from '@google/gemini-cli-core';
13
14
  // Mock coreEvents
14
15
  const mockCoreEvents = vi.hoisted(() => ({
@@ -116,6 +117,10 @@ describe('AppContainer State Management', () => {
116
117
  let mockSettings;
117
118
  let mockInitResult;
118
119
  let mockExtensionManager;
120
+ // Helper to generate the AppContainer JSX for render and rerender
121
+ const getAppContainer = ({ settings = mockSettings, config = mockConfig, version = '1.0.0', initResult = mockInitResult, startupWarnings, resumedSessionData, } = {}) => (_jsx(SettingsContext.Provider, { value: settings, children: _jsx(AppContainer, { config: config, version: version, initializationResult: initResult, startupWarnings: startupWarnings, resumedSessionData: resumedSessionData }) }));
122
+ // Helper to render the AppContainer
123
+ const renderAppContainer = (props) => render(getAppContainer(props));
119
124
  // Create typed mocks for all hooks
120
125
  const mockedUseQuotaAndFallback = useQuotaAndFallback;
121
126
  const mockedUseHistory = useHistory;
@@ -278,6 +283,7 @@ describe('AppContainer State Management', () => {
278
283
  showStatusInTitle: false,
279
284
  hideWindowTitle: false,
280
285
  },
286
+ useAlternateBuffer: false,
281
287
  },
282
288
  };
283
289
  // Mock InitializationResult
@@ -293,7 +299,7 @@ describe('AppContainer State Management', () => {
293
299
  });
294
300
  describe('Basic Rendering', () => {
295
301
  it('renders without crashing with minimal props', async () => {
296
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
302
+ const { unmount } = renderAppContainer();
297
303
  await act(async () => {
298
304
  await new Promise((resolve) => setTimeout(resolve, 0));
299
305
  });
@@ -301,7 +307,7 @@ describe('AppContainer State Management', () => {
301
307
  });
302
308
  it('renders with startup warnings', async () => {
303
309
  const startupWarnings = ['Warning 1', 'Warning 2'];
304
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, startupWarnings: startupWarnings, version: "1.0.0", initializationResult: mockInitResult }));
310
+ const { unmount } = renderAppContainer({ startupWarnings });
305
311
  await act(async () => {
306
312
  await new Promise((resolve) => setTimeout(resolve, 0));
307
313
  });
@@ -314,7 +320,9 @@ describe('AppContainer State Management', () => {
314
320
  ...mockInitResult,
315
321
  themeError: 'Failed to load theme',
316
322
  };
317
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: initResultWithError }));
323
+ const { unmount } = renderAppContainer({
324
+ initResult: initResultWithError,
325
+ });
318
326
  await act(async () => {
319
327
  await new Promise((resolve) => setTimeout(resolve, 0));
320
328
  });
@@ -324,13 +332,13 @@ describe('AppContainer State Management', () => {
324
332
  const debugConfig = makeFakeConfig();
325
333
  vi.spyOn(debugConfig, 'getDebugMode').mockReturnValue(true);
326
334
  expect(() => {
327
- render(_jsx(AppContainer, { config: debugConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
335
+ renderAppContainer({ config: debugConfig });
328
336
  }).not.toThrow();
329
337
  });
330
338
  });
331
339
  describe('Context Providers', () => {
332
340
  it('provides AppContext with correct values', async () => {
333
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "2.0.0", initializationResult: mockInitResult }));
341
+ const { unmount } = renderAppContainer({ version: '2.0.0' });
334
342
  await act(async () => {
335
343
  await new Promise((resolve) => setTimeout(resolve, 0));
336
344
  });
@@ -338,21 +346,21 @@ describe('AppContainer State Management', () => {
338
346
  expect(() => unmount()).not.toThrow();
339
347
  });
340
348
  it('provides UIStateContext with state management', async () => {
341
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
349
+ const { unmount } = renderAppContainer();
342
350
  await act(async () => {
343
351
  await new Promise((resolve) => setTimeout(resolve, 0));
344
352
  });
345
353
  unmount();
346
354
  });
347
355
  it('provides UIActionsContext with action handlers', async () => {
348
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
356
+ const { unmount } = renderAppContainer();
349
357
  await act(async () => {
350
358
  await new Promise((resolve) => setTimeout(resolve, 0));
351
359
  });
352
360
  unmount();
353
361
  });
354
362
  it('provides ConfigContext with config object', async () => {
355
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
363
+ const { unmount } = renderAppContainer();
356
364
  await act(async () => {
357
365
  await new Promise((resolve) => setTimeout(resolve, 0));
358
366
  });
@@ -369,7 +377,7 @@ describe('AppContainer State Management', () => {
369
377
  showMemoryUsage: false,
370
378
  },
371
379
  };
372
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: settingsAllHidden, version: "1.0.0", initializationResult: mockInitResult }));
380
+ const { unmount } = renderAppContainer({ settings: settingsAllHidden });
373
381
  await act(async () => {
374
382
  await new Promise((resolve) => setTimeout(resolve, 0));
375
383
  });
@@ -384,7 +392,7 @@ describe('AppContainer State Management', () => {
384
392
  showMemoryUsage: true,
385
393
  },
386
394
  };
387
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: settingsWithMemory, version: "1.0.0", initializationResult: mockInitResult }));
395
+ const { unmount } = renderAppContainer({ settings: settingsWithMemory });
388
396
  await act(async () => {
389
397
  await new Promise((resolve) => setTimeout(resolve, 0));
390
398
  });
@@ -393,7 +401,7 @@ describe('AppContainer State Management', () => {
393
401
  });
394
402
  describe('Version Handling', () => {
395
403
  it.each(['1.0.0', '2.1.3-beta', '3.0.0-nightly'])('handles version format: %s', async (version) => {
396
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: version, initializationResult: mockInitResult }));
404
+ const { unmount } = renderAppContainer({ version });
397
405
  await act(async () => {
398
406
  await new Promise((resolve) => setTimeout(resolve, 0));
399
407
  });
@@ -407,7 +415,7 @@ describe('AppContainer State Management', () => {
407
415
  throw new Error('Config error');
408
416
  });
409
417
  // Should still render without crashing - errors should be handled internally
410
- const { unmount } = render(_jsx(AppContainer, { config: errorConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
418
+ const { unmount } = renderAppContainer({ config: errorConfig });
411
419
  await act(async () => {
412
420
  await new Promise((resolve) => setTimeout(resolve, 0));
413
421
  });
@@ -417,7 +425,7 @@ describe('AppContainer State Management', () => {
417
425
  const undefinedSettings = {
418
426
  merged: {},
419
427
  };
420
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: undefinedSettings, version: "1.0.0", initializationResult: mockInitResult }));
428
+ const { unmount } = renderAppContainer({ settings: undefinedSettings });
421
429
  await act(async () => {
422
430
  await new Promise((resolve) => setTimeout(resolve, 0));
423
431
  });
@@ -428,14 +436,294 @@ describe('AppContainer State Management', () => {
428
436
  it('establishes correct provider nesting order', () => {
429
437
  // This tests that all the context providers are properly nested
430
438
  // and that the component tree can be built without circular dependencies
431
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
439
+ const { unmount } = renderAppContainer();
432
440
  expect(() => unmount()).not.toThrow();
433
441
  });
434
442
  });
443
+ describe('Session Resumption', () => {
444
+ it('handles resumed session data correctly', async () => {
445
+ const mockResumedSessionData = {
446
+ conversation: {
447
+ sessionId: 'test-session-123',
448
+ projectHash: 'test-project-hash',
449
+ startTime: '2024-01-01T00:00:00Z',
450
+ lastUpdated: '2024-01-01T00:00:01Z',
451
+ messages: [
452
+ {
453
+ id: 'msg-1',
454
+ type: 'user',
455
+ content: 'Hello',
456
+ timestamp: '2024-01-01T00:00:00Z',
457
+ },
458
+ {
459
+ id: 'msg-2',
460
+ type: 'gemini',
461
+ content: 'Hi there!',
462
+ role: 'model',
463
+ parts: [{ text: 'Hi there!' }],
464
+ timestamp: '2024-01-01T00:00:01Z',
465
+ },
466
+ ],
467
+ },
468
+ filePath: '/tmp/test-session.json',
469
+ };
470
+ let unmount;
471
+ await act(async () => {
472
+ const result = renderAppContainer({
473
+ config: mockConfig,
474
+ settings: mockSettings,
475
+ version: '1.0.0',
476
+ initResult: mockInitResult,
477
+ resumedSessionData: mockResumedSessionData,
478
+ });
479
+ unmount = result.unmount;
480
+ });
481
+ await act(async () => {
482
+ unmount();
483
+ });
484
+ });
485
+ it('renders without resumed session data', async () => {
486
+ let unmount;
487
+ await act(async () => {
488
+ const result = renderAppContainer({
489
+ config: mockConfig,
490
+ settings: mockSettings,
491
+ version: '1.0.0',
492
+ initResult: mockInitResult,
493
+ resumedSessionData: undefined,
494
+ });
495
+ unmount = result.unmount;
496
+ });
497
+ await act(async () => {
498
+ unmount();
499
+ });
500
+ });
501
+ it('initializes chat recording service when config has it', () => {
502
+ const mockChatRecordingService = {
503
+ initialize: vi.fn(),
504
+ recordMessage: vi.fn(),
505
+ recordMessageTokens: vi.fn(),
506
+ recordToolCalls: vi.fn(),
507
+ };
508
+ const mockGeminiClient = {
509
+ isInitialized: vi.fn(() => true),
510
+ resumeChat: vi.fn(),
511
+ getUserTier: vi.fn(),
512
+ getChatRecordingService: vi.fn(() => mockChatRecordingService),
513
+ };
514
+ const configWithRecording = {
515
+ ...mockConfig,
516
+ getGeminiClient: vi.fn(() => mockGeminiClient),
517
+ };
518
+ expect(() => {
519
+ renderAppContainer({
520
+ config: configWithRecording,
521
+ settings: mockSettings,
522
+ version: '1.0.0',
523
+ initResult: mockInitResult,
524
+ });
525
+ }).not.toThrow();
526
+ });
527
+ });
528
+ describe('Session Recording Integration', () => {
529
+ it('provides chat recording service configuration', () => {
530
+ const mockChatRecordingService = {
531
+ initialize: vi.fn(),
532
+ recordMessage: vi.fn(),
533
+ recordMessageTokens: vi.fn(),
534
+ recordToolCalls: vi.fn(),
535
+ getSessionId: vi.fn(() => 'test-session-123'),
536
+ getCurrentConversation: vi.fn(),
537
+ };
538
+ const mockGeminiClient = {
539
+ isInitialized: vi.fn(() => true),
540
+ resumeChat: vi.fn(),
541
+ getUserTier: vi.fn(),
542
+ getChatRecordingService: vi.fn(() => mockChatRecordingService),
543
+ setHistory: vi.fn(),
544
+ };
545
+ const configWithRecording = {
546
+ ...mockConfig,
547
+ getGeminiClient: vi.fn(() => mockGeminiClient),
548
+ getSessionId: vi.fn(() => 'test-session-123'),
549
+ };
550
+ expect(() => {
551
+ renderAppContainer({
552
+ config: configWithRecording,
553
+ settings: mockSettings,
554
+ version: '1.0.0',
555
+ initResult: mockInitResult,
556
+ });
557
+ }).not.toThrow();
558
+ // Verify the recording service structure is correct
559
+ expect(configWithRecording.getGeminiClient).toBeDefined();
560
+ expect(mockGeminiClient.getChatRecordingService).toBeDefined();
561
+ expect(mockChatRecordingService.initialize).toBeDefined();
562
+ expect(mockChatRecordingService.recordMessage).toBeDefined();
563
+ });
564
+ it('handles session recording when messages are added', () => {
565
+ const mockRecordMessage = vi.fn();
566
+ const mockRecordMessageTokens = vi.fn();
567
+ const mockChatRecordingService = {
568
+ initialize: vi.fn(),
569
+ recordMessage: mockRecordMessage,
570
+ recordMessageTokens: mockRecordMessageTokens,
571
+ recordToolCalls: vi.fn(),
572
+ getSessionId: vi.fn(() => 'test-session-123'),
573
+ };
574
+ const mockGeminiClient = {
575
+ isInitialized: vi.fn(() => true),
576
+ getChatRecordingService: vi.fn(() => mockChatRecordingService),
577
+ getUserTier: vi.fn(),
578
+ };
579
+ const configWithRecording = {
580
+ ...mockConfig,
581
+ getGeminiClient: vi.fn(() => mockGeminiClient),
582
+ };
583
+ renderAppContainer({
584
+ config: configWithRecording,
585
+ settings: mockSettings,
586
+ version: '1.0.0',
587
+ initResult: mockInitResult,
588
+ });
589
+ // The actual recording happens through the useHistory hook
590
+ // which would be triggered by user interactions
591
+ expect(mockChatRecordingService.initialize).toBeDefined();
592
+ expect(mockChatRecordingService.recordMessage).toBeDefined();
593
+ });
594
+ });
595
+ describe('Session Resume Flow', () => {
596
+ it('accepts resumed session data', () => {
597
+ const mockResumeChat = vi.fn();
598
+ const mockGeminiClient = {
599
+ isInitialized: vi.fn(() => true),
600
+ resumeChat: mockResumeChat,
601
+ getUserTier: vi.fn(),
602
+ getChatRecordingService: vi.fn(() => ({
603
+ initialize: vi.fn(),
604
+ recordMessage: vi.fn(),
605
+ recordMessageTokens: vi.fn(),
606
+ recordToolCalls: vi.fn(),
607
+ })),
608
+ };
609
+ const configWithClient = {
610
+ ...mockConfig,
611
+ getGeminiClient: vi.fn(() => mockGeminiClient),
612
+ };
613
+ const resumedData = {
614
+ conversation: {
615
+ sessionId: 'resumed-session-456',
616
+ projectHash: 'project-hash',
617
+ startTime: '2024-01-01T00:00:00Z',
618
+ lastUpdated: '2024-01-01T00:01:00Z',
619
+ messages: [
620
+ {
621
+ id: 'msg-1',
622
+ type: 'user',
623
+ content: 'Previous question',
624
+ timestamp: '2024-01-01T00:00:00Z',
625
+ },
626
+ {
627
+ id: 'msg-2',
628
+ type: 'gemini',
629
+ content: 'Previous answer',
630
+ role: 'model',
631
+ parts: [{ text: 'Previous answer' }],
632
+ timestamp: '2024-01-01T00:00:30Z',
633
+ tokenCount: { input: 10, output: 20 },
634
+ },
635
+ ],
636
+ },
637
+ filePath: '/tmp/resumed-session.json',
638
+ };
639
+ expect(() => {
640
+ renderAppContainer({
641
+ config: configWithClient,
642
+ settings: mockSettings,
643
+ version: '1.0.0',
644
+ initResult: mockInitResult,
645
+ resumedSessionData: resumedData,
646
+ });
647
+ }).not.toThrow();
648
+ // Verify the resume functionality structure is in place
649
+ expect(mockGeminiClient.resumeChat).toBeDefined();
650
+ expect(resumedData.conversation.messages).toHaveLength(2);
651
+ });
652
+ it('does not attempt resume when client is not initialized', () => {
653
+ const mockResumeChat = vi.fn();
654
+ const mockGeminiClient = {
655
+ isInitialized: vi.fn(() => false), // Not initialized
656
+ resumeChat: mockResumeChat,
657
+ getUserTier: vi.fn(),
658
+ getChatRecordingService: vi.fn(),
659
+ };
660
+ const configWithClient = {
661
+ ...mockConfig,
662
+ getGeminiClient: vi.fn(() => mockGeminiClient),
663
+ };
664
+ const resumedData = {
665
+ conversation: {
666
+ sessionId: 'test-session',
667
+ projectHash: 'project-hash',
668
+ startTime: '2024-01-01T00:00:00Z',
669
+ lastUpdated: '2024-01-01T00:01:00Z',
670
+ messages: [],
671
+ },
672
+ filePath: '/tmp/session.json',
673
+ };
674
+ renderAppContainer({
675
+ config: configWithClient,
676
+ settings: mockSettings,
677
+ version: '1.0.0',
678
+ initResult: mockInitResult,
679
+ resumedSessionData: resumedData,
680
+ });
681
+ // Should not call resumeChat when client is not initialized
682
+ expect(mockResumeChat).not.toHaveBeenCalled();
683
+ });
684
+ });
685
+ describe('Token Counting from Session Stats', () => {
686
+ it('tracks token counts from session messages', () => {
687
+ // Session stats are provided through the SessionStatsProvider context
688
+ // in the real app, not through the config directly
689
+ const mockChatRecordingService = {
690
+ initialize: vi.fn(),
691
+ recordMessage: vi.fn(),
692
+ recordMessageTokens: vi.fn(),
693
+ recordToolCalls: vi.fn(),
694
+ getSessionId: vi.fn(() => 'test-session-123'),
695
+ getCurrentConversation: vi.fn(() => ({
696
+ sessionId: 'test-session-123',
697
+ messages: [],
698
+ totalInputTokens: 150,
699
+ totalOutputTokens: 350,
700
+ })),
701
+ };
702
+ const mockGeminiClient = {
703
+ isInitialized: vi.fn(() => true),
704
+ getChatRecordingService: vi.fn(() => mockChatRecordingService),
705
+ getUserTier: vi.fn(),
706
+ };
707
+ const configWithRecording = {
708
+ ...mockConfig,
709
+ getGeminiClient: vi.fn(() => mockGeminiClient),
710
+ };
711
+ renderAppContainer({
712
+ config: configWithRecording,
713
+ settings: mockSettings,
714
+ version: '1.0.0',
715
+ initResult: mockInitResult,
716
+ });
717
+ // In the actual app, these stats would be displayed in components
718
+ // and updated as messages are processed through the recording service
719
+ expect(mockChatRecordingService.recordMessageTokens).toBeDefined();
720
+ expect(mockChatRecordingService.getCurrentConversation).toBeDefined();
721
+ });
722
+ });
435
723
  describe('Quota and Fallback Integration', () => {
436
724
  it('passes a null proQuotaRequest to UIStateContext by default', async () => {
437
725
  // The default mock from beforeEach already sets proQuotaRequest to null
438
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
726
+ const { unmount } = renderAppContainer();
439
727
  await act(async () => {
440
728
  await new Promise((resolve) => setTimeout(resolve, 0));
441
729
  });
@@ -455,7 +743,7 @@ describe('AppContainer State Management', () => {
455
743
  handleProQuotaChoice: vi.fn(),
456
744
  });
457
745
  // Act: Render the container
458
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
746
+ const { unmount } = renderAppContainer();
459
747
  await act(async () => {
460
748
  await new Promise((resolve) => setTimeout(resolve, 0));
461
749
  });
@@ -471,7 +759,7 @@ describe('AppContainer State Management', () => {
471
759
  handleProQuotaChoice: mockHandler,
472
760
  });
473
761
  // Act: Render the container
474
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
762
+ const { unmount } = renderAppContainer();
475
763
  await act(async () => {
476
764
  await new Promise((resolve) => setTimeout(resolve, 0));
477
765
  });
@@ -479,9 +767,9 @@ describe('AppContainer State Management', () => {
479
767
  expect(capturedUIActions.handleProQuotaChoice).toBe(mockHandler);
480
768
  // You can even verify that the plumbed function is callable
481
769
  act(() => {
482
- capturedUIActions.handleProQuotaChoice('auth');
770
+ capturedUIActions.handleProQuotaChoice('retry_later');
483
771
  });
484
- expect(mockHandler).toHaveBeenCalledWith('auth');
772
+ expect(mockHandler).toHaveBeenCalledWith('retry_later');
485
773
  unmount();
486
774
  });
487
775
  });
@@ -504,7 +792,9 @@ describe('AppContainer State Management', () => {
504
792
  },
505
793
  };
506
794
  // Act: Render the container
507
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettingsWithShowStatusFalse, version: "1.0.0", initializationResult: mockInitResult }));
795
+ const { unmount } = renderAppContainer({
796
+ settings: mockSettingsWithShowStatusFalse,
797
+ });
508
798
  // Assert: Check that no title-related writes occurred
509
799
  const titleWrites = mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]2;'));
510
800
  expect(titleWrites).toHaveLength(0);
@@ -524,7 +814,9 @@ describe('AppContainer State Management', () => {
524
814
  },
525
815
  };
526
816
  // Act: Render the container
527
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettingsWithHideTitleTrue, version: "1.0.0", initializationResult: mockInitResult }));
817
+ const { unmount } = renderAppContainer({
818
+ settings: mockSettingsWithHideTitleTrue,
819
+ });
528
820
  // Assert: Check that no title-related writes occurred
529
821
  const titleWrites = mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]2;'));
530
822
  expect(titleWrites).toHaveLength(0);
@@ -554,7 +846,9 @@ describe('AppContainer State Management', () => {
554
846
  cancelOngoingRequest: vi.fn(),
555
847
  });
556
848
  // Act: Render the container
557
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettingsWithTitleEnabled, version: "1.0.0", initializationResult: mockInitResult }));
849
+ const { unmount } = renderAppContainer({
850
+ settings: mockSettingsWithTitleEnabled,
851
+ });
558
852
  // Assert: Check that title was updated with thought subject
559
853
  const titleWrites = mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]2;'));
560
854
  expect(titleWrites).toHaveLength(1);
@@ -584,7 +878,9 @@ describe('AppContainer State Management', () => {
584
878
  cancelOngoingRequest: vi.fn(),
585
879
  });
586
880
  // Act: Render the container
587
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettingsWithTitleEnabled, version: "1.0.0", initializationResult: mockInitResult }));
881
+ const { unmount } = renderAppContainer({
882
+ settings: mockSettingsWithTitleEnabled,
883
+ });
588
884
  // Assert: Check that title was updated with default Idle text
589
885
  const titleWrites = mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]2;'));
590
886
  expect(titleWrites).toHaveLength(1);
@@ -615,7 +911,9 @@ describe('AppContainer State Management', () => {
615
911
  cancelOngoingRequest: vi.fn(),
616
912
  });
617
913
  // Act: Render the container
618
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettingsWithTitleEnabled, version: "1.0.0", initializationResult: mockInitResult }));
914
+ const { unmount } = renderAppContainer({
915
+ settings: mockSettingsWithTitleEnabled,
916
+ });
619
917
  // Assert: Check that title was updated with confirmation text
620
918
  const titleWrites = mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]2;'));
621
919
  expect(titleWrites).toHaveLength(1);
@@ -646,7 +944,9 @@ describe('AppContainer State Management', () => {
646
944
  cancelOngoingRequest: vi.fn(),
647
945
  });
648
946
  // Act: Render the container
649
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettingsWithTitleEnabled, version: "1.0.0", initializationResult: mockInitResult }));
947
+ const { unmount } = renderAppContainer({
948
+ settings: mockSettingsWithTitleEnabled,
949
+ });
650
950
  // Assert: Check that title is padded to exactly 80 characters
651
951
  const titleWrites = mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]2;'));
652
952
  expect(titleWrites).toHaveLength(1);
@@ -682,7 +982,9 @@ describe('AppContainer State Management', () => {
682
982
  cancelOngoingRequest: vi.fn(),
683
983
  });
684
984
  // Act: Render the container
685
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettingsWithTitleEnabled, version: "1.0.0", initializationResult: mockInitResult }));
985
+ const { unmount } = renderAppContainer({
986
+ settings: mockSettingsWithTitleEnabled,
987
+ });
686
988
  // Assert: Check that the correct ANSI escape sequence is used
687
989
  const titleWrites = mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]2;'));
688
990
  expect(titleWrites).toHaveLength(1);
@@ -715,7 +1017,9 @@ describe('AppContainer State Management', () => {
715
1017
  cancelOngoingRequest: vi.fn(),
716
1018
  });
717
1019
  // Act: Render the container
718
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettingsWithTitleEnabled, version: "1.0.0", initializationResult: mockInitResult }));
1020
+ const { unmount } = renderAppContainer({
1021
+ settings: mockSettingsWithTitleEnabled,
1022
+ });
719
1023
  // Assert: Check that title was updated with CLI_TITLE value
720
1024
  const titleWrites = mockStdout.write.mock.calls.filter((call) => call[0].includes('\x1b]2;'));
721
1025
  expect(titleWrites).toHaveLength(1);
@@ -731,7 +1035,7 @@ describe('AppContainer State Management', () => {
731
1035
  vi.useRealTimers();
732
1036
  });
733
1037
  it('should set and clear the queue error message after a timeout', async () => {
734
- const { rerender, unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1038
+ const { rerender, unmount } = renderAppContainer();
735
1039
  await act(async () => {
736
1040
  vi.advanceTimersByTime(0);
737
1041
  });
@@ -739,24 +1043,24 @@ describe('AppContainer State Management', () => {
739
1043
  act(() => {
740
1044
  capturedUIActions.setQueueErrorMessage('Test error');
741
1045
  });
742
- rerender(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1046
+ rerender(getAppContainer());
743
1047
  expect(capturedUIState.queueErrorMessage).toBe('Test error');
744
1048
  act(() => {
745
1049
  vi.advanceTimersByTime(3000);
746
1050
  });
747
- rerender(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1051
+ rerender(getAppContainer());
748
1052
  expect(capturedUIState.queueErrorMessage).toBeNull();
749
1053
  unmount();
750
1054
  });
751
1055
  it('should reset the timer if a new error message is set', async () => {
752
- const { rerender, unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1056
+ const { rerender, unmount } = renderAppContainer();
753
1057
  await act(async () => {
754
1058
  vi.advanceTimersByTime(0);
755
1059
  });
756
1060
  act(() => {
757
1061
  capturedUIActions.setQueueErrorMessage('First error');
758
1062
  });
759
- rerender(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1063
+ rerender(getAppContainer());
760
1064
  expect(capturedUIState.queueErrorMessage).toBe('First error');
761
1065
  act(() => {
762
1066
  vi.advanceTimersByTime(1500);
@@ -764,18 +1068,18 @@ describe('AppContainer State Management', () => {
764
1068
  act(() => {
765
1069
  capturedUIActions.setQueueErrorMessage('Second error');
766
1070
  });
767
- rerender(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1071
+ rerender(getAppContainer());
768
1072
  expect(capturedUIState.queueErrorMessage).toBe('Second error');
769
1073
  act(() => {
770
1074
  vi.advanceTimersByTime(2000);
771
1075
  });
772
- rerender(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1076
+ rerender(getAppContainer());
773
1077
  expect(capturedUIState.queueErrorMessage).toBe('Second error');
774
1078
  // 5. Advance time past the 3 second timeout from the second message
775
1079
  act(() => {
776
1080
  vi.advanceTimersByTime(1000);
777
1081
  });
778
- rerender(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1082
+ rerender(getAppContainer());
779
1083
  expect(capturedUIState.queueErrorMessage).toBeNull();
780
1084
  unmount();
781
1085
  });
@@ -797,7 +1101,7 @@ describe('AppContainer State Management', () => {
797
1101
  cancelOngoingRequest: vi.fn(),
798
1102
  activePtyId: 'some-id',
799
1103
  });
800
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1104
+ const { unmount } = renderAppContainer();
801
1105
  await act(async () => {
802
1106
  await new Promise((resolve) => setTimeout(resolve, 0));
803
1107
  });
@@ -818,11 +1122,11 @@ describe('AppContainer State Management', () => {
818
1122
  let unmount;
819
1123
  // Helper function to reduce boilerplate in tests
820
1124
  const setupKeypressTest = async () => {
821
- const renderResult = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1125
+ const renderResult = renderAppContainer();
822
1126
  await act(async () => {
823
1127
  vi.advanceTimersByTime(0);
824
1128
  });
825
- rerender = () => renderResult.rerender(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1129
+ rerender = () => renderResult.rerender(getAppContainer());
826
1130
  unmount = renderResult.unmount;
827
1131
  };
828
1132
  const pressKey = (key, times = 1) => {
@@ -957,11 +1261,11 @@ describe('AppContainer State Management', () => {
957
1261
  },
958
1262
  },
959
1263
  };
960
- const renderResult = render(_jsx(AppContainer, { config: mockConfig, settings: testSettings, version: "1.0.0", initializationResult: mockInitResult }));
1264
+ const renderResult = renderAppContainer({ settings: testSettings });
961
1265
  await act(async () => {
962
1266
  vi.advanceTimersByTime(0);
963
1267
  });
964
- rerender = () => renderResult.rerender(_jsx(AppContainer, { config: mockConfig, settings: testSettings, version: "1.0.0", initializationResult: mockInitResult }));
1268
+ rerender = () => renderResult.rerender(getAppContainer({ settings: testSettings }));
965
1269
  unmount = renderResult.unmount;
966
1270
  };
967
1271
  beforeEach(() => {
@@ -996,6 +1300,7 @@ describe('AppContainer State Management', () => {
996
1300
  meta: false,
997
1301
  shift: false,
998
1302
  paste: false,
1303
+ insertable: false,
999
1304
  sequence: '\x13',
1000
1305
  });
1001
1306
  });
@@ -1020,6 +1325,7 @@ describe('AppContainer State Management', () => {
1020
1325
  meta: false,
1021
1326
  shift: false,
1022
1327
  paste: false,
1328
+ insertable: false,
1023
1329
  sequence: '\x13',
1024
1330
  });
1025
1331
  });
@@ -1033,6 +1339,7 @@ describe('AppContainer State Management', () => {
1033
1339
  meta: false,
1034
1340
  shift: false,
1035
1341
  paste: false,
1342
+ insertable: true,
1036
1343
  sequence: 'a',
1037
1344
  });
1038
1345
  });
@@ -1050,6 +1357,7 @@ describe('AppContainer State Management', () => {
1050
1357
  meta: false,
1051
1358
  shift: false,
1052
1359
  paste: false,
1360
+ insertable: false,
1053
1361
  sequence: '\x13',
1054
1362
  });
1055
1363
  });
@@ -1063,6 +1371,7 @@ describe('AppContainer State Management', () => {
1063
1371
  meta: false,
1064
1372
  shift: false,
1065
1373
  paste: false,
1374
+ insertable: true,
1066
1375
  sequence: 'a',
1067
1376
  });
1068
1377
  });
@@ -1081,7 +1390,7 @@ describe('AppContainer State Management', () => {
1081
1390
  openModelDialog: vi.fn(),
1082
1391
  closeModelDialog: vi.fn(),
1083
1392
  });
1084
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1393
+ const { unmount } = renderAppContainer();
1085
1394
  await act(async () => {
1086
1395
  await new Promise((resolve) => setTimeout(resolve, 0));
1087
1396
  });
@@ -1095,7 +1404,7 @@ describe('AppContainer State Management', () => {
1095
1404
  openModelDialog: vi.fn(),
1096
1405
  closeModelDialog: mockCloseModelDialog,
1097
1406
  });
1098
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1407
+ const { unmount } = renderAppContainer();
1099
1408
  await act(async () => {
1100
1409
  await new Promise((resolve) => setTimeout(resolve, 0));
1101
1410
  });
@@ -1109,7 +1418,7 @@ describe('AppContainer State Management', () => {
1109
1418
  });
1110
1419
  describe('CoreEvents Integration', () => {
1111
1420
  it('subscribes to UserFeedback and drains backlog on mount', async () => {
1112
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1421
+ const { unmount } = renderAppContainer();
1113
1422
  await act(async () => {
1114
1423
  await new Promise((resolve) => setTimeout(resolve, 0));
1115
1424
  });
@@ -1118,7 +1427,7 @@ describe('AppContainer State Management', () => {
1118
1427
  unmount();
1119
1428
  });
1120
1429
  it('unsubscribes from UserFeedback on unmount', async () => {
1121
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1430
+ const { unmount } = renderAppContainer();
1122
1431
  await act(async () => {
1123
1432
  await new Promise((resolve) => setTimeout(resolve, 0));
1124
1433
  });
@@ -1126,7 +1435,7 @@ describe('AppContainer State Management', () => {
1126
1435
  expect(mockCoreEvents.off).toHaveBeenCalledWith(CoreEvent.UserFeedback, expect.any(Function));
1127
1436
  });
1128
1437
  it('adds history item when UserFeedback event is received', async () => {
1129
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1438
+ const { unmount } = renderAppContainer();
1130
1439
  await act(async () => {
1131
1440
  await new Promise((resolve) => setTimeout(resolve, 0));
1132
1441
  });
@@ -1150,8 +1459,7 @@ describe('AppContainer State Management', () => {
1150
1459
  it('updates currentModel when ModelChanged event is received', async () => {
1151
1460
  // Arrange: Mock initial model
1152
1461
  vi.spyOn(mockConfig, 'getModel').mockReturnValue('initial-model');
1153
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1154
- // Verify initial model
1462
+ const { unmount } = renderAppContainer();
1155
1463
  await act(async () => {
1156
1464
  await vi.waitFor(() => {
1157
1465
  expect(capturedUIState?.currentModel).toBe('initial-model');
@@ -1186,7 +1494,7 @@ describe('AppContainer State Management', () => {
1186
1494
  activePtyId: 'some-pty-id', // Make sure activePtyId is set
1187
1495
  });
1188
1496
  // The main assertion is that the render does not throw.
1189
- const { unmount } = render(_jsx(AppContainer, { config: mockConfig, settings: mockSettings, version: "1.0.0", initializationResult: mockInitResult }));
1497
+ const { unmount } = render(_jsx(SettingsContext.Provider, { value: mockSettings, children: _jsx(AppContainer, { config: mockConfig, version: "1.0.0", initializationResult: mockInitResult }) }));
1190
1498
  await act(async () => {
1191
1499
  await new Promise((resolve) => setTimeout(resolve, 0));
1192
1500
  });