import { Box, Text } from "ink" import * as theme from "../../theme.js" import { Icon } from "../Icon.js" import type { ToolRendererProps } from "./types.js" import { truncateText, sanitizeContent, getToolDisplayName, getToolIconName } from "./utils.js" const MAX_CONTENT_LINES = 12 export function GenericTool({ toolData, rawContent }: ToolRendererProps) { const iconName = getToolIconName(toolData.tool) const displayName = getToolDisplayName(toolData.tool) // Gather all available information const path = toolData.path const content = toolData.content ? sanitizeContent(toolData.content) : "" const reason = toolData.reason ? sanitizeContent(toolData.reason) : "" const mode = toolData.mode // Build display content from available fields let displayContent = content || reason || "" // If we have no structured content but have raw content, try to parse it if (!displayContent && rawContent) { try { const parsed = JSON.parse(rawContent) // Extract any content-like fields displayContent = sanitizeContent(parsed.content || parsed.output || parsed.result || parsed.reason || "") } catch { // Use raw content as-is if not JSON displayContent = sanitizeContent(rawContent) } } const { text: previewContent, truncated, hiddenLines } = truncateText(displayContent, MAX_CONTENT_LINES) return ( {/* Header */} {" "} {displayName} {/* Path if present */} {path && ( path: {path} {toolData.isOutsideWorkspace && ( {" "} ⚠ outside workspace )} {toolData.isProtected && 🔒 protected} )} {/* Mode if present */} {mode && ( mode: {mode} )} {/* Content */} {previewContent && ( {previewContent.split("\n").map((line, i) => ( {line} ))} {truncated && ( ... ({hiddenLines} more lines) )} )} ) }