// Renders a read tool result as bounded lines with file offsets. Ported from // the pi-fabric read preview (src/ui/core-tool-render.ts renderContent): the // same `NN │ text` shape, first-line offset from the read call's offset arg, // and the shared 2000-char preview bound. import type { Theme } from "@earendil-works/pi-coding-agent"; import { boundPreviewLines } from "./bound.ts"; import { previewStyle } from "./style.ts"; export interface ReadPreviewInput { /** Line limit of the read call; the read tool already bounds the output. */ readonly limit?: number; /** First line of the read (defaults to 1). */ readonly offset?: number; /** The read result text. */ readonly output: string; /** File that was read; the row title already shows it (call context). */ readonly path: string; } export function renderReadPreview( input: ReadPreviewInput, theme?: Theme ): string[] { if (input.output.trim().length === 0) { return [previewStyle(theme, "muted", "(empty file)")]; } const firstLine = Math.max(1, Math.floor(input.offset ?? 1)); const lines = input.output .replace(/\r\n/g, "\n") .replace(/\r/g, "\n") .split("\n"); if (lines.length > 1 && (lines.at(-1) ?? "") === "") { lines.pop(); } const width = String(firstLine + lines.length - 1).length; const rendered = lines.map((text, index) => { const lineNumber = String(firstLine + index).padStart(width, " "); const content = text.length === 0 ? " " : text; return `${previewStyle(theme, "dim", `${lineNumber} │ `)}${previewStyle( theme, "toolOutput", content )}`; }); return [...boundPreviewLines(rendered).lines]; }