/**
* @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 { ContextUsageDisplay } from './ContextUsageDisplay.js';
import { useTerminalSize } from '../hooks/useTerminalSize.js';
import { AutoAcceptIndicator } from './AutoAcceptIndicator.js';
import { ShellModeIndicator } from './ShellModeIndicator.js';
import { isNarrowWidth } from '../utils/isNarrowWidth.js';
import { useUIState } from '../contexts/UIStateContext.js';
import { useConfig } from '../contexts/ConfigContext.js';
import { useVimMode } from '../contexts/VimModeContext.js';
import { useVerboseMode } from '../contexts/VerboseModeContext.js';
import { ApprovalMode } from '@qwen-code/qwen-code-core';
import { t } from '../../i18n/index.js';
export const Footer: React.FC = () => {
const uiState = useUIState();
const config = useConfig();
const { vimEnabled, vimMode } = useVimMode();
const { verboseMode } = useVerboseMode();
const { promptTokenCount, showAutoAcceptIndicator } = {
promptTokenCount: uiState.sessionStats.lastPromptTokenCount,
showAutoAcceptIndicator: uiState.showAutoAcceptIndicator,
};
const { columns: terminalWidth } = useTerminalSize();
const isNarrow = isNarrowWidth(terminalWidth);
// Determine sandbox info from environment
const sandboxEnv = process.env['SANDBOX'];
const sandboxInfo = sandboxEnv
? sandboxEnv === 'sandbox-exec'
? 'seatbelt'
: sandboxEnv.startsWith('qwen-code')
? 'docker'
: sandboxEnv
: null;
// Check if debug mode is enabled
const debugMode = config.getDebugMode();
const contextWindowSize =
config.getContentGeneratorConfig()?.contextWindowSize;
// Left section should show exactly ONE thing at any time, in priority order.
const leftContent = uiState.ctrlCPressedOnce ? (
{t('Press Ctrl+C again to exit.')}
) : uiState.ctrlDPressedOnce ? (
{t('Press Ctrl+D again to exit.')}
) : uiState.showEscapePrompt ? (
{t('Press Esc again to clear.')}
) : vimEnabled && vimMode === 'INSERT' ? (
-- INSERT --
) : uiState.shellModeActive ? (
) : showAutoAcceptIndicator !== undefined &&
showAutoAcceptIndicator !== ApprovalMode.DEFAULT ? (
) : (
{t('? for shortcuts')}
);
const rightItems: Array<{ key: string; node: React.ReactNode }> = [];
if (sandboxInfo) {
rightItems.push({
key: 'sandbox',
node: 🔒 {sandboxInfo},
});
}
if (debugMode) {
rightItems.push({
key: 'debug',
node: Debug Mode,
});
}
if (promptTokenCount > 0 && contextWindowSize) {
rightItems.push({
key: 'context',
node: (
),
});
}
if (verboseMode) {
rightItems.push({
key: 'verbose',
node: {t('verbose')},
});
}
return (
{/* Left Section: Exactly one status line (exit prompts / mode indicator / default hint) */}
{leftContent}
{/* Right Section: Sandbox Info, Debug Mode, Context Usage, and Console Summary */}
{rightItems.map(({ key, node }, index) => (
{index > 0 && | }
{node}
))}
);
};