feat(ui): show images from PR and issue bodies in kitty-graphics terminals #60

Closed
opened 2026-10-08 14:51:18 -05:00 by deadstyle · 5 comments
Owner

Problem

Images in PR and issue bodies (screenshots) can't be seen in the terminal.

Idea

Render them inline, in the scrolling body, in terminals that speak the kitty graphics protocol; elsewhere show the alt text as a link (today's behavior). (PM: inline in the scrolling body, not a separate view.)

Plan (tracking issue; decided by Opus)

Kitty Unicode placeholders, so images scroll and clip like text. Delivered as:

  1. #65 fetch and decode authenticated images (forge + core, ADR 0015)
  2. #66 kitty graphics layer and terminal detection
  3. Markdown and details integration (filed once #65 and #66 merge). Needs the PM answers below.
  4. Optional: HTML <img>, WebP, external hosts.

Open product questions are in the 🤖 comment on this ticket.

## Problem Images in PR and issue bodies (screenshots) can't be seen in the terminal. ## Idea Render them inline, in the scrolling body, in terminals that speak the kitty graphics protocol; elsewhere show the alt text as a link (today's behavior). *(PM: inline in the scrolling body, not a separate view.)* ## Plan (tracking issue; decided by Opus) Kitty Unicode placeholders, so images scroll and clip like text. Delivered as: 1. #65 fetch and decode authenticated images (forge + core, ADR 0015) 2. #66 kitty graphics layer and terminal detection 3. Markdown and details integration (filed once #65 and #66 merge). Needs the PM answers below. 4. Optional: HTML `<img>`, WebP, external hosts. Open product questions are in the 🤖 comment on this ticket.
Author
Owner

🤖 PM answered: images render inline in the scrolling body (yazi does it), not in a separate view. Still needs a spike for authenticated image URLs and scrolling. Depends on #59.

🤖 PM answered: images render inline in the scrolling body (yazi does it), not in a separate view. Still needs a spike for authenticated image URLs and scrolling. Depends on #59.
Author
Owner

🤖 Engineering is settled (Opus; details in #65 and #66). Defaults below apply unless you say otherwise. #65 and #66 proceed now; only the final integration ticket waits on these.

  1. Images from other sites (shields.io, GitHub-hosted screenshots): loading them tells that site you opened the item. Recommend: v1 loads only images hosted on the forge you're connected to; others keep the 🖼 alt link.
  2. Image size: Recommend: fit the pane width, capped at the pane's visible height, so a whole image is on screen at once.
  3. Which terminals: Recommend: kitty and Ghostty only in v1; WezTerm keeps the link until we can verify it.
  4. Off switch: Recommend: a Settings toggle "Show images", default on.
  5. tmux: images need set -g allow-passthrough on. Recommend: without it, silent fallback to the link; we never change tmux settings.
  6. Loading and failure: Recommend: the link shows while an image loads or if it fails, with no error message.
🤖 Engineering is settled (Opus; details in #65 and #66). Defaults below apply unless you say otherwise. #65 and #66 proceed now; only the final integration ticket waits on these. 1. **Images from other sites** (shields.io, GitHub-hosted screenshots): loading them tells that site you opened the item. *Recommend:* v1 loads only images hosted on the forge you're connected to; others keep the `🖼 alt` link. 2. **Image size:** *Recommend:* fit the pane width, capped at the pane's visible height, so a whole image is on screen at once. 3. **Which terminals:** *Recommend:* kitty and Ghostty only in v1; WezTerm keeps the link until we can verify it. 4. **Off switch:** *Recommend:* a Settings toggle "Show images", default on. 5. **tmux:** images need `set -g allow-passthrough on`. *Recommend:* without it, silent fallback to the link; we never change tmux settings. 6. **Loading and failure:** *Recommend:* the link shows while an image loads or if it fails, with no error message.
Author
Owner

🤖 PM answered: 1) only images on our own forge; 2) fit pane width, capped at visible height; 3) auto-detect any capable terminal if possible, else kitty and Ghostty; 4) Settings toggle 'Show images', default on; 5) tmux without allow-passthrough falls back silently; 6) link while loading or on failure, no error. On 3: the protocol query tells us a terminal speaks kitty graphics, but nothing tells us it supports the placeholder method (WezTerm answers yes to the query and lacks placeholders). So detection is automatic, but the placeholder-capable list is an allowlist (kitty, Ghostty) that grows as terminals are verified. The integration MR records these answers in docs/design.md.

🤖 PM answered: 1) only images on our own forge; 2) fit pane width, capped at visible height; 3) auto-detect any capable terminal if possible, else kitty and Ghostty; 4) Settings toggle 'Show images', default on; 5) tmux without allow-passthrough falls back silently; 6) link while loading or on failure, no error. On 3: the protocol query tells us a terminal speaks kitty graphics, but nothing tells us it supports the placeholder method (WezTerm answers yes to the query and lacks placeholders). So detection is automatic, but the placeholder-capable list is an allowlist (kitty, Ghostty) that grows as terminals are verified. The integration MR records these answers in docs/design.md.
Author
Owner

🤖 #65 (merged, PR 69) and #66 (merged, PR 70) are done. The last piece is filed as #71 (Details pane integration), with acceptance criteria taken from your six answers. #60 stays open as the tracking issue until #71 merges.

🤖 #65 (merged, PR 69) and #66 (merged, PR 70) are done. The last piece is filed as #71 (Details pane integration), with acceptance criteria taken from your six answers. #60 stays open as the tracking issue until #71 merges.
Author
Owner

🤖 done: #65 (PR 69), #66 (PR 70) and #71 (PR 78) are merged. Real-terminal check (kitty, Ghostty, tmux) is still manual.

🤖 done: #65 (PR 69), #66 (PR 70) and #71 (PR 78) are merged. Real-terminal check (kitty, Ghostty, tmux) is still manual.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
deadstyle/lazyforge#60
No description provided.