import React from 'react' import { removeSandboxViolationTags } from 'src/utils/sandbox/sandbox-ui-utils.js' import { KeyboardShortcutHint } from '../../components/design-system/KeyboardShortcutHint.js' import { MessageResponse } from '../../components/MessageResponse.js' import { OutputLine } from '../../components/shell/OutputLine.js' import { ShellTimeDisplay } from '../../components/shell/ShellTimeDisplay.js' import { Box, Text } from '../../ink.js' import type { Out as BashOut } from './BashTool.js' type Props = { content: Omit verbose: boolean timeoutMs?: number } // Pattern to match "Shell cwd was reset to " message // Use (?:^|\n) to match either start of string or after a newline const SHELL_CWD_RESET_PATTERN = /(?:^|\n)(Shell cwd was reset to .+)$/ /** * Extracts sandbox violations from stderr if present * Returns both the cleaned stderr and the violations content */ function extractSandboxViolations(stderr: string): { cleanedStderr: string } { const violationsMatch = stderr.match( /([\s\S]*?)<\/sandbox_violations>/, ) if (!violationsMatch) { return { cleanedStderr: stderr } } // Remove the sandbox violations section from stderr const cleanedStderr = removeSandboxViolationTags(stderr).trim() return { cleanedStderr, } } /** * Extracts the "Shell cwd was reset" warning message from stderr * Returns the cleaned stderr and the warning message separately */ function extractCwdResetWarning(stderr: string): { cleanedStderr: string cwdResetWarning: string | null } { const match = stderr.match(SHELL_CWD_RESET_PATTERN) if (!match) { return { cleanedStderr: stderr, cwdResetWarning: null } } // Extract the warning message from capture group 1 const cwdResetWarning = match[1] ?? null // Remove the warning from stderr (replace the full match) const cleanedStderr = stderr.replace(SHELL_CWD_RESET_PATTERN, '').trim() return { cleanedStderr, cwdResetWarning } } export default function BashToolResultMessage({ content: { stdout = '', stderr: stdErrWithViolations = '', isImage, returnCodeInterpretation, noOutputExpected, backgroundTaskId, }, verbose, timeoutMs, }: Props): React.ReactNode { // Extract sandbox violations from stderr as it feels cleaner on the UI // We want the model to see the violations, so it can explain what went wrong, and the // user can access them in the violation logs const { cleanedStderr: stderrWithoutViolations } = extractSandboxViolations(stdErrWithViolations) // Extract "Shell cwd was reset" warning to render it with warning color instead of error const { cleanedStderr: stderr, cwdResetWarning } = extractCwdResetWarning( stderrWithoutViolations, ) // If this is an image, we don't want to truncate it in the UI if (isImage) { return ( [Image data detected and sent to Claude] ) } return ( {stdout !== '' ? : null} {stderr.trim() !== '' ? ( ) : null} {cwdResetWarning ? ( {cwdResetWarning} ) : null} {stdout === '' && stderr.trim() === '' && !cwdResetWarning ? ( {backgroundTaskId ? ( <> Running in the background{' '} ) : ( returnCodeInterpretation || (noOutputExpected ? 'Done' : '(No output)') )} ) : null} {timeoutMs && ( )} ) }