/** * @license * Copyright 2026 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import type React from 'react'; import { Box, Text } from 'ink'; import type { HistoryItem, HistoryItemWithoutId, HistoryItemToolDisplayGroup, ToolDisplayItem, } from '../../types.js'; import { theme } from '../../semantic-colors.js'; import { ToolStatusIndicator } from './ToolShared.js'; import { useSettings } from '../../contexts/SettingsContext.js'; interface ToolGroupDisplayProps { item: HistoryItem | HistoryItemWithoutId; isToolGroupBoundary?: boolean; } export const ToolGroupDisplay: React.FC = ({ item, isToolGroupBoundary, }) => { if (item.type !== 'tool_display_group') { return null; } const { tools, borderColor, borderDimColor, borderTop, borderBottom } = item as HistoryItemToolDisplayGroup; return ( {tools.map((tool, index) => ( ))} ); }; interface ToolDisplayMessageProps { tool: ToolDisplayItem; } const ToolDisplayMessage: React.FC = ({ tool }) => { const settings = useSettings(); const isCompactModeEnabled = settings.merged.ui?.compactToolOutput === true; // Since ToolDisplayItem is ToolDisplay & { status, ... }, we check for identifying properties // of ToolDisplay. If name or description is missing and there's no result, it might be "empty". // But per instructions, if display is missing (which we now interpret as the ToolDisplay part being effectively empty/null), show error. if (!tool.name && !tool.description && !tool.result && !tool.resultSummary) { return ( Error: Tool display missing ); } const { status, format: preferredFormat, name, description, resultSummary, result, } = tool; const format = preferredFormat || 'auto'; if (format === 'hidden') { return null; } const isCompact = format === 'compact' || (format === 'auto' && isCompactModeEnabled); if (isCompact) { return ( {' '} {name || tool.originalRequestName}{' '} {description && {description}} {resultSummary && ( → {resultSummary} )} ); } // Box format (full) return ( {' '} {name || tool.originalRequestName}{' '} {description && {description}} {resultSummary && !result && ( → {resultSummary} )} {result && ( )} ); }; interface ToolResultDisplayContentProps { content: ToolDisplayItem['result']; summary?: string | null; } const ToolResultDisplayContent: React.FC = ({ content, summary, }) => { if (!content) return null; switch (content.type) { case 'text': return {content.text}; case 'diff': // Simplified diff display for now return ( {summary && {summary}} {`[Diff Display: ${content.beforeText.length} -> ${content.afterText.length} chars]`} ); case 'terminal': return [Terminal Output]; case 'agent': return ( [Subagent: {content.threadId}] ); default: return null; } };