--- type: decision adr: 004 status: accepted date: 2026-10-17 supersedes: tags: [adr, preview, kitty, sixel] --- # ADR-004: image preview protocol chain (kitty first) ## Context Ranger's biggest UX liability is image preview depending on unmaintained X11-only ueberzug. Research ([[research/rust-preview-stack]]): terminals support one of several incompatible graphics protocols; no single one covers everything. The owner's daily terminal is **kitty without a multiplexer**, but viexp targets all Linux users. ## Options considered | Option | Pros | Cons | |--------|------|------| | Multi-protocol chain behind one trait, runtime detection (yazi model) | works everywhere; upgrade path | most implementation work | | kitty-only | minimal work for owner's setup | useless for everyone else; vifm/nnn trap | | Always chafa/halfblocks | works everywhere incl. ssh | ugly; not a differentiator | ## Decision Implement a `GraphicsAdapter` trait with a **priority chain, first match wins**: 1. **kitty graphics** (unicode-placeholder mode) — kitty ≥0.28, Ghostty — implemented first 2. **iTerm2 inline** images 3. **sixel** (via ratatui-image/quantette) 4. **ueberzug++ subprocess** (X11 + wlroots Wayland) 5. **chafa/halfblocks** — universal floor 6. plain text (name, size, mime) Detection: `$TERM`/`$TERM_PROGRAM`/`$XDG_SESSION_TYPE` env + terminal capability queries; shortcut via `ratatui-image` `Picker`, with ueberzug++/chafa as our tiers 4–5. Thumbnails: decode once at preview size → disk cache → in-memory LRU → neighbor preloading. ## Consequences - Positive: owner gets tier-1 quality from Sprint 6; everyone else degrades gracefully; no dead X11 dependency. - Negative: five adapters is real work; tmux/alacritty edge cases documented, not solved. - Mitigations: chain built incrementally (kitty in Sprint 6, sixel/ueberzug++ in the backlog); adapter chosen once per session, cached.