[FEATURE] OSC title: distinct idle marker when idle but background shell(s) still running
Summary
Claude Code already emits a state-dependent marker glyph as the prefix of the OSC terminal title — a braille spinner (⠂, ⠄, …, U+2800–U+28FF) while working and an asterisk-family idle marker (✳/✱) once the turn ends and the prompt is ready. This is great for telling "working" from "idle" at a glance across terminal tabs.
The gap: the idle marker is identical whether or not background shells are still running. When a turn ends but a run_in_background Bash command (or background agent) is still executing — the case the footer already labels · N shell — the tab still shows the plain idle marker. There's no way to distinguish "fully idle" from "idle, but a shell is still working."
Request: emit a distinct OSC-title marker for the "idle prompt with ≥1 background shell/agent still running" state.
Current behavior (observed, Claude Code 2.1.181)
- The binary writes the tab title via OSC sequences (
ESC ] 0 ;/ESC ] 2 ;) and ships the marker glyphs. - Working → braille spinner prefix; turn complete → asterisk idle marker prefix (see #68643, which documents this scheme:
working = ^[\x{2800}-\x{28FF}],idle = ^\x{2733}). - The footer shows
· 1 shellexactly when a background shell is running — so Claude Code already knows this state internally; it just isn't reflected in the OSC title.
Problem
When juggling several tabs, you can't tell which idle sessions are truly done versus still chewing on a background task without focusing each tab to read the footer. The information exists internally but isn't surfaced where it's most useful — the tab title.
Why this can't be solved in user-land today
I tried to do this myself with a Stop/UserPromptSubmit hook writing the OSC title, and it's blocked on two independent fronts:
- The marker is owned by Claude Code's title writer, which re-emits the title on state changes and overwrites whatever a hook writes — so a hook can't reliably substitute its own glyph.
- Background-shell state isn't available to a hook anyway. Per #62516,
run_in_backgroundtasks are reparented to PID 1 (so process-tree walking misses them) and are tracked in-memory with no filesystem status file — a shell hook has no reliable way to detect "a background shell is running." Only Claude Code itself has this state.
So this realistically has to be done by Claude Code's own OSC-title writer, which already has both the title-writing path and the background-task count in hand.
Proposal
Add a third idle sub-state to the existing OSC-title marker scheme:
| State | Today's marker | Proposed |
|-------|----------------|----------|
| Working | braille spinner (⠂…) | unchanged |
| Idle, no background work | ✳/✱ | unchanged |
| Idle, ≥1 background shell/agent running | ✳/✱ (same as idle) | distinct glyph |
Minimal version: pick any distinct glyph for the new sub-state (a pipe |, a different asterisk, etc. — leave the exact glyph to the team, as suggested in #21894). Even a fixed, non-configurable distinct marker fully solves the use case.
Nice-to-have: let the marker set be configurable, which would dovetail with the existing tab-title customization/disable requests (#62384, #64952, #60621, #7229). That would also help workspace managers that parse the OSC title for state (the consumer in #68643).
Related issues
- #68643 — OSC title not emitting idle marker after turn ends (closed/completed): documents the existing braille-vs-asterisk state→glyph scheme this builds on.
- #62516 — Expose background task state to SessionEnd hooks (open): same underlying state; explains why hooks can't see background shells (PID-1 reparenting, in-memory only). This request is the "surface it in the title" sibling.
- #21894 — Visual prompt state indicators (working/waiting/done/error) (open): the broader prompt-indicator concept; this issue is the narrow, tab-title-specific, background-shell-running slice of it.
- #62384 / #64952 / #60621 / #7229 — terminal-title customize/disable requests, relevant if the marker is made configurable.
Environment
- Claude Code: 2.1.181
- OS: Linux
- Any terminal that renders the OSC title in its tab/window
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗