Support pets in VS Code integrated terminal with Sixel enabled
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
- Enable image support in VS Code settings:
"terminal.integrated.enableImages": true
- Open a VS Code integrated terminal connected to WSL.
- Run Codex CLI normally:
codex
- 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:
- Detect VS Code integrated terminal image support when Sixel/iTerm inline image support is available, or
- Provide an explicit config/env override for the image protocol so users do not need to spoof
TERMand unsetTERM_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.
6 Comments
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:
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.
This report lines up with the current terminal detection order:
TERM_PROGRAM=vscodeis treated as the explicit terminal identity beforeTERMis used as the capability fallback. That meansTERM=xterm-sixelcan be masked whenever VS Code setsTERM_PROGRAM=vscode.A targeted test case would be useful here:
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 codexworks in the same display surface: removingTERM_PROGRAMlets the capability fallback win.I ran the suggested matrix. Results:
So this seems to confirm the issue more precisely:
TERM=xterm-sixelis sufficient for pets/image support whenTERM_PROGRAMis unset.TERM=xterm-256colorremains unsupported as expected.TERM_PROGRAM=vscodeappears to mask theTERM=xterm-sixelcapability fallback.This suggests the problem is not WSL itself and not the display surface in general, but specifically the detection path when
TERM_PROGRAM=vscodeis present.FYI, the correct way to detect whether a terminal supports Sixel is by sending it a primary device attributes query:
\x1b[cThe 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
4in 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;22cwhen the image add-on is enabled (note the4in 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
I also tested the DA1 / primary device attributes response in the same VS Code integrated terminal with images enabled.
The terminal responds with:
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-sixelworkaround. That suggests Codex could potentially use the DA1 response as a more reliable capability signal here, instead of relying primarily onTERM_PROGRAM/TERMclassification.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:
sixel_supportedTERM_PROGRAM=vscodeand caches the result for pets image-protocol detection4Validation run locally on
codex-tui:just fmtjust test -p codex-tui terminal_probe-> 9 passedjust test -p codex-tui pets::image_protocol-> 18 passedjust fix -p codex-tuiThis matches the reporter confirmed VS Code DA1 response
\\x1b[?62;4;9;22cand avoids relying onTERM=xterm-sixelbeing visible afterTERM_PROGRAM=vscodeterminal classification.