From 0ed1b0431444f1e9321c5cf3a9e0acd04da11f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Hou=C5=A1ka?= Date: Mon, 19 Oct 2026 22:01:41 +0200 Subject: [PATCH] feat(tui): detect Rex terminal for OSC 8 hyperlinks Rex supports OSC 8 but was treated as an unknown terminal, so links fell back to the `text (url)` format. Detect it via TERM_PROGRAM=rex and enable hyperlinks and truecolor. Images stay off because Rex only partially implements the Kitty graphics protocol (no Unicode placeholders). The check runs before the outer-terminal checks so leaked variables like KITTY_WINDOW_ID don't win. Closes #11131 --- packages/tui/src/terminal-image.ts | 6 ++++++ packages/tui/test/terminal-image.test.ts | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/packages/tui/src/terminal-image.ts b/packages/tui/src/terminal-image.ts index ec2a2338f..fd7001fdd 100644 --- a/packages/tui/src/terminal-image.ts +++ b/packages/tui/src/terminal-image.ts @@ -92,6 +92,12 @@ function detectCapabilitiesFromEnvironment(tmuxForwardsHyperlink: () => boolean) return { images: "kitty", trueColor: hasTrueColorHint, hyperlinks: true }; } + // Rex supports OSC 8 hyperlinks but only partially implements the Kitty graphics protocol + // (no Unicode placeholders), so leave images off. Check it before outer-terminal detection. + if (termProgram === "rex") { + return { images: null, trueColor: true, hyperlinks: true }; + } + if (process.env.KITTY_WINDOW_ID || termProgram === "kitty") { return { images: "kitty", trueColor: true, hyperlinks: true }; } diff --git a/packages/tui/test/terminal-image.test.ts b/packages/tui/test/terminal-image.test.ts index aa28c7537..063ab0862 100644 --- a/packages/tui/test/terminal-image.test.ts +++ b/packages/tui/test/terminal-image.test.ts @@ -330,6 +330,19 @@ describe("detectCapabilities", () => { }); }); + // #11131 + it("enables hyperlinks without images for Rex", () => { + withEnv({ TERM_PROGRAM: "rex", TERM: "xterm-256color", KITTY_WINDOW_ID: "1" }, () => { + const caps = detectCapabilities(); + assert.strictEqual(caps.hyperlinks, true); + assert.strictEqual(caps.images, null); + assert.strictEqual(caps.trueColor, true); + }); + withEnv({ TERM_PROGRAM: "rex", PI_HYPERLINKS: "0" }, () => { + assert.strictEqual(detectCapabilities().hyperlinks, false); + }); + }); + it("enables hyperlinks for Ghostty", () => { withEnv({ TERM_PROGRAM: "ghostty" }, () => { const caps = detectCapabilities();