Agent chat: Claude Code desktop's action rows under prompts and answers
Merged
TE
16d ago+939+939+012345678901234567890123456789-504-504-012345678901234567890123456789
Stacked on #22658. Merge that one first; until then this diff also shows #22658's commits. The commits that belong to this PR are the last two: 97f5886 (tests) and 1629c8c (fix).
Problem
The action rows under messages don't match Claude Code desktop.
- Under a prompt you get a lone bookmark icon on hover.
- Under an answer, "4:48 PM ⧉ ↻ ⌄ ⤴" sits at the column's far right, away from the text it belongs to.
Change
- Under a prompt (right-aligned under the bubble,
UserBubble.tsx): the row is the prompt's age ("1 hour ago", with the exact time on hover, fromIntl.RelativeTimeFormatin the pane's language), ✓✓ once delivered (not while pending), then Copy, Edit, Fork and Bookmark.- Edit and Fork show only where the chat can fork through the turn before the prompt. Fork forks there, as Edit's resend does.
- Bookmark is now one item in the row instead of a lone icon.
- Under an answer: the row moves to the left under the text, in Claude's order: time, Copy, Retry ⌄, Fork.
turnActionsPlacementnow defaults to left in the web view and in Swift (AgentPaneTunables.turnActionsPlacementdefault.left). Debug "right" keeps the old right edge.
- Visibility: the latest prompt's row and the last turn's row are always shown. Older ones show on hover or keyboard focus, as in Claude. VirtualTranscript marks
data-last-promptthe way it already marksdata-last-turn. - This overrides an earlier Leo decision for prompts. On 2026-10-13 Leo asked for one hover action per row (the
hover-actionsexperiment). This PR deliberately shows Claude's full row for prompts, per the GUI-push brief from 2026-10-20. Other rows (queued prompts, channel messages) are unchanged. - Default change (the defaults guard will ask for a call owner):
agentPane.debug.turnActionsPlacementgoes from right to left. - #22340 overlaps. It is ownerless and also left-aligns the answer footer; this PR covers that part, plus the prompt row and the visibility rule. #22340's spinner fix is not included here.
Screenshots (gallery agent-pane.transcript/conversation; before = #22658 head, after = this branch)
Under a prompt (the latest prompt, no hover)
| Before | After |
|---|---|
![]() | ![]() |
Under an answer
| Before | After |
|---|---|
![]() | ![]() |
The Claude Code desktop reference isn't attached yet. I found no public screenshot of these rows, and capturing Leo's own Claude window would publish his chats. It will go here once one is supplied.
Verification
- New
test/user-message-actions.test.tsx:- the row reads "1 hour ago · Delivered · Copy · Edit · Fork from here", and Fork forks through the turn before the prompt;
- a pending prompt has no ticks and no Fork;
- relative time in en and de, including a time ahead of the minute clock reading "now".
- Updated
edit-resend,turn-actions-placementandagent-pane-merge-restoreto the new defaults. These 11 tests and the conversation suites pass locally. - No local typecheck or Swift build on this Mac (a hook blocks
tsc, and Mac builds are CI-only). CI covers both. - Localization: one new key,
message.delivered, in all 21 locales. The relative time and absolute time come from Intl.
Agent session: cosmic-gray
🤖 Generated with Claude Code



