Agent pane: inbox rows share the tool rows' icon column; a sender's mark is its real harness
Leo, 2026-11-01, on an inbox message line in the transcript: "i wanted this to be left aligned with the other tool calls". On the folded message group ("2 messages from 1 session") under a stack of tool rows: "let's just make this look better".
What changed
Every folded group of messages from other sessions now has a tool-row head. On base these groups are drawn by three components:
- the waiting group,
PendingMessagesCard("N messages from M sessions", the row Leo named); - a delivered inbox batch,
LaneNoticeBatch("N inbox threads"); - the legacy
InboxNoticeCardgroup.
Each had a bare chevron as its leading glyph, a 26px line, and words 1.5px right of the tool rows'. All three now share MessageGroupHead.tsx/.css, which is a tool row (.cv-tool):
- Icon: the sender's harness mark in the tool rows' icon column. With several senders it shows the messages glyph (
agent.chat). There is no leading chevron. - Size: the tool rows' 22px height, icon-to-word gap and type size.
- Text: the count reads as the summary, with the session names muted after it (hidden in a narrow pane, as before).
- Chevron: after the label. It shows and lights only on hover, focus or while the group is open, as an opened tool group's steps do.
- What opening shows is unchanged, and so are the existing toggle class names (
cv-pending__toggle,cv-lane-batch__toggle). A report batch ("N reviews ended") keeps its own head. The row estimate (model.ts) follows the 22px heads.
A sender's mark is its real harness, never a guess from its name. SenderMark (from IncomingMessageCard.tsx, shared by received lines, inbox lines and the group heads) takes the listed chat's harness, else the fromHarness acpmux bound. With neither, it draws the neutral agent glyph. Before, it fell back to a brand looked up from the sender's name, so an unlisted Codex lane called claude-… drew Claude's mark. The notice's fromHarness now reaches the delivered batch's received lines (laneReport.ts, laneNoticeBatches.ts). The root cause is that acpmux outbox sends bind no fromSessionId/fromHarness. That fix belongs in acpmux and is filed as #30247.
Single inbox line. On base its glyph center and title x already equal the tool rows' (#29124 folded #28796's alignment). The new browser test pins that, so it stays aligned among tool rows.
Not changed: tool rows themselves, the status rows between replies (#29124) and subagent rows (#29276). Each row's content, colours and glass are kept.
Gallery
agent-pane.inbox-notice has new versions. Each shows, among tool runs: a received line, an unlisted claude-… sender (neutral glyph), a delivered one-sender group, a delivered several-sender group, and the waiting "2 messages from 1 session".
icon-column: shipped. The chevron shows on hover.icon-column-look-chevron: the chevron always shown.icon-column-look-count: the count alone, with senders in the tooltip.icon-column-open: the several-sender group opened.
The existing look-lines-* and look-card-* versions stay beside them. I picked icon-column: it matches the tool rows exactly, and the always-on chevron repeats a control on every row.
Tests
webviews/test/inbox-row-icon-column.test.ts(Chromium, light and dark): every received line's and group head's glyph center and title x equal a tool row's (0.5px). Each group head's height, icon-to-word gap and type size equal a tool row's, and its chevron is hidden at rest and shown on hover.- Red with the base
PendingMessagesCard/LaneNoticeBatchat the same gallery: the delivered batches' glyph is at 32px vs the tool rows' 28, their title at 46.5px vs 42.5, and they are 26px tall vs 22. The waiting group's title is at 44px vs 42.5, its gap 8px vs 6.5, and it is 26px tall. - Green after: every group is glyph 28px, text 42.5px, gap 6.5px, 22px tall and 14px type, the same as the tool rows.
- Red with the base
webviews/test/inbox-sender-mark.test.tsx: a Claude sender (listed, or bound byfromHarness) gets the Claude mark. A listed Codex chat namedclaude-sr2-fleet-mesh-2gets OpenAI's. An unknownclaude-xsender gets the neutral glyph. A one-sender group gets its mark and a mixed group the messages glyph. Red on base (3 of 5 failed), green after.- Still green:
transcript-icon-column,incoming-sender-chip,lane-notice-card,incoming-message-disclosure-browser,agent-pane-suggested-tasks,InboxNoticeCard.test.tsx,check:piecesandtsc. All ran on the fleet throughcmux-ci test.
Spec: design/chat-transcript.md "One icon column". The inbox-row rule is added in a leo-workspace PR that cites this one.
Risk: low. The change is limited to the three message-group heads' markup and CSS, the row estimate for those heads, and the sender-mark fallback. A sender whose name alone used to pick a brand now shows the neutral glyph until acpmux binds its harness (#30247).
🤖 Generated with Claude Code
Agent session: agent session