fss-link 1.0.40 → 1.0.45

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 (428) hide show
  1. package/dist/commands/mcp/add.test.ts +122 -0
  2. package/dist/commands/mcp/add.ts +222 -0
  3. package/dist/commands/mcp/list.test.ts +154 -0
  4. package/dist/commands/mcp/list.ts +139 -0
  5. package/dist/commands/mcp/remove.test.ts +69 -0
  6. package/dist/commands/mcp/remove.ts +60 -0
  7. package/dist/commands/mcp.test.ts +55 -0
  8. package/dist/commands/mcp.ts +27 -0
  9. package/dist/config/apiValidation.test.ts +118 -0
  10. package/dist/config/auth.test.ts +79 -0
  11. package/dist/config/auth.ts +100 -0
  12. package/dist/config/config.integration.test.ts +407 -0
  13. package/dist/config/config.test.ts +1952 -0
  14. package/dist/config/config.ts +690 -0
  15. package/dist/config/database.test.ts +96 -0
  16. package/dist/config/database.ts +752 -0
  17. package/dist/config/extension.test.ts +236 -0
  18. package/dist/config/extension.ts +180 -0
  19. package/dist/config/keyBindings.test.ts +62 -0
  20. package/dist/config/keyBindings.ts +184 -0
  21. package/dist/config/modelManager.ts +275 -0
  22. package/dist/config/providerManager.ts +244 -0
  23. package/dist/config/providerPersistence.test.ts +377 -0
  24. package/dist/config/providerPersistence.ts +105 -0
  25. package/dist/config/sandboxConfig.ts +107 -0
  26. package/dist/config/settings.test.ts +1424 -0
  27. package/dist/config/settings.ts +517 -0
  28. package/dist/config/settingsSchema.test.ts +252 -0
  29. package/dist/config/settingsSchema.ts +728 -0
  30. package/dist/config/trustedFolders.test.ts +208 -0
  31. package/dist/config/trustedFolders.ts +167 -0
  32. package/dist/gemini.test.tsx +252 -0
  33. package/dist/gemini.tsx +357 -0
  34. package/dist/generated/git-commit.ts +10 -0
  35. package/dist/index.ts +21 -0
  36. package/dist/nonInteractiveCli.test.ts +276 -0
  37. package/dist/nonInteractiveCli.ts +143 -0
  38. package/dist/package.json +87 -87
  39. package/dist/patches/is-in-ci.ts +17 -0
  40. package/dist/services/BuiltinCommandLoader.test.ts +127 -0
  41. package/dist/services/BuiltinCommandLoader.ts +95 -0
  42. package/dist/services/CommandService.test.ts +352 -0
  43. package/dist/services/CommandService.ts +103 -0
  44. package/dist/services/FileCommandLoader.test.ts +1002 -0
  45. package/dist/services/FileCommandLoader.ts +289 -0
  46. package/dist/services/McpPromptLoader.ts +231 -0
  47. package/dist/services/SearchEngineConfigProvider.ts +100 -0
  48. package/dist/services/prompt-processors/argumentProcessor.test.ts +41 -0
  49. package/dist/services/prompt-processors/argumentProcessor.ts +23 -0
  50. package/dist/services/prompt-processors/shellProcessor.test.ts +709 -0
  51. package/dist/services/prompt-processors/shellProcessor.ts +248 -0
  52. package/dist/services/prompt-processors/types.ts +44 -0
  53. package/dist/services/types.ts +24 -0
  54. package/dist/src/config/apiValidation.test.d.ts +6 -0
  55. package/dist/src/config/apiValidation.test.js +99 -0
  56. package/dist/src/config/apiValidation.test.js.map +1 -0
  57. package/dist/src/config/database.d.ts +32 -0
  58. package/dist/src/config/database.js +281 -2
  59. package/dist/src/config/database.js.map +1 -1
  60. package/dist/src/config/database.test.d.ts +6 -0
  61. package/dist/src/config/database.test.js +80 -0
  62. package/dist/src/config/database.test.js.map +1 -0
  63. package/dist/src/config/providerManager.d.ts +74 -0
  64. package/dist/src/config/providerManager.js +203 -0
  65. package/dist/src/config/providerManager.js.map +1 -0
  66. package/dist/src/config/providerPersistence.d.ts +75 -0
  67. package/dist/src/config/providerPersistence.js +55 -0
  68. package/dist/src/config/providerPersistence.js.map +1 -0
  69. package/dist/src/config/providerPersistence.test.d.ts +6 -0
  70. package/dist/src/config/providerPersistence.test.js +283 -0
  71. package/dist/src/config/providerPersistence.test.js.map +1 -0
  72. package/dist/src/config/settingsSchema.d.ts +9 -0
  73. package/dist/src/config/settingsSchema.js +9 -0
  74. package/dist/src/config/settingsSchema.js.map +1 -1
  75. package/dist/src/generated/git-commit.d.ts +1 -1
  76. package/dist/src/generated/git-commit.js +1 -1
  77. package/dist/src/services/BuiltinCommandLoader.js +2 -0
  78. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  79. package/dist/src/ui/App.js +14 -2
  80. package/dist/src/ui/App.js.map +1 -1
  81. package/dist/src/ui/commands/contextCommand.d.ts +7 -0
  82. package/dist/src/ui/commands/contextCommand.js +115 -0
  83. package/dist/src/ui/commands/contextCommand.js.map +1 -0
  84. package/dist/src/ui/components/ContextUsageDisplay.d.ts +3 -1
  85. package/dist/src/ui/components/ContextUsageDisplay.js +43 -3
  86. package/dist/src/ui/components/ContextUsageDisplay.js.map +1 -1
  87. package/dist/src/ui/components/Footer.d.ts +1 -0
  88. package/dist/src/ui/components/Footer.js +2 -2
  89. package/dist/src/ui/components/Footer.js.map +1 -1
  90. package/dist/src/ui/components/GeminiKeyDialog.d.ts +11 -0
  91. package/dist/src/ui/components/GeminiKeyDialog.js +156 -0
  92. package/dist/src/ui/components/GeminiKeyDialog.js.map +1 -0
  93. package/dist/src/ui/components/OpenAIEndpointDialog.d.ts +19 -0
  94. package/dist/src/ui/components/OpenAIEndpointDialog.js +163 -0
  95. package/dist/src/ui/components/OpenAIEndpointDialog.js.map +1 -0
  96. package/dist/src/ui/components/WelcomeBackDialog.d.ts +36 -0
  97. package/dist/src/ui/components/WelcomeBackDialog.js +109 -0
  98. package/dist/src/ui/components/WelcomeBackDialog.js.map +1 -0
  99. package/dist/src/ui/hooks/useWelcomeBack.d.ts +52 -0
  100. package/dist/src/ui/hooks/useWelcomeBack.js +214 -0
  101. package/dist/src/ui/hooks/useWelcomeBack.js.map +1 -0
  102. package/dist/src/zed-integration/schema.d.ts +1516 -1516
  103. package/dist/test-setup.ts +12 -0
  104. package/dist/test-utils/customMatchers.ts +65 -0
  105. package/dist/test-utils/mockCommandContext.test.ts +62 -0
  106. package/dist/test-utils/mockCommandContext.ts +105 -0
  107. package/dist/test-utils/render.tsx +18 -0
  108. package/dist/tsconfig.tsbuildinfo +1 -1
  109. package/dist/ui/App.test.tsx +2181 -0
  110. package/dist/ui/App.tsx +1344 -0
  111. package/dist/ui/IdeIntegrationNudge.tsx +98 -0
  112. package/dist/ui/__snapshots__/App.test.tsx.snap +124 -0
  113. package/dist/ui/colors.ts +56 -0
  114. package/dist/ui/commands/aboutCommand.test.ts +153 -0
  115. package/dist/ui/commands/aboutCommand.ts +49 -0
  116. package/dist/ui/commands/authCommand.test.ts +36 -0
  117. package/dist/ui/commands/authCommand.ts +17 -0
  118. package/dist/ui/commands/bugCommand.test.ts +114 -0
  119. package/dist/ui/commands/bugCommand.ts +92 -0
  120. package/dist/ui/commands/chatCommand.test.ts +414 -0
  121. package/dist/ui/commands/chatCommand.ts +280 -0
  122. package/dist/ui/commands/clearCommand.test.ts +100 -0
  123. package/dist/ui/commands/clearCommand.ts +29 -0
  124. package/dist/ui/commands/compressCommand.test.ts +129 -0
  125. package/dist/ui/commands/compressCommand.ts +78 -0
  126. package/dist/ui/commands/contextCommand.ts +132 -0
  127. package/dist/ui/commands/copyCommand.test.ts +296 -0
  128. package/dist/ui/commands/copyCommand.ts +67 -0
  129. package/dist/ui/commands/corgiCommand.test.ts +34 -0
  130. package/dist/ui/commands/corgiCommand.ts +16 -0
  131. package/dist/ui/commands/directoryCommand.test.tsx +185 -0
  132. package/dist/ui/commands/directoryCommand.tsx +179 -0
  133. package/dist/ui/commands/docsCommand.test.ts +99 -0
  134. package/dist/ui/commands/docsCommand.ts +42 -0
  135. package/dist/ui/commands/editorCommand.test.ts +30 -0
  136. package/dist/ui/commands/editorCommand.ts +21 -0
  137. package/dist/ui/commands/extensionsCommand.test.ts +67 -0
  138. package/dist/ui/commands/extensionsCommand.ts +46 -0
  139. package/dist/ui/commands/helpCommand.test.ts +52 -0
  140. package/dist/ui/commands/helpCommand.ts +23 -0
  141. package/dist/ui/commands/ideCommand.test.ts +255 -0
  142. package/dist/ui/commands/ideCommand.ts +283 -0
  143. package/dist/ui/commands/initCommand.test.ts +127 -0
  144. package/dist/ui/commands/initCommand.ts +117 -0
  145. package/dist/ui/commands/mcpCommand.test.ts +1057 -0
  146. package/dist/ui/commands/mcpCommand.ts +531 -0
  147. package/dist/ui/commands/memoryCommand.test.ts +344 -0
  148. package/dist/ui/commands/memoryCommand.ts +305 -0
  149. package/dist/ui/commands/privacyCommand.test.ts +38 -0
  150. package/dist/ui/commands/privacyCommand.ts +17 -0
  151. package/dist/ui/commands/quitCommand.test.ts +55 -0
  152. package/dist/ui/commands/quitCommand.ts +36 -0
  153. package/dist/ui/commands/restoreCommand.test.ts +250 -0
  154. package/dist/ui/commands/restoreCommand.ts +157 -0
  155. package/dist/ui/commands/searchEngineSetupCommand.ts +18 -0
  156. package/dist/ui/commands/settingsCommand.test.ts +36 -0
  157. package/dist/ui/commands/settingsCommand.ts +17 -0
  158. package/dist/ui/commands/setupGithubCommand.test.ts +238 -0
  159. package/dist/ui/commands/setupGithubCommand.ts +212 -0
  160. package/dist/ui/commands/speakCommand.ts +175 -0
  161. package/dist/ui/commands/statsCommand.test.ts +78 -0
  162. package/dist/ui/commands/statsCommand.ts +70 -0
  163. package/dist/ui/commands/terminalSetupCommand.test.ts +85 -0
  164. package/dist/ui/commands/terminalSetupCommand.ts +45 -0
  165. package/dist/ui/commands/themeCommand.test.ts +38 -0
  166. package/dist/ui/commands/themeCommand.ts +17 -0
  167. package/dist/ui/commands/toolsCommand.test.ts +105 -0
  168. package/dist/ui/commands/toolsCommand.ts +71 -0
  169. package/dist/ui/commands/ttsCommand.ts +143 -0
  170. package/dist/ui/commands/types.ts +204 -0
  171. package/dist/ui/commands/vimCommand.ts +25 -0
  172. package/dist/ui/commands/voiceCommand.ts +125 -0
  173. package/dist/ui/components/AboutBox.tsx +133 -0
  174. package/dist/ui/components/AsciiArt.ts +54 -0
  175. package/dist/ui/components/AuthDialog.test.tsx +334 -0
  176. package/dist/ui/components/AuthDialog.tsx +289 -0
  177. package/dist/ui/components/AuthInProgress.tsx +62 -0
  178. package/dist/ui/components/AutoAcceptIndicator.tsx +47 -0
  179. package/dist/ui/components/ConsoleSummaryDisplay.tsx +35 -0
  180. package/dist/ui/components/ContextSummaryDisplay.test.tsx +85 -0
  181. package/dist/ui/components/ContextSummaryDisplay.tsx +120 -0
  182. package/dist/ui/components/ContextUsageDisplay.tsx +77 -0
  183. package/dist/ui/components/DebugProfiler.tsx +36 -0
  184. package/dist/ui/components/DetailedMessagesDisplay.tsx +82 -0
  185. package/dist/ui/components/EditorSettingsDialog.tsx +172 -0
  186. package/dist/ui/components/FolderTrustDialog.test.tsx +36 -0
  187. package/dist/ui/components/FolderTrustDialog.tsx +74 -0
  188. package/dist/ui/components/Footer.test.tsx +159 -0
  189. package/dist/ui/components/Footer.tsx +158 -0
  190. package/dist/ui/components/GeminiKeyDialog.tsx +252 -0
  191. package/dist/ui/components/GeminiRespondingSpinner.tsx +34 -0
  192. package/dist/ui/components/Header.test.tsx +44 -0
  193. package/dist/ui/components/Header.tsx +70 -0
  194. package/dist/ui/components/Help.tsx +174 -0
  195. package/dist/ui/components/HistoryItemDisplay.test.tsx +125 -0
  196. package/dist/ui/components/HistoryItemDisplay.tsx +98 -0
  197. package/dist/ui/components/InputPrompt.test.tsx +1467 -0
  198. package/dist/ui/components/InputPrompt.tsx +641 -0
  199. package/dist/ui/components/LMStudioModelPrompt.tsx +215 -0
  200. package/dist/ui/components/LoadingIndicator.test.tsx +296 -0
  201. package/dist/ui/components/LoadingIndicator.tsx +82 -0
  202. package/dist/ui/components/MemoryUsageDisplay.tsx +36 -0
  203. package/dist/ui/components/ModelStatsDisplay.test.tsx +252 -0
  204. package/dist/ui/components/ModelStatsDisplay.tsx +197 -0
  205. package/dist/ui/components/OllamaModelPrompt.tsx +206 -0
  206. package/dist/ui/components/OpenAIEndpointDialog.tsx +261 -0
  207. package/dist/ui/components/OpenAIKeyPrompt.test.tsx +64 -0
  208. package/dist/ui/components/OpenAIKeyPrompt.tsx +197 -0
  209. package/dist/ui/components/PrepareLabel.tsx +48 -0
  210. package/dist/ui/components/SearchEngineConfigDialog.tsx +280 -0
  211. package/dist/ui/components/SessionSummaryDisplay.test.tsx +75 -0
  212. package/dist/ui/components/SessionSummaryDisplay.tsx +18 -0
  213. package/dist/ui/components/SettingsDialog.test.tsx +865 -0
  214. package/dist/ui/components/SettingsDialog.tsx +753 -0
  215. package/dist/ui/components/ShellConfirmationDialog.test.tsx +53 -0
  216. package/dist/ui/components/ShellConfirmationDialog.tsx +103 -0
  217. package/dist/ui/components/ShellModeIndicator.tsx +18 -0
  218. package/dist/ui/components/ShowMoreLines.tsx +40 -0
  219. package/dist/ui/components/StatsDisplay.test.tsx +401 -0
  220. package/dist/ui/components/StatsDisplay.tsx +273 -0
  221. package/dist/ui/components/SuggestionsDisplay.tsx +102 -0
  222. package/dist/ui/components/ThemeDialog.tsx +310 -0
  223. package/dist/ui/components/Tips.tsx +45 -0
  224. package/dist/ui/components/TodoDisplay.test.tsx +97 -0
  225. package/dist/ui/components/TodoDisplay.tsx +72 -0
  226. package/dist/ui/components/ToolStatsDisplay.test.tsx +180 -0
  227. package/dist/ui/components/ToolStatsDisplay.tsx +208 -0
  228. package/dist/ui/components/UpdateNotification.tsx +23 -0
  229. package/dist/ui/components/WelcomeBackDialog.tsx +290 -0
  230. package/dist/ui/components/__snapshots__/IDEContextDetailDisplay.test.tsx.snap +24 -0
  231. package/dist/ui/components/__snapshots__/ModelStatsDisplay.test.tsx.snap +121 -0
  232. package/dist/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap +30 -0
  233. package/dist/ui/components/__snapshots__/ShellConfirmationDialog.test.tsx.snap +21 -0
  234. package/dist/ui/components/__snapshots__/StatsDisplay.test.tsx.snap +264 -0
  235. package/dist/ui/components/__snapshots__/ToolStatsDisplay.test.tsx.snap +91 -0
  236. package/dist/ui/components/messages/CompressionMessage.tsx +49 -0
  237. package/dist/ui/components/messages/DiffRenderer.test.tsx +365 -0
  238. package/dist/ui/components/messages/DiffRenderer.tsx +358 -0
  239. package/dist/ui/components/messages/ErrorMessage.tsx +31 -0
  240. package/dist/ui/components/messages/GeminiMessage.tsx +43 -0
  241. package/dist/ui/components/messages/GeminiMessageContent.tsx +43 -0
  242. package/dist/ui/components/messages/InfoMessage.tsx +32 -0
  243. package/dist/ui/components/messages/ToolConfirmationMessage.test.tsx +58 -0
  244. package/dist/ui/components/messages/ToolConfirmationMessage.tsx +297 -0
  245. package/dist/ui/components/messages/ToolGroupMessage.tsx +126 -0
  246. package/dist/ui/components/messages/ToolMessage.test.tsx +183 -0
  247. package/dist/ui/components/messages/ToolMessage.tsx +296 -0
  248. package/dist/ui/components/messages/UserMessage.tsx +43 -0
  249. package/dist/ui/components/messages/UserShellMessage.tsx +25 -0
  250. package/dist/ui/components/shared/MaxSizedBox.test.tsx +425 -0
  251. package/dist/ui/components/shared/MaxSizedBox.tsx +624 -0
  252. package/dist/ui/components/shared/RadioButtonSelect.test.tsx +181 -0
  253. package/dist/ui/components/shared/RadioButtonSelect.tsx +234 -0
  254. package/dist/ui/components/shared/__snapshots__/RadioButtonSelect.test.tsx.snap +47 -0
  255. package/dist/ui/components/shared/text-buffer.test.ts +1728 -0
  256. package/dist/ui/components/shared/text-buffer.ts +2227 -0
  257. package/dist/ui/components/shared/vim-buffer-actions.test.ts +1119 -0
  258. package/dist/ui/components/shared/vim-buffer-actions.ts +814 -0
  259. package/dist/ui/constants.ts +17 -0
  260. package/dist/ui/contexts/KeypressContext.test.tsx +391 -0
  261. package/dist/ui/contexts/KeypressContext.tsx +440 -0
  262. package/dist/ui/contexts/OverflowContext.tsx +87 -0
  263. package/dist/ui/contexts/SessionContext.test.tsx +132 -0
  264. package/dist/ui/contexts/SessionContext.tsx +143 -0
  265. package/dist/ui/contexts/SettingsContext.tsx +20 -0
  266. package/dist/ui/contexts/StreamingContext.tsx +22 -0
  267. package/dist/ui/contexts/VimModeContext.tsx +79 -0
  268. package/dist/ui/editors/editorSettingsManager.ts +66 -0
  269. package/dist/ui/hooks/atCommandProcessor.test.ts +1102 -0
  270. package/dist/ui/hooks/atCommandProcessor.ts +485 -0
  271. package/dist/ui/hooks/shellCommandProcessor.test.ts +481 -0
  272. package/dist/ui/hooks/shellCommandProcessor.ts +314 -0
  273. package/dist/ui/hooks/slashCommandProcessor.test.ts +1044 -0
  274. package/dist/ui/hooks/slashCommandProcessor.ts +595 -0
  275. package/dist/ui/hooks/useAtCompletion.test.ts +497 -0
  276. package/dist/ui/hooks/useAtCompletion.ts +244 -0
  277. package/dist/ui/hooks/useAuthCommand.ts +129 -0
  278. package/dist/ui/hooks/useAutoAcceptIndicator.test.ts +300 -0
  279. package/dist/ui/hooks/useAutoAcceptIndicator.ts +52 -0
  280. package/dist/ui/hooks/useBracketedPaste.ts +37 -0
  281. package/dist/ui/hooks/useCommandCompletion.test.ts +518 -0
  282. package/dist/ui/hooks/useCommandCompletion.tsx +238 -0
  283. package/dist/ui/hooks/useCompletion.ts +128 -0
  284. package/dist/ui/hooks/useConsoleMessages.test.ts +147 -0
  285. package/dist/ui/hooks/useConsoleMessages.ts +110 -0
  286. package/dist/ui/hooks/useEditorSettings.test.ts +283 -0
  287. package/dist/ui/hooks/useEditorSettings.ts +75 -0
  288. package/dist/ui/hooks/useFocus.test.ts +119 -0
  289. package/dist/ui/hooks/useFocus.ts +48 -0
  290. package/dist/ui/hooks/useFolderTrust.test.ts +159 -0
  291. package/dist/ui/hooks/useFolderTrust.ts +72 -0
  292. package/dist/ui/hooks/useGeminiStream.test.tsx +1998 -0
  293. package/dist/ui/hooks/useGeminiStream.ts +1017 -0
  294. package/dist/ui/hooks/useGitBranchName.test.ts +280 -0
  295. package/dist/ui/hooks/useGitBranchName.ts +79 -0
  296. package/dist/ui/hooks/useHistoryManager.test.ts +202 -0
  297. package/dist/ui/hooks/useHistoryManager.ts +111 -0
  298. package/dist/ui/hooks/useInputHistory.test.ts +261 -0
  299. package/dist/ui/hooks/useInputHistory.ts +111 -0
  300. package/dist/ui/hooks/useKeypress.test.ts +280 -0
  301. package/dist/ui/hooks/useKeypress.ts +39 -0
  302. package/dist/ui/hooks/useKittyKeyboardProtocol.ts +31 -0
  303. package/dist/ui/hooks/useLoadingIndicator.test.ts +139 -0
  304. package/dist/ui/hooks/useLoadingIndicator.ts +57 -0
  305. package/dist/ui/hooks/useLogger.ts +32 -0
  306. package/dist/ui/hooks/useMessageQueue.test.ts +226 -0
  307. package/dist/ui/hooks/useMessageQueue.ts +69 -0
  308. package/dist/ui/hooks/usePhraseCycler.test.ts +145 -0
  309. package/dist/ui/hooks/usePhraseCycler.ts +198 -0
  310. package/dist/ui/hooks/usePrivacySettings.test.ts +242 -0
  311. package/dist/ui/hooks/usePrivacySettings.ts +150 -0
  312. package/dist/ui/hooks/useReactToolScheduler.ts +309 -0
  313. package/dist/ui/hooks/useRefreshMemoryCommand.ts +7 -0
  314. package/dist/ui/hooks/useReverseSearchCompletion.test.tsx +260 -0
  315. package/dist/ui/hooks/useReverseSearchCompletion.tsx +95 -0
  316. package/dist/ui/hooks/useSettingsCommand.ts +25 -0
  317. package/dist/ui/hooks/useShellHistory.test.ts +219 -0
  318. package/dist/ui/hooks/useShellHistory.ts +133 -0
  319. package/dist/ui/hooks/useShowMemoryCommand.ts +75 -0
  320. package/dist/ui/hooks/useSlashCompletion.test.ts +434 -0
  321. package/dist/ui/hooks/useSlashCompletion.ts +187 -0
  322. package/dist/ui/hooks/useStateAndRef.ts +36 -0
  323. package/dist/ui/hooks/useTerminalSize.ts +32 -0
  324. package/dist/ui/hooks/useThemeCommand.ts +110 -0
  325. package/dist/ui/hooks/useTimer.test.ts +120 -0
  326. package/dist/ui/hooks/useTimer.ts +65 -0
  327. package/dist/ui/hooks/useToolScheduler.test.ts +1123 -0
  328. package/dist/ui/hooks/useWelcomeBack.ts +253 -0
  329. package/dist/ui/hooks/vim.test.ts +1691 -0
  330. package/dist/ui/hooks/vim.ts +784 -0
  331. package/dist/ui/keyMatchers.test.ts +337 -0
  332. package/dist/ui/keyMatchers.ts +105 -0
  333. package/dist/ui/privacy/CloudFreePrivacyNotice.tsx +117 -0
  334. package/dist/ui/privacy/CloudPaidPrivacyNotice.tsx +59 -0
  335. package/dist/ui/privacy/GeminiPrivacyNotice.tsx +62 -0
  336. package/dist/ui/privacy/PrivacyNotice.tsx +42 -0
  337. package/dist/ui/semantic-colors.ts +26 -0
  338. package/dist/ui/themes/ansi-light.ts +150 -0
  339. package/dist/ui/themes/ansi.ts +159 -0
  340. package/dist/ui/themes/atom-one-dark.ts +147 -0
  341. package/dist/ui/themes/ayu-light.ts +139 -0
  342. package/dist/ui/themes/ayu.ts +113 -0
  343. package/dist/ui/themes/color-utils.test.ts +221 -0
  344. package/dist/ui/themes/color-utils.ts +231 -0
  345. package/dist/ui/themes/default-light.ts +108 -0
  346. package/dist/ui/themes/default.ts +151 -0
  347. package/dist/ui/themes/dracula.ts +124 -0
  348. package/dist/ui/themes/fss-code-dark.ts +156 -0
  349. package/dist/ui/themes/fss-dark.ts +113 -0
  350. package/dist/ui/themes/fss-light.ts +139 -0
  351. package/dist/ui/themes/github-dark.ts +147 -0
  352. package/dist/ui/themes/github-light.ts +149 -0
  353. package/dist/ui/themes/googlecode.ts +146 -0
  354. package/dist/ui/themes/no-color.ts +125 -0
  355. package/dist/ui/themes/qwen-dark.ts +118 -0
  356. package/dist/ui/themes/qwen-light.ts +144 -0
  357. package/dist/ui/themes/semantic-tokens.ts +127 -0
  358. package/dist/ui/themes/shades-of-purple.ts +352 -0
  359. package/dist/ui/themes/theme-manager.test.ts +99 -0
  360. package/dist/ui/themes/theme-manager.ts +257 -0
  361. package/dist/ui/themes/theme.test.ts +97 -0
  362. package/dist/ui/themes/theme.ts +451 -0
  363. package/dist/ui/themes/xcode.ts +154 -0
  364. package/dist/ui/types.ts +255 -0
  365. package/dist/ui/utils/CodeColorizer.tsx +217 -0
  366. package/dist/ui/utils/ConsolePatcher.ts +71 -0
  367. package/dist/ui/utils/InlineMarkdownRenderer.tsx +173 -0
  368. package/dist/ui/utils/MarkdownDisplay.test.tsx +244 -0
  369. package/dist/ui/utils/MarkdownDisplay.tsx +415 -0
  370. package/dist/ui/utils/TableRenderer.tsx +159 -0
  371. package/dist/ui/utils/__snapshots__/MarkdownDisplay.test.tsx.snap +93 -0
  372. package/dist/ui/utils/clipboardUtils.test.ts +76 -0
  373. package/dist/ui/utils/clipboardUtils.ts +149 -0
  374. package/dist/ui/utils/commandUtils.test.ts +384 -0
  375. package/dist/ui/utils/commandUtils.ts +106 -0
  376. package/dist/ui/utils/computeStats.test.ts +292 -0
  377. package/dist/ui/utils/computeStats.ts +86 -0
  378. package/dist/ui/utils/displayUtils.test.ts +58 -0
  379. package/dist/ui/utils/displayUtils.ts +32 -0
  380. package/dist/ui/utils/formatters.test.ts +72 -0
  381. package/dist/ui/utils/formatters.ts +63 -0
  382. package/dist/ui/utils/isNarrowWidth.ts +9 -0
  383. package/dist/ui/utils/kittyProtocolDetector.ts +105 -0
  384. package/dist/ui/utils/markdownUtilities.test.ts +50 -0
  385. package/dist/ui/utils/markdownUtilities.ts +125 -0
  386. package/dist/ui/utils/platformConstants.ts +52 -0
  387. package/dist/ui/utils/terminalSetup.ts +342 -0
  388. package/dist/ui/utils/textUtils.ts +40 -0
  389. package/dist/ui/utils/updateCheck.test.ts +163 -0
  390. package/dist/ui/utils/updateCheck.ts +100 -0
  391. package/dist/utils/checks.ts +28 -0
  392. package/dist/utils/cleanup.test.ts +68 -0
  393. package/dist/utils/cleanup.ts +36 -0
  394. package/dist/utils/dialogScopeUtils.ts +64 -0
  395. package/dist/utils/events.ts +14 -0
  396. package/dist/utils/gitUtils.test.ts +149 -0
  397. package/dist/utils/gitUtils.ts +116 -0
  398. package/dist/utils/handleAutoUpdate.test.ts +272 -0
  399. package/dist/utils/handleAutoUpdate.ts +145 -0
  400. package/dist/utils/installationInfo.test.ts +315 -0
  401. package/dist/utils/installationInfo.ts +176 -0
  402. package/dist/utils/package.ts +38 -0
  403. package/dist/utils/readStdin.ts +51 -0
  404. package/dist/utils/resolvePath.ts +21 -0
  405. package/dist/utils/sandbox-macos-permissive-closed.sb +32 -0
  406. package/dist/utils/sandbox-macos-permissive-open.sb +25 -0
  407. package/dist/utils/sandbox-macos-permissive-proxied.sb +37 -0
  408. package/dist/utils/sandbox-macos-restrictive-closed.sb +93 -0
  409. package/dist/utils/sandbox-macos-restrictive-open.sb +96 -0
  410. package/dist/utils/sandbox-macos-restrictive-proxied.sb +98 -0
  411. package/dist/utils/sandbox.ts +962 -0
  412. package/dist/utils/settingsUtils.test.ts +797 -0
  413. package/dist/utils/settingsUtils.ts +489 -0
  414. package/dist/utils/spawnWrapper.ts +9 -0
  415. package/dist/utils/startupWarnings.test.ts +83 -0
  416. package/dist/utils/startupWarnings.ts +40 -0
  417. package/dist/utils/updateEventEmitter.ts +13 -0
  418. package/dist/utils/userStartupWarnings.test.ts +87 -0
  419. package/dist/utils/userStartupWarnings.ts +69 -0
  420. package/dist/utils/version.ts +12 -0
  421. package/dist/validateNonInterActiveAuth.test.ts +260 -0
  422. package/dist/validateNonInterActiveAuth.ts +51 -0
  423. package/dist/vitest.config.ts +37 -0
  424. package/dist/zed-integration/acp.ts +366 -0
  425. package/dist/zed-integration/fileSystemService.ts +47 -0
  426. package/dist/zed-integration/schema.ts +466 -0
  427. package/dist/zed-integration/zedIntegration.ts +944 -0
  428. package/package.json +2 -2
@@ -0,0 +1,797 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { describe, it, expect } from 'vitest';
8
+ import {
9
+ // Schema utilities
10
+ getSettingsByCategory,
11
+ getSettingDefinition,
12
+ requiresRestart,
13
+ getDefaultValue,
14
+ getRestartRequiredSettings,
15
+ getEffectiveValue,
16
+ getAllSettingKeys,
17
+ getSettingsByType,
18
+ getSettingsRequiringRestart,
19
+ isValidSettingKey,
20
+ getSettingCategory,
21
+ shouldShowInDialog,
22
+ getDialogSettingsByCategory,
23
+ getDialogSettingsByType,
24
+ getDialogSettingKeys,
25
+ // Business logic utilities
26
+ getSettingValue,
27
+ isSettingModified,
28
+ settingExistsInScope,
29
+ setPendingSettingValue,
30
+ hasRestartRequiredSettings,
31
+ getRestartRequiredFromModified,
32
+ getDisplayValue,
33
+ isDefaultValue,
34
+ isValueInherited,
35
+ getEffectiveDisplayValue,
36
+ } from './settingsUtils.js';
37
+
38
+ describe('SettingsUtils', () => {
39
+ describe('Schema Utilities', () => {
40
+ describe('getSettingsByCategory', () => {
41
+ it('should group settings by category', () => {
42
+ const categories = getSettingsByCategory();
43
+
44
+ expect(categories).toHaveProperty('General');
45
+ expect(categories).toHaveProperty('Accessibility');
46
+ expect(categories).toHaveProperty('Checkpointing');
47
+ expect(categories).toHaveProperty('File Filtering');
48
+ expect(categories).toHaveProperty('UI');
49
+ expect(categories).toHaveProperty('Mode');
50
+ expect(categories).toHaveProperty('Updates');
51
+ });
52
+
53
+ it('should include key property in grouped settings', () => {
54
+ const categories = getSettingsByCategory();
55
+
56
+ Object.entries(categories).forEach(([_category, settings]) => {
57
+ settings.forEach((setting) => {
58
+ expect(setting.key).toBeDefined();
59
+ });
60
+ });
61
+ });
62
+ });
63
+
64
+ describe('getSettingDefinition', () => {
65
+ it('should return definition for valid setting', () => {
66
+ const definition = getSettingDefinition('showMemoryUsage');
67
+ expect(definition).toBeDefined();
68
+ expect(definition?.label).toBe('Show Memory Usage');
69
+ });
70
+
71
+ it('should return undefined for invalid setting', () => {
72
+ const definition = getSettingDefinition('invalidSetting');
73
+ expect(definition).toBeUndefined();
74
+ });
75
+ });
76
+
77
+ describe('requiresRestart', () => {
78
+ it('should return true for settings that require restart', () => {
79
+ expect(requiresRestart('autoConfigureMaxOldSpaceSize')).toBe(true);
80
+ expect(requiresRestart('checkpointing.enabled')).toBe(true);
81
+ });
82
+
83
+ it('should return false for settings that do not require restart', () => {
84
+ expect(requiresRestart('showMemoryUsage')).toBe(false);
85
+ expect(requiresRestart('hideTips')).toBe(false);
86
+ });
87
+
88
+ it('should return false for invalid settings', () => {
89
+ expect(requiresRestart('invalidSetting')).toBe(false);
90
+ });
91
+ });
92
+
93
+ describe('getDefaultValue', () => {
94
+ it('should return correct default values', () => {
95
+ expect(getDefaultValue('showMemoryUsage')).toBe(false);
96
+ expect(getDefaultValue('fileFiltering.enableRecursiveFileSearch')).toBe(
97
+ true,
98
+ );
99
+ });
100
+
101
+ it('should return undefined for invalid settings', () => {
102
+ expect(getDefaultValue('invalidSetting')).toBeUndefined();
103
+ });
104
+ });
105
+
106
+ describe('getRestartRequiredSettings', () => {
107
+ it('should return all settings that require restart', () => {
108
+ const restartSettings = getRestartRequiredSettings();
109
+ expect(restartSettings).toContain('autoConfigureMaxOldSpaceSize');
110
+ expect(restartSettings).toContain('checkpointing.enabled');
111
+ expect(restartSettings).not.toContain('showMemoryUsage');
112
+ });
113
+ });
114
+
115
+ describe('getEffectiveValue', () => {
116
+ it('should return value from settings when set', () => {
117
+ const settings = { showMemoryUsage: true };
118
+ const mergedSettings = { showMemoryUsage: false };
119
+
120
+ const value = getEffectiveValue(
121
+ 'showMemoryUsage',
122
+ settings,
123
+ mergedSettings,
124
+ );
125
+ expect(value).toBe(true);
126
+ });
127
+
128
+ it('should return value from merged settings when not set in current scope', () => {
129
+ const settings = {};
130
+ const mergedSettings = { showMemoryUsage: true };
131
+
132
+ const value = getEffectiveValue(
133
+ 'showMemoryUsage',
134
+ settings,
135
+ mergedSettings,
136
+ );
137
+ expect(value).toBe(true);
138
+ });
139
+
140
+ it('should return default value when not set anywhere', () => {
141
+ const settings = {};
142
+ const mergedSettings = {};
143
+
144
+ const value = getEffectiveValue(
145
+ 'showMemoryUsage',
146
+ settings,
147
+ mergedSettings,
148
+ );
149
+ expect(value).toBe(false); // default value
150
+ });
151
+
152
+ it('should handle nested settings correctly', () => {
153
+ const settings = {
154
+ accessibility: { disableLoadingPhrases: true },
155
+ };
156
+ const mergedSettings = {
157
+ accessibility: { disableLoadingPhrases: false },
158
+ };
159
+
160
+ const value = getEffectiveValue(
161
+ 'accessibility.disableLoadingPhrases',
162
+ settings,
163
+ mergedSettings,
164
+ );
165
+ expect(value).toBe(true);
166
+ });
167
+
168
+ it('should return undefined for invalid settings', () => {
169
+ const settings = {};
170
+ const mergedSettings = {};
171
+
172
+ const value = getEffectiveValue(
173
+ 'invalidSetting',
174
+ settings,
175
+ mergedSettings,
176
+ );
177
+ expect(value).toBeUndefined();
178
+ });
179
+ });
180
+
181
+ describe('getAllSettingKeys', () => {
182
+ it('should return all setting keys', () => {
183
+ const keys = getAllSettingKeys();
184
+ expect(keys).toContain('showMemoryUsage');
185
+ expect(keys).toContain('accessibility.disableLoadingPhrases');
186
+ expect(keys).toContain('checkpointing.enabled');
187
+ });
188
+ });
189
+
190
+ describe('getSettingsByType', () => {
191
+ it('should return only boolean settings', () => {
192
+ const booleanSettings = getSettingsByType('boolean');
193
+ expect(booleanSettings.length).toBeGreaterThan(0);
194
+ booleanSettings.forEach((setting) => {
195
+ expect(setting.type).toBe('boolean');
196
+ });
197
+ });
198
+ });
199
+
200
+ describe('getSettingsRequiringRestart', () => {
201
+ it('should return only settings that require restart', () => {
202
+ const restartSettings = getSettingsRequiringRestart();
203
+ expect(restartSettings.length).toBeGreaterThan(0);
204
+ restartSettings.forEach((setting) => {
205
+ expect(setting.requiresRestart).toBe(true);
206
+ });
207
+ });
208
+ });
209
+
210
+ describe('isValidSettingKey', () => {
211
+ it('should return true for valid setting keys', () => {
212
+ expect(isValidSettingKey('showMemoryUsage')).toBe(true);
213
+ expect(isValidSettingKey('accessibility.disableLoadingPhrases')).toBe(
214
+ true,
215
+ );
216
+ });
217
+
218
+ it('should return false for invalid setting keys', () => {
219
+ expect(isValidSettingKey('invalidSetting')).toBe(false);
220
+ expect(isValidSettingKey('')).toBe(false);
221
+ });
222
+ });
223
+
224
+ describe('getSettingCategory', () => {
225
+ it('should return correct category for valid settings', () => {
226
+ expect(getSettingCategory('showMemoryUsage')).toBe('UI');
227
+ expect(getSettingCategory('accessibility.disableLoadingPhrases')).toBe(
228
+ 'Accessibility',
229
+ );
230
+ });
231
+
232
+ it('should return undefined for invalid settings', () => {
233
+ expect(getSettingCategory('invalidSetting')).toBeUndefined();
234
+ });
235
+ });
236
+
237
+ describe('shouldShowInDialog', () => {
238
+ it('should return true for settings marked to show in dialog', () => {
239
+ expect(shouldShowInDialog('showMemoryUsage')).toBe(true);
240
+ expect(shouldShowInDialog('vimMode')).toBe(true);
241
+ expect(shouldShowInDialog('hideWindowTitle')).toBe(true);
242
+ expect(shouldShowInDialog('usageStatisticsEnabled')).toBe(false);
243
+ });
244
+
245
+ it('should return false for settings marked to hide from dialog', () => {
246
+ expect(shouldShowInDialog('selectedAuthType')).toBe(false);
247
+ expect(shouldShowInDialog('coreTools')).toBe(false);
248
+ expect(shouldShowInDialog('customThemes')).toBe(false);
249
+ expect(shouldShowInDialog('theme')).toBe(false); // Changed to false
250
+ expect(shouldShowInDialog('preferredEditor')).toBe(false); // Changed to false
251
+ });
252
+
253
+ it('should return true for invalid settings (default behavior)', () => {
254
+ expect(shouldShowInDialog('invalidSetting')).toBe(true);
255
+ });
256
+ });
257
+
258
+ describe('getDialogSettingsByCategory', () => {
259
+ it('should only return settings marked for dialog display', async () => {
260
+ const categories = getDialogSettingsByCategory();
261
+
262
+ // Should include UI settings that are marked for dialog
263
+ expect(categories['UI']).toBeDefined();
264
+ const uiSettings = categories['UI'];
265
+ const uiKeys = uiSettings.map((s) => s.key);
266
+ expect(uiKeys).toContain('showMemoryUsage');
267
+ expect(uiKeys).toContain('hideWindowTitle');
268
+ expect(uiKeys).not.toContain('customThemes'); // This is marked false
269
+ expect(uiKeys).not.toContain('theme'); // This is now marked false
270
+ });
271
+
272
+ it('should not include Advanced category settings', () => {
273
+ const categories = getDialogSettingsByCategory();
274
+
275
+ // Advanced settings should be filtered out
276
+ expect(categories['Advanced']).toBeUndefined();
277
+ });
278
+
279
+ it('should include settings with showInDialog=true', () => {
280
+ const categories = getDialogSettingsByCategory();
281
+
282
+ const allSettings = Object.values(categories).flat();
283
+ const allKeys = allSettings.map((s) => s.key);
284
+
285
+ expect(allKeys).toContain('vimMode');
286
+ expect(allKeys).toContain('ideMode');
287
+ expect(allKeys).toContain('disableAutoUpdate');
288
+ expect(allKeys).toContain('showMemoryUsage');
289
+ expect(allKeys).not.toContain('usageStatisticsEnabled');
290
+ expect(allKeys).not.toContain('selectedAuthType');
291
+ expect(allKeys).not.toContain('coreTools');
292
+ expect(allKeys).not.toContain('theme'); // Now hidden
293
+ expect(allKeys).not.toContain('preferredEditor'); // Now hidden
294
+ });
295
+ });
296
+
297
+ describe('getDialogSettingsByType', () => {
298
+ it('should return only boolean dialog settings', () => {
299
+ const booleanSettings = getDialogSettingsByType('boolean');
300
+
301
+ const keys = booleanSettings.map((s) => s.key);
302
+ expect(keys).toContain('showMemoryUsage');
303
+ expect(keys).toContain('vimMode');
304
+ expect(keys).toContain('hideWindowTitle');
305
+ expect(keys).not.toContain('usageStatisticsEnabled');
306
+ expect(keys).not.toContain('selectedAuthType'); // Advanced setting
307
+ expect(keys).not.toContain('useExternalAuth'); // Advanced setting
308
+ });
309
+
310
+ it('should return only string dialog settings', () => {
311
+ const stringSettings = getDialogSettingsByType('string');
312
+
313
+ const keys = stringSettings.map((s) => s.key);
314
+ // Note: theme and preferredEditor are now hidden from dialog
315
+ expect(keys).not.toContain('theme'); // Now marked false
316
+ expect(keys).not.toContain('preferredEditor'); // Now marked false
317
+ expect(keys).not.toContain('selectedAuthType'); // Advanced setting
318
+
319
+ // Most string settings are now hidden, so let's just check they exclude advanced ones
320
+ expect(keys.every((key) => !key.startsWith('tool'))).toBe(true); // No tool-related settings
321
+ });
322
+ });
323
+
324
+ describe('getDialogSettingKeys', () => {
325
+ it('should return only settings marked for dialog display', () => {
326
+ const dialogKeys = getDialogSettingKeys();
327
+
328
+ // Should include settings marked for dialog
329
+ expect(dialogKeys).toContain('showMemoryUsage');
330
+ expect(dialogKeys).toContain('vimMode');
331
+ expect(dialogKeys).toContain('hideWindowTitle');
332
+ expect(dialogKeys).not.toContain('usageStatisticsEnabled');
333
+ expect(dialogKeys).toContain('ideMode');
334
+ expect(dialogKeys).toContain('disableAutoUpdate');
335
+
336
+ // Should include nested settings marked for dialog
337
+ expect(dialogKeys).toContain('fileFiltering.respectGitIgnore');
338
+ expect(dialogKeys).toContain('fileFiltering.respectFssLinkIgnore');
339
+ expect(dialogKeys).toContain('fileFiltering.enableRecursiveFileSearch');
340
+
341
+ // Should NOT include settings marked as hidden
342
+ expect(dialogKeys).not.toContain('theme'); // Hidden
343
+ expect(dialogKeys).not.toContain('customThemes'); // Hidden
344
+ expect(dialogKeys).not.toContain('preferredEditor'); // Hidden
345
+ expect(dialogKeys).not.toContain('selectedAuthType'); // Advanced
346
+ expect(dialogKeys).not.toContain('coreTools'); // Advanced
347
+ expect(dialogKeys).not.toContain('mcpServers'); // Advanced
348
+ expect(dialogKeys).not.toContain('telemetry'); // Advanced
349
+ });
350
+
351
+ it('should return fewer keys than getAllSettingKeys', () => {
352
+ const allKeys = getAllSettingKeys();
353
+ const dialogKeys = getDialogSettingKeys();
354
+
355
+ expect(dialogKeys.length).toBeLessThan(allKeys.length);
356
+ expect(dialogKeys.length).toBeGreaterThan(0);
357
+ });
358
+
359
+ it('should handle nested settings display correctly', () => {
360
+ // Test the specific issue with fileFiltering.respectGitIgnore
361
+ const key = 'fileFiltering.respectGitIgnore';
362
+ const initialSettings = {};
363
+ const pendingSettings = {};
364
+
365
+ // Set the nested setting to true
366
+ const updatedPendingSettings = setPendingSettingValue(
367
+ key,
368
+ true,
369
+ pendingSettings,
370
+ );
371
+
372
+ // Check if the setting exists in pending settings
373
+ const existsInPending = settingExistsInScope(
374
+ key,
375
+ updatedPendingSettings,
376
+ );
377
+ expect(existsInPending).toBe(true);
378
+
379
+ // Get the value from pending settings
380
+ const valueFromPending = getSettingValue(
381
+ key,
382
+ updatedPendingSettings,
383
+ {},
384
+ );
385
+ expect(valueFromPending).toBe(true);
386
+
387
+ // Test getDisplayValue should show the pending change
388
+ const displayValue = getDisplayValue(
389
+ key,
390
+ initialSettings,
391
+ {},
392
+ new Set(),
393
+ updatedPendingSettings,
394
+ );
395
+ expect(displayValue).toBe('true'); // Should show true (no * since value matches default)
396
+
397
+ // Test that modified settings also show the * indicator
398
+ const modifiedSettings = new Set([key]);
399
+ const displayValueWithModified = getDisplayValue(
400
+ key,
401
+ initialSettings,
402
+ {},
403
+ modifiedSettings,
404
+ {},
405
+ );
406
+ expect(displayValueWithModified).toBe('true*'); // Should show true* because it's in modified settings and default is true
407
+ });
408
+ });
409
+ });
410
+
411
+ describe('Business Logic Utilities', () => {
412
+ describe('getSettingValue', () => {
413
+ it('should return value from settings when set', () => {
414
+ const settings = { showMemoryUsage: true };
415
+ const mergedSettings = { showMemoryUsage: false };
416
+
417
+ const value = getSettingValue(
418
+ 'showMemoryUsage',
419
+ settings,
420
+ mergedSettings,
421
+ );
422
+ expect(value).toBe(true);
423
+ });
424
+
425
+ it('should return value from merged settings when not set in current scope', () => {
426
+ const settings = {};
427
+ const mergedSettings = { showMemoryUsage: true };
428
+
429
+ const value = getSettingValue(
430
+ 'showMemoryUsage',
431
+ settings,
432
+ mergedSettings,
433
+ );
434
+ expect(value).toBe(true);
435
+ });
436
+
437
+ it('should return default value for invalid setting', () => {
438
+ const settings = {};
439
+ const mergedSettings = {};
440
+
441
+ const value = getSettingValue(
442
+ 'invalidSetting',
443
+ settings,
444
+ mergedSettings,
445
+ );
446
+ expect(value).toBe(false); // Default fallback
447
+ });
448
+ });
449
+
450
+ describe('isSettingModified', () => {
451
+ it('should return true when value differs from default', () => {
452
+ expect(isSettingModified('showMemoryUsage', true)).toBe(true);
453
+ expect(
454
+ isSettingModified('fileFiltering.enableRecursiveFileSearch', false),
455
+ ).toBe(true);
456
+ });
457
+
458
+ it('should return false when value matches default', () => {
459
+ expect(isSettingModified('showMemoryUsage', false)).toBe(false);
460
+ expect(
461
+ isSettingModified('fileFiltering.enableRecursiveFileSearch', true),
462
+ ).toBe(false);
463
+ });
464
+ });
465
+
466
+ describe('settingExistsInScope', () => {
467
+ it('should return true for top-level settings that exist', () => {
468
+ const settings = { showMemoryUsage: true };
469
+ expect(settingExistsInScope('showMemoryUsage', settings)).toBe(true);
470
+ });
471
+
472
+ it('should return false for top-level settings that do not exist', () => {
473
+ const settings = {};
474
+ expect(settingExistsInScope('showMemoryUsage', settings)).toBe(false);
475
+ });
476
+
477
+ it('should return true for nested settings that exist', () => {
478
+ const settings = {
479
+ accessibility: { disableLoadingPhrases: true },
480
+ };
481
+ expect(
482
+ settingExistsInScope('accessibility.disableLoadingPhrases', settings),
483
+ ).toBe(true);
484
+ });
485
+
486
+ it('should return false for nested settings that do not exist', () => {
487
+ const settings = {};
488
+ expect(
489
+ settingExistsInScope('accessibility.disableLoadingPhrases', settings),
490
+ ).toBe(false);
491
+ });
492
+
493
+ it('should return false when parent exists but child does not', () => {
494
+ const settings = { accessibility: {} };
495
+ expect(
496
+ settingExistsInScope('accessibility.disableLoadingPhrases', settings),
497
+ ).toBe(false);
498
+ });
499
+ });
500
+
501
+ describe('setPendingSettingValue', () => {
502
+ it('should set top-level setting value', () => {
503
+ const pendingSettings = {};
504
+ const result = setPendingSettingValue(
505
+ 'showMemoryUsage',
506
+ true,
507
+ pendingSettings,
508
+ );
509
+
510
+ expect(result.showMemoryUsage).toBe(true);
511
+ });
512
+
513
+ it('should set nested setting value', () => {
514
+ const pendingSettings = {};
515
+ const result = setPendingSettingValue(
516
+ 'accessibility.disableLoadingPhrases',
517
+ true,
518
+ pendingSettings,
519
+ );
520
+
521
+ expect(result.accessibility?.disableLoadingPhrases).toBe(true);
522
+ });
523
+
524
+ it('should preserve existing nested settings', () => {
525
+ const pendingSettings = {
526
+ accessibility: { disableLoadingPhrases: false },
527
+ };
528
+ const result = setPendingSettingValue(
529
+ 'accessibility.disableLoadingPhrases',
530
+ true,
531
+ pendingSettings,
532
+ );
533
+
534
+ expect(result.accessibility?.disableLoadingPhrases).toBe(true);
535
+ });
536
+
537
+ it('should not mutate original settings', () => {
538
+ const pendingSettings = {};
539
+ setPendingSettingValue('showMemoryUsage', true, pendingSettings);
540
+
541
+ expect(pendingSettings).toEqual({});
542
+ });
543
+ });
544
+
545
+ describe('hasRestartRequiredSettings', () => {
546
+ it('should return true when modified settings require restart', () => {
547
+ const modifiedSettings = new Set<string>([
548
+ 'autoConfigureMaxOldSpaceSize',
549
+ 'showMemoryUsage',
550
+ ]);
551
+ expect(hasRestartRequiredSettings(modifiedSettings)).toBe(true);
552
+ });
553
+
554
+ it('should return false when no modified settings require restart', () => {
555
+ const modifiedSettings = new Set<string>([
556
+ 'showMemoryUsage',
557
+ 'hideTips',
558
+ ]);
559
+ expect(hasRestartRequiredSettings(modifiedSettings)).toBe(false);
560
+ });
561
+
562
+ it('should return false for empty set', () => {
563
+ const modifiedSettings = new Set<string>();
564
+ expect(hasRestartRequiredSettings(modifiedSettings)).toBe(false);
565
+ });
566
+ });
567
+
568
+ describe('getRestartRequiredFromModified', () => {
569
+ it('should return only settings that require restart', () => {
570
+ const modifiedSettings = new Set<string>([
571
+ 'autoConfigureMaxOldSpaceSize',
572
+ 'showMemoryUsage',
573
+ 'checkpointing.enabled',
574
+ ]);
575
+ const result = getRestartRequiredFromModified(modifiedSettings);
576
+
577
+ expect(result).toContain('autoConfigureMaxOldSpaceSize');
578
+ expect(result).toContain('checkpointing.enabled');
579
+ expect(result).not.toContain('showMemoryUsage');
580
+ });
581
+
582
+ it('should return empty array when no settings require restart', () => {
583
+ const modifiedSettings = new Set<string>([
584
+ 'showMemoryUsage',
585
+ 'hideTips',
586
+ ]);
587
+ const result = getRestartRequiredFromModified(modifiedSettings);
588
+
589
+ expect(result).toEqual([]);
590
+ });
591
+ });
592
+
593
+ describe('getDisplayValue', () => {
594
+ it('should show value without * when setting matches default', () => {
595
+ const settings = { showMemoryUsage: false }; // false matches default, so no *
596
+ const mergedSettings = { showMemoryUsage: false };
597
+ const modifiedSettings = new Set<string>();
598
+
599
+ const result = getDisplayValue(
600
+ 'showMemoryUsage',
601
+ settings,
602
+ mergedSettings,
603
+ modifiedSettings,
604
+ );
605
+ expect(result).toBe('false*');
606
+ });
607
+
608
+ it('should show default value when setting is not in scope', () => {
609
+ const settings = {}; // no setting in scope
610
+ const mergedSettings = { showMemoryUsage: false };
611
+ const modifiedSettings = new Set<string>();
612
+
613
+ const result = getDisplayValue(
614
+ 'showMemoryUsage',
615
+ settings,
616
+ mergedSettings,
617
+ modifiedSettings,
618
+ );
619
+ expect(result).toBe('false'); // shows default value
620
+ });
621
+
622
+ it('should show value with * when changed from default', () => {
623
+ const settings = { showMemoryUsage: true }; // true is different from default (false)
624
+ const mergedSettings = { showMemoryUsage: true };
625
+ const modifiedSettings = new Set<string>();
626
+
627
+ const result = getDisplayValue(
628
+ 'showMemoryUsage',
629
+ settings,
630
+ mergedSettings,
631
+ modifiedSettings,
632
+ );
633
+ expect(result).toBe('true*');
634
+ });
635
+
636
+ it('should show default value without * when setting does not exist in scope', () => {
637
+ const settings = {}; // setting doesn't exist in scope, show default
638
+ const mergedSettings = { showMemoryUsage: false };
639
+ const modifiedSettings = new Set<string>();
640
+
641
+ const result = getDisplayValue(
642
+ 'showMemoryUsage',
643
+ settings,
644
+ mergedSettings,
645
+ modifiedSettings,
646
+ );
647
+ expect(result).toBe('false'); // default value (false) without *
648
+ });
649
+
650
+ it('should show value with * when user changes from default', () => {
651
+ const settings = {}; // setting doesn't exist in scope originally
652
+ const mergedSettings = { showMemoryUsage: false };
653
+ const modifiedSettings = new Set<string>(['showMemoryUsage']);
654
+ const pendingSettings = { showMemoryUsage: true }; // user changed to true
655
+
656
+ const result = getDisplayValue(
657
+ 'showMemoryUsage',
658
+ settings,
659
+ mergedSettings,
660
+ modifiedSettings,
661
+ pendingSettings,
662
+ );
663
+ expect(result).toBe('true*'); // changed from default (false) to true
664
+ });
665
+ });
666
+
667
+ describe('isDefaultValue', () => {
668
+ it('should return true when setting does not exist in scope', () => {
669
+ const settings = {}; // setting doesn't exist
670
+
671
+ const result = isDefaultValue('showMemoryUsage', settings);
672
+ expect(result).toBe(true);
673
+ });
674
+
675
+ it('should return false when setting exists in scope', () => {
676
+ const settings = { showMemoryUsage: true }; // setting exists
677
+
678
+ const result = isDefaultValue('showMemoryUsage', settings);
679
+ expect(result).toBe(false);
680
+ });
681
+
682
+ it('should return true when nested setting does not exist in scope', () => {
683
+ const settings = {}; // nested setting doesn't exist
684
+
685
+ const result = isDefaultValue(
686
+ 'accessibility.disableLoadingPhrases',
687
+ settings,
688
+ );
689
+ expect(result).toBe(true);
690
+ });
691
+
692
+ it('should return false when nested setting exists in scope', () => {
693
+ const settings = { accessibility: { disableLoadingPhrases: true } }; // nested setting exists
694
+
695
+ const result = isDefaultValue(
696
+ 'accessibility.disableLoadingPhrases',
697
+ settings,
698
+ );
699
+ expect(result).toBe(false);
700
+ });
701
+ });
702
+
703
+ describe('isValueInherited', () => {
704
+ it('should return false for top-level settings that exist in scope', () => {
705
+ const settings = { showMemoryUsage: true };
706
+ const mergedSettings = { showMemoryUsage: true };
707
+
708
+ const result = isValueInherited(
709
+ 'showMemoryUsage',
710
+ settings,
711
+ mergedSettings,
712
+ );
713
+ expect(result).toBe(false);
714
+ });
715
+
716
+ it('should return true for top-level settings that do not exist in scope', () => {
717
+ const settings = {};
718
+ const mergedSettings = { showMemoryUsage: true };
719
+
720
+ const result = isValueInherited(
721
+ 'showMemoryUsage',
722
+ settings,
723
+ mergedSettings,
724
+ );
725
+ expect(result).toBe(true);
726
+ });
727
+
728
+ it('should return false for nested settings that exist in scope', () => {
729
+ const settings = {
730
+ accessibility: { disableLoadingPhrases: true },
731
+ };
732
+ const mergedSettings = {
733
+ accessibility: { disableLoadingPhrases: true },
734
+ };
735
+
736
+ const result = isValueInherited(
737
+ 'accessibility.disableLoadingPhrases',
738
+ settings,
739
+ mergedSettings,
740
+ );
741
+ expect(result).toBe(false);
742
+ });
743
+
744
+ it('should return true for nested settings that do not exist in scope', () => {
745
+ const settings = {};
746
+ const mergedSettings = {
747
+ accessibility: { disableLoadingPhrases: true },
748
+ };
749
+
750
+ const result = isValueInherited(
751
+ 'accessibility.disableLoadingPhrases',
752
+ settings,
753
+ mergedSettings,
754
+ );
755
+ expect(result).toBe(true);
756
+ });
757
+ });
758
+
759
+ describe('getEffectiveDisplayValue', () => {
760
+ it('should return value from settings when available', () => {
761
+ const settings = { showMemoryUsage: true };
762
+ const mergedSettings = { showMemoryUsage: false };
763
+
764
+ const result = getEffectiveDisplayValue(
765
+ 'showMemoryUsage',
766
+ settings,
767
+ mergedSettings,
768
+ );
769
+ expect(result).toBe(true);
770
+ });
771
+
772
+ it('should return value from merged settings when not in scope', () => {
773
+ const settings = {};
774
+ const mergedSettings = { showMemoryUsage: true };
775
+
776
+ const result = getEffectiveDisplayValue(
777
+ 'showMemoryUsage',
778
+ settings,
779
+ mergedSettings,
780
+ );
781
+ expect(result).toBe(true);
782
+ });
783
+
784
+ it('should return default value for undefined values', () => {
785
+ const settings = {};
786
+ const mergedSettings = {};
787
+
788
+ const result = getEffectiveDisplayValue(
789
+ 'showMemoryUsage',
790
+ settings,
791
+ mergedSettings,
792
+ );
793
+ expect(result).toBe(false); // Default value
794
+ });
795
+ });
796
+ });
797
+ });