@google/gemini-cli 0.26.0-preview.4 → 0.27.0-nightly.20260126.cb772a5b7

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 (461) hide show
  1. package/README.md +18 -1
  2. package/dist/google-gemini-cli-0.27.0-nightly.20260121.97aac696f.tgz +0 -0
  3. package/dist/package.json +3 -4
  4. package/dist/src/commands/extensions.js +4 -1
  5. package/dist/src/commands/extensions.js.map +1 -1
  6. package/dist/src/commands/hooks.js +4 -1
  7. package/dist/src/commands/hooks.js.map +1 -1
  8. package/dist/src/commands/mcp/enableDisable.d.ts +13 -0
  9. package/dist/src/commands/mcp/enableDisable.js +122 -0
  10. package/dist/src/commands/mcp/enableDisable.js.map +1 -0
  11. package/dist/src/commands/mcp/list.d.ts +2 -0
  12. package/dist/src/commands/mcp/list.js +1 -1
  13. package/dist/src/commands/mcp/list.js.map +1 -1
  14. package/dist/src/commands/mcp.js +7 -1
  15. package/dist/src/commands/mcp.js.map +1 -1
  16. package/dist/src/commands/mcp.test.js +3 -1
  17. package/dist/src/commands/mcp.test.js.map +1 -1
  18. package/dist/src/commands/skills.js +4 -1
  19. package/dist/src/commands/skills.js.map +1 -1
  20. package/dist/src/config/config.d.ts +4 -0
  21. package/dist/src/config/config.js +41 -20
  22. package/dist/src/config/config.js.map +1 -1
  23. package/dist/src/config/config.test.js +181 -15
  24. package/dist/src/config/config.test.js.map +1 -1
  25. package/dist/src/config/keyBindings.d.ts +8 -5
  26. package/dist/src/config/keyBindings.js +38 -32
  27. package/dist/src/config/keyBindings.js.map +1 -1
  28. package/dist/src/config/keyBindings.test.js +8 -5
  29. package/dist/src/config/keyBindings.test.js.map +1 -1
  30. package/dist/src/config/mcp/index.d.ts +6 -0
  31. package/dist/src/config/mcp/index.js +7 -0
  32. package/dist/src/config/mcp/index.js.map +1 -0
  33. package/dist/src/config/mcp/mcpServerEnablement.d.ts +145 -0
  34. package/dist/src/config/mcp/mcpServerEnablement.js +254 -0
  35. package/dist/src/config/mcp/mcpServerEnablement.js.map +1 -0
  36. package/dist/src/config/mcp/mcpServerEnablement.test.js +147 -0
  37. package/dist/src/config/mcp/mcpServerEnablement.test.js.map +1 -0
  38. package/dist/src/config/sandboxConfig.test.js +11 -5
  39. package/dist/src/config/sandboxConfig.test.js.map +1 -1
  40. package/dist/src/config/settings.js +76 -0
  41. package/dist/src/config/settings.js.map +1 -1
  42. package/dist/src/config/settings.test.js +44 -0
  43. package/dist/src/config/settings.test.js.map +1 -1
  44. package/dist/src/config/settingsSchema.d.ts +21 -78
  45. package/dist/src/config/settingsSchema.js +21 -79
  46. package/dist/src/config/settingsSchema.js.map +1 -1
  47. package/dist/src/config/settingsSchema.test.js +1 -1
  48. package/dist/src/config/settingsSchema.test.js.map +1 -1
  49. package/dist/src/config/settings_repro.test.js +6 -2
  50. package/dist/src/config/settings_repro.test.js.map +1 -1
  51. package/dist/src/gemini.js +12 -7
  52. package/dist/src/gemini.js.map +1 -1
  53. package/dist/src/gemini.test.js +140 -10
  54. package/dist/src/gemini.test.js.map +1 -1
  55. package/dist/src/generated/git-commit.d.ts +2 -2
  56. package/dist/src/generated/git-commit.js +2 -2
  57. package/dist/src/generated/git-commit.js.map +1 -1
  58. package/dist/src/nonInteractiveCli.js +11 -3
  59. package/dist/src/nonInteractiveCli.js.map +1 -1
  60. package/dist/src/nonInteractiveCli.test.js +193 -3
  61. package/dist/src/nonInteractiveCli.test.js.map +1 -1
  62. package/dist/src/nonInteractiveCliCommands.js +6 -1
  63. package/dist/src/nonInteractiveCliCommands.js.map +1 -1
  64. package/dist/src/services/BuiltinCommandLoader.js +2 -0
  65. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  66. package/dist/src/services/FileCommandLoader.js +12 -4
  67. package/dist/src/services/FileCommandLoader.js.map +1 -1
  68. package/dist/src/services/FileCommandLoader.test.js +56 -0
  69. package/dist/src/services/FileCommandLoader.test.js.map +1 -1
  70. package/dist/src/test-utils/mockCommandContext.js +2 -0
  71. package/dist/src/test-utils/mockCommandContext.js.map +1 -1
  72. package/dist/src/test-utils/persistentStateFake.d.ts +26 -0
  73. package/dist/src/test-utils/persistentStateFake.js +39 -0
  74. package/dist/src/test-utils/persistentStateFake.js.map +1 -0
  75. package/dist/src/test-utils/render.d.ts +10 -1
  76. package/dist/src/test-utils/render.js +45 -16
  77. package/dist/src/test-utils/render.js.map +1 -1
  78. package/dist/src/ui/App.test.js +96 -38
  79. package/dist/src/ui/App.test.js.map +1 -1
  80. package/dist/src/ui/AppContainer.js +78 -18
  81. package/dist/src/ui/AppContainer.js.map +1 -1
  82. package/dist/src/ui/AppContainer.test.js +185 -19
  83. package/dist/src/ui/AppContainer.test.js.map +1 -1
  84. package/dist/src/ui/auth/ApiAuthDialog.test.js +5 -5
  85. package/dist/src/ui/auth/ApiAuthDialog.test.js.map +1 -1
  86. package/dist/src/ui/auth/AuthDialog.test.js +13 -9
  87. package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
  88. package/dist/src/ui/auth/LoginWithGoogleRestartDialog.test.js +6 -6
  89. package/dist/src/ui/auth/LoginWithGoogleRestartDialog.test.js.map +1 -1
  90. package/dist/src/ui/commands/aboutCommand.js +2 -0
  91. package/dist/src/ui/commands/aboutCommand.js.map +1 -1
  92. package/dist/src/ui/commands/aboutCommand.test.js +12 -0
  93. package/dist/src/ui/commands/aboutCommand.test.js.map +1 -1
  94. package/dist/src/ui/commands/agentsCommand.js +75 -4
  95. package/dist/src/ui/commands/agentsCommand.js.map +1 -1
  96. package/dist/src/ui/commands/agentsCommand.test.js +114 -0
  97. package/dist/src/ui/commands/agentsCommand.test.js.map +1 -1
  98. package/dist/src/ui/commands/directoryCommand.js +53 -49
  99. package/dist/src/ui/commands/directoryCommand.js.map +1 -1
  100. package/dist/src/ui/commands/directoryCommand.test.js +79 -23
  101. package/dist/src/ui/commands/directoryCommand.test.js.map +1 -1
  102. package/dist/src/ui/commands/initCommand.test.js +8 -4
  103. package/dist/src/ui/commands/initCommand.test.js.map +1 -1
  104. package/dist/src/ui/commands/mcpCommand.js +136 -5
  105. package/dist/src/ui/commands/mcpCommand.js.map +1 -1
  106. package/dist/src/ui/commands/policiesCommand.js +33 -20
  107. package/dist/src/ui/commands/policiesCommand.js.map +1 -1
  108. package/dist/src/ui/commands/policiesCommand.test.js +7 -4
  109. package/dist/src/ui/commands/policiesCommand.test.js.map +1 -1
  110. package/dist/src/ui/commands/rewindCommand.d.ts +7 -0
  111. package/dist/src/ui/commands/rewindCommand.js +132 -0
  112. package/dist/src/ui/commands/rewindCommand.js.map +1 -0
  113. package/dist/src/ui/commands/rewindCommand.test.js +242 -0
  114. package/dist/src/ui/commands/rewindCommand.test.js.map +1 -0
  115. package/dist/src/ui/commands/skillsCommand.js +6 -4
  116. package/dist/src/ui/commands/skillsCommand.js.map +1 -1
  117. package/dist/src/ui/commands/skillsCommand.test.js +17 -3
  118. package/dist/src/ui/commands/skillsCommand.test.js.map +1 -1
  119. package/dist/src/ui/commands/types.d.ts +5 -3
  120. package/dist/src/ui/commands/types.js.map +1 -1
  121. package/dist/src/ui/components/AboutBox.d.ts +1 -0
  122. package/dist/src/ui/components/AboutBox.js +5 -1
  123. package/dist/src/ui/components/AboutBox.js.map +1 -1
  124. package/dist/src/ui/components/AboutBox.test.js +8 -2
  125. package/dist/src/ui/components/AboutBox.test.js.map +1 -1
  126. package/dist/src/ui/components/AgentConfigDialog.d.ts +18 -0
  127. package/dist/src/ui/components/AgentConfigDialog.js +296 -0
  128. package/dist/src/ui/components/AgentConfigDialog.js.map +1 -0
  129. package/dist/src/ui/components/AgentConfigDialog.test.js +241 -0
  130. package/dist/src/ui/components/AgentConfigDialog.test.js.map +1 -0
  131. package/dist/src/ui/components/AlternateBufferQuittingDisplay.js +9 -2
  132. package/dist/src/ui/components/AlternateBufferQuittingDisplay.js.map +1 -1
  133. package/dist/src/ui/components/AlternateBufferQuittingDisplay.test.js +54 -25
  134. package/dist/src/ui/components/AlternateBufferQuittingDisplay.test.js.map +1 -1
  135. package/dist/src/ui/components/AppHeader.js +4 -1
  136. package/dist/src/ui/components/AppHeader.js.map +1 -1
  137. package/dist/src/ui/components/AppHeader.test.js +95 -22
  138. package/dist/src/ui/components/AppHeader.test.js.map +1 -1
  139. package/dist/src/ui/components/{AutoAcceptIndicator.d.ts → ApprovalModeIndicator.d.ts} +2 -2
  140. package/dist/src/ui/components/{AutoAcceptIndicator.js → ApprovalModeIndicator.js} +8 -3
  141. package/dist/src/ui/components/ApprovalModeIndicator.js.map +1 -0
  142. package/dist/src/ui/components/ApprovalModeIndicator.test.d.ts +6 -0
  143. package/dist/src/ui/components/{AutoAcceptIndicator.test.js → ApprovalModeIndicator.test.js} +13 -7
  144. package/dist/src/ui/components/ApprovalModeIndicator.test.js.map +1 -0
  145. package/dist/src/ui/components/AskUserDialog.d.ts +39 -0
  146. package/dist/src/ui/components/AskUserDialog.js +618 -0
  147. package/dist/src/ui/components/AskUserDialog.js.map +1 -0
  148. package/dist/src/ui/components/AskUserDialog.test.d.ts +6 -0
  149. package/dist/src/ui/components/AskUserDialog.test.js +598 -0
  150. package/dist/src/ui/components/AskUserDialog.test.js.map +1 -0
  151. package/dist/src/ui/components/Composer.d.ts +3 -1
  152. package/dist/src/ui/components/Composer.js +5 -5
  153. package/dist/src/ui/components/Composer.js.map +1 -1
  154. package/dist/src/ui/components/Composer.test.js +6 -6
  155. package/dist/src/ui/components/Composer.test.js.map +1 -1
  156. package/dist/src/ui/components/ConfigInitDisplay.js +3 -4
  157. package/dist/src/ui/components/ConfigInitDisplay.js.map +1 -1
  158. package/dist/src/ui/components/ConfigInitDisplay.test.js +13 -29
  159. package/dist/src/ui/components/ConfigInitDisplay.test.js.map +1 -1
  160. package/dist/src/ui/components/ContextUsageDisplay.test.js +7 -3
  161. package/dist/src/ui/components/ContextUsageDisplay.test.js.map +1 -1
  162. package/dist/src/ui/components/DialogManager.js +13 -0
  163. package/dist/src/ui/components/DialogManager.js.map +1 -1
  164. package/dist/src/ui/components/DialogManager.test.js +24 -0
  165. package/dist/src/ui/components/DialogManager.test.js.map +1 -1
  166. package/dist/src/ui/components/FolderTrustDialog.test.js +3 -1
  167. package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
  168. package/dist/src/ui/components/Footer.test.js +7 -0
  169. package/dist/src/ui/components/Footer.test.js.map +1 -1
  170. package/dist/src/ui/components/Help.js +5 -2
  171. package/dist/src/ui/components/Help.js.map +1 -1
  172. package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
  173. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  174. package/dist/src/ui/components/InputPrompt.js +32 -20
  175. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  176. package/dist/src/ui/components/InputPrompt.test.js +75 -1
  177. package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
  178. package/dist/src/ui/components/MultiFolderTrustDialog.js +2 -1
  179. package/dist/src/ui/components/MultiFolderTrustDialog.js.map +1 -1
  180. package/dist/src/ui/components/MultiFolderTrustDialog.test.js +12 -10
  181. package/dist/src/ui/components/MultiFolderTrustDialog.test.js.map +1 -1
  182. package/dist/src/ui/components/Notifications.js +14 -20
  183. package/dist/src/ui/components/Notifications.js.map +1 -1
  184. package/dist/src/ui/components/Notifications.test.js +45 -35
  185. package/dist/src/ui/components/Notifications.test.js.map +1 -1
  186. package/dist/src/ui/components/RewindViewer.d.ts +1 -1
  187. package/dist/src/ui/components/RewindViewer.js +65 -17
  188. package/dist/src/ui/components/RewindViewer.js.map +1 -1
  189. package/dist/src/ui/components/RewindViewer.test.js +5 -3
  190. package/dist/src/ui/components/RewindViewer.test.js.map +1 -1
  191. package/dist/src/ui/components/SessionBrowser.js +3 -2
  192. package/dist/src/ui/components/SessionBrowser.js.map +1 -1
  193. package/dist/src/ui/components/SessionBrowser.test.js +10 -3
  194. package/dist/src/ui/components/SessionBrowser.test.js.map +1 -1
  195. package/dist/src/ui/components/SettingsDialog.d.ts +1 -1
  196. package/dist/src/ui/components/SettingsDialog.js +266 -516
  197. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  198. package/dist/src/ui/components/SettingsDialog.test.js +2 -2
  199. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  200. package/dist/src/ui/components/ShellInputPrompt.test.js +17 -8
  201. package/dist/src/ui/components/ShellInputPrompt.test.js.map +1 -1
  202. package/dist/src/ui/components/SuggestionsDisplay.d.ts +1 -1
  203. package/dist/src/ui/components/SuggestionsDisplay.js +4 -3
  204. package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
  205. package/dist/src/ui/components/ToolConfirmationQueue.d.ts +12 -0
  206. package/dist/src/ui/components/ToolConfirmationQueue.js +30 -0
  207. package/dist/src/ui/components/ToolConfirmationQueue.js.map +1 -0
  208. package/dist/src/ui/components/ToolConfirmationQueue.test.d.ts +6 -0
  209. package/dist/src/ui/components/ToolConfirmationQueue.test.js +71 -0
  210. package/dist/src/ui/components/ToolConfirmationQueue.test.js.map +1 -0
  211. package/dist/src/ui/components/messages/RedirectionConfirmation.test.js +2 -4
  212. package/dist/src/ui/components/messages/RedirectionConfirmation.test.js.map +1 -1
  213. package/dist/src/ui/components/messages/ShellToolMessage.js +6 -41
  214. package/dist/src/ui/components/messages/ShellToolMessage.js.map +1 -1
  215. package/dist/src/ui/components/messages/ToolConfirmationMessage.d.ts +3 -2
  216. package/dist/src/ui/components/messages/ToolConfirmationMessage.js +61 -76
  217. package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
  218. package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +20 -7
  219. package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -1
  220. package/dist/src/ui/components/messages/ToolGroupMessage.js +34 -18
  221. package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
  222. package/dist/src/ui/components/messages/ToolGroupMessage.test.js +209 -24
  223. package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
  224. package/dist/src/ui/components/messages/ToolMessage.d.ts +1 -1
  225. package/dist/src/ui/components/messages/ToolMessage.js +7 -29
  226. package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
  227. package/dist/src/ui/components/messages/ToolMessageFocusHint.test.d.ts +6 -0
  228. package/dist/src/ui/components/messages/ToolMessageFocusHint.test.js +89 -0
  229. package/dist/src/ui/components/messages/ToolMessageFocusHint.test.js.map +1 -0
  230. package/dist/src/ui/components/messages/ToolShared.d.ts +26 -0
  231. package/dist/src/ui/components/messages/ToolShared.js +59 -6
  232. package/dist/src/ui/components/messages/ToolShared.js.map +1 -1
  233. package/dist/src/ui/components/shared/BaseSelectionList.d.ts +3 -1
  234. package/dist/src/ui/components/shared/BaseSelectionList.js +4 -2
  235. package/dist/src/ui/components/shared/BaseSelectionList.js.map +1 -1
  236. package/dist/src/ui/components/shared/BaseSelectionList.test.js +1 -0
  237. package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -1
  238. package/dist/src/ui/components/shared/BaseSettingsDialog.d.ts +72 -0
  239. package/dist/src/ui/components/shared/BaseSettingsDialog.js +293 -0
  240. package/dist/src/ui/components/shared/BaseSettingsDialog.js.map +1 -0
  241. package/dist/src/ui/components/shared/BaseSettingsDialog.test.d.ts +6 -0
  242. package/dist/src/ui/components/shared/BaseSettingsDialog.test.js +434 -0
  243. package/dist/src/ui/components/shared/BaseSettingsDialog.test.js.map +1 -0
  244. package/dist/src/ui/components/shared/ExpandableText.d.ts +17 -0
  245. package/dist/src/ui/components/{PrepareLabel.js → shared/ExpandableText.js} +30 -15
  246. package/dist/src/ui/components/shared/ExpandableText.js.map +1 -0
  247. package/dist/src/ui/components/shared/ExpandableText.test.d.ts +6 -0
  248. package/dist/src/ui/components/{PrepareLabel.test.js → shared/ExpandableText.test.js} +22 -11
  249. package/dist/src/ui/components/shared/ExpandableText.test.js.map +1 -0
  250. package/dist/src/ui/components/shared/TabHeader.d.ts +51 -0
  251. package/dist/src/ui/components/shared/TabHeader.js +42 -0
  252. package/dist/src/ui/components/shared/TabHeader.js.map +1 -0
  253. package/dist/src/ui/components/shared/TabHeader.test.d.ts +6 -0
  254. package/dist/src/ui/components/shared/TabHeader.test.js +106 -0
  255. package/dist/src/ui/components/shared/TabHeader.test.js.map +1 -0
  256. package/dist/src/ui/components/shared/TextInput.test.js +32 -24
  257. package/dist/src/ui/components/shared/TextInput.test.js.map +1 -1
  258. package/dist/src/ui/components/shared/text-buffer.d.ts +13 -0
  259. package/dist/src/ui/components/shared/text-buffer.js +173 -14
  260. package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
  261. package/dist/src/ui/components/shared/text-buffer.test.js +256 -44
  262. package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
  263. package/dist/src/ui/components/shared/vim-buffer-actions.test.js +4 -1
  264. package/dist/src/ui/components/shared/vim-buffer-actions.test.js.map +1 -1
  265. package/dist/src/ui/components/views/McpStatus.d.ts +1 -0
  266. package/dist/src/ui/components/views/McpStatus.js +30 -18
  267. package/dist/src/ui/components/views/McpStatus.js.map +1 -1
  268. package/dist/src/ui/components/views/McpStatus.test.js +7 -0
  269. package/dist/src/ui/components/views/McpStatus.test.js.map +1 -1
  270. package/dist/src/ui/constants/tips.js +2 -2
  271. package/dist/src/ui/constants/tips.js.map +1 -1
  272. package/dist/src/ui/constants.d.ts +1 -0
  273. package/dist/src/ui/constants.js +1 -0
  274. package/dist/src/ui/constants.js.map +1 -1
  275. package/dist/src/ui/contexts/KeypressContext.d.ts +3 -2
  276. package/dist/src/ui/contexts/KeypressContext.js +33 -25
  277. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  278. package/dist/src/ui/contexts/KeypressContext.test.js +151 -41
  279. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  280. package/dist/src/ui/contexts/MouseContext.test.js +8 -8
  281. package/dist/src/ui/contexts/MouseContext.test.js.map +1 -1
  282. package/dist/src/ui/contexts/ToolActionsContext.d.ts +20 -0
  283. package/dist/src/ui/contexts/ToolActionsContext.js +74 -0
  284. package/dist/src/ui/contexts/ToolActionsContext.js.map +1 -0
  285. package/dist/src/ui/contexts/ToolActionsContext.test.d.ts +6 -0
  286. package/dist/src/ui/contexts/ToolActionsContext.test.js +135 -0
  287. package/dist/src/ui/contexts/ToolActionsContext.test.js.map +1 -0
  288. package/dist/src/ui/contexts/UIActionsContext.d.ts +3 -1
  289. package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
  290. package/dist/src/ui/contexts/UIStateContext.d.ts +6 -2
  291. package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
  292. package/dist/src/ui/hooks/atCommandProcessor.js +19 -4
  293. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  294. package/dist/src/ui/hooks/keyToAnsi.js +1 -1
  295. package/dist/src/ui/hooks/keyToAnsi.js.map +1 -1
  296. package/dist/src/ui/hooks/slashCommandProcessor.d.ts +3 -1
  297. package/dist/src/ui/hooks/slashCommandProcessor.js +24 -7
  298. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  299. package/dist/src/ui/hooks/slashCommandProcessor.test.js +126 -30
  300. package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
  301. package/dist/src/ui/hooks/toolMapping.js +8 -11
  302. package/dist/src/ui/hooks/toolMapping.js.map +1 -1
  303. package/dist/src/ui/hooks/toolMapping.test.js +27 -6
  304. package/dist/src/ui/hooks/toolMapping.test.js.map +1 -1
  305. package/dist/src/ui/hooks/{useAutoAcceptIndicator.d.ts → useApprovalModeIndicator.d.ts} +2 -2
  306. package/dist/src/ui/hooks/{useAutoAcceptIndicator.js → useApprovalModeIndicator.js} +25 -11
  307. package/dist/src/ui/hooks/useApprovalModeIndicator.js.map +1 -0
  308. package/dist/src/ui/hooks/useApprovalModeIndicator.test.d.ts +6 -0
  309. package/dist/src/ui/hooks/{useAutoAcceptIndicator.test.js → useApprovalModeIndicator.test.js} +56 -31
  310. package/dist/src/ui/hooks/useApprovalModeIndicator.test.js.map +1 -0
  311. package/dist/src/ui/hooks/useConfirmingTool.d.ts +16 -0
  312. package/dist/src/ui/hooks/useConfirmingTool.js +39 -0
  313. package/dist/src/ui/hooks/useConfirmingTool.js.map +1 -0
  314. package/dist/src/ui/hooks/useGeminiStream.d.ts +1 -1
  315. package/dist/src/ui/hooks/useGeminiStream.js +20 -8
  316. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  317. package/dist/src/ui/hooks/useGeminiStream.test.js +79 -19
  318. package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
  319. package/dist/src/ui/hooks/useIncludeDirsTrust.d.ts +1 -1
  320. package/dist/src/ui/hooks/useIncludeDirsTrust.js +9 -20
  321. package/dist/src/ui/hooks/useIncludeDirsTrust.js.map +1 -1
  322. package/dist/src/ui/hooks/useIncludeDirsTrust.test.js +33 -12
  323. package/dist/src/ui/hooks/useIncludeDirsTrust.test.js.map +1 -1
  324. package/dist/src/ui/hooks/useKeypress.test.js +10 -3
  325. package/dist/src/ui/hooks/useKeypress.test.js.map +1 -1
  326. package/dist/src/ui/hooks/useLoadingIndicator.d.ts +7 -1
  327. package/dist/src/ui/hooks/useLoadingIndicator.js +3 -3
  328. package/dist/src/ui/hooks/useLoadingIndicator.js.map +1 -1
  329. package/dist/src/ui/hooks/useLoadingIndicator.test.js +17 -9
  330. package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
  331. package/dist/src/ui/hooks/usePhraseCycler.d.ts +2 -2
  332. package/dist/src/ui/hooks/usePhraseCycler.js +4 -14
  333. package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
  334. package/dist/src/ui/hooks/usePhraseCycler.test.js +13 -42
  335. package/dist/src/ui/hooks/usePhraseCycler.test.js.map +1 -1
  336. package/dist/src/ui/hooks/useSelectionList.d.ts +4 -1
  337. package/dist/src/ui/hooks/useSelectionList.js +51 -13
  338. package/dist/src/ui/hooks/useSelectionList.js.map +1 -1
  339. package/dist/src/ui/hooks/useSelectionList.test.js +35 -3
  340. package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
  341. package/dist/src/ui/hooks/useSessionResume.test.js +3 -2
  342. package/dist/src/ui/hooks/useSessionResume.test.js.map +1 -1
  343. package/dist/src/ui/hooks/useShellInactivityStatus.d.ts +26 -0
  344. package/dist/src/ui/hooks/useShellInactivityStatus.js +46 -0
  345. package/dist/src/ui/hooks/useShellInactivityStatus.js.map +1 -0
  346. package/dist/src/ui/hooks/useShellInactivityStatus.test.d.ts +6 -0
  347. package/dist/src/ui/hooks/useShellInactivityStatus.test.js +84 -0
  348. package/dist/src/ui/hooks/useShellInactivityStatus.test.js.map +1 -0
  349. package/dist/src/ui/hooks/useTabbedNavigation.d.ts +53 -0
  350. package/dist/src/ui/hooks/useTabbedNavigation.js +150 -0
  351. package/dist/src/ui/hooks/useTabbedNavigation.js.map +1 -0
  352. package/dist/src/ui/hooks/useTabbedNavigation.test.d.ts +6 -0
  353. package/dist/src/ui/hooks/useTabbedNavigation.test.js +187 -0
  354. package/dist/src/ui/hooks/useTabbedNavigation.test.js.map +1 -0
  355. package/dist/src/ui/hooks/useTips.d.ts +10 -0
  356. package/dist/src/ui/hooks/useTips.js +18 -0
  357. package/dist/src/ui/hooks/useTips.js.map +1 -0
  358. package/dist/src/ui/hooks/useTips.test.d.ts +6 -0
  359. package/dist/src/ui/hooks/useTips.test.js +33 -0
  360. package/dist/src/ui/hooks/useTips.test.js.map +1 -0
  361. package/dist/src/ui/hooks/useToolExecutionScheduler.d.ts +30 -0
  362. package/dist/src/ui/hooks/useToolExecutionScheduler.js +113 -0
  363. package/dist/src/ui/hooks/useToolExecutionScheduler.js.map +1 -0
  364. package/dist/src/ui/hooks/useToolExecutionScheduler.test.d.ts +6 -0
  365. package/dist/src/ui/hooks/useToolExecutionScheduler.test.js +296 -0
  366. package/dist/src/ui/hooks/useToolExecutionScheduler.test.js.map +1 -0
  367. package/dist/src/ui/hooks/useToolScheduler.d.ts +29 -0
  368. package/dist/src/ui/hooks/useToolScheduler.js +30 -0
  369. package/dist/src/ui/hooks/useToolScheduler.js.map +1 -0
  370. package/dist/src/ui/hooks/useToolScheduler.test.js +1 -1
  371. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  372. package/dist/src/ui/hooks/useToolSchedulerFacade.test.d.ts +6 -0
  373. package/dist/src/ui/hooks/useToolSchedulerFacade.test.js +45 -0
  374. package/dist/src/ui/hooks/useToolSchedulerFacade.test.js.map +1 -0
  375. package/dist/src/ui/hooks/useTurnActivityMonitor.d.ts +16 -0
  376. package/dist/src/ui/hooks/useTurnActivityMonitor.js +49 -0
  377. package/dist/src/ui/hooks/useTurnActivityMonitor.js.map +1 -0
  378. package/dist/src/ui/hooks/useTurnActivityMonitor.test.d.ts +6 -0
  379. package/dist/src/ui/hooks/useTurnActivityMonitor.test.js +97 -0
  380. package/dist/src/ui/hooks/useTurnActivityMonitor.test.js.map +1 -0
  381. package/dist/src/ui/hooks/vim.js +5 -3
  382. package/dist/src/ui/hooks/vim.js.map +1 -1
  383. package/dist/src/ui/hooks/vim.test.js +4 -2
  384. package/dist/src/ui/hooks/vim.test.js.map +1 -1
  385. package/dist/src/ui/keyMatchers.js +5 -13
  386. package/dist/src/ui/keyMatchers.js.map +1 -1
  387. package/dist/src/ui/keyMatchers.test.js +23 -20
  388. package/dist/src/ui/keyMatchers.test.js.map +1 -1
  389. package/dist/src/ui/layouts/DefaultAppLayout.js +10 -2
  390. package/dist/src/ui/layouts/DefaultAppLayout.js.map +1 -1
  391. package/dist/src/ui/noninteractive/nonInteractiveUi.js +1 -0
  392. package/dist/src/ui/noninteractive/nonInteractiveUi.js.map +1 -1
  393. package/dist/src/ui/types.d.ts +11 -3
  394. package/dist/src/ui/types.js.map +1 -1
  395. package/dist/src/ui/utils/clipboardUtils.d.ts +4 -4
  396. package/dist/src/ui/utils/clipboardUtils.js +198 -12
  397. package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
  398. package/dist/src/ui/utils/clipboardUtils.test.js +219 -47
  399. package/dist/src/ui/utils/clipboardUtils.test.js.map +1 -1
  400. package/dist/src/ui/utils/clipboardUtils.windows.test.js +3 -0
  401. package/dist/src/ui/utils/clipboardUtils.windows.test.js.map +1 -1
  402. package/dist/src/ui/utils/commandUtils.test.js +11 -3
  403. package/dist/src/ui/utils/commandUtils.test.js.map +1 -1
  404. package/dist/src/ui/utils/directoryUtils.d.ts +10 -0
  405. package/dist/src/ui/utils/directoryUtils.js +12 -0
  406. package/dist/src/ui/utils/directoryUtils.js.map +1 -1
  407. package/dist/src/ui/utils/directoryUtils.test.js +8 -4
  408. package/dist/src/ui/utils/directoryUtils.test.js.map +1 -1
  409. package/dist/src/ui/utils/formatters.d.ts +1 -1
  410. package/dist/src/ui/utils/formatters.js +2 -3
  411. package/dist/src/ui/utils/formatters.js.map +1 -1
  412. package/dist/src/ui/utils/highlight.d.ts +2 -2
  413. package/dist/src/ui/utils/highlight.js +9 -3
  414. package/dist/src/ui/utils/highlight.js.map +1 -1
  415. package/dist/src/ui/utils/highlight.test.js +3 -0
  416. package/dist/src/ui/utils/highlight.test.js.map +1 -1
  417. package/dist/src/ui/utils/terminalCapabilityManager.d.ts +1 -2
  418. package/dist/src/ui/utils/terminalCapabilityManager.js +2 -8
  419. package/dist/src/ui/utils/terminalCapabilityManager.js.map +1 -1
  420. package/dist/src/ui/utils/terminalCapabilityManager.test.js +2 -3
  421. package/dist/src/ui/utils/terminalCapabilityManager.test.js.map +1 -1
  422. package/dist/src/ui/utils/terminalSetup.test.js +5 -3
  423. package/dist/src/ui/utils/terminalSetup.test.js.map +1 -1
  424. package/dist/src/ui/utils/textUtils.d.ts +5 -0
  425. package/dist/src/ui/utils/textUtils.js +14 -0
  426. package/dist/src/ui/utils/textUtils.js.map +1 -1
  427. package/dist/src/ui/utils/textUtils.test.js +19 -1
  428. package/dist/src/ui/utils/textUtils.test.js.map +1 -1
  429. package/dist/src/utils/cleanup.js +15 -0
  430. package/dist/src/utils/cleanup.js.map +1 -1
  431. package/dist/src/utils/events.d.ts +1 -6
  432. package/dist/src/utils/events.js +0 -2
  433. package/dist/src/utils/events.js.map +1 -1
  434. package/dist/src/utils/events.test.js +4 -4
  435. package/dist/src/utils/events.test.js.map +1 -1
  436. package/dist/src/utils/handleAutoUpdate.test.js +3 -0
  437. package/dist/src/utils/handleAutoUpdate.test.js.map +1 -1
  438. package/dist/src/utils/installationInfo.js +4 -2
  439. package/dist/src/utils/installationInfo.js.map +1 -1
  440. package/dist/src/utils/persistentState.d.ts +2 -0
  441. package/dist/src/utils/persistentState.js.map +1 -1
  442. package/dist/src/utils/windowTitle.d.ts +2 -1
  443. package/dist/src/utils/windowTitle.js +8 -1
  444. package/dist/src/utils/windowTitle.js.map +1 -1
  445. package/dist/src/utils/windowTitle.test.js +25 -1
  446. package/dist/src/utils/windowTitle.test.js.map +1 -1
  447. package/dist/src/zed-integration/zedIntegration.js +26 -5
  448. package/dist/src/zed-integration/zedIntegration.js.map +1 -1
  449. package/dist/tsconfig.tsbuildinfo +1 -1
  450. package/package.json +4 -5
  451. package/dist/google-gemini-cli-0.26.0-preview.3.tgz +0 -0
  452. package/dist/src/ui/components/AutoAcceptIndicator.js.map +0 -1
  453. package/dist/src/ui/components/AutoAcceptIndicator.test.js.map +0 -1
  454. package/dist/src/ui/components/PrepareLabel.d.ts +0 -15
  455. package/dist/src/ui/components/PrepareLabel.js.map +0 -1
  456. package/dist/src/ui/components/PrepareLabel.test.js.map +0 -1
  457. package/dist/src/ui/hooks/useAutoAcceptIndicator.js.map +0 -1
  458. package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +0 -1
  459. /package/dist/src/{ui/components/AutoAcceptIndicator.test.d.ts → config/mcp/mcpServerEnablement.test.d.ts} +0 -0
  460. /package/dist/src/ui/{components/PrepareLabel.test.d.ts → commands/rewindCommand.test.d.ts} +0 -0
  461. /package/dist/src/ui/{hooks/useAutoAcceptIndicator.test.d.ts → components/AgentConfigDialog.test.d.ts} +0 -0
@@ -1,39 +1,24 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- /**
3
- * @license
4
- * Copyright 2025 Google LLC
5
- * SPDX-License-Identifier: Apache-2.0
6
- */
7
- import React, { useState, useEffect, useMemo } from 'react';
8
- import { Box, Text } from 'ink';
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect, useMemo, useCallback } from 'react';
3
+ import { Text } from 'ink';
9
4
  import { AsyncFzf } from 'fzf';
10
5
  import { theme } from '../semantic-colors.js';
11
6
  import { SettingScope } from '../../config/settings.js';
12
- import { getScopeItems, getScopeMessageForSetting, } from '../../utils/dialogScopeUtils.js';
13
- import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
14
- import { getDialogSettingKeys, setPendingSettingValue, getDisplayValue, hasRestartRequiredSettings, saveModifiedSettings, getSettingDefinition, isDefaultValue, requiresRestart, getRestartRequiredFromModified, getEffectiveDefaultValue, setPendingSettingValueAny, getNestedValue, getEffectiveValue, } from '../../utils/settingsUtils.js';
7
+ import { getScopeMessageForSetting } from '../../utils/dialogScopeUtils.js';
8
+ import { getDialogSettingKeys, setPendingSettingValue, getDisplayValue, hasRestartRequiredSettings, saveModifiedSettings, getSettingDefinition, isDefaultValue, requiresRestart, getRestartRequiredFromModified, getEffectiveDefaultValue, setPendingSettingValueAny, getEffectiveValue, } from '../../utils/settingsUtils.js';
15
9
  import { useVimMode } from '../contexts/VimModeContext.js';
16
- import { useKeypress } from '../hooks/useKeypress.js';
17
- import chalk from 'chalk';
18
- import { cpSlice, cpLen, stripUnsafeCharacters, getCachedStringWidth, } from '../utils/textUtils.js';
10
+ import { getCachedStringWidth } from '../utils/textUtils.js';
19
11
  import { TOGGLE_TYPES, } from '../../config/settingsSchema.js';
20
12
  import { coreEvents, debugLogger } from '@google/gemini-cli-core';
21
- import { keyMatchers, Command } from '../keyMatchers.js';
22
13
  import { useUIState } from '../contexts/UIStateContext.js';
23
14
  import { useTextBuffer } from './shared/text-buffer.js';
24
- import { TextInput } from './shared/TextInput.js';
15
+ import { BaseSettingsDialog, } from './shared/BaseSettingsDialog.js';
25
16
  const MAX_ITEMS_TO_SHOW = 8;
26
17
  export function SettingsDialog({ settings, onSelect, onRestartRequest, availableTerminalHeight, config, }) {
27
18
  // Get vim mode context to sync vim mode changes
28
19
  const { vimEnabled, toggleVimEnabled } = useVimMode();
29
- // Focus state: 'settings' or 'scope'
30
- const [focusSection, setFocusSection] = useState('settings');
31
20
  // Scope selector state (User by default)
32
21
  const [selectedScope, setSelectedScope] = useState(SettingScope.User);
33
- // Active indices
34
- const [activeSettingIndex, setActiveSettingIndex] = useState(0);
35
- // Scroll offset for settings
36
- const [scrollOffset, setScrollOffset] = useState(0);
37
22
  const [showRestartPrompt, setShowRestartPrompt] = useState(false);
38
23
  // Search state
39
24
  const [searchQuery, setSearchQuery] = useState('');
@@ -73,8 +58,6 @@ export function SettingsDialog({ settings, onSelect, onRestartRequest, available
73
58
  matchedKeys.add(key);
74
59
  });
75
60
  setFilteredKeys(Array.from(matchedKeys));
76
- setActiveSettingIndex(0); // Reset cursor
77
- setScrollOffset(0);
78
61
  };
79
62
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
80
63
  doSearch();
@@ -134,141 +117,160 @@ export function SettingsDialog({ settings, onSelect, onRestartRequest, available
134
117
  }
135
118
  return max;
136
119
  }, [selectedScope, settings]);
137
- const generateSettingsItems = () => {
138
- const settingKeys = searchQuery ? filteredKeys : getDialogSettingKeys();
120
+ // Get mainAreaWidth for search buffer viewport
121
+ const { mainAreaWidth } = useUIState();
122
+ const viewportWidth = mainAreaWidth - 8;
123
+ // Search input buffer
124
+ const searchBuffer = useTextBuffer({
125
+ initialText: '',
126
+ initialCursorOffset: 0,
127
+ viewport: {
128
+ width: viewportWidth,
129
+ height: 1,
130
+ },
131
+ isValidPath: () => false,
132
+ singleLine: true,
133
+ onChange: (text) => setSearchQuery(text),
134
+ });
135
+ // Generate items for BaseSettingsDialog
136
+ const settingKeys = searchQuery ? filteredKeys : getDialogSettingKeys();
137
+ const items = useMemo(() => {
138
+ const scopeSettings = settings.forScope(selectedScope).settings;
139
+ const mergedSettings = settings.merged;
139
140
  return settingKeys.map((key) => {
140
141
  const definition = getSettingDefinition(key);
142
+ const type = definition?.type ?? 'string';
143
+ // Get the display value (with * indicator if modified)
144
+ const displayValue = getDisplayValue(key, scopeSettings, mergedSettings, modifiedSettings, pendingSettings);
145
+ // Get the scope message (e.g., "(Modified in Workspace)")
146
+ const scopeMessage = getScopeMessageForSetting(key, selectedScope, settings);
147
+ // Check if the value is at default (grey it out)
148
+ const isGreyedOut = isDefaultValue(key, scopeSettings);
149
+ // Get raw value for edit mode initialization
150
+ const rawValue = getEffectiveValue(key, pendingSettings, {});
141
151
  return {
152
+ key,
142
153
  label: definition?.label || key,
143
154
  description: definition?.description,
144
- value: key,
145
- type: definition?.type,
146
- toggle: () => {
147
- if (!TOGGLE_TYPES.has(definition?.type)) {
148
- return;
149
- }
150
- const currentValue = getEffectiveValue(key, pendingSettings, {});
151
- let newValue;
152
- if (definition?.type === 'boolean') {
153
- newValue = !currentValue;
154
- setPendingSettings((prev) => setPendingSettingValue(key, newValue, prev));
155
- }
156
- else if (definition?.type === 'enum' && definition.options) {
157
- const options = definition.options;
158
- const currentIndex = options?.findIndex((opt) => opt.value === currentValue);
159
- if (currentIndex !== -1 && currentIndex < options.length - 1) {
160
- newValue = options[currentIndex + 1].value;
161
- }
162
- else {
163
- newValue = options[0].value; // loop back to start.
164
- }
165
- setPendingSettings((prev) => setPendingSettingValueAny(key, newValue, prev));
166
- }
167
- if (!requiresRestart(key)) {
168
- const immediateSettings = new Set([key]);
169
- const currentScopeSettings = settings.forScope(selectedScope).settings;
170
- const immediateSettingsObject = setPendingSettingValueAny(key, newValue, currentScopeSettings);
171
- debugLogger.log(`[DEBUG SettingsDialog] Saving ${key} immediately with value:`, newValue);
172
- saveModifiedSettings(immediateSettings, immediateSettingsObject, settings, selectedScope);
173
- // Special handling for vim mode to sync with VimModeContext
174
- if (key === 'general.vimMode' && newValue !== vimEnabled) {
175
- // Call toggleVimEnabled to sync the VimModeContext local state
176
- toggleVimEnabled().catch((error) => {
177
- coreEvents.emitFeedback('error', 'Failed to toggle vim mode:', error);
178
- });
179
- }
180
- // Remove from modifiedSettings since it's now saved
181
- setModifiedSettings((prev) => {
182
- const updated = new Set(prev);
183
- updated.delete(key);
184
- return updated;
185
- });
186
- // Also remove from restart-required settings if it was there
187
- setRestartRequiredSettings((prev) => {
188
- const updated = new Set(prev);
189
- updated.delete(key);
190
- return updated;
191
- });
192
- // Remove from global pending changes if present
193
- setGlobalPendingChanges((prev) => {
194
- if (!prev.has(key))
195
- return prev;
196
- const next = new Map(prev);
197
- next.delete(key);
198
- return next;
199
- });
200
- if (key === 'general.previewFeatures') {
201
- config?.setPreviewFeatures(newValue);
202
- }
203
- }
204
- else {
205
- // For restart-required settings, track as modified
206
- setModifiedSettings((prev) => {
207
- const updated = new Set(prev).add(key);
208
- const needsRestart = hasRestartRequiredSettings(updated);
209
- debugLogger.log(`[DEBUG SettingsDialog] Modified settings:`, Array.from(updated), 'Needs restart:', needsRestart);
210
- if (needsRestart) {
211
- setShowRestartPrompt(true);
212
- setRestartRequiredSettings((prevRestart) => new Set(prevRestart).add(key));
213
- }
214
- return updated;
215
- });
216
- // Add/update pending change globally so it persists across scopes
217
- setGlobalPendingChanges((prev) => {
218
- const next = new Map(prev);
219
- next.set(key, newValue);
220
- return next;
221
- });
222
- }
223
- },
155
+ type: type,
156
+ displayValue,
157
+ isGreyedOut,
158
+ scopeMessage,
159
+ rawValue: rawValue,
224
160
  };
225
161
  });
226
- };
227
- const items = generateSettingsItems();
228
- // Generic edit state
229
- const [editingKey, setEditingKey] = useState(null);
230
- const [editBuffer, setEditBuffer] = useState('');
231
- const [editCursorPos, setEditCursorPos] = useState(0); // Cursor position within edit buffer
232
- const [cursorVisible, setCursorVisible] = useState(true);
233
- useEffect(() => {
234
- if (!editingKey) {
235
- setCursorVisible(true);
162
+ }, [settingKeys, selectedScope, settings, modifiedSettings, pendingSettings]);
163
+ // Scope selection handler
164
+ const handleScopeChange = useCallback((scope) => {
165
+ setSelectedScope(scope);
166
+ }, []);
167
+ // Toggle handler for boolean/enum settings
168
+ const handleItemToggle = useCallback((key, _item) => {
169
+ const definition = getSettingDefinition(key);
170
+ if (!TOGGLE_TYPES.has(definition?.type)) {
236
171
  return;
237
172
  }
238
- const id = setInterval(() => setCursorVisible((v) => !v), 500);
239
- return () => clearInterval(id);
240
- }, [editingKey]);
241
- const startEditing = (key, initial) => {
242
- setEditingKey(key);
243
- const initialValue = initial ?? '';
244
- setEditBuffer(initialValue);
245
- setEditCursorPos(cpLen(initialValue)); // Position cursor at end of initial value
246
- };
247
- const commitEdit = (key) => {
173
+ const currentValue = getEffectiveValue(key, pendingSettings, {});
174
+ let newValue;
175
+ if (definition?.type === 'boolean') {
176
+ newValue = !currentValue;
177
+ setPendingSettings((prev) => setPendingSettingValue(key, newValue, prev));
178
+ }
179
+ else if (definition?.type === 'enum' && definition.options) {
180
+ const options = definition.options;
181
+ const currentIndex = options?.findIndex((opt) => opt.value === currentValue);
182
+ if (currentIndex !== -1 && currentIndex < options.length - 1) {
183
+ newValue = options[currentIndex + 1].value;
184
+ }
185
+ else {
186
+ newValue = options[0].value; // loop back to start.
187
+ }
188
+ setPendingSettings((prev) => setPendingSettingValueAny(key, newValue, prev));
189
+ }
190
+ if (!requiresRestart(key)) {
191
+ const immediateSettings = new Set([key]);
192
+ const currentScopeSettings = settings.forScope(selectedScope).settings;
193
+ const immediateSettingsObject = setPendingSettingValueAny(key, newValue, currentScopeSettings);
194
+ debugLogger.log(`[DEBUG SettingsDialog] Saving ${key} immediately with value:`, newValue);
195
+ saveModifiedSettings(immediateSettings, immediateSettingsObject, settings, selectedScope);
196
+ // Special handling for vim mode to sync with VimModeContext
197
+ if (key === 'general.vimMode' && newValue !== vimEnabled) {
198
+ // Call toggleVimEnabled to sync the VimModeContext local state
199
+ toggleVimEnabled().catch((error) => {
200
+ coreEvents.emitFeedback('error', 'Failed to toggle vim mode:', error);
201
+ });
202
+ }
203
+ // Remove from modifiedSettings since it's now saved
204
+ setModifiedSettings((prev) => {
205
+ const updated = new Set(prev);
206
+ updated.delete(key);
207
+ return updated;
208
+ });
209
+ // Also remove from restart-required settings if it was there
210
+ setRestartRequiredSettings((prev) => {
211
+ const updated = new Set(prev);
212
+ updated.delete(key);
213
+ return updated;
214
+ });
215
+ // Remove from global pending changes if present
216
+ setGlobalPendingChanges((prev) => {
217
+ if (!prev.has(key))
218
+ return prev;
219
+ const next = new Map(prev);
220
+ next.delete(key);
221
+ return next;
222
+ });
223
+ if (key === 'general.previewFeatures') {
224
+ config?.setPreviewFeatures(newValue);
225
+ }
226
+ }
227
+ else {
228
+ // For restart-required settings, track as modified
229
+ setModifiedSettings((prev) => {
230
+ const updated = new Set(prev).add(key);
231
+ const needsRestart = hasRestartRequiredSettings(updated);
232
+ debugLogger.log(`[DEBUG SettingsDialog] Modified settings:`, Array.from(updated), 'Needs restart:', needsRestart);
233
+ if (needsRestart) {
234
+ setShowRestartPrompt(true);
235
+ setRestartRequiredSettings((prevRestart) => new Set(prevRestart).add(key));
236
+ }
237
+ return updated;
238
+ });
239
+ // Record pending change globally
240
+ setGlobalPendingChanges((prev) => {
241
+ const next = new Map(prev);
242
+ next.set(key, newValue);
243
+ return next;
244
+ });
245
+ }
246
+ }, [
247
+ pendingSettings,
248
+ settings,
249
+ selectedScope,
250
+ vimEnabled,
251
+ toggleVimEnabled,
252
+ config,
253
+ ]);
254
+ // Edit commit handler
255
+ const handleEditCommit = useCallback((key, newValue, _item) => {
248
256
  const definition = getSettingDefinition(key);
249
257
  const type = definition?.type;
250
- if (editBuffer.trim() === '' && type === 'number') {
258
+ if (newValue.trim() === '' && type === 'number') {
251
259
  // Nothing entered for a number; cancel edit
252
- setEditingKey(null);
253
- setEditBuffer('');
254
- setEditCursorPos(0);
255
260
  return;
256
261
  }
257
262
  let parsed;
258
263
  if (type === 'number') {
259
- const numParsed = Number(editBuffer.trim());
264
+ const numParsed = Number(newValue.trim());
260
265
  if (Number.isNaN(numParsed)) {
261
266
  // Invalid number; cancel edit
262
- setEditingKey(null);
263
- setEditBuffer('');
264
- setEditCursorPos(0);
265
267
  return;
266
268
  }
267
269
  parsed = numParsed;
268
270
  }
269
271
  else {
270
272
  // For strings, use the buffer as is.
271
- parsed = editBuffer;
273
+ parsed = newValue;
272
274
  }
273
275
  // Update pending
274
276
  setPendingSettings((prev) => setPendingSettingValueAny(key, parsed, prev));
@@ -315,84 +317,67 @@ export function SettingsDialog({ settings, onSelect, onRestartRequest, available
315
317
  return next;
316
318
  });
317
319
  }
318
- setEditingKey(null);
319
- setEditBuffer('');
320
- setEditCursorPos(0);
321
- };
322
- // Scope selector items
323
- const scopeItems = getScopeItems().map((item) => ({
324
- ...item,
325
- key: item.value,
326
- }));
327
- const handleScopeHighlight = (scope) => {
328
- setSelectedScope(scope);
329
- };
330
- const handleScopeSelect = (scope) => {
331
- handleScopeHighlight(scope);
332
- setFocusSection('settings');
333
- };
334
- // Height constraint calculations similar to ThemeDialog
335
- const DIALOG_PADDING = 5;
336
- const SETTINGS_TITLE_HEIGHT = 2; // "Settings" title + spacing
337
- const SCROLL_ARROWS_HEIGHT = 2; // Up and down arrows
338
- const SPACING_HEIGHT = 1; // Space between settings list and scope
339
- const SCOPE_SELECTION_HEIGHT = 4; // Apply To section height
340
- const BOTTOM_HELP_TEXT_HEIGHT = 1; // Help text
341
- const RESTART_PROMPT_HEIGHT = showRestartPrompt ? 1 : 0;
342
- let currentAvailableTerminalHeight = availableTerminalHeight ?? Number.MAX_SAFE_INTEGER;
343
- currentAvailableTerminalHeight -= 2; // Top and bottom borders
344
- // Start with basic fixed height (without scope selection)
345
- let totalFixedHeight = DIALOG_PADDING +
346
- SETTINGS_TITLE_HEIGHT +
347
- SCROLL_ARROWS_HEIGHT +
348
- SPACING_HEIGHT +
349
- BOTTOM_HELP_TEXT_HEIGHT +
350
- RESTART_PROMPT_HEIGHT;
351
- // Calculate how much space we have for settings
352
- let availableHeightForSettings = Math.max(1, currentAvailableTerminalHeight - totalFixedHeight);
353
- // Each setting item takes up to 3 lines (label/value row, description row, and spacing)
354
- let maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3));
355
- // Decide whether to show scope selection based on remaining space
356
- let showScopeSelection = true;
357
- // If we have limited height, prioritize showing more settings over scope selection
358
- if (availableTerminalHeight && availableTerminalHeight < 25) {
359
- // For very limited height, hide scope selection to show more settings
360
- const totalWithScope = totalFixedHeight + SCOPE_SELECTION_HEIGHT;
361
- const availableWithScope = Math.max(1, currentAvailableTerminalHeight - totalWithScope);
362
- const maxItemsWithScope = Math.max(1, Math.floor(availableWithScope / 3));
363
- // If hiding scope selection allows us to show significantly more settings, do it
364
- if (maxVisibleItems > maxItemsWithScope + 1) {
365
- showScopeSelection = false;
320
+ }, [settings, selectedScope]);
321
+ // Clear/reset handler - removes the value from settings.json so it falls back to default
322
+ const handleItemClear = useCallback((key, _item) => {
323
+ const defaultValue = getEffectiveDefaultValue(key, config);
324
+ // Update local pending state to show the default value
325
+ if (typeof defaultValue === 'boolean') {
326
+ setPendingSettings((prev) => setPendingSettingValue(key, defaultValue, prev));
366
327
  }
367
- else {
368
- // Otherwise include scope selection and recalculate
369
- totalFixedHeight += SCOPE_SELECTION_HEIGHT;
370
- availableHeightForSettings = Math.max(1, currentAvailableTerminalHeight - totalFixedHeight);
371
- maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3));
328
+ else if (typeof defaultValue === 'number' ||
329
+ typeof defaultValue === 'string') {
330
+ setPendingSettings((prev) => setPendingSettingValueAny(key, defaultValue, prev));
372
331
  }
373
- }
374
- else {
375
- // For normal height, include scope selection
376
- totalFixedHeight += SCOPE_SELECTION_HEIGHT;
377
- availableHeightForSettings = Math.max(1, currentAvailableTerminalHeight - totalFixedHeight);
378
- maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3));
379
- }
380
- // Use the calculated maxVisibleItems or fall back to the original maxItemsToShow
381
- const effectiveMaxItemsToShow = availableTerminalHeight
382
- ? Math.min(maxVisibleItems, items.length)
383
- : MAX_ITEMS_TO_SHOW;
384
- // Ensure focus stays on settings when scope selection is hidden
385
- React.useEffect(() => {
386
- if (!showScopeSelection && focusSection === 'scope') {
387
- setFocusSection('settings');
332
+ // Clear the value from settings.json (set to undefined to remove the key)
333
+ if (!requiresRestart(key)) {
334
+ settings.setValue(selectedScope, key, undefined);
335
+ // Special handling for vim mode
336
+ if (key === 'general.vimMode') {
337
+ const booleanDefaultValue = typeof defaultValue === 'boolean' ? defaultValue : false;
338
+ if (booleanDefaultValue !== vimEnabled) {
339
+ toggleVimEnabled().catch((error) => {
340
+ coreEvents.emitFeedback('error', 'Failed to toggle vim mode:', error);
341
+ });
342
+ }
343
+ }
344
+ if (key === 'general.previewFeatures') {
345
+ const booleanDefaultValue = typeof defaultValue === 'boolean' ? defaultValue : false;
346
+ config?.setPreviewFeatures(booleanDefaultValue);
347
+ }
388
348
  }
389
- }, [showScopeSelection, focusSection]);
390
- // Scroll logic for settings
391
- const visibleItems = items.slice(scrollOffset, scrollOffset + effectiveMaxItemsToShow);
392
- // Show arrows if there are more items than can be displayed
393
- const showScrollUp = items.length > effectiveMaxItemsToShow;
394
- const showScrollDown = items.length > effectiveMaxItemsToShow;
395
- const saveRestartRequiredSettings = () => {
349
+ // Remove from modified sets
350
+ setModifiedSettings((prev) => {
351
+ const updated = new Set(prev);
352
+ updated.delete(key);
353
+ return updated;
354
+ });
355
+ setRestartRequiredSettings((prev) => {
356
+ const updated = new Set(prev);
357
+ updated.delete(key);
358
+ return updated;
359
+ });
360
+ setGlobalPendingChanges((prev) => {
361
+ if (!prev.has(key))
362
+ return prev;
363
+ const next = new Map(prev);
364
+ next.delete(key);
365
+ return next;
366
+ });
367
+ // Update restart prompt
368
+ setShowRestartPrompt((_prev) => {
369
+ const remaining = getRestartRequiredFromModified(modifiedSettings);
370
+ return remaining.filter((k) => k !== key).length > 0;
371
+ });
372
+ }, [
373
+ config,
374
+ settings,
375
+ selectedScope,
376
+ vimEnabled,
377
+ toggleVimEnabled,
378
+ modifiedSettings,
379
+ ]);
380
+ const saveRestartRequiredSettings = useCallback(() => {
396
381
  const restartRequiredSettings = getRestartRequiredFromModified(modifiedSettings);
397
382
  const restartRequiredSet = new Set(restartRequiredSettings);
398
383
  if (restartRequiredSet.size > 0) {
@@ -408,317 +393,82 @@ export function SettingsDialog({ settings, onSelect, onRestartRequest, available
408
393
  return next;
409
394
  });
410
395
  }
411
- };
412
- useKeypress((key) => {
413
- const { name } = key;
414
- if (name === 'tab' && showScopeSelection) {
415
- setFocusSection((prev) => (prev === 'settings' ? 'scope' : 'settings'));
416
- }
417
- if (focusSection === 'settings') {
418
- // If editing, capture input and control keys
419
- if (editingKey) {
420
- const definition = getSettingDefinition(editingKey);
421
- const type = definition?.type;
422
- if (key.name === 'paste' && key.sequence) {
423
- let pasted = key.sequence;
424
- if (type === 'number') {
425
- pasted = key.sequence.replace(/[^0-9\-+.]/g, '');
426
- }
427
- if (pasted) {
428
- setEditBuffer((b) => {
429
- const before = cpSlice(b, 0, editCursorPos);
430
- const after = cpSlice(b, editCursorPos);
431
- return before + pasted + after;
432
- });
433
- setEditCursorPos((pos) => pos + cpLen(pasted));
434
- }
435
- return;
436
- }
437
- if (name === 'backspace' || name === 'delete') {
438
- if (name === 'backspace' && editCursorPos > 0) {
439
- setEditBuffer((b) => {
440
- const before = cpSlice(b, 0, editCursorPos - 1);
441
- const after = cpSlice(b, editCursorPos);
442
- return before + after;
443
- });
444
- setEditCursorPos((pos) => pos - 1);
445
- }
446
- else if (name === 'delete' && editCursorPos < cpLen(editBuffer)) {
447
- setEditBuffer((b) => {
448
- const before = cpSlice(b, 0, editCursorPos);
449
- const after = cpSlice(b, editCursorPos + 1);
450
- return before + after;
451
- });
452
- // Cursor position stays the same for delete
453
- }
454
- return;
455
- }
456
- if (keyMatchers[Command.ESCAPE](key)) {
457
- commitEdit(editingKey);
458
- return;
459
- }
460
- if (keyMatchers[Command.RETURN](key)) {
461
- commitEdit(editingKey);
462
- return;
463
- }
464
- let ch = key.sequence;
465
- let isValidChar = false;
466
- if (type === 'number') {
467
- // Allow digits, minus, plus, and dot.
468
- isValidChar = /[0-9\-+.]/.test(ch);
469
- }
470
- else {
471
- ch = stripUnsafeCharacters(ch);
472
- // For strings, allow any single character that isn't a control
473
- // sequence.
474
- isValidChar = ch.length === 1;
475
- }
476
- if (isValidChar) {
477
- setEditBuffer((currentBuffer) => {
478
- const beforeCursor = cpSlice(currentBuffer, 0, editCursorPos);
479
- const afterCursor = cpSlice(currentBuffer, editCursorPos);
480
- return beforeCursor + ch + afterCursor;
481
- });
482
- setEditCursorPos((pos) => pos + 1);
483
- return;
484
- }
485
- // Arrow key navigation
486
- if (name === 'left') {
487
- setEditCursorPos((pos) => Math.max(0, pos - 1));
488
- return;
489
- }
490
- if (name === 'right') {
491
- setEditCursorPos((pos) => Math.min(cpLen(editBuffer), pos + 1));
492
- return;
493
- }
494
- // Home and End keys
495
- if (keyMatchers[Command.HOME](key)) {
496
- setEditCursorPos(0);
497
- return;
498
- }
499
- if (keyMatchers[Command.END](key)) {
500
- setEditCursorPos(cpLen(editBuffer));
501
- return;
502
- }
503
- // Block other keys while editing
504
- return;
505
- }
506
- if (keyMatchers[Command.DIALOG_NAVIGATION_UP](key)) {
507
- // If editing, commit first
508
- if (editingKey) {
509
- commitEdit(editingKey);
510
- }
511
- const newIndex = activeSettingIndex > 0 ? activeSettingIndex - 1 : items.length - 1;
512
- setActiveSettingIndex(newIndex);
513
- // Adjust scroll offset for wrap-around
514
- if (newIndex === items.length - 1) {
515
- setScrollOffset(Math.max(0, items.length - effectiveMaxItemsToShow));
516
- }
517
- else if (newIndex < scrollOffset) {
518
- setScrollOffset(newIndex);
519
- }
520
- }
521
- else if (keyMatchers[Command.DIALOG_NAVIGATION_DOWN](key)) {
522
- // If editing, commit first
523
- if (editingKey) {
524
- commitEdit(editingKey);
525
- }
526
- const newIndex = activeSettingIndex < items.length - 1 ? activeSettingIndex + 1 : 0;
527
- setActiveSettingIndex(newIndex);
528
- // Adjust scroll offset for wrap-around
529
- if (newIndex === 0) {
530
- setScrollOffset(0);
531
- }
532
- else if (newIndex >= scrollOffset + effectiveMaxItemsToShow) {
533
- setScrollOffset(newIndex - effectiveMaxItemsToShow + 1);
534
- }
535
- }
536
- else if (keyMatchers[Command.RETURN](key)) {
537
- const currentItem = items[activeSettingIndex];
538
- if (currentItem?.type === 'number' ||
539
- currentItem?.type === 'string') {
540
- startEditing(currentItem.value);
541
- }
542
- else {
543
- currentItem?.toggle();
544
- }
545
- }
546
- else if (/^[0-9]$/.test(key.sequence || '') && !editingKey) {
547
- const currentItem = items[activeSettingIndex];
548
- if (currentItem?.type === 'number') {
549
- startEditing(currentItem.value, key.sequence);
550
- }
551
- }
552
- else if (keyMatchers[Command.CLEAR_INPUT](key) ||
553
- keyMatchers[Command.CLEAR_SCREEN](key)) {
554
- // Ctrl+C or Ctrl+L: Clear current setting and reset to default
555
- const currentSetting = items[activeSettingIndex];
556
- if (currentSetting) {
557
- const defaultValue = getEffectiveDefaultValue(currentSetting.value, config);
558
- const defType = currentSetting.type;
559
- if (defType === 'boolean') {
560
- const booleanDefaultValue = typeof defaultValue === 'boolean' ? defaultValue : false;
561
- setPendingSettings((prev) => setPendingSettingValue(currentSetting.value, booleanDefaultValue, prev));
562
- }
563
- else if (defType === 'number' || defType === 'string') {
564
- if (typeof defaultValue === 'number' ||
565
- typeof defaultValue === 'string') {
566
- setPendingSettings((prev) => setPendingSettingValueAny(currentSetting.value, defaultValue, prev));
567
- }
568
- }
569
- // Remove from modified settings since it's now at default
570
- setModifiedSettings((prev) => {
571
- const updated = new Set(prev);
572
- updated.delete(currentSetting.value);
573
- return updated;
574
- });
575
- // Remove from restart-required settings if it was there
576
- setRestartRequiredSettings((prev) => {
577
- const updated = new Set(prev);
578
- updated.delete(currentSetting.value);
579
- return updated;
580
- });
581
- // If this setting doesn't require restart, save it immediately
582
- if (!requiresRestart(currentSetting.value)) {
583
- const immediateSettings = new Set([currentSetting.value]);
584
- const toSaveValue = currentSetting.type === 'boolean'
585
- ? typeof defaultValue === 'boolean'
586
- ? defaultValue
587
- : false
588
- : typeof defaultValue === 'number' ||
589
- typeof defaultValue === 'string'
590
- ? defaultValue
591
- : undefined;
592
- const currentScopeSettings = settings.forScope(selectedScope).settings;
593
- const immediateSettingsObject = toSaveValue !== undefined
594
- ? setPendingSettingValueAny(currentSetting.value, toSaveValue, currentScopeSettings)
595
- : currentScopeSettings;
596
- saveModifiedSettings(immediateSettings, immediateSettingsObject, settings, selectedScope);
597
- // Remove from global pending changes if present
598
- setGlobalPendingChanges((prev) => {
599
- if (!prev.has(currentSetting.value))
600
- return prev;
601
- const next = new Map(prev);
602
- next.delete(currentSetting.value);
603
- return next;
604
- });
605
- }
606
- else {
607
- // Track default reset as a pending change if restart required
608
- if ((currentSetting.type === 'boolean' &&
609
- typeof defaultValue === 'boolean') ||
610
- (currentSetting.type === 'number' &&
611
- typeof defaultValue === 'number') ||
612
- (currentSetting.type === 'string' &&
613
- typeof defaultValue === 'string')) {
614
- setGlobalPendingChanges((prev) => {
615
- const next = new Map(prev);
616
- next.set(currentSetting.value, defaultValue);
617
- return next;
618
- });
619
- }
620
- }
621
- }
622
- }
623
- }
624
- if (showRestartPrompt && name === 'r') {
625
- // Only save settings that require restart (non-restart settings were already saved immediately)
626
- saveRestartRequiredSettings();
396
+ }, [modifiedSettings, pendingSettings, settings, selectedScope]);
397
+ // Close handler
398
+ const handleClose = useCallback(() => {
399
+ // Save any restart-required settings before closing
400
+ saveRestartRequiredSettings();
401
+ onSelect(undefined, selectedScope);
402
+ }, [saveRestartRequiredSettings, onSelect, selectedScope]);
403
+ // Custom key handler for restart key
404
+ const handleKeyPress = useCallback((key, _currentItem) => {
405
+ // 'r' key for restart
406
+ if (showRestartPrompt && key.sequence === 'r') {
627
407
  setShowRestartPrompt(false);
628
- setRestartRequiredSettings(new Set()); // Clear restart-required settings
408
+ setModifiedSettings(new Set());
409
+ setRestartRequiredSettings(new Set());
629
410
  if (onRestartRequest)
630
411
  onRestartRequest();
412
+ return true;
631
413
  }
632
- if (keyMatchers[Command.ESCAPE](key)) {
633
- if (editingKey) {
634
- commitEdit(editingKey);
635
- }
636
- else {
637
- // Save any restart-required settings before closing
638
- saveRestartRequiredSettings();
639
- onSelect(undefined, selectedScope);
414
+ return false;
415
+ }, [showRestartPrompt, onRestartRequest]);
416
+ // Calculate effective max items and scope visibility based on terminal height
417
+ const { effectiveMaxItemsToShow, showScopeSelection } = useMemo(() => {
418
+ // Only show scope selector if we have a workspace
419
+ const hasWorkspace = settings.workspace.path !== undefined;
420
+ if (!availableTerminalHeight) {
421
+ return {
422
+ effectiveMaxItemsToShow: Math.min(MAX_ITEMS_TO_SHOW, items.length),
423
+ showScopeSelection: hasWorkspace,
424
+ };
425
+ }
426
+ // Layout constants
427
+ const DIALOG_PADDING = 2; // Top and bottom borders
428
+ const SETTINGS_TITLE_HEIGHT = 1;
429
+ const SEARCH_BOX_HEIGHT = 3;
430
+ const SCROLL_ARROWS_HEIGHT = 2;
431
+ const SPACING_HEIGHT = 2;
432
+ const SCOPE_SELECTION_HEIGHT = 4;
433
+ const BOTTOM_HELP_TEXT_HEIGHT = 1;
434
+ const RESTART_PROMPT_HEIGHT = showRestartPrompt ? 1 : 0;
435
+ const ITEM_HEIGHT = 3; // Label + description + spacing
436
+ const currentAvailableHeight = availableTerminalHeight - DIALOG_PADDING;
437
+ const baseFixedHeight = SETTINGS_TITLE_HEIGHT +
438
+ SEARCH_BOX_HEIGHT +
439
+ SCROLL_ARROWS_HEIGHT +
440
+ SPACING_HEIGHT +
441
+ BOTTOM_HELP_TEXT_HEIGHT +
442
+ RESTART_PROMPT_HEIGHT;
443
+ // Calculate max items with scope selector
444
+ const heightWithScope = baseFixedHeight + SCOPE_SELECTION_HEIGHT;
445
+ const availableForItemsWithScope = currentAvailableHeight - heightWithScope;
446
+ const maxItemsWithScope = Math.max(1, Math.floor(availableForItemsWithScope / ITEM_HEIGHT));
447
+ // Calculate max items without scope selector
448
+ const availableForItemsWithoutScope = currentAvailableHeight - baseFixedHeight;
449
+ const maxItemsWithoutScope = Math.max(1, Math.floor(availableForItemsWithoutScope / ITEM_HEIGHT));
450
+ // In small terminals, hide scope selector if it would allow more items to show
451
+ let shouldShowScope = hasWorkspace;
452
+ let maxItems = maxItemsWithScope;
453
+ if (hasWorkspace && availableTerminalHeight < 25) {
454
+ // Hide scope selector if it gains us more than 1 extra item
455
+ if (maxItemsWithoutScope > maxItemsWithScope + 1) {
456
+ shouldShowScope = false;
457
+ maxItems = maxItemsWithoutScope;
640
458
  }
641
459
  }
642
- }, { isActive: true });
643
- const { mainAreaWidth } = useUIState();
644
- const viewportWidth = mainAreaWidth - 8;
645
- const buffer = useTextBuffer({
646
- initialText: '',
647
- initialCursorOffset: 0,
648
- viewport: {
649
- width: viewportWidth,
650
- height: 1,
651
- },
652
- isValidPath: () => false,
653
- singleLine: true,
654
- onChange: (text) => setSearchQuery(text),
655
- });
656
- return (_jsx(Box, { borderStyle: "round", borderColor: theme.border.default, flexDirection: "row", padding: 1, width: "100%", height: "100%", children: _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Box, { marginX: 1, children: _jsxs(Text, { bold: focusSection === 'settings' && !editingKey, wrap: "truncate", children: [focusSection === 'settings' ? '> ' : ' ', "Settings", ' '] }) }), _jsx(Box, { borderStyle: "round", borderColor: editingKey
657
- ? theme.border.default
658
- : focusSection === 'settings'
659
- ? theme.border.focused
660
- : theme.border.default, paddingX: 1, height: 3, marginTop: 1, children: _jsx(TextInput, { focus: focusSection === 'settings' && !editingKey, buffer: buffer, placeholder: "Search to filter" }) }), _jsx(Box, { height: 1 }), visibleItems.length === 0 ? (_jsx(Box, { marginX: 1, height: 1, flexDirection: "column", children: _jsx(Text, { color: theme.text.secondary, children: "No matches found." }) })) : (_jsxs(_Fragment, { children: [showScrollUp && (_jsx(Box, { marginX: 1, children: _jsx(Text, { color: theme.text.secondary, children: "\u25B2" }) })), visibleItems.map((item, idx) => {
661
- const isActive = focusSection === 'settings' &&
662
- activeSettingIndex === idx + scrollOffset;
663
- const scopeSettings = settings.forScope(selectedScope).settings;
664
- const mergedSettings = settings.merged;
665
- let displayValue;
666
- if (editingKey === item.value) {
667
- // Show edit buffer with advanced cursor highlighting
668
- if (cursorVisible && editCursorPos < cpLen(editBuffer)) {
669
- // Cursor is in the middle or at start of text
670
- const beforeCursor = cpSlice(editBuffer, 0, editCursorPos);
671
- const atCursor = cpSlice(editBuffer, editCursorPos, editCursorPos + 1);
672
- const afterCursor = cpSlice(editBuffer, editCursorPos + 1);
673
- displayValue =
674
- beforeCursor + chalk.inverse(atCursor) + afterCursor;
675
- }
676
- else if (cursorVisible &&
677
- editCursorPos >= cpLen(editBuffer)) {
678
- // Cursor is at the end - show inverted space
679
- displayValue = editBuffer + chalk.inverse(' ');
680
- }
681
- else {
682
- // Cursor not visible
683
- displayValue = editBuffer;
684
- }
685
- }
686
- else if (item.type === 'number' || item.type === 'string') {
687
- // For numbers/strings, get the actual current value from pending settings
688
- const path = item.value.split('.');
689
- const currentValue = getNestedValue(pendingSettings, path);
690
- const defaultValue = getEffectiveDefaultValue(item.value, config);
691
- if (currentValue !== undefined && currentValue !== null) {
692
- displayValue = String(currentValue);
693
- }
694
- else {
695
- displayValue =
696
- defaultValue !== undefined && defaultValue !== null
697
- ? String(defaultValue)
698
- : '';
699
- }
700
- // Add * if value differs from default OR if currently being modified
701
- const isModified = modifiedSettings.has(item.value);
702
- const effectiveCurrentValue = currentValue !== undefined && currentValue !== null
703
- ? currentValue
704
- : defaultValue;
705
- const isDifferentFromDefault = effectiveCurrentValue !== defaultValue;
706
- if (isDifferentFromDefault || isModified) {
707
- displayValue += '*';
708
- }
709
- }
710
- else {
711
- // For booleans and other types, use existing logic
712
- displayValue = getDisplayValue(item.value, scopeSettings, mergedSettings, modifiedSettings, pendingSettings);
713
- }
714
- const shouldBeGreyedOut = isDefaultValue(item.value, scopeSettings);
715
- // Generate scope message for this setting
716
- const scopeMessage = getScopeMessageForSetting(item.value, selectedScope, settings);
717
- return (_jsxs(React.Fragment, { children: [_jsxs(Box, { marginX: 1, flexDirection: "row", alignItems: "flex-start", children: [_jsx(Box, { minWidth: 2, flexShrink: 0, children: _jsx(Text, { color: isActive ? theme.status.success : theme.text.secondary, children: isActive ? '●' : '' }) }), _jsxs(Box, { flexDirection: "row", flexGrow: 1, minWidth: 0, alignItems: "flex-start", children: [_jsxs(Box, { flexDirection: "column", width: maxLabelOrDescriptionWidth, minWidth: 0, children: [_jsxs(Text, { color: isActive ? theme.status.success : theme.text.primary, children: [item.label, scopeMessage && (_jsxs(Text, { color: theme.text.secondary, children: [' ', scopeMessage] }))] }), _jsx(Text, { color: theme.text.secondary, wrap: "truncate", children: item.description ?? '' })] }), _jsx(Box, { minWidth: 3 }), _jsx(Box, { flexShrink: 0, children: _jsx(Text, { color: isActive
718
- ? theme.status.success
719
- : shouldBeGreyedOut
720
- ? theme.text.secondary
721
- : theme.text.primary, children: displayValue }) })] })] }), _jsx(Box, { height: 1 })] }, item.value));
722
- }), showScrollDown && (_jsx(Box, { marginX: 1, children: _jsx(Text, { color: theme.text.secondary, children: "\u25BC" }) }))] })), _jsx(Box, { height: 1 }), showScopeSelection && (_jsxs(Box, { marginX: 1, flexDirection: "column", children: [_jsxs(Text, { bold: focusSection === 'scope', wrap: "truncate", children: [focusSection === 'scope' ? '> ' : ' ', "Apply To"] }), _jsx(RadioButtonSelect, { items: scopeItems, initialIndex: scopeItems.findIndex((item) => item.value === selectedScope), onSelect: handleScopeSelect, onHighlight: handleScopeHighlight, isFocused: focusSection === 'scope', showNumbers: focusSection === 'scope' })] })), _jsx(Box, { height: 1 }), _jsx(Box, { marginX: 1, children: _jsxs(Text, { color: theme.text.secondary, children: ["(Use Enter to select", showScopeSelection ? ', Tab to change focus' : '', ", Esc to close)"] }) }), showRestartPrompt && (_jsx(Box, { marginX: 1, children: _jsx(Text, { color: theme.status.warning, children: "To see changes, Gemini CLI must be restarted. Press r to exit and apply changes now." }) }))] }) }));
460
+ return {
461
+ effectiveMaxItemsToShow: Math.min(maxItems, items.length),
462
+ showScopeSelection: shouldShowScope,
463
+ };
464
+ }, [
465
+ availableTerminalHeight,
466
+ items.length,
467
+ settings.workspace.path,
468
+ showRestartPrompt,
469
+ ]);
470
+ // Footer content for restart prompt
471
+ const footerContent = showRestartPrompt ? (_jsx(Text, { color: theme.status.warning, children: "To see changes, Gemini CLI must be restarted. Press r to exit and apply changes now." })) : null;
472
+ return (_jsx(BaseSettingsDialog, { title: "Settings", searchEnabled: true, searchBuffer: searchBuffer, items: items, showScopeSelector: showScopeSelection, selectedScope: selectedScope, onScopeChange: handleScopeChange, maxItemsToShow: effectiveMaxItemsToShow, maxLabelWidth: maxLabelOrDescriptionWidth, onItemToggle: handleItemToggle, onEditCommit: handleEditCommit, onItemClear: handleItemClear, onClose: handleClose, onKeyPress: handleKeyPress, footerContent: footerContent }));
723
473
  }
724
474
  //# sourceMappingURL=SettingsDialog.js.map