Repository navigation
Agent transcript: one-line activity rows share one pitch and columns - #29965
Conversation
…nd columns A browser geometry test over the real transcript (VirtualTranscript): tool rows, a sent message, received lines, inbox notice lines, a background task line, a report batch head and the waiting messages' head must share one line height, one top-to-top pitch, one icon x and one text x within 0.5px. Red on base: the rows pitch differently by kind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-013e821a578a652a3caa
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-013e821a578a652a3caa
Tool rows, sent messages, received and inbox lines, a task's notice line, a report batch's head and the waiting group's head now all draw on the tool rows' 22px line in a one-call tool run's frame (2px over, 4px under) and join the step rows beside them, so consecutive one-line rows of any kind sit one 22px line apart. Before, a received line pitched 38px, a fold head 38px and a tool row 28px after it, so the column read unevenly. - model.ts: isLineRow names those rows; the estimator uses the same frame (LINE_ROW = 2 + 22 + 4) and a grouped member's line alone. - App.tsx: marks them acpmux-row--line and joins them as step rows. - CSS: --cv-message-line is the tool row height; received, pending and lane-batch lines drop their own margins; the sent message toggle is 22px; the waiting group's chevron and words move onto the shared icon and text columns; a notice's tool line takes its user row's width (it sat at the row's right end). Leo, 2026-11-01: "doesn't make sense for these to be spaced differently". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-013e821a578a652a3caa
…e 24px Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-013e821a578a652a3caa
There was a problem hiding this comment.
3 issues found across 9 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="webviews/src/agent-session/acpmux/conversation/AgentMessageRow.css">
<violation number="1" location="webviews/src/agent-session/acpmux/conversation/AgentMessageRow.css:117">
P2: This custom property is not defined in the acpmux production entry, so the declaration is dropped and message toggles lose their row height there. Add a local fallback (or load `conversation.css` in that entry) so the shared frame remains valid wherever this component is rendered.</violation>
</file>
<file name="webviews/src/agent-session/acpmux/model.ts">
<violation number="1" location="webviews/src/agent-session/acpmux/model.ts:1541">
P2: The estimator always reserves the full 28px line frame, but the new step-row classes remove that frame's padding when a line is adjacent to another step. Pass the previous/next step adjacency into the estimator and subtract the corresponding top/bottom padding so initial layout matches the rendered row.</violation>
</file>
<file name="webviews/src/agent-session/acpmux/conversation/conversation.css">
<violation number="1" location="webviews/src/agent-session/acpmux/conversation/conversation.css:63">
P3: The new message-line alias follows the tight and roomy tool-spacing variants, but the row estimator still uses fixed 22px/4px constants. Keep the message line and frame fixed for gallery variants, or make the estimator consume the same configured spacing values.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
| height: 26px; | ||
| /* The tool rows' line, so a message row is as tall as the rows around it (Leo, 2026-11-01: | ||
| "doesn't make sense for these to be spaced differently"). */ | ||
| height: var(--cv-tool-row-height); |
There was a problem hiding this comment.
P2: This custom property is not defined in the acpmux production entry, so the declaration is dropped and message toggles lose their row height there. Add a local fallback (or load conversation.css in that entry) so the shared frame remains valid wherever this component is rendered.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/conversation/AgentMessageRow.css, line 117:
<comment>This custom property is not defined in the acpmux production entry, so the declaration is dropped and message toggles lose their row height there. Add a local fallback (or load `conversation.css` in that entry) so the shared frame remains valid wherever this component is rendered.</comment>
<file context>
@@ -112,7 +112,9 @@ button.cv-agentmsg__name:focus-visible {
- height: 26px;
+ /* The tool rows' line, so a message row is as tall as the rows around it (Leo, 2026-11-01:
+ "doesn't make sense for these to be spaced differently"). */
+ height: var(--cv-tool-row-height);
cursor: default;
border-radius: 4px;
</file context>
| height: var(--cv-tool-row-height); | |
| height: var(--cv-tool-row-height, 22px); |
|
Review (codex gpt-6.1-sol xhigh, router-review): BLOCK at 3bd8fe3 BLOCK at 3bd8fe3 Visual verdict: no images; Leo tries the build
|
Resolves #29124 (status rows centred between replies, shared icon column): App.tsx keeps its status edge class beside acpmux-row--line; the waiting group's head takes base's slot geometry and keeps no margins of its own; a one-line row's padding yields to the status edges (same specificity, later) and statusDelta counts a line row's 4px run gap as a tool run's. Also, from review: a message this agent sent another one (SendMessage, acpmux send, a sub-session's send_message) estimates as one 22px tool line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-013e821a578a652a3caa
… text column Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-013e821a578a652a3caa
|
Review (codex gpt-6.1-sol xhigh, router-review): BLOCK at f71b584 BLOCK at f71b584 Visual verdict: no images; Leo tries the build
|
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Gallery before/after for
States
Pick other states with a red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base c7c9a16; does not block Shipped in:
|
|
Found 13 test failures on Blacksmith runners: Failures
...and 3 more test failures. View all on Blacksmith
|
Review at f71b584: a received line's buttons kept DisclosureRow's 26px floor inside the 22px line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-013e821a578a652a3caa
DisclosureRow.css gives .cv-disclosure__toggle and .cv-disclosure__open a sub-session row's 26px min-height; inside .cv-received both now take the line's height with no floor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-013e821a578a652a3caa
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="webviews/test/transcript-row-pitch-browser.test.ts">
<violation number="1" location="webviews/test/transcript-row-pitch-browser.test.ts:177">
P2: This assertion misses overflow from nested row parts: it measures the sentence/actions wrapper, not the controls inside it. Inspect all descendant elements so a 24px button or similar child cannot regress the one-line invariant without failing this test.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
| // How far the line's own parts (its buttons, its sentence) stand out of its box. | ||
| const overhang = Math.max( | ||
| 0, | ||
| ...[...el.children].map((child) => { |
There was a problem hiding this comment.
P2: This assertion misses overflow from nested row parts: it measures the sentence/actions wrapper, not the controls inside it. Inspect all descendant elements so a 24px button or similar child cannot regress the one-line invariant without failing this test.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/test/transcript-row-pitch-browser.test.ts, line 177:
<comment>This assertion misses overflow from nested row parts: it measures the sentence/actions wrapper, not the controls inside it. Inspect all descendant elements so a 24px button or similar child cannot regress the one-line invariant without failing this test.</comment>
<file context>
@@ -171,11 +171,20 @@ await requireBrowserLane("transcript-row-pitch-browser.test.ts", async () => {
+ // How far the line's own parts (its buttons, its sentence) stand out of its box.
+ const overhang = Math.max(
+ 0,
+ ...[...el.children].map((child) => {
+ const part = child.getBoundingClientRect();
+ return part.height === 0 ? 0 : Math.max(box.top - part.top, part.bottom - box.bottom);
</file context>
| ...[...el.children].map((child) => { | |
| ...[...el.querySelectorAll<HTMLElement>("*")].map((child) => { |
|
Review (codex, router-review): SHIP at 00c42fe Reviewer: codex gpt-6-astra high, fast tier. Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward. SHIP at 00c42fe Visual verdict: no images; Leo tries the build No correctness findings from static review. Tests could not run because Bun and webview dependencies are unavailable.
Follow-ups:
|
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Review (subagent opus-5.5 medium): SHIP at 9979dbb router-review could not run at this head (the host's GraphQL quota was spent). The delta since the Codex SHIP at 0296ead is a base merge and one test assertion (a received line is 22px in agent-pane-suggested-tasks, which the webview base-check named). Independent read of the whole diff: cascade against styles.css user-row padding, last-turn, the status-edge rules and step joins; estimates against CSS for closed and opened received messages, notices, inbox notices (grouped, ungrouped, card), pending and lane-batch members, lastTurn and statusDelta. No blocking findings. Follow-ups (filed as one issue):
CI at this head: |
…ript-row-pitch # Conflicts: # webviews/src/agent-session/acpmux/App.tsx
|
Review (subagent opus-5.5 medium): SHIP at 501cbb2 This head only merges base (c7c9a16) into 9979dbb, which already had a SHIP.
Follow-ups:
|
…30791) into transcript rhythm Conflict resolution: - #29965 one-line rows: lineRow() = the grid tool row (28, scaled) with a zero frame, same 28 at 100%; --cv-message-line follows --cv-tool-row-height; --cv-tool-run-top-gap 0 on the grid - Rows keep the grid's stack-owned spacing - userMetaHeight keeps the grid's zero-height action row - #30791 revert drops .cv-repo-recovery - Design token baseline re-ratcheted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…otice lines span the row After the base merge: - A legacy activity line keeps the footer slot's one line. Base #30561 measured it as text. - Session-start and standalone notes estimate one 28 grid row instead of 37. Review at 66ddd56. - Restore #29965's .acpmux-row--line .cv-tools rule, so a notice's tool line keeps the icon and text columns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#29965's transcript-row-pitch-browser test caught the report batch head ("N reviews ended") 4px right of the icon column: raising LaneNoticeBatch.css's toggle selectors with :not() let its inset beat the one-line row rules. Keep base's selectors and zero the inset and hover plate on the tool-row head alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ark is its real harness (#30652) * Agent pane: inbox rows share the tool rows' icon column; a sender's mark is its real harness Leo, 2026-11-01: "i wanted this to be left aligned with the other tool calls", and on the folded group: "let's just make this look better". - A folded inbox group ("N messages from M sessions") is now a tool row: the sender's harness mark (several senders: the messages glyph) in the tool rows' icon column, their 22px height, gap and type, the count as the summary with the senders muted, and the chevron after the label shown only on hover, focus or while open. Opened, its threads start at the tool rows' text x. - A sender's mark comes from the listed chat's harness, else the fromHarness acpmux bound, else the neutral agent glyph. It is never guessed from the sender's name: a Codex lane called claude-* drew Claude's mark (cmux#30247). Inbox threads read fromHarness. - Gallery: agent-pane.inbox-notice icon-column (shipped) and two head versions (group-chevron, group-count) beside lines and card. - Tests: inbox-row-icon-column.test.ts (Chromium, light and dark) and inbox-sender-mark.test.tsx. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-06adbde0c46733e12100 * Waiting and delivered message groups: a tool-row head Leo, 2026-11-01, on "2 messages from 1 session": "let's just make this look better". On the new base the groups he sees are the waiting group (PendingMessagesCard) and a delivered inbox batch (LaneNoticeBatch), not the legacy InboxNoticeCard group. All three now share MessageGroupHead: a tool row with the sender's harness mark (several senders: the messages glyph) in the icon column, the count as the summary, the senders muted, and the chevron after them, shown on hover. acpmux's fromHarness now reaches the batch's received lines. The row estimate follows the 22px head. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Message group head: keep the report batch's head on base's selectors #29965's transcript-row-pitch-browser test caught the report batch head ("N reviews ended") 4px right of the icon column: raising LaneNoticeBatch.css's toggle selectors with :not() let its inset beat the one-line row rules. Keep base's selectors and zero the inset and hover plate on the tool-row head alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Add shared layout grid tokens and validate their CSS and Swift copies Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * test(webviews): measure gallery grid lines from runtime tokens Add warning-level surface scenes, baseline/cap-height text measurements, named optical offsets, and recoverable per-line JSON evidence. Missing mounts and unknown selector coverage fail. Browser measurements and full checks are delegated to the parent fleet run; scoped lint, formatting, browser lane discovery, gallery IDs, and TypeScript syntax checked locally. Agent-Session: https://cmux.com/deeplink/agent?id=aid-b562541d72b66523f655 * Add transcript rhythm tokens and role-based grid measurement selectors Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * Keep selector fallback valid when the marked surface is the target itself Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * test(webviews): align grid scenes with shared surface roles Use stable surface IDs across variants and ink-only role hints with selector fallbacks. Add existing plus, mode, project and tray scenes plus a 31-row expanded subagent fixture. Retain transcript action coverage and leave toolgroup/rhythm implementation to its owner. Scoped lint/format and gallery entry discovery passed; browser measurement remains delegated to parent fleet integration. Agent-Session: https://cmux.com/deeplink/agent?id=aid-b562541d72b66523f655 * Identify repeated grid scenes by their measured root Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * Add shared transcript between-turn gap token Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * Run layout grid validation in NEXT checks and scale the base unit Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * Run layout grid drift check in the webviews warning branch Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * Keep sidebar trailing marks fixed across densities Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * test(chat): reproduce transcript column and block rhythm drift Agent-Session: https://cmux.com/deeplink/agent?id=aid-539c2a9f2e69febb66f6 * Add canonical composer foot gap token and measure against it Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * fix(chat): centralize virtual transcript block rhythm and columns Agent-Session: https://cmux.com/deeplink/agent?id=aid-539c2a9f2e69febb66f6 * Measure visible placeholder ink and emit each grid scene baseline Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * test(webviews): correct card grid fixture selectors Read card fixture JSX: command permission body is its scope line; inline summary omits popover fold and close controls; glance inspector sections have distinct body labels and only Context/Connectors supply header icons. Scope absence diagnostics by fixture/section without changing coverageFailure assertions. Scoped format/lint, gallery discovery, and diff checks passed. Browser validation remains with parent fleet run. Agent-Session: https://cmux.com/deeplink/agent?id=aid-b562541d72b66523f655 * test(chat): cover turn boundaries, opened cards and count geometry Agent-Session: https://cmux.com/deeplink/agent?id=aid-539c2a9f2e69febb66f6 * Set composer foot gap token to four points Agent-Session: https://cmux.com/deeplink/agent?id=aid-2bd8d22f53cb987a8eea * test(chat): rhythm hover scene and cards fixture covers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * fix(chat): gap precedence, waiting indicator, foot gap, count spacing and trailing chevrons One gap per adjacent pair, most specific first (waiting rule, composer, turn, block). The waiting indicator takes the block gap on both sides; the composer gap is the block gap after a message so its action row fits. The quiet row sits var(--grid-gap-foot) under the composer box. Count summaries part verb and count with one space and tabular figures. The user action row is positioned again inside .cv-user__body. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * fix(chat): the last turn footer keeps the block gap to the composer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * fix(chat): received message chevron ends on col-right like every tool row Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * test(chat): rhythm and estimate checks on base's received, steps and status rows Base now leads a received message with its sender, reads a count summary whole, draws no per-reply action row and centres status rows with its own gaps. The rhythm test measures those rows where base draws them; the estimate tests expect the grid's 28 rows with no status room. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(chat): carets sit inline after their label (#28018), not on col-right Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): a disclosure caret stays inline after its words (#28018) Review BLOCK at e0c3d9b: the rotor margin-inline-start auto pushed a sub-session caret to the line end. The rhythm test now checks each caret sits at most one grid gap after its words. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): transcript gaps scale with Interface Size in the virtual placement Review BLOCK at 18cf6d8: the CSS grid tokens multiply by --cmux-interface-scale, but layoutConversation and placeRows placed the gaps unscaled, so at 125% the footer action row laid in a 24 gap overlapped the next row. The gaps (and the tail gap) now take the same factor, read once per pass; kept rows reuse their gaps only at the same scale. The rhythm test adds a 1.25x case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): measured placement reads the live Interface Size, kept rows only at their own Review BLOCK at 1691838: placeRows copied a kept prefix placed at another scale and stamped the estimate's scale. It now reads gridScale() itself, keeps a prefix only at the same scale, and a unit test covers 100% to 125% with kept rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(chat): hold transcript-spacing to the grid action row (28 control laid in the gap) Base #30297 measured a 24px meta row 4px under the bubble. design/grid.md lays a message's action row in the gap with 28 controls and no layout height, so the test now measures that. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): row estimates scale grid lengths with the Interface Size Review BLOCK at b1de39a: gaps scaled with --cmux-interface-scale but the estimates still used raw grid metrics (action row 28, tool row, page edge), so at 125% rows drawn 35 were estimated 28. layoutConversation now sets the scale once per pass and those lengths multiply by it; the page edge reads gridScale(). A unit test covers 100% to 125%. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): scale the remaining grid-derived estimates (bubble, block and list gaps) Review BLOCK at 5d643f0: the Markdown block gap, tool-run gaps between activity items, and the prompt bubble's padding and sides were still raw grid lengths, and listHeight left out the inner gap .cv-list now draws between items. All of them multiply by the per-pass Interface Size now, and the unit test also covers a two-call run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): folded run estimates include the block gap between children Review BLOCK at 84dc1b7: foldedRunSteps and foldedGroupHeight summed child heights without the --grid-gap-block that .cv-tools, .cv-tool-run and .cv-tool-group draw between them, so an expanded or partly folded run was estimated one 24 gap short per adjacent child. Both add (n - 1) block gaps at the per-pass Interface Size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(chat): folded run lines are stacked with the block gap The tool stacks (.cv-tools, .cv-tool-run, .cv-tool-group) draw --grid-gap-block between their lines, which 66ddd56 now estimates. The unit test counted lines with no gap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): one-line notes and activity lines estimate one grid row; notice lines span the row After the base merge: - A legacy activity line keeps the footer slot's one line. Base #30561 measured it as text. - Session-start and standalone notes estimate one 28 grid row instead of 37. Review at 66ddd56. - Restore #29965's .acpmux-row--line .cv-tools rule, so a notice's tool line keeps the icon and text columns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): centre the footer in the turn gap on the action control token itself Review at 45df014: the turn-gap footer rule read --cv-meta-row. On this branch that is var(--grid-transcript-action-control) (28), but base's value is 24, so naming the 28 control directly takes the ambiguity away. The value does not change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(chat): a note's estimate takes the grid's zero note gap Review BLOCK at 5cedb24: #30400 estimates a note as its 20 line plus 12 above and below, but on the grid .cv-tool-note has no margin (the run's block gap is the room), so each note was overestimated by 24. NOTE_GAP is 0, matching --cv-note-gap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(chat): a note between tool rows has the run's block gap on the grid Base's transcript-interim-prose-gap (#30400) holds a 12px note gap. On the grid a run stacks rows and notes with the 24 block gap, which gives a note more room than base's 12 and the same room as between any two blocks. The test now reads the grid token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Per the grid owner's correction the 22px one-line row pitch is intended (#29965) and the grid lane restores it, so the row pitch tests go back to base. transcript-row-alignment now expects the block gap above and below every status row (grid.md 5.5, block 24, gaps never add up). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-2f629b93d5a20c58e6f8
…apart (#29965) The running turn's live line (thinking/working, and the live run line) took the 24 block gap under a run of step rows; it is one more line of the run, so it joins flush. Under its own prompt it still waits a block gap (grid.md 5.5). continuationSpacing tests both. The reply-room comment no longer says a note adds no room (review follow-up). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0
…l run (#29965) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0
…on) (#31497) * fix(chat): one-line activity rows sit 22 apart again (#27580 regression) #27580 drew every tool, notice, inbox and message line on the 28 list row and put the 24 block gap between each one (between transcript rows and inside a run's .cv-tools, .cv-tool-run and .cv-tool-group), so consecutive one-line rows sat about 50 apart top to top. Leo, 2026-11-02: "well now there's sometimes too much spacing between tool calls". design/chat-transcript.md "One-line row pitch" (#29965) has them flush, 22 apart. - --cv-tool-row-height is 22 again; received lines and disclosure lines use it. - Run stacks list their lines flush (gap 0); a note keeps the block gap around it (--cv-note-gap). - transcriptGrid: a step row (a tool run or an isLineRow line, MARK_STEP) after another step row takes no gap; the block gap is only around a run of them. The estimator matches (22 lines, no in-run gaps, the note gap). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * test(chat): one-line rows estimate 22; the live line's check resolves its tokens rowEstimates: another agent's message, a sent message and a task notice are one 22px line (design/chat-transcript.md "One-line row pitch"). agent-pane-working-counts read --cv-meta-row with parseFloat, which is NaN since the token is a var() chain; it resolves each token through a probe's height. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * docs(chat): the note rule names the block gap and noteGap Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * fix(chat): the live line under a run of one-line rows sits flush, 22 apart (#29965) The running turn's live line (thinking/working, and the live run line) took the 24 block gap under a run of step rows; it is one more line of the run, so it joins flush. Under its own prompt it still waits a block gap (grid.md 5.5). continuationSpacing tests both. The reply-room comment no longer says a note adds no room (review follow-up). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * test(chat): transcript-rhythm holds the live line flush under its tool run (#29965) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 * style(chat): name the step-row test so the layout pass fits the formatter Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-ac5053f7854c8635a4d0 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
) (#31745) The running turn's line as its last row sat in the footer's 32 slot even right under a step row, so it measured 27 under the run and the waiting messages' head 51 under it. Right under a step row it is now a step row itself, 22 tall, so both are 22. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Leo, 2026-11-01, on a column of transcript rows (tool rows, inbox lines, agent message lines, fold heads) whose vertical gaps differ by row type:
Every one-line activity row in the agent transcript now draws on the tool rows' 22px line in a one-call tool run's frame (2px over, 4px under), and joins the step rows beside it, so any two consecutive one-line rows sit exactly 22px apart, top to top, whatever their kind. Their icons share one column and their words one text column.
What changed:
model.ts:isLineRownames those rows (another agent's message, a notice, an inbox notice, a report batch, the waiting group). The estimator uses the same frame (LINE_ROW= 2 + 22 + 4) and an open group's member as its line alone.App.tsx: marks themacpmux-row--lineand treats them as step rows, so they join their neighbours as tool runs already do.--cv-message-lineis now the tool row height; received, pending and lane-batch lines drop their own vertical margins; the sent message's toggle is 22px and its hidden Copy no longer stretches the line to 24px; the waiting group's chevron and words sit on the shared icon and text columns; a task notice's tool line takes its row's width (it sat at the row's right end, since the row is a user row).statusDeltacounts its 4px run gap as a tool run's.model.tsalso estimates a sent message (SendMessage,acpmux send, a sub-session'ssend_message) as one 22px line (review finding at 3bd8fe3).design/chat-transcript.md, "One-line row pitch" (separate notes PR).Prior art: #29754 (shared activity row grammar), #29613 (meta rows' icon and text columns) and #29124 (status rows' columns and centred gaps), all merged, are built on, not redone: this keeps their columns and adds the vertical rhythm. #29830 (flat waiting group) touches the group's contents, not its head geometry.
Changelog
Fixed: every one-line row in the agent transcript (tool rows, sent and received messages, inbox lines, background task lines, report and waiting-message fold heads) now sits on one line height and one spacing, with one icon and text column.
Test
CMUX_BROWSER_TESTS=1 bun test test/transcript-row-pitch-browser.test.ts(Chromium throughcmux-ci test, realVirtualTranscriptlayout, light and dark): equal line height, equal top-to-top pitch, one icon x and one text x within 0.5px across 12 rows of 7 kinds.t1 (cv-tool) is 22px tall, m1 26px,i1 sits 28px under t1, 38px elsewhere,t3 sits 34px under lane-notices:r1,n1 (cv-tool) icon at 534, 20 elsewhere,pending-messages icon at 24, 20 elsewhere; words at 48, 42.5 elsewhere, and more (19 findings).m1 (cv-disclosure__line) has a part 2px out of its line, same for i1, i2, m2.transcript-meta-columns-browser,transcript-row-alignment(Agent pane: status, tool and message rows and the action row line up with the prose #29124's centred status gaps),incoming-message-disclosure-browserandreceived-message-fold-browser.Observed / Not run
received-message-fold-browser,transcript-fold-no-blank-space-browser,other-session-message-actions-browser(all pass). LocallyrowEstimates(a new case: a sent message estimates 2 + 22 + 4),agent-pane-reply-actions-frame,agent-pane-transcript-spacing,foldAnchor,footerActionspass;transcript-hover-fadefails on.cv-subagent__stopin subagents.css, a file this PR does not touch. Locally:rowEstimates,rowLayoutLinearity,continuationSpacing,lane-notice-batches,lane-notice-card,transcript-received-messages(41 pass).vp fmt/vp linton the changed TS files,prepush-gate.py.risk:normal
Agent session: agent session
🤖 Generated with Claude Code