2025-09-06 01:39:02 -04:00
|
|
|
/**
|
|
|
|
|
* @license
|
2026-02-09 21:53:10 -05:00
|
|
|
* Copyright 2026 Google LLC
|
2025-09-06 01:39:02 -04:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { createContext, useContext } from 'react';
|
|
|
|
|
import type {
|
|
|
|
|
HistoryItem,
|
|
|
|
|
ThoughtSummary,
|
|
|
|
|
ConsoleMessageItem,
|
|
|
|
|
ConfirmationRequest,
|
2026-02-09 21:53:10 -05:00
|
|
|
QuotaStats,
|
2025-09-10 22:20:13 -07:00
|
|
|
LoopDetectionConfirmationRequest,
|
2025-09-06 01:39:02 -04:00
|
|
|
HistoryItemWithoutId,
|
|
|
|
|
StreamingState,
|
2026-01-06 15:52:12 -05:00
|
|
|
ActiveHook,
|
2026-02-09 12:24:28 -08:00
|
|
|
PermissionConfirmationRequest,
|
2025-09-06 01:39:02 -04:00
|
|
|
} from '../types.js';
|
|
|
|
|
import type { CommandContext, SlashCommand } from '../commands/types.js';
|
|
|
|
|
import type { TextBuffer } from '../components/shared/text-buffer.js';
|
|
|
|
|
import type {
|
|
|
|
|
IdeContext,
|
|
|
|
|
ApprovalMode,
|
|
|
|
|
UserTierId,
|
2025-09-18 15:23:24 -04:00
|
|
|
IdeInfo,
|
2025-09-08 16:19:52 -04:00
|
|
|
FallbackIntent,
|
2026-01-20 16:23:01 -08:00
|
|
|
ValidationIntent,
|
2026-01-22 10:30:44 -08:00
|
|
|
AgentDefinition,
|
2025-09-06 01:39:02 -04:00
|
|
|
} from '@google/gemini-cli-core';
|
2026-02-09 21:04:34 -05:00
|
|
|
import { type TransientMessageType } from '../../utils/events.js';
|
2025-09-06 01:39:02 -04:00
|
|
|
import type { DOMElement } from 'ink';
|
|
|
|
|
import type { SessionStatsState } from '../contexts/SessionContext.js';
|
2025-09-12 09:20:04 -07:00
|
|
|
import type { ExtensionUpdateState } from '../state/extensions.js';
|
2025-10-01 14:53:15 -07:00
|
|
|
import type { UpdateObject } from '../utils/updateCheck.js';
|
2025-09-06 01:39:02 -04:00
|
|
|
|
2025-09-08 16:19:52 -04:00
|
|
|
export interface ProQuotaDialogRequest {
|
|
|
|
|
failedModel: string;
|
|
|
|
|
fallbackModel: string;
|
2025-11-18 12:01:16 -05:00
|
|
|
message: string;
|
|
|
|
|
isTerminalQuotaError: boolean;
|
|
|
|
|
isModelNotFoundError?: boolean;
|
2025-09-08 16:19:52 -04:00
|
|
|
resolve: (intent: FallbackIntent) => void;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-20 16:23:01 -08:00
|
|
|
export interface ValidationDialogRequest {
|
|
|
|
|
validationLink?: string;
|
|
|
|
|
validationDescription?: string;
|
|
|
|
|
learnMoreUrl?: string;
|
|
|
|
|
resolve: (intent: ValidationIntent) => void;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-22 11:45:02 -07:00
|
|
|
import { type UseHistoryManagerReturn } from '../hooks/useHistoryManager.js';
|
2025-09-29 13:54:12 -07:00
|
|
|
import { type RestartReason } from '../hooks/useIdeTrustListener.js';
|
2025-12-18 10:36:48 -08:00
|
|
|
import type { TerminalBackgroundColor } from '../utils/terminalCapabilityManager.js';
|
2026-01-30 09:53:09 -08:00
|
|
|
import type { BackgroundShell } from '../hooks/shellCommandProcessor.js';
|
2025-09-22 11:45:02 -07:00
|
|
|
|
2026-02-09 21:53:10 -05:00
|
|
|
export interface QuotaState {
|
|
|
|
|
userTier: UserTierId | undefined;
|
|
|
|
|
stats: QuotaStats | undefined;
|
|
|
|
|
proQuotaRequest: ProQuotaDialogRequest | null;
|
|
|
|
|
validationRequest: ValidationDialogRequest | null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-06 01:39:02 -04:00
|
|
|
export interface UIState {
|
|
|
|
|
history: HistoryItem[];
|
2025-09-22 11:45:02 -07:00
|
|
|
historyManager: UseHistoryManagerReturn;
|
2025-09-06 01:39:02 -04:00
|
|
|
isThemeDialogOpen: boolean;
|
2026-02-13 17:57:55 -05:00
|
|
|
shouldShowRetentionWarning: boolean;
|
|
|
|
|
sessionsToDeleteCount: number;
|
2025-09-06 01:39:02 -04:00
|
|
|
themeError: string | null;
|
|
|
|
|
isAuthenticating: boolean;
|
2025-09-08 16:37:36 -07:00
|
|
|
isConfigInitialized: boolean;
|
2025-09-06 01:39:02 -04:00
|
|
|
authError: string | null;
|
|
|
|
|
isAuthDialogOpen: boolean;
|
2025-10-29 18:58:08 -07:00
|
|
|
isAwaitingApiKeyInput: boolean;
|
|
|
|
|
apiKeyDefaultValue?: string;
|
2025-09-06 01:39:02 -04:00
|
|
|
editorError: string | null;
|
|
|
|
|
isEditorDialogOpen: boolean;
|
|
|
|
|
showPrivacyNotice: boolean;
|
|
|
|
|
corgiMode: boolean;
|
|
|
|
|
debugMessage: string;
|
|
|
|
|
quittingMessages: HistoryItem[] | null;
|
|
|
|
|
isSettingsDialogOpen: boolean;
|
2025-11-25 11:54:09 -07:00
|
|
|
isSessionBrowserOpen: boolean;
|
2025-09-23 12:50:09 -04:00
|
|
|
isModelDialogOpen: boolean;
|
2026-01-22 10:30:44 -08:00
|
|
|
isAgentConfigDialogOpen: boolean;
|
|
|
|
|
selectedAgentName?: string;
|
|
|
|
|
selectedAgentDisplayName?: string;
|
|
|
|
|
selectedAgentDefinition?: AgentDefinition;
|
2025-09-22 11:45:02 -07:00
|
|
|
isPermissionsDialogOpen: boolean;
|
2025-11-14 14:41:53 -08:00
|
|
|
permissionsDialogProps: { targetDirectory?: string } | null;
|
2025-10-14 18:15:57 -07:00
|
|
|
slashCommands: readonly SlashCommand[] | undefined;
|
2025-09-06 01:39:02 -04:00
|
|
|
pendingSlashCommandHistoryItems: HistoryItemWithoutId[];
|
|
|
|
|
commandContext: CommandContext;
|
2026-01-30 09:57:34 -05:00
|
|
|
commandConfirmationRequest: ConfirmationRequest | null;
|
|
|
|
|
authConsentRequest: ConfirmationRequest | null;
|
2025-09-29 14:19:19 -07:00
|
|
|
confirmUpdateExtensionRequests: ConfirmationRequest[];
|
2025-09-10 22:20:13 -07:00
|
|
|
loopDetectionConfirmationRequest: LoopDetectionConfirmationRequest | null;
|
2026-02-09 12:24:28 -08:00
|
|
|
permissionConfirmationRequest: PermissionConfirmationRequest | null;
|
2025-09-06 01:39:02 -04:00
|
|
|
geminiMdFileCount: number;
|
|
|
|
|
streamingState: StreamingState;
|
|
|
|
|
initError: string | null;
|
|
|
|
|
pendingGeminiHistoryItems: HistoryItemWithoutId[];
|
|
|
|
|
thought: ThoughtSummary | null;
|
|
|
|
|
shellModeActive: boolean;
|
|
|
|
|
userMessages: string[];
|
|
|
|
|
buffer: TextBuffer;
|
|
|
|
|
inputWidth: number;
|
|
|
|
|
suggestionsWidth: number;
|
|
|
|
|
isInputActive: boolean;
|
2026-01-26 19:59:20 +03:00
|
|
|
isResuming: boolean;
|
2025-09-06 01:39:02 -04:00
|
|
|
shouldShowIdePrompt: boolean;
|
|
|
|
|
isFolderTrustDialogOpen: boolean;
|
|
|
|
|
isTrustedFolder: boolean | undefined;
|
|
|
|
|
constrainHeight: boolean;
|
|
|
|
|
showErrorDetails: boolean;
|
|
|
|
|
filteredConsoleMessages: ConsoleMessageItem[];
|
|
|
|
|
ideContextState: IdeContext | undefined;
|
2025-10-16 11:23:36 -07:00
|
|
|
renderMarkdown: boolean;
|
2025-09-06 01:39:02 -04:00
|
|
|
ctrlCPressedOnce: boolean;
|
|
|
|
|
ctrlDPressedOnce: boolean;
|
|
|
|
|
showEscapePrompt: boolean;
|
2026-02-06 11:33:39 -08:00
|
|
|
shortcutsHelpVisible: boolean;
|
2026-02-12 14:25:24 -05:00
|
|
|
cleanUiDetailsVisible: boolean;
|
2025-09-06 01:39:02 -04:00
|
|
|
elapsedTime: number;
|
2026-02-10 09:36:20 -08:00
|
|
|
currentLoadingPhrase: string | undefined;
|
2025-09-06 01:39:02 -04:00
|
|
|
historyRemountKey: number;
|
2026-01-06 15:52:12 -05:00
|
|
|
activeHooks: ActiveHook[];
|
2025-09-06 01:39:02 -04:00
|
|
|
messageQueue: string[];
|
2025-10-15 22:32:50 +05:30
|
|
|
queueErrorMessage: string | null;
|
2026-01-21 10:19:47 -05:00
|
|
|
showApprovalModeIndicator: ApprovalMode;
|
2026-02-17 12:36:59 -05:00
|
|
|
allowPlanMode: boolean;
|
2025-09-06 01:39:02 -04:00
|
|
|
// Quota-related state
|
2026-02-09 21:53:10 -05:00
|
|
|
quota: QuotaState;
|
2025-09-06 01:39:02 -04:00
|
|
|
currentModel: string;
|
|
|
|
|
contextFileNames: string[];
|
|
|
|
|
errorCount: number;
|
|
|
|
|
availableTerminalHeight: number | undefined;
|
|
|
|
|
mainAreaWidth: number;
|
|
|
|
|
staticAreaMaxItemHeight: number;
|
|
|
|
|
staticExtraHeight: number;
|
|
|
|
|
dialogsVisible: boolean;
|
|
|
|
|
pendingHistoryItems: HistoryItemWithoutId[];
|
|
|
|
|
nightly: boolean;
|
|
|
|
|
branchName: string | undefined;
|
|
|
|
|
sessionStats: SessionStatsState;
|
|
|
|
|
terminalWidth: number;
|
|
|
|
|
terminalHeight: number;
|
|
|
|
|
mainControlsRef: React.MutableRefObject<DOMElement | null>;
|
2025-10-10 13:18:38 -07:00
|
|
|
// NOTE: This is for performance profiling only.
|
|
|
|
|
rootUiRef: React.MutableRefObject<DOMElement | null>;
|
2025-09-18 15:23:24 -04:00
|
|
|
currentIDE: IdeInfo | null;
|
2025-09-06 01:39:02 -04:00
|
|
|
updateInfo: UpdateObject | null;
|
|
|
|
|
showIdeRestartPrompt: boolean;
|
2025-09-29 13:54:12 -07:00
|
|
|
ideTrustRestartReason: RestartReason;
|
2025-09-06 01:39:02 -04:00
|
|
|
isRestarting: boolean;
|
2025-09-12 09:20:04 -07:00
|
|
|
extensionsUpdateState: Map<string, ExtensionUpdateState>;
|
2025-09-11 13:27:27 -07:00
|
|
|
activePtyId: number | undefined;
|
2026-01-30 09:53:09 -08:00
|
|
|
backgroundShellCount: number;
|
|
|
|
|
isBackgroundShellVisible: boolean;
|
2025-09-20 10:59:37 -07:00
|
|
|
embeddedShellFocused: boolean;
|
2025-10-07 10:28:35 -07:00
|
|
|
showDebugProfiler: boolean;
|
2025-10-17 21:10:57 -07:00
|
|
|
showFullTodos: boolean;
|
2025-11-11 07:50:11 -08:00
|
|
|
copyModeEnabled: boolean;
|
2025-11-18 12:01:16 -05:00
|
|
|
bannerData: {
|
|
|
|
|
defaultText: string;
|
|
|
|
|
warningText: string;
|
|
|
|
|
};
|
|
|
|
|
bannerVisible: boolean;
|
2025-11-14 19:06:30 -08:00
|
|
|
customDialog: React.ReactNode | null;
|
2025-12-18 10:36:48 -08:00
|
|
|
terminalBackgroundColor: TerminalBackgroundColor;
|
2026-01-05 15:12:51 -08:00
|
|
|
settingsNonce: number;
|
2026-01-30 09:53:09 -08:00
|
|
|
backgroundShells: Map<number, BackgroundShell>;
|
|
|
|
|
activeBackgroundShellPid: number | null;
|
|
|
|
|
backgroundShellHeight: number;
|
|
|
|
|
isBackgroundShellListOpen: boolean;
|
2026-01-16 15:24:53 -05:00
|
|
|
adminSettingsChanged: boolean;
|
2026-01-26 19:49:32 +00:00
|
|
|
newAgents: AgentDefinition[] | null;
|
2026-02-18 14:05:50 -08:00
|
|
|
hintMode: boolean;
|
|
|
|
|
hintBuffer: string;
|
2026-02-09 21:04:34 -05:00
|
|
|
transientMessage: {
|
|
|
|
|
text: string;
|
|
|
|
|
type: TransientMessageType;
|
|
|
|
|
} | null;
|
2025-09-06 01:39:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const UIStateContext = createContext<UIState | null>(null);
|
|
|
|
|
|
|
|
|
|
export const useUIState = () => {
|
|
|
|
|
const context = useContext(UIStateContext);
|
|
|
|
|
if (!context) {
|
|
|
|
|
throw new Error('useUIState must be used within a UIStateProvider');
|
|
|
|
|
}
|
|
|
|
|
return context;
|
|
|
|
|
};
|