aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/domains/screenshot.ts15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/domains/screenshot.ts b/src/domains/screenshot.ts
index 60d4b26..74042be 100644
--- a/src/domains/screenshot.ts
+++ b/src/domains/screenshot.ts
@@ -1,7 +1,7 @@
import { readFileSync } from "node:fs";
import { writeFile, rename } from "node:fs/promises";
import { Type } from "typebox";
-import { Image, type ImageTheme, Text } from "@mariozechner/pi-tui";
+import { Image, type ImageTheme, Text, truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
import type { BrowserClient } from "../client";
import { type Result, err, ok } from "../util/result";
import { defineBrowserTool, type ToolErr, type ToolOk } from "../util/tool";
@@ -98,11 +98,22 @@ export const screenshotTool = defineBrowserTool({
const imageTheme: ImageTheme = {
fallbackColor: (str: string) => theme.fg("dim", str),
};
- return new Image(b64, mimeType, imageTheme, {
+ const image = new Image(b64, mimeType, imageTheme, {
maxWidthCells: 80,
maxHeightCells: 24,
filename: filePath,
});
+ // Image's text fallback (when terminal lacks inline-image support) does
+ // not respect the rendered width, so a long file path can blow past the
+ // terminal width and crash the host TUI. Wrap the component to truncate
+ // each rendered line to fit.
+ return {
+ invalidate: () => image.invalidate(),
+ render: (width: number) =>
+ image.render(width).map((line) =>
+ visibleWidth(line) > width ? truncateToWidth(line, width) : line,
+ ),
+ };
} catch {
return new Text(theme.fg("warning", `Screenshot saved: ${filePath}`), 0, 0);
}