fix(tui): detect Orca terminals as Kitty-image capable (#9329)

## Summary

Treat `TERM_PROGRAM=Orca` as Kitty-image capable in `pi-tui`'s terminal
capability detection, so image components render inline instead of
falling back to text when running inside Orca.

- Recognize Orca as supporting Kitty inline images, true color, and OSC
8 hyperlinks.
- Preserve the existing tmux and screen precedence guards.
- Gate images on Orca's capability advertisement: require both
`TERM_PROGRAM=Orca` and Orca's `ORCA_IMAGE_PROTOCOL=kitty` signal before
enabling Kitty output, so existing Orca releases that do not yet
advertise image support safely keep the text fallback.
- Add a regression test and the package/CLI changesets.

## Related

- Requested by maintainer approval in
[earendil-works/pi#7357](https://github.com/earendil-works/pi/issues/7357)
(lgtm).
- Depends on the Orca-side capability advertisement, which has landed:
[stablyai/orca#19512](https://github.com/stablyai/orca/pull/19512)
(merged 2026-09-18, `09073086a8`) exports `ORCA_IMAGE_PROTOCOL=kitty` on
the daemon, local, and relay PTY paths, and forwards it across the WSL
boundary. Supersedes
[stablyai/orca#11706](https://github.com/stablyai/orca/pull/11706),
which was closed in favor of #19512.

## Testing

- `pnpm --filter @moonshot-ai/pi-tui test` — focused regression suite
passes.
- `pnpm --filter @moonshot-ai/pi-tui typecheck` — passes.
This commit is contained in:
Rcardo 2026-10-30 05:11:08 +08:00 • committed by GitHub
parent 2ce9d527d9
commit f09d01b85e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 24 additions and 0 deletions

View file

@ -96,6 +96,13 @@ function detectCapabilitiesFromEnvironment(tmuxForwardsHyperlink: () => boolean)
return { images: "kitty", trueColor: true, hyperlinks: true };
}
// Orca supports Kitty graphics but only advertises it through ORCA_IMAGE_PROTOCOL. Require
// both signals so Orca releases predating that advertisement keep the text fallback instead
// of reserving image rows that nothing renders.
if (termProgram === "orca" && process.env.ORCA_IMAGE_PROTOCOL === "kitty") {
return { images: "kitty", trueColor: true, hyperlinks: true };
}
if (process.env.KITTY_WINDOW_ID || termProgram === "kitty") {
return { images: "kitty", trueColor: true, hyperlinks: true };
}

View file

@ -34,6 +34,7 @@ import { visibleWidth } from "../src/utils.ts";
const ENV_KEYS = [
"TERM",
"TERM_PROGRAM",
"ORCA_IMAGE_PROTOCOL",
"TERMINAL_EMULATOR",
"COLORTERM",
"TMUX",
@ -343,6 +344,22 @@ describe("detectCapabilities", () => {
});
});
it("keeps images disabled for Orca without an image capability signal", () => {
withEnv({ TERM_PROGRAM: "Orca" }, () => {
const caps = detectCapabilities();
assert.strictEqual(caps.images, null);
});
});
it("enables images and hyperlinks for Orca advertising Kitty support", () => {
withEnv({ TERM_PROGRAM: "Orca", ORCA_IMAGE_PROTOCOL: "kitty" }, () => {
const caps = detectCapabilities();
assert.strictEqual(caps.images, "kitty");
assert.strictEqual(caps.trueColor, true);
assert.strictEqual(caps.hyperlinks, true);
});
});
it("enables hyperlinks for Ghostty", () => {
withEnv({ TERM_PROGRAM: "ghostty" }, () => {
const caps = detectCapabilities();