Transcript: a finished Claude turn folds per run, as Claude desktop does (Codex unchanged)
Leo, 2026-11-01: "do we have the claude style tool call/interim chatter collapse restored yet the 7:11 nightly didnt' seem to have that nor the expanding tool calls doesn't push chats up yet"
Then, on how: "separate it per harness/model family. claude gets claude behaviour, codex gets codex".
Why Claude lost it. Replaying a real Claude Code turn through the pane's client and turnView showed the calls folding under Worked for but every interim note left outside it. #29802 turned the interim fold off for Claude chats (preserveAssistantText). Leo wants #29802 kept for Codex, so this keeps it and gives Claude its own behaviour.
What changes, keyed on the session family App.tsx already passes (snapshot.summary?.family):
- Codex / ChatGPT: unchanged. The whole turn's work and chatter fold under one Worked for, and the final answer stays below it.
- Claude, as Claude desktop draws it: no Worked for. Each run of calls folds into its own summary line ("Ran 5 commands, read 2 files"), along with the short notes inside that run, edit runs included. The line opens on a click anywhere on it (the existing run disclosure). A longer message between runs stays in place, and the final answer stays last.
- Both: a steer and the reply before it are never folded (#29740), and for Claude that reply never joins a run. Interim text has no per-reply copy row (
hasReplyActionsis off app-wide; the footer copies the turn).
Tests
transcript-claude-turn-groups.test.tsreplays one real Claude Code turn as acpmux recorded it (fixtures/claude-turn-groups.ndjson: 81 calls, 17 messages, every word and command replaced with neutral text of the same short or long kind). For Claude it checks: no Worked for, every run folded, no short note left between runs, the 3 long messages in place, the answer last. For Codex it checks that the same events still give one Worked for and the answer.- A steered turn for both families: for Claude,
u, run(b1+note), r1, run(b3), s1, run(b4+note), answer, summary. For Codex,u, Worked for, r1, s1, answer, summary(today's output, pinned). transcript-steer-continuous.test.tsx: the two #29802 Claude expectations move to the new behaviour, and the one-fold steer test runs as Codex.- Fleet run of the transcript and conversation suites at this tree: 1118 pass, 0 fail.
tscis clean apart fromtest/latency/probe.ts, which this PR doesn't touch.vp fmtandvp lintare clean.
Risk: transcript shaping only (turns.ts shapeTurn and mergeShortNotes), and every new branch is gated on the Claude family. No Swift, no persistence.
Agent session: agent session
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
A finished Claude chat turn now folds per run, as Claude desktop draws it, while Codex and ChatGPT keep today's behavior of folding the whole turn under one "Worked for".
Behavior
- Claude turns no longer draw a "Worked for" card; each run of calls folds into its own summary line that opens on a click, with the short notes inside that run (edit runs included).
- Longer messages stay in place between runs, and the final answer stays last.
- Codex/ChatGPT turns are unchanged.
- Both families keep a steer and its preceding reply in sight, and that reply never joins a run.
Tests
- Adds
transcript-claude-turn-groups.test.ts, which replays one real Claude Code turn (81 calls, 17 messages) and a steered turn for both families, checking the per-run fold for Claude and the single "Worked for" for Codex. - Updated the Claude expectations in
transcript-steer-continuous.test.tsxto the new per-run behavior. - Updated browser tests to open a Claude turn's run line where they used to open "Worked for"; the history paging tests now use Codex-family chats to keep reading the "Worked for" label.