Observed: In the screenshot below, the "Create hyperframes movi..." row shows a small "·" glyph inline before the title text, and a separate spinner ring at the end of the row — both indicating the same thing (Claude is actively working). The "binary-preview" row above it, which is idle, shows only a "✳" inline before its title and no trailing spinner.
Root cause: These are two independent systems that happen to read the same underlying signal:
- The inline glyph (
✳ = idle, a Braille spinner frame = busy) is Claude Code's own raw OSC terminal-title convention, passed through verbatim by termic (TerminalPane.tsx onTitleChange, deliberately not stripped).
- The trailing badge (spinner ring / done dot / attention bell) is termic's own
TabBadge, driven by classifyTitle() parsing that same leading glyph, then rendered at the opposite end of the row (Sidebar.tsx:1490-1495).
Because 2 is derived from 1, the two nearly always agree and just double up the signal, redundantly and inconsistently styled (one is raw CLI text, the other a designed icon).
Why not just truncate the leading glyph: already tried and reverted per the comment in TerminalPane.tsx:860-865 — stripping it removes the only working/idle signal for users who have workingIndicator (the trailing badge) turned off, which is the default.
Options:
- Truncate the inline glyph only when the trailing badge is active (i.e., when
workingIndicator is on). That subset of users already gets the signal from the badge, so the raw glyph becomes pure noise for them; users with the badge off keep seeing it as their only signal.
- Keep the inline glyph, but explain it — tooltip or legend on hover for
tab.cli === "claude" titles, so it reads as an intentional indicator instead of a stray character.
- Truncate the inline glyph unconditionally and flip
workingIndicator to on by default, making the trailing badge the single source of truth. Reopens the reason the badge is opt-in today: it can misfire on noisy TUI redraws.
Recommend option 1: it's the only one that removes the redundancy without regressing the off-by-default case or re-triggering the noisy-redraw problem that made the badge opt-in.
@simion, WDYT?
Observed: In the screenshot below, the "Create hyperframes movi..." row shows a small "·" glyph inline before the title text, and a separate spinner ring at the end of the row — both indicating the same thing (Claude is actively working). The "binary-preview" row above it, which is idle, shows only a "✳" inline before its title and no trailing spinner.
Root cause: These are two independent systems that happen to read the same underlying signal:
✳= idle, a Braille spinner frame = busy) is Claude Code's own raw OSC terminal-title convention, passed through verbatim by termic (TerminalPane.tsxonTitleChange, deliberately not stripped).TabBadge, driven byclassifyTitle()parsing that same leading glyph, then rendered at the opposite end of the row (Sidebar.tsx:1490-1495).Because 2 is derived from 1, the two nearly always agree and just double up the signal, redundantly and inconsistently styled (one is raw CLI text, the other a designed icon).
Why not just truncate the leading glyph: already tried and reverted per the comment in
TerminalPane.tsx:860-865— stripping it removes the only working/idle signal for users who haveworkingIndicator(the trailing badge) turned off, which is the default.Options:
workingIndicatoris on). That subset of users already gets the signal from the badge, so the raw glyph becomes pure noise for them; users with the badge off keep seeing it as their only signal.tab.cli === "claude"titles, so it reads as an intentional indicator instead of a stray character.workingIndicatorto on by default, making the trailing badge the single source of truth. Reopens the reason the badge is opt-in today: it can misfire on noisy TUI redraws.Recommend option 1: it's the only one that removes the redundancy without regressing the off-by-default case or re-triggering the noisy-redraw problem that made the badge opt-in.
@simion, WDYT?