fix(terminal): let Claude use truecolor so its themed backgrounds render

Claude draws the user's own messages as a block of background color, and
inside a Codeman pane that block was invisible. tmux hands each pane
TERM=screen, which supports-color reads as 16 colors, and Claude's registry
entry deleted COLORTERM on top of that. Claude therefore quantized every RGB
color its theme asked for down to the basic palette, where rgb(55, 55, 55)
and every other dark background becomes ESC[40m, the terminal's own black.
Changing the color in a custom Claude theme moved nothing on screen.

Claude now exports COLORTERM=truecolor and unsets NO_COLOR, matching codex,
gemini, antigravity, pi, grok and omp. CLAUDECODE stays unset, because Claude
reads it as a signal that it is running nested inside itself. Both the tmux
session and the attach client read this one registry entry, so they cannot
disagree.

PR #3 introduced the unset in February, citing xterm.js#484 for the claim
that xterm.js mishandles truecolor. xterm.js closed that issue in April 2019,
Codeman now depends on @xterm/xterm 6, and TmuxManager already sets
terminal-overrides ",*:Tc" on its own tmux server, so 24-bit color reaches
the browser today for every CLI that asks for it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Grundberg
2026-09-13 12:15:28 +02:00
co-authored by Claude Opus 5
parent a017e9a8e0
commit 7767b16d4f
3 changed files with 33 additions and 3 deletions
@@ -0,0 +1,21 @@
---
"aicodeman": patch
---
fix(terminal): let Claude use truecolor so its themed backgrounds render
Claude draws the user's own messages as a block of background color, and inside a Codeman
pane that block was invisible. tmux hands each pane `TERM=screen`, which supports-color reads
as 16 colors, and the registry entry for Claude deleted `COLORTERM` on top of that. Claude
therefore quantized every RGB color its theme asked for down to the basic palette, where
`rgb(55, 55, 55)` and every other dark background becomes `ESC[40m` — the terminal's own
black. A custom Claude theme could change the color and nothing on screen moved.
Claude now exports `COLORTERM=truecolor` and unsets `NO_COLOR`, which is what codex, gemini,
antigravity, pi, grok and omp already do. `CLAUDECODE` stays unset, because Claude reads it
as a signal that it is running nested inside itself.
PR #3 introduced the `unset COLORTERM` in February, citing xterm.js#484 for the claim that
xterm.js mishandles truecolor. xterm.js closed that issue in April 2019, Codeman now depends
on `@xterm/xterm` 6, and `TmuxManager` sets `terminal-overrides ",*:Tc"` on its own tmux
server, so 24-bit color already reaches the browser for the six CLIs that ask for it.
File diff suppressed because one or more lines are too long
+11 -2
View File
@@ -174,8 +174,17 @@ const CLAUDE: CliEntry = {
legacyConfigAliases: { resumeId: 'resumeSessionId' }, legacyConfigAliases: { resumeId: 'resumeSessionId' },
}, },
env: { env: {
exports: [], // Claude joins the truecolor list with COLORTERM=truecolor and NO_COLOR unset.
unset: ['CLAUDECODE', 'COLORTERM'], // tmux hands the pane TERM=screen, which supports-color reads as 16 colors, and
// Claude then quantizes every RGB color its theme asks for down to that palette.
// Each dark background lands on ESC[40m, the terminal's own black, so the block
// Claude draws behind the user's own messages renders invisible. PR #3 unset
// COLORTERM here against xterm.js#484, which xterm.js had already closed in 2019,
// and Codeman now ships @xterm/xterm 6 and sets `terminal-overrides *:Tc` itself.
// CLAUDECODE stays unset, because Claude reads it as a signal that it is running
// nested inside itself.
exports: [{ name: 'COLORTERM', value: 'truecolor' }],
unset: ['CLAUDECODE', 'NO_COLOR'],
tmuxSetenvKeys: [], tmuxSetenvKeys: [],
dockerExecEnvNames: [], dockerExecEnvNames: [],
allowedPrefixes: ['CLAUDE_CODE_'], allowedPrefixes: ['CLAUDE_CODE_'],