/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import type React from 'react'; import { Box, Text } from 'ink'; import { theme } from '../semantic-colors.js'; import { shortenPath, tildeifyPath } from '@google/gemini-cli-core'; import { ConsoleSummaryDisplay } from './ConsoleSummaryDisplay.js'; import process from 'node:process'; import Gradient from 'ink-gradient'; import { MemoryUsageDisplay } from './MemoryUsageDisplay.js'; import { ContextUsageDisplay } from './ContextUsageDisplay.js'; import { DebugProfiler } from './DebugProfiler.js'; import { isDevelopment } from '../../utils/installationInfo.js'; import { useUIState } from '../contexts/UIStateContext.js'; import { useConfig } from '../contexts/ConfigContext.js'; import { useSettings } from '../contexts/SettingsContext.js'; import { useVimMode } from '../contexts/VimModeContext.js'; export const Footer: React.FC = () => { const uiState = useUIState(); const config = useConfig(); const settings = useSettings(); const { vimEnabled, vimMode } = useVimMode(); const { model, targetDir, debugMode, branchName, debugMessage, corgiMode, errorCount, showErrorDetails, promptTokenCount, nightly, isTrustedFolder, mainAreaWidth, } = { model: uiState.currentModel, targetDir: config.getTargetDir(), debugMode: config.getDebugMode(), branchName: uiState.branchName, debugMessage: uiState.debugMessage, corgiMode: uiState.corgiMode, errorCount: uiState.errorCount, showErrorDetails: uiState.showErrorDetails, promptTokenCount: uiState.sessionStats.lastPromptTokenCount, nightly: uiState.nightly, isTrustedFolder: uiState.isTrustedFolder, mainAreaWidth: uiState.mainAreaWidth, }; const showMemoryUsage = config.getDebugMode() || settings.merged.ui?.showMemoryUsage || false; const hideCWD = settings.merged.ui?.footer?.hideCWD || false; const hideSandboxStatus = settings.merged.ui?.footer?.hideSandboxStatus || false; const hideModelInfo = settings.merged.ui?.footer?.hideModelInfo || false; const pathLength = Math.max(20, Math.floor(mainAreaWidth * 0.25)); const displayPath = shortenPath(tildeifyPath(targetDir), pathLength); const justifyContent = hideCWD && hideModelInfo ? 'center' : 'space-between'; const displayVimMode = vimEnabled ? vimMode : undefined; const showDebugProfiler = debugMode || isDevelopment; return ( {(showDebugProfiler || displayVimMode || !hideCWD) && ( {showDebugProfiler && } {displayVimMode && ( [{displayVimMode}] )} {!hideCWD && (nightly ? ( {displayPath} {branchName && ({branchName}*)} ) : ( {displayPath} {branchName && ( ({branchName}*) )} ))} {debugMode && ( {' ' + (debugMessage || '--debug')} )} )} {/* Middle Section: Centered Trust/Sandbox Info */} {!hideSandboxStatus && ( {isTrustedFolder === false ? ( untrusted ) : process.env['SANDBOX'] && process.env['SANDBOX'] !== 'sandbox-exec' ? ( {process.env['SANDBOX'].replace(/^gemini-(?:cli-)?/, '')} ) : process.env['SANDBOX'] === 'sandbox-exec' ? ( macOS Seatbelt{' '} ({process.env['SEATBELT_PROFILE']}) ) : ( no sandbox {mainAreaWidth >= 100 && ( (see /docs) )} )} )} {/* Right Section: Gemini Label and Console Summary */} {!hideModelInfo && ( {model}{' '} {showMemoryUsage && } {corgiMode && ( | `) )} {!showErrorDetails && errorCount > 0 && ( | )} )} ); };