Support pets in VS Code integrated terminal with Sixel enabled

Open 💬 6 comments Opened Jun 10, 2026 by Cx330-502

Summary

Codex CLI pets report that images are unavailable in the VS Code integrated terminal, even when VS Code image support is enabled and the terminal can display Sixel output. The same environment works when Codex is launched with TERM=xterm-sixel and TERM_PROGRAM unset, which suggests the display path works but Codex's terminal/image-protocol detection does not recognize this case.

Environment

  • Terminal UI: VS Code integrated terminal
  • Remote environment: VS Code Remote WSL
  • Shell: zsh
  • VS Code version / terminal program version observed: TERM_PROGRAM_VERSION=1.123.0
  • VS Code setting enabled:
"terminal.integrated.enableImages": true

Observed environment variables before workaround:

TERM=xterm-256color
TERM_PROGRAM=vscode
TERM_PROGRAM_VERSION=1.123.0

No Kitty / WezTerm / Windows Terminal / tmux / zellij related variables were present in the checked output.

Reproduction

  1. Enable image support in VS Code settings:
"terminal.integrated.enableImages": true
  1. Open a VS Code integrated terminal connected to WSL.
  2. Run Codex CLI normally:
codex
  1. Enable/use pets.

Actual behavior

Codex reports:

⚠ Pets aren’t available in this terminal. Terminal pets need image support, and this terminal environment doesn’t expose a supported image protocol. Try a terminal with Kitty graphics or Sixel support, or run Codex outside tmux.

Workaround

Launching Codex like this makes pets work in the same VS Code integrated terminal:

env -u TERM_PROGRAM TERM=xterm-sixel codex

This suggests that VS Code's terminal image support is functional, but Codex's automatic image protocol detection does not recognize this environment.

Expected behavior

Codex should either:

  1. Detect VS Code integrated terminal image support when Sixel/iTerm inline image support is available, or
  2. Provide an explicit config/env override for the image protocol so users do not need to spoof TERM and unset TERM_PROGRAM.

Notes

This may be a compatibility gap in the pets image protocol detection path: TERM_PROGRAM=vscode appears to take precedence over the fact that the terminal can handle image output when VS Code's image support is enabled.

View original on GitHub ↗

6 Comments

Cx330-502 · 1 month ago

Additional clarification: Codex CLI is the latest version in this setup, 0.139.x.

I also do not think WSL itself is the primary cause here. In this setup, WSL is mainly where the shell and Codex process run; the display surface is still the VS Code integrated terminal.

The relevant detection inputs appear to be:

TERM=xterm-256color
TERM_PROGRAM=vscode
TERM_PROGRAM_VERSION=1.123.0

So the issue seems more specifically about Codex's image-protocol detection for VS Code integrated terminal: VS Code can render the image path when forced through the Sixel branch, but Codex does not infer that from the normal VS Code terminal environment.

SylvainWinning · 1 month ago

This report lines up with the current terminal detection order: TERM_PROGRAM=vscode is treated as the explicit terminal identity before TERM is used as the capability fallback. That means TERM=xterm-sixel can be masked whenever VS Code sets TERM_PROGRAM=vscode.

A targeted test case would be useful here:

TERM_PROGRAM=vscode
TERM_PROGRAM_VERSION=1.123.0
TERM=xterm-sixel

Expected result for pets/image support would be either “VS Code + sixel capability is supported” or an explicit override path, rather than losing the Sixel capability because the terminal name was classified first.

This also explains why env -u TERM_PROGRAM TERM=xterm-sixel codex works in the same display surface: removing TERM_PROGRAM lets the capability fallback win.

Cx330-502 · 1 month ago

I ran the suggested matrix. Results:

# Fails: pets are still reported unavailable
env TERM_PROGRAM=vscode TERM_PROGRAM_VERSION=1.123.0 TERM=xterm-sixel codex

# Fails as expected: no Sixel capability exposed
env -u TERM_PROGRAM TERM_PROGRAM_VERSION=1.123.0 TERM=xterm-256color codex

# Works: pets render successfully
env -u TERM_PROGRAM TERM_PROGRAM_VERSION=1.123.0 TERM=xterm-sixel codex

So this seems to confirm the issue more precisely:

  • TERM=xterm-sixel is sufficient for pets/image support when TERM_PROGRAM is unset.
  • TERM=xterm-256color remains unsupported as expected.
  • TERM_PROGRAM=vscode appears to mask the TERM=xterm-sixel capability fallback.

This suggests the problem is not WSL itself and not the display surface in general, but specifically the detection path when TERM_PROGRAM=vscode is present.

j4james · 1 month ago

FYI, the correct way to detect whether a terminal supports Sixel is by sending it a primary device attributes query: \x1b[c

The terminal should then respond with an escape sequence indicating which capabilities it supports. This will obviously vary from one terminal to the next, but if you see the number 4 in the returned list of values, that indicates that the terminal supports Sixel.

I've not confirmed this in VS Code, but I believe it uses the xterm.js library, which typically responds with \x1b[?62;4;9;22c when the image add-on is enabled (note the 4 in that response).

And it looks like you might already be sending a device attribute query to the terminal - you're just not doing anything with the response. See here:
https://github.com/openai/codex/blob/f42780109c6646463f74eb8c8cf484437fedcca3/codex-rs/tui/src/terminal_probe.rs#L457

Cx330-502 · 1 month ago

I also tested the DA1 / primary device attributes response in the same VS Code integrated terminal with images enabled.

The terminal responds with:

b'\x1b[?62;4;9;22c'

This response includes capability 4, which indicates Sixel support.

So in this environment, the terminal is explicitly advertising Sixel capability through DA1, not only through the TERM=xterm-sixel workaround. That suggests Codex could potentially use the DA1 response as a more reliable capability signal here, instead of relying primarily on TERM_PROGRAM / TERM classification.

SylvainWinning · 1 month ago

I prepared a small tested patch for this, published as a Gist instead of opening an unsolicited PR because external code contributions are invitation-only for this repo:

https://gist.github.com/SylvainWinning/878671398ade4869f6fc1f177a52f439

What it changes:

  • extends the existing startup terminal probe to retain DA1 / primary device attributes as sixel_supported
  • makes the DA1 query independent from the keyboard-enhancement probe, so VS Code can still be queried when keyboard enhancement is skipped
  • queries DA1 for TERM_PROGRAM=vscode and caches the result for pets image-protocol detection
  • enables Sixel pets for VS Code only when DA1 advertises capability 4
  • keeps tmux/Zellij safety checks ahead of the DA1 signal

Validation run locally on codex-tui:

  • just fmt
  • just test -p codex-tui terminal_probe -> 9 passed
  • just test -p codex-tui pets::image_protocol -> 18 passed
  • just fix -p codex-tui

This matches the reporter confirmed VS Code DA1 response \\x1b[?62;4;9;22c and avoids relying on TERM=xterm-sixel being visible after TERM_PROGRAM=vscode terminal classification.