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, parseDiff } from "./utils.js"
const MAX_DIFF_LINES = 15
export function FileWriteTool({ toolData }: ToolRendererProps) {
const iconName = getToolIconName(toolData.tool)
const displayName = getToolDisplayName(toolData.tool)
const path = toolData.path || ""
const diffStats = toolData.diffStats
const diff = toolData.diff ? sanitizeContent(toolData.diff) : ""
const isProtected = toolData.isProtected
const isOutsideWorkspace = toolData.isOutsideWorkspace
const isNewFile = toolData.tool === "newFileCreated" || toolData.tool === "write_to_file"
// Handle batch diff operations
if (toolData.batchDiffs && toolData.batchDiffs.length > 0) {
return (
{/* Header */}
{" "}
{displayName}
({toolData.batchDiffs.length} files)
{/* File list with stats */}
{toolData.batchDiffs.slice(0, 8).map((file, index) => (
{file.path}
{file.diffStats && (
+{file.diffStats.added}
/
-{file.diffStats.removed}
)}
))}
{toolData.batchDiffs.length > 8 && (
... and {toolData.batchDiffs.length - 8} more files
)}
)
}
// Single file write
const { text: previewDiff, truncated, hiddenLines } = truncateText(diff, MAX_DIFF_LINES)
const diffHunks = diff ? parseDiff(diff) : []
return (
{/* Header row with path on same line */}
{displayName}
{path && (
<>
ยท
{path}
>
)}
{isNewFile && (
{" "}
NEW
)}
{/* Diff stats badge */}
{diffStats && (
<>
+{diffStats.added}
/
-{diffStats.removed}
>
)}
{/* Warning badges */}
{isProtected && ๐ protected}
{isOutsideWorkspace && (
{" "}
โ outside workspace
)}
{/* Diff preview */}
{diffHunks.length > 0 && (
{diffHunks.slice(0, 2).map((hunk, hunkIndex) => (
{/* Hunk header */}
{hunk.header}
{/* Diff lines */}
{hunk.lines.slice(0, 8).map((line, lineIndex) => (
{line.type === "added" ? "+" : line.type === "removed" ? "-" : " "}
{line.content}
))}
{hunk.lines.length > 8 && (
... ({hunk.lines.length - 8} more lines in hunk)
)}
))}
{diffHunks.length > 2 && (
... ({diffHunks.length - 2} more hunks)
)}
)}
{/* Fallback to raw diff if no hunks parsed */}
{diffHunks.length === 0 && previewDiff && (
{previewDiff}
{truncated && (
... ({hiddenLines} more lines)
)}
)}
)
}