2TDG53JBZHZA6ZPYONPINKVDV4UXLP4T4CI5C2MEZIIYO7DQE5RAC FRY33K6EGWLU3F5NJJ66AT5RBV6OEOWSDKY3JH2CPKKGPAHOMM6AC 5KIKDA72HM6JFIPKOWGLM2EO7D5PTSK7WEVYV3YZWGMG3M34PJXQC 34FVOOTLYPUGWW52DALTVLTMBS7SMM4KB2G2G4CX5CDGBOEYQQSAC DBOROCRFD6A5SJBMFYFEJI5S5M77X4EFEK6KDQWA5QDMQJKIHRWQC 3JA7HYRMHV57SIMGMGPDOMKQ3NBQS2SKOX3EKDHRBQRP7ZPZGFTQC GQNMVJQBC6DRV5XGK3K5L7YWG2GJUXR7EQE3OHNW72XK6BFY3AHQC D4EL6RSTSZ3S3IDSETRNGLJHZKGZEE2V2OZIOKQK6LRLHQNS77JQC W3A2EECCD23SVHJZN6MXPH2PAVFHH5CNFD2XHPQRRW6M4GUTG3FAC ZFMOUTHEMHYYEAGXRQ3L427FVZPNBC7CX6QATVXU2KPDJOVEH2EQC }}func TestWriteITermImage(t *testing.T) {img := image.NewGray(image.Rect(0, 0, 4, 4))img.SetGray(0, 0, color.Gray{Y: 128})var buf strings.Builderif err := WriteITermImage(img, &buf); err != nil {t.Fatalf("WriteITermImage: %v", err)}out := buf.String()if !strings.HasPrefix(out, "\x1b]1337;File=") {t.Errorf("expected iTerm2 OSC prefix, got %q", out[:min(30, len(out))])}if !strings.Contains(out, "inline=1") {t.Error("expected inline=1 parameter")}if !strings.HasSuffix(out, "\x07") {t.Error("expected BEL terminator")}}func TestWriteImage_ITerm(t *testing.T) {img := image.NewGray(image.Rect(0, 0, 4, 4))var buf strings.Builderif err := WriteImage(img, &buf, ProtocolITerm); err != nil {t.Fatalf("WriteImage iterm: %v", err)}if !strings.HasPrefix(buf.String(), "\x1b]1337;File=") {t.Error("expected iTerm2 OSC prefix")}}func TestClearImages_ITerm(t *testing.T) {var buf strings.BuilderClearImages(&buf, ProtocolITerm)if buf.String() != "" {t.Errorf("expected no output for iTerm2 clear, got %q", buf.String())
return err}// WriteITermImage writes an image using the iTerm2 Inline Image Protocol.func WriteITermImage(img image.Image, w io.Writer) error {var buf bytes.Bufferif err := png.Encode(&buf, img); err != nil {return err}b64 := base64.StdEncoding.EncodeToString(buf.Bytes())_, err := io.WriteString(w, ansi.ITerm2(iterm2.File{Inline: true,Content: []byte(b64),}))
// sixelImageCmd returns a tea.Cmd that generates and writes a sixel image// directly to the terminal, bypassing BubbleTea's renderer.func sixelImageCmd(state *tools.ClassifyState) tea.Cmd {
// inlineImageCmd returns a tea.Cmd that generates and writes an inline image// (sixel or iTerm2) directly to the terminal, bypassing BubbleTea's renderer.func inlineImageCmd(state *tools.ClassifyState, protocol utils.ImageProtocol) tea.Cmd {
## [2026-03-04] Add iTerm2 Inline Image Protocol Support**New feature:** Added `--iterm` flag for terminals supporting the iTerm2 Inline Image Protocol (WezTerm, iTerm2, VS Code terminal).- `utils/terminal_image.go` — Added `ProtocolITerm` enum value and `WriteITermImage()` using charm's `x/ansi/iterm2` package; PNG-encodes then base64-encodes for the iTerm2 escape sequence- `tools/calls_show_images.go` — Added `ITerm` field to `CallsShowImagesInput`, checked before `Sixel` in protocol selection- `tools/calls_classify.go` — Added `ITerm` field to `ClassifyConfig`- `cmd/calls.go` — Added `--iterm` flag to `show-images` subcommand- `cmd/calls_classify.go` — Added `--iterm` flag to `classify` subcommand- `tui/classify.go` — Renamed `sixelImageCmd` to `inlineImageCmd` with protocol parameter; changed conditionals from `== ProtocolSixel` to `!= ProtocolKitty` so both sixel and iTerm2 use the same inline rendering path- `utils/terminal_image_test.go` — Tests for `WriteITermImage`, `WriteImage` routing, and `ClearImages` no-op