fix(next): append Quote in Reply after composer draft

Closed
TE
6d ago
+577-2

Quote in Reply appends a rendered Markdown block after the current draft and leaves the caret below it. Repeated quotes keep their order; selected text that resembles a reference definition stays visible and serialized. The existing muted left bar supplies the quote treatment, matching the Claude desktop quote reference while retaining cmux's colours and glass.

Leo: “I feel like putting it at the very lowest bit makes sense”.

Canonical route: chat.quoteReply({markdown}) from #26660 → ComposerHandle.quoteReply(markdown) here. The standalone composer head does not register that page action. #26654 is closed as superseded.

Before / after

Before: existing draftAfter: quote appended, typed reply outside it
Dark draftDark appended quote
Light draftLight appended quote
Focused draftSuccessive quotes keep their order
Dark focused draftDark successive quotes
Light focused draftLight successive quotes

Persistence review repair

Current repair head: 917f6261d65a9c08b214ef04dd9146955a53e671, tree 6aa173e4198d9937442a547beb81d1a4c9d1ef39. This is a normal fast-forward from reviewed head 04c96e958babccef9aac7b215a6f818709fe74ec; no base merge or rebase.

Addresses the quote-only draft persistence finding. The serializer now preserves a blank-line boundary when an empty reply paragraph follows a block. Existing restore logic recreates that paragraph, so reopening keeps the end caret outside the quote. Ordinary paragraph drafts retain their existing trimming behavior. Canonical Quote in Reply insertion and native/menu routes are unchanged.

The new browser fixture mounts the real Composer, calls ComposerHandle.quoteReply and settleDraft, unmounts/remounts the Composer/editor, types through Playwright, and checks the actual onSend Markdown. Only daemon draft storage is a fixture. Both quote-only and existing typed drafts are covered.

Fleet red/green proof 40876007269 runs the exact browser regression against the old serializer and confirms both swallowed-reply failures; with the repaired serializer, the complete web check and all 33 focused tests / 107 assertions pass. The run's overall conclusion is FAILURE because its shell cleanup used a relative path after changing directories; the source tree and all test results are retained. Final hosted run 40876648578 is SUCCESS at the pushed repair head and identical tree: the static gate fetches the real immutable base/head history and reports no new violations; both browser save/unmount/reopen/type/send cases pass (8 assertions).

Earlier review and integrated-capture receipts below apply to their stated heads. Fresh review belongs to the existing landing workflow.

Performance

No perf numbers: this is a persistence correctness repair with behavioral browser and editor tests; it makes no measured performance claim.

Prior verification

Dependency: #26660 must land first. This standalone head’s gallery health reports agent-pane.quote-reply#append waiting for the unregistered page action (run 40655066591); the combined proof below passes that interaction. The PR’s own four react-apps-check shards pass. This gallery failure is an own dependency failure, not a base-red exemption.

Frozen head: 8d19f6d54f558aa6bbf7e68ecdec47f649d15f25.
Review (codex gpt-6-astra xhigh): SHIP at 8d19f6d54f558aa6bbf7e68ecdec47f649d15f25.

Focused quote/editor/selection/message regression suites pass (42 tests on the combined production). The earlier three attachment-paste failures also reproduce on base; no attachment code changed. All heavy verification ran on the fleet.

Integrated proof combines #26660 producer 655393f0d31ee7cbac3d5fbc2847a40cfcd3c48b and #26655 composer 8d19f6d54f558aa6bbf7e68ecdec47f649d15f25. Production merge: 04ce1974a450849f27cb5258e430592bfb9802fc; capture candidate: b95c200fae699529cb2bfda166daa1f07d38af93, tree 1feeaebb269fb3736185409bad271553dc54edee. Later candidate commits change only the capture test, not either survivor branch.

Fleet run 40664890704 is SUCCESS: eight light/dark gallery interactions/captures, full web check, localization scanners and web lint. Six post-type observations assert the action is registered, the draft stays first, one or two rendered quotes stay ordered, the caret/typed reply is in the trailing paragraph, and Markdown round-trips with blank lines. Root inspected all eight images. Zero-step gallery status none is accepted only for an empty measurement list without errors, followed by the actual DOM/serialization assertions; it is not a performance pass.

Review (codex gpt-6-astra xhigh): SHIP at b95c200fae699529cb2bfda166daa1f07d38af93 (isolated integration; static review). Native compile/runtime is separate and remains unverified; Swift HOLD #26809 still applies to #26660. Captures use a public-safe fixture, never Leo's private references.

Changelog

Fixed: Quote in Reply stays below the draft, renders as a quote, preserves selected text, and leaves a ready-to-type paragraph.

Agent session: agent session