Files
tty7/crates/tty7-cli
hhdebb 56238bf3bb fix(tabs): take the agent's status mark off the title it writes (#847)
Agents animate in the terminal title while they work, and they do not
agree on an alphabet: Claude Code cycles the quadrant circles and rests
on an asterisk, others step through the braille frames, some write
nothing at all. Rendered as they arrive, a column of tabs carries a mark
in front of some rows and not others, in three vocabularies — while the
row already says what the agent is doing, in one, with its status dot.

So the mark comes off, for everyone, with no setting. A switch would not
settle this: nobody opens settings to decide how a spinner is drawn, and
a default-off toggle buys two render paths to maintain forever in order
to answer a question that has one right answer per person and no way for
the app to know which.

**A known alphabet, not a shape.** The obvious rule — a leading character
that is non-ASCII and above some code point, followed by a space — matches
by shape, and `🔥 build`, or `📁 ~/repo` written by somebody's shell
integration, fits it exactly and quietly loses its first character with no
way to ask for it back and no clue as to what took it. Matching marks we
have actually seen costs the same and cannot do that: the braille block,
the four quadrant circles, and Claude Code's resting asterisk. When an
agent invents a mark that is not on the list, the failure is today's
behaviour — the mark stays — which is the safe direction to fail in, and
adding it is a line in the table.

Two things the rule insists on, both to keep it from reaching past what
it is for. A mark only counts with whitespace behind it, so `✳fixing` is
a word that starts with a character rather than a mark in front of one.
And a title that is *only* a mark keeps it: taking it would leave an empty
string, and an empty title is not a tab called nothing, it is a tab that
falls back to its number — less than the mark was saying.

It happens in `TabView::label`, which is where a title becomes a label, so
the strip, the sidebar, the switcher and the rename box's prefill all
agree without being told separately — and, because `label` reaches a
given name before it reaches the title, a tab somebody deliberately
called `✳ release` keeps what they called it. That ordering is the only
thing standing between a user's name and a rename behind their back, so
there is a test on it rather than a comment. Three existing tests carried
`✳` in their fixtures and now expect it gone. The one in `switcher.rs` was
asserting that a tab in another window is named the way a local one would
be, which is still exactly what it asserts; the one in `tty7-cli` is the
table getting this for free, since `tab_label` reads `label` and so
`tty7 ls` says what the tab strip says without either being told about the
other. The daemon's fixtures keep their marks on purpose: a title is stored
as the terminal wrote it, and only what turns one into a label takes
anything off.

This leaves the row with nothing moving in it, which is a real loss and is
answered separately: `AgentStatus::dot_rgb` returns three flat colours,
and a `Working` dot that breathes says the same thing in the vocabulary
the row already speaks.
2026-09-11 01:10:21 +08:00
..