fss-link 1.0.49 → 1.0.51
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.
- package/dist/index.js +0 -0
- package/dist/package.json +2 -2
- package/dist/src/config/auth.js +8 -5
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/database.d.ts +103 -11
- package/dist/src/config/database.js +301 -59
- package/dist/src/config/database.js.map +1 -1
- package/dist/src/config/databaseBackup.d.ts +114 -0
- package/dist/src/config/databaseBackup.js +334 -0
- package/dist/src/config/databaseBackup.js.map +1 -0
- package/dist/src/config/databaseMigrations.d.ts +63 -0
- package/dist/src/config/databaseMigrations.js +379 -0
- package/dist/src/config/databaseMigrations.js.map +1 -0
- package/dist/src/config/databasePool.d.ts +70 -0
- package/dist/src/config/databasePool.js +193 -0
- package/dist/src/config/databasePool.js.map +1 -0
- package/dist/src/config/queryOptimizer.d.ts +127 -0
- package/dist/src/config/queryOptimizer.js +309 -0
- package/dist/src/config/queryOptimizer.js.map +1 -0
- package/dist/src/utils/sandbox.js +2 -8
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +3 -7
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/commands/mcp/add.test.ts +0 -122
- package/dist/commands/mcp/add.ts +0 -222
- package/dist/commands/mcp/list.test.ts +0 -154
- package/dist/commands/mcp/list.ts +0 -139
- package/dist/commands/mcp/remove.test.ts +0 -69
- package/dist/commands/mcp/remove.ts +0 -60
- package/dist/commands/mcp.test.ts +0 -55
- package/dist/commands/mcp.ts +0 -27
- package/dist/config/apiValidation.test.ts +0 -118
- package/dist/config/auth.test.ts +0 -79
- package/dist/config/auth.ts +0 -100
- package/dist/config/config.integration.test.ts +0 -407
- package/dist/config/config.test.ts +0 -1952
- package/dist/config/config.ts +0 -690
- package/dist/config/database.test.ts +0 -96
- package/dist/config/database.ts +0 -824
- package/dist/config/extension.test.ts +0 -236
- package/dist/config/extension.ts +0 -180
- package/dist/config/keyBindings.test.ts +0 -62
- package/dist/config/keyBindings.ts +0 -184
- package/dist/config/modelManager.ts +0 -326
- package/dist/config/providerManager.ts +0 -244
- package/dist/config/providerPersistence.test.ts +0 -377
- package/dist/config/providerPersistence.ts +0 -105
- package/dist/config/sandboxConfig.ts +0 -107
- package/dist/config/settings.test.ts +0 -1424
- package/dist/config/settings.ts +0 -517
- package/dist/config/settingsSchema.test.ts +0 -252
- package/dist/config/settingsSchema.ts +0 -728
- package/dist/config/trustedFolders.test.ts +0 -208
- package/dist/config/trustedFolders.ts +0 -167
- package/dist/gemini.test.tsx +0 -252
- package/dist/gemini.tsx +0 -357
- package/dist/generated/git-commit.ts +0 -10
- package/dist/index.ts +0 -21
- package/dist/nonInteractiveCli.test.ts +0 -276
- package/dist/nonInteractiveCli.ts +0 -143
- package/dist/patches/is-in-ci.ts +0 -17
- package/dist/services/BuiltinCommandLoader.test.ts +0 -127
- package/dist/services/BuiltinCommandLoader.ts +0 -95
- package/dist/services/CommandService.test.ts +0 -352
- package/dist/services/CommandService.ts +0 -103
- package/dist/services/FileCommandLoader.test.ts +0 -1002
- package/dist/services/FileCommandLoader.ts +0 -289
- package/dist/services/McpPromptLoader.ts +0 -231
- package/dist/services/SearchEngineConfigProvider.ts +0 -100
- package/dist/services/prompt-processors/argumentProcessor.test.ts +0 -41
- package/dist/services/prompt-processors/argumentProcessor.ts +0 -23
- package/dist/services/prompt-processors/shellProcessor.test.ts +0 -709
- package/dist/services/prompt-processors/shellProcessor.ts +0 -248
- package/dist/services/prompt-processors/types.ts +0 -44
- package/dist/services/types.ts +0 -24
- package/dist/src/config/apiValidation.test.d.ts +0 -6
- package/dist/src/config/apiValidation.test.js +0 -99
- package/dist/src/config/apiValidation.test.js.map +0 -1
- package/dist/src/config/database.test.d.ts +0 -6
- package/dist/src/config/database.test.js +0 -80
- package/dist/src/config/database.test.js.map +0 -1
- package/dist/src/config/providerManager.d.ts +0 -74
- package/dist/src/config/providerManager.js +0 -203
- package/dist/src/config/providerManager.js.map +0 -1
- package/dist/src/config/providerPersistence.test.d.ts +0 -6
- package/dist/src/config/providerPersistence.test.js +0 -283
- package/dist/src/config/providerPersistence.test.js.map +0 -1
- package/dist/src/ui/components/GeminiKeyDialog.d.ts +0 -11
- package/dist/src/ui/components/GeminiKeyDialog.js +0 -156
- package/dist/src/ui/components/GeminiKeyDialog.js.map +0 -1
- package/dist/src/ui/components/OpenAIEndpointDialog.d.ts +0 -19
- package/dist/src/ui/components/OpenAIEndpointDialog.js +0 -163
- package/dist/src/ui/components/OpenAIEndpointDialog.js.map +0 -1
- package/dist/test-setup.ts +0 -12
- package/dist/test-utils/customMatchers.ts +0 -65
- package/dist/test-utils/mockCommandContext.test.ts +0 -62
- package/dist/test-utils/mockCommandContext.ts +0 -105
- package/dist/test-utils/render.tsx +0 -18
- package/dist/ui/App.test.tsx +0 -2181
- package/dist/ui/App.tsx +0 -1344
- package/dist/ui/IdeIntegrationNudge.tsx +0 -98
- package/dist/ui/__snapshots__/App.test.tsx.snap +0 -124
- package/dist/ui/colors.ts +0 -56
- package/dist/ui/commands/aboutCommand.test.ts +0 -153
- package/dist/ui/commands/aboutCommand.ts +0 -49
- package/dist/ui/commands/authCommand.test.ts +0 -36
- package/dist/ui/commands/authCommand.ts +0 -17
- package/dist/ui/commands/bugCommand.test.ts +0 -114
- package/dist/ui/commands/bugCommand.ts +0 -92
- package/dist/ui/commands/chatCommand.test.ts +0 -414
- package/dist/ui/commands/chatCommand.ts +0 -280
- package/dist/ui/commands/clearCommand.test.ts +0 -100
- package/dist/ui/commands/clearCommand.ts +0 -29
- package/dist/ui/commands/compressCommand.test.ts +0 -129
- package/dist/ui/commands/compressCommand.ts +0 -78
- package/dist/ui/commands/contextCommand.ts +0 -132
- package/dist/ui/commands/copyCommand.test.ts +0 -296
- package/dist/ui/commands/copyCommand.ts +0 -67
- package/dist/ui/commands/corgiCommand.test.ts +0 -34
- package/dist/ui/commands/corgiCommand.ts +0 -16
- package/dist/ui/commands/directoryCommand.test.tsx +0 -185
- package/dist/ui/commands/directoryCommand.tsx +0 -179
- package/dist/ui/commands/docsCommand.test.ts +0 -99
- package/dist/ui/commands/docsCommand.ts +0 -42
- package/dist/ui/commands/editorCommand.test.ts +0 -30
- package/dist/ui/commands/editorCommand.ts +0 -21
- package/dist/ui/commands/extensionsCommand.test.ts +0 -67
- package/dist/ui/commands/extensionsCommand.ts +0 -46
- package/dist/ui/commands/helpCommand.test.ts +0 -52
- package/dist/ui/commands/helpCommand.ts +0 -23
- package/dist/ui/commands/ideCommand.test.ts +0 -255
- package/dist/ui/commands/ideCommand.ts +0 -283
- package/dist/ui/commands/initCommand.test.ts +0 -127
- package/dist/ui/commands/initCommand.ts +0 -117
- package/dist/ui/commands/mcpCommand.test.ts +0 -1057
- package/dist/ui/commands/mcpCommand.ts +0 -531
- package/dist/ui/commands/memoryCommand.test.ts +0 -344
- package/dist/ui/commands/memoryCommand.ts +0 -305
- package/dist/ui/commands/privacyCommand.test.ts +0 -38
- package/dist/ui/commands/privacyCommand.ts +0 -17
- package/dist/ui/commands/quitCommand.test.ts +0 -55
- package/dist/ui/commands/quitCommand.ts +0 -36
- package/dist/ui/commands/restoreCommand.test.ts +0 -250
- package/dist/ui/commands/restoreCommand.ts +0 -157
- package/dist/ui/commands/searchEngineSetupCommand.ts +0 -18
- package/dist/ui/commands/settingsCommand.test.ts +0 -36
- package/dist/ui/commands/settingsCommand.ts +0 -17
- package/dist/ui/commands/setupGithubCommand.test.ts +0 -238
- package/dist/ui/commands/setupGithubCommand.ts +0 -212
- package/dist/ui/commands/speakCommand.ts +0 -175
- package/dist/ui/commands/statsCommand.test.ts +0 -78
- package/dist/ui/commands/statsCommand.ts +0 -70
- package/dist/ui/commands/terminalSetupCommand.test.ts +0 -85
- package/dist/ui/commands/terminalSetupCommand.ts +0 -45
- package/dist/ui/commands/themeCommand.test.ts +0 -38
- package/dist/ui/commands/themeCommand.ts +0 -17
- package/dist/ui/commands/toolsCommand.test.ts +0 -105
- package/dist/ui/commands/toolsCommand.ts +0 -71
- package/dist/ui/commands/ttsCommand.ts +0 -143
- package/dist/ui/commands/types.ts +0 -204
- package/dist/ui/commands/vimCommand.ts +0 -25
- package/dist/ui/commands/voiceCommand.ts +0 -125
- package/dist/ui/components/AboutBox.tsx +0 -133
- package/dist/ui/components/AsciiArt.ts +0 -54
- package/dist/ui/components/AuthDialog.test.tsx +0 -334
- package/dist/ui/components/AuthDialog.tsx +0 -289
- package/dist/ui/components/AuthInProgress.tsx +0 -62
- package/dist/ui/components/AutoAcceptIndicator.tsx +0 -47
- package/dist/ui/components/ConsoleSummaryDisplay.tsx +0 -35
- package/dist/ui/components/ContextSummaryDisplay.test.tsx +0 -85
- package/dist/ui/components/ContextSummaryDisplay.tsx +0 -120
- package/dist/ui/components/ContextUsageDisplay.tsx +0 -77
- package/dist/ui/components/DebugProfiler.tsx +0 -36
- package/dist/ui/components/DetailedMessagesDisplay.tsx +0 -82
- package/dist/ui/components/EditorSettingsDialog.tsx +0 -172
- package/dist/ui/components/FolderTrustDialog.test.tsx +0 -36
- package/dist/ui/components/FolderTrustDialog.tsx +0 -74
- package/dist/ui/components/Footer.test.tsx +0 -159
- package/dist/ui/components/Footer.tsx +0 -158
- package/dist/ui/components/GeminiKeyDialog.tsx +0 -252
- package/dist/ui/components/GeminiRespondingSpinner.tsx +0 -34
- package/dist/ui/components/Header.test.tsx +0 -44
- package/dist/ui/components/Header.tsx +0 -70
- package/dist/ui/components/Help.tsx +0 -174
- package/dist/ui/components/HistoryItemDisplay.test.tsx +0 -125
- package/dist/ui/components/HistoryItemDisplay.tsx +0 -98
- package/dist/ui/components/InputPrompt.test.tsx +0 -1467
- package/dist/ui/components/InputPrompt.tsx +0 -641
- package/dist/ui/components/LMStudioModelPrompt.tsx +0 -215
- package/dist/ui/components/LoadingIndicator.test.tsx +0 -296
- package/dist/ui/components/LoadingIndicator.tsx +0 -82
- package/dist/ui/components/MemoryUsageDisplay.tsx +0 -36
- package/dist/ui/components/ModelStatsDisplay.test.tsx +0 -252
- package/dist/ui/components/ModelStatsDisplay.tsx +0 -197
- package/dist/ui/components/OllamaModelPrompt.tsx +0 -206
- package/dist/ui/components/OpenAIEndpointDialog.tsx +0 -261
- package/dist/ui/components/OpenAIKeyPrompt.test.tsx +0 -64
- package/dist/ui/components/OpenAIKeyPrompt.tsx +0 -197
- package/dist/ui/components/PrepareLabel.tsx +0 -48
- package/dist/ui/components/SearchEngineConfigDialog.tsx +0 -280
- package/dist/ui/components/SessionSummaryDisplay.test.tsx +0 -75
- package/dist/ui/components/SessionSummaryDisplay.tsx +0 -18
- package/dist/ui/components/SettingsDialog.test.tsx +0 -865
- package/dist/ui/components/SettingsDialog.tsx +0 -753
- package/dist/ui/components/ShellConfirmationDialog.test.tsx +0 -53
- package/dist/ui/components/ShellConfirmationDialog.tsx +0 -103
- package/dist/ui/components/ShellModeIndicator.tsx +0 -18
- package/dist/ui/components/ShowMoreLines.tsx +0 -40
- package/dist/ui/components/StatsDisplay.test.tsx +0 -401
- package/dist/ui/components/StatsDisplay.tsx +0 -273
- package/dist/ui/components/SuggestionsDisplay.tsx +0 -102
- package/dist/ui/components/ThemeDialog.tsx +0 -310
- package/dist/ui/components/Tips.tsx +0 -45
- package/dist/ui/components/TodoDisplay.test.tsx +0 -97
- package/dist/ui/components/TodoDisplay.tsx +0 -72
- package/dist/ui/components/ToolStatsDisplay.test.tsx +0 -180
- package/dist/ui/components/ToolStatsDisplay.tsx +0 -208
- package/dist/ui/components/UpdateNotification.tsx +0 -23
- package/dist/ui/components/WelcomeBackDialog.tsx +0 -290
- package/dist/ui/components/__snapshots__/IDEContextDetailDisplay.test.tsx.snap +0 -24
- package/dist/ui/components/__snapshots__/ModelStatsDisplay.test.tsx.snap +0 -121
- package/dist/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap +0 -30
- package/dist/ui/components/__snapshots__/ShellConfirmationDialog.test.tsx.snap +0 -21
- package/dist/ui/components/__snapshots__/StatsDisplay.test.tsx.snap +0 -264
- package/dist/ui/components/__snapshots__/ToolStatsDisplay.test.tsx.snap +0 -91
- package/dist/ui/components/messages/CompressionMessage.tsx +0 -49
- package/dist/ui/components/messages/DiffRenderer.test.tsx +0 -365
- package/dist/ui/components/messages/DiffRenderer.tsx +0 -358
- package/dist/ui/components/messages/ErrorMessage.tsx +0 -31
- package/dist/ui/components/messages/GeminiMessage.tsx +0 -43
- package/dist/ui/components/messages/GeminiMessageContent.tsx +0 -43
- package/dist/ui/components/messages/InfoMessage.tsx +0 -32
- package/dist/ui/components/messages/ToolConfirmationMessage.test.tsx +0 -58
- package/dist/ui/components/messages/ToolConfirmationMessage.tsx +0 -297
- package/dist/ui/components/messages/ToolGroupMessage.tsx +0 -126
- package/dist/ui/components/messages/ToolMessage.test.tsx +0 -183
- package/dist/ui/components/messages/ToolMessage.tsx +0 -296
- package/dist/ui/components/messages/UserMessage.tsx +0 -43
- package/dist/ui/components/messages/UserShellMessage.tsx +0 -25
- package/dist/ui/components/shared/MaxSizedBox.test.tsx +0 -425
- package/dist/ui/components/shared/MaxSizedBox.tsx +0 -624
- package/dist/ui/components/shared/RadioButtonSelect.test.tsx +0 -181
- package/dist/ui/components/shared/RadioButtonSelect.tsx +0 -234
- package/dist/ui/components/shared/__snapshots__/RadioButtonSelect.test.tsx.snap +0 -47
- package/dist/ui/components/shared/text-buffer.test.ts +0 -1728
- package/dist/ui/components/shared/text-buffer.ts +0 -2227
- package/dist/ui/components/shared/vim-buffer-actions.test.ts +0 -1119
- package/dist/ui/components/shared/vim-buffer-actions.ts +0 -814
- package/dist/ui/constants.ts +0 -17
- package/dist/ui/contexts/KeypressContext.test.tsx +0 -391
- package/dist/ui/contexts/KeypressContext.tsx +0 -440
- package/dist/ui/contexts/OverflowContext.tsx +0 -87
- package/dist/ui/contexts/SessionContext.test.tsx +0 -132
- package/dist/ui/contexts/SessionContext.tsx +0 -143
- package/dist/ui/contexts/SettingsContext.tsx +0 -20
- package/dist/ui/contexts/StreamingContext.tsx +0 -22
- package/dist/ui/contexts/VimModeContext.tsx +0 -79
- package/dist/ui/editors/editorSettingsManager.ts +0 -66
- package/dist/ui/hooks/atCommandProcessor.test.ts +0 -1102
- package/dist/ui/hooks/atCommandProcessor.ts +0 -485
- package/dist/ui/hooks/shellCommandProcessor.test.ts +0 -481
- package/dist/ui/hooks/shellCommandProcessor.ts +0 -314
- package/dist/ui/hooks/slashCommandProcessor.test.ts +0 -1044
- package/dist/ui/hooks/slashCommandProcessor.ts +0 -595
- package/dist/ui/hooks/useAtCompletion.test.ts +0 -497
- package/dist/ui/hooks/useAtCompletion.ts +0 -244
- package/dist/ui/hooks/useAuthCommand.ts +0 -129
- package/dist/ui/hooks/useAutoAcceptIndicator.test.ts +0 -300
- package/dist/ui/hooks/useAutoAcceptIndicator.ts +0 -52
- package/dist/ui/hooks/useBracketedPaste.ts +0 -37
- package/dist/ui/hooks/useCommandCompletion.test.ts +0 -518
- package/dist/ui/hooks/useCommandCompletion.tsx +0 -238
- package/dist/ui/hooks/useCompletion.ts +0 -128
- package/dist/ui/hooks/useConsoleMessages.test.ts +0 -147
- package/dist/ui/hooks/useConsoleMessages.ts +0 -110
- package/dist/ui/hooks/useEditorSettings.test.ts +0 -283
- package/dist/ui/hooks/useEditorSettings.ts +0 -75
- package/dist/ui/hooks/useFocus.test.ts +0 -119
- package/dist/ui/hooks/useFocus.ts +0 -48
- package/dist/ui/hooks/useFolderTrust.test.ts +0 -159
- package/dist/ui/hooks/useFolderTrust.ts +0 -72
- package/dist/ui/hooks/useGeminiStream.test.tsx +0 -1998
- package/dist/ui/hooks/useGeminiStream.ts +0 -1017
- package/dist/ui/hooks/useGitBranchName.test.ts +0 -280
- package/dist/ui/hooks/useGitBranchName.ts +0 -79
- package/dist/ui/hooks/useHistoryManager.test.ts +0 -202
- package/dist/ui/hooks/useHistoryManager.ts +0 -111
- package/dist/ui/hooks/useInputHistory.test.ts +0 -261
- package/dist/ui/hooks/useInputHistory.ts +0 -111
- package/dist/ui/hooks/useKeypress.test.ts +0 -280
- package/dist/ui/hooks/useKeypress.ts +0 -39
- package/dist/ui/hooks/useKittyKeyboardProtocol.ts +0 -31
- package/dist/ui/hooks/useLoadingIndicator.test.ts +0 -139
- package/dist/ui/hooks/useLoadingIndicator.ts +0 -57
- package/dist/ui/hooks/useLogger.ts +0 -32
- package/dist/ui/hooks/useMessageQueue.test.ts +0 -226
- package/dist/ui/hooks/useMessageQueue.ts +0 -69
- package/dist/ui/hooks/usePhraseCycler.test.ts +0 -145
- package/dist/ui/hooks/usePhraseCycler.ts +0 -198
- package/dist/ui/hooks/usePrivacySettings.test.ts +0 -242
- package/dist/ui/hooks/usePrivacySettings.ts +0 -150
- package/dist/ui/hooks/useReactToolScheduler.ts +0 -309
- package/dist/ui/hooks/useRefreshMemoryCommand.ts +0 -7
- package/dist/ui/hooks/useReverseSearchCompletion.test.tsx +0 -260
- package/dist/ui/hooks/useReverseSearchCompletion.tsx +0 -95
- package/dist/ui/hooks/useSettingsCommand.ts +0 -25
- package/dist/ui/hooks/useShellHistory.test.ts +0 -219
- package/dist/ui/hooks/useShellHistory.ts +0 -133
- package/dist/ui/hooks/useShowMemoryCommand.ts +0 -75
- package/dist/ui/hooks/useSlashCompletion.test.ts +0 -434
- package/dist/ui/hooks/useSlashCompletion.ts +0 -187
- package/dist/ui/hooks/useStateAndRef.ts +0 -36
- package/dist/ui/hooks/useTerminalSize.ts +0 -32
- package/dist/ui/hooks/useThemeCommand.ts +0 -110
- package/dist/ui/hooks/useTimer.test.ts +0 -120
- package/dist/ui/hooks/useTimer.ts +0 -65
- package/dist/ui/hooks/useToolScheduler.test.ts +0 -1123
- package/dist/ui/hooks/useWelcomeBack.ts +0 -253
- package/dist/ui/hooks/vim.test.ts +0 -1691
- package/dist/ui/hooks/vim.ts +0 -784
- package/dist/ui/keyMatchers.test.ts +0 -337
- package/dist/ui/keyMatchers.ts +0 -105
- package/dist/ui/privacy/CloudFreePrivacyNotice.tsx +0 -117
- package/dist/ui/privacy/CloudPaidPrivacyNotice.tsx +0 -59
- package/dist/ui/privacy/GeminiPrivacyNotice.tsx +0 -62
- package/dist/ui/privacy/PrivacyNotice.tsx +0 -42
- package/dist/ui/semantic-colors.ts +0 -26
- package/dist/ui/themes/ansi-light.ts +0 -150
- package/dist/ui/themes/ansi.ts +0 -159
- package/dist/ui/themes/atom-one-dark.ts +0 -147
- package/dist/ui/themes/ayu-light.ts +0 -139
- package/dist/ui/themes/ayu.ts +0 -113
- package/dist/ui/themes/color-utils.test.ts +0 -221
- package/dist/ui/themes/color-utils.ts +0 -231
- package/dist/ui/themes/default-light.ts +0 -108
- package/dist/ui/themes/default.ts +0 -151
- package/dist/ui/themes/dracula.ts +0 -124
- package/dist/ui/themes/fss-code-dark.ts +0 -156
- package/dist/ui/themes/fss-dark.ts +0 -113
- package/dist/ui/themes/fss-light.ts +0 -139
- package/dist/ui/themes/github-dark.ts +0 -147
- package/dist/ui/themes/github-light.ts +0 -149
- package/dist/ui/themes/googlecode.ts +0 -146
- package/dist/ui/themes/no-color.ts +0 -125
- package/dist/ui/themes/qwen-dark.ts +0 -118
- package/dist/ui/themes/qwen-light.ts +0 -144
- package/dist/ui/themes/semantic-tokens.ts +0 -127
- package/dist/ui/themes/shades-of-purple.ts +0 -352
- package/dist/ui/themes/theme-manager.test.ts +0 -99
- package/dist/ui/themes/theme-manager.ts +0 -257
- package/dist/ui/themes/theme.test.ts +0 -97
- package/dist/ui/themes/theme.ts +0 -451
- package/dist/ui/themes/xcode.ts +0 -154
- package/dist/ui/types.ts +0 -255
- package/dist/ui/utils/CodeColorizer.tsx +0 -217
- package/dist/ui/utils/ConsolePatcher.ts +0 -71
- package/dist/ui/utils/InlineMarkdownRenderer.tsx +0 -173
- package/dist/ui/utils/MarkdownDisplay.test.tsx +0 -244
- package/dist/ui/utils/MarkdownDisplay.tsx +0 -415
- package/dist/ui/utils/TableRenderer.tsx +0 -159
- package/dist/ui/utils/__snapshots__/MarkdownDisplay.test.tsx.snap +0 -93
- package/dist/ui/utils/clipboardUtils.test.ts +0 -76
- package/dist/ui/utils/clipboardUtils.ts +0 -149
- package/dist/ui/utils/commandUtils.test.ts +0 -384
- package/dist/ui/utils/commandUtils.ts +0 -106
- package/dist/ui/utils/computeStats.test.ts +0 -292
- package/dist/ui/utils/computeStats.ts +0 -86
- package/dist/ui/utils/displayUtils.test.ts +0 -58
- package/dist/ui/utils/displayUtils.ts +0 -32
- package/dist/ui/utils/formatters.test.ts +0 -72
- package/dist/ui/utils/formatters.ts +0 -63
- package/dist/ui/utils/isNarrowWidth.ts +0 -9
- package/dist/ui/utils/kittyProtocolDetector.ts +0 -105
- package/dist/ui/utils/markdownUtilities.test.ts +0 -50
- package/dist/ui/utils/markdownUtilities.ts +0 -125
- package/dist/ui/utils/platformConstants.ts +0 -52
- package/dist/ui/utils/terminalSetup.ts +0 -342
- package/dist/ui/utils/textUtils.ts +0 -40
- package/dist/ui/utils/updateCheck.test.ts +0 -163
- package/dist/ui/utils/updateCheck.ts +0 -100
- package/dist/utils/checks.ts +0 -28
- package/dist/utils/cleanup.test.ts +0 -68
- package/dist/utils/cleanup.ts +0 -36
- package/dist/utils/dialogScopeUtils.ts +0 -64
- package/dist/utils/events.ts +0 -14
- package/dist/utils/gitUtils.test.ts +0 -149
- package/dist/utils/gitUtils.ts +0 -116
- package/dist/utils/handleAutoUpdate.test.ts +0 -272
- package/dist/utils/handleAutoUpdate.ts +0 -145
- package/dist/utils/installationInfo.test.ts +0 -315
- package/dist/utils/installationInfo.ts +0 -176
- package/dist/utils/package.ts +0 -38
- package/dist/utils/readStdin.ts +0 -51
- package/dist/utils/resolvePath.ts +0 -21
- package/dist/utils/sandbox-macos-permissive-closed.sb +0 -32
- package/dist/utils/sandbox-macos-permissive-open.sb +0 -25
- package/dist/utils/sandbox-macos-permissive-proxied.sb +0 -37
- package/dist/utils/sandbox-macos-restrictive-closed.sb +0 -93
- package/dist/utils/sandbox-macos-restrictive-open.sb +0 -96
- package/dist/utils/sandbox-macos-restrictive-proxied.sb +0 -98
- package/dist/utils/sandbox.ts +0 -962
- package/dist/utils/settingsUtils.test.ts +0 -797
- package/dist/utils/settingsUtils.ts +0 -489
- package/dist/utils/spawnWrapper.ts +0 -9
- package/dist/utils/startupWarnings.test.ts +0 -83
- package/dist/utils/startupWarnings.ts +0 -40
- package/dist/utils/updateEventEmitter.ts +0 -13
- package/dist/utils/userStartupWarnings.test.ts +0 -87
- package/dist/utils/userStartupWarnings.ts +0 -69
- package/dist/utils/version.ts +0 -12
- package/dist/validateNonInterActiveAuth.test.ts +0 -260
- package/dist/validateNonInterActiveAuth.ts +0 -51
- package/dist/vitest.config.ts +0 -37
- package/dist/zed-integration/acp.ts +0 -366
- package/dist/zed-integration/fileSystemService.ts +0 -47
- package/dist/zed-integration/schema.ts +0 -466
- package/dist/zed-integration/zedIntegration.ts +0 -944
|
@@ -1,753 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, { useState, useEffect } from 'react';
|
|
8
|
-
import { Box, Text } from 'ink';
|
|
9
|
-
import { Colors } from '../colors.js';
|
|
10
|
-
import {
|
|
11
|
-
LoadedSettings,
|
|
12
|
-
SettingScope,
|
|
13
|
-
Settings,
|
|
14
|
-
} from '../../config/settings.js';
|
|
15
|
-
import {
|
|
16
|
-
getScopeItems,
|
|
17
|
-
getScopeMessageForSetting,
|
|
18
|
-
} from '../../utils/dialogScopeUtils.js';
|
|
19
|
-
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
|
|
20
|
-
import {
|
|
21
|
-
getDialogSettingKeys,
|
|
22
|
-
getSettingValue,
|
|
23
|
-
setPendingSettingValue,
|
|
24
|
-
getDisplayValue,
|
|
25
|
-
hasRestartRequiredSettings,
|
|
26
|
-
saveModifiedSettings,
|
|
27
|
-
getSettingDefinition,
|
|
28
|
-
isDefaultValue,
|
|
29
|
-
requiresRestart,
|
|
30
|
-
getRestartRequiredFromModified,
|
|
31
|
-
getDefaultValue,
|
|
32
|
-
setPendingSettingValueAny,
|
|
33
|
-
getNestedValue,
|
|
34
|
-
} from '../../utils/settingsUtils.js';
|
|
35
|
-
import { useVimMode } from '../contexts/VimModeContext.js';
|
|
36
|
-
import { useKeypress } from '../hooks/useKeypress.js';
|
|
37
|
-
import chalk from 'chalk';
|
|
38
|
-
import { cpSlice, cpLen } from '../utils/textUtils.js';
|
|
39
|
-
|
|
40
|
-
interface SettingsDialogProps {
|
|
41
|
-
settings: LoadedSettings;
|
|
42
|
-
onSelect: (settingName: string | undefined, scope: SettingScope) => void;
|
|
43
|
-
onRestartRequest?: () => void;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const maxItemsToShow = 8;
|
|
47
|
-
|
|
48
|
-
export function SettingsDialog({
|
|
49
|
-
settings,
|
|
50
|
-
onSelect,
|
|
51
|
-
onRestartRequest,
|
|
52
|
-
}: SettingsDialogProps): React.JSX.Element {
|
|
53
|
-
// Get vim mode context to sync vim mode changes
|
|
54
|
-
const { vimEnabled, toggleVimEnabled } = useVimMode();
|
|
55
|
-
|
|
56
|
-
// Focus state: 'settings' or 'scope'
|
|
57
|
-
const [focusSection, setFocusSection] = useState<'settings' | 'scope'>(
|
|
58
|
-
'settings',
|
|
59
|
-
);
|
|
60
|
-
// Scope selector state (User by default)
|
|
61
|
-
const [selectedScope, setSelectedScope] = useState<SettingScope>(
|
|
62
|
-
SettingScope.User,
|
|
63
|
-
);
|
|
64
|
-
// Active indices
|
|
65
|
-
const [activeSettingIndex, setActiveSettingIndex] = useState(0);
|
|
66
|
-
// Scroll offset for settings
|
|
67
|
-
const [scrollOffset, setScrollOffset] = useState(0);
|
|
68
|
-
const [showRestartPrompt, setShowRestartPrompt] = useState(false);
|
|
69
|
-
|
|
70
|
-
// Local pending settings state for the selected scope
|
|
71
|
-
const [pendingSettings, setPendingSettings] = useState<Settings>(() =>
|
|
72
|
-
// Deep clone to avoid mutation
|
|
73
|
-
structuredClone(settings.forScope(selectedScope).settings),
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
// Track which settings have been modified by the user
|
|
77
|
-
const [modifiedSettings, setModifiedSettings] = useState<Set<string>>(
|
|
78
|
-
new Set(),
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
// Preserve pending changes across scope switches (boolean and number values only)
|
|
82
|
-
type PendingValue = boolean | number;
|
|
83
|
-
const [globalPendingChanges, setGlobalPendingChanges] = useState<
|
|
84
|
-
Map<string, PendingValue>
|
|
85
|
-
>(new Map());
|
|
86
|
-
|
|
87
|
-
// Track restart-required settings across scope changes
|
|
88
|
-
const [_restartRequiredSettings, setRestartRequiredSettings] = useState<
|
|
89
|
-
Set<string>
|
|
90
|
-
>(new Set());
|
|
91
|
-
|
|
92
|
-
useEffect(() => {
|
|
93
|
-
// Base settings for selected scope
|
|
94
|
-
let updated = structuredClone(settings.forScope(selectedScope).settings);
|
|
95
|
-
// Overlay globally pending (unsaved) changes so user sees their modifications in any scope
|
|
96
|
-
const newModified = new Set<string>();
|
|
97
|
-
const newRestartRequired = new Set<string>();
|
|
98
|
-
for (const [key, value] of globalPendingChanges.entries()) {
|
|
99
|
-
const def = getSettingDefinition(key);
|
|
100
|
-
if (def?.type === 'boolean' && typeof value === 'boolean') {
|
|
101
|
-
updated = setPendingSettingValue(key, value, updated);
|
|
102
|
-
} else if (def?.type === 'number' && typeof value === 'number') {
|
|
103
|
-
updated = setPendingSettingValueAny(key, value, updated);
|
|
104
|
-
}
|
|
105
|
-
newModified.add(key);
|
|
106
|
-
if (requiresRestart(key)) newRestartRequired.add(key);
|
|
107
|
-
}
|
|
108
|
-
setPendingSettings(updated);
|
|
109
|
-
setModifiedSettings(newModified);
|
|
110
|
-
setRestartRequiredSettings(newRestartRequired);
|
|
111
|
-
setShowRestartPrompt(newRestartRequired.size > 0);
|
|
112
|
-
}, [selectedScope, settings, globalPendingChanges]);
|
|
113
|
-
|
|
114
|
-
const generateSettingsItems = () => {
|
|
115
|
-
const settingKeys = getDialogSettingKeys();
|
|
116
|
-
|
|
117
|
-
return settingKeys.map((key: string) => {
|
|
118
|
-
const definition = getSettingDefinition(key);
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
label: definition?.label || key,
|
|
122
|
-
value: key,
|
|
123
|
-
type: definition?.type,
|
|
124
|
-
toggle: () => {
|
|
125
|
-
if (definition?.type !== 'boolean') {
|
|
126
|
-
// For non-boolean (e.g., number) items, toggle will be handled via edit mode.
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
const currentValue = getSettingValue(key, pendingSettings, {});
|
|
130
|
-
const newValue = !currentValue;
|
|
131
|
-
|
|
132
|
-
setPendingSettings((prev) =>
|
|
133
|
-
setPendingSettingValue(key, newValue, prev),
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
if (!requiresRestart(key)) {
|
|
137
|
-
const immediateSettings = new Set([key]);
|
|
138
|
-
const immediateSettingsObject = setPendingSettingValueAny(
|
|
139
|
-
key,
|
|
140
|
-
newValue,
|
|
141
|
-
{} as Settings,
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
console.log(
|
|
145
|
-
`[DEBUG SettingsDialog] Saving ${key} immediately with value:`,
|
|
146
|
-
newValue,
|
|
147
|
-
);
|
|
148
|
-
saveModifiedSettings(
|
|
149
|
-
immediateSettings,
|
|
150
|
-
immediateSettingsObject,
|
|
151
|
-
settings,
|
|
152
|
-
selectedScope,
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
// Special handling for vim mode to sync with VimModeContext
|
|
156
|
-
if (key === 'vimMode' && newValue !== vimEnabled) {
|
|
157
|
-
// Call toggleVimEnabled to sync the VimModeContext local state
|
|
158
|
-
toggleVimEnabled().catch((error) => {
|
|
159
|
-
console.error('Failed to toggle vim mode:', error);
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Remove from modifiedSettings since it's now saved
|
|
164
|
-
setModifiedSettings((prev) => {
|
|
165
|
-
const updated = new Set(prev);
|
|
166
|
-
updated.delete(key);
|
|
167
|
-
return updated;
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// Also remove from restart-required settings if it was there
|
|
171
|
-
setRestartRequiredSettings((prev) => {
|
|
172
|
-
const updated = new Set(prev);
|
|
173
|
-
updated.delete(key);
|
|
174
|
-
return updated;
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
// Remove from global pending changes if present
|
|
178
|
-
setGlobalPendingChanges((prev) => {
|
|
179
|
-
if (!prev.has(key)) return prev;
|
|
180
|
-
const next = new Map(prev);
|
|
181
|
-
next.delete(key);
|
|
182
|
-
return next;
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
// Refresh pending settings from the saved state
|
|
186
|
-
setPendingSettings(
|
|
187
|
-
structuredClone(settings.forScope(selectedScope).settings),
|
|
188
|
-
);
|
|
189
|
-
} else {
|
|
190
|
-
// For restart-required settings, track as modified
|
|
191
|
-
setModifiedSettings((prev) => {
|
|
192
|
-
const updated = new Set(prev).add(key);
|
|
193
|
-
const needsRestart = hasRestartRequiredSettings(updated);
|
|
194
|
-
console.log(
|
|
195
|
-
`[DEBUG SettingsDialog] Modified settings:`,
|
|
196
|
-
Array.from(updated),
|
|
197
|
-
'Needs restart:',
|
|
198
|
-
needsRestart,
|
|
199
|
-
);
|
|
200
|
-
if (needsRestart) {
|
|
201
|
-
setShowRestartPrompt(true);
|
|
202
|
-
setRestartRequiredSettings((prevRestart) =>
|
|
203
|
-
new Set(prevRestart).add(key),
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
return updated;
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
// Add/update pending change globally so it persists across scopes
|
|
210
|
-
setGlobalPendingChanges((prev) => {
|
|
211
|
-
const next = new Map(prev);
|
|
212
|
-
next.set(key, newValue as PendingValue);
|
|
213
|
-
return next;
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
};
|
|
218
|
-
});
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
const items = generateSettingsItems();
|
|
222
|
-
|
|
223
|
-
// Number edit state
|
|
224
|
-
const [editingKey, setEditingKey] = useState<string | null>(null);
|
|
225
|
-
const [editBuffer, setEditBuffer] = useState<string>('');
|
|
226
|
-
const [editCursorPos, setEditCursorPos] = useState<number>(0); // Cursor position within edit buffer
|
|
227
|
-
const [cursorVisible, setCursorVisible] = useState<boolean>(true);
|
|
228
|
-
|
|
229
|
-
useEffect(() => {
|
|
230
|
-
if (!editingKey) {
|
|
231
|
-
setCursorVisible(true);
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
const id = setInterval(() => setCursorVisible((v) => !v), 500);
|
|
235
|
-
return () => clearInterval(id);
|
|
236
|
-
}, [editingKey]);
|
|
237
|
-
|
|
238
|
-
const startEditingNumber = (key: string, initial?: string) => {
|
|
239
|
-
setEditingKey(key);
|
|
240
|
-
const initialValue = initial ?? '';
|
|
241
|
-
setEditBuffer(initialValue);
|
|
242
|
-
setEditCursorPos(cpLen(initialValue)); // Position cursor at end of initial value
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
const commitNumberEdit = (key: string) => {
|
|
246
|
-
if (editBuffer.trim() === '') {
|
|
247
|
-
// Nothing entered; cancel edit
|
|
248
|
-
setEditingKey(null);
|
|
249
|
-
setEditBuffer('');
|
|
250
|
-
setEditCursorPos(0);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
const parsed = Number(editBuffer.trim());
|
|
254
|
-
if (Number.isNaN(parsed)) {
|
|
255
|
-
// Invalid number; cancel edit
|
|
256
|
-
setEditingKey(null);
|
|
257
|
-
setEditBuffer('');
|
|
258
|
-
setEditCursorPos(0);
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Update pending
|
|
263
|
-
setPendingSettings((prev) => setPendingSettingValueAny(key, parsed, prev));
|
|
264
|
-
|
|
265
|
-
if (!requiresRestart(key)) {
|
|
266
|
-
const immediateSettings = new Set([key]);
|
|
267
|
-
const immediateSettingsObject = setPendingSettingValueAny(
|
|
268
|
-
key,
|
|
269
|
-
parsed,
|
|
270
|
-
{} as Settings,
|
|
271
|
-
);
|
|
272
|
-
saveModifiedSettings(
|
|
273
|
-
immediateSettings,
|
|
274
|
-
immediateSettingsObject,
|
|
275
|
-
settings,
|
|
276
|
-
selectedScope,
|
|
277
|
-
);
|
|
278
|
-
|
|
279
|
-
// Remove from modified sets if present
|
|
280
|
-
setModifiedSettings((prev) => {
|
|
281
|
-
const updated = new Set(prev);
|
|
282
|
-
updated.delete(key);
|
|
283
|
-
return updated;
|
|
284
|
-
});
|
|
285
|
-
setRestartRequiredSettings((prev) => {
|
|
286
|
-
const updated = new Set(prev);
|
|
287
|
-
updated.delete(key);
|
|
288
|
-
return updated;
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
// Remove from global pending since it's immediately saved
|
|
292
|
-
setGlobalPendingChanges((prev) => {
|
|
293
|
-
if (!prev.has(key)) return prev;
|
|
294
|
-
const next = new Map(prev);
|
|
295
|
-
next.delete(key);
|
|
296
|
-
return next;
|
|
297
|
-
});
|
|
298
|
-
} else {
|
|
299
|
-
// Mark as modified and needing restart
|
|
300
|
-
setModifiedSettings((prev) => {
|
|
301
|
-
const updated = new Set(prev).add(key);
|
|
302
|
-
const needsRestart = hasRestartRequiredSettings(updated);
|
|
303
|
-
if (needsRestart) {
|
|
304
|
-
setShowRestartPrompt(true);
|
|
305
|
-
setRestartRequiredSettings((prevRestart) =>
|
|
306
|
-
new Set(prevRestart).add(key),
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
return updated;
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
// Record pending change globally for persistence across scopes
|
|
313
|
-
setGlobalPendingChanges((prev) => {
|
|
314
|
-
const next = new Map(prev);
|
|
315
|
-
next.set(key, parsed as PendingValue);
|
|
316
|
-
return next;
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
setEditingKey(null);
|
|
321
|
-
setEditBuffer('');
|
|
322
|
-
setEditCursorPos(0);
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
// Scope selector items
|
|
326
|
-
const scopeItems = getScopeItems();
|
|
327
|
-
|
|
328
|
-
const handleScopeHighlight = (scope: SettingScope) => {
|
|
329
|
-
setSelectedScope(scope);
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
const handleScopeSelect = (scope: SettingScope) => {
|
|
333
|
-
handleScopeHighlight(scope);
|
|
334
|
-
setFocusSection('settings');
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
// Scroll logic for settings
|
|
338
|
-
const visibleItems = items.slice(scrollOffset, scrollOffset + maxItemsToShow);
|
|
339
|
-
// Always show arrows for consistent UI and to indicate circular navigation
|
|
340
|
-
const showScrollUp = true;
|
|
341
|
-
const showScrollDown = true;
|
|
342
|
-
|
|
343
|
-
useKeypress(
|
|
344
|
-
(key) => {
|
|
345
|
-
const { name, ctrl } = key;
|
|
346
|
-
if (name === 'tab') {
|
|
347
|
-
setFocusSection((prev) => (prev === 'settings' ? 'scope' : 'settings'));
|
|
348
|
-
}
|
|
349
|
-
if (focusSection === 'settings') {
|
|
350
|
-
// If editing a number, capture numeric input and control keys
|
|
351
|
-
if (editingKey) {
|
|
352
|
-
if (key.paste && key.sequence) {
|
|
353
|
-
const pasted = key.sequence.replace(/[^0-9\-+.]/g, '');
|
|
354
|
-
if (pasted) {
|
|
355
|
-
setEditBuffer((b) => {
|
|
356
|
-
const before = cpSlice(b, 0, editCursorPos);
|
|
357
|
-
const after = cpSlice(b, editCursorPos);
|
|
358
|
-
return before + pasted + after;
|
|
359
|
-
});
|
|
360
|
-
setEditCursorPos((pos) => pos + cpLen(pasted));
|
|
361
|
-
}
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
if (name === 'backspace' || name === 'delete') {
|
|
365
|
-
if (name === 'backspace' && editCursorPos > 0) {
|
|
366
|
-
setEditBuffer((b) => {
|
|
367
|
-
const before = cpSlice(b, 0, editCursorPos - 1);
|
|
368
|
-
const after = cpSlice(b, editCursorPos);
|
|
369
|
-
return before + after;
|
|
370
|
-
});
|
|
371
|
-
setEditCursorPos((pos) => pos - 1);
|
|
372
|
-
} else if (name === 'delete' && editCursorPos < cpLen(editBuffer)) {
|
|
373
|
-
setEditBuffer((b) => {
|
|
374
|
-
const before = cpSlice(b, 0, editCursorPos);
|
|
375
|
-
const after = cpSlice(b, editCursorPos + 1);
|
|
376
|
-
return before + after;
|
|
377
|
-
});
|
|
378
|
-
// Cursor position stays the same for delete
|
|
379
|
-
}
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
if (name === 'escape') {
|
|
383
|
-
commitNumberEdit(editingKey);
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
if (name === 'return') {
|
|
387
|
-
commitNumberEdit(editingKey);
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
// Allow digits, minus, plus, and dot
|
|
391
|
-
const ch = key.sequence;
|
|
392
|
-
if (/[0-9\-+.]/.test(ch)) {
|
|
393
|
-
setEditBuffer((currentBuffer) => {
|
|
394
|
-
const beforeCursor = cpSlice(currentBuffer, 0, editCursorPos);
|
|
395
|
-
const afterCursor = cpSlice(currentBuffer, editCursorPos);
|
|
396
|
-
return beforeCursor + ch + afterCursor;
|
|
397
|
-
});
|
|
398
|
-
setEditCursorPos((pos) => pos + 1);
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
// Arrow key navigation
|
|
402
|
-
if (name === 'left') {
|
|
403
|
-
setEditCursorPos((pos) => Math.max(0, pos - 1));
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
if (name === 'right') {
|
|
407
|
-
setEditCursorPos((pos) => Math.min(cpLen(editBuffer), pos + 1));
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
// Home and End keys
|
|
411
|
-
if (name === 'home') {
|
|
412
|
-
setEditCursorPos(0);
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
if (name === 'end') {
|
|
416
|
-
setEditCursorPos(cpLen(editBuffer));
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
// Block other keys while editing
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
if (name === 'up' || name === 'k') {
|
|
423
|
-
// If editing, commit first
|
|
424
|
-
if (editingKey) {
|
|
425
|
-
commitNumberEdit(editingKey);
|
|
426
|
-
}
|
|
427
|
-
const newIndex =
|
|
428
|
-
activeSettingIndex > 0 ? activeSettingIndex - 1 : items.length - 1;
|
|
429
|
-
setActiveSettingIndex(newIndex);
|
|
430
|
-
// Adjust scroll offset for wrap-around
|
|
431
|
-
if (newIndex === items.length - 1) {
|
|
432
|
-
setScrollOffset(Math.max(0, items.length - maxItemsToShow));
|
|
433
|
-
} else if (newIndex < scrollOffset) {
|
|
434
|
-
setScrollOffset(newIndex);
|
|
435
|
-
}
|
|
436
|
-
} else if (name === 'down' || name === 'j') {
|
|
437
|
-
// If editing, commit first
|
|
438
|
-
if (editingKey) {
|
|
439
|
-
commitNumberEdit(editingKey);
|
|
440
|
-
}
|
|
441
|
-
const newIndex =
|
|
442
|
-
activeSettingIndex < items.length - 1 ? activeSettingIndex + 1 : 0;
|
|
443
|
-
setActiveSettingIndex(newIndex);
|
|
444
|
-
// Adjust scroll offset for wrap-around
|
|
445
|
-
if (newIndex === 0) {
|
|
446
|
-
setScrollOffset(0);
|
|
447
|
-
} else if (newIndex >= scrollOffset + maxItemsToShow) {
|
|
448
|
-
setScrollOffset(newIndex - maxItemsToShow + 1);
|
|
449
|
-
}
|
|
450
|
-
} else if (name === 'return' || name === 'space') {
|
|
451
|
-
const currentItem = items[activeSettingIndex];
|
|
452
|
-
if (currentItem?.type === 'number') {
|
|
453
|
-
startEditingNumber(currentItem.value);
|
|
454
|
-
} else {
|
|
455
|
-
currentItem?.toggle();
|
|
456
|
-
}
|
|
457
|
-
} else if (/^[0-9]$/.test(key.sequence || '') && !editingKey) {
|
|
458
|
-
const currentItem = items[activeSettingIndex];
|
|
459
|
-
if (currentItem?.type === 'number') {
|
|
460
|
-
startEditingNumber(currentItem.value, key.sequence);
|
|
461
|
-
}
|
|
462
|
-
} else if (ctrl && (name === 'c' || name === 'l')) {
|
|
463
|
-
// Ctrl+C or Ctrl+L: Clear current setting and reset to default
|
|
464
|
-
const currentSetting = items[activeSettingIndex];
|
|
465
|
-
if (currentSetting) {
|
|
466
|
-
const defaultValue = getDefaultValue(currentSetting.value);
|
|
467
|
-
const defType = currentSetting.type;
|
|
468
|
-
if (defType === 'boolean') {
|
|
469
|
-
const booleanDefaultValue =
|
|
470
|
-
typeof defaultValue === 'boolean' ? defaultValue : false;
|
|
471
|
-
setPendingSettings((prev) =>
|
|
472
|
-
setPendingSettingValue(
|
|
473
|
-
currentSetting.value,
|
|
474
|
-
booleanDefaultValue,
|
|
475
|
-
prev,
|
|
476
|
-
),
|
|
477
|
-
);
|
|
478
|
-
} else if (defType === 'number') {
|
|
479
|
-
if (typeof defaultValue === 'number') {
|
|
480
|
-
setPendingSettings((prev) =>
|
|
481
|
-
setPendingSettingValueAny(
|
|
482
|
-
currentSetting.value,
|
|
483
|
-
defaultValue,
|
|
484
|
-
prev,
|
|
485
|
-
),
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Remove from modified settings since it's now at default
|
|
491
|
-
setModifiedSettings((prev) => {
|
|
492
|
-
const updated = new Set(prev);
|
|
493
|
-
updated.delete(currentSetting.value);
|
|
494
|
-
return updated;
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
// Remove from restart-required settings if it was there
|
|
498
|
-
setRestartRequiredSettings((prev) => {
|
|
499
|
-
const updated = new Set(prev);
|
|
500
|
-
updated.delete(currentSetting.value);
|
|
501
|
-
return updated;
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
// If this setting doesn't require restart, save it immediately
|
|
505
|
-
if (!requiresRestart(currentSetting.value)) {
|
|
506
|
-
const immediateSettings = new Set([currentSetting.value]);
|
|
507
|
-
const toSaveValue =
|
|
508
|
-
currentSetting.type === 'boolean'
|
|
509
|
-
? typeof defaultValue === 'boolean'
|
|
510
|
-
? defaultValue
|
|
511
|
-
: false
|
|
512
|
-
: typeof defaultValue === 'number'
|
|
513
|
-
? defaultValue
|
|
514
|
-
: undefined;
|
|
515
|
-
const immediateSettingsObject =
|
|
516
|
-
toSaveValue !== undefined
|
|
517
|
-
? setPendingSettingValueAny(
|
|
518
|
-
currentSetting.value,
|
|
519
|
-
toSaveValue,
|
|
520
|
-
{} as Settings,
|
|
521
|
-
)
|
|
522
|
-
: ({} as Settings);
|
|
523
|
-
|
|
524
|
-
saveModifiedSettings(
|
|
525
|
-
immediateSettings,
|
|
526
|
-
immediateSettingsObject,
|
|
527
|
-
settings,
|
|
528
|
-
selectedScope,
|
|
529
|
-
);
|
|
530
|
-
|
|
531
|
-
// Remove from global pending changes if present
|
|
532
|
-
setGlobalPendingChanges((prev) => {
|
|
533
|
-
if (!prev.has(currentSetting.value)) return prev;
|
|
534
|
-
const next = new Map(prev);
|
|
535
|
-
next.delete(currentSetting.value);
|
|
536
|
-
return next;
|
|
537
|
-
});
|
|
538
|
-
} else {
|
|
539
|
-
// Track default reset as a pending change if restart required
|
|
540
|
-
if (
|
|
541
|
-
(currentSetting.type === 'boolean' &&
|
|
542
|
-
typeof defaultValue === 'boolean') ||
|
|
543
|
-
(currentSetting.type === 'number' &&
|
|
544
|
-
typeof defaultValue === 'number')
|
|
545
|
-
) {
|
|
546
|
-
setGlobalPendingChanges((prev) => {
|
|
547
|
-
const next = new Map(prev);
|
|
548
|
-
next.set(currentSetting.value, defaultValue as PendingValue);
|
|
549
|
-
return next;
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
if (showRestartPrompt && name === 'r') {
|
|
557
|
-
// Only save settings that require restart (non-restart settings were already saved immediately)
|
|
558
|
-
const restartRequiredSettings =
|
|
559
|
-
getRestartRequiredFromModified(modifiedSettings);
|
|
560
|
-
const restartRequiredSet = new Set(restartRequiredSettings);
|
|
561
|
-
|
|
562
|
-
if (restartRequiredSet.size > 0) {
|
|
563
|
-
saveModifiedSettings(
|
|
564
|
-
restartRequiredSet,
|
|
565
|
-
pendingSettings,
|
|
566
|
-
settings,
|
|
567
|
-
selectedScope,
|
|
568
|
-
);
|
|
569
|
-
|
|
570
|
-
// Remove saved keys from global pending changes
|
|
571
|
-
setGlobalPendingChanges((prev) => {
|
|
572
|
-
if (prev.size === 0) return prev;
|
|
573
|
-
const next = new Map(prev);
|
|
574
|
-
for (const key of restartRequiredSet) {
|
|
575
|
-
next.delete(key);
|
|
576
|
-
}
|
|
577
|
-
return next;
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
setShowRestartPrompt(false);
|
|
582
|
-
setRestartRequiredSettings(new Set()); // Clear restart-required settings
|
|
583
|
-
if (onRestartRequest) onRestartRequest();
|
|
584
|
-
}
|
|
585
|
-
if (name === 'escape') {
|
|
586
|
-
if (editingKey) {
|
|
587
|
-
commitNumberEdit(editingKey);
|
|
588
|
-
} else {
|
|
589
|
-
onSelect(undefined, selectedScope);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
},
|
|
593
|
-
{ isActive: true },
|
|
594
|
-
);
|
|
595
|
-
|
|
596
|
-
return (
|
|
597
|
-
<Box
|
|
598
|
-
borderStyle="round"
|
|
599
|
-
borderColor={Colors.Gray}
|
|
600
|
-
flexDirection="row"
|
|
601
|
-
padding={1}
|
|
602
|
-
width="100%"
|
|
603
|
-
height="100%"
|
|
604
|
-
>
|
|
605
|
-
<Box flexDirection="column" flexGrow={1}>
|
|
606
|
-
<Text bold color={Colors.AccentBlue}>
|
|
607
|
-
Settings
|
|
608
|
-
</Text>
|
|
609
|
-
<Box height={1} />
|
|
610
|
-
{showScrollUp && <Text color={Colors.Gray}>▲</Text>}
|
|
611
|
-
{visibleItems.map((item, idx) => {
|
|
612
|
-
const isActive =
|
|
613
|
-
focusSection === 'settings' &&
|
|
614
|
-
activeSettingIndex === idx + scrollOffset;
|
|
615
|
-
|
|
616
|
-
const scopeSettings = settings.forScope(selectedScope).settings;
|
|
617
|
-
const mergedSettings = settings.merged;
|
|
618
|
-
|
|
619
|
-
let displayValue: string;
|
|
620
|
-
if (editingKey === item.value) {
|
|
621
|
-
// Show edit buffer with advanced cursor highlighting
|
|
622
|
-
if (cursorVisible && editCursorPos < cpLen(editBuffer)) {
|
|
623
|
-
// Cursor is in the middle or at start of text
|
|
624
|
-
const beforeCursor = cpSlice(editBuffer, 0, editCursorPos);
|
|
625
|
-
const atCursor = cpSlice(
|
|
626
|
-
editBuffer,
|
|
627
|
-
editCursorPos,
|
|
628
|
-
editCursorPos + 1,
|
|
629
|
-
);
|
|
630
|
-
const afterCursor = cpSlice(editBuffer, editCursorPos + 1);
|
|
631
|
-
displayValue =
|
|
632
|
-
beforeCursor + chalk.inverse(atCursor) + afterCursor;
|
|
633
|
-
} else if (cursorVisible && editCursorPos >= cpLen(editBuffer)) {
|
|
634
|
-
// Cursor is at the end - show inverted space
|
|
635
|
-
displayValue = editBuffer + chalk.inverse(' ');
|
|
636
|
-
} else {
|
|
637
|
-
// Cursor not visible
|
|
638
|
-
displayValue = editBuffer;
|
|
639
|
-
}
|
|
640
|
-
} else if (item.type === 'number') {
|
|
641
|
-
// For numbers, get the actual current value from pending settings
|
|
642
|
-
const path = item.value.split('.');
|
|
643
|
-
const currentValue = getNestedValue(pendingSettings, path);
|
|
644
|
-
|
|
645
|
-
const defaultValue = getDefaultValue(item.value);
|
|
646
|
-
|
|
647
|
-
if (currentValue !== undefined && currentValue !== null) {
|
|
648
|
-
displayValue = String(currentValue);
|
|
649
|
-
} else {
|
|
650
|
-
displayValue =
|
|
651
|
-
defaultValue !== undefined && defaultValue !== null
|
|
652
|
-
? String(defaultValue)
|
|
653
|
-
: '';
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// Add * if value differs from default OR if currently being modified
|
|
657
|
-
const isModified = modifiedSettings.has(item.value);
|
|
658
|
-
const effectiveCurrentValue =
|
|
659
|
-
currentValue !== undefined && currentValue !== null
|
|
660
|
-
? currentValue
|
|
661
|
-
: defaultValue;
|
|
662
|
-
const isDifferentFromDefault =
|
|
663
|
-
effectiveCurrentValue !== defaultValue;
|
|
664
|
-
|
|
665
|
-
if (isDifferentFromDefault || isModified) {
|
|
666
|
-
displayValue += '*';
|
|
667
|
-
}
|
|
668
|
-
} else {
|
|
669
|
-
// For booleans and other types, use existing logic
|
|
670
|
-
displayValue = getDisplayValue(
|
|
671
|
-
item.value,
|
|
672
|
-
scopeSettings,
|
|
673
|
-
mergedSettings,
|
|
674
|
-
modifiedSettings,
|
|
675
|
-
pendingSettings,
|
|
676
|
-
);
|
|
677
|
-
}
|
|
678
|
-
const shouldBeGreyedOut = isDefaultValue(item.value, scopeSettings);
|
|
679
|
-
|
|
680
|
-
// Generate scope message for this setting
|
|
681
|
-
const scopeMessage = getScopeMessageForSetting(
|
|
682
|
-
item.value,
|
|
683
|
-
selectedScope,
|
|
684
|
-
settings,
|
|
685
|
-
);
|
|
686
|
-
|
|
687
|
-
return (
|
|
688
|
-
<React.Fragment key={item.value}>
|
|
689
|
-
<Box flexDirection="row" alignItems="center">
|
|
690
|
-
<Box minWidth={2} flexShrink={0}>
|
|
691
|
-
<Text color={isActive ? Colors.AccentGreen : Colors.Gray}>
|
|
692
|
-
{isActive ? '●' : ''}
|
|
693
|
-
</Text>
|
|
694
|
-
</Box>
|
|
695
|
-
<Box minWidth={50}>
|
|
696
|
-
<Text
|
|
697
|
-
color={isActive ? Colors.AccentGreen : Colors.Foreground}
|
|
698
|
-
>
|
|
699
|
-
{item.label}
|
|
700
|
-
{scopeMessage && (
|
|
701
|
-
<Text color={Colors.Gray}> {scopeMessage}</Text>
|
|
702
|
-
)}
|
|
703
|
-
</Text>
|
|
704
|
-
</Box>
|
|
705
|
-
<Box minWidth={3} />
|
|
706
|
-
<Text
|
|
707
|
-
color={
|
|
708
|
-
isActive
|
|
709
|
-
? Colors.AccentGreen
|
|
710
|
-
: shouldBeGreyedOut
|
|
711
|
-
? Colors.Gray
|
|
712
|
-
: Colors.Foreground
|
|
713
|
-
}
|
|
714
|
-
>
|
|
715
|
-
{displayValue}
|
|
716
|
-
</Text>
|
|
717
|
-
</Box>
|
|
718
|
-
<Box height={1} />
|
|
719
|
-
</React.Fragment>
|
|
720
|
-
);
|
|
721
|
-
})}
|
|
722
|
-
{showScrollDown && <Text color={Colors.Gray}>▼</Text>}
|
|
723
|
-
|
|
724
|
-
<Box height={1} />
|
|
725
|
-
|
|
726
|
-
<Box marginTop={1} flexDirection="column">
|
|
727
|
-
<Text bold={focusSection === 'scope'} wrap="truncate">
|
|
728
|
-
{focusSection === 'scope' ? '> ' : ' '}Apply To
|
|
729
|
-
</Text>
|
|
730
|
-
<RadioButtonSelect
|
|
731
|
-
items={scopeItems}
|
|
732
|
-
initialIndex={0}
|
|
733
|
-
onSelect={handleScopeSelect}
|
|
734
|
-
onHighlight={handleScopeHighlight}
|
|
735
|
-
isFocused={focusSection === 'scope'}
|
|
736
|
-
showNumbers={focusSection === 'scope'}
|
|
737
|
-
/>
|
|
738
|
-
</Box>
|
|
739
|
-
|
|
740
|
-
<Box height={1} />
|
|
741
|
-
<Text color={Colors.Gray}>
|
|
742
|
-
(Use Enter to select, Tab to change focus)
|
|
743
|
-
</Text>
|
|
744
|
-
{showRestartPrompt && (
|
|
745
|
-
<Text color={Colors.AccentYellow}>
|
|
746
|
-
To see changes, Gemini CLI must be restarted. Press r to exit and
|
|
747
|
-
apply changes now.
|
|
748
|
-
</Text>
|
|
749
|
-
)}
|
|
750
|
-
</Box>
|
|
751
|
-
</Box>
|
|
752
|
-
);
|
|
753
|
-
}
|