Repository navigation
fix(next): select text from transcript gaps - #26704
Conversation
Add browser regressions for row-gap midpoint drags and control ownership before the gap handler repair.\n\nAgent-Session: https://cmux.com/deeplink/agent?harness=codex&session=transcript-gap-selection-1028&host=big-red Agent-Session: https://cmux.com/deeplink/agent?id=aid-f7f42a8c196bca5f0498
Leo reported dead zones between tool calls, prompts, and agent messages. Resolve a gap or side-gutter press to the nearest mounted caret on pointerdown, then extend a native range across rows without intercepting controls. Agent-Session: https://cmux.com/deeplink/agent?id=aid-f7f42a8c196bca5f0498
|
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)
Unclear: CI failed on
Not re-run automatically: Written by red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 7c46740 to compare; do not merge until green; see lane-rules Gallery before/after for
States
Pick other states with a |
Exercise every tool, prompt, and agent row pair through the real virtual transcript, including both gutters, selection restart, plain clicks, and control ownership. Agent-Session: https://cmux.com/deeplink/agent?id=aid-f7f42a8c196bca5f0498
|
Found 6 test failures on Blacksmith runners: Failures
|
Preserve native text and control presses, resolve every row gap and side gutter to the closest rendered line, and only inspect mounted text on pointerdown. Keep touch scrolling native. Add the public gallery matrix for tool, prompt, and agent row pairs. Agent-Session: https://cmux.com/deeplink/agent?id=aid-f7f42a8c196bca5f0498
|
Bead |
|
Review (codex gpt-6-astra high, next-review): SHIP at 28a929e No blocking findings. |
|
Review (codex gpt-6-astra high, next-review): SHIP at 1cac423 No blocking findings. Reviewed the supplied diff and changed files. Tests were not rerun in this environment. |
|
Review (codex gpt-6-astra high, next-review): SHIP at 682f9e3 No blocking findings. |
|
Shipped in:
|
…mpty rows, dev host trust, four stale tests) (#27794) * fix(webviews): six react-apps-check base reds (tables in WebKit, empty rows, stale tests) - markdown tables: a drag across cells in WebKit stayed on its first cell. prosemirror-tables normalizes a text selection whose head lands at the next cell's start to the first cell's text; Chromium waits for the mouseup to write the editor's selection to the page, WebKit writes it at once and its drag stops there. tableTextSelectPlugin drops that normalization while the button is down. - transcript: a row whose renderer draws nothing took its padding again (`article.acpmux-row:empty` stopped matching once every row holds its `.acpmux-row__gap` target, #26704). The rule now matches a row with no child but the gap. - MarkdownMath: the test reads the text without the <wbr> break points #27277 adds. - bare-ref-repo: another agent's message is one line until opened (#27312); the test opens it before reading its chips. - transcript-send-remount: the fixture's turn ends with its footer, so the reply does not gain its own action row on send (#27313), a redraw the test is not about. - trailing-plates-tool-output: Reduce Motion still runs transitions for 0.01ms; the test reads the actions once their reveal has run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ffe9f4bb4afcf68decf6 * fix(webviews): the browser dev host never invents a folder's trust chat-open-long (busy daemon) has been red since #24144. Before the pane's daemon client binds its actions, a trust read reaches the browser dev host, which answered every folder "unknown". That drew a "Trust cmux?" card (73px) over a folder acpmux trusts. Since #24144 scoped trust to its route authority, the client's bind reads the folder again and the card goes away, so the transcript shifts. Before #24144 the wrong card just stayed. The dev host now says it can't answer acp.trust.get (native.unsupported), as it does for other host-only reads. readFolderTrust treats that as "can't say" and draws no card, and the client's read after the bind gives acpmux's real answer. The shipped app's native host is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(markdown): a table press ends however the button comes up Review (Codex, #27794): the drag flag ended only on a mouseup or dragstart the page saw. A button released over another app never reaches the page, so the flag stayed set, and the filter went on dropping a cross-cell text selection's narrowing (a keyboard caret move out of it). The window listeners also outlived an editor destroyed mid-press. The press now also ends on the window's own blur (not capturing, since the press's own focus change blurs an element), on a key, and on a mousemove with the primary button up (as prosemirror-view's own MouseDown does). The plugin view's destroy removes the listeners, and a new press clears any earlier one first. A browser test can't release the button without delivering a mouseup to the page (Playwright keeps it pressed, and so does prosemirror-view's own MouseDown), so the case isn't simulated. The existing drag, click and Shift-click tests cover the paths that must keep working. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(markdown): a key pressed mid-drag does not end a table press Review (Codex, delta at 11a2424): Shift or Cmd pressed during a cross-cell drag leaves the button down, but the capturing keydown listener ended the press, so WebKit's drag went back to sticking on the first cell. The window's blur and a mousemove with the primary button up still end a press whose mouseup never reached the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: ci <ci@example.invalid>
) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64
…lapse it (#29699) * Transcript: a collapsible's whole header line is its toggle The edits card header toggled only from its title strip; now its padding, icon, counts and gaps toggle too, and the same holds for an agent message's line and a disclosure row's line. Inner controls keep their own click. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64 * foldAnchor test: click an agent message line's words Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64 * Format Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64 * Edits card: keep the header marked interactive for gap selection (#26704) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64 * Received line: the sender keeps its own click; gallery audit allows the edits header's chevron wash Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64 --------- 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)
Dragging from the blank padding between transcript rows now starts or restarts text selection at the nearest visible caret. A line above contributes its end and a line below its start. Plain gap clicks clear an old selection; text and controls keep their native pointer behavior.
Leo's request:
The existing transcript handler resolves mounted text once on pointerdown and extends a native range during the drag. Public fixtures cover all nine tool/prompt/agent row pairs, both side gutters, selection restart and clearing, control padding, and invisible code handoff text. Separate midpoint cases add a 32px gap only in the integration fixture, measure the actual upper/lower article bounds, and verify that each press lands outside both rows and their controls; production spacing is unchanged.
The pointerdown path now checks
event.composedPath()before classifying transcript padding. Presses whose path enters an open shadow root or shadow host stay with native selection; the handler never synthesizes a range inside that boundary. The browser test server supplies Pierre's real portable workers on HTTP soHighlightedCodeandEditDiffHunksrender their actualdiffs-containertext. Regressions drag inside each component's own shadow root, assert native pointer ownership and code-only selection, then unmount React roots and terminate the test workers. Product scheme policy is unchanged.Changelog
Fixed: Text selection can start in the gaps and padding between transcript messages and tool calls.
Observed / Not run
093474ad1e141146b2008496254cbcac71981420; whole treeea7f132314bd5dd41ede7aa0f6a82f3dfe312947.26f252bb3c2fa64c543a375614febc57078a57fband final source share the whole tree above.Review (independent Codex gpt-6-astra high, review_gap_final_26704): SHIP at 093474a
The reviewer re-inspected the whole final diff, surrounding lifecycle, and final gallery-only repair from the bare mirror. Primary inspection agrees. This is a different-model read-only subagent review; fleet runs are separate evidence.
The transcript spacing follows the private Claude tool-row and Codex expanded-command references; those reference images are not published here. The gap-behavior captures below use the public
agent-pane.gutter-select/gaps-readygallery fixture, Chromium 151, 1280×560, English, Apple System Colors, and the same drag coordinates.Final checks: all 80 checks pass apart from
Package dependency lists sortedin cmux-next. Exact base replay 40808066907 reproduces the identicalCmuxNextHomeEngineTests: imports CmuxNextHome but does not declare it in its dependencieson the tested merge basefe31ba94c5d1eeee3c81dc1768a8a910872e9b8c. This PR changes no Swift, manifest or dependency-checker input. All four own web shards and gallery health pass; no pending checks remain.Agent session: agent session