[FEATURE] Support terminal tab color escape sequences from hooks and Bash tool (Windows Terminal)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
I built a Claude Code plugin that automatically sets the Windows Terminal tab color based on which repo the session is opened in — making it easy to visually distinguish multiple tiled Claude Code sessions at a glance. The plugin uses a SessionStart command hook that computes a color (via ClickUp doc matching or a deterministic hash of the repo name) and emits Windows Terminal's proprietary OSC escape sequences (\033]6;1;bg;red;brightness;N\007, etc.).
It doesn't work. Every approach to emit escape sequences from a plugin hook or the Bash tool is blocked by Claude Code's subprocess architecture. The sequences never reach the terminal.
What Was Tried
I systematically tested every available output path. None of them work:
| Strategy | Result |
|---|---|
| /dev/tty (original approach) | Device exists but cannot be opened: "No such device or address" |
| stdout | Captured by Claude Code as text; escape sequences appear as literals in tool output |
| stderr | Also captured by Claude Code |
| PowerShell [Console]::Write | Output is redirected/captured |
| Win32 WriteConsole on stdout handle | Returns False — stdout is a pipe, not a console |
| Win32 CreateFileW("CONOUT$") + WriteConsoleW | Handle opens successfully, WriteConsoleW returns True, but no visible effect — likely writes to ConPTY layer which doesn't forward proprietary OSC sequences to Windows Terminal |
Why This Can't Be a Plugin
The architecture makes it impossible for any subprocess to set tab colors:
Windows Terminal (VT parser — interprets tab color sequences here)
↕ ConPTY pseudoconsole
Claude Code (Node.js/Bun — owns the ConPTY endpoint)
↕ pipes (stdout/stderr captured)
Hook scripts / Bash tool subprocesses
- Tab title works because Claude Code sets it via
process.title, which on Windows calls theSetConsoleTitleWin32 API — a kernel call that propagates through ConPTY. - Tab color requires escape sequences in the VT stream that Windows Terminal parses. Only Claude Code's own process can write to that stream. Subprocess output is piped, not connected to the terminal.
This is the same root cause as #23757 (Bash tool doesn't pass escape sequences to parent TTY), but extends to command hooks as well — not just the Bash tool.
Proposed Solution
Add a mechanism for plugins/hooks to request terminal escape sequence passthrough. Some options:
Option A: Hook response field
Allow command hooks to return escape sequences that Claude Code emits on their behalf:
{
"terminalEscapeSequences": "\^[]6;1;bg;red;brightness;200\^G..."
}
Option B: Built-in tab color support
Add a tabColor setting (similar to statusLine) that accepts a script:
{
"tabColor": {
"type": "command",
"command": "~/.claude/tab-color.sh"
}
}
Claude Code would emit the appropriate escape sequences for the detected terminal emulator (Windows Terminal, iTerm2, etc.).
Option C: Escape sequence passthrough for hooks
Have Claude Code forward escape sequences from hook subprocess output to the terminal, rather than capturing them. This would also fix #23757 for hooks.
Alternative Solutions
- #17951 proposes a
terminalTitlesetting — atabColorequivalent could follow the same pattern - The
CONOUT$Win32 approach _might_ work if ConPTY forwarded proprietary OSC sequences, but it doesn't appear to
Priority
Medium - Would be very helpful
Feature Category
Configuration and settings
Use Case Example
I work across 4+ repos simultaneously in tiled Windows Terminal panes, all running Claude Code. Every tab looks identical. With automatic tab coloring based on the repo name, I can instantly identify which pane is which — the same way I'd color-code tabs manually, but automated via a plugin.
Additional Context
- Related: #23757 (Bash tool escape sequence passthrough), #17951 (terminal title configuration)
- The plugin (wt-theme) works correctly in every other respect — repo detection, color computation, ClickUp integration — it's only the final "emit the escape sequence" step that's blocked
- Windows Terminal, iTerm2, and other modern terminals all support tab color via OSC sequences; this isn't WT-specific
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗