@vybestack/llxprt-code 0.1.14-nightly.250729.2076f7c6 → 0.1.15
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/README.md +53 -0
- package/dist/package.json +4 -5
- package/dist/src/config/extension.d.ts +1 -0
- package/dist/src/config/extension.js +4 -0
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/settings.d.ts +2 -1
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/gemini.d.ts +1 -0
- package/dist/src/gemini.js +35 -15
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +2 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/CommandService.d.ts +8 -4
- package/dist/src/services/CommandService.js +24 -8
- package/dist/src/services/CommandService.js.map +1 -1
- package/dist/src/services/FileCommandLoader.d.ts +15 -3
- package/dist/src/services/FileCommandLoader.js +94 -42
- package/dist/src/services/FileCommandLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.d.ts +25 -0
- package/dist/src/services/McpPromptLoader.js +192 -0
- package/dist/src/services/McpPromptLoader.js.map +1 -0
- package/dist/src/services/prompt-processors/shellProcessor.d.ts +32 -0
- package/dist/src/services/prompt-processors/shellProcessor.js +77 -0
- package/dist/src/services/prompt-processors/shellProcessor.js.map +1 -0
- package/dist/src/services/prompt-processors/types.d.ts +4 -0
- package/dist/src/services/prompt-processors/types.js +4 -0
- package/dist/src/services/prompt-processors/types.js.map +1 -1
- package/dist/src/ui/App.js +312 -195
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +39 -1
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/initCommand.d.ts +7 -0
- package/dist/src/ui/commands/initCommand.js +76 -0
- package/dist/src/ui/commands/initCommand.js.map +1 -0
- package/dist/src/ui/commands/mcpCommand.js +53 -8
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +22 -3
- package/dist/src/ui/commands/types.js +1 -0
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/commands/vimCommand.js +0 -7
- package/dist/src/ui/commands/vimCommand.js.map +1 -1
- package/dist/src/ui/components/ContextSummaryDisplay.d.ts +3 -3
- package/dist/src/ui/components/ContextSummaryDisplay.js +8 -8
- package/dist/src/ui/components/ContextSummaryDisplay.js.map +1 -1
- package/dist/src/ui/components/Footer.d.ts +1 -0
- package/dist/src/ui/components/Footer.js +2 -2
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Header.js +1 -1
- package/dist/src/ui/components/Header.js.map +1 -1
- package/dist/src/ui/components/Help.js +2 -2
- package/dist/src/ui/components/Help.js.map +1 -1
- package/dist/src/ui/components/IDEContextDetailDisplay.d.ts +4 -4
- package/dist/src/ui/components/IDEContextDetailDisplay.js +5 -7
- package/dist/src/ui/components/IDEContextDetailDisplay.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.d.ts +2 -0
- package/dist/src/ui/components/InputPrompt.js +5 -1
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.d.ts +15 -0
- package/dist/src/ui/components/ShellConfirmationDialog.js +45 -0
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -0
- package/dist/src/ui/components/Tips.js +1 -1
- package/dist/src/ui/components/Tips.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.d.ts +270 -2
- package/dist/src/ui/components/shared/text-buffer.js +415 -70
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/vim-buffer-actions.d.ts +72 -0
- package/dist/src/ui/components/shared/vim-buffer-actions.js +565 -0
- package/dist/src/ui/components/shared/vim-buffer-actions.js.map +1 -0
- package/dist/src/ui/contexts/VimModeContext.js +2 -2
- package/dist/src/ui/contexts/VimModeContext.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.d.ts +1 -0
- package/dist/src/ui/hooks/shellCommandProcessor.js +139 -200
- package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +7 -3
- package/dist/src/ui/hooks/slashCommandProcessor.js +208 -129
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useCompletion.js +7 -2
- package/dist/src/ui/hooks/useCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.js +53 -37
- package/dist/src/ui/hooks/useConsoleMessages.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +14 -2
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useKeypress.js +5 -2
- package/dist/src/ui/hooks/useKeypress.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +0 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/vim.d.ts +28 -0
- package/dist/src/ui/hooks/vim.js +630 -0
- package/dist/src/ui/hooks/vim.js.map +1 -0
- package/dist/src/ui/themes/theme-manager.js +10 -1
- package/dist/src/ui/themes/theme-manager.js.map +1 -1
- package/dist/src/ui/themes/theme.d.ts +1 -0
- package/dist/src/ui/themes/theme.js +19 -4
- package/dist/src/ui/themes/theme.js.map +1 -1
- package/dist/src/ui/utils/textUtils.d.ts +0 -8
- package/dist/src/ui/utils/textUtils.js +0 -22
- package/dist/src/ui/utils/textUtils.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.d.ts +7 -1
- package/dist/src/ui/utils/updateCheck.js +17 -28
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/utils/events.d.ts +11 -0
- package/dist/src/utils/events.js +13 -0
- package/dist/src/utils/events.js.map +1 -0
- package/dist/src/utils/handleAutoUpdate.d.ts +10 -0
- package/dist/src/utils/handleAutoUpdate.js +97 -0
- package/dist/src/utils/handleAutoUpdate.js.map +1 -0
- package/dist/src/utils/installationInfo.d.ts +23 -0
- package/dist/src/utils/installationInfo.js +154 -0
- package/dist/src/utils/installationInfo.js.map +1 -0
- package/dist/src/utils/updateEventEmitter.d.ts +11 -0
- package/dist/src/utils/updateEventEmitter.js +12 -0
- package/dist/src/utils/updateEventEmitter.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -5
package/dist/src/ui/App.js
CHANGED
@@ -4,18 +4,15 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
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, Static, Text, useStdin, useStdout, useInput, } from 'ink';
|
9
|
-
import { StreamingState } from './types.js';
|
7
|
+
import { useCallback, useEffect, useMemo, useState, useRef, useReducer, } from 'react';
|
8
|
+
import { Box, measureElement, Static, Text, useStdin, useStdout, useInput, } from 'ink';
|
9
|
+
import { StreamingState, MessageType } from './types.js';
|
10
|
+
import { useTerminalSize } from './hooks/useTerminalSize.js';
|
10
11
|
import { useGeminiStream } from './hooks/useGeminiStream.js';
|
11
12
|
import { useLoadingIndicator } from './hooks/useLoadingIndicator.js';
|
12
13
|
import { useThemeCommand } from './hooks/useThemeCommand.js';
|
13
14
|
import { useAuthCommand } from './hooks/useAuthCommand.js';
|
14
15
|
import { useEditorSettings } from './hooks/useEditorSettings.js';
|
15
|
-
import { useProviderModelDialog } from './hooks/useProviderModelDialog.js';
|
16
|
-
import { useProviderDialog } from './hooks/useProviderDialog.js';
|
17
|
-
import { ProviderModelDialog } from './components/ProviderModelDialog.js';
|
18
|
-
import { ProviderDialog } from './components/ProviderDialog.js';
|
19
16
|
import { useSlashCommandProcessor } from './hooks/slashCommandProcessor.js';
|
20
17
|
import { useAutoAcceptIndicator } from './hooks/useAutoAcceptIndicator.js';
|
21
18
|
import { useConsoleMessages } from './hooks/useConsoleMessages.js';
|
@@ -29,8 +26,10 @@ import { ThemeDialog } from './components/ThemeDialog.js';
|
|
29
26
|
import { AuthDialog } from './components/AuthDialog.js';
|
30
27
|
import { AuthInProgress } from './components/AuthInProgress.js';
|
31
28
|
import { EditorSettingsDialog } from './components/EditorSettingsDialog.js';
|
29
|
+
import { ShellConfirmationDialog } from './components/ShellConfirmationDialog.js';
|
32
30
|
import { Colors } from './colors.js';
|
33
31
|
import { Help } from './components/Help.js';
|
32
|
+
import { loadHierarchicalLlxprtMemory } from '../config/config.js';
|
34
33
|
import { Tips } from './components/Tips.js';
|
35
34
|
import { ConsolePatcher } from './utils/ConsolePatcher.js';
|
36
35
|
import { registerCleanup } from '../utils/cleanup.js';
|
@@ -38,9 +37,9 @@ import { DetailedMessagesDisplay } from './components/DetailedMessagesDisplay.js
|
|
38
37
|
import { HistoryItemDisplay } from './components/HistoryItemDisplay.js';
|
39
38
|
import { ContextSummaryDisplay } from './components/ContextSummaryDisplay.js';
|
40
39
|
import { IDEContextDetailDisplay } from './components/IDEContextDetailDisplay.js';
|
41
|
-
|
40
|
+
import { useHistory } from './hooks/useHistoryManager.js';
|
42
41
|
import process from 'node:process';
|
43
|
-
import { getAllLlxprtMdFilenames, ApprovalMode, isEditorAvailable, ideContext, } from '@vybestack/llxprt-code-core';
|
42
|
+
import { getErrorMessage, getAllLlxprtMdFilenames, ApprovalMode, isEditorAvailable, FlashFallbackEvent, logFlashFallback, AuthType, ideContext, } from '@vybestack/llxprt-code-core';
|
44
43
|
import { validateAuthMethod } from '../config/auth.js';
|
45
44
|
import { useLogger } from './hooks/useLogger.js';
|
46
45
|
import { StreamingContext } from './contexts/StreamingContext.js';
|
@@ -49,32 +48,43 @@ import { useGitBranchName } from './hooks/useGitBranchName.js';
|
|
49
48
|
import { useFocus } from './hooks/useFocus.js';
|
50
49
|
import { useBracketedPaste } from './hooks/useBracketedPaste.js';
|
51
50
|
import { useTextBuffer } from './components/shared/text-buffer.js';
|
51
|
+
import { useVimMode, VimModeProvider } from './contexts/VimModeContext.js';
|
52
|
+
import { useVim } from './hooks/vim.js';
|
52
53
|
import * as fs from 'fs';
|
54
|
+
import { appReducer, initialAppState, } from './reducers/appReducer.js';
|
55
|
+
import { AppDispatchProvider } from './contexts/AppDispatchContext.js';
|
53
56
|
import { UpdateNotification } from './components/UpdateNotification.js';
|
54
|
-
|
55
|
-
import { checkForUpdates } from './utils/updateCheck.js';
|
57
|
+
import { isProQuotaExceededError, isGenericQuotaExceededError, UserTierId, } from '@vybestack/llxprt-code-core';
|
56
58
|
import ansiEscapes from 'ansi-escapes';
|
57
59
|
import { OverflowProvider } from './contexts/OverflowContext.js';
|
58
60
|
import { ShowMoreLines } from './components/ShowMoreLines.js';
|
59
61
|
import { PrivacyNotice } from './privacy/PrivacyNotice.js';
|
62
|
+
import { setUpdateHandler } from '../utils/handleAutoUpdate.js';
|
63
|
+
import { appEvents, AppEvent } from '../utils/events.js';
|
60
64
|
import { getProviderManager } from '../providers/providerManagerInstance.js';
|
61
|
-
import {
|
62
|
-
import {
|
63
|
-
import {
|
64
|
-
import {
|
65
|
+
import { useProviderModelDialog } from './hooks/useProviderModelDialog.js';
|
66
|
+
import { useProviderDialog } from './hooks/useProviderDialog.js';
|
67
|
+
import { ProviderModelDialog } from './components/ProviderModelDialog.js';
|
68
|
+
import { ProviderDialog } from './components/ProviderDialog.js';
|
65
69
|
const CTRL_EXIT_PROMPT_DURATION_MS = 1000;
|
66
|
-
export const AppWrapper = (props) => (_jsx(SessionStatsProvider, { children: _jsx(
|
67
|
-
//
|
68
|
-
const
|
70
|
+
export const AppWrapper = (props) => (_jsx(SessionStatsProvider, { children: _jsx(VimModeProvider, { settings: props.settings, children: _jsx(AppWithState, { ...props }) }) }));
|
71
|
+
// New intermediate component that manages state and provides context
|
72
|
+
const AppWithState = (props) => {
|
73
|
+
const [appState, appDispatch] = useReducer(appReducer, initialAppState);
|
74
|
+
return (_jsx(AppDispatchProvider, { value: appDispatch, children: _jsx(App, { ...props, appState: appState, appDispatch: appDispatch }) }));
|
75
|
+
};
|
76
|
+
const App = (props) => {
|
77
|
+
const { config, settings, startupWarnings = [], version, appState } = props;
|
69
78
|
const isFocused = useFocus();
|
70
79
|
useBracketedPaste();
|
71
|
-
const [
|
80
|
+
const [updateInfo, setUpdateInfo] = useState(null);
|
72
81
|
const { stdout } = useStdout();
|
73
82
|
const nightly = version.includes('nightly');
|
83
|
+
const { history, addItem, clearItems, loadHistory } = useHistory();
|
74
84
|
useEffect(() => {
|
75
|
-
|
76
|
-
|
77
|
-
|
85
|
+
const cleanup = setUpdateHandler(addItem, setUpdateInfo);
|
86
|
+
return cleanup;
|
87
|
+
}, [addItem]);
|
78
88
|
const { consoleMessages, handleNewMessage, clearConsoleMessages: clearConsoleMessagesState, } = useConsoleMessages();
|
79
89
|
useEffect(() => {
|
80
90
|
const consolePatcher = new ConsolePatcher({
|
@@ -85,37 +95,6 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
85
95
|
registerCleanup(consolePatcher.cleanup);
|
86
96
|
}, [handleNewMessage, config]);
|
87
97
|
const { stats: sessionStats } = useSessionStats();
|
88
|
-
// These are now managed by SessionController
|
89
|
-
const { currentModel, isPaidMode, transientWarnings: sessionTransientWarnings, modelSwitchedFromQuotaError, } = sessionState;
|
90
|
-
// Add payment mode warning to startup warnings only at startup
|
91
|
-
const allStartupWarnings = useMemo(() => {
|
92
|
-
const warnings = [...startupWarnings];
|
93
|
-
// Only show payment warnings at startup (when history is empty)
|
94
|
-
if (history.length === 0) {
|
95
|
-
try {
|
96
|
-
const providerManager = getProviderManager();
|
97
|
-
if (providerManager.hasActiveProvider()) {
|
98
|
-
const provider = providerManager.getActiveProvider();
|
99
|
-
const isPaidMode = provider.isPaidMode?.();
|
100
|
-
// Only show paid/free mode warnings for Gemini provider
|
101
|
-
if (isPaidMode !== undefined && provider.name === 'gemini') {
|
102
|
-
if (isPaidMode) {
|
103
|
-
warnings.push(`! PAID MODE: You are using Gemini with API credentials - usage will be charged to your account`);
|
104
|
-
}
|
105
|
-
else {
|
106
|
-
warnings.push(`FREE MODE: You are using Gemini with OAuth authentication - no charges will apply`);
|
107
|
-
}
|
108
|
-
}
|
109
|
-
}
|
110
|
-
}
|
111
|
-
catch (_e) {
|
112
|
-
// Ignore errors when checking payment mode
|
113
|
-
}
|
114
|
-
}
|
115
|
-
return warnings;
|
116
|
-
}, [startupWarnings, history]);
|
117
|
-
// Use transient warnings from session state
|
118
|
-
const transientWarnings = sessionTransientWarnings;
|
119
98
|
const [staticNeedsRefresh, setStaticNeedsRefresh] = useState(false);
|
120
99
|
const [staticKey, setStaticKey] = useState(0);
|
121
100
|
const refreshStatic = useCallback(() => {
|
@@ -125,6 +104,12 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
125
104
|
const [llxprtMdFileCount, setLlxprtMdFileCount] = useState(0);
|
126
105
|
const [debugMessage, setDebugMessage] = useState('');
|
127
106
|
const [showHelp, setShowHelp] = useState(false);
|
107
|
+
const [_themeError, _setThemeError] = useState(null);
|
108
|
+
const [authError, setAuthError] = useState(null);
|
109
|
+
const [_editorError, _setEditorError] = useState(null);
|
110
|
+
const [footerHeight, setFooterHeight] = useState(0);
|
111
|
+
const [_corgiMode, setCorgiMode] = useState(false);
|
112
|
+
const [currentModel, setCurrentModel] = useState(config.getModel());
|
128
113
|
const [shellModeActive, setShellModeActive] = useState(false);
|
129
114
|
const [showErrorDetails, setShowErrorDetails] = useState(false);
|
130
115
|
const [showToolDescriptions, setShowToolDescriptions] = useState(false);
|
@@ -134,92 +119,227 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
134
119
|
const ctrlCTimerRef = useRef(null);
|
135
120
|
const [ctrlDPressedOnce, setCtrlDPressedOnce] = useState(false);
|
136
121
|
const ctrlDTimerRef = useRef(null);
|
137
|
-
const
|
138
|
-
|
139
|
-
const [
|
140
|
-
const [
|
122
|
+
const [constrainHeight, setConstrainHeight] = useState(true);
|
123
|
+
const [showPrivacyNotice, setShowPrivacyNotice] = useState(false);
|
124
|
+
const [modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError] = useState(false);
|
125
|
+
const [userTier, setUserTier] = useState(undefined);
|
126
|
+
const [ideContextState, setIdeContextState] = useState();
|
127
|
+
const [isProcessing, setIsProcessing] = useState(false);
|
128
|
+
const [providerModels, setProviderModels] = useState([]);
|
141
129
|
useEffect(() => {
|
142
|
-
const unsubscribe = ideContext.
|
130
|
+
const unsubscribe = ideContext.subscribeToIdeContext(setIdeContextState);
|
143
131
|
// Set the initial value
|
144
|
-
|
132
|
+
setIdeContextState(ideContext.getIdeContext());
|
145
133
|
return unsubscribe;
|
146
134
|
}, []);
|
135
|
+
useEffect(() => {
|
136
|
+
const openDebugConsole = () => {
|
137
|
+
setShowErrorDetails(true);
|
138
|
+
setConstrainHeight(false); // Make sure the user sees the full message.
|
139
|
+
};
|
140
|
+
appEvents.on(AppEvent.OpenDebugConsole, openDebugConsole);
|
141
|
+
const logErrorHandler = (errorMessage) => {
|
142
|
+
handleNewMessage({
|
143
|
+
type: 'error',
|
144
|
+
content: String(errorMessage),
|
145
|
+
count: 1,
|
146
|
+
});
|
147
|
+
};
|
148
|
+
appEvents.on(AppEvent.LogError, logErrorHandler);
|
149
|
+
return () => {
|
150
|
+
appEvents.off(AppEvent.OpenDebugConsole, openDebugConsole);
|
151
|
+
appEvents.off(AppEvent.LogError, logErrorHandler);
|
152
|
+
};
|
153
|
+
}, [handleNewMessage]);
|
147
154
|
const openPrivacyNotice = useCallback(() => {
|
148
|
-
|
149
|
-
}, [
|
150
|
-
const closePrivacyNotice = useCallback(() => {
|
151
|
-
appDispatch({ type: 'CLOSE_DIALOG', payload: 'privacy' });
|
152
|
-
}, [appDispatch]);
|
155
|
+
setShowPrivacyNotice(true);
|
156
|
+
}, []);
|
153
157
|
const initialPromptSubmitted = useRef(false);
|
154
|
-
const errorCount = useMemo(() => consoleMessages
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
payload: { itemData, baseTimestamp },
|
160
|
-
});
|
161
|
-
}, [appDispatch]);
|
162
|
-
const { isThemeDialogOpen, openThemeDialog, handleThemeSelect, handleThemeHighlight, } = useThemeCommand(settings, appState, addItemViaDispatch);
|
163
|
-
const { isAuthDialogOpen, openAuthDialog, handleAuthSelect, isAuthenticating: authIsAuthenticating, cancelAuthentication, } = useAuthCommand(settings, appState, config);
|
164
|
-
// Sync auth state with parent
|
165
|
-
useEffect(() => {
|
166
|
-
setIsAuthenticating(authIsAuthenticating);
|
167
|
-
}, [authIsAuthenticating, setIsAuthenticating]);
|
168
|
-
const onAuthTimeout = useCallback(() => {
|
169
|
-
appDispatch({
|
170
|
-
type: 'SET_AUTH_ERROR',
|
171
|
-
payload: 'Authentication timed out. Please try again.',
|
172
|
-
});
|
173
|
-
cancelAuthentication();
|
174
|
-
openAuthDialog();
|
175
|
-
}, [cancelAuthentication, openAuthDialog, appDispatch]);
|
158
|
+
const errorCount = useMemo(() => consoleMessages
|
159
|
+
.filter((msg) => msg.type === 'error')
|
160
|
+
.reduce((total, msg) => total + msg.count, 0), [consoleMessages]);
|
161
|
+
const { isThemeDialogOpen, openThemeDialog, handleThemeSelect, handleThemeHighlight, } = useThemeCommand(settings, appState, addItem);
|
162
|
+
const { isAuthDialogOpen, openAuthDialog, handleAuthSelect, isAuthenticating, cancelAuthentication, } = useAuthCommand(settings, appState, config);
|
176
163
|
useEffect(() => {
|
177
164
|
if (settings.merged.selectedAuthType) {
|
178
165
|
const error = validateAuthMethod(settings.merged.selectedAuthType);
|
179
166
|
if (error) {
|
180
|
-
|
167
|
+
setAuthError(error);
|
181
168
|
openAuthDialog();
|
182
169
|
}
|
183
170
|
}
|
184
|
-
}, [settings.merged.selectedAuthType, openAuthDialog,
|
185
|
-
//
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
171
|
+
}, [settings.merged.selectedAuthType, openAuthDialog, setAuthError]);
|
172
|
+
// Sync user tier from config when authentication changes
|
173
|
+
useEffect(() => {
|
174
|
+
// Only sync when not currently authenticating
|
175
|
+
if (!isAuthenticating) {
|
176
|
+
setUserTier(config.getGeminiClient()?.getUserTier());
|
177
|
+
}
|
178
|
+
}, [config, isAuthenticating]);
|
179
|
+
const { isEditorDialogOpen, openEditorDialog, handleEditorSelect, exitEditorDialog, } = useEditorSettings(settings, appState, addItem);
|
180
|
+
const providerManager = getProviderManager(config);
|
181
|
+
const { showDialog: isProviderDialogOpen, openDialog: openProviderDialog, handleSelect: handleProviderSelect, closeDialog: exitProviderDialog, } = useProviderDialog({
|
182
|
+
addMessage: (msg) => addItem({ type: msg.type, text: msg.content }, msg.timestamp.getTime()),
|
193
183
|
appState,
|
184
|
+
config,
|
194
185
|
});
|
195
|
-
const
|
196
|
-
|
197
|
-
clearConsoleMessagesState();
|
198
|
-
console.clear();
|
199
|
-
refreshStatic();
|
200
|
-
}, [clearItems, clearConsoleMessagesState, refreshStatic]);
|
201
|
-
// Provider selection dialog
|
202
|
-
const providerDialog = useProviderDialog({
|
203
|
-
addMessage: (m) => addItemViaDispatch({ type: m.type, text: m.content }, m.timestamp.getTime()),
|
204
|
-
onProviderChange: () => {
|
205
|
-
// Provider change will be detected by SessionController's useEffect
|
206
|
-
checkPaymentModeChange?.();
|
207
|
-
},
|
186
|
+
const { showDialog: isProviderModelDialogOpen, openDialog: openProviderModelDialogRaw, handleSelect: handleProviderModelChange, closeDialog: exitProviderModelDialog, } = useProviderModelDialog({
|
187
|
+
addMessage: (msg) => addItem({ type: msg.type, text: msg.content }, msg.timestamp.getTime()),
|
208
188
|
appState,
|
209
|
-
config,
|
210
|
-
onClear: handleClearScreen,
|
211
189
|
});
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
190
|
+
const openProviderModelDialog = useCallback(async () => {
|
191
|
+
try {
|
192
|
+
const activeProvider = providerManager.getActiveProvider();
|
193
|
+
if (activeProvider) {
|
194
|
+
const models = await activeProvider.getModels();
|
195
|
+
setProviderModels(models);
|
196
|
+
}
|
197
|
+
}
|
198
|
+
catch (e) {
|
199
|
+
console.error('Failed to load models:', e);
|
200
|
+
setProviderModels([]);
|
201
|
+
}
|
202
|
+
await openProviderModelDialogRaw();
|
203
|
+
}, [providerManager, openProviderModelDialogRaw]);
|
204
|
+
// Update current model when provider or model changes
|
205
|
+
useEffect(() => {
|
206
|
+
const activeProvider = providerManager.getActiveProvider();
|
207
|
+
if (activeProvider) {
|
208
|
+
const providerModel = activeProvider.getCurrentModel?.();
|
209
|
+
if (providerModel && providerModel !== currentModel) {
|
210
|
+
setCurrentModel(providerModel);
|
211
|
+
}
|
212
|
+
}
|
213
|
+
}, [providerManager, currentModel]);
|
214
|
+
const toggleCorgiMode = useCallback(() => {
|
215
|
+
setCorgiMode((prev) => !prev);
|
216
|
+
}, []);
|
217
|
+
const performMemoryRefresh = useCallback(async () => {
|
218
|
+
addItem({
|
219
|
+
type: MessageType.INFO,
|
220
|
+
text: 'Refreshing hierarchical memory (LLXPRT.md or other context files)...',
|
221
|
+
}, Date.now());
|
222
|
+
try {
|
223
|
+
const { memoryContent, fileCount } = await loadHierarchicalLlxprtMemory(process.cwd(), config.getDebugMode(), config.getFileService(), settings.merged, config.getExtensionContextFilePaths(), config.getFileFilteringOptions());
|
224
|
+
config.setUserMemory(memoryContent);
|
225
|
+
config.setLlxprtMdFileCount(fileCount);
|
226
|
+
setLlxprtMdFileCount(fileCount);
|
227
|
+
addItem({
|
228
|
+
type: MessageType.INFO,
|
229
|
+
text: `Memory refreshed successfully. ${memoryContent.length > 0 ? `Loaded ${memoryContent.length} characters from ${fileCount} file(s).` : 'No memory content found.'}`,
|
230
|
+
}, Date.now());
|
231
|
+
if (config.getDebugMode()) {
|
232
|
+
console.log(`[DEBUG] Refreshed memory content in config: ${memoryContent.substring(0, 200)}...`);
|
233
|
+
}
|
234
|
+
}
|
235
|
+
catch (error) {
|
236
|
+
const errorMessage = getErrorMessage(error);
|
237
|
+
addItem({
|
238
|
+
type: MessageType.ERROR,
|
239
|
+
text: `Error refreshing memory: ${errorMessage}`,
|
240
|
+
}, Date.now());
|
241
|
+
console.error('Error refreshing memory:', error);
|
242
|
+
}
|
243
|
+
}, [config, addItem, settings.merged]);
|
244
|
+
// Watch for model changes (e.g., from Flash fallback)
|
245
|
+
useEffect(() => {
|
246
|
+
const checkModelChange = () => {
|
247
|
+
const configModel = config.getModel();
|
248
|
+
if (configModel !== currentModel) {
|
249
|
+
setCurrentModel(configModel);
|
250
|
+
}
|
251
|
+
};
|
252
|
+
// Check immediately and then periodically
|
253
|
+
checkModelChange();
|
254
|
+
const interval = setInterval(checkModelChange, 1000); // Check every second
|
255
|
+
return () => clearInterval(interval);
|
256
|
+
}, [config, currentModel]);
|
257
|
+
// Set up Flash fallback handler
|
258
|
+
useEffect(() => {
|
259
|
+
const flashFallbackHandler = async (currentModel, fallbackModel, error) => {
|
260
|
+
let message;
|
261
|
+
const contentGenConfig = config.getContentGeneratorConfig();
|
262
|
+
const authType = contentGenConfig?.authType;
|
263
|
+
if (authType === AuthType.LOGIN_WITH_GOOGLE) {
|
264
|
+
// Use actual user tier if available; otherwise, default to FREE tier behavior (safe default)
|
265
|
+
const isPaidTier = userTier === UserTierId.LEGACY || userTier === UserTierId.STANDARD;
|
266
|
+
// Check if this is a Pro quota exceeded error
|
267
|
+
if (error && isProQuotaExceededError(error)) {
|
268
|
+
if (isPaidTier) {
|
269
|
+
message = `⚡ You have reached your daily ${currentModel} quota limit.
|
270
|
+
⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
|
271
|
+
⚡ 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`;
|
272
|
+
}
|
273
|
+
else {
|
274
|
+
message = `⚡ You have reached your daily ${currentModel} quota limit.
|
275
|
+
⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
|
276
|
+
⚡ 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
|
277
|
+
⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
|
278
|
+
⚡ You can switch authentication methods by typing /auth`;
|
279
|
+
}
|
280
|
+
}
|
281
|
+
else if (error && isGenericQuotaExceededError(error)) {
|
282
|
+
if (isPaidTier) {
|
283
|
+
message = `⚡ You have reached your daily quota limit.
|
284
|
+
⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
|
285
|
+
⚡ 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`;
|
286
|
+
}
|
287
|
+
else {
|
288
|
+
message = `⚡ You have reached your daily quota limit.
|
289
|
+
⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
|
290
|
+
⚡ 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
|
291
|
+
⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
|
292
|
+
⚡ You can switch authentication methods by typing /auth`;
|
293
|
+
}
|
294
|
+
}
|
295
|
+
else {
|
296
|
+
if (isPaidTier) {
|
297
|
+
// Default fallback message for other cases (like consecutive 429s)
|
298
|
+
message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
|
299
|
+
⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
|
300
|
+
⚡ 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`;
|
301
|
+
}
|
302
|
+
else {
|
303
|
+
// Default fallback message for other cases (like consecutive 429s)
|
304
|
+
message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
|
305
|
+
⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
|
306
|
+
⚡ 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
|
307
|
+
⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
|
308
|
+
⚡ You can switch authentication methods by typing /auth`;
|
309
|
+
}
|
310
|
+
}
|
311
|
+
// Add message to UI history
|
312
|
+
if (message) {
|
313
|
+
addItem({
|
314
|
+
type: MessageType.INFO,
|
315
|
+
text: message,
|
316
|
+
}, Date.now());
|
317
|
+
}
|
318
|
+
// Set the flag to prevent tool continuation
|
319
|
+
setModelSwitchedFromQuotaError(true);
|
320
|
+
// Set global quota error flag to prevent Flash model calls
|
321
|
+
config.setQuotaErrorOccurred(true);
|
322
|
+
}
|
323
|
+
// Switch model for future use but return false to stop current retry
|
324
|
+
if (fallbackModel) {
|
325
|
+
config.setModel(fallbackModel);
|
326
|
+
}
|
327
|
+
config.setFallbackMode(true);
|
328
|
+
const contentGenConfigForEvent = config.getContentGeneratorConfig();
|
329
|
+
const authTypeForEvent = contentGenConfigForEvent?.authType || AuthType.USE_GEMINI;
|
330
|
+
logFlashFallback(config, new FlashFallbackEvent(authTypeForEvent));
|
331
|
+
return false; // Don't continue with current prompt
|
332
|
+
};
|
333
|
+
config.setFlashFallbackHandler(flashFallbackHandler);
|
334
|
+
}, [config, addItem, userTier]);
|
335
|
+
// Terminal and UI setup
|
336
|
+
const { rows: terminalHeight, columns: terminalWidth } = useTerminalSize();
|
222
337
|
const { stdin, setRawMode } = useStdin();
|
338
|
+
const isInitialMount = useRef(true);
|
339
|
+
const widthFraction = 0.9;
|
340
|
+
const inputWidth = Math.max(20, Math.floor(terminalWidth * widthFraction) - 3);
|
341
|
+
const suggestionsWidth = Math.max(60, Math.floor(terminalWidth * 0.8));
|
342
|
+
// Utility callbacks
|
223
343
|
const isValidPath = useCallback((filePath) => {
|
224
344
|
try {
|
225
345
|
return fs.existsSync(filePath) && fs.statSync(filePath).isFile();
|
@@ -228,17 +348,51 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
228
348
|
return false;
|
229
349
|
}
|
230
350
|
}, []);
|
231
|
-
const
|
232
|
-
|
233
|
-
|
351
|
+
const getPreferredEditor = useCallback(() => {
|
352
|
+
const editorType = settings.merged.preferredEditor;
|
353
|
+
const isValidEditor = isEditorAvailable(editorType);
|
354
|
+
if (!isValidEditor) {
|
355
|
+
openEditorDialog();
|
356
|
+
return;
|
357
|
+
}
|
358
|
+
return editorType;
|
359
|
+
}, [settings, openEditorDialog]);
|
360
|
+
const onAuthError = useCallback(() => {
|
361
|
+
setAuthError('reauth required');
|
362
|
+
openAuthDialog();
|
363
|
+
}, [openAuthDialog, setAuthError]);
|
364
|
+
const handleAuthTimeout = useCallback(() => {
|
365
|
+
setAuthError('Authentication timed out. Please try again.');
|
366
|
+
cancelAuthentication();
|
367
|
+
openAuthDialog();
|
368
|
+
}, [setAuthError, cancelAuthentication, openAuthDialog]);
|
369
|
+
const handlePrivacyNoticeExit = useCallback(() => {
|
370
|
+
setShowPrivacyNotice(false);
|
371
|
+
}, []);
|
372
|
+
// Core hooks and processors
|
373
|
+
const { vimEnabled: vimModeEnabled, vimMode, toggleVimEnabled, } = useVimMode();
|
374
|
+
const { handleSlashCommand, slashCommands, pendingHistoryItems: pendingSlashCommandHistoryItems, commandContext, shellConfirmationRequest, } = useSlashCommandProcessor(config, settings, addItem, clearItems, loadHistory, refreshStatic, setShowHelp, setDebugMessage, openThemeDialog, openAuthDialog, openEditorDialog, openProviderDialog, openProviderModelDialog, toggleCorgiMode, setQuittingMessages, openPrivacyNotice, toggleVimEnabled, setIsProcessing);
|
375
|
+
const { streamingState, submitQuery, initError, pendingHistoryItems: pendingGeminiHistoryItems, thought, } = useGeminiStream(config.getGeminiClient(), history, addItem, setShowHelp, config, setDebugMessage, handleSlashCommand, shellModeActive, getPreferredEditor, onAuthError, performMemoryRefresh, modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError);
|
376
|
+
// Input handling
|
377
|
+
const handleFinalSubmit = useCallback((submittedValue) => {
|
378
|
+
const trimmedValue = submittedValue.trim();
|
379
|
+
if (trimmedValue.length > 0) {
|
380
|
+
submitQuery(trimmedValue);
|
381
|
+
}
|
382
|
+
}, [submitQuery]);
|
234
383
|
const buffer = useTextBuffer({
|
235
384
|
initialText: '',
|
236
|
-
viewport:
|
385
|
+
viewport: { height: 10, width: inputWidth },
|
237
386
|
stdin,
|
238
387
|
setRawMode,
|
239
388
|
isValidPath,
|
240
389
|
shellModeActive,
|
241
390
|
});
|
391
|
+
const { handleInput: vimHandleInput } = useVim(buffer, handleFinalSubmit);
|
392
|
+
const pendingHistoryItems = [...pendingSlashCommandHistoryItems];
|
393
|
+
pendingHistoryItems.push(...pendingGeminiHistoryItems);
|
394
|
+
const { elapsedTime, currentLoadingPhrase } = useLoadingIndicator(streamingState);
|
395
|
+
const showAutoAcceptIndicator = useAutoAcceptIndicator({ config });
|
242
396
|
const handleExit = useCallback((pressedOnce, setPressedOnce, timerRef) => {
|
243
397
|
if (pressedOnce) {
|
244
398
|
if (timerRef.current) {
|
@@ -276,7 +430,7 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
276
430
|
handleSlashCommand(newValue ? '/mcp desc' : '/mcp nodesc');
|
277
431
|
}
|
278
432
|
}
|
279
|
-
else if (key.ctrl && input === 'e' &&
|
433
|
+
else if (key.ctrl && input === 'e' && ideContextState) {
|
280
434
|
setShowIDEContextDetail((prev) => !prev);
|
281
435
|
}
|
282
436
|
else if (key.ctrl && (input === 'c' || input === 'C')) {
|
@@ -298,49 +452,6 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
298
452
|
setLlxprtMdFileCount(config.getLlxprtMdFileCount());
|
299
453
|
}
|
300
454
|
}, [config]);
|
301
|
-
const getPreferredEditor = useCallback(() => {
|
302
|
-
const editorType = settings.merged.preferredEditor;
|
303
|
-
const isValidEditor = isEditorAvailable(editorType);
|
304
|
-
if (!isValidEditor) {
|
305
|
-
openEditorDialog();
|
306
|
-
return;
|
307
|
-
}
|
308
|
-
return editorType;
|
309
|
-
}, [settings, openEditorDialog]);
|
310
|
-
const onAuthError = useCallback(() => {
|
311
|
-
appDispatch({ type: 'SET_AUTH_ERROR', payload: 'reauth required' });
|
312
|
-
openAuthDialog();
|
313
|
-
}, [openAuthDialog, appDispatch]);
|
314
|
-
const geminiClientForStream = useMemo(() => config.getGeminiClient(), [config]);
|
315
|
-
const { streamingState, submitQuery, initError, pendingHistoryItems: pendingGeminiHistoryItems, thought, } = useGeminiStream(geminiClientForStream, history, addItem, setShowHelp, config, setDebugMessage, handleSlashCommand, shellModeActive, getPreferredEditor, onAuthError, performMemoryRefresh, modelSwitchedFromQuotaError, useCallback((value) => {
|
316
|
-
if (typeof value === 'function') {
|
317
|
-
// Handle function form of setState
|
318
|
-
const currentValue = modelSwitchedFromQuotaError;
|
319
|
-
sessionDispatch({
|
320
|
-
type: 'SET_MODEL_SWITCHED_FROM_QUOTA_ERROR',
|
321
|
-
payload: value(currentValue),
|
322
|
-
});
|
323
|
-
}
|
324
|
-
else {
|
325
|
-
sessionDispatch({
|
326
|
-
type: 'SET_MODEL_SWITCHED_FROM_QUOTA_ERROR',
|
327
|
-
payload: value,
|
328
|
-
});
|
329
|
-
}
|
330
|
-
}, [modelSwitchedFromQuotaError, sessionDispatch]));
|
331
|
-
// FIX: Create a new array instead of mutating the existing one
|
332
|
-
// This ensures React can properly track changes and prevents infinite loops
|
333
|
-
pendingHistoryItems = [...pendingHistoryItems, ...pendingGeminiHistoryItems];
|
334
|
-
const { elapsedTime, currentLoadingPhrase } = useLoadingIndicator(streamingState);
|
335
|
-
const showAutoAcceptIndicator = useAutoAcceptIndicator({ config });
|
336
|
-
const handleFinalSubmit = useCallback((submittedValue) => {
|
337
|
-
const trimmedValue = submittedValue.trim();
|
338
|
-
if (trimmedValue.length > 0) {
|
339
|
-
// Clear transient warnings when user submits a message
|
340
|
-
sessionDispatch({ type: 'CLEAR_TRANSIENT_WARNINGS' });
|
341
|
-
submitQuery(trimmedValue);
|
342
|
-
}
|
343
|
-
}, [submitQuery, sessionDispatch]);
|
344
455
|
const logger = useLogger();
|
345
456
|
const [userMessages, setUserMessages] = useState([]);
|
346
457
|
useEffect(() => {
|
@@ -372,12 +483,23 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
372
483
|
};
|
373
484
|
fetchUserMessages();
|
374
485
|
}, [history, logger]);
|
375
|
-
const isInputActive = streamingState === StreamingState.Idle && !initError;
|
486
|
+
const isInputActive = streamingState === StreamingState.Idle && !initError && !isProcessing;
|
487
|
+
const handleClearScreen = useCallback(() => {
|
488
|
+
clearItems();
|
489
|
+
clearConsoleMessagesState();
|
490
|
+
console.clear();
|
491
|
+
refreshStatic();
|
492
|
+
}, [clearItems, clearConsoleMessagesState, refreshStatic]);
|
493
|
+
const mainControlsRef = useRef(null);
|
376
494
|
const pendingHistoryItemRef = useRef(null);
|
377
|
-
// Register dependencies that affect footer height with LayoutManager
|
378
495
|
useEffect(() => {
|
379
|
-
|
380
|
-
|
496
|
+
if (mainControlsRef.current) {
|
497
|
+
const fullFooterMeasurement = measureElement(mainControlsRef.current);
|
498
|
+
setFooterHeight(fullFooterMeasurement.height);
|
499
|
+
}
|
500
|
+
}, [terminalHeight, consoleMessages, showErrorDetails]);
|
501
|
+
const staticExtraHeight = /* margins and padding */ 3;
|
502
|
+
const availableTerminalHeight = useMemo(() => terminalHeight - footerHeight - staticExtraHeight, [terminalHeight, footerHeight]);
|
381
503
|
useEffect(() => {
|
382
504
|
// skip refreshing Static during first mount
|
383
505
|
if (isInitialMount.current) {
|
@@ -414,26 +536,30 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
414
536
|
return getAllLlxprtMdFilenames();
|
415
537
|
}, [settings.merged.contextFileName]);
|
416
538
|
const initialPrompt = useMemo(() => config.getQuestion(), [config]);
|
417
|
-
const geminiClient =
|
539
|
+
const geminiClient = config.getGeminiClient();
|
418
540
|
useEffect(() => {
|
419
541
|
if (initialPrompt &&
|
420
542
|
!initialPromptSubmitted.current &&
|
421
|
-
!
|
543
|
+
!isAuthenticating &&
|
422
544
|
!isAuthDialogOpen &&
|
423
545
|
!isThemeDialogOpen &&
|
424
546
|
!isEditorDialogOpen &&
|
547
|
+
!isProviderDialogOpen &&
|
548
|
+
!isProviderModelDialogOpen &&
|
425
549
|
!showPrivacyNotice &&
|
426
|
-
geminiClient) {
|
550
|
+
geminiClient?.isInitialized?.()) {
|
427
551
|
submitQuery(initialPrompt);
|
428
552
|
initialPromptSubmitted.current = true;
|
429
553
|
}
|
430
554
|
}, [
|
431
555
|
initialPrompt,
|
432
556
|
submitQuery,
|
433
|
-
|
557
|
+
isAuthenticating,
|
434
558
|
isAuthDialogOpen,
|
435
559
|
isThemeDialogOpen,
|
436
560
|
isEditorDialogOpen,
|
561
|
+
isProviderDialogOpen,
|
562
|
+
isProviderModelDialogOpen,
|
437
563
|
showPrivacyNotice,
|
438
564
|
geminiClient,
|
439
565
|
]);
|
@@ -445,32 +571,23 @@ const AppInner = ({ config, settings, startupWarnings = [], version, setIsAuthen
|
|
445
571
|
// Arbitrary threshold to ensure that items in the static area are large
|
446
572
|
// enough but not too large to make the terminal hard to use.
|
447
573
|
const staticAreaMaxItemHeight = Math.max(terminalHeight * 4, 100);
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
}
|
453
|
-
return (_jsx(StreamingContext.Provider, { value: streamingState, children: _jsxs(Box, { flexDirection: "column", marginBottom: 1, width: "90%", children: [updateMessage && _jsx(UpdateNotification, { message: updateMessage }), _jsx(Static, { items: [
|
574
|
+
const placeholder = vimModeEnabled
|
575
|
+
? " Press 'i' for INSERT mode and 'Esc' for NORMAL mode."
|
576
|
+
: ' Type your message or @path/to/file';
|
577
|
+
return (_jsx(StreamingContext.Provider, { value: streamingState, children: _jsxs(Box, { flexDirection: "column", width: "90%", children: [_jsx(Static, { items: [
|
454
578
|
_jsxs(Box, { flexDirection: "column", children: [!settings.merged.hideBanner && (_jsx(Header, { terminalWidth: terminalWidth, version: version, nightly: nightly })), !settings.merged.hideTips && _jsx(Tips, { config: config })] }, "header"),
|
455
579
|
...history.map((h) => (_jsx(HistoryItemDisplay, { terminalWidth: mainAreaWidth, availableTerminalHeight: staticAreaMaxItemHeight, item: h, isPending: false, config: config }, h.id))),
|
456
580
|
], 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,
|
457
581
|
// TODO(taehykim): It seems like references to ids aren't necessary in
|
458
582
|
// HistoryItemDisplay. Refactor later. Use a fake id for now.
|
459
|
-
item: { ...item, id: 0 }, isPending: true, config: config, isFocused: !isEditorDialogOpen }, i))), _jsx(ShowMoreLines, { constrainHeight: constrainHeight })] }) }), showHelp && _jsx(Help, { commands: slashCommands }), _jsxs(Box, { flexDirection: "column", ref:
|
460
|
-
? terminalHeight -
|
461
|
-
: undefined, terminalWidth: mainAreaWidth })] })) :
|
583
|
+
item: { ...item, id: 0 }, isPending: true, config: config, isFocused: !isEditorDialogOpen }, i))), _jsx(ShowMoreLines, { constrainHeight: constrainHeight })] }) }), showHelp && _jsx(Help, { commands: slashCommands }), _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))) })), shellConfirmationRequest ? (_jsx(ShellConfirmationDialog, { request: shellConfirmationRequest })) : 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
|
584
|
+
? terminalHeight - staticExtraHeight
|
585
|
+
: undefined, terminalWidth: mainAreaWidth })] })) : isAuthenticating ? (_jsxs(_Fragment, { children: [_jsx(AuthInProgress, { onTimeout: handleAuthTimeout }), 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 })] })) : isProviderDialogOpen ? (_jsx(Box, { flexDirection: "column", children: _jsx(ProviderDialog, { providers: providerManager.listProviders(), currentProvider: providerManager.getActiveProviderName(), onSelect: handleProviderSelect, onClose: exitProviderDialog }) })) : isProviderModelDialogOpen ? (_jsx(Box, { flexDirection: "column", children: _jsx(ProviderModelDialog, { models: providerModels, currentModel: currentModel, onSelect: handleProviderModelChange, onClose: exitProviderModelDialog }) })) : showPrivacyNotice ? (_jsx(PrivacyNotice, { onExit: handlePrivacyNoticeExit, config: config })) : (_jsxs(_Fragment, { children: [_jsx(LoadingIndicator, { thought: streamingState === StreamingState.WaitingForConfirmation ||
|
462
586
|
config.getAccessibility()?.disableLoadingPhrases
|
463
587
|
? undefined
|
464
588
|
: thought, currentLoadingPhrase: config.getAccessibility()?.disableLoadingPhrases
|
465
589
|
? undefined
|
466
|
-
: currentLoadingPhrase, elapsedTime: elapsedTime }), _jsxs(Box, { marginTop: 1, display: "flex", justifyContent: "space-between", width: "100%", 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." })) : (_jsx(ContextSummaryDisplay, {
|
467
|
-
!shellModeActive && (_jsx(AutoAcceptIndicator, { approvalMode: showAutoAcceptIndicator })), shellModeActive && _jsx(ShellModeIndicator, {})] })] }), showIDEContextDetail && (_jsx(IDEContextDetailDisplay, {
|
468
|
-
};
|
469
|
-
// Intermediate component to pass isAuthenticating to SessionController
|
470
|
-
const AppWithAuth = (props) => {
|
471
|
-
const [isAuthenticating, setIsAuthenticating] = useState(false);
|
472
|
-
return (_jsx(SessionController, { config: props.config, isAuthenticating: isAuthenticating, children: _jsx(AppInner, { ...props, isAuthenticating: isAuthenticating, setIsAuthenticating: setIsAuthenticating }) }));
|
590
|
+
: currentLoadingPhrase, elapsedTime: elapsedTime }), _jsxs(Box, { marginTop: 1, display: "flex", justifyContent: "space-between", width: "100%", 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." })) : (_jsx(ContextSummaryDisplay, { ideContext: ideContextState, llxprtMdFileCount: llxprtMdFileCount, contextFileNames: contextFileNames, mcpServers: config.getMcpServers(), blockedMcpServers: config.getBlockedMcpServers(), showToolDescriptions: showToolDescriptions }))] }), _jsxs(Box, { children: [showAutoAcceptIndicator !== ApprovalMode.DEFAULT &&
|
591
|
+
!shellModeActive && (_jsx(AutoAcceptIndicator, { approvalMode: showAutoAcceptIndicator })), shellModeActive && _jsx(ShellModeIndicator, {})] })] }), showIDEContextDetail && (_jsx(IDEContextDetailDisplay, { ideContext: ideContextState })), 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: userMessages, onClearScreen: handleClearScreen, config: config, slashCommands: slashCommands, commandContext: commandContext, shellModeActive: shellModeActive, setShellModeActive: setShellModeActive, 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."] })] })) })), _jsx(Footer, { model: currentModel, targetDir: config.getTargetDir(), debugMode: config.getDebugMode(), branchName: branchName, debugMessage: debugMessage, errorCount: errorCount, showErrorDetails: showErrorDetails, showMemoryUsage: config.getDebugMode() || config.getShowMemoryUsage(), promptTokenCount: sessionStats.lastPromptTokenCount, nightly: nightly, vimMode: vimModeEnabled ? vimMode : undefined })] })] }) }));
|
473
592
|
};
|
474
|
-
// Main App component that provides the UIStateShell wrapper
|
475
|
-
const App = (props) => (_jsx(UIStateShell, { children: _jsx(AppWithAuth, { ...props }) }));
|
476
593
|
//# sourceMappingURL=App.js.map
|