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
package/dist/ui/App.tsx
DELETED
|
@@ -1,1344 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { useCallback, useEffect, useMemo, useState, useRef } from 'react';
|
|
8
|
-
import {
|
|
9
|
-
Box,
|
|
10
|
-
DOMElement,
|
|
11
|
-
measureElement,
|
|
12
|
-
Static,
|
|
13
|
-
Text,
|
|
14
|
-
useStdin,
|
|
15
|
-
useStdout,
|
|
16
|
-
} from 'ink';
|
|
17
|
-
import { StreamingState, type HistoryItem, MessageType } from './types.js';
|
|
18
|
-
import { useTerminalSize } from './hooks/useTerminalSize.js';
|
|
19
|
-
import { useGeminiStream } from './hooks/useGeminiStream.js';
|
|
20
|
-
import { useLoadingIndicator } from './hooks/useLoadingIndicator.js';
|
|
21
|
-
import { useThemeCommand } from './hooks/useThemeCommand.js';
|
|
22
|
-
import { useAuthCommand } from './hooks/useAuthCommand.js';
|
|
23
|
-
import { useWelcomeBack } from './hooks/useWelcomeBack.js';
|
|
24
|
-
import { useFolderTrust } from './hooks/useFolderTrust.js';
|
|
25
|
-
import { useEditorSettings } from './hooks/useEditorSettings.js';
|
|
26
|
-
import { useSlashCommandProcessor } from './hooks/slashCommandProcessor.js';
|
|
27
|
-
import { useAutoAcceptIndicator } from './hooks/useAutoAcceptIndicator.js';
|
|
28
|
-
import { useMessageQueue } from './hooks/useMessageQueue.js';
|
|
29
|
-
import { useConsoleMessages } from './hooks/useConsoleMessages.js';
|
|
30
|
-
import { Header } from './components/Header.js';
|
|
31
|
-
import { LoadingIndicator } from './components/LoadingIndicator.js';
|
|
32
|
-
import { AutoAcceptIndicator } from './components/AutoAcceptIndicator.js';
|
|
33
|
-
import { ShellModeIndicator } from './components/ShellModeIndicator.js';
|
|
34
|
-
import { InputPrompt } from './components/InputPrompt.js';
|
|
35
|
-
import { Footer } from './components/Footer.js';
|
|
36
|
-
import { ThemeDialog } from './components/ThemeDialog.js';
|
|
37
|
-
import { AuthDialog } from './components/AuthDialog.js';
|
|
38
|
-
import { WelcomeBackDialog } from './components/WelcomeBackDialog.js';
|
|
39
|
-
import { SearchEngineConfigDialog } from './components/SearchEngineConfigDialog.js';
|
|
40
|
-
import { AuthInProgress } from './components/AuthInProgress.js';
|
|
41
|
-
import { EditorSettingsDialog } from './components/EditorSettingsDialog.js';
|
|
42
|
-
import { FolderTrustDialog } from './components/FolderTrustDialog.js';
|
|
43
|
-
import { ShellConfirmationDialog } from './components/ShellConfirmationDialog.js';
|
|
44
|
-
import { RadioButtonSelect } from './components/shared/RadioButtonSelect.js';
|
|
45
|
-
import { Colors } from './colors.js';
|
|
46
|
-
import { loadHierarchicalGeminiMemory } from '../config/config.js';
|
|
47
|
-
import { LoadedSettings, SettingScope } from '../config/settings.js';
|
|
48
|
-
import { Tips } from './components/Tips.js';
|
|
49
|
-
import { ConsolePatcher } from './utils/ConsolePatcher.js';
|
|
50
|
-
import { registerCleanup } from '../utils/cleanup.js';
|
|
51
|
-
import { DetailedMessagesDisplay } from './components/DetailedMessagesDisplay.js';
|
|
52
|
-
import { HistoryItemDisplay } from './components/HistoryItemDisplay.js';
|
|
53
|
-
import { ContextSummaryDisplay } from './components/ContextSummaryDisplay.js';
|
|
54
|
-
import { useHistory } from './hooks/useHistoryManager.js';
|
|
55
|
-
import process from 'node:process';
|
|
56
|
-
import {
|
|
57
|
-
getErrorMessage,
|
|
58
|
-
type Config,
|
|
59
|
-
getAllGeminiMdFilenames,
|
|
60
|
-
ApprovalMode,
|
|
61
|
-
isEditorAvailable,
|
|
62
|
-
EditorType,
|
|
63
|
-
FlashFallbackEvent,
|
|
64
|
-
logFlashFallback,
|
|
65
|
-
AuthType,
|
|
66
|
-
type IdeContext,
|
|
67
|
-
ideContext,
|
|
68
|
-
} from 'fss-link-core';
|
|
69
|
-
import {
|
|
70
|
-
IdeIntegrationNudge,
|
|
71
|
-
IdeIntegrationNudgeResult,
|
|
72
|
-
} from './IdeIntegrationNudge.js';
|
|
73
|
-
import { validateAuthMethod } from '../config/auth.js';
|
|
74
|
-
import { useLogger } from './hooks/useLogger.js';
|
|
75
|
-
import { StreamingContext } from './contexts/StreamingContext.js';
|
|
76
|
-
import {
|
|
77
|
-
SessionStatsProvider,
|
|
78
|
-
useSessionStats,
|
|
79
|
-
} from './contexts/SessionContext.js';
|
|
80
|
-
import { useGitBranchName } from './hooks/useGitBranchName.js';
|
|
81
|
-
import { useFocus } from './hooks/useFocus.js';
|
|
82
|
-
import { useBracketedPaste } from './hooks/useBracketedPaste.js';
|
|
83
|
-
import { useTextBuffer } from './components/shared/text-buffer.js';
|
|
84
|
-
import { useVimMode, VimModeProvider } from './contexts/VimModeContext.js';
|
|
85
|
-
import { useVim } from './hooks/vim.js';
|
|
86
|
-
import { useKeypress, Key } from './hooks/useKeypress.js';
|
|
87
|
-
import { KeypressProvider } from './contexts/KeypressContext.js';
|
|
88
|
-
import { useKittyKeyboardProtocol } from './hooks/useKittyKeyboardProtocol.js';
|
|
89
|
-
import { keyMatchers, Command } from './keyMatchers.js';
|
|
90
|
-
import * as fs from 'fs';
|
|
91
|
-
import { UpdateNotification } from './components/UpdateNotification.js';
|
|
92
|
-
import {
|
|
93
|
-
isProQuotaExceededError,
|
|
94
|
-
isGenericQuotaExceededError,
|
|
95
|
-
UserTierId,
|
|
96
|
-
} from 'fss-link-core';
|
|
97
|
-
import { UpdateObject } from './utils/updateCheck.js';
|
|
98
|
-
import ansiEscapes from 'ansi-escapes';
|
|
99
|
-
import { SearchEngineConfigProvider } from '../services/SearchEngineConfigProvider.js';
|
|
100
|
-
import { OverflowProvider } from './contexts/OverflowContext.js';
|
|
101
|
-
import { ShowMoreLines } from './components/ShowMoreLines.js';
|
|
102
|
-
import { PrivacyNotice } from './privacy/PrivacyNotice.js';
|
|
103
|
-
import { useSettingsCommand } from './hooks/useSettingsCommand.js';
|
|
104
|
-
import { SettingsDialog } from './components/SettingsDialog.js';
|
|
105
|
-
import { setUpdateHandler } from '../utils/handleAutoUpdate.js';
|
|
106
|
-
import { appEvents, AppEvent } from '../utils/events.js';
|
|
107
|
-
import { isNarrowWidth } from './utils/isNarrowWidth.js';
|
|
108
|
-
|
|
109
|
-
const CTRL_EXIT_PROMPT_DURATION_MS = 1000;
|
|
110
|
-
// Maximum number of queued messages to display in UI to prevent performance issues
|
|
111
|
-
const MAX_DISPLAYED_QUEUED_MESSAGES = 3;
|
|
112
|
-
|
|
113
|
-
interface AppProps {
|
|
114
|
-
config: Config;
|
|
115
|
-
settings: LoadedSettings;
|
|
116
|
-
startupWarnings?: string[];
|
|
117
|
-
version: string;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export const AppWrapper = (props: AppProps) => {
|
|
121
|
-
const kittyProtocolStatus = useKittyKeyboardProtocol();
|
|
122
|
-
return (
|
|
123
|
-
<KeypressProvider
|
|
124
|
-
kittyProtocolEnabled={kittyProtocolStatus.enabled}
|
|
125
|
-
config={props.config}
|
|
126
|
-
>
|
|
127
|
-
<SessionStatsProvider>
|
|
128
|
-
<VimModeProvider settings={props.settings}>
|
|
129
|
-
<App {...props} />
|
|
130
|
-
</VimModeProvider>
|
|
131
|
-
</SessionStatsProvider>
|
|
132
|
-
</KeypressProvider>
|
|
133
|
-
);
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
|
|
137
|
-
const isFocused = useFocus();
|
|
138
|
-
useBracketedPaste();
|
|
139
|
-
const [updateInfo, setUpdateInfo] = useState<UpdateObject | null>(null);
|
|
140
|
-
const { stdout } = useStdout();
|
|
141
|
-
const nightly = version.includes('nightly');
|
|
142
|
-
const { history, addItem, clearItems, loadHistory } = useHistory();
|
|
143
|
-
|
|
144
|
-
const [idePromptAnswered, setIdePromptAnswered] = useState(false);
|
|
145
|
-
const currentIDE = config.getIdeClient().getCurrentIde();
|
|
146
|
-
useEffect(() => {
|
|
147
|
-
registerCleanup(() => config.getIdeClient().disconnect());
|
|
148
|
-
}, [config]);
|
|
149
|
-
const shouldShowIdePrompt =
|
|
150
|
-
currentIDE &&
|
|
151
|
-
!config.getIdeMode() &&
|
|
152
|
-
!settings.merged.hasSeenIdeIntegrationNudge &&
|
|
153
|
-
!idePromptAnswered;
|
|
154
|
-
|
|
155
|
-
useEffect(() => {
|
|
156
|
-
const cleanup = setUpdateHandler(addItem, setUpdateInfo);
|
|
157
|
-
return cleanup;
|
|
158
|
-
}, [addItem]);
|
|
159
|
-
|
|
160
|
-
const {
|
|
161
|
-
consoleMessages,
|
|
162
|
-
handleNewMessage,
|
|
163
|
-
clearConsoleMessages: clearConsoleMessagesState,
|
|
164
|
-
} = useConsoleMessages();
|
|
165
|
-
|
|
166
|
-
useEffect(() => {
|
|
167
|
-
const consolePatcher = new ConsolePatcher({
|
|
168
|
-
onNewMessage: handleNewMessage,
|
|
169
|
-
debugMode: config.getDebugMode(),
|
|
170
|
-
});
|
|
171
|
-
consolePatcher.patch();
|
|
172
|
-
registerCleanup(consolePatcher.cleanup);
|
|
173
|
-
}, [handleNewMessage, config]);
|
|
174
|
-
|
|
175
|
-
const { stats: sessionStats } = useSessionStats();
|
|
176
|
-
const [staticNeedsRefresh, setStaticNeedsRefresh] = useState(false);
|
|
177
|
-
const [staticKey, setStaticKey] = useState(0);
|
|
178
|
-
const refreshStatic = useCallback(() => {
|
|
179
|
-
stdout.write(ansiEscapes.clearTerminal);
|
|
180
|
-
setStaticKey((prev) => prev + 1);
|
|
181
|
-
}, [setStaticKey, stdout]);
|
|
182
|
-
|
|
183
|
-
const [geminiMdFileCount, setGeminiMdFileCount] = useState<number>(0);
|
|
184
|
-
const [debugMessage, setDebugMessage] = useState<string>('');
|
|
185
|
-
const [themeError, setThemeError] = useState<string | null>(null);
|
|
186
|
-
const [authError, setAuthError] = useState<string | null>(null);
|
|
187
|
-
const [editorError, setEditorError] = useState<string | null>(null);
|
|
188
|
-
const [isSearchDialogOpen, setIsSearchDialogOpen] = useState<boolean>(false);
|
|
189
|
-
const [footerHeight, setFooterHeight] = useState<number>(0);
|
|
190
|
-
|
|
191
|
-
// Initialize search engine configuration from database
|
|
192
|
-
useEffect(() => {
|
|
193
|
-
const configProvider = SearchEngineConfigProvider.getInstance();
|
|
194
|
-
configProvider.loadConfiguration();
|
|
195
|
-
}, []);
|
|
196
|
-
const [corgiMode, setCorgiMode] = useState(false);
|
|
197
|
-
const [isTrustedFolderState, setIsTrustedFolder] = useState(
|
|
198
|
-
config.isTrustedFolder(),
|
|
199
|
-
);
|
|
200
|
-
const [currentModel, setCurrentModel] = useState(config.getModel());
|
|
201
|
-
const [shellModeActive, setShellModeActive] = useState(false);
|
|
202
|
-
const [showErrorDetails, setShowErrorDetails] = useState<boolean>(false);
|
|
203
|
-
const [showToolDescriptions, setShowToolDescriptions] =
|
|
204
|
-
useState<boolean>(false);
|
|
205
|
-
|
|
206
|
-
const [ctrlCPressedOnce, setCtrlCPressedOnce] = useState(false);
|
|
207
|
-
const [quittingMessages, setQuittingMessages] = useState<
|
|
208
|
-
HistoryItem[] | null
|
|
209
|
-
>(null);
|
|
210
|
-
const ctrlCTimerRef = useRef<NodeJS.Timeout | null>(null);
|
|
211
|
-
const [ctrlDPressedOnce, setCtrlDPressedOnce] = useState(false);
|
|
212
|
-
const ctrlDTimerRef = useRef<NodeJS.Timeout | null>(null);
|
|
213
|
-
const [constrainHeight, setConstrainHeight] = useState<boolean>(true);
|
|
214
|
-
const [showPrivacyNotice, setShowPrivacyNotice] = useState<boolean>(false);
|
|
215
|
-
const [modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError] =
|
|
216
|
-
useState<boolean>(false);
|
|
217
|
-
const [userTier, setUserTier] = useState<UserTierId | undefined>(undefined);
|
|
218
|
-
const [ideContextState, setIdeContextState] = useState<
|
|
219
|
-
IdeContext | undefined
|
|
220
|
-
>();
|
|
221
|
-
const [showEscapePrompt, setShowEscapePrompt] = useState(false);
|
|
222
|
-
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
|
223
|
-
|
|
224
|
-
useEffect(() => {
|
|
225
|
-
const unsubscribe = ideContext.subscribeToIdeContext(setIdeContextState);
|
|
226
|
-
// Set the initial value
|
|
227
|
-
setIdeContextState(ideContext.getIdeContext());
|
|
228
|
-
return unsubscribe;
|
|
229
|
-
}, []);
|
|
230
|
-
|
|
231
|
-
useEffect(() => {
|
|
232
|
-
const openDebugConsole = () => {
|
|
233
|
-
setShowErrorDetails(true);
|
|
234
|
-
setConstrainHeight(false); // Make sure the user sees the full message.
|
|
235
|
-
};
|
|
236
|
-
appEvents.on(AppEvent.OpenDebugConsole, openDebugConsole);
|
|
237
|
-
|
|
238
|
-
const logErrorHandler = (errorMessage: unknown) => {
|
|
239
|
-
handleNewMessage({
|
|
240
|
-
type: 'error',
|
|
241
|
-
content: String(errorMessage),
|
|
242
|
-
count: 1,
|
|
243
|
-
});
|
|
244
|
-
};
|
|
245
|
-
appEvents.on(AppEvent.LogError, logErrorHandler);
|
|
246
|
-
|
|
247
|
-
return () => {
|
|
248
|
-
appEvents.off(AppEvent.OpenDebugConsole, openDebugConsole);
|
|
249
|
-
appEvents.off(AppEvent.LogError, logErrorHandler);
|
|
250
|
-
};
|
|
251
|
-
}, [handleNewMessage]);
|
|
252
|
-
|
|
253
|
-
const openPrivacyNotice = useCallback(() => {
|
|
254
|
-
setShowPrivacyNotice(true);
|
|
255
|
-
}, []);
|
|
256
|
-
|
|
257
|
-
const handleEscapePromptChange = useCallback((showPrompt: boolean) => {
|
|
258
|
-
setShowEscapePrompt(showPrompt);
|
|
259
|
-
}, []);
|
|
260
|
-
|
|
261
|
-
const initialPromptSubmitted = useRef(false);
|
|
262
|
-
|
|
263
|
-
const errorCount = useMemo(
|
|
264
|
-
() =>
|
|
265
|
-
consoleMessages
|
|
266
|
-
.filter((msg) => msg.type === 'error')
|
|
267
|
-
.reduce((total, msg) => total + msg.count, 0),
|
|
268
|
-
[consoleMessages],
|
|
269
|
-
);
|
|
270
|
-
|
|
271
|
-
const {
|
|
272
|
-
isThemeDialogOpen,
|
|
273
|
-
openThemeDialog,
|
|
274
|
-
handleThemeSelect,
|
|
275
|
-
handleThemeHighlight,
|
|
276
|
-
} = useThemeCommand(settings, setThemeError, addItem);
|
|
277
|
-
|
|
278
|
-
const { isSettingsDialogOpen, openSettingsDialog, closeSettingsDialog } =
|
|
279
|
-
useSettingsCommand();
|
|
280
|
-
|
|
281
|
-
const { isFolderTrustDialogOpen, handleFolderTrustSelect } = useFolderTrust(
|
|
282
|
-
settings,
|
|
283
|
-
setIsTrustedFolder,
|
|
284
|
-
);
|
|
285
|
-
|
|
286
|
-
const {
|
|
287
|
-
isAuthDialogOpen,
|
|
288
|
-
openAuthDialog,
|
|
289
|
-
handleAuthSelect,
|
|
290
|
-
isAuthenticating,
|
|
291
|
-
cancelAuthentication,
|
|
292
|
-
} = useAuthCommand(settings, setAuthError, config);
|
|
293
|
-
|
|
294
|
-
const {
|
|
295
|
-
shouldShow: shouldShowWelcomeBack,
|
|
296
|
-
projectSummary,
|
|
297
|
-
contextToPopulate,
|
|
298
|
-
handleContinue: handleWelcomeBackContinue,
|
|
299
|
-
handleRestart: handleWelcomeBackRestart,
|
|
300
|
-
handleCancel: handleWelcomeBackCancel,
|
|
301
|
-
} = useWelcomeBack(settings);
|
|
302
|
-
|
|
303
|
-
useEffect(() => {
|
|
304
|
-
if (settings.merged.selectedAuthType && !settings.merged.useExternalAuth) {
|
|
305
|
-
const error = validateAuthMethod(settings.merged.selectedAuthType);
|
|
306
|
-
if (error) {
|
|
307
|
-
setAuthError(error);
|
|
308
|
-
openAuthDialog();
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}, [
|
|
312
|
-
settings.merged.selectedAuthType,
|
|
313
|
-
settings.merged.useExternalAuth,
|
|
314
|
-
openAuthDialog,
|
|
315
|
-
setAuthError,
|
|
316
|
-
]);
|
|
317
|
-
|
|
318
|
-
// Sync user tier from config when authentication changes
|
|
319
|
-
useEffect(() => {
|
|
320
|
-
// Only sync when not currently authenticating
|
|
321
|
-
if (!isAuthenticating) {
|
|
322
|
-
setUserTier(config.getGeminiClient()?.getUserTier());
|
|
323
|
-
}
|
|
324
|
-
}, [config, isAuthenticating]);
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const {
|
|
328
|
-
isEditorDialogOpen,
|
|
329
|
-
openEditorDialog,
|
|
330
|
-
handleEditorSelect,
|
|
331
|
-
exitEditorDialog,
|
|
332
|
-
} = useEditorSettings(settings, setEditorError, addItem);
|
|
333
|
-
|
|
334
|
-
const toggleCorgiMode = useCallback(() => {
|
|
335
|
-
setCorgiMode((prev) => !prev);
|
|
336
|
-
}, []);
|
|
337
|
-
|
|
338
|
-
const openSearchDialog = useCallback(() => {
|
|
339
|
-
setIsSearchDialogOpen(true);
|
|
340
|
-
}, []);
|
|
341
|
-
|
|
342
|
-
const performMemoryRefresh = useCallback(async () => {
|
|
343
|
-
addItem(
|
|
344
|
-
{
|
|
345
|
-
type: MessageType.INFO,
|
|
346
|
-
text: 'Refreshing hierarchical memory (LINK.md or other context files)...',
|
|
347
|
-
},
|
|
348
|
-
Date.now(),
|
|
349
|
-
);
|
|
350
|
-
try {
|
|
351
|
-
const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(
|
|
352
|
-
process.cwd(),
|
|
353
|
-
settings.merged.loadMemoryFromIncludeDirectories
|
|
354
|
-
? config.getWorkspaceContext().getDirectories()
|
|
355
|
-
: [],
|
|
356
|
-
config.getDebugMode(),
|
|
357
|
-
config.getFileService(),
|
|
358
|
-
settings.merged,
|
|
359
|
-
config.getExtensionContextFilePaths(),
|
|
360
|
-
settings.merged.memoryImportFormat || 'tree', // Use setting or default to 'tree'
|
|
361
|
-
config.getFileFilteringOptions(),
|
|
362
|
-
);
|
|
363
|
-
|
|
364
|
-
config.setUserMemory(memoryContent);
|
|
365
|
-
config.setGeminiMdFileCount(fileCount);
|
|
366
|
-
setGeminiMdFileCount(fileCount);
|
|
367
|
-
|
|
368
|
-
addItem(
|
|
369
|
-
{
|
|
370
|
-
type: MessageType.INFO,
|
|
371
|
-
text: `Memory refreshed successfully. ${memoryContent.length > 0 ? `Loaded ${memoryContent.length} characters from ${fileCount} file(s).` : 'No memory content found.'}`,
|
|
372
|
-
},
|
|
373
|
-
Date.now(),
|
|
374
|
-
);
|
|
375
|
-
if (config.getDebugMode()) {
|
|
376
|
-
console.log(
|
|
377
|
-
`[DEBUG] Refreshed memory content in config: ${memoryContent.substring(0, 200)}...`,
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
} catch (error) {
|
|
381
|
-
const errorMessage = getErrorMessage(error);
|
|
382
|
-
addItem(
|
|
383
|
-
{
|
|
384
|
-
type: MessageType.ERROR,
|
|
385
|
-
text: `Error refreshing memory: ${errorMessage}`,
|
|
386
|
-
},
|
|
387
|
-
Date.now(),
|
|
388
|
-
);
|
|
389
|
-
console.error('Error refreshing memory:', error);
|
|
390
|
-
}
|
|
391
|
-
}, [config, addItem, settings.merged]);
|
|
392
|
-
|
|
393
|
-
// Watch for model changes (e.g., from Flash fallback)
|
|
394
|
-
useEffect(() => {
|
|
395
|
-
const checkModelChange = () => {
|
|
396
|
-
const configModel = config.getModel();
|
|
397
|
-
if (configModel !== currentModel) {
|
|
398
|
-
setCurrentModel(configModel);
|
|
399
|
-
}
|
|
400
|
-
};
|
|
401
|
-
|
|
402
|
-
// Check immediately and then periodically
|
|
403
|
-
checkModelChange();
|
|
404
|
-
const interval = setInterval(checkModelChange, 1000); // Check every second
|
|
405
|
-
|
|
406
|
-
return () => clearInterval(interval);
|
|
407
|
-
}, [config, currentModel]);
|
|
408
|
-
|
|
409
|
-
// Set up Flash fallback handler
|
|
410
|
-
useEffect(() => {
|
|
411
|
-
const flashFallbackHandler = async (
|
|
412
|
-
currentModel: string,
|
|
413
|
-
fallbackModel: string,
|
|
414
|
-
error?: unknown,
|
|
415
|
-
): Promise<boolean> => {
|
|
416
|
-
let message: string;
|
|
417
|
-
|
|
418
|
-
if (
|
|
419
|
-
config.getContentGeneratorConfig().authType ===
|
|
420
|
-
AuthType.LOGIN_WITH_GOOGLE
|
|
421
|
-
) {
|
|
422
|
-
// Use actual user tier if available; otherwise, default to FREE tier behavior (safe default)
|
|
423
|
-
const isPaidTier =
|
|
424
|
-
userTier === UserTierId.LEGACY || userTier === UserTierId.STANDARD;
|
|
425
|
-
|
|
426
|
-
// Check if this is a Pro quota exceeded error
|
|
427
|
-
if (error && isProQuotaExceededError(error)) {
|
|
428
|
-
if (isPaidTier) {
|
|
429
|
-
message = `⚡ You have reached your daily ${currentModel} quota limit.
|
|
430
|
-
⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
|
|
431
|
-
⚡ To continue accessing the ${currentModel} model today, consider using /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey`;
|
|
432
|
-
} else {
|
|
433
|
-
message = `⚡ You have reached your daily ${currentModel} quota limit.
|
|
434
|
-
⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
|
|
435
|
-
⚡ To increase your limits, upgrade to a Gemini Code Assist Standard or Enterprise plan with higher limits at https://goo.gle/set-up-gemini-code-assist
|
|
436
|
-
⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
|
|
437
|
-
⚡ You can switch authentication methods by typing /auth`;
|
|
438
|
-
}
|
|
439
|
-
} else if (error && isGenericQuotaExceededError(error)) {
|
|
440
|
-
if (isPaidTier) {
|
|
441
|
-
message = `⚡ You have reached your daily quota limit.
|
|
442
|
-
⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
|
|
443
|
-
⚡ To continue accessing the ${currentModel} model today, consider using /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey`;
|
|
444
|
-
} else {
|
|
445
|
-
message = `⚡ You have reached your daily quota limit.
|
|
446
|
-
⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
|
|
447
|
-
⚡ To increase your limits, upgrade to a Gemini Code Assist Standard or Enterprise plan with higher limits at https://goo.gle/set-up-gemini-code-assist
|
|
448
|
-
⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
|
|
449
|
-
⚡ You can switch authentication methods by typing /auth`;
|
|
450
|
-
}
|
|
451
|
-
} else {
|
|
452
|
-
if (isPaidTier) {
|
|
453
|
-
// Default fallback message for other cases (like consecutive 429s)
|
|
454
|
-
message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
|
|
455
|
-
⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
|
|
456
|
-
⚡ To continue accessing the ${currentModel} model today, consider using /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey`;
|
|
457
|
-
} else {
|
|
458
|
-
// Default fallback message for other cases (like consecutive 429s)
|
|
459
|
-
message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
|
|
460
|
-
⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
|
|
461
|
-
⚡ To increase your limits, upgrade to a Gemini Code Assist Standard or Enterprise plan with higher limits at https://goo.gle/set-up-gemini-code-assist
|
|
462
|
-
⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
|
|
463
|
-
⚡ You can switch authentication methods by typing /auth`;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// Add message to UI history
|
|
468
|
-
addItem(
|
|
469
|
-
{
|
|
470
|
-
type: MessageType.INFO,
|
|
471
|
-
text: message,
|
|
472
|
-
},
|
|
473
|
-
Date.now(),
|
|
474
|
-
);
|
|
475
|
-
|
|
476
|
-
// Set the flag to prevent tool continuation
|
|
477
|
-
setModelSwitchedFromQuotaError(true);
|
|
478
|
-
// Set global quota error flag to prevent Flash model calls
|
|
479
|
-
config.setQuotaErrorOccurred(true);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// Switch model for future use but return false to stop current retry
|
|
483
|
-
config.setModel(fallbackModel);
|
|
484
|
-
config.setFallbackMode(true);
|
|
485
|
-
logFlashFallback(
|
|
486
|
-
config,
|
|
487
|
-
new FlashFallbackEvent(config.getContentGeneratorConfig().authType!),
|
|
488
|
-
);
|
|
489
|
-
return false; // Don't continue with current prompt
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
config.setFlashFallbackHandler(flashFallbackHandler);
|
|
493
|
-
}, [config, addItem, userTier]);
|
|
494
|
-
|
|
495
|
-
// Terminal and UI setup
|
|
496
|
-
const { rows: terminalHeight, columns: terminalWidth } = useTerminalSize();
|
|
497
|
-
const isNarrow = isNarrowWidth(terminalWidth);
|
|
498
|
-
const { stdin, setRawMode } = useStdin();
|
|
499
|
-
const isInitialMount = useRef(true);
|
|
500
|
-
|
|
501
|
-
const widthFraction = 0.9;
|
|
502
|
-
const inputWidth = Math.max(
|
|
503
|
-
20,
|
|
504
|
-
Math.floor(terminalWidth * widthFraction) - 3,
|
|
505
|
-
);
|
|
506
|
-
const suggestionsWidth = Math.max(20, Math.floor(terminalWidth * 0.8));
|
|
507
|
-
|
|
508
|
-
// Utility callbacks
|
|
509
|
-
const isValidPath = useCallback((filePath: string): boolean => {
|
|
510
|
-
try {
|
|
511
|
-
return fs.existsSync(filePath) && fs.statSync(filePath).isFile();
|
|
512
|
-
} catch (_e) {
|
|
513
|
-
return false;
|
|
514
|
-
}
|
|
515
|
-
}, []);
|
|
516
|
-
|
|
517
|
-
const getPreferredEditor = useCallback(() => {
|
|
518
|
-
const editorType = settings.merged.preferredEditor;
|
|
519
|
-
const isValidEditor = isEditorAvailable(editorType);
|
|
520
|
-
if (!isValidEditor) {
|
|
521
|
-
openEditorDialog();
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
|
-
return editorType as EditorType;
|
|
525
|
-
}, [settings, openEditorDialog]);
|
|
526
|
-
|
|
527
|
-
const onAuthError = useCallback(() => {
|
|
528
|
-
setAuthError('reauth required');
|
|
529
|
-
openAuthDialog();
|
|
530
|
-
}, [openAuthDialog, setAuthError]);
|
|
531
|
-
|
|
532
|
-
// Core hooks and processors
|
|
533
|
-
const {
|
|
534
|
-
vimEnabled: vimModeEnabled,
|
|
535
|
-
vimMode,
|
|
536
|
-
toggleVimEnabled,
|
|
537
|
-
} = useVimMode();
|
|
538
|
-
|
|
539
|
-
const {
|
|
540
|
-
handleSlashCommand,
|
|
541
|
-
slashCommands,
|
|
542
|
-
pendingHistoryItems: pendingSlashCommandHistoryItems,
|
|
543
|
-
commandContext,
|
|
544
|
-
shellConfirmationRequest,
|
|
545
|
-
confirmationRequest,
|
|
546
|
-
} = useSlashCommandProcessor(
|
|
547
|
-
config,
|
|
548
|
-
settings,
|
|
549
|
-
addItem,
|
|
550
|
-
clearItems,
|
|
551
|
-
loadHistory,
|
|
552
|
-
refreshStatic,
|
|
553
|
-
setDebugMessage,
|
|
554
|
-
openThemeDialog,
|
|
555
|
-
openAuthDialog,
|
|
556
|
-
openEditorDialog,
|
|
557
|
-
openSearchDialog,
|
|
558
|
-
toggleCorgiMode,
|
|
559
|
-
setQuittingMessages,
|
|
560
|
-
openPrivacyNotice,
|
|
561
|
-
openSettingsDialog,
|
|
562
|
-
toggleVimEnabled,
|
|
563
|
-
setIsProcessing,
|
|
564
|
-
setGeminiMdFileCount,
|
|
565
|
-
);
|
|
566
|
-
|
|
567
|
-
const buffer = useTextBuffer({
|
|
568
|
-
initialText: '',
|
|
569
|
-
viewport: { height: 10, width: inputWidth },
|
|
570
|
-
stdin,
|
|
571
|
-
setRawMode,
|
|
572
|
-
isValidPath,
|
|
573
|
-
shellModeActive,
|
|
574
|
-
});
|
|
575
|
-
|
|
576
|
-
const [userMessages, setUserMessages] = useState<string[]>([]);
|
|
577
|
-
|
|
578
|
-
// Stable reference for cancel handler to avoid circular dependency
|
|
579
|
-
const cancelHandlerRef = useRef<() => void>(() => {});
|
|
580
|
-
|
|
581
|
-
const {
|
|
582
|
-
streamingState,
|
|
583
|
-
submitQuery,
|
|
584
|
-
initError,
|
|
585
|
-
pendingHistoryItems: pendingGeminiHistoryItems,
|
|
586
|
-
thought,
|
|
587
|
-
cancelOngoingRequest,
|
|
588
|
-
} = useGeminiStream(
|
|
589
|
-
config.getGeminiClient(),
|
|
590
|
-
history,
|
|
591
|
-
addItem,
|
|
592
|
-
config,
|
|
593
|
-
setDebugMessage,
|
|
594
|
-
handleSlashCommand,
|
|
595
|
-
shellModeActive,
|
|
596
|
-
getPreferredEditor,
|
|
597
|
-
onAuthError,
|
|
598
|
-
performMemoryRefresh,
|
|
599
|
-
modelSwitchedFromQuotaError,
|
|
600
|
-
setModelSwitchedFromQuotaError,
|
|
601
|
-
refreshStatic,
|
|
602
|
-
() => cancelHandlerRef.current(),
|
|
603
|
-
);
|
|
604
|
-
|
|
605
|
-
// Handle Welcome Back context population
|
|
606
|
-
useEffect(() => {
|
|
607
|
-
if (contextToPopulate && !initialPromptSubmitted.current) {
|
|
608
|
-
submitQuery(contextToPopulate);
|
|
609
|
-
initialPromptSubmitted.current = true;
|
|
610
|
-
}
|
|
611
|
-
}, [contextToPopulate, submitQuery]);
|
|
612
|
-
|
|
613
|
-
// Message queue for handling input during streaming
|
|
614
|
-
const { messageQueue, addMessage, clearQueue, getQueuedMessagesText } =
|
|
615
|
-
useMessageQueue({
|
|
616
|
-
streamingState,
|
|
617
|
-
submitQuery,
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
// Update the cancel handler with message queue support
|
|
621
|
-
cancelHandlerRef.current = useCallback(() => {
|
|
622
|
-
const lastUserMessage = userMessages.at(-1);
|
|
623
|
-
let textToSet = lastUserMessage || '';
|
|
624
|
-
|
|
625
|
-
// Append queued messages if any exist
|
|
626
|
-
const queuedText = getQueuedMessagesText();
|
|
627
|
-
if (queuedText) {
|
|
628
|
-
textToSet = textToSet ? `${textToSet}\n\n${queuedText}` : queuedText;
|
|
629
|
-
clearQueue();
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
if (textToSet) {
|
|
633
|
-
buffer.setText(textToSet);
|
|
634
|
-
}
|
|
635
|
-
}, [buffer, userMessages, getQueuedMessagesText, clearQueue]);
|
|
636
|
-
|
|
637
|
-
// Input handling - queue messages for processing
|
|
638
|
-
const handleFinalSubmit = useCallback(
|
|
639
|
-
(submittedValue: string) => {
|
|
640
|
-
addMessage(submittedValue);
|
|
641
|
-
},
|
|
642
|
-
[addMessage],
|
|
643
|
-
);
|
|
644
|
-
|
|
645
|
-
const handleIdePromptComplete = useCallback(
|
|
646
|
-
(result: IdeIntegrationNudgeResult) => {
|
|
647
|
-
if (result.userSelection === 'yes') {
|
|
648
|
-
if (result.isExtensionPreInstalled) {
|
|
649
|
-
handleSlashCommand('/ide enable');
|
|
650
|
-
} else {
|
|
651
|
-
handleSlashCommand('/ide install');
|
|
652
|
-
}
|
|
653
|
-
settings.setValue(
|
|
654
|
-
SettingScope.User,
|
|
655
|
-
'hasSeenIdeIntegrationNudge',
|
|
656
|
-
true,
|
|
657
|
-
);
|
|
658
|
-
} else if (result.userSelection === 'dismiss') {
|
|
659
|
-
settings.setValue(
|
|
660
|
-
SettingScope.User,
|
|
661
|
-
'hasSeenIdeIntegrationNudge',
|
|
662
|
-
true,
|
|
663
|
-
);
|
|
664
|
-
}
|
|
665
|
-
setIdePromptAnswered(true);
|
|
666
|
-
},
|
|
667
|
-
[handleSlashCommand, settings],
|
|
668
|
-
);
|
|
669
|
-
|
|
670
|
-
const { handleInput: vimHandleInput } = useVim(buffer, handleFinalSubmit);
|
|
671
|
-
const pendingHistoryItems = [...pendingSlashCommandHistoryItems];
|
|
672
|
-
pendingHistoryItems.push(...pendingGeminiHistoryItems);
|
|
673
|
-
|
|
674
|
-
const { elapsedTime, currentLoadingPhrase } =
|
|
675
|
-
useLoadingIndicator(streamingState);
|
|
676
|
-
const showAutoAcceptIndicator = useAutoAcceptIndicator({ config });
|
|
677
|
-
|
|
678
|
-
const handleExit = useCallback(
|
|
679
|
-
(
|
|
680
|
-
pressedOnce: boolean,
|
|
681
|
-
setPressedOnce: (value: boolean) => void,
|
|
682
|
-
timerRef: ReturnType<typeof useRef<NodeJS.Timeout | null>>,
|
|
683
|
-
) => {
|
|
684
|
-
if (pressedOnce) {
|
|
685
|
-
if (timerRef.current) {
|
|
686
|
-
clearTimeout(timerRef.current);
|
|
687
|
-
}
|
|
688
|
-
// Directly invoke the central command handler.
|
|
689
|
-
handleSlashCommand('/quit');
|
|
690
|
-
} else {
|
|
691
|
-
setPressedOnce(true);
|
|
692
|
-
timerRef.current = setTimeout(() => {
|
|
693
|
-
setPressedOnce(false);
|
|
694
|
-
timerRef.current = null;
|
|
695
|
-
}, CTRL_EXIT_PROMPT_DURATION_MS);
|
|
696
|
-
}
|
|
697
|
-
},
|
|
698
|
-
[handleSlashCommand],
|
|
699
|
-
);
|
|
700
|
-
|
|
701
|
-
const handleGlobalKeypress = useCallback(
|
|
702
|
-
(key: Key) => {
|
|
703
|
-
let enteringConstrainHeightMode = false;
|
|
704
|
-
if (!constrainHeight) {
|
|
705
|
-
enteringConstrainHeightMode = true;
|
|
706
|
-
setConstrainHeight(true);
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
if (keyMatchers[Command.SHOW_ERROR_DETAILS](key)) {
|
|
710
|
-
setShowErrorDetails((prev) => !prev);
|
|
711
|
-
} else if (keyMatchers[Command.TOGGLE_TOOL_DESCRIPTIONS](key)) {
|
|
712
|
-
const newValue = !showToolDescriptions;
|
|
713
|
-
setShowToolDescriptions(newValue);
|
|
714
|
-
|
|
715
|
-
const mcpServers = config.getMcpServers();
|
|
716
|
-
if (Object.keys(mcpServers || {}).length > 0) {
|
|
717
|
-
handleSlashCommand(newValue ? '/mcp desc' : '/mcp nodesc');
|
|
718
|
-
}
|
|
719
|
-
} else if (
|
|
720
|
-
keyMatchers[Command.TOGGLE_IDE_CONTEXT_DETAIL](key) &&
|
|
721
|
-
config.getIdeMode() &&
|
|
722
|
-
ideContextState
|
|
723
|
-
) {
|
|
724
|
-
// Show IDE status when in IDE mode and context is available.
|
|
725
|
-
handleSlashCommand('/ide status');
|
|
726
|
-
} else if (keyMatchers[Command.QUIT](key)) {
|
|
727
|
-
// When authenticating, let AuthInProgress component handle Ctrl+C.
|
|
728
|
-
if (isAuthenticating) {
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
if (!ctrlCPressedOnce) {
|
|
732
|
-
cancelOngoingRequest?.();
|
|
733
|
-
}
|
|
734
|
-
handleExit(ctrlCPressedOnce, setCtrlCPressedOnce, ctrlCTimerRef);
|
|
735
|
-
} else if (keyMatchers[Command.EXIT](key)) {
|
|
736
|
-
if (buffer.text.length > 0) {
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
handleExit(ctrlDPressedOnce, setCtrlDPressedOnce, ctrlDTimerRef);
|
|
740
|
-
} else if (
|
|
741
|
-
keyMatchers[Command.SHOW_MORE_LINES](key) &&
|
|
742
|
-
!enteringConstrainHeightMode
|
|
743
|
-
) {
|
|
744
|
-
setConstrainHeight(false);
|
|
745
|
-
}
|
|
746
|
-
},
|
|
747
|
-
[
|
|
748
|
-
constrainHeight,
|
|
749
|
-
setConstrainHeight,
|
|
750
|
-
setShowErrorDetails,
|
|
751
|
-
showToolDescriptions,
|
|
752
|
-
setShowToolDescriptions,
|
|
753
|
-
config,
|
|
754
|
-
ideContextState,
|
|
755
|
-
handleExit,
|
|
756
|
-
ctrlCPressedOnce,
|
|
757
|
-
setCtrlCPressedOnce,
|
|
758
|
-
ctrlCTimerRef,
|
|
759
|
-
buffer.text.length,
|
|
760
|
-
ctrlDPressedOnce,
|
|
761
|
-
setCtrlDPressedOnce,
|
|
762
|
-
ctrlDTimerRef,
|
|
763
|
-
handleSlashCommand,
|
|
764
|
-
isAuthenticating,
|
|
765
|
-
cancelOngoingRequest,
|
|
766
|
-
],
|
|
767
|
-
);
|
|
768
|
-
|
|
769
|
-
useKeypress(handleGlobalKeypress, {
|
|
770
|
-
isActive: true,
|
|
771
|
-
});
|
|
772
|
-
|
|
773
|
-
useEffect(() => {
|
|
774
|
-
if (config) {
|
|
775
|
-
setGeminiMdFileCount(config.getGeminiMdFileCount());
|
|
776
|
-
}
|
|
777
|
-
}, [config, config.getGeminiMdFileCount]);
|
|
778
|
-
|
|
779
|
-
const logger = useLogger();
|
|
780
|
-
|
|
781
|
-
useEffect(() => {
|
|
782
|
-
const fetchUserMessages = async () => {
|
|
783
|
-
const pastMessagesRaw = (await logger?.getPreviousUserMessages()) || []; // Newest first
|
|
784
|
-
|
|
785
|
-
const currentSessionUserMessages = history
|
|
786
|
-
.filter(
|
|
787
|
-
(item): item is HistoryItem & { type: 'user'; text: string } =>
|
|
788
|
-
item.type === 'user' &&
|
|
789
|
-
typeof item.text === 'string' &&
|
|
790
|
-
item.text.trim() !== '',
|
|
791
|
-
)
|
|
792
|
-
.map((item) => item.text)
|
|
793
|
-
.reverse(); // Newest first, to match pastMessagesRaw sorting
|
|
794
|
-
|
|
795
|
-
// Combine, with current session messages being more recent
|
|
796
|
-
const combinedMessages = [
|
|
797
|
-
...currentSessionUserMessages,
|
|
798
|
-
...pastMessagesRaw,
|
|
799
|
-
];
|
|
800
|
-
|
|
801
|
-
// Deduplicate consecutive identical messages from the combined list (still newest first)
|
|
802
|
-
const deduplicatedMessages: string[] = [];
|
|
803
|
-
if (combinedMessages.length > 0) {
|
|
804
|
-
deduplicatedMessages.push(combinedMessages[0]); // Add the newest one unconditionally
|
|
805
|
-
for (let i = 1; i < combinedMessages.length; i++) {
|
|
806
|
-
if (combinedMessages[i] !== combinedMessages[i - 1]) {
|
|
807
|
-
deduplicatedMessages.push(combinedMessages[i]);
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
// Reverse to oldest first for useInputHistory
|
|
812
|
-
setUserMessages(deduplicatedMessages.reverse());
|
|
813
|
-
};
|
|
814
|
-
fetchUserMessages();
|
|
815
|
-
}, [history, logger]);
|
|
816
|
-
|
|
817
|
-
const isInputActive =
|
|
818
|
-
(streamingState === StreamingState.Idle ||
|
|
819
|
-
streamingState === StreamingState.Responding) &&
|
|
820
|
-
!initError &&
|
|
821
|
-
!isProcessing;
|
|
822
|
-
|
|
823
|
-
const handleClearScreen = useCallback(() => {
|
|
824
|
-
clearItems();
|
|
825
|
-
clearConsoleMessagesState();
|
|
826
|
-
console.clear();
|
|
827
|
-
refreshStatic();
|
|
828
|
-
}, [clearItems, clearConsoleMessagesState, refreshStatic]);
|
|
829
|
-
|
|
830
|
-
const mainControlsRef = useRef<DOMElement>(null);
|
|
831
|
-
const pendingHistoryItemRef = useRef<DOMElement>(null);
|
|
832
|
-
|
|
833
|
-
useEffect(() => {
|
|
834
|
-
if (mainControlsRef.current) {
|
|
835
|
-
const fullFooterMeasurement = measureElement(mainControlsRef.current);
|
|
836
|
-
setFooterHeight(fullFooterMeasurement.height);
|
|
837
|
-
}
|
|
838
|
-
}, [terminalHeight, consoleMessages, showErrorDetails]);
|
|
839
|
-
|
|
840
|
-
const staticExtraHeight = /* margins and padding */ 3;
|
|
841
|
-
const availableTerminalHeight = useMemo(
|
|
842
|
-
() => terminalHeight - footerHeight - staticExtraHeight,
|
|
843
|
-
[terminalHeight, footerHeight],
|
|
844
|
-
);
|
|
845
|
-
|
|
846
|
-
useEffect(() => {
|
|
847
|
-
// skip refreshing Static during first mount
|
|
848
|
-
if (isInitialMount.current) {
|
|
849
|
-
isInitialMount.current = false;
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
// debounce so it doesn't fire up too often during resize
|
|
854
|
-
const handler = setTimeout(() => {
|
|
855
|
-
setStaticNeedsRefresh(false);
|
|
856
|
-
refreshStatic();
|
|
857
|
-
}, 300);
|
|
858
|
-
|
|
859
|
-
return () => {
|
|
860
|
-
clearTimeout(handler);
|
|
861
|
-
};
|
|
862
|
-
}, [terminalWidth, terminalHeight, refreshStatic]);
|
|
863
|
-
|
|
864
|
-
useEffect(() => {
|
|
865
|
-
if (streamingState === StreamingState.Idle && staticNeedsRefresh) {
|
|
866
|
-
setStaticNeedsRefresh(false);
|
|
867
|
-
refreshStatic();
|
|
868
|
-
}
|
|
869
|
-
}, [streamingState, refreshStatic, staticNeedsRefresh]);
|
|
870
|
-
|
|
871
|
-
const filteredConsoleMessages = useMemo(() => {
|
|
872
|
-
if (config.getDebugMode()) {
|
|
873
|
-
return consoleMessages;
|
|
874
|
-
}
|
|
875
|
-
return consoleMessages.filter((msg) => msg.type !== 'debug');
|
|
876
|
-
}, [consoleMessages, config]);
|
|
877
|
-
|
|
878
|
-
const branchName = useGitBranchName(config.getTargetDir());
|
|
879
|
-
|
|
880
|
-
const contextFileNames = useMemo(() => {
|
|
881
|
-
const fromSettings = settings.merged.contextFileName;
|
|
882
|
-
if (fromSettings) {
|
|
883
|
-
return Array.isArray(fromSettings) ? fromSettings : [fromSettings];
|
|
884
|
-
}
|
|
885
|
-
return getAllGeminiMdFilenames();
|
|
886
|
-
}, [settings.merged.contextFileName]);
|
|
887
|
-
|
|
888
|
-
const initialPrompt = useMemo(() => config.getQuestion(), [config]);
|
|
889
|
-
const geminiClient = config.getGeminiClient();
|
|
890
|
-
|
|
891
|
-
useEffect(() => {
|
|
892
|
-
if (
|
|
893
|
-
initialPrompt &&
|
|
894
|
-
!initialPromptSubmitted.current &&
|
|
895
|
-
!isAuthenticating &&
|
|
896
|
-
!isAuthDialogOpen &&
|
|
897
|
-
!shouldShowWelcomeBack &&
|
|
898
|
-
!isThemeDialogOpen &&
|
|
899
|
-
!isEditorDialogOpen &&
|
|
900
|
-
!isSearchDialogOpen &&
|
|
901
|
-
!showPrivacyNotice &&
|
|
902
|
-
geminiClient?.isInitialized?.()
|
|
903
|
-
) {
|
|
904
|
-
submitQuery(initialPrompt);
|
|
905
|
-
initialPromptSubmitted.current = true;
|
|
906
|
-
}
|
|
907
|
-
}, [
|
|
908
|
-
initialPrompt,
|
|
909
|
-
submitQuery,
|
|
910
|
-
isAuthenticating,
|
|
911
|
-
isAuthDialogOpen,
|
|
912
|
-
shouldShowWelcomeBack,
|
|
913
|
-
isThemeDialogOpen,
|
|
914
|
-
isEditorDialogOpen,
|
|
915
|
-
isSearchDialogOpen,
|
|
916
|
-
showPrivacyNotice,
|
|
917
|
-
geminiClient,
|
|
918
|
-
]);
|
|
919
|
-
|
|
920
|
-
if (quittingMessages) {
|
|
921
|
-
return (
|
|
922
|
-
<Box flexDirection="column" marginBottom={1}>
|
|
923
|
-
{quittingMessages.map((item) => (
|
|
924
|
-
<HistoryItemDisplay
|
|
925
|
-
key={item.id}
|
|
926
|
-
availableTerminalHeight={
|
|
927
|
-
constrainHeight ? availableTerminalHeight : undefined
|
|
928
|
-
}
|
|
929
|
-
terminalWidth={terminalWidth}
|
|
930
|
-
item={item}
|
|
931
|
-
isPending={false}
|
|
932
|
-
config={config}
|
|
933
|
-
/>
|
|
934
|
-
))}
|
|
935
|
-
</Box>
|
|
936
|
-
);
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
const mainAreaWidth = Math.floor(terminalWidth * 0.9);
|
|
940
|
-
const debugConsoleMaxHeight = Math.floor(Math.max(terminalHeight * 0.2, 5));
|
|
941
|
-
// Arbitrary threshold to ensure that items in the static area are large
|
|
942
|
-
// enough but not too large to make the terminal hard to use.
|
|
943
|
-
const staticAreaMaxItemHeight = Math.max(terminalHeight * 4, 100);
|
|
944
|
-
const placeholder = vimModeEnabled
|
|
945
|
-
? " Press 'i' for INSERT mode and 'Esc' for NORMAL mode."
|
|
946
|
-
: ' Type your message or @path/to/file';
|
|
947
|
-
|
|
948
|
-
return (
|
|
949
|
-
<StreamingContext.Provider value={streamingState}>
|
|
950
|
-
<Box flexDirection="column" width="90%">
|
|
951
|
-
{/*
|
|
952
|
-
* The Static component is an Ink intrinsic in which there can only be 1 per application.
|
|
953
|
-
* Because of this restriction we're hacking it slightly by having a 'header' item here to
|
|
954
|
-
* ensure that it's statically rendered.
|
|
955
|
-
*
|
|
956
|
-
* Background on the Static Item: Anything in the Static component is written a single time
|
|
957
|
-
* to the console. Think of it like doing a console.log and then never using ANSI codes to
|
|
958
|
-
* clear that content ever again. Effectively it has a moving frame that every time new static
|
|
959
|
-
* content is set it'll flush content to the terminal and move the area which it's "clearing"
|
|
960
|
-
* down a notch. Without Static the area which gets erased and redrawn continuously grows.
|
|
961
|
-
*/}
|
|
962
|
-
<Static
|
|
963
|
-
key={staticKey}
|
|
964
|
-
items={[
|
|
965
|
-
<Box flexDirection="column" key="header">
|
|
966
|
-
{!settings.merged.hideBanner && (
|
|
967
|
-
<Header version={version} nightly={nightly} />
|
|
968
|
-
)}
|
|
969
|
-
{!settings.merged.hideTips && <Tips config={config} />}
|
|
970
|
-
</Box>,
|
|
971
|
-
...history.map((h) => (
|
|
972
|
-
<HistoryItemDisplay
|
|
973
|
-
terminalWidth={mainAreaWidth}
|
|
974
|
-
availableTerminalHeight={staticAreaMaxItemHeight}
|
|
975
|
-
key={h.id}
|
|
976
|
-
item={h}
|
|
977
|
-
isPending={false}
|
|
978
|
-
config={config}
|
|
979
|
-
commands={slashCommands}
|
|
980
|
-
/>
|
|
981
|
-
)),
|
|
982
|
-
]}
|
|
983
|
-
>
|
|
984
|
-
{(item) => item}
|
|
985
|
-
</Static>
|
|
986
|
-
<OverflowProvider>
|
|
987
|
-
<Box ref={pendingHistoryItemRef} flexDirection="column">
|
|
988
|
-
{pendingHistoryItems.map((item, i) => (
|
|
989
|
-
<HistoryItemDisplay
|
|
990
|
-
key={i}
|
|
991
|
-
availableTerminalHeight={
|
|
992
|
-
constrainHeight ? availableTerminalHeight : undefined
|
|
993
|
-
}
|
|
994
|
-
terminalWidth={mainAreaWidth}
|
|
995
|
-
// TODO(taehykim): It seems like references to ids aren't necessary in
|
|
996
|
-
// HistoryItemDisplay. Refactor later. Use a fake id for now.
|
|
997
|
-
item={{ ...item, id: 0 }}
|
|
998
|
-
isPending={true}
|
|
999
|
-
config={config}
|
|
1000
|
-
isFocused={!isEditorDialogOpen}
|
|
1001
|
-
/>
|
|
1002
|
-
))}
|
|
1003
|
-
<ShowMoreLines constrainHeight={constrainHeight} />
|
|
1004
|
-
</Box>
|
|
1005
|
-
</OverflowProvider>
|
|
1006
|
-
|
|
1007
|
-
<Box flexDirection="column" ref={mainControlsRef}>
|
|
1008
|
-
{/* Move UpdateNotification to render update notification above input area */}
|
|
1009
|
-
{updateInfo && <UpdateNotification message={updateInfo.message} />}
|
|
1010
|
-
{startupWarnings.length > 0 && (
|
|
1011
|
-
<Box
|
|
1012
|
-
borderStyle="round"
|
|
1013
|
-
borderColor={Colors.AccentYellow}
|
|
1014
|
-
paddingX={1}
|
|
1015
|
-
marginY={1}
|
|
1016
|
-
flexDirection="column"
|
|
1017
|
-
>
|
|
1018
|
-
{startupWarnings.map((warning, index) => (
|
|
1019
|
-
<Text key={index} color={Colors.AccentYellow}>
|
|
1020
|
-
{warning}
|
|
1021
|
-
</Text>
|
|
1022
|
-
))}
|
|
1023
|
-
</Box>
|
|
1024
|
-
)}
|
|
1025
|
-
|
|
1026
|
-
{shouldShowIdePrompt && currentIDE ? (
|
|
1027
|
-
<IdeIntegrationNudge
|
|
1028
|
-
ide={currentIDE}
|
|
1029
|
-
onComplete={handleIdePromptComplete}
|
|
1030
|
-
/>
|
|
1031
|
-
) : isFolderTrustDialogOpen ? (
|
|
1032
|
-
<FolderTrustDialog onSelect={handleFolderTrustSelect} />
|
|
1033
|
-
) : shellConfirmationRequest ? (
|
|
1034
|
-
<ShellConfirmationDialog request={shellConfirmationRequest} />
|
|
1035
|
-
) : confirmationRequest ? (
|
|
1036
|
-
<Box flexDirection="column">
|
|
1037
|
-
{confirmationRequest.prompt}
|
|
1038
|
-
<Box paddingY={1}>
|
|
1039
|
-
<RadioButtonSelect
|
|
1040
|
-
isFocused={!!confirmationRequest}
|
|
1041
|
-
items={[
|
|
1042
|
-
{ label: 'Yes', value: true },
|
|
1043
|
-
{ label: 'No', value: false },
|
|
1044
|
-
]}
|
|
1045
|
-
onSelect={(value: boolean) => {
|
|
1046
|
-
confirmationRequest.onConfirm(value);
|
|
1047
|
-
}}
|
|
1048
|
-
/>
|
|
1049
|
-
</Box>
|
|
1050
|
-
</Box>
|
|
1051
|
-
) : isThemeDialogOpen ? (
|
|
1052
|
-
<Box flexDirection="column">
|
|
1053
|
-
{themeError && (
|
|
1054
|
-
<Box marginBottom={1}>
|
|
1055
|
-
<Text color={Colors.AccentRed}>{themeError}</Text>
|
|
1056
|
-
</Box>
|
|
1057
|
-
)}
|
|
1058
|
-
<ThemeDialog
|
|
1059
|
-
onSelect={handleThemeSelect}
|
|
1060
|
-
onHighlight={handleThemeHighlight}
|
|
1061
|
-
settings={settings}
|
|
1062
|
-
availableTerminalHeight={
|
|
1063
|
-
constrainHeight
|
|
1064
|
-
? terminalHeight - staticExtraHeight
|
|
1065
|
-
: undefined
|
|
1066
|
-
}
|
|
1067
|
-
terminalWidth={mainAreaWidth}
|
|
1068
|
-
/>
|
|
1069
|
-
</Box>
|
|
1070
|
-
) : isSettingsDialogOpen ? (
|
|
1071
|
-
<Box flexDirection="column">
|
|
1072
|
-
<SettingsDialog
|
|
1073
|
-
settings={settings}
|
|
1074
|
-
onSelect={() => closeSettingsDialog()}
|
|
1075
|
-
onRestartRequest={() => process.exit(0)}
|
|
1076
|
-
/>
|
|
1077
|
-
</Box>
|
|
1078
|
-
) : isAuthenticating ? (
|
|
1079
|
-
<>
|
|
1080
|
-
<AuthInProgress
|
|
1081
|
-
onTimeout={() => {
|
|
1082
|
-
setAuthError('Authentication timed out. Please try again.');
|
|
1083
|
-
cancelAuthentication();
|
|
1084
|
-
openAuthDialog();
|
|
1085
|
-
}}
|
|
1086
|
-
/>
|
|
1087
|
-
{showErrorDetails && (
|
|
1088
|
-
<OverflowProvider>
|
|
1089
|
-
<Box flexDirection="column">
|
|
1090
|
-
<DetailedMessagesDisplay
|
|
1091
|
-
messages={filteredConsoleMessages}
|
|
1092
|
-
maxHeight={
|
|
1093
|
-
constrainHeight ? debugConsoleMaxHeight : undefined
|
|
1094
|
-
}
|
|
1095
|
-
width={inputWidth}
|
|
1096
|
-
/>
|
|
1097
|
-
<ShowMoreLines constrainHeight={constrainHeight} />
|
|
1098
|
-
</Box>
|
|
1099
|
-
</OverflowProvider>
|
|
1100
|
-
)}
|
|
1101
|
-
</>
|
|
1102
|
-
) : isAuthDialogOpen ? (
|
|
1103
|
-
<Box flexDirection="column">
|
|
1104
|
-
<AuthDialog
|
|
1105
|
-
onSelect={handleAuthSelect}
|
|
1106
|
-
settings={settings}
|
|
1107
|
-
initialErrorMessage={authError}
|
|
1108
|
-
/>
|
|
1109
|
-
</Box>
|
|
1110
|
-
) : shouldShowWelcomeBack && projectSummary ? (
|
|
1111
|
-
<Box flexDirection="column">
|
|
1112
|
-
<WelcomeBackDialog
|
|
1113
|
-
projectSummary={projectSummary}
|
|
1114
|
-
onContinue={handleWelcomeBackContinue}
|
|
1115
|
-
onRestart={handleWelcomeBackRestart}
|
|
1116
|
-
onCancel={handleWelcomeBackCancel}
|
|
1117
|
-
/>
|
|
1118
|
-
</Box>
|
|
1119
|
-
) : isEditorDialogOpen ? (
|
|
1120
|
-
<Box flexDirection="column">
|
|
1121
|
-
{editorError && (
|
|
1122
|
-
<Box marginBottom={1}>
|
|
1123
|
-
<Text color={Colors.AccentRed}>{editorError}</Text>
|
|
1124
|
-
</Box>
|
|
1125
|
-
)}
|
|
1126
|
-
<EditorSettingsDialog
|
|
1127
|
-
onSelect={handleEditorSelect}
|
|
1128
|
-
settings={settings}
|
|
1129
|
-
onExit={exitEditorDialog}
|
|
1130
|
-
/>
|
|
1131
|
-
</Box>
|
|
1132
|
-
) : isSearchDialogOpen ? (
|
|
1133
|
-
<Box flexDirection="column">
|
|
1134
|
-
<SearchEngineConfigDialog
|
|
1135
|
-
onSubmit={(result) => {
|
|
1136
|
-
setIsSearchDialogOpen(false);
|
|
1137
|
-
// Show success message
|
|
1138
|
-
addItem(
|
|
1139
|
-
{
|
|
1140
|
-
type: MessageType.INFO,
|
|
1141
|
-
text: `Search engines configured! ${result.braveEnabled ? 'Brave Search' : ''}${result.braveEnabled && result.tavilyEnabled ? ' and ' : ''}${result.tavilyEnabled ? 'Tavily Search' : ''} ${result.braveEnabled || result.tavilyEnabled ? 'enabled' : 'disabled'}.`,
|
|
1142
|
-
},
|
|
1143
|
-
Date.now(),
|
|
1144
|
-
);
|
|
1145
|
-
}}
|
|
1146
|
-
onCancel={() => {
|
|
1147
|
-
setIsSearchDialogOpen(false);
|
|
1148
|
-
}}
|
|
1149
|
-
/>
|
|
1150
|
-
</Box>
|
|
1151
|
-
) : showPrivacyNotice ? (
|
|
1152
|
-
<PrivacyNotice
|
|
1153
|
-
onExit={() => setShowPrivacyNotice(false)}
|
|
1154
|
-
config={config}
|
|
1155
|
-
/>
|
|
1156
|
-
) : (
|
|
1157
|
-
<>
|
|
1158
|
-
<LoadingIndicator
|
|
1159
|
-
thought={
|
|
1160
|
-
streamingState === StreamingState.WaitingForConfirmation ||
|
|
1161
|
-
config.getAccessibility()?.disableLoadingPhrases
|
|
1162
|
-
? undefined
|
|
1163
|
-
: thought
|
|
1164
|
-
}
|
|
1165
|
-
currentLoadingPhrase={
|
|
1166
|
-
config.getAccessibility()?.disableLoadingPhrases
|
|
1167
|
-
? undefined
|
|
1168
|
-
: currentLoadingPhrase
|
|
1169
|
-
}
|
|
1170
|
-
elapsedTime={elapsedTime}
|
|
1171
|
-
/>
|
|
1172
|
-
|
|
1173
|
-
{/* Display queued messages below loading indicator */}
|
|
1174
|
-
{messageQueue.length > 0 && (
|
|
1175
|
-
<Box flexDirection="column" marginTop={1}>
|
|
1176
|
-
{messageQueue
|
|
1177
|
-
.slice(0, MAX_DISPLAYED_QUEUED_MESSAGES)
|
|
1178
|
-
.map((message, index) => {
|
|
1179
|
-
// Ensure multi-line messages are collapsed for the preview.
|
|
1180
|
-
// Replace all whitespace (including newlines) with a single space.
|
|
1181
|
-
const preview = message.replace(/\s+/g, ' ');
|
|
1182
|
-
|
|
1183
|
-
return (
|
|
1184
|
-
// Ensure the Box takes full width so truncation calculates correctly
|
|
1185
|
-
<Box key={index} paddingLeft={2} width="100%">
|
|
1186
|
-
{/* Use wrap="truncate" to ensure it fits the terminal width and doesn't wrap */}
|
|
1187
|
-
<Text dimColor wrap="truncate">
|
|
1188
|
-
{preview}
|
|
1189
|
-
</Text>
|
|
1190
|
-
</Box>
|
|
1191
|
-
);
|
|
1192
|
-
})}
|
|
1193
|
-
{messageQueue.length > MAX_DISPLAYED_QUEUED_MESSAGES && (
|
|
1194
|
-
<Box paddingLeft={2}>
|
|
1195
|
-
<Text dimColor>
|
|
1196
|
-
... (+
|
|
1197
|
-
{messageQueue.length -
|
|
1198
|
-
MAX_DISPLAYED_QUEUED_MESSAGES}{' '}
|
|
1199
|
-
more)
|
|
1200
|
-
</Text>
|
|
1201
|
-
</Box>
|
|
1202
|
-
)}
|
|
1203
|
-
</Box>
|
|
1204
|
-
)}
|
|
1205
|
-
|
|
1206
|
-
<Box
|
|
1207
|
-
marginTop={1}
|
|
1208
|
-
justifyContent="space-between"
|
|
1209
|
-
width="100%"
|
|
1210
|
-
flexDirection={isNarrow ? 'column' : 'row'}
|
|
1211
|
-
alignItems={isNarrow ? 'flex-start' : 'center'}
|
|
1212
|
-
>
|
|
1213
|
-
<Box>
|
|
1214
|
-
{process.env['GEMINI_SYSTEM_MD'] && (
|
|
1215
|
-
<Text color={Colors.AccentRed}>|⌐■_■| </Text>
|
|
1216
|
-
)}
|
|
1217
|
-
{ctrlCPressedOnce ? (
|
|
1218
|
-
<Text color={Colors.AccentYellow}>
|
|
1219
|
-
Press Ctrl+C again to exit.
|
|
1220
|
-
</Text>
|
|
1221
|
-
) : ctrlDPressedOnce ? (
|
|
1222
|
-
<Text color={Colors.AccentYellow}>
|
|
1223
|
-
Press Ctrl+D again to exit.
|
|
1224
|
-
</Text>
|
|
1225
|
-
) : showEscapePrompt ? (
|
|
1226
|
-
<Text color={Colors.Gray}>Press Esc again to clear.</Text>
|
|
1227
|
-
) : (
|
|
1228
|
-
<ContextSummaryDisplay
|
|
1229
|
-
ideContext={ideContextState}
|
|
1230
|
-
geminiMdFileCount={geminiMdFileCount}
|
|
1231
|
-
contextFileNames={contextFileNames}
|
|
1232
|
-
mcpServers={config.getMcpServers()}
|
|
1233
|
-
blockedMcpServers={config.getBlockedMcpServers()}
|
|
1234
|
-
showToolDescriptions={showToolDescriptions}
|
|
1235
|
-
/>
|
|
1236
|
-
)}
|
|
1237
|
-
</Box>
|
|
1238
|
-
<Box paddingTop={isNarrow ? 1 : 0}>
|
|
1239
|
-
{showAutoAcceptIndicator !== ApprovalMode.DEFAULT &&
|
|
1240
|
-
!shellModeActive && (
|
|
1241
|
-
<AutoAcceptIndicator
|
|
1242
|
-
approvalMode={showAutoAcceptIndicator}
|
|
1243
|
-
/>
|
|
1244
|
-
)}
|
|
1245
|
-
{shellModeActive && <ShellModeIndicator />}
|
|
1246
|
-
</Box>
|
|
1247
|
-
</Box>
|
|
1248
|
-
|
|
1249
|
-
{showErrorDetails && (
|
|
1250
|
-
<OverflowProvider>
|
|
1251
|
-
<Box flexDirection="column">
|
|
1252
|
-
<DetailedMessagesDisplay
|
|
1253
|
-
messages={filteredConsoleMessages}
|
|
1254
|
-
maxHeight={
|
|
1255
|
-
constrainHeight ? debugConsoleMaxHeight : undefined
|
|
1256
|
-
}
|
|
1257
|
-
width={inputWidth}
|
|
1258
|
-
/>
|
|
1259
|
-
<ShowMoreLines constrainHeight={constrainHeight} />
|
|
1260
|
-
</Box>
|
|
1261
|
-
</OverflowProvider>
|
|
1262
|
-
)}
|
|
1263
|
-
|
|
1264
|
-
{isInputActive && (
|
|
1265
|
-
<InputPrompt
|
|
1266
|
-
buffer={buffer}
|
|
1267
|
-
inputWidth={inputWidth}
|
|
1268
|
-
suggestionsWidth={suggestionsWidth}
|
|
1269
|
-
onSubmit={handleFinalSubmit}
|
|
1270
|
-
userMessages={userMessages}
|
|
1271
|
-
onClearScreen={handleClearScreen}
|
|
1272
|
-
config={config}
|
|
1273
|
-
slashCommands={slashCommands}
|
|
1274
|
-
commandContext={commandContext}
|
|
1275
|
-
shellModeActive={shellModeActive}
|
|
1276
|
-
setShellModeActive={setShellModeActive}
|
|
1277
|
-
onEscapePromptChange={handleEscapePromptChange}
|
|
1278
|
-
focus={isFocused}
|
|
1279
|
-
vimHandleInput={vimHandleInput}
|
|
1280
|
-
placeholder={placeholder}
|
|
1281
|
-
/>
|
|
1282
|
-
)}
|
|
1283
|
-
</>
|
|
1284
|
-
)}
|
|
1285
|
-
|
|
1286
|
-
{initError && streamingState !== StreamingState.Responding && (
|
|
1287
|
-
<Box
|
|
1288
|
-
borderStyle="round"
|
|
1289
|
-
borderColor={Colors.AccentRed}
|
|
1290
|
-
paddingX={1}
|
|
1291
|
-
marginBottom={1}
|
|
1292
|
-
>
|
|
1293
|
-
{history.find(
|
|
1294
|
-
(item) =>
|
|
1295
|
-
item.type === 'error' && item.text?.includes(initError),
|
|
1296
|
-
)?.text ? (
|
|
1297
|
-
<Text color={Colors.AccentRed}>
|
|
1298
|
-
{
|
|
1299
|
-
history.find(
|
|
1300
|
-
(item) =>
|
|
1301
|
-
item.type === 'error' && item.text?.includes(initError),
|
|
1302
|
-
)?.text
|
|
1303
|
-
}
|
|
1304
|
-
</Text>
|
|
1305
|
-
) : (
|
|
1306
|
-
<>
|
|
1307
|
-
<Text color={Colors.AccentRed}>
|
|
1308
|
-
Initialization Error: {initError}
|
|
1309
|
-
</Text>
|
|
1310
|
-
<Text color={Colors.AccentRed}>
|
|
1311
|
-
{' '}
|
|
1312
|
-
Please check API key and configuration.
|
|
1313
|
-
</Text>
|
|
1314
|
-
</>
|
|
1315
|
-
)}
|
|
1316
|
-
</Box>
|
|
1317
|
-
)}
|
|
1318
|
-
{!settings.merged.hideFooter && (
|
|
1319
|
-
<Footer
|
|
1320
|
-
model={currentModel}
|
|
1321
|
-
targetDir={config.getTargetDir()}
|
|
1322
|
-
debugMode={config.getDebugMode()}
|
|
1323
|
-
branchName={branchName}
|
|
1324
|
-
debugMessage={debugMessage}
|
|
1325
|
-
corgiMode={corgiMode}
|
|
1326
|
-
errorCount={errorCount}
|
|
1327
|
-
showErrorDetails={showErrorDetails}
|
|
1328
|
-
showMemoryUsage={
|
|
1329
|
-
config.getDebugMode() ||
|
|
1330
|
-
settings.merged.showMemoryUsage ||
|
|
1331
|
-
false
|
|
1332
|
-
}
|
|
1333
|
-
promptTokenCount={sessionStats.lastPromptTokenCount}
|
|
1334
|
-
nightly={nightly}
|
|
1335
|
-
vimMode={vimModeEnabled ? vimMode : undefined}
|
|
1336
|
-
isTrustedFolder={isTrustedFolderState}
|
|
1337
|
-
config={config}
|
|
1338
|
-
/>
|
|
1339
|
-
)}
|
|
1340
|
-
</Box>
|
|
1341
|
-
</Box>
|
|
1342
|
-
</StreamingContext.Provider>
|
|
1343
|
-
);
|
|
1344
|
-
};
|