@google/gemini-cli 0.4.0-preview.2 → 0.5.0-nightly.20250908.4693137b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/google-gemini-cli-0.3.4.tgz +0 -0
  2. package/dist/package.json +2 -2
  3. package/dist/src/commands/extensions/install.js +3 -3
  4. package/dist/src/commands/extensions/install.js.map +1 -1
  5. package/dist/src/commands/extensions/install.test.js +2 -2
  6. package/dist/src/commands/extensions/install.test.js.map +1 -1
  7. package/dist/src/config/config.js +13 -11
  8. package/dist/src/config/config.js.map +1 -1
  9. package/dist/src/config/extension.js +2 -1
  10. package/dist/src/config/extension.js.map +1 -1
  11. package/dist/src/config/settings.js +2 -13
  12. package/dist/src/config/settings.js.map +1 -1
  13. package/dist/src/config/settingsSchema.d.ts +19 -1
  14. package/dist/src/config/settingsSchema.js +20 -1
  15. package/dist/src/config/settingsSchema.js.map +1 -1
  16. package/dist/src/core/auth.d.ts +13 -0
  17. package/dist/src/core/auth.js +27 -0
  18. package/dist/src/core/auth.js.map +1 -0
  19. package/dist/src/core/initializer.d.ts +21 -0
  20. package/dist/src/core/initializer.js +28 -0
  21. package/dist/src/core/initializer.js.map +1 -0
  22. package/dist/src/core/theme.d.ts +12 -0
  23. package/dist/src/core/theme.js +20 -0
  24. package/dist/src/core/theme.js.map +1 -0
  25. package/dist/src/gemini.d.ts +2 -1
  26. package/dist/src/gemini.js +37 -7
  27. package/dist/src/gemini.js.map +1 -1
  28. package/dist/src/gemini.test.js +91 -14
  29. package/dist/src/gemini.test.js.map +1 -1
  30. package/dist/src/generated/git-commit.d.ts +2 -2
  31. package/dist/src/generated/git-commit.js +2 -2
  32. package/dist/src/generated/git-commit.js.map +1 -1
  33. package/dist/src/services/BuiltinCommandLoader.test.js +16 -17
  34. package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
  35. package/dist/src/ui/App.d.ts +1 -10
  36. package/dist/src/ui/App.js +13 -729
  37. package/dist/src/ui/App.js.map +1 -1
  38. package/dist/src/ui/AppContainer.d.ts +17 -0
  39. package/dist/src/ui/AppContainer.js +932 -0
  40. package/dist/src/ui/AppContainer.js.map +1 -0
  41. package/dist/src/ui/AppContainer.test.js +195 -0
  42. package/dist/src/ui/AppContainer.test.js.map +1 -0
  43. package/dist/src/ui/auth/AuthDialog.d.ts +18 -0
  44. package/dist/src/ui/{components → auth}/AuthDialog.js +35 -34
  45. package/dist/src/ui/auth/AuthDialog.js.map +1 -0
  46. package/dist/src/ui/auth/AuthDialog.test.d.ts +6 -0
  47. package/dist/src/ui/auth/AuthDialog.test.js +184 -0
  48. package/dist/src/ui/auth/AuthDialog.test.js.map +1 -0
  49. package/dist/src/ui/auth/AuthInProgress.js.map +1 -0
  50. package/dist/src/ui/auth/useAuth.d.ts +15 -0
  51. package/dist/src/ui/auth/useAuth.js +73 -0
  52. package/dist/src/ui/auth/useAuth.js.map +1 -0
  53. package/dist/src/ui/commands/corgiCommand.js +1 -0
  54. package/dist/src/ui/commands/corgiCommand.js.map +1 -1
  55. package/dist/src/ui/commands/mcpCommand.js +1 -1
  56. package/dist/src/ui/commands/mcpCommand.js.map +1 -1
  57. package/dist/src/ui/commands/types.d.ts +1 -0
  58. package/dist/src/ui/components/AppHeader.d.ts +10 -0
  59. package/dist/src/ui/components/AppHeader.js +19 -0
  60. package/dist/src/ui/components/AppHeader.js.map +1 -0
  61. package/dist/src/ui/components/Composer.d.ts +6 -0
  62. package/dist/src/ui/components/Composer.js +68 -0
  63. package/dist/src/ui/components/Composer.js.map +1 -0
  64. package/dist/src/ui/components/Composer.test.d.ts +6 -0
  65. package/dist/src/ui/components/Composer.test.js +340 -0
  66. package/dist/src/ui/components/Composer.test.js.map +1 -0
  67. package/dist/src/ui/components/DialogManager.d.ts +6 -0
  68. package/dist/src/ui/components/DialogManager.js +82 -0
  69. package/dist/src/ui/components/DialogManager.js.map +1 -0
  70. package/dist/src/ui/components/Footer.d.ts +1 -5
  71. package/dist/src/ui/components/Footer.js +3 -4
  72. package/dist/src/ui/components/Footer.js.map +1 -1
  73. package/dist/src/ui/components/Help.d.ts +1 -1
  74. package/dist/src/ui/components/Help.js +6 -3
  75. package/dist/src/ui/components/Help.js.map +1 -1
  76. package/dist/src/ui/components/Help.test.d.ts +6 -0
  77. package/dist/src/ui/components/Help.test.js +57 -0
  78. package/dist/src/ui/components/Help.test.js.map +1 -0
  79. package/dist/src/ui/components/HistoryItemDisplay.d.ts +0 -2
  80. package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
  81. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  82. package/dist/src/ui/components/InputPrompt.js +25 -3
  83. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  84. package/dist/src/ui/components/MainContent.d.ts +6 -0
  85. package/dist/src/ui/components/MainContent.js +23 -0
  86. package/dist/src/ui/components/MainContent.js.map +1 -0
  87. package/dist/src/ui/components/Notifications.d.ts +6 -0
  88. package/dist/src/ui/components/Notifications.js +23 -0
  89. package/dist/src/ui/components/Notifications.js.map +1 -0
  90. package/dist/src/ui/components/QuittingDisplay.d.ts +6 -0
  91. package/dist/src/ui/components/QuittingDisplay.js +20 -0
  92. package/dist/src/ui/components/QuittingDisplay.js.map +1 -0
  93. package/dist/src/ui/components/SuggestionsDisplay.d.ts +2 -0
  94. package/dist/src/ui/components/SuggestionsDisplay.js +6 -12
  95. package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
  96. package/dist/src/ui/components/messages/ToolGroupMessage.d.ts +0 -2
  97. package/dist/src/ui/components/messages/ToolGroupMessage.js +7 -5
  98. package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
  99. package/dist/src/ui/components/messages/ToolGroupMessage.test.js +17 -15
  100. package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
  101. package/dist/src/ui/contexts/AppContext.d.ts +11 -0
  102. package/dist/src/ui/contexts/AppContext.js +15 -0
  103. package/dist/src/ui/contexts/AppContext.js.map +1 -0
  104. package/dist/src/ui/contexts/ConfigContext.d.ts +9 -0
  105. package/dist/src/ui/contexts/ConfigContext.js +16 -0
  106. package/dist/src/ui/contexts/ConfigContext.js.map +1 -0
  107. package/dist/src/ui/contexts/KeypressContext.d.ts +3 -0
  108. package/dist/src/ui/contexts/KeypressContext.js +51 -2
  109. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  110. package/dist/src/ui/contexts/KeypressContext.test.js +173 -1
  111. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  112. package/dist/src/ui/contexts/UIActionsContext.d.ts +36 -0
  113. package/dist/src/ui/contexts/UIActionsContext.js +20 -0
  114. package/dist/src/ui/contexts/UIActionsContext.js.map +1 -0
  115. package/dist/src/ui/contexts/UIStateContext.d.ts +85 -0
  116. package/dist/src/ui/contexts/UIStateContext.js +15 -0
  117. package/dist/src/ui/contexts/UIStateContext.js.map +1 -0
  118. package/dist/src/ui/hooks/atCommandProcessor.test.js +7 -5
  119. package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
  120. package/dist/src/ui/hooks/slashCommandProcessor.d.ts +13 -2
  121. package/dist/src/ui/hooks/slashCommandProcessor.js +13 -25
  122. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  123. package/dist/src/ui/hooks/useFolderTrust.d.ts +2 -1
  124. package/dist/src/ui/hooks/useFolderTrust.js +10 -24
  125. package/dist/src/ui/hooks/useFolderTrust.js.map +1 -1
  126. package/dist/src/ui/hooks/useGeminiStream.d.ts +1 -1
  127. package/dist/src/ui/hooks/useGeminiStream.js +1 -1
  128. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  129. package/dist/src/ui/hooks/useReactToolScheduler.js +2 -0
  130. package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
  131. package/dist/src/ui/hooks/useSlashCompletion.js +4 -2
  132. package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
  133. package/dist/src/ui/hooks/useSlashCompletion.test.js +155 -268
  134. package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
  135. package/dist/src/ui/hooks/useThemeCommand.d.ts +1 -1
  136. package/dist/src/ui/hooks/useThemeCommand.js +3 -14
  137. package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
  138. package/dist/src/ui/hooks/useToolScheduler.test.js +6 -1
  139. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  140. package/dist/src/ui/hooks/useWorkspaceMigration.js +2 -1
  141. package/dist/src/ui/hooks/useWorkspaceMigration.js.map +1 -1
  142. package/dist/src/ui/types.d.ts +17 -1
  143. package/dist/src/ui/types.js +10 -0
  144. package/dist/src/ui/types.js.map +1 -1
  145. package/dist/src/ui/utils/highlight.d.ts +1 -1
  146. package/dist/src/ui/utils/highlight.js +15 -6
  147. package/dist/src/ui/utils/highlight.js.map +1 -1
  148. package/dist/src/ui/utils/highlight.test.js +56 -29
  149. package/dist/src/ui/utils/highlight.test.js.map +1 -1
  150. package/dist/src/ui/utils/kittyProtocolDetector.js +39 -29
  151. package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -1
  152. package/dist/src/zed-integration/schema.d.ts +592 -592
  153. package/dist/tsconfig.tsbuildinfo +1 -1
  154. package/package.json +3 -3
  155. package/dist/google-gemini-cli-0.4.0-preview.1.tgz +0 -0
  156. package/dist/src/ui/components/AuthDialog.d.ts +0 -16
  157. package/dist/src/ui/components/AuthDialog.js.map +0 -1
  158. package/dist/src/ui/components/AuthDialog.test.js +0 -307
  159. package/dist/src/ui/components/AuthDialog.test.js.map +0 -1
  160. package/dist/src/ui/components/AuthInProgress.js.map +0 -1
  161. package/dist/src/ui/hooks/useAuthCommand.d.ts +0 -14
  162. package/dist/src/ui/hooks/useAuthCommand.js +0 -66
  163. package/dist/src/ui/hooks/useAuthCommand.js.map +0 -1
  164. /package/dist/src/ui/{components/AuthDialog.test.d.ts → AppContainer.test.d.ts} +0 -0
  165. /package/dist/src/ui/{components → auth}/AuthInProgress.d.ts +0 -0
  166. /package/dist/src/ui/{components → auth}/AuthInProgress.js +0 -0
@@ -1,738 +1,22 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * @license
4
4
  * Copyright 2025 Google LLC
5
5
  * SPDX-License-Identifier: Apache-2.0
6
6
  */
7
- import { useCallback, useEffect, useMemo, useState, useRef } from 'react';
8
- import { Box, measureElement, Static, Text, useStdin, useStdout, } from 'ink';
9
- import { StreamingState, MessageType, ToolCallStatus, } from './types.js';
10
- import { useTerminalSize } from './hooks/useTerminalSize.js';
11
- import { useGeminiStream } from './hooks/useGeminiStream.js';
12
- import { useLoadingIndicator } from './hooks/useLoadingIndicator.js';
13
- import { useThemeCommand } from './hooks/useThemeCommand.js';
14
- import { useAuthCommand } from './hooks/useAuthCommand.js';
15
- import { useFolderTrust } from './hooks/useFolderTrust.js';
16
- import { useIdeTrustListener } from './hooks/useIdeTrustListener.js';
17
- import { useEditorSettings } from './hooks/useEditorSettings.js';
18
- import { useSlashCommandProcessor } from './hooks/slashCommandProcessor.js';
19
- import { useAutoAcceptIndicator } from './hooks/useAutoAcceptIndicator.js';
20
- import { useMessageQueue } from './hooks/useMessageQueue.js';
21
- import { useConsoleMessages } from './hooks/useConsoleMessages.js';
22
- import { Header } from './components/Header.js';
23
- import { LoadingIndicator } from './components/LoadingIndicator.js';
24
- import { AutoAcceptIndicator } from './components/AutoAcceptIndicator.js';
25
- import { ShellModeIndicator } from './components/ShellModeIndicator.js';
26
- import { InputPrompt } from './components/InputPrompt.js';
27
- import { Footer } from './components/Footer.js';
28
- import { ThemeDialog } from './components/ThemeDialog.js';
29
- import { AuthDialog } from './components/AuthDialog.js';
30
- import { AuthInProgress } from './components/AuthInProgress.js';
31
- import { EditorSettingsDialog } from './components/EditorSettingsDialog.js';
32
- import { FolderTrustDialog } from './components/FolderTrustDialog.js';
33
- import { ShellConfirmationDialog } from './components/ShellConfirmationDialog.js';
34
- import { RadioButtonSelect } from './components/shared/RadioButtonSelect.js';
35
- import { Colors } from './colors.js';
36
- import { loadHierarchicalGeminiMemory } from '../config/config.js';
37
- import { SettingScope } from '../config/settings.js';
38
- import { Tips } from './components/Tips.js';
39
- import { ConsolePatcher } from './utils/ConsolePatcher.js';
40
- import { registerCleanup } from '../utils/cleanup.js';
41
- import { DetailedMessagesDisplay } from './components/DetailedMessagesDisplay.js';
42
- import { HistoryItemDisplay } from './components/HistoryItemDisplay.js';
43
- import { ContextSummaryDisplay } from './components/ContextSummaryDisplay.js';
44
- import { useHistory } from './hooks/useHistoryManager.js';
45
- import { useInputHistoryStore } from './hooks/useInputHistoryStore.js';
46
- import process from 'node:process';
47
- import { ApprovalMode, getAllGeminiMdFilenames, isEditorAvailable, getErrorMessage, AuthType, logFlashFallback, FlashFallbackEvent, ideContext, isProQuotaExceededError, isGenericQuotaExceededError, UserTierId, DEFAULT_GEMINI_FLASH_MODEL, IdeClient, } from '@google/gemini-cli-core';
48
- import { IdeIntegrationNudge } from './IdeIntegrationNudge.js';
49
- import { validateAuthMethod } from '../config/auth.js';
50
- import { useLogger } from './hooks/useLogger.js';
7
+ import { Box } from 'ink';
51
8
  import { StreamingContext } from './contexts/StreamingContext.js';
52
- import { SessionStatsProvider, useSessionStats, } from './contexts/SessionContext.js';
53
- import { useGitBranchName } from './hooks/useGitBranchName.js';
54
- import { useFocus } from './hooks/useFocus.js';
55
- import { useBracketedPaste } from './hooks/useBracketedPaste.js';
56
- import { useTextBuffer } from './components/shared/text-buffer.js';
57
- import { useVimMode, VimModeProvider } from './contexts/VimModeContext.js';
58
- import { useVim } from './hooks/vim.js';
59
- import { useKeypress } from './hooks/useKeypress.js';
60
- import { KeypressProvider } from './contexts/KeypressContext.js';
61
- import { useKittyKeyboardProtocol } from './hooks/useKittyKeyboardProtocol.js';
62
- import { keyMatchers, Command } from './keyMatchers.js';
63
- import * as fs from 'node:fs';
64
- import { UpdateNotification } from './components/UpdateNotification.js';
65
- import ansiEscapes from 'ansi-escapes';
66
- import { OverflowProvider } from './contexts/OverflowContext.js';
67
- import { ShowMoreLines } from './components/ShowMoreLines.js';
68
- import { PrivacyNotice } from './privacy/PrivacyNotice.js';
69
- import { useSettingsCommand } from './hooks/useSettingsCommand.js';
70
- import { SettingsDialog } from './components/SettingsDialog.js';
71
- import { ProQuotaDialog } from './components/ProQuotaDialog.js';
72
- import { setUpdateHandler } from '../utils/handleAutoUpdate.js';
73
- import { appEvents, AppEvent } from '../utils/events.js';
74
- import { isNarrowWidth } from './utils/isNarrowWidth.js';
75
- import { useWorkspaceMigration } from './hooks/useWorkspaceMigration.js';
76
- import { WorkspaceMigrationDialog } from './components/WorkspaceMigrationDialog.js';
77
- import { isWorkspaceTrusted } from '../config/trustedFolders.js';
78
- const CTRL_EXIT_PROMPT_DURATION_MS = 1000;
79
- // Maximum number of queued messages to display in UI to prevent performance issues
80
- const MAX_DISPLAYED_QUEUED_MESSAGES = 3;
81
- function isToolExecuting(pendingHistoryItems) {
82
- return pendingHistoryItems.some((item) => {
83
- if (item && item.type === 'tool_group') {
84
- return item.tools.some((tool) => ToolCallStatus.Executing === tool.status);
85
- }
86
- return false;
87
- });
88
- }
89
- export const AppWrapper = (props) => {
90
- const kittyProtocolStatus = useKittyKeyboardProtocol();
91
- return (_jsx(KeypressProvider, { kittyProtocolEnabled: kittyProtocolStatus.enabled, config: props.config, debugKeystrokeLogging: props.settings.merged.general?.debugKeystrokeLogging, children: _jsx(SessionStatsProvider, { children: _jsx(VimModeProvider, { settings: props.settings, children: _jsx(App, { ...props }) }) }) }));
92
- };
93
- const App = ({ config, settings, startupWarnings = [], version }) => {
94
- const isFocused = useFocus();
95
- useBracketedPaste();
96
- const [updateInfo, setUpdateInfo] = useState(null);
97
- const { stdout } = useStdout();
98
- const nightly = version.includes('nightly');
99
- const { history, addItem, clearItems, loadHistory } = useHistory();
100
- const [idePromptAnswered, setIdePromptAnswered] = useState(false);
101
- const [currentIDE, setCurrentIDE] = useState();
102
- useEffect(() => {
103
- (async () => {
104
- const ideClient = await IdeClient.getInstance();
105
- setCurrentIDE(ideClient.getCurrentIde());
106
- })();
107
- registerCleanup(async () => {
108
- const ideClient = await IdeClient.getInstance();
109
- ideClient.disconnect();
110
- });
111
- }, [config]);
112
- const shouldShowIdePrompt = currentIDE &&
113
- !config.getIdeMode() &&
114
- !settings.merged.ide?.hasSeenNudge &&
115
- !idePromptAnswered;
116
- useEffect(() => {
117
- const cleanup = setUpdateHandler(addItem, setUpdateInfo);
118
- return cleanup;
119
- }, [addItem]);
120
- const { consoleMessages, handleNewMessage, clearConsoleMessages: clearConsoleMessagesState, } = useConsoleMessages();
121
- useEffect(() => {
122
- const consolePatcher = new ConsolePatcher({
123
- onNewMessage: handleNewMessage,
124
- debugMode: config.getDebugMode(),
125
- });
126
- consolePatcher.patch();
127
- registerCleanup(consolePatcher.cleanup);
128
- }, [handleNewMessage, config]);
129
- const { stats: sessionStats } = useSessionStats();
130
- const [staticNeedsRefresh, setStaticNeedsRefresh] = useState(false);
131
- const [staticKey, setStaticKey] = useState(0);
132
- const refreshStatic = useCallback(() => {
133
- stdout.write(ansiEscapes.clearTerminal);
134
- setStaticKey((prev) => prev + 1);
135
- }, [setStaticKey, stdout]);
136
- const [geminiMdFileCount, setGeminiMdFileCount] = useState(0);
137
- const [debugMessage, setDebugMessage] = useState('');
138
- const [themeError, setThemeError] = useState(null);
139
- const [authError, setAuthError] = useState(null);
140
- const [editorError, setEditorError] = useState(null);
141
- const [footerHeight, setFooterHeight] = useState(0);
142
- const [corgiMode, setCorgiMode] = useState(false);
143
- const [isTrustedFolderState, setIsTrustedFolder] = useState(isWorkspaceTrusted(settings.merged));
144
- const [currentModel, setCurrentModel] = useState(config.getModel());
145
- const [shellModeActive, setShellModeActive] = useState(false);
146
- const [showErrorDetails, setShowErrorDetails] = useState(false);
147
- const [showToolDescriptions, setShowToolDescriptions] = useState(false);
148
- const [ctrlCPressedOnce, setCtrlCPressedOnce] = useState(false);
149
- const [quittingMessages, setQuittingMessages] = useState(null);
150
- const ctrlCTimerRef = useRef(null);
151
- const [ctrlDPressedOnce, setCtrlDPressedOnce] = useState(false);
152
- const ctrlDTimerRef = useRef(null);
153
- const [constrainHeight, setConstrainHeight] = useState(true);
154
- const [showPrivacyNotice, setShowPrivacyNotice] = useState(false);
155
- const [modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError] = useState(false);
156
- const [userTier, setUserTier] = useState(undefined);
157
- const [ideContextState, setIdeContextState] = useState();
158
- const [showEscapePrompt, setShowEscapePrompt] = useState(false);
159
- const [showIdeRestartPrompt, setShowIdeRestartPrompt] = useState(false);
160
- const [isProcessing, setIsProcessing] = useState(false);
161
- const { showWorkspaceMigrationDialog, workspaceExtensions, onWorkspaceMigrationDialogOpen, onWorkspaceMigrationDialogClose, } = useWorkspaceMigration(settings);
162
- const [isProQuotaDialogOpen, setIsProQuotaDialogOpen] = useState(false);
163
- const [proQuotaDialogResolver, setProQuotaDialogResolver] = useState(null);
164
- useEffect(() => {
165
- const unsubscribe = ideContext.subscribeToIdeContext(setIdeContextState);
166
- // Set the initial value
167
- setIdeContextState(ideContext.getIdeContext());
168
- return unsubscribe;
169
- }, []);
170
- useEffect(() => {
171
- const openDebugConsole = () => {
172
- setShowErrorDetails(true);
173
- setConstrainHeight(false); // Make sure the user sees the full message.
174
- };
175
- appEvents.on(AppEvent.OpenDebugConsole, openDebugConsole);
176
- const logErrorHandler = (errorMessage) => {
177
- handleNewMessage({
178
- type: 'error',
179
- content: String(errorMessage),
180
- count: 1,
181
- });
182
- };
183
- appEvents.on(AppEvent.LogError, logErrorHandler);
184
- return () => {
185
- appEvents.off(AppEvent.OpenDebugConsole, openDebugConsole);
186
- appEvents.off(AppEvent.LogError, logErrorHandler);
187
- };
188
- }, [handleNewMessage]);
189
- const openPrivacyNotice = useCallback(() => {
190
- setShowPrivacyNotice(true);
191
- }, []);
192
- const handleEscapePromptChange = useCallback((showPrompt) => {
193
- setShowEscapePrompt(showPrompt);
194
- }, []);
195
- const initialPromptSubmitted = useRef(false);
196
- const errorCount = useMemo(() => consoleMessages
197
- .filter((msg) => msg.type === 'error')
198
- .reduce((total, msg) => total + msg.count, 0), [consoleMessages]);
199
- const { isThemeDialogOpen, openThemeDialog, handleThemeSelect, handleThemeHighlight, } = useThemeCommand(settings, setThemeError, addItem);
200
- const { isSettingsDialogOpen, openSettingsDialog, closeSettingsDialog } = useSettingsCommand();
201
- const { isFolderTrustDialogOpen, handleFolderTrustSelect, isRestarting } = useFolderTrust(settings, setIsTrustedFolder);
202
- const { needsRestart: ideNeedsRestart } = useIdeTrustListener();
203
- useEffect(() => {
204
- if (ideNeedsRestart) {
205
- // IDE trust changed, force a restart.
206
- setShowIdeRestartPrompt(true);
207
- }
208
- }, [ideNeedsRestart]);
209
- useKeypress((key) => {
210
- if (key.name === 'r' || key.name === 'R') {
211
- process.exit(0);
212
- }
213
- }, { isActive: showIdeRestartPrompt });
214
- const { isAuthDialogOpen, openAuthDialog, handleAuthSelect, isAuthenticating, cancelAuthentication, } = useAuthCommand(settings, setAuthError, config);
215
- useEffect(() => {
216
- if (settings.merged.security?.auth?.enforcedType &&
217
- settings.merged.security?.auth.selectedType &&
218
- settings.merged.security?.auth.enforcedType !==
219
- settings.merged.security?.auth.selectedType) {
220
- setAuthError(`Authentication is enforced to be ${settings.merged.security?.auth.enforcedType}, but you are currently using ${settings.merged.security?.auth.selectedType}.`);
221
- openAuthDialog();
222
- }
223
- else if (settings.merged.security?.auth?.selectedType &&
224
- !settings.merged.security?.auth?.useExternal) {
225
- const error = validateAuthMethod(settings.merged.security.auth.selectedType);
226
- if (error) {
227
- setAuthError(error);
228
- openAuthDialog();
229
- }
230
- }
231
- }, [
232
- settings.merged.security?.auth?.selectedType,
233
- settings.merged.security?.auth?.enforcedType,
234
- settings.merged.security?.auth?.useExternal,
235
- openAuthDialog,
236
- setAuthError,
237
- ]);
238
- // Sync user tier from config when authentication changes
239
- useEffect(() => {
240
- // Only sync when not currently authenticating
241
- if (!isAuthenticating) {
242
- setUserTier(config.getGeminiClient()?.getUserTier());
243
- }
244
- }, [config, isAuthenticating]);
245
- const { isEditorDialogOpen, openEditorDialog, handleEditorSelect, exitEditorDialog, } = useEditorSettings(settings, setEditorError, addItem);
246
- const toggleCorgiMode = useCallback(() => {
247
- setCorgiMode((prev) => !prev);
248
- }, []);
249
- const performMemoryRefresh = useCallback(async () => {
250
- addItem({
251
- type: MessageType.INFO,
252
- text: 'Refreshing hierarchical memory (GEMINI.md or other context files)...',
253
- }, Date.now());
254
- try {
255
- const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(process.cwd(), settings.merged.context?.loadMemoryFromIncludeDirectories
256
- ? config.getWorkspaceContext().getDirectories()
257
- : [], config.getDebugMode(), config.getFileService(), settings.merged, config.getExtensionContextFilePaths(), config.getFolderTrust(), settings.merged.context?.importFormat || 'tree', // Use setting or default to 'tree'
258
- config.getFileFilteringOptions());
259
- config.setUserMemory(memoryContent);
260
- config.setGeminiMdFileCount(fileCount);
261
- setGeminiMdFileCount(fileCount);
262
- addItem({
263
- type: MessageType.INFO,
264
- text: `Memory refreshed successfully. ${memoryContent.length > 0 ? `Loaded ${memoryContent.length} characters from ${fileCount} file(s).` : 'No memory content found.'}`,
265
- }, Date.now());
266
- if (config.getDebugMode()) {
267
- console.log(`[DEBUG] Refreshed memory content in config: ${memoryContent.substring(0, 200)}...`);
268
- }
269
- }
270
- catch (error) {
271
- const errorMessage = getErrorMessage(error);
272
- addItem({
273
- type: MessageType.ERROR,
274
- text: `Error refreshing memory: ${errorMessage}`,
275
- }, Date.now());
276
- console.error('Error refreshing memory:', error);
277
- }
278
- }, [config, addItem, settings.merged]);
279
- // Watch for model changes (e.g., from Flash fallback)
280
- useEffect(() => {
281
- const checkModelChange = () => {
282
- const configModel = config.getModel();
283
- if (configModel !== currentModel) {
284
- setCurrentModel(configModel);
285
- }
286
- };
287
- // Check immediately and then periodically
288
- checkModelChange();
289
- const interval = setInterval(checkModelChange, 1000); // Check every second
290
- return () => clearInterval(interval);
291
- }, [config, currentModel]);
292
- // Set up Flash fallback handler
293
- useEffect(() => {
294
- const flashFallbackHandler = async (currentModel, fallbackModel, error) => {
295
- // Check if we've already switched to the fallback model
296
- if (config.isInFallbackMode()) {
297
- // If we're already in fallback mode, don't show the dialog again
298
- return false;
299
- }
300
- let message;
301
- if (config.getContentGeneratorConfig().authType ===
302
- AuthType.LOGIN_WITH_GOOGLE) {
303
- // Use actual user tier if available; otherwise, default to FREE tier behavior (safe default)
304
- const isPaidTier = userTier === UserTierId.LEGACY || userTier === UserTierId.STANDARD;
305
- // Check if this is a Pro quota exceeded error
306
- if (error && isProQuotaExceededError(error)) {
307
- if (isPaidTier) {
308
- message = `⚡ You have reached your daily ${currentModel} quota limit.
309
- ⚡ You can choose to authenticate with a paid API key or continue with the fallback model.
310
- ⚡ 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`;
311
- }
312
- else {
313
- message = `⚡ You have reached your daily ${currentModel} quota limit.
314
- ⚡ You can choose to authenticate with a paid API key or continue with the fallback model.
315
- ⚡ 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
316
- ⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
317
- ⚡ You can switch authentication methods by typing /auth`;
318
- }
319
- }
320
- else if (error && isGenericQuotaExceededError(error)) {
321
- if (isPaidTier) {
322
- message = `⚡ You have reached your daily quota limit.
323
- ⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
324
- ⚡ 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`;
325
- }
326
- else {
327
- message = `⚡ You have reached your daily quota limit.
328
- ⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
329
- ⚡ 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
330
- ⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
331
- ⚡ You can switch authentication methods by typing /auth`;
332
- }
333
- }
334
- else {
335
- if (isPaidTier) {
336
- // Default fallback message for other cases (like consecutive 429s)
337
- message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
338
- ⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
339
- ⚡ 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`;
340
- }
341
- else {
342
- // Default fallback message for other cases (like consecutive 429s)
343
- message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
344
- ⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
345
- ⚡ 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
346
- ⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
347
- ⚡ You can switch authentication methods by typing /auth`;
348
- }
349
- }
350
- // Add message to UI history
351
- addItem({
352
- type: MessageType.INFO,
353
- text: message,
354
- }, Date.now());
355
- // For Pro quota errors, show the dialog and wait for user's choice
356
- if (error && isProQuotaExceededError(error)) {
357
- // Set the flag to prevent tool continuation
358
- setModelSwitchedFromQuotaError(true);
359
- // Set global quota error flag to prevent Flash model calls
360
- config.setQuotaErrorOccurred(true);
361
- // Show the ProQuotaDialog and wait for user's choice
362
- const shouldContinueWithFallback = await new Promise((resolve) => {
363
- setIsProQuotaDialogOpen(true);
364
- setProQuotaDialogResolver(() => resolve);
365
- });
366
- // If user chose to continue with fallback, we don't need to stop the current prompt
367
- if (shouldContinueWithFallback) {
368
- // Switch to fallback model for future use
369
- config.setModel(fallbackModel);
370
- config.setFallbackMode(true);
371
- logFlashFallback(config, new FlashFallbackEvent(config.getContentGeneratorConfig().authType));
372
- return true; // Continue with current prompt using fallback model
373
- }
374
- // If user chose to authenticate, stop current prompt
375
- return false;
376
- }
377
- // For other quota errors, automatically switch to fallback model
378
- // Set the flag to prevent tool continuation
379
- setModelSwitchedFromQuotaError(true);
380
- // Set global quota error flag to prevent Flash model calls
381
- config.setQuotaErrorOccurred(true);
382
- }
383
- // Switch model for future use but return false to stop current retry
384
- config.setModel(fallbackModel);
385
- config.setFallbackMode(true);
386
- logFlashFallback(config, new FlashFallbackEvent(config.getContentGeneratorConfig().authType));
387
- return false; // Don't continue with current prompt
388
- };
389
- config.setFlashFallbackHandler(flashFallbackHandler);
390
- }, [config, addItem, userTier]);
391
- // Terminal and UI setup
392
- const { rows: terminalHeight, columns: terminalWidth } = useTerminalSize();
393
- const isNarrow = isNarrowWidth(terminalWidth);
394
- const { stdin, setRawMode } = useStdin();
395
- const isInitialMount = useRef(true);
396
- const widthFraction = 0.9;
397
- const inputWidth = Math.max(20, Math.floor(terminalWidth * widthFraction) - 3);
398
- const suggestionsWidth = Math.max(20, Math.floor(terminalWidth * 0.8));
399
- // Utility callbacks
400
- const isValidPath = useCallback((filePath) => {
401
- try {
402
- return fs.existsSync(filePath) && fs.statSync(filePath).isFile();
403
- }
404
- catch (_e) {
405
- return false;
406
- }
407
- }, []);
408
- const getPreferredEditor = useCallback(() => {
409
- const editorType = settings.merged.general?.preferredEditor;
410
- const isValidEditor = isEditorAvailable(editorType);
411
- if (!isValidEditor) {
412
- openEditorDialog();
413
- return;
414
- }
415
- return editorType;
416
- }, [settings, openEditorDialog]);
417
- const onAuthError = useCallback(() => {
418
- setAuthError('reauth required');
419
- openAuthDialog();
420
- }, [openAuthDialog, setAuthError]);
421
- // Core hooks and processors
422
- const { vimEnabled: vimModeEnabled, vimMode, toggleVimEnabled, } = useVimMode();
423
- const { handleSlashCommand, slashCommands, pendingHistoryItems: pendingSlashCommandHistoryItems, commandContext, shellConfirmationRequest, confirmationRequest, } = useSlashCommandProcessor(config, settings, addItem, clearItems, loadHistory, refreshStatic, setDebugMessage, openThemeDialog, openAuthDialog, openEditorDialog, toggleCorgiMode, setQuittingMessages, openPrivacyNotice, openSettingsDialog, toggleVimEnabled, setIsProcessing, setGeminiMdFileCount);
424
- const buffer = useTextBuffer({
425
- initialText: '',
426
- viewport: { height: 10, width: inputWidth },
427
- stdin,
428
- setRawMode,
429
- isValidPath,
430
- shellModeActive,
431
- });
432
- // Independent input history management (unaffected by /clear)
433
- const inputHistoryStore = useInputHistoryStore();
434
- // Stable reference for cancel handler to avoid circular dependency
435
- const cancelHandlerRef = useRef(() => { });
436
- const { streamingState, submitQuery, initError, pendingHistoryItems: pendingGeminiHistoryItems, thought, cancelOngoingRequest, } = useGeminiStream(config.getGeminiClient(), history, addItem, config, settings, setDebugMessage, handleSlashCommand, shellModeActive, getPreferredEditor, onAuthError, performMemoryRefresh, modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError, refreshStatic, () => cancelHandlerRef.current());
437
- const pendingHistoryItems = useMemo(() => [...pendingSlashCommandHistoryItems, ...pendingGeminiHistoryItems], [pendingSlashCommandHistoryItems, pendingGeminiHistoryItems]);
438
- // Message queue for handling input during streaming
439
- const { messageQueue, addMessage, clearQueue, getQueuedMessagesText } = useMessageQueue({
440
- streamingState,
441
- submitQuery,
442
- });
443
- // Update the cancel handler with message queue support
444
- cancelHandlerRef.current = useCallback(() => {
445
- if (isToolExecuting(pendingHistoryItems)) {
446
- buffer.setText(''); // Just clear the prompt
447
- return;
448
- }
449
- const lastUserMessage = inputHistoryStore.inputHistory.at(-1);
450
- let textToSet = lastUserMessage || '';
451
- // Append queued messages if any exist
452
- const queuedText = getQueuedMessagesText();
453
- if (queuedText) {
454
- textToSet = textToSet ? `${textToSet}\n\n${queuedText}` : queuedText;
455
- clearQueue();
456
- }
457
- if (textToSet) {
458
- buffer.setText(textToSet);
459
- }
460
- }, [
461
- buffer,
462
- inputHistoryStore.inputHistory,
463
- getQueuedMessagesText,
464
- clearQueue,
465
- pendingHistoryItems,
466
- ]);
467
- // Input handling - queue messages for processing
468
- const handleFinalSubmit = useCallback((submittedValue) => {
469
- const trimmedValue = submittedValue.trim();
470
- if (trimmedValue.length > 0) {
471
- // Add to independent input history
472
- inputHistoryStore.addInput(trimmedValue);
473
- }
474
- // Always add to message queue
475
- addMessage(submittedValue);
476
- }, [addMessage, inputHistoryStore]);
477
- const handleIdePromptComplete = useCallback((result) => {
478
- if (result.userSelection === 'yes') {
479
- if (result.isExtensionPreInstalled) {
480
- handleSlashCommand('/ide enable');
481
- }
482
- else {
483
- handleSlashCommand('/ide install');
484
- }
485
- settings.setValue(SettingScope.User, 'hasSeenIdeIntegrationNudge', true);
486
- }
487
- else if (result.userSelection === 'dismiss') {
488
- settings.setValue(SettingScope.User, 'hasSeenIdeIntegrationNudge', true);
489
- }
490
- setIdePromptAnswered(true);
491
- }, [handleSlashCommand, settings]);
492
- const { handleInput: vimHandleInput } = useVim(buffer, handleFinalSubmit);
493
- const { elapsedTime, currentLoadingPhrase } = useLoadingIndicator(streamingState, settings.merged.ui?.customWittyPhrases);
494
- const showAutoAcceptIndicator = useAutoAcceptIndicator({ config, addItem });
495
- const handleExit = useCallback((pressedOnce, setPressedOnce, timerRef) => {
496
- if (pressedOnce) {
497
- if (timerRef.current) {
498
- clearTimeout(timerRef.current);
499
- }
500
- // Directly invoke the central command handler.
501
- handleSlashCommand('/quit');
502
- }
503
- else {
504
- setPressedOnce(true);
505
- timerRef.current = setTimeout(() => {
506
- setPressedOnce(false);
507
- timerRef.current = null;
508
- }, CTRL_EXIT_PROMPT_DURATION_MS);
509
- }
510
- }, [handleSlashCommand]);
511
- const handleGlobalKeypress = useCallback((key) => {
512
- // Debug log keystrokes if enabled
513
- if (settings.merged.general?.debugKeystrokeLogging) {
514
- console.log('[DEBUG] Keystroke:', JSON.stringify(key));
515
- }
516
- let enteringConstrainHeightMode = false;
517
- if (!constrainHeight) {
518
- enteringConstrainHeightMode = true;
519
- setConstrainHeight(true);
520
- }
521
- if (keyMatchers[Command.SHOW_ERROR_DETAILS](key)) {
522
- setShowErrorDetails((prev) => !prev);
523
- }
524
- else if (keyMatchers[Command.TOGGLE_TOOL_DESCRIPTIONS](key)) {
525
- const newValue = !showToolDescriptions;
526
- setShowToolDescriptions(newValue);
527
- const mcpServers = config.getMcpServers();
528
- if (Object.keys(mcpServers || {}).length > 0) {
529
- handleSlashCommand(newValue ? '/mcp desc' : '/mcp nodesc');
530
- }
531
- }
532
- else if (keyMatchers[Command.TOGGLE_IDE_CONTEXT_DETAIL](key) &&
533
- config.getIdeMode() &&
534
- ideContextState) {
535
- // Show IDE status when in IDE mode and context is available.
536
- handleSlashCommand('/ide status');
537
- }
538
- else if (keyMatchers[Command.QUIT](key)) {
539
- // When authenticating, let AuthInProgress component handle Ctrl+C.
540
- if (isAuthenticating) {
541
- return;
542
- }
543
- if (!ctrlCPressedOnce) {
544
- cancelOngoingRequest?.();
545
- }
546
- handleExit(ctrlCPressedOnce, setCtrlCPressedOnce, ctrlCTimerRef);
547
- }
548
- else if (keyMatchers[Command.EXIT](key)) {
549
- if (buffer.text.length > 0) {
550
- return;
551
- }
552
- handleExit(ctrlDPressedOnce, setCtrlDPressedOnce, ctrlDTimerRef);
553
- }
554
- else if (keyMatchers[Command.SHOW_MORE_LINES](key) &&
555
- !enteringConstrainHeightMode) {
556
- setConstrainHeight(false);
557
- }
558
- }, [
559
- constrainHeight,
560
- setConstrainHeight,
561
- setShowErrorDetails,
562
- showToolDescriptions,
563
- setShowToolDescriptions,
564
- config,
565
- ideContextState,
566
- handleExit,
567
- ctrlCPressedOnce,
568
- setCtrlCPressedOnce,
569
- ctrlCTimerRef,
570
- buffer.text.length,
571
- ctrlDPressedOnce,
572
- setCtrlDPressedOnce,
573
- ctrlDTimerRef,
574
- handleSlashCommand,
575
- isAuthenticating,
576
- cancelOngoingRequest,
577
- settings.merged.general?.debugKeystrokeLogging,
578
- ]);
579
- useKeypress(handleGlobalKeypress, {
580
- isActive: true,
581
- });
582
- useEffect(() => {
583
- if (config) {
584
- setGeminiMdFileCount(config.getGeminiMdFileCount());
585
- }
586
- }, [config, config.getGeminiMdFileCount]);
587
- const logger = useLogger(config.storage);
588
- // Initialize independent input history from logger
589
- useEffect(() => {
590
- inputHistoryStore.initializeFromLogger(logger);
591
- }, [logger, inputHistoryStore]);
592
- const isInputActive = (streamingState === StreamingState.Idle ||
593
- streamingState === StreamingState.Responding) &&
594
- !initError &&
595
- !isProcessing &&
596
- !isProQuotaDialogOpen;
597
- const handleClearScreen = useCallback(() => {
598
- clearItems();
599
- clearConsoleMessagesState();
600
- console.clear();
601
- refreshStatic();
602
- }, [clearItems, clearConsoleMessagesState, refreshStatic]);
603
- const mainControlsRef = useRef(null);
604
- const pendingHistoryItemRef = useRef(null);
605
- useEffect(() => {
606
- if (mainControlsRef.current) {
607
- const fullFooterMeasurement = measureElement(mainControlsRef.current);
608
- setFooterHeight(fullFooterMeasurement.height);
609
- }
610
- }, [terminalHeight, consoleMessages, showErrorDetails]);
611
- const staticExtraHeight = /* margins and padding */ 3;
612
- const availableTerminalHeight = useMemo(() => terminalHeight - footerHeight - staticExtraHeight, [terminalHeight, footerHeight]);
613
- useEffect(() => {
614
- // skip refreshing Static during first mount
615
- if (isInitialMount.current) {
616
- isInitialMount.current = false;
617
- return;
618
- }
619
- // debounce so it doesn't fire up too often during resize
620
- const handler = setTimeout(() => {
621
- setStaticNeedsRefresh(false);
622
- refreshStatic();
623
- }, 300);
624
- return () => {
625
- clearTimeout(handler);
626
- };
627
- }, [terminalWidth, terminalHeight, refreshStatic]);
628
- useEffect(() => {
629
- if (streamingState === StreamingState.Idle && staticNeedsRefresh) {
630
- setStaticNeedsRefresh(false);
631
- refreshStatic();
632
- }
633
- }, [streamingState, refreshStatic, staticNeedsRefresh]);
634
- const filteredConsoleMessages = useMemo(() => {
635
- if (config.getDebugMode()) {
636
- return consoleMessages;
637
- }
638
- return consoleMessages.filter((msg) => msg.type !== 'debug');
639
- }, [consoleMessages, config]);
640
- const branchName = useGitBranchName(config.getTargetDir());
641
- const contextFileNames = useMemo(() => {
642
- const fromSettings = settings.merged.context?.fileName;
643
- if (fromSettings) {
644
- return Array.isArray(fromSettings) ? fromSettings : [fromSettings];
645
- }
646
- return getAllGeminiMdFilenames();
647
- }, [settings.merged.context?.fileName]);
648
- const initialPrompt = useMemo(() => config.getQuestion(), [config]);
649
- const geminiClient = config.getGeminiClient();
650
- useEffect(() => {
651
- if (initialPrompt &&
652
- !initialPromptSubmitted.current &&
653
- !isAuthenticating &&
654
- !isAuthDialogOpen &&
655
- !isThemeDialogOpen &&
656
- !isEditorDialogOpen &&
657
- !showPrivacyNotice &&
658
- geminiClient?.isInitialized?.()) {
659
- submitQuery(initialPrompt);
660
- initialPromptSubmitted.current = true;
661
- }
662
- }, [
663
- initialPrompt,
664
- submitQuery,
665
- isAuthenticating,
666
- isAuthDialogOpen,
667
- isThemeDialogOpen,
668
- isEditorDialogOpen,
669
- showPrivacyNotice,
670
- geminiClient,
671
- ]);
672
- if (quittingMessages) {
673
- return (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: quittingMessages.map((item) => (_jsx(HistoryItemDisplay, { availableTerminalHeight: constrainHeight ? availableTerminalHeight : undefined, terminalWidth: terminalWidth, item: item, isPending: false, config: config }, item.id))) }));
9
+ import { Notifications } from './components/Notifications.js';
10
+ import { MainContent } from './components/MainContent.js';
11
+ import { DialogManager } from './components/DialogManager.js';
12
+ import { Composer } from './components/Composer.js';
13
+ import { useUIState } from './contexts/UIStateContext.js';
14
+ import { QuittingDisplay } from './components/QuittingDisplay.js';
15
+ export const App = () => {
16
+ const uiState = useUIState();
17
+ if (uiState.quittingMessages) {
18
+ return _jsx(QuittingDisplay, {});
674
19
  }
675
- const mainAreaWidth = Math.floor(terminalWidth * 0.9);
676
- const debugConsoleMaxHeight = Math.floor(Math.max(terminalHeight * 0.2, 5));
677
- // Arbitrary threshold to ensure that items in the static area are large
678
- // enough but not too large to make the terminal hard to use.
679
- const staticAreaMaxItemHeight = Math.max(terminalHeight * 4, 100);
680
- const placeholder = vimModeEnabled
681
- ? " Press 'i' for INSERT mode and 'Esc' for NORMAL mode."
682
- : ' Type your message or @path/to/file';
683
- const hideContextSummary = settings.merged.ui?.hideContextSummary ?? false;
684
- return (_jsx(StreamingContext.Provider, { value: streamingState, children: _jsxs(Box, { flexDirection: "column", width: "90%", children: [_jsx(Static, { items: [
685
- _jsxs(Box, { flexDirection: "column", children: [!(settings.merged.ui?.hideBanner || config.getScreenReader()) && _jsx(Header, { version: version, nightly: nightly }), !(settings.merged.ui?.hideTips || config.getScreenReader()) && (_jsx(Tips, { config: config }))] }, "header"),
686
- ...history.map((h) => (_jsx(HistoryItemDisplay, { terminalWidth: mainAreaWidth, availableTerminalHeight: staticAreaMaxItemHeight, item: h, isPending: false, config: config, commands: slashCommands }, h.id))),
687
- ], children: (item) => item }, staticKey), _jsx(OverflowProvider, { children: _jsxs(Box, { ref: pendingHistoryItemRef, flexDirection: "column", children: [pendingHistoryItems.map((item, i) => (_jsx(HistoryItemDisplay, { availableTerminalHeight: constrainHeight ? availableTerminalHeight : undefined, terminalWidth: mainAreaWidth,
688
- // TODO(taehykim): It seems like references to ids aren't necessary in
689
- // HistoryItemDisplay. Refactor later. Use a fake id for now.
690
- item: { ...item, id: 0 }, isPending: true, config: config, isFocused: !isEditorDialogOpen }, i))), _jsx(ShowMoreLines, { constrainHeight: constrainHeight })] }) }), _jsxs(Box, { flexDirection: "column", ref: mainControlsRef, children: [updateInfo && _jsx(UpdateNotification, { message: updateInfo.message }), startupWarnings.length > 0 && (_jsx(Box, { borderStyle: "round", borderColor: Colors.AccentYellow, paddingX: 1, marginY: 1, flexDirection: "column", children: startupWarnings.map((warning, index) => (_jsx(Text, { color: Colors.AccentYellow, children: warning }, index))) })), showWorkspaceMigrationDialog ? (_jsx(WorkspaceMigrationDialog, { workspaceExtensions: workspaceExtensions, onOpen: onWorkspaceMigrationDialogOpen, onClose: onWorkspaceMigrationDialogClose })) : shouldShowIdePrompt && currentIDE ? (_jsx(IdeIntegrationNudge, { ide: currentIDE, onComplete: handleIdePromptComplete })) : isProQuotaDialogOpen ? (_jsx(ProQuotaDialog, { currentModel: config.getModel(), fallbackModel: DEFAULT_GEMINI_FLASH_MODEL, onChoice: (choice) => {
691
- setIsProQuotaDialogOpen(false);
692
- if (!proQuotaDialogResolver)
693
- return;
694
- const resolveValue = choice !== 'auth';
695
- proQuotaDialogResolver(resolveValue);
696
- setProQuotaDialogResolver(null);
697
- if (choice === 'auth') {
698
- openAuthDialog();
699
- }
700
- else {
701
- addItem({
702
- type: MessageType.INFO,
703
- text: 'Switched to fallback model. Tip: Press Ctrl+P to recall your previous prompt and submit it again if you wish.',
704
- }, Date.now());
705
- }
706
- } })) : showIdeRestartPrompt ? (_jsx(Box, { borderStyle: "round", borderColor: Colors.AccentYellow, paddingX: 1, children: _jsx(Text, { color: Colors.AccentYellow, children: "Workspace trust has changed. Press 'r' to restart Gemini to apply the changes." }) })) : isFolderTrustDialogOpen ? (_jsx(FolderTrustDialog, { onSelect: handleFolderTrustSelect, isRestarting: isRestarting })) : shellConfirmationRequest ? (_jsx(ShellConfirmationDialog, { request: shellConfirmationRequest })) : confirmationRequest ? (_jsxs(Box, { flexDirection: "column", children: [confirmationRequest.prompt, _jsx(Box, { paddingY: 1, children: _jsx(RadioButtonSelect, { isFocused: !!confirmationRequest, items: [
707
- { label: 'Yes', value: true },
708
- { label: 'No', value: false },
709
- ], onSelect: (value) => {
710
- confirmationRequest.onConfirm(value);
711
- } }) })] })) : isThemeDialogOpen ? (_jsxs(Box, { flexDirection: "column", children: [themeError && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: Colors.AccentRed, children: themeError }) })), _jsx(ThemeDialog, { onSelect: handleThemeSelect, onHighlight: handleThemeHighlight, settings: settings, availableTerminalHeight: constrainHeight
712
- ? terminalHeight - staticExtraHeight
713
- : undefined, terminalWidth: mainAreaWidth })] })) : isSettingsDialogOpen ? (_jsx(Box, { flexDirection: "column", children: _jsx(SettingsDialog, { settings: settings, onSelect: () => closeSettingsDialog(), onRestartRequest: () => process.exit(0) }) })) : isAuthenticating ? (_jsxs(_Fragment, { children: [_jsx(AuthInProgress, { onTimeout: () => {
714
- setAuthError('Authentication timed out. Please try again.');
715
- cancelAuthentication();
716
- openAuthDialog();
717
- } }), showErrorDetails && (_jsx(OverflowProvider, { children: _jsxs(Box, { flexDirection: "column", children: [_jsx(DetailedMessagesDisplay, { messages: filteredConsoleMessages, maxHeight: constrainHeight ? debugConsoleMaxHeight : undefined, width: inputWidth }), _jsx(ShowMoreLines, { constrainHeight: constrainHeight })] }) }))] })) : isAuthDialogOpen ? (_jsx(Box, { flexDirection: "column", children: _jsx(AuthDialog, { onSelect: handleAuthSelect, settings: settings, initialErrorMessage: authError }) })) : isEditorDialogOpen ? (_jsxs(Box, { flexDirection: "column", children: [editorError && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: Colors.AccentRed, children: editorError }) })), _jsx(EditorSettingsDialog, { onSelect: handleEditorSelect, settings: settings, onExit: exitEditorDialog })] })) : showPrivacyNotice ? (_jsx(PrivacyNotice, { onExit: () => setShowPrivacyNotice(false), config: config })) : (_jsxs(_Fragment, { children: [_jsx(LoadingIndicator, { thought: streamingState === StreamingState.WaitingForConfirmation ||
718
- config.getAccessibility()?.disableLoadingPhrases ||
719
- config.getScreenReader()
720
- ? undefined
721
- : thought, currentLoadingPhrase: config.getAccessibility()?.disableLoadingPhrases ||
722
- config.getScreenReader()
723
- ? undefined
724
- : currentLoadingPhrase, elapsedTime: elapsedTime }), messageQueue.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [messageQueue
725
- .slice(0, MAX_DISPLAYED_QUEUED_MESSAGES)
726
- .map((message, index) => {
727
- // Ensure multi-line messages are collapsed for the preview.
728
- // Replace all whitespace (including newlines) with a single space.
729
- const preview = message.replace(/\s+/g, ' ');
730
- return (
731
- // Ensure the Box takes full width so truncation calculates correctly
732
- _jsx(Box, { paddingLeft: 2, width: "100%", children: _jsx(Text, { dimColor: true, wrap: "truncate", children: preview }) }, index));
733
- }), messageQueue.length > MAX_DISPLAYED_QUEUED_MESSAGES && (_jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { dimColor: true, children: ["... (+", messageQueue.length - MAX_DISPLAYED_QUEUED_MESSAGES, "more)"] }) }))] })), _jsxs(Box, { marginTop: 1, justifyContent: hideContextSummary ? 'flex-start' : 'space-between', width: "100%", flexDirection: isNarrow ? 'column' : 'row', alignItems: isNarrow ? 'flex-start' : 'center', children: [_jsxs(Box, { children: [process.env['GEMINI_SYSTEM_MD'] && (_jsx(Text, { color: Colors.AccentRed, children: "|\u2310\u25A0_\u25A0| " })), ctrlCPressedOnce ? (_jsx(Text, { color: Colors.AccentYellow, children: "Press Ctrl+C again to exit." })) : ctrlDPressedOnce ? (_jsx(Text, { color: Colors.AccentYellow, children: "Press Ctrl+D again to exit." })) : showEscapePrompt ? (_jsx(Text, { color: Colors.Gray, children: "Press Esc again to clear." })) : !hideContextSummary ? (_jsx(ContextSummaryDisplay, { ideContext: ideContextState, geminiMdFileCount: geminiMdFileCount, contextFileNames: contextFileNames, mcpServers: config.getMcpServers(), blockedMcpServers: config.getBlockedMcpServers(), showToolDescriptions: showToolDescriptions })) : null] }), _jsxs(Box, { paddingTop: isNarrow ? 1 : 0, marginLeft: hideContextSummary ? 1 : 2, children: [showAutoAcceptIndicator !== ApprovalMode.DEFAULT &&
734
- !shellModeActive && (_jsx(AutoAcceptIndicator, { approvalMode: showAutoAcceptIndicator })), shellModeActive && _jsx(ShellModeIndicator, {})] })] }), showErrorDetails && (_jsx(OverflowProvider, { children: _jsxs(Box, { flexDirection: "column", children: [_jsx(DetailedMessagesDisplay, { messages: filteredConsoleMessages, maxHeight: constrainHeight ? debugConsoleMaxHeight : undefined, width: inputWidth }), _jsx(ShowMoreLines, { constrainHeight: constrainHeight })] }) })), isInputActive && (_jsx(InputPrompt, { buffer: buffer, inputWidth: inputWidth, suggestionsWidth: suggestionsWidth, onSubmit: handleFinalSubmit, userMessages: inputHistoryStore.inputHistory, onClearScreen: handleClearScreen, config: config, slashCommands: slashCommands, commandContext: commandContext, shellModeActive: shellModeActive, setShellModeActive: setShellModeActive, onEscapePromptChange: handleEscapePromptChange, focus: isFocused, vimHandleInput: vimHandleInput, placeholder: placeholder }))] })), initError && streamingState !== StreamingState.Responding && (_jsx(Box, { borderStyle: "round", borderColor: Colors.AccentRed, paddingX: 1, marginBottom: 1, children: history.find((item) => item.type === 'error' && item.text?.includes(initError))?.text ? (_jsx(Text, { color: Colors.AccentRed, children: history.find((item) => item.type === 'error' && item.text?.includes(initError))?.text })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { color: Colors.AccentRed, children: ["Initialization Error: ", initError] }), _jsxs(Text, { color: Colors.AccentRed, children: [' ', "Please check API key and configuration."] })] })) })), !settings.merged.ui?.hideFooter && (_jsx(Footer, { model: currentModel, targetDir: config.getTargetDir(), debugMode: config.getDebugMode(), branchName: branchName, debugMessage: debugMessage, corgiMode: corgiMode, errorCount: errorCount, showErrorDetails: showErrorDetails, showMemoryUsage: config.getDebugMode() ||
735
- settings.merged.ui?.showMemoryUsage ||
736
- false, promptTokenCount: sessionStats.lastPromptTokenCount, nightly: nightly, vimMode: vimModeEnabled ? vimMode : undefined, isTrustedFolder: isTrustedFolderState, hideCWD: settings.merged.ui?.footer?.hideCWD, hideSandboxStatus: settings.merged.ui?.footer?.hideSandboxStatus, hideModelInfo: settings.merged.ui?.footer?.hideModelInfo }))] })] }) }));
20
+ return (_jsx(StreamingContext.Provider, { value: uiState.streamingState, children: _jsxs(Box, { flexDirection: "column", width: "90%", children: [_jsx(MainContent, {}), _jsxs(Box, { flexDirection: "column", ref: uiState.mainControlsRef, children: [_jsx(Notifications, {}), uiState.dialogsVisible ? _jsx(DialogManager, {}) : _jsx(Composer, {})] })] }) }));
737
21
  };
738
22
  //# sourceMappingURL=App.js.map