/** * @license * Copyright 2026 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 { useConfig } from '../contexts/ConfigContext.js'; import { ToolConfirmationMessage } from './messages/ToolConfirmationMessage.js'; import { ToolStatusIndicator, ToolInfo } from './messages/ToolShared.js'; import { useUIState } from '../contexts/UIStateContext.js'; import type { ConfirmingToolState } from '../hooks/useConfirmingTool.js'; import { OverflowProvider } from '../contexts/OverflowContext.js'; import { ShowMoreLines } from './ShowMoreLines.js'; import { StickyHeader } from './StickyHeader.js'; import { useAlternateBuffer } from '../hooks/useAlternateBuffer.js'; import type { SerializableConfirmationDetails } from '@google/gemini-cli-core'; function getConfirmationHeader( details: SerializableConfirmationDetails | undefined, ): string { const headers: Partial< Record > = { ask_user: 'Answer Questions', }; if (!details?.type) { return 'Action Required'; } return headers[details.type] ?? 'Action Required'; } interface ToolConfirmationQueueProps { confirmingTool: ConfirmingToolState; } export const ToolConfirmationQueue: React.FC = ({ confirmingTool, }) => { const config = useConfig(); const isAlternateBuffer = useAlternateBuffer(); const { mainAreaWidth, terminalHeight, constrainHeight, availableTerminalHeight: uiAvailableHeight, } = useUIState(); const { tool, index, total } = confirmingTool; // Safety check: ToolConfirmationMessage requires confirmationDetails if (!tool.confirmationDetails) return null; // Render up to 100% of the available terminal height (minus 1 line for safety) // to maximize space for diffs and other content. const maxHeight = uiAvailableHeight !== undefined ? Math.max(uiAvailableHeight - 1, 4) : Math.floor(terminalHeight * 0.5); // ToolConfirmationMessage needs to know the height available for its OWN content. // We subtract the lines used by the Queue wrapper: // - 2 lines for the rounded border // - 2 lines for the Header (text + margin) // - 2 lines for Tool Identity (text + margin) const availableContentHeight = constrainHeight && !isAlternateBuffer ? Math.max(maxHeight - 6, 4) : undefined; const borderColor = theme.status.warning; const hideToolIdentity = tool.confirmationDetails?.type === 'ask_user'; return ( {/* Header */} {getConfirmationHeader(tool.confirmationDetails)} {total > 1 && ( {index} of {total} )} {!hideToolIdentity && ( )} {/* Interactive Area */} {/* Note: We force isFocused={true} because if this component is rendered, it effectively acts as a modal over the shell/composer. */} ); };