From f603a377ae5bee929d86a31aa4d35da559d401bf Mon Sep 17 00:00:00 2001 From: Nico Bailon Date: Fri, 12 Dec 2025 19:35:54 -0800 Subject: [PATCH] add PI_NO_IMAGES env var to disable inline image rendering --- packages/tui/src/terminal-image.ts | 6 ++++ packages/tui/test/image-test.ts | 56 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 packages/tui/test/image-test.ts diff --git a/packages/tui/src/terminal-image.ts b/packages/tui/src/terminal-image.ts index 35daf0d0..8ad801da 100644 --- a/packages/tui/src/terminal-image.ts +++ b/packages/tui/src/terminal-image.ts @@ -28,6 +28,12 @@ export function detectCapabilities(): TerminalCapabilities { const termProgram = process.env.TERM_PROGRAM?.toLowerCase() || ""; const term = process.env.TERM?.toLowerCase() || ""; const colorTerm = process.env.COLORTERM?.toLowerCase() || ""; + const disableImages = process.env.PI_NO_IMAGES === "1" || process.env.PI_NO_IMAGES === "true"; + + if (disableImages) { + const trueColor = colorTerm === "truecolor" || colorTerm === "24bit"; + return { images: null, trueColor, hyperlinks: true }; + } if (process.env.KITTY_WINDOW_ID || termProgram === "kitty") { return { images: "kitty", trueColor: true, hyperlinks: true }; diff --git a/packages/tui/test/image-test.ts b/packages/tui/test/image-test.ts new file mode 100644 index 00000000..f24d24c0 --- /dev/null +++ b/packages/tui/test/image-test.ts @@ -0,0 +1,56 @@ +import { readFileSync } from "fs"; +import { Image } from "../src/components/image.js"; +import { Spacer } from "../src/components/spacer.js"; +import { Text } from "../src/components/text.js"; +import { ProcessTerminal } from "../src/terminal.js"; +import { getCapabilities, getImageDimensions } from "../src/terminal-image.js"; +import { TUI } from "../src/tui.js"; + +const testImagePath = process.argv[2] || "/tmp/test-image.png"; + +console.log("Terminal capabilities:", getCapabilities()); +console.log("Loading image from:", testImagePath); + +let imageBuffer: Buffer; +try { + imageBuffer = readFileSync(testImagePath); +} catch (e) { + console.error(`Failed to load image: ${testImagePath}`); + console.error("Usage: npx tsx test/image-test.ts [path-to-image.png]"); + process.exit(1); +} + +const base64Data = imageBuffer.toString("base64"); +const dims = getImageDimensions(base64Data, "image/png"); + +console.log("Image dimensions:", dims); +console.log(""); + +const terminal = new ProcessTerminal(); +const tui = new TUI(terminal); + +tui.addChild(new Text("Image Rendering Test", 1, 1)); +tui.addChild(new Spacer(1)); + +if (dims) { + tui.addChild( + new Image(base64Data, "image/png", { fallbackColor: (s) => `\x1b[33m${s}\x1b[0m` }, { maxWidthCells: 60 }, dims), + ); +} else { + tui.addChild(new Text("Could not parse image dimensions", 1, 0)); +} + +tui.addChild(new Spacer(1)); +tui.addChild(new Text("Press Ctrl+C to exit", 1, 0)); + +const editor = { + handleInput(data: string) { + if (data.charCodeAt(0) === 3) { + tui.stop(); + process.exit(0); + } + }, +}; + +tui.setFocus(editor as any); +tui.start();