How to make pi agent background colors work in tmux

How to make pi agent background colors work in tmux
この記事は約10分で読めます。
スポンサーリンク

You should run AI agents through tmux.

Many people isolate their work environment for security and reach it over SSH when using agents like Claude Code or pi agent. If that is how you work, always go through tmux. Two reasons:

  • Your work survives a dropped connection. If the network dies, the agent keeps running, and reconnecting puts you back on the same screen
  • You can resume from anywhere. Start a task at the office and pick it up from home or your phone

Running AI agents through tmux makes a drastic difference to usability and stress.

But there is one catch. Inside tmux, pi agent’s tool-call blocks lose their background color and turn gray. tmux converts pi’s truecolor output to 256 colors, and the conversion lands on a different color than pi intended. This post traces the cause with actual measurements and shows the one setting that keeps the colors working inside tmux.

Key Takeaways

  • tmux sets COLORTERM=truecolor for processes inside a pane, so pi switches to 24-bit color output
  • tmux has no RGB capability in terminal-features, so it converts that 24-bit color to 256 colors
  • pi and tmux round the same color #283228 differently: pi picks green (index 22), tmux picks gray (index 236)
  • Setting export PI_TRUE_COLOR=0 makes pi emit 256-color codes, which tmux passes through unchanged

The symptom: only inside tmux does the background go gray

The same pi agent looks different outside and inside tmux. I sampled the background pixels directly from screenshots.

Where it runsBlock backgroundMeasured RGB
Outside tmuxgreenrgb(1,94,0)
Inside tmuxgrayrgb(48,48,48)

Text and status bars render correctly. Only the background color changes, so this is not a total loss of color.

The cause: tmux converts truecolor to 256 colors

pi’s dark theme defines the tool-call success background as #283228, which is rgb(40,50,40). The result depends on which side performs the 256-color conversion.

Converted byResultActual color
pi (outside tmux)256-color index 22rgb(0,95,0) green
tmux (inside tmux)256-color index 236rgb(48,48,48) gray

For the same #283228, pi picks green and tmux picks gray. The two use different rounding rules.

The next question is why pi draws in truecolor at all inside tmux. The environment variables explain it.

# outside tmux
echo "TERM=$TERM COLORTERM=${COLORTERM:-unset}"

Output:

TERM=xterm-256color COLORTERM=unset
# inside tmux
echo "TERM=$TERM COLORTERM=$COLORTERM"

Output:

TERM=screen-256color COLORTERM=truecolor

tmux sets COLORTERM=truecolor for the shell inside a pane. pi reads that, decides truecolor is available, and draws the background with ESC[48;2;40;50;40m, a 24-bit code. tmux cannot store 24-bit color, so it converts the value to 256 colors before writing to the outer terminal. That conversion is where the two rounding rules diverge.

Verifying that tmux really converts it

Rather than guess, I measured what the outer terminal receives after the sequence passes through tmux.

input : ESC[48;2;40;50;40m   →  output: ESC[48;5;236m      # converted to gray
input : ESC[48;5;22m         →  output: ESC[48;5;22m       # passed through unchanged

If pi sends 256-color codes, tmux changes nothing. Only 24-bit codes get converted.

The reason tmux will not preserve 24-bit color is in terminal-features.

tmux show-options -g terminal-features

Output:

terminal-features[0] xterm*:clipboard:ccolour:cstyle:focus:title
terminal-features[1] screen*:title
terminal-features[2] rxvt*:ignorefkeys

There is no RGB entry. tmux checks terminfo to decide whether the attached terminal supports truecolor. Neither xterm-256color nor tmux-256color defines RGB, so tmux leaves it disabled.

infocmp -x xterm-256color | grep -iE '\bRGB\b|\bTc\b'

Output:

(no match)

Fix: set PI_TRUE_COLOR=0

pi lets you override truecolor detection with an environment variable. Add one line to ~/.bashrc.

export PI_TRUE_COLOR=0

pi now emits ESC[48;5;22m, and tmux passes it through unchanged. The block renders in the same green you see outside tmux.

You need a new shell for this to take effect. An already running pi process keeps the old value.

source ~/.bashrc
pi

Checking the output afterwards confirms pi switched to 256-color codes.

with PI_TRUE_COLOR=0: pi emits ESC[48;5;22m  → after tmux: still ESC[48;5;22m

Alternative: let tmux pass truecolor through

You can also tell tmux that the attached terminal supports RGB.

# ~/.tmux.conf (or ~/.byobu/.tmux.conf with byobu)
set -ag terminal-features "xterm*:RGB"

I measured this and confirmed 24-bit codes survive the trip.

input : ESC[48;2;40;50;40m   →  output: ESC[48;2;40;50;40m   # passed through

This only works if the outer terminal really supports truecolor. Sending 24-bit color to a terminal that does not can break the display. If you want a fix that does not depend on terminal capabilities, PI_TRUE_COLOR=0 is the safer choice.

The other background colors were grayed out for the same reason

The tool-call success block stood out only because its color is green-tinted. Every other background is also converted to gray inside tmux, but the originals are neutral gray, so nobody notices.

Theme colorOriginalpi conversiontmux conversion
toolSuccessBg#28322822 rgb(0,95,0)236 rgb(48,48,48)
userMessageBg#34354159 rgb(95,95,95)237 rgb(58,58,58)
toolErrorBg#3c282852 rgb(95,0,0)236 rgb(48,48,48)

Summary

  • Inside tmux, COLORTERM=truecolor makes pi draw backgrounds with 24-bit codes
  • tmux has no RGB capability in terminal-features, so it converts those codes to 256 colors
  • pi and tmux round the same color differently, so #283228 becomes gray instead of green
  • export PI_TRUE_COLOR=0 pins pi to 256 colors, which tmux passes through unchanged
  • Enabling RGB in tmux also works, but only if the outer terminal supports truecolor

コメント

タイトルとURLをコピーしました