Agent chat: every disclosure chevron sits right after its label, pointing down, the ChatGPT way
Leo, 2026-11-03: "this how chatgpt does their chevrons", next to ChatGPT's "Worked for 11s ā" and our "Background update" row, whose chevron was parked at the transcript's far right edge.
Every disclosure chevron in the agent chat transcript now sits right after its label's words, the way ChatGPT draws it. It is small and muted (a 12px glyph whose ink starts 5px after the last visible word), points down while closed and up while open, and is never right-aligned at the row's edge. A label cut with an ellipsis keeps the chevron right after the visible words: the chevron is the label's sibling and never shrinks, the label does. An opened group's inner steps still show theirs only on hover (2026-11-01), now after their labels. A row's status or duration ("Delivered", "2m 28s") moves after the chevron, to the line's end.
Rows changed:
- tool rows, tool groups and their inner steps, Worked for, and thought rows (one glyph size and gap; down/up instead of right/down)
- activity rows: "Scheduled check", "Background update" and other background-turn lines (
TranscriptActivityRow) - received messages (
IncomingMessageCardthroughDisclosureRow), the "Received N messages" and "N messages from M sessions" heads (MessageGroupHead) - message lines (
AgentMessageRow,SentMessageLine): the chevron comes before the hover Copy, and the delivery word ends the line - finished-subagent lines (
SubagentDoneLine): the mark follows the words (it opens a chat, so it still points right)
Everything is scoped under .acpmux-row, so Home's run ledger and the composer don't change.
Design spec: leo-workspace design/chat-transcript.md, rule "Always put a disclosure chevron right after its label's words" (teamleaderleo/leo-workspace#2611). It replaces the "chevron in column 4, every chevron on one x" line from #28860. References used (private): chatgpt/live/transcript-disclosure-chevron-chatgpt, cmux/live/transcript-background-update-row-far-right-chevron, cmux/live/transcript-tool-summary-row-chevron-alignment, claude/live/transcript-received-message-expanded.
Gallery: agent-pane.transcript-chevron-after-label has four variants of glyph size and gap: chatgpt (12px, 5px, selected and the default), tight (10px, 3px), spaced (12px, 8px) and large (14px, 5px), at 420, 760 and 900 widths.
Test
New: webviews/test/transcript-chevron-after-label.test.ts (Chromium). It runs over agent-pane.transcript-system-rows#leo-capture, agent-pane.received-messages (collapsed, level-1, level-2), agent-pane.transcript-spacing-table (shipped, peer-lines) and the new entry, at 760px and 420px. Every laid-out transcript chevron, hover-only ones included, must start within 8px after the last visible words before it on its line, and those words may not be a trailing status or duration. Every chevron's glyph must be wider than tall, so it points down or up and never right.
Command: cmux-ci test --setup playwright -- bash -c 'cd webviews && bun test test/transcript-chevron-after-label.test.ts'
- Base (feat-cmux-next plus the test commit only): 24 fail, 12 pass. Received lines and sent lines sat at the row's edge (gaps of 100 to 380px), "Scheduled check" was 570px past its words, and every chevron pointed right.
- Head: pass.
Existing tests updated to the new rule:
webviews/test/incoming-message-disclosure-browser.test.ts: "a delivered message and a waiting one draw the same line". It asserted both received lines' chevrons end on one x; it now asserts each chevron sits within 8px after its preview, and still that hover doesn't move it.webviews/src/agent-session/acpmux/conversation/RowGrammar.test.tsx: "the trailing column and chevron use the shared flex row contract" becomes "the chevron follows the words and the trailing column ends the line". It also read the first.cv-tool {block, which since #32805 holds only shimmer tokens.
Observed / Not run
Observed, on the fleet at head d3e886cdc76 (cmux-ci test --setup playwright): bun run check passes, and 215 of 215 tests pass across 20 files. Those files are the new test, agent-pane-transcript-chevron-column, incoming-message-disclosure-browser, transcript-system-rows, received-messages-columns-browser, browser/transcript-rhythm, transcript-row-pitch-browser, transcript-meta-columns-browser, subagent-list-chevron-column, agent-pane-background-tasks, agent-pane-background-turns, agent-message-card, subsession-row-opens-chat, lane-notice-card, inbox-sender-mark, received-messages-fold, incoming-minimal-collapse, queue-agent-message, subagent-tray and RowGrammar. I looked at the scene stills from that run: chevrons follow the words, and the cut received line keeps its chevron after the ellipsis at 420px.
Not run: the full webview suite (CI runs it), a native app build (no Swift changes) and a DEV build.
Follow-ups: #32822 (an opened lead thought step's chevron still floats at its row's end; the test skips that one case), #32847 (a cut received line's hover actions cover its chevron), #32848 (the ChevronColumn and RowGrammar gallery notes still describe the old column).
Overlap: #32798 (Background update rows without a chevron) also changes TranscriptActivityRow.tsx. Whichever lands second rebases.
Changelog
- Changed: Disclosure chevrons in the agent chat sit right after their label and point down, as in ChatGPT, instead of at the row's far edge.
Agent session: agent session
š¤ Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith Ā· Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Moves every disclosure chevron in the agent chat transcript to sit right after its label's words, pointing down while closed and up while open, the way ChatGPT draws them. Chevrons previously sat at the row's far right edge and pointed right.
Rows changed
- Tool rows, tool groups and inner steps, "Worked for", thought rows, and activity rows ("Scheduled check", "Background update") get the chevron right after the words.
- Received messages, their group heads, message lines, and finished-subagent lines follow the same rule.
- Status and duration ("Delivered", "2m 28s") move to the line's end; finished-subagent lines still point right since they open a chat.
- Scoped under
.acpmux-row, so Home's run ledger and the composer are unchanged.
Tests
- New Chromium test
transcript-chevron-after-label.test.tschecks every laid-out chevron starts within 8px of its words and points down or up, across gallery scenes at 760px and 420px. incoming-message-disclosure-browser.test.tsandRowGrammar.test.tsxupdated to the new chevron-after-words rule.