import type { ToolResultBlockParam } from '@anthropic-ai/sdk/resources/index.mjs' import * as React from 'react' import { KeyboardShortcutHint } from '@anthropic/ink' import { FallbackToolUseErrorMessage } from '../../components/FallbackToolUseErrorMessage.js' import { MessageResponse } from '../../components/MessageResponse.js' import { OutputLine } from '../../components/shell/OutputLine.js' import { ShellProgressMessage } from '../../components/shell/ShellProgressMessage.js' import { ShellTimeDisplay } from '../../components/shell/ShellTimeDisplay.js' import { Box, Text } from '@anthropic/ink' import type { Tool } from '../../Tool.js' import type { ProgressMessage } from '../../types/message.js' import type { PowerShellProgress } from '../../types/tools.js' import type { ThemeName } from '../../utils/theme.js' import type { Out, PowerShellToolInput } from './PowerShellTool.js' // Constants for command display const MAX_COMMAND_DISPLAY_LINES = 2 const MAX_COMMAND_DISPLAY_CHARS = 160 export function renderToolUseMessage( input: Partial, { verbose, theme: _theme }: { verbose: boolean; theme: ThemeName }, ): React.ReactNode { const { command } = input if (!command) { return null } const displayCommand = command if (!verbose) { const lines = displayCommand.split('\n') const needsLineTruncation = lines.length > MAX_COMMAND_DISPLAY_LINES const needsCharTruncation = displayCommand.length > MAX_COMMAND_DISPLAY_CHARS if (needsLineTruncation || needsCharTruncation) { let truncated = displayCommand if (needsLineTruncation) { truncated = lines.slice(0, MAX_COMMAND_DISPLAY_LINES).join('\n') } if (truncated.length > MAX_COMMAND_DISPLAY_CHARS) { truncated = truncated.slice(0, MAX_COMMAND_DISPLAY_CHARS) } return {truncated.trim()}… } } return displayCommand } export function renderToolUseProgressMessage( progressMessagesForMessage: ProgressMessage[], { verbose, tools: _tools, terminalSize: _terminalSize, inProgressToolCallCount: _inProgressToolCallCount, }: { tools: Tool[] verbose: boolean terminalSize?: { columns: number; rows: number } inProgressToolCallCount?: number }, ): React.ReactNode { const lastProgress = progressMessagesForMessage.at(-1) if (!lastProgress || !lastProgress.data) { return ( Running… ) } const data = lastProgress.data return ( ) } export function renderToolUseQueuedMessage(): React.ReactNode { return ( Waiting… ) } export function renderToolResultMessage( content: Out, progressMessagesForMessage: ProgressMessage[], { verbose, theme: _theme, tools: _tools, style: _style, }: { verbose: boolean theme: ThemeName tools: Tool[] style?: 'condensed' }, ): React.ReactNode { const lastProgress = progressMessagesForMessage.at(-1) const timeoutMs = lastProgress?.data?.timeoutMs const { stdout, stderr, interrupted, returnCodeInterpretation, isImage, backgroundTaskId, } = content if (isImage) { return ( [Image data detected and sent to Claude] ) } return ( {stdout !== '' ? : null} {stderr.trim() !== '' ? ( ) : null} {stdout === '' && stderr.trim() === '' ? ( {backgroundTaskId ? ( <> Running in the background{' '} ) : interrupted ? ( 'Interrupted' ) : ( returnCodeInterpretation || '(No output)' )} ) : null} {timeoutMs ? ( ) : null} ) } export function renderToolUseErrorMessage( result: ToolResultBlockParam['content'], { verbose, progressMessagesForMessage: _progressMessagesForMessage, tools: _tools, }: { verbose: boolean progressMessagesForMessage: ProgressMessage[] tools: Tool[] }, ): React.ReactNode { return }