@google/gemini-cli 0.24.0-preview.0 → 0.25.0-nightly.20260112.15891721a

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 (299) hide show
  1. package/README.md +1 -1
  2. package/dist/google-gemini-cli-0.25.0-nightly.20260107.59a18e710.tgz +0 -0
  3. package/dist/package.json +3 -3
  4. package/dist/src/commands/extensions/configure.d.ts +13 -0
  5. package/dist/src/commands/extensions/configure.js +124 -0
  6. package/dist/src/commands/extensions/configure.js.map +1 -0
  7. package/dist/src/commands/extensions/configure.test.d.ts +1 -0
  8. package/dist/src/commands/extensions/configure.test.js +197 -0
  9. package/dist/src/commands/extensions/configure.test.js.map +1 -0
  10. package/dist/src/commands/extensions/examples/hooks/gemini-extension.json +4 -0
  11. package/dist/src/commands/extensions/examples/hooks/hooks/hooks.json +14 -0
  12. package/dist/src/commands/extensions/examples/hooks/scripts/on-start.js +8 -0
  13. package/dist/src/commands/extensions/examples/mcp-server/README.md +35 -0
  14. package/dist/src/commands/extensions/examples/mcp-server/example.js +36 -22
  15. package/dist/src/commands/extensions/examples/mcp-server/gemini-extension.json +1 -1
  16. package/dist/src/commands/extensions/examples/mcp-server/package.json +0 -7
  17. package/dist/src/commands/extensions/examples/skills/gemini-extension.json +4 -0
  18. package/dist/src/commands/extensions/examples/skills/skills/greeter/SKILL.md +7 -0
  19. package/dist/src/commands/extensions/utils.d.ts +1 -0
  20. package/dist/src/commands/extensions/utils.js +5 -1
  21. package/dist/src/commands/extensions/utils.js.map +1 -1
  22. package/dist/src/commands/extensions.js +2 -2
  23. package/dist/src/commands/extensions.js.map +1 -1
  24. package/dist/src/commands/skills/disable.d.ts +2 -2
  25. package/dist/src/commands/skills/disable.js +8 -10
  26. package/dist/src/commands/skills/disable.js.map +1 -1
  27. package/dist/src/commands/skills/disable.test.js +7 -7
  28. package/dist/src/commands/skills/disable.test.js.map +1 -1
  29. package/dist/src/commands/skills/enable.d.ts +0 -2
  30. package/dist/src/commands/skills/enable.js +9 -21
  31. package/dist/src/commands/skills/enable.js.map +1 -1
  32. package/dist/src/commands/skills/enable.test.js +39 -12
  33. package/dist/src/commands/skills/enable.test.js.map +1 -1
  34. package/dist/src/commands/skills/list.d.ts +3 -1
  35. package/dist/src/commands/skills/list.js +20 -6
  36. package/dist/src/commands/skills/list.js.map +1 -1
  37. package/dist/src/commands/skills/list.test.js +37 -3
  38. package/dist/src/commands/skills/list.test.js.map +1 -1
  39. package/dist/src/config/config.js +6 -4
  40. package/dist/src/config/config.js.map +1 -1
  41. package/dist/src/config/config.test.js +33 -0
  42. package/dist/src/config/config.test.js.map +1 -1
  43. package/dist/src/config/extension-manager-scope.test.js +144 -0
  44. package/dist/src/config/extension-manager-scope.test.js.map +1 -0
  45. package/dist/src/config/extension-manager-skills.test.js +91 -43
  46. package/dist/src/config/extension-manager-skills.test.js.map +1 -1
  47. package/dist/src/config/extension-manager.js +57 -15
  48. package/dist/src/config/extension-manager.js.map +1 -1
  49. package/dist/src/config/extension.test.js +65 -0
  50. package/dist/src/config/extension.test.js.map +1 -1
  51. package/dist/src/config/extensions/extensionSettings.d.ts +5 -4
  52. package/dist/src/config/extensions/extensionSettings.js +20 -14
  53. package/dist/src/config/extensions/extensionSettings.js.map +1 -1
  54. package/dist/src/config/extensions/extensionSettings.test.js +8 -8
  55. package/dist/src/config/extensions/extensionSettings.test.js.map +1 -1
  56. package/dist/src/config/extensions/extensionUpdates.test.js +5 -21
  57. package/dist/src/config/extensions/extensionUpdates.test.js.map +1 -1
  58. package/dist/src/config/extensions/storage.js +2 -2
  59. package/dist/src/config/extensions/storage.js.map +1 -1
  60. package/dist/src/config/settings.d.ts +4 -6
  61. package/dist/src/config/settings.js +42 -238
  62. package/dist/src/config/settings.js.map +1 -1
  63. package/dist/src/config/settings.test.js +148 -684
  64. package/dist/src/config/settings.test.js.map +1 -1
  65. package/dist/src/config/settingsSchema.d.ts +20 -10
  66. package/dist/src/config/settingsSchema.js +23 -11
  67. package/dist/src/config/settingsSchema.js.map +1 -1
  68. package/dist/src/config/settings_validation_warning.test.js +10 -5
  69. package/dist/src/config/settings_validation_warning.test.js.map +1 -1
  70. package/dist/src/config/trustedFolders.js +1 -2
  71. package/dist/src/config/trustedFolders.js.map +1 -1
  72. package/dist/src/config/trustedFolders.test.js +7 -0
  73. package/dist/src/config/trustedFolders.test.js.map +1 -1
  74. package/dist/src/gemini.js +60 -66
  75. package/dist/src/gemini.js.map +1 -1
  76. package/dist/src/gemini.test.js +36 -83
  77. package/dist/src/gemini.test.js.map +1 -1
  78. package/dist/src/gemini_cleanup.test.js +2 -0
  79. package/dist/src/gemini_cleanup.test.js.map +1 -1
  80. package/dist/src/generated/git-commit.d.ts +2 -2
  81. package/dist/src/generated/git-commit.js +2 -2
  82. package/dist/src/generated/git-commit.js.map +1 -1
  83. package/dist/src/nonInteractiveCli.js +2 -2
  84. package/dist/src/nonInteractiveCli.js.map +1 -1
  85. package/dist/src/nonInteractiveCli.test.js +2 -1
  86. package/dist/src/nonInteractiveCli.test.js.map +1 -1
  87. package/dist/src/services/BuiltinCommandLoader.js +29 -6
  88. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  89. package/dist/src/services/BuiltinCommandLoader.test.js +55 -1
  90. package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
  91. package/dist/src/services/prompt-processors/shellProcessor.js +13 -11
  92. package/dist/src/services/prompt-processors/shellProcessor.js.map +1 -1
  93. package/dist/src/services/prompt-processors/shellProcessor.test.js +93 -61
  94. package/dist/src/services/prompt-processors/shellProcessor.test.js.map +1 -1
  95. package/dist/src/test-utils/render.js +2 -2
  96. package/dist/src/test-utils/render.js.map +1 -1
  97. package/dist/src/ui/App.test.js +2 -2
  98. package/dist/src/ui/App.test.js.map +1 -1
  99. package/dist/src/ui/AppContainer.js +22 -30
  100. package/dist/src/ui/AppContainer.js.map +1 -1
  101. package/dist/src/ui/commands/agentsCommand.d.ts +7 -0
  102. package/dist/src/ui/commands/agentsCommand.js +75 -0
  103. package/dist/src/ui/commands/agentsCommand.js.map +1 -0
  104. package/dist/src/ui/commands/agentsCommand.test.js +91 -0
  105. package/dist/src/ui/commands/agentsCommand.test.js.map +1 -0
  106. package/dist/src/ui/commands/bugCommand.js +27 -4
  107. package/dist/src/ui/commands/bugCommand.js.map +1 -1
  108. package/dist/src/ui/commands/bugCommand.test.js +70 -2
  109. package/dist/src/ui/commands/bugCommand.test.js.map +1 -1
  110. package/dist/src/ui/commands/chatCommand.d.ts +1 -2
  111. package/dist/src/ui/commands/chatCommand.js +38 -30
  112. package/dist/src/ui/commands/chatCommand.js.map +1 -1
  113. package/dist/src/ui/commands/chatCommand.test.js +79 -52
  114. package/dist/src/ui/commands/chatCommand.test.js.map +1 -1
  115. package/dist/src/ui/commands/clearCommand.js +7 -11
  116. package/dist/src/ui/commands/clearCommand.js.map +1 -1
  117. package/dist/src/ui/commands/clearCommand.test.js +4 -0
  118. package/dist/src/ui/commands/clearCommand.test.js.map +1 -1
  119. package/dist/src/ui/commands/extensionsCommand.js +70 -2
  120. package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
  121. package/dist/src/ui/commands/extensionsCommand.test.js +70 -3
  122. package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -1
  123. package/dist/src/ui/commands/hooksCommand.js +153 -18
  124. package/dist/src/ui/commands/hooksCommand.js.map +1 -1
  125. package/dist/src/ui/commands/hooksCommand.test.js +186 -15
  126. package/dist/src/ui/commands/hooksCommand.test.js.map +1 -1
  127. package/dist/src/ui/commands/skillsCommand.js +27 -29
  128. package/dist/src/ui/commands/skillsCommand.js.map +1 -1
  129. package/dist/src/ui/commands/skillsCommand.test.js +84 -2
  130. package/dist/src/ui/commands/skillsCommand.test.js.map +1 -1
  131. package/dist/src/ui/commands/types.d.ts +2 -1
  132. package/dist/src/ui/commands/types.js +1 -0
  133. package/dist/src/ui/commands/types.js.map +1 -1
  134. package/dist/src/ui/components/Composer.test.js +1 -0
  135. package/dist/src/ui/components/Composer.test.js.map +1 -1
  136. package/dist/src/ui/components/DialogManager.js +1 -1
  137. package/dist/src/ui/components/DialogManager.js.map +1 -1
  138. package/dist/src/ui/components/HistoryItemDisplay.js +2 -1
  139. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  140. package/dist/src/ui/components/HistoryItemDisplay.test.js +21 -0
  141. package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
  142. package/dist/src/ui/components/InputPrompt.test.js +0 -2
  143. package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
  144. package/dist/src/ui/components/MainContent.js +6 -1
  145. package/dist/src/ui/components/MainContent.js.map +1 -1
  146. package/dist/src/ui/components/Notifications.js +2 -3
  147. package/dist/src/ui/components/Notifications.js.map +1 -1
  148. package/dist/src/ui/components/Notifications.test.js +1 -0
  149. package/dist/src/ui/components/Notifications.test.js.map +1 -1
  150. package/dist/src/ui/components/ProQuotaDialog.d.ts +1 -3
  151. package/dist/src/ui/components/ProQuotaDialog.js +8 -21
  152. package/dist/src/ui/components/ProQuotaDialog.js.map +1 -1
  153. package/dist/src/ui/components/ProQuotaDialog.test.js +31 -11
  154. package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -1
  155. package/dist/src/ui/components/SettingsDialog.test.js +1 -3
  156. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  157. package/dist/src/ui/components/StatusDisplay.js +2 -2
  158. package/dist/src/ui/components/StatusDisplay.js.map +1 -1
  159. package/dist/src/ui/components/StatusDisplay.test.js +1 -0
  160. package/dist/src/ui/components/StatusDisplay.test.js.map +1 -1
  161. package/dist/src/ui/components/SuggestionsDisplay.js +7 -2
  162. package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
  163. package/dist/src/ui/components/ThemeDialog.test.js +1 -1
  164. package/dist/src/ui/components/ThemeDialog.test.js.map +1 -1
  165. package/dist/src/ui/components/messages/ToolMessage.test.js +1 -0
  166. package/dist/src/ui/components/messages/ToolMessage.test.js.map +1 -1
  167. package/dist/src/ui/components/views/AgentsStatus.d.ts +13 -0
  168. package/dist/src/ui/components/views/AgentsStatus.js +23 -0
  169. package/dist/src/ui/components/views/AgentsStatus.js.map +1 -0
  170. package/dist/src/ui/components/views/ExtensionsList.js +2 -1
  171. package/dist/src/ui/components/views/ExtensionsList.js.map +1 -1
  172. package/dist/src/ui/components/views/ExtensionsList.test.js +12 -1
  173. package/dist/src/ui/components/views/ExtensionsList.test.js.map +1 -1
  174. package/dist/src/ui/components/views/HooksList.js +25 -16
  175. package/dist/src/ui/components/views/HooksList.js.map +1 -1
  176. package/dist/src/ui/components/views/SkillsList.js +9 -7
  177. package/dist/src/ui/components/views/SkillsList.js.map +1 -1
  178. package/dist/src/ui/components/views/SkillsList.test.js +15 -0
  179. package/dist/src/ui/components/views/SkillsList.test.js.map +1 -1
  180. package/dist/src/ui/contexts/KeypressContext.js +5 -28
  181. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  182. package/dist/src/ui/contexts/KeypressContext.test.js +28 -8
  183. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  184. package/dist/src/ui/hooks/atCommandProcessor.js +15 -1
  185. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  186. package/dist/src/ui/hooks/atCommandProcessor_agents.test.js +183 -0
  187. package/dist/src/ui/hooks/atCommandProcessor_agents.test.js.map +1 -0
  188. package/dist/src/ui/hooks/slashCommandProcessor.test.js +1 -0
  189. package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
  190. package/dist/src/ui/hooks/useAtCompletion.js +31 -0
  191. package/dist/src/ui/hooks/useAtCompletion.js.map +1 -1
  192. package/dist/src/ui/hooks/useAtCompletion_agents.test.d.ts +6 -0
  193. package/dist/src/ui/hooks/useAtCompletion_agents.test.js +85 -0
  194. package/dist/src/ui/hooks/useAtCompletion_agents.test.js.map +1 -0
  195. package/dist/src/ui/hooks/useCommandCompletion.js +12 -8
  196. package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
  197. package/dist/src/ui/hooks/useCommandCompletion.test.js +81 -0
  198. package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
  199. package/dist/src/ui/hooks/useExtensionUpdates.test.js +7 -0
  200. package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -1
  201. package/dist/src/ui/hooks/useGeminiStream.js +6 -6
  202. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  203. package/dist/src/ui/hooks/useGeminiStream.test.js +45 -2
  204. package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
  205. package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js +10 -3
  206. package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js.map +1 -1
  207. package/dist/src/ui/hooks/useQuotaAndFallback.js +15 -10
  208. package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -1
  209. package/dist/src/ui/hooks/useQuotaAndFallback.test.js +13 -8
  210. package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
  211. package/dist/src/ui/hooks/useRewind.d.ts +14 -0
  212. package/dist/src/ui/hooks/useRewind.js +31 -0
  213. package/dist/src/ui/hooks/useRewind.js.map +1 -0
  214. package/dist/src/ui/hooks/useRewind.test.d.ts +6 -0
  215. package/dist/src/ui/hooks/useRewind.test.js +100 -0
  216. package/dist/src/ui/hooks/useRewind.test.js.map +1 -0
  217. package/dist/src/ui/hooks/useToolScheduler.test.js +10 -2
  218. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  219. package/dist/src/ui/themes/theme-manager.js +2 -3
  220. package/dist/src/ui/themes/theme-manager.js.map +1 -1
  221. package/dist/src/ui/themes/theme-manager.test.js +7 -0
  222. package/dist/src/ui/themes/theme-manager.test.js.map +1 -1
  223. package/dist/src/ui/types.d.ts +8 -2
  224. package/dist/src/ui/types.js +1 -0
  225. package/dist/src/ui/types.js.map +1 -1
  226. package/dist/src/ui/utils/CodeColorizer.test.js +1 -1
  227. package/dist/src/ui/utils/CodeColorizer.test.js.map +1 -1
  228. package/dist/src/ui/utils/MarkdownDisplay.test.js +1 -1
  229. package/dist/src/ui/utils/MarkdownDisplay.test.js.map +1 -1
  230. package/dist/src/ui/utils/directoryUtils.js +4 -4
  231. package/dist/src/ui/utils/directoryUtils.js.map +1 -1
  232. package/dist/src/ui/utils/directoryUtils.test.js +1 -0
  233. package/dist/src/ui/utils/directoryUtils.test.js.map +1 -1
  234. package/dist/src/ui/utils/historyExportUtils.d.ts +21 -0
  235. package/dist/src/ui/utils/historyExportUtils.js +59 -0
  236. package/dist/src/ui/utils/historyExportUtils.js.map +1 -0
  237. package/dist/src/ui/utils/rewindFileOps.d.ts +47 -0
  238. package/dist/src/ui/utils/rewindFileOps.js +190 -0
  239. package/dist/src/ui/utils/rewindFileOps.js.map +1 -0
  240. package/dist/src/ui/utils/rewindFileOps.test.d.ts +6 -0
  241. package/dist/src/ui/utils/rewindFileOps.test.js +375 -0
  242. package/dist/src/ui/utils/rewindFileOps.test.js.map +1 -0
  243. package/dist/src/ui/utils/terminalCapabilityManager.d.ts +3 -10
  244. package/dist/src/ui/utils/terminalCapabilityManager.js +11 -35
  245. package/dist/src/ui/utils/terminalCapabilityManager.js.map +1 -1
  246. package/dist/src/ui/utils/terminalCapabilityManager.test.js +13 -34
  247. package/dist/src/ui/utils/terminalCapabilityManager.test.js.map +1 -1
  248. package/dist/src/ui/utils/terminalSetup.d.ts +1 -1
  249. package/dist/src/ui/utils/terminalSetup.js +19 -4
  250. package/dist/src/ui/utils/terminalSetup.js.map +1 -1
  251. package/dist/src/ui/utils/terminalSetup.test.js +7 -0
  252. package/dist/src/ui/utils/terminalSetup.test.js.map +1 -1
  253. package/dist/src/ui/utils/textUtils.js +9 -1
  254. package/dist/src/ui/utils/textUtils.js.map +1 -1
  255. package/dist/src/ui/utils/textUtils.test.js +12 -1
  256. package/dist/src/ui/utils/textUtils.test.js.map +1 -1
  257. package/dist/src/utils/activityLogger.d.ts +47 -0
  258. package/dist/src/utils/activityLogger.js +297 -0
  259. package/dist/src/utils/activityLogger.js.map +1 -0
  260. package/dist/src/utils/cleanup.d.ts +5 -0
  261. package/dist/src/utils/cleanup.js +17 -0
  262. package/dist/src/utils/cleanup.js.map +1 -1
  263. package/dist/src/utils/cleanup.test.js +21 -31
  264. package/dist/src/utils/cleanup.test.js.map +1 -1
  265. package/dist/src/utils/resolvePath.js +3 -3
  266. package/dist/src/utils/resolvePath.js.map +1 -1
  267. package/dist/src/utils/resolvePath.test.js +3 -0
  268. package/dist/src/utils/resolvePath.test.js.map +1 -1
  269. package/dist/src/utils/sandbox.js +17 -10
  270. package/dist/src/utils/sandbox.js.map +1 -1
  271. package/dist/src/utils/sandbox.test.js +17 -5
  272. package/dist/src/utils/sandbox.test.js.map +1 -1
  273. package/dist/src/utils/skillSettings.d.ts +33 -0
  274. package/dist/src/utils/skillSettings.js +101 -0
  275. package/dist/src/utils/skillSettings.js.map +1 -0
  276. package/dist/src/utils/skillUtils.d.ts +16 -0
  277. package/dist/src/utils/skillUtils.js +51 -0
  278. package/dist/src/utils/skillUtils.js.map +1 -0
  279. package/dist/src/utils/userStartupWarnings.d.ts +2 -1
  280. package/dist/src/utils/userStartupWarnings.js +17 -7
  281. package/dist/src/utils/userStartupWarnings.js.map +1 -1
  282. package/dist/src/utils/userStartupWarnings.test.js +37 -6
  283. package/dist/src/utils/userStartupWarnings.test.js.map +1 -1
  284. package/dist/tsconfig.tsbuildinfo +1 -1
  285. package/package.json +4 -4
  286. package/dist/src/commands/extensions/examples/mcp-server/example.js.map +0 -1
  287. package/dist/src/commands/extensions/examples/mcp-server/example.test.js +0 -111
  288. package/dist/src/commands/extensions/examples/mcp-server/example.test.js.map +0 -1
  289. package/dist/src/commands/extensions/examples/mcp-server/example.test.ts +0 -135
  290. package/dist/src/commands/extensions/examples/mcp-server/example.ts +0 -60
  291. package/dist/src/commands/extensions/examples/mcp-server/tsconfig.json +0 -13
  292. package/dist/src/commands/extensions/settings.d.ts +0 -7
  293. package/dist/src/commands/extensions/settings.js +0 -115
  294. package/dist/src/commands/extensions/settings.js.map +0 -1
  295. package/dist/src/commands/extensions/settings.test.js +0 -170
  296. package/dist/src/commands/extensions/settings.test.js.map +0 -1
  297. /package/dist/src/{commands/extensions/examples/mcp-server/example.d.ts → config/extension-manager-scope.test.d.ts} +0 -0
  298. /package/dist/src/{commands/extensions/examples/mcp-server/example.test.d.ts → ui/commands/agentsCommand.test.d.ts} +0 -0
  299. /package/dist/src/{commands/extensions/settings.test.d.ts → ui/hooks/atCommandProcessor_agents.test.d.ts} +0 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import fs from 'node:fs/promises';
7
+ import * as Diff from 'diff';
8
+ import { coreEvents, debugLogger, getFileDiffFromResultDisplay, computeAddedAndRemovedLines, } from '@google/gemini-cli-core';
9
+ /**
10
+ * Calculates file change statistics for a single turn.
11
+ * A turn is defined as the sequence of messages starting after the given user message
12
+ * and continuing until the next user message or the end of the conversation.
13
+ *
14
+ * @param conversation The full conversation record.
15
+ * @param userMessage The starting user message for the turn.
16
+ * @returns Statistics about lines added/removed and files touched, or null if no edits occurred.
17
+ */
18
+ export function calculateTurnStats(conversation, userMessage) {
19
+ const msgIndex = conversation.messages.indexOf(userMessage);
20
+ if (msgIndex === -1)
21
+ return null;
22
+ let addedLines = 0;
23
+ let removedLines = 0;
24
+ const files = new Set();
25
+ let hasEdits = false;
26
+ // Look ahead until the next user message (single turn)
27
+ for (let i = msgIndex + 1; i < conversation.messages.length; i++) {
28
+ const msg = conversation.messages[i];
29
+ if (msg.type === 'user')
30
+ break; // Stop at next user message
31
+ if (msg.type === 'gemini' && msg.toolCalls) {
32
+ for (const toolCall of msg.toolCalls) {
33
+ const fileDiff = getFileDiffFromResultDisplay(toolCall.resultDisplay);
34
+ if (fileDiff) {
35
+ hasEdits = true;
36
+ const stats = fileDiff.diffStat;
37
+ const calculations = computeAddedAndRemovedLines(stats);
38
+ addedLines += calculations.addedLines;
39
+ removedLines += calculations.removedLines;
40
+ files.add(fileDiff.fileName);
41
+ }
42
+ }
43
+ }
44
+ }
45
+ if (!hasEdits)
46
+ return null;
47
+ return {
48
+ addedLines,
49
+ removedLines,
50
+ fileCount: files.size,
51
+ };
52
+ }
53
+ /**
54
+ * Calculates the cumulative file change statistics from a specific message
55
+ * to the end of the conversation.
56
+ *
57
+ * @param conversation The full conversation record.
58
+ * @param userMessage The message to start calculating impact from (exclusive).
59
+ * @returns Aggregate statistics about lines added/removed and files touched, or null if no edits occurred.
60
+ */
61
+ export function calculateRewindImpact(conversation, userMessage) {
62
+ const msgIndex = conversation.messages.indexOf(userMessage);
63
+ if (msgIndex === -1)
64
+ return null;
65
+ let addedLines = 0;
66
+ let removedLines = 0;
67
+ const files = new Set();
68
+ const details = [];
69
+ let hasEdits = false;
70
+ // Look ahead to the end of conversation (cumulative)
71
+ for (let i = msgIndex + 1; i < conversation.messages.length; i++) {
72
+ const msg = conversation.messages[i];
73
+ // Do NOT break on user message - we want total impact
74
+ if (msg.type === 'gemini' && msg.toolCalls) {
75
+ for (const toolCall of msg.toolCalls) {
76
+ const fileDiff = getFileDiffFromResultDisplay(toolCall.resultDisplay);
77
+ if (fileDiff) {
78
+ hasEdits = true;
79
+ const stats = fileDiff.diffStat;
80
+ const calculations = computeAddedAndRemovedLines(stats);
81
+ addedLines += calculations.addedLines;
82
+ removedLines += calculations.removedLines;
83
+ files.add(fileDiff.fileName);
84
+ details.push({
85
+ fileName: fileDiff.fileName,
86
+ diff: fileDiff.fileDiff,
87
+ });
88
+ }
89
+ }
90
+ }
91
+ }
92
+ if (!hasEdits)
93
+ return null;
94
+ return {
95
+ addedLines,
96
+ removedLines,
97
+ fileCount: files.size,
98
+ details,
99
+ };
100
+ }
101
+ /**
102
+ * Reverts file changes made by the model from the end of the conversation
103
+ * back to a specific target message.
104
+ *
105
+ * It iterates backwards through the conversation history and attempts to undo
106
+ * any file modifications. It handles cases where the user might have subsequently
107
+ * modified the file by attempting a smart patch (using the `diff` library).
108
+ *
109
+ * @param conversation The full conversation record.
110
+ * @param targetMessageId The ID of the message to revert back to. Changes *after* this message will be undone.
111
+ */
112
+ export async function revertFileChanges(conversation, targetMessageId) {
113
+ const messageIndex = conversation.messages.findIndex((m) => m.id === targetMessageId);
114
+ if (messageIndex === -1) {
115
+ debugLogger.error('Requested message to rewind to was not found ');
116
+ return;
117
+ }
118
+ // Iterate backwards from the end to the message being rewound (exclusive of the messageId itself)
119
+ for (let i = conversation.messages.length - 1; i > messageIndex; i--) {
120
+ const msg = conversation.messages[i];
121
+ if (msg.type === 'gemini' && msg.toolCalls) {
122
+ for (let j = msg.toolCalls.length - 1; j >= 0; j--) {
123
+ const toolCall = msg.toolCalls[j];
124
+ const fileDiff = getFileDiffFromResultDisplay(toolCall.resultDisplay);
125
+ if (fileDiff) {
126
+ const { filePath, fileName, newContent, originalContent, isNewFile } = fileDiff;
127
+ try {
128
+ let currentContent = null;
129
+ try {
130
+ currentContent = await fs.readFile(filePath, 'utf8');
131
+ }
132
+ catch (e) {
133
+ const error = e;
134
+ if ('code' in error && error.code === 'ENOENT') {
135
+ // File does not exist, which is fine in some revert scenarios.
136
+ debugLogger.debug(`File ${fileName} not found during revert, proceeding as it may be a new file deletion.`);
137
+ }
138
+ else {
139
+ // Other read errors are unexpected.
140
+ coreEvents.emitFeedback('error', `Error reading ${fileName} during revert: ${error.message}`, e);
141
+ // Continue to next tool call
142
+ return;
143
+ }
144
+ }
145
+ // 1. Exact Match: Safe to revert directly
146
+ if (currentContent === newContent) {
147
+ if (!isNewFile) {
148
+ await fs.writeFile(filePath, originalContent ?? '');
149
+ }
150
+ else {
151
+ // Original content was null (new file), so we delete the file
152
+ await fs.unlink(filePath);
153
+ }
154
+ }
155
+ // 2. Mismatch: Attempt Smart Revert (Patch)
156
+ else if (currentContent !== null) {
157
+ const originalText = originalContent ?? '';
158
+ // Create a patch that transforms Agent -> Original
159
+ const undoPatch = Diff.createPatch(fileName, newContent, originalText);
160
+ // Apply that patch to the Current content
161
+ const patchedContent = Diff.applyPatch(currentContent, undoPatch);
162
+ if (typeof patchedContent === 'string') {
163
+ if (patchedContent === '' && isNewFile) {
164
+ // If the result is empty and the file didn't exist originally, delete it
165
+ await fs.unlink(filePath);
166
+ }
167
+ else {
168
+ await fs.writeFile(filePath, patchedContent);
169
+ }
170
+ }
171
+ else {
172
+ // Patch failed
173
+ coreEvents.emitFeedback('warning', `Smart revert for ${fileName} failed. The file may have been modified in a way that conflicts with the undo operation.`);
174
+ }
175
+ }
176
+ else {
177
+ // File was deleted by the user, but we expected content.
178
+ // This can happen if a file created by the agent is deleted before rewind.
179
+ coreEvents.emitFeedback('warning', `Cannot revert changes for ${fileName} because it was not found on disk. This is expected if a file created by the agent was deleted before rewind`);
180
+ }
181
+ }
182
+ catch (e) {
183
+ coreEvents.emitFeedback('error', `An unexpected error occurred while reverting ${fileName}.`, e);
184
+ }
185
+ }
186
+ }
187
+ }
188
+ }
189
+ }
190
+ //# sourceMappingURL=rewindFileOps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rewindFileOps.js","sourceRoot":"","sources":["../../../../src/ui/utils/rewindFileOps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
@@ -0,0 +1,375 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
7
+ import fs from 'node:fs/promises';
8
+ import { calculateTurnStats, calculateRewindImpact, revertFileChanges, } from './rewindFileOps.js';
9
+ import { coreEvents, } from '@google/gemini-cli-core';
10
+ // Mock fs/promises
11
+ vi.mock('node:fs/promises', () => ({
12
+ default: {
13
+ readFile: vi.fn(),
14
+ writeFile: vi.fn(),
15
+ rm: vi.fn(),
16
+ unlink: vi.fn(),
17
+ },
18
+ }));
19
+ // Mock @google/gemini-cli-core
20
+ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
21
+ const actual = await importOriginal();
22
+ return {
23
+ ...actual,
24
+ debugLogger: {
25
+ log: vi.fn(),
26
+ warn: vi.fn(),
27
+ error: vi.fn(),
28
+ debug: vi.fn(),
29
+ },
30
+ getFileDiffFromResultDisplay: vi.fn(),
31
+ computeAddedAndRemovedLines: vi.fn(),
32
+ };
33
+ });
34
+ describe('rewindFileOps', () => {
35
+ beforeEach(() => {
36
+ vi.clearAllMocks();
37
+ vi.spyOn(coreEvents, 'emitFeedback');
38
+ });
39
+ describe('calculateTurnStats', () => {
40
+ it('returns null if no edits found after user message', () => {
41
+ const userMsg = { type: 'user' };
42
+ const conversation = {
43
+ messages: [
44
+ userMsg,
45
+ { type: 'gemini', text: 'Hello' },
46
+ ],
47
+ };
48
+ const result = calculateTurnStats(conversation, userMsg);
49
+ expect(result).toBeNull();
50
+ });
51
+ it('calculates stats for single turn correctly', async () => {
52
+ const { getFileDiffFromResultDisplay, computeAddedAndRemovedLines } = await import('@google/gemini-cli-core');
53
+ vi.mocked(getFileDiffFromResultDisplay).mockReturnValue({
54
+ filePath: 'test.ts',
55
+ fileName: 'test.ts',
56
+ originalContent: 'old',
57
+ newContent: 'new',
58
+ isNewFile: false,
59
+ diffStat: {
60
+ model_added_lines: 0,
61
+ model_removed_lines: 0,
62
+ model_added_chars: 0,
63
+ model_removed_chars: 0,
64
+ user_added_lines: 0,
65
+ user_removed_lines: 0,
66
+ user_added_chars: 0,
67
+ user_removed_chars: 0,
68
+ },
69
+ fileDiff: 'diff',
70
+ });
71
+ vi.mocked(computeAddedAndRemovedLines).mockReturnValue({
72
+ addedLines: 3,
73
+ removedLines: 3,
74
+ });
75
+ const userMsg = { type: 'user' };
76
+ const conversation = {
77
+ messages: [
78
+ userMsg,
79
+ {
80
+ type: 'gemini',
81
+ toolCalls: [
82
+ {
83
+ name: 'replace',
84
+ args: {},
85
+ resultDisplay: 'diff',
86
+ },
87
+ ],
88
+ },
89
+ ],
90
+ };
91
+ const result = calculateTurnStats(conversation, userMsg);
92
+ expect(result).toEqual({
93
+ fileCount: 1,
94
+ addedLines: 3,
95
+ removedLines: 3,
96
+ });
97
+ });
98
+ });
99
+ describe('calculateRewindImpact', () => {
100
+ it('calculates cumulative stats across multiple turns', async () => {
101
+ const { getFileDiffFromResultDisplay, computeAddedAndRemovedLines } = await import('@google/gemini-cli-core');
102
+ vi.mocked(getFileDiffFromResultDisplay)
103
+ .mockReturnValueOnce({
104
+ filePath: 'file1.ts',
105
+ fileName: 'file1.ts',
106
+ originalContent: '123',
107
+ newContent: '12345',
108
+ isNewFile: false,
109
+ diffStat: {
110
+ model_added_lines: 0,
111
+ model_removed_lines: 0,
112
+ model_added_chars: 0,
113
+ model_removed_chars: 0,
114
+ user_added_lines: 0,
115
+ user_removed_lines: 0,
116
+ user_added_chars: 0,
117
+ user_removed_chars: 0,
118
+ },
119
+ fileDiff: 'diff1',
120
+ })
121
+ .mockReturnValueOnce({
122
+ filePath: 'file2.ts',
123
+ fileName: 'file2.ts',
124
+ originalContent: 'abc',
125
+ newContent: 'abcd',
126
+ isNewFile: true,
127
+ diffStat: {
128
+ model_added_lines: 0,
129
+ model_removed_lines: 0,
130
+ model_added_chars: 0,
131
+ model_removed_chars: 0,
132
+ user_added_lines: 0,
133
+ user_removed_lines: 0,
134
+ user_added_chars: 0,
135
+ user_removed_chars: 0,
136
+ },
137
+ fileDiff: 'diff2',
138
+ });
139
+ vi.mocked(computeAddedAndRemovedLines)
140
+ .mockReturnValueOnce({ addedLines: 5, removedLines: 3 })
141
+ .mockReturnValueOnce({ addedLines: 4, removedLines: 0 });
142
+ const userMsg = { type: 'user' };
143
+ const conversation = {
144
+ messages: [
145
+ userMsg,
146
+ {
147
+ type: 'gemini',
148
+ toolCalls: [
149
+ {
150
+ resultDisplay: 'd1',
151
+ },
152
+ ],
153
+ },
154
+ {
155
+ type: 'user',
156
+ },
157
+ {
158
+ type: 'gemini',
159
+ toolCalls: [
160
+ {
161
+ resultDisplay: 'd2',
162
+ },
163
+ ],
164
+ },
165
+ ],
166
+ };
167
+ const result = calculateRewindImpact(conversation, userMsg);
168
+ expect(result).toEqual({
169
+ fileCount: 2,
170
+ addedLines: 9, // 5 + 4
171
+ removedLines: 3, // 3 + 0
172
+ details: [
173
+ { fileName: 'file1.ts', diff: 'diff1' },
174
+ { fileName: 'file2.ts', diff: 'diff2' },
175
+ ],
176
+ });
177
+ });
178
+ });
179
+ describe('revertFileChanges', () => {
180
+ it('does nothing if message not found', async () => {
181
+ await revertFileChanges({ messages: [] }, 'missing');
182
+ expect(fs.writeFile).not.toHaveBeenCalled();
183
+ });
184
+ it('reverts exact match', async () => {
185
+ const { getFileDiffFromResultDisplay } = await import('@google/gemini-cli-core');
186
+ vi.mocked(getFileDiffFromResultDisplay).mockReturnValue({
187
+ filePath: '/abs/path/test.ts',
188
+ fileName: 'test.ts',
189
+ originalContent: 'ORIGINAL_CONTENT',
190
+ newContent: 'NEW_CONTENT',
191
+ isNewFile: false,
192
+ diffStat: {
193
+ model_added_lines: 0,
194
+ model_removed_lines: 0,
195
+ model_added_chars: 0,
196
+ model_removed_chars: 0,
197
+ user_added_lines: 0,
198
+ user_removed_lines: 0,
199
+ user_added_chars: 0,
200
+ user_removed_chars: 0,
201
+ },
202
+ fileDiff: 'diff',
203
+ });
204
+ const userMsg = {
205
+ type: 'user',
206
+ id: 'target',
207
+ };
208
+ const conversation = {
209
+ messages: [
210
+ userMsg,
211
+ {
212
+ type: 'gemini',
213
+ toolCalls: [{ resultDisplay: 'diff' }],
214
+ },
215
+ ],
216
+ };
217
+ vi.mocked(fs.readFile).mockResolvedValue('NEW_CONTENT');
218
+ await revertFileChanges(conversation, 'target');
219
+ expect(fs.writeFile).toHaveBeenCalledWith('/abs/path/test.ts', 'ORIGINAL_CONTENT');
220
+ });
221
+ it('deletes new file on revert', async () => {
222
+ const { getFileDiffFromResultDisplay } = await import('@google/gemini-cli-core');
223
+ vi.mocked(getFileDiffFromResultDisplay).mockReturnValue({
224
+ filePath: '/abs/path/new.ts',
225
+ fileName: 'new.ts',
226
+ originalContent: '',
227
+ newContent: 'SOME_CONTENT',
228
+ isNewFile: true,
229
+ diffStat: {
230
+ model_added_lines: 0,
231
+ model_removed_lines: 0,
232
+ model_added_chars: 0,
233
+ model_removed_chars: 0,
234
+ user_added_lines: 0,
235
+ user_removed_lines: 0,
236
+ user_added_chars: 0,
237
+ user_removed_chars: 0,
238
+ },
239
+ fileDiff: 'diff',
240
+ });
241
+ const userMsg = {
242
+ type: 'user',
243
+ id: 'target',
244
+ };
245
+ const conversation = {
246
+ messages: [
247
+ userMsg,
248
+ {
249
+ type: 'gemini',
250
+ toolCalls: [{ resultDisplay: 'diff' }],
251
+ },
252
+ ],
253
+ };
254
+ vi.mocked(fs.readFile).mockResolvedValue('SOME_CONTENT');
255
+ await revertFileChanges(conversation, 'target');
256
+ expect(fs.unlink).toHaveBeenCalledWith('/abs/path/new.ts');
257
+ });
258
+ it('handles smart revert (patching) successfully', async () => {
259
+ const { getFileDiffFromResultDisplay } = await import('@google/gemini-cli-core');
260
+ vi.mocked(getFileDiffFromResultDisplay).mockReturnValue({
261
+ filePath: '/abs/path/test.ts',
262
+ fileName: 'test.ts',
263
+ originalContent: 'LINE1\nLINE2\nLINE3',
264
+ newContent: 'LINE1\nEDITED\nLINE3',
265
+ isNewFile: false,
266
+ diffStat: {
267
+ model_added_lines: 0,
268
+ model_removed_lines: 0,
269
+ model_added_chars: 0,
270
+ model_removed_chars: 0,
271
+ user_added_lines: 0,
272
+ user_removed_lines: 0,
273
+ user_added_chars: 0,
274
+ user_removed_chars: 0,
275
+ },
276
+ fileDiff: 'diff',
277
+ });
278
+ const userMsg = {
279
+ type: 'user',
280
+ id: 'target',
281
+ };
282
+ const conversation = {
283
+ messages: [
284
+ userMsg,
285
+ {
286
+ type: 'gemini',
287
+ toolCalls: [{ resultDisplay: 'diff' }],
288
+ },
289
+ ],
290
+ };
291
+ // Current content has FURTHER changes
292
+ vi.mocked(fs.readFile).mockResolvedValue('LINE1\nEDITED\nLINE3\nNEWLINE');
293
+ await revertFileChanges(conversation, 'target');
294
+ // Should have successfully patched it back to ORIGINAL state but kept the NEWLINE
295
+ expect(fs.writeFile).toHaveBeenCalledWith('/abs/path/test.ts', 'LINE1\nLINE2\nLINE3\nNEWLINE');
296
+ });
297
+ it('emits warning on smart revert failure', async () => {
298
+ const { getFileDiffFromResultDisplay } = await import('@google/gemini-cli-core');
299
+ vi.mocked(getFileDiffFromResultDisplay).mockReturnValue({
300
+ filePath: '/abs/path/test.ts',
301
+ fileName: 'test.ts',
302
+ originalContent: 'OLD',
303
+ newContent: 'NEW',
304
+ isNewFile: false,
305
+ diffStat: {
306
+ model_added_lines: 0,
307
+ model_removed_lines: 0,
308
+ model_added_chars: 0,
309
+ model_removed_chars: 0,
310
+ user_added_lines: 0,
311
+ user_removed_lines: 0,
312
+ user_added_chars: 0,
313
+ user_removed_chars: 0,
314
+ },
315
+ fileDiff: 'diff',
316
+ });
317
+ const userMsg = {
318
+ type: 'user',
319
+ id: 'target',
320
+ };
321
+ const conversation = {
322
+ messages: [
323
+ userMsg,
324
+ {
325
+ type: 'gemini',
326
+ toolCalls: [{ resultDisplay: 'diff' }],
327
+ },
328
+ ],
329
+ };
330
+ // Current content is completely unrelated - diff won't apply
331
+ vi.mocked(fs.readFile).mockResolvedValue('UNRELATED');
332
+ await revertFileChanges(conversation, 'target');
333
+ expect(fs.writeFile).not.toHaveBeenCalled();
334
+ expect(coreEvents.emitFeedback).toHaveBeenCalledWith('warning', expect.stringContaining('Smart revert for test.ts failed'));
335
+ });
336
+ it('emits error if fs.readFile fails with a generic error', async () => {
337
+ const { getFileDiffFromResultDisplay } = await import('@google/gemini-cli-core');
338
+ vi.mocked(getFileDiffFromResultDisplay).mockReturnValue({
339
+ filePath: '/abs/path/test.ts',
340
+ fileName: 'test.ts',
341
+ originalContent: 'OLD',
342
+ newContent: 'NEW',
343
+ isNewFile: false,
344
+ diffStat: {
345
+ model_added_lines: 0,
346
+ model_removed_lines: 0,
347
+ model_added_chars: 0,
348
+ model_removed_chars: 0,
349
+ user_added_lines: 0,
350
+ user_removed_lines: 0,
351
+ user_added_chars: 0,
352
+ user_removed_chars: 0,
353
+ },
354
+ fileDiff: 'diff',
355
+ });
356
+ const userMsg = {
357
+ type: 'user',
358
+ id: 'target',
359
+ };
360
+ const conversation = {
361
+ messages: [
362
+ userMsg,
363
+ {
364
+ type: 'gemini',
365
+ toolCalls: [{ resultDisplay: 'diff' }],
366
+ },
367
+ ],
368
+ };
369
+ vi.mocked(fs.readFile).mockRejectedValue(new Error('disk failure'));
370
+ await revertFileChanges(conversation, 'target');
371
+ expect(coreEvents.emitFeedback).toHaveBeenCalledWith('error', expect.stringContaining('Error reading test.ts during revert: disk failure'), expect.any(Error));
372
+ });
373
+ });
374
+ });
375
+ //# sourceMappingURL=rewindFileOps.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rewindFileOps.test.js","sourceRoot":"","sources":["../../../../src/ui/utils/rewindFileOps.test.ts"],"names":[],"mappings":"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"}
@@ -11,22 +11,18 @@ export declare class TerminalCapabilityManager {
11
11
  private static readonly TERMINAL_NAME_QUERY;
12
12
  private static readonly DEVICE_ATTRIBUTES_QUERY;
13
13
  private static readonly MODIFY_OTHER_KEYS_QUERY;
14
- private static readonly BRACKETED_PASTE_QUERY;
15
14
  private static readonly KITTY_REGEX;
16
15
  private static readonly TERMINAL_NAME_REGEX;
17
16
  private static readonly DEVICE_ATTRIBUTES_REGEX;
18
17
  private static readonly OSC_11_REGEX;
19
18
  private static readonly MODIFY_OTHER_KEYS_REGEX;
20
- private static readonly BRACKETED_PASTE_REGEX;
19
+ private detectionComplete;
21
20
  private terminalBackgroundColor;
22
21
  private kittySupported;
23
22
  private kittyEnabled;
24
- private detectionComplete;
25
23
  private terminalName;
26
- private modifyOtherKeysSupported;
27
- private modifyOtherKeysEnabled;
28
- private bracketedPasteSupported;
29
- private bracketedPasteEnabled;
24
+ private modifyOtherKeysSupported?;
25
+ private deviceAttributesSupported;
30
26
  private constructor();
31
27
  static getInstance(): TerminalCapabilityManager;
32
28
  static resetInstanceForTesting(): void;
@@ -40,9 +36,6 @@ export declare class TerminalCapabilityManager {
40
36
  getTerminalBackgroundColor(): TerminalBackgroundColor;
41
37
  getTerminalName(): string | undefined;
42
38
  isKittyProtocolEnabled(): boolean;
43
- isBracketedPasteSupported(): boolean;
44
- isBracketedPasteEnabled(): boolean;
45
- isModifyOtherKeysEnabled(): boolean;
46
39
  private parseColor;
47
40
  }
48
41
  export declare const terminalCapabilityManager: TerminalCapabilityManager;