Skip to content

Agent chat: rich copy out of the transcript, and rich paste into the composer - #36112

Merged
cmux-bot[bot] merged 16 commits into
feat-cmux-nextfrom
lane/rich-copy-paste-markdown
Nov 5, 2026
Merged

cmux-bot[bot] merged 16 commits into
feat-cmux-nextfrom
lane/rich-copy-paste-markdown

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Leo, 2026-11-05: "Okay, we need to be doing this where you can copy and it's a rich copy of the transcript, the agent chat stuff. Like it needs to be copying the formatting, because Claude does it, ChatGPT does it, we don't, and we don't even render bullet points properly in our thing when we're pasting that stuff in. So we need to just do that. Like, I mean, we have it when we manually type it, you know, with the space or whatever, but we need to be able to just have that on paste as well."

What changes

Rich copy out of the agent transcript

  • A message's Copy button (replies, prompts, queued prompts) now writes the message's Markdown as text/plain, as before, and adds the same message as text/html, the way Claude and ChatGPT copy. When you paste into Notes, Slack, Docs or Mail, the headings, bullets, numbered lists, bold, links, code blocks and tables come through (richClipboard.ts copyMarkdownResult, rendered with marked, which the pane already uses). Raw HTML in a reply is copied as escaped text, not markup.
  • Select text, then Cmd-C inside one message: the HTML on the clipboard is the reply's own formatting with the transcript's classes, inline colors, buttons and icons removed, so a paste into Notes does not pick up the pane's dark-theme text color. text/plain is the selection as Markdown, so pasting into the composer or a terminal keeps the bullets (conversation/selectionCopy.ts). Some selections still use the page's default copy: one that contains math (mathCopy.ts handles it), one that contains highlighted code (its shadow root can't be cloned), and one that spans more than one message.

The composer renders rich paste

  • A paste whose HTML has lists, headings, quotes or tables (Notes, Docs, Slack, a web page, or a copy from our own transcript) is converted to Markdown. Plain text that is Markdown with a list or a fenced code block (Claude's or ChatGPT's Copy) is used as it is. Either way the composer parses it into the same blocks that typing - already makes: bullets, numbered lists, headings, code blocks, bold and links. Line breaks inside a paragraph stay line breaks, as they do in a plain paste. The text's own * and _ stay literal characters.
  • Everything else pastes as plain lines, the same as before (cmux NEXT composer: line breaks copy and paste as lines, never <br /> #23840): prose, logs, and a script with a # comment (a lone heading or quote doesn't trigger Markdown), VS Code pastes, pastes into a code block, images and file names.
  • Paste as Plain Text (Cmd-Shift-V, or the prompt menu) still pastes plain lines. The field marks the next paste as plain.
  • A huge paste still turns into a Pasted text chip first (onBeforeInput).

Typing behavior is unchanged, and the plain-text copy is unchanged.

What the pasteboard gets (copy side)

When you click Copy on the bulleted reply from Leo's screenshots, the pasteboard gets two types:

text/plain (unchanged: the Markdown source)

Continuing the landing pass:

- **#21620** merged; no red of its own
- **#21621** typecheck fixed where `vp check` failed
- **#21200** waiting on review

text/html (new; Notes, Slack, Docs and Mail paste this)

<p>Continuing the landing pass:</p>
<ul>
<li><strong>#21620</strong> merged; no red of its own</li>
<li><strong>#21621</strong> typecheck fixed where <code>vp check</code> failed</li>
<li><strong>#21200</strong> waiting on review</li>
</ul>

A Cmd-C selection inside a reply gets the same kind of HTML, cloned from the reply with every class, style and data- attribute removed, and buttons and icons dropped, with Markdown as its text/plain (selectionCopy.test.ts).

Gallery (composer paste)

The PR's gallery advisory run captures these composer.gallery.ts states in Linux Chromium, light and dark:

  • paste-bulleted-reply-plain: before, and still the result of Paste as Plain Text. The reply goes in as literal - / ** lines.
  • paste-bulleted-reply: after. The same paste shows an intro line and three bullets, with bold and inline code.
  • paste-heading-and-code: HTML with a heading, a list and a code block shows those blocks.

Prior art

Changelog

  • Added: Copying a message in an agent chat carries its formatting (bullets, headings, bold, links, code) into Notes, Slack, Docs and Mail, and pasting formatted text or Markdown into the composer shows it as lists, headings and code blocks.

Tests

  • bun test src/agent-session/acpmux/richClipboard.test.ts src/agent-session/acpmux/conversation/selectionCopy.test.ts: the Markdown→HTML conversion and back, Notes- and Docs-shaped HTML, escaping, the paste trigger rules, and selection-copy cleaning.
  • webviews/test/composer-rich-paste.test.ts (Chromium and WebKit): a Markdown list pastes as ul/ol with the intro's lines kept; Notes/web HTML pastes as a heading, a list and a code block; Cmd-Shift-V keeps - one as text and the next paste is rich again; a # comment script stays as lines; a message's Copy writes Markdown plus <ul> HTML, and pasting that back gives the list.
  • webviews/test/composer-line-breaks.test.ts: still covers cmux NEXT composer: line breaks copy and paste as lines, never <br /> #23840's lines. Its clipboard mock gained write, because Copy now writes both formats in one call.

Observed / Not run

Observed:

  • Fleet run of 138bee4a (run 41994387325): 25/25 browser tests (composer-rich-paste, pane-english, composer-line-breaks, composer-html-paste-edit) in Chromium and WebKit, 42/42 unit tests (richClipboard, selectionCopy, agent-pane-math, chat-icon-tooltips, card-corner-copy, user-prompt-collapse), lint 0 warnings, no type errors.
  • Review BLOCK at 0a37de19 (gpt-6.1-sol): copy lost line breaks inside a paragraph, a selection inside a table copied bare cells, and an ordered-list selection copied the drawn numbers twice. Fixed in 138bee4a, each covered in richClipboard.test.ts / selectionCopy.test.ts.
  • Fleet run of f7b86bc3 (run 41966234063): 8/8 unit tests and 30/30 browser tests in Chromium and WebKit. That covers composer-rich-paste, plus composer-line-breaks (cmux NEXT composer: line breaks copy and paste as lines, never <br /> #23840), composer-html-paste-edit, composer-paste-end and gallery-composer-paste, all unchanged and passing. The full bun run check passed: lint 0 warnings, no type errors.
  • The first fleet run (70323e4a) caught a real bug: in WebKit, a list pasted after text on the same line lost its first bullet, because that item was merged into the line. Fixed in f7b86bc3; the pasted slice now stays open only at an end that is a paragraph.
  • Review BLOCK at 70323e4a (gpt-6-astra): a selection entirely inside one equation was taken from mathCopy. Fixed in f1ff596b. selectionCopy.test.ts fails without the fix and passes with it.

Not run: pasting into Notes or Slack in a DEV build. Gallery images come from this PR's advisory run.

🤖 Generated with Claude Code

Agent session: agent session

teamleaderleo and others added 2 commits November 5, 2026 03:40
…the composer

Red on base: the composer pastes a Markdown list or Notes/web HTML list as
flat lines or literal '- ' text, and there is no rich clipboard module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
…to the composer

Leo, 2026-11-05: "we need to be doing this where you can copy and it's a
rich copy of the transcript ... and we don't even render bullet points
properly in our thing when we're pasting that stuff in."

Copy on a message writes its Markdown (text/plain, as before) and the same
message as HTML; Cmd-C on a selection inside one message writes clean HTML
(no transcript classes or theme colors) with Markdown as its plain text.
A composer paste whose HTML has lists, headings, quotes or tables, or whose
text is Markdown with a list or fenced code, goes in as the blocks typing
makes; everything else stays its plain lines (#23840), and Paste as Plain
Text stays plain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
@cursor

cursor Bot commented Nov 5, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot 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.

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 4cb7825: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr36112 -f ref=lane/rich-copy-paste-markdown -f platform=macos -f backend_mode=local

Gallery before/after for 4cb7825: 16 states rendered, 12 images differ, 3717 more touched states not rendered. Images are in the run's artifact, not on this public PR; the independent review of this head reads them on its own, so the PR needs no hand-made screenshots of these states.

gh run download 41998339321 -R manaflow-ai/cmux -n gallery-advisory-36112-4cb7825f181ce07a9731448b7ca3857b46bdb10b (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.card-copy/prompt-rest Apple System Colors Light changed 0.0109% own CardCopy.tsx
agent-pane.card-copy/prompt-rest Apple System Colors changed 0.0101% own CardCopy.tsx
agent-pane.card-copy/prompt-hover Apple System Colors changed 0% own CardCopy.tsx
agent-pane.card-copy/prompt-hover Apple System Colors Light unchanged 0% own CardCopy.tsx
agent-pane.card-copy/prompt-copied Apple System Colors Light unchanged 0% own CardCopy.tsx
agent-pane.card-copy/prompt-copied Apple System Colors unchanged 0% own CardCopy.tsx
agent-pane.card-copy/message-rest Apple System Colors Light changed 0.0101% own CardCopy.tsx
agent-pane.card-copy/message-rest Apple System Colors unchanged 0% own CardCopy.tsx
agent-pane.card-copy/message-hover Apple System Colors Light unchanged 0% own CardCopy.tsx
agent-pane.card-copy/message-hover Apple System Colors unchanged 0% own CardCopy.tsx
agent-pane.card-copy/message-copied Apple System Colors Light unchanged 0% own CardCopy.tsx
agent-pane.card-copy/message-copied Apple System Colors unchanged 0% own CardCopy.tsx
agent-pane.card-copy/quiet-rest Apple System Colors changed 0.134% own CardCopy.tsx
agent-pane.card-copy/quiet-rest Apple System Colors Light changed 0.0109% own CardCopy.tsx
agent-pane.card-copy/quiet-copied Apple System Colors Light unchanged 0% own CardCopy.tsx
agent-pane.card-copy/quiet-copied Apple System Colors unchanged 0% own CardCopy.tsx
agent-pane.composer/paste-bulleted-reply-plain Apple System Colors Light new 0% own ComposerBox.tsx
agent-pane.composer/paste-bulleted-reply-plain Apple System Colors new 0% own ComposerBox.tsx
agent-pane.composer/paste-bulleted-reply Apple System Colors Light new 0% own ComposerBox.tsx
agent-pane.composer/paste-bulleted-reply Apple System Colors new 0% own ComposerBox.tsx
agent-pane.composer/paste-heading-and-code Apple System Colors Light new 0% own ComposerBox.tsx
agent-pane.composer/paste-heading-and-code Apple System Colors new 0% own ComposerBox.tsx
agent-pane.composer/font-size-chat-14 Apple System Colors Light unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-chat-14 Apple System Colors unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-new-chat-14 Apple System Colors Light unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-new-chat-14 Apple System Colors unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-new-tab-14 Apple System Colors Light unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-new-tab-14 Apple System Colors unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-chat-21 Apple System Colors Light unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-chat-21 Apple System Colors unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-new-chat-21 Apple System Colors Light unchanged 0% own ComposerBox.tsx
agent-pane.composer/font-size-new-chat-21 Apple System Colors unchanged 0% own ComposerBox.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

Passes: CI passes on 4cb7825f18.

CI passes on 4cb7825f18 (run 41998339539 attempt 1).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

web and size checks: green

Shipped in:

@teamleaderleo teamleaderleo added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 5, 2026
…, a pasted heading and code block

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
Fleet run of composer-rich-paste.test.ts on 70323e4: the paste after
Paste as Plain Text drew one bullet for two (WebKit), since the slice was
open at its start and the first item joined the line before the caret.
A pasted slice now opens only at a paragraph end. The round-trip test
counted each item's own <p>; it now reads top-level paragraphs only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
…opy's

Review (gpt-6-astra, BLOCK at 70323e4): a selection that starts and ends
inside one typeset equation clones only glyphs, so selectionCopy took it
and Cmd-C copied KaTeX glyphs instead of the TeX. It now leaves any range
that touches an equation to mathCopy. selectionCopy.test.ts: red on the
old code, green now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
@blacksmith-sh

blacksmith-sh Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Found 3 test failures on Blacksmith runners:

Failures

Test View Logs
nightly cmux-tui resolve/nightly cmux-tui resolve View Logs
test_every_compile_job_names_its_warm_sources (main.ThisTree.test_every_compile_job
_names_its_warm_sources)/
test_every_compile_job_names_its_warm_sources (main.ThisTree.test_every_compile_job
_names_its_warm_sources)
View Logs
the six-hour schedule must allow 90 minutes for a cold cache build and use the matching
runner, Xcode, and visible timing output/
the six-hour schedule must allow 90 minutes for a cold cache build and use the matching
runner, Xcode, and visible timing output
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at f1ff596

Reviewer: codex gpt-6-astra high, fast tier.

Follow-ups: 2. They land as checklist items in this PR's one follow-up tracking issue in this repo (Follow-ups: #N ..., label follow-up; add to an open one before filing, never one issue per finding), linking this receipt; the lane that opened the PR fixes them forward.

SHIP at f1ff596bbf8e76858f21e45a674efd2a5c9a4954

Visual verdict: no images; Leo tries the build

  • [P2] [follow-up] [category:correctness] [finding:F1] [outcome:pending] HTML-only code blocks are not recognized as rich input: htmlHasBlocks omits <pre> at richClipboard.ts:36, so a clipboard containing only <pre><code>…</code></pre> falls back to plain lines and loses code-block formatting. Include pre in the trigger and add coverage.
  • [P2] [follow-up] [category:reliability] [finding:F2] [outcome:pending] Paste-as-plain-text windows are inconsistent: MarkdownField.tsx:375 expires after 1 second, while pastedChips.ts:11 allows 2 seconds. If native paste delivery is delayed beyond one second, a list/fence can be parsed as rich Markdown despite Paste as Plain Text. Share one timeout or one state flag.

Follow-ups:

  • F1: recognize standalone HTML <pre> code blocks.
  • F2: align the plain-paste timeout across the field and chip handler.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves f1ff596: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

Web shards on f1ff596: Copy failed where the page has only
clipboard.writeText (user-prompt-collapse, chat-icon-tooltips,
sent-skill-dollars), because the rich copy tried the async write and the
copy event and gave up. It now ends with copyTextResult's plain text. The
math test's no-math selection is now the rich selection copy's (its text
and clean HTML), not the page's own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, router-review): BLOCK at 1e437fb

BLOCK at 1e437fb

Visual verdict: no images; Leo tries the build

  • [P1] [blocking] [category:correctness] [finding:F1] [outcome:pending] Plain-paste timing is inconsistent: [MarkdownField.tsx:987] expires its flag after 1000 ms, while the existing menu/host path remains armed for 2000 ms ([pastedChips.ts:11], [ComposerBox.tsx:195]). A delayed Paste as Plain Text event can therefore parse - one as a rich list. Use one shared timeout/marker.

  • [P2] [follow-up] [category:correctness] [finding:F2] [outcome:pending] Expanded prompt/message cards still use copyTextResult through [CardCopy.tsx:20-41], so their Copy buttons omit text/html despite the PR’s rich-copy behavior.

Follow-ups:

  • [finding:F2] Wire CardCopy’s default writer through the rich clipboard writer.

…field and chips

Review (gpt-6-astra, BLOCK at 1e437fb): the field kept a plain paste plain
for 1 s while the composer's chip path (and the menu's paste through the
host) allows 2 s, so a late Paste as Plain Text could still draw a list.
Both now read pastedChips.ts PLAIN_PASTE_MS; composer-rich-paste waits
1.5 s before its plain paste. Also: an expanded card's Copy writes the
rich copy too (review follow-up), and the selection copy installs per
document, so a second DOM in one test process gets it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
…age Markdown

Review (gpt-6.1-sol, BLOCK at 0785306): a copied transcript message with a
remote image and a list took the rich path, whose HTML conversion drops
<img>, so the image's ![alt](url) never went in. A paste whose plain text
carries image Markdown now takes the plain path, as before this PR.
composer-rich-paste covers it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
…ion copy

Review (gpt-6-astra, BLOCK at f952d19):
- A paste whose HTML holds an <img> now takes the plain path and image
  intake too, not only one whose text has image Markdown; the rich path
  would drop the picture.
- The selection copy unwrapped nothing and removed every <button>, so a
  visible link chip's words and an image that opens were lost. Buttons are
  now unwrapped (their icons still go) and images keep src and alt.
selectionCopy.test.ts and composer-rich-paste.test.ts cover both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, router-review): BLOCK at 23abcc7

BLOCK at 23abcc7

Visual verdict: no images; Leo tries the build

  • [P1] [blocking] [category:security] [finding:F1] [outcome:pending] [richClipboard.ts:87-92] markdownHtml emits Markdown link destinations without protocol validation. A reply containing [click](javascript:...) is copied as an executable href; pasting that HTML into a rich editor can create a JavaScript link. Reuse the existing safeHref policy or allowlist safe protocols before generating clipboard HTML.

Follow-ups: none

…targets

Review (gpt-6-astra, BLOCK at 23abcc7): Copy's HTML wrote a reply's link
target as written, so [x](javascript:...) became an executable href in the
app it was pasted into. Copy and the selection copy now keep a link's
target only for a web link (safeHref, as the transcript draws it) or a
mail address, and a picture's only for a web image; anything else copies
as its words. richClipboard.test.ts and selectionCopy.test.ts cover it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at a5ff677

Reviewer: codex gpt-6-astra high, fast tier.

Follow-ups: 1. They land as checklist items in this PR's one follow-up tracking issue in this repo (Follow-ups: #N ..., label follow-up; add to an open one before filing, never one issue per finding), linking this receipt; the lane that opened the PR fixes them forward.

SHIP at a5ff677

Visual verdict: no images; Leo tries the build

  1. [P2] [follow-up] [category:ux] [finding:F1] [outcome:pending] Gallery stills were unavailable, so the visual result could not be independently checked.

Follow-ups:

  • [F1] Provide gallery stills for the rich-paste states.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves a5ff677: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

Webview replays at a5ff677 (read by claude-sr2-fleet-mesh-3):
- pane-english flagged the clipboard HTML templates in richClipboard.ts;
  they carry l10n-allow (markup, not words a person reads).
- composer-rich-paste's Copy round trip waited for a sent bubble, a step
  that is red on base in this harness (composer-line-breaks (a)); it now
  calls copyMarkdownResult, the writer MessageCopy and CardCopy use, from
  the page and pastes that back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
… root

The pane's dev server is rooted at src/agent-session/acpmux, so
/src/... did not resolve and the Copy round trip failed at its import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, router-review): BLOCK at ada8050

BLOCK at ada8050

Visual verdict: Rich-paste formatting is consistent with Claude/ChatGPT. All 13 supplied before/after pairs are identical; no introduced visual defect found.

  1. [P1] [blocking] [category:correctness] [finding:F1] [outcome:pending] Selection-copy corrupts unhighlighted code. selectionCopy.ts:70 intercepts selections in PlainCodeLines, used during streaming, in tool output, and for highlighting fallbacks. Those blocks render each line as a <div> inside <pre>. Selecting across lines converts if ready:\n run() into if ready:\n\nrun(), removing indentation. A selection including the <pre> instead concatenates its lines through textContent. Preserve these code selections through native copy, or explicitly reconstruct their whitespace and line boundaries before overriding the clipboard. Add regression coverage for both selection shapes.

  2. [P2] [follow-up] [category:correctness] [finding:F2] [outcome:pending] Selections confined to a list lose their bullets. selectionCopy.ts:45 clones only the range contents. Dragging from the first item’s text through the second item leaves orphan <li> elements because their common <ul> ancestor is excluded. htmlMarkdown consequently produces one\n\ntwo, and pasting back creates paragraphs rather than bullets. Preserve the enclosing list context, including ordered-list numbering, and test a range whose endpoints are inside item text.

Follow-ups:

  • Preserve list structure for selections confined to list items.

… selection keeps its list

Review (gpt-6-astra, BLOCK at ada8050): plain code draws each line as an
element inside <pre>, so the selection copy dropped indentation and line
ends. Any selection touching a <pre> is now the page's own copy. Also
(follow-up): a selection inside one list cloned bare <li>s and pasted back
as paragraphs; it is now wrapped in its <ul>/<ol>, an ordered list from
its first selected item's number. selectionCopy.test.ts covers both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol xhigh, router-review): BLOCK at 0a37de1

BLOCK at 0a37de1

Visual verdict: rich bullets and code match the expected ChatGPT/Claude presentation. All 13 supplied before/after pairs are identical.

  1. [P1] [blocking] [category:correctness] [finding:F1] [outcome:pending] Preserve message line breaks in rich Copy. richClipboard.ts:28 leaves Marked’s breaks disabled. Copying Intro\nnext line\n\n- one produces HTML without a <br> between the first two lines. Rich destinations flatten them; pasting back into this composer also yields Intro next line because it prefers that HTML. Preserve the transcript’s explicit line breaks and test this round trip.

  2. [P1] [blocking] [category:correctness] [finding:F2] [outcome:pending] Preserve boundaries when copying across table cells. selectionCopy.ts:50 clones a selection within a table row as bare <td> elements without restoring their table context. htmlMarkdown concatenates those cells: selecting alpha and beta writes alphabeta, losing the separators native copy preserved. Restore the required ancestors or leave these selections to native copy.

  3. [P2] [follow-up] [category:correctness] [finding:F3] [outcome:pending] Remove explicit ordered-list number spans before stripping classes. selectionCopy.ts:65 retains the real transcript’s .cv-li__num text alongside the <ol> numbering. Selected items therefore copy as 1. 1.one and 2. 2.two. Add coverage using the actual rendered list structure.

Follow-ups:

  • Remove duplicate ordered-list numbers described in finding 3.

…st numbers right

Review (gpt-6.1-sol, BLOCK at 0a37de1):
- Copy's HTML now keeps a line break inside a paragraph as <br> (Marked
  breaks), so 'Intro\nnext line' stays two lines in other apps and when
  pasted back into the composer.
- A selection inside one table is the page's own copy; the clone had bare
  cells and wrote 'alphabeta'.
- The transcript's drawn list numbers and bullets (.cv-li__num,
  .cv-li__bullet) are dropped from the selection copy, so an ordered list
  copies as '4. four', not '4. 4.four'.
richClipboard.test.ts and selectionCopy.test.ts cover all three, the list
case on the transcript's real markup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-d1d94e42440e6bac3569
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 138bee4

Reviewer: codex gpt-6.1-sol xhigh, fast tier.

Follow-ups: 1. They land as checklist items in this PR's one follow-up tracking issue in this repo (Follow-ups: #N ..., label follow-up; add to an open one before filing, never one issue per finding), linking this receipt; the lane that opened the PR fixes them forward.

SHIP at 138bee4

Visual verdict: no images; Leo tries the build

  • [P2] [follow-up] [category:correctness] [finding:F1] [outcome:pending] MarkdownField.tsx:925-928 returns before consuming plainPasteAt when onPasteFirst handles an attachment/inline paste. After Cmd-Shift-V followed by such a paste, the next ordinary paste within two seconds is incorrectly forced through the plain-text path; clear the field marker whenever an earlier paste handler consumes the event.

Follow-ups:

  • [P2] [finding:F1] Clear plainPasteAt when onPasteFirst consumes the paste.

…opy-paste-markdown

# Conflicts:
#	webviews/src/agent-session/acpmux/composer.gallery.ts
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 4cb7825

Reviewer: codex gpt-6-astra high, fast tier.

Follow-ups: 1. They land as checklist items in this PR's one follow-up tracking issue in this repo (Follow-ups: #N ..., label follow-up; add to an open one before filing, never one issue per finding), linking this receipt; the lane that opened the PR fixes them forward.

SHIP at 4cb7825

Visual verdict: no images; Leo tries the build

  • [P2] [follow-up] [category:correctness] [finding:F1] [outcome:pending] HTML containing only a code block (<pre>/<code>) is not recognized as rich paste because htmlHasBlocks omits pre (richClipboard.ts). MarkdownField therefore falls back to plain text, so code copied from a code editor or document loses its fenced code block unless another supported block is also present. Include pre in the rich-paste trigger or explicitly document and test this limitation.

Follow-ups:

  • F1: HTML-only code-block pastes lose code-block formatting.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves 4cb7825: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

@cmux-bot
cmux-bot Bot merged commit a883bad into feat-cmux-next Nov 5, 2026
196 of 197 checks passed
@cmux-bot
cmux-bot Bot deleted the lane/rich-copy-paste-markdown branch November 5, 2026 10:04

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 4cb7825f Deployed Nov 5, 2026 by teamleaderleo via cmux-tui tree preflight #115277
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant