Conversation
Implement SixelRenderer as a new RendererPort implementation that outputs Sixel escape sequences. Unlike Kitty (upload once, display by ID), Sixel re-encodes each frame inline using Floyd-Steinberg dithering with a 216-color uniform palette. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add CLI flag to choose between kitty (default) and sixel renderers. Introduce createRenderer factory function for DI wiring. Both runStatic and runViewer now accept and propagate the renderer type. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover Display, Upload, Clear, minimap operations, cache behavior, Sixel encoding, RLE compression, and palette generation. Renderer package coverage increased from 42% to 83%. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Sixel-capable terminals to compatibility table, document -r/--renderer flag usage, and update architecture description. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Kitty Graphics Protocol 非対応のターミナルでも画像表示できるように、Sixel グラフィックスプロトコル対応を追加し、CLI からレンダラを選択可能にする PR です。renderer 実装を RendererPort の差し替えで吸収し、既存のユースケース構造に統合しています。
Changes:
SixelRenderer(Sixel エンコード、ミニマップ、キャッシュ)を新規追加--renderer / -rフラグとcreateRendererファクトリでkitty|sixelを選択可能に- README の対応ターミナル表・使用例を更新、Sixel のテストを追加
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| internal/adapter/renderer/sixel_renderer.go | Sixel 描画・ミニマップ描画・Sixel エンコード処理を追加 |
| internal/adapter/renderer/sixel_renderer_test.go | SixelRenderer の基本動作、ミニマップ、エンコード周りのテストを追加 |
| cmd/gaze/main.go | --renderer/-r 追加とレンダラ生成の DI 抽象化(kitty/sixel 切替) |
| README.md | Sixel 対応の説明・対応ターミナル表・CLI 使用例を追加 |
| func (r *SixelRenderer) ClearMinimap() error { | ||
| r.prevCached = false | ||
| r.prevSixel = "" | ||
| return nil |
There was a problem hiding this comment.
SixelRenderer の ClearMinimap がキャッシュ無効化だけで端末上のミニマップ表示を消していないため、RenderFrameUseCase の「表示→非表示」遷移時にミニマップが画面に残る可能性があります(KittyRenderer は端末側画像を削除して見た目も消える)。Sixel でも最後に描画した位置・サイズを保持して、その領域を空白で上書きする(または ERASE 系 CSI を併用する)など、画面上のミニマップを確実に消す処理を入れてください。
| // Collect colors used in this band | ||
| usedInBand := make(map[uint8]bool) | ||
| for dy := 0; dy < bandH; dy++ { | ||
| rowOff := (bandY + dy) * paletted.Stride | ||
| for x := 0; x < w; x++ { | ||
| usedInBand[paletted.Pix[rowOff+x]] = true | ||
| } | ||
| } | ||
|
|
||
| sortedColors := make([]uint8, 0, len(usedInBand)) | ||
| for ci := range usedInBand { | ||
| sortedColors = append(sortedColors, ci) | ||
| } | ||
| sort.Slice(sortedColors, func(i, j int) bool { return sortedColors[i] < sortedColors[j] }) |
There was a problem hiding this comment.
encodeSixel のバンド処理で usedInBand を map で作成→keys を sort しており、フレーム毎にバンド数分の割り当てとソートが発生します(Sixel は毎フレーム再エンコードなので GC/CPU コストが積み上がりやすいです)。パレットが 216 色で固定なので、[216]bool のフラグ配列 + インデックス配列の再利用などで map/sort を避ける形にすると負荷を下げられます。
Bubbletea's line-based diff renderer corrupts DCS escape sequences when they are returned via View(). Write Sixel image data directly to stdout (like Kitty's Upload does) and return only cursor positioning from Display/DisplayMinimap for Bubbletea to handle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
概要
Sixel グラフィックスプロトコルに対応し、
--renderer / -rフラグでkitty(デフォルト)またはsixelを選択できるようにした。これにより Kitty Graphics Protocol 非対応のターミナル(foot, mlterm, xterm 等)でも画像表示が可能になる。変更内容
SixelRendererを新規作成(RendererPortインターフェースの実装)--renderer / -rCLI フラグを追加(kitty|sixel、デフォルト:kitty)createRendererファクトリ関数で DI 配線を抽象化テスト計画
make ci)internal/adapter/renderer/sixel_renderer_test.go(20テストケース)備考
RendererPortインターフェースへの変更なし(既存の Kitty レンダリングパスに影響なし)🤖 Generated with Claude Code