acpmux: name a sent prompt's pasted blocks (user_message.pasted)

Merged
TE
16d ago
+146-7

The composer sends each paste as its own ACP text block marked _meta: {"cmux": {"pasted": true}}, but the daemon dropped the marker, so a sent message couldn't show a collapsed "Pasted text · N lines" chip. A prompt's user_message now has pasted: [{start, end}], one entry for each pasted block, as UTF-16 code-unit offsets into text. A client can read a paste with text.slice(start, end). The key is left out when nothing was pasted.

  • prompt_text is now built on prompt_text_parts: one walk that joins the non-context text blocks with "\n" (as before, with no trimming) and records the pasted ranges. The text and the ranges can't drift apart.
  • append_prompt adds pasted, so it covers both turns and steers. So do the queued record and queue_edit's queue_updated record. pasted is added only when the record's text is exactly the text the ranges were computed from.
  • cmux-tui/crates/acpmux/docs/acpmux-schema.json documents pasted on user_message and queued. It also documents user_message.images, which was missing. The webviews copy (handoff/schema/acpmux-schema.json) is a sha-pinned snapshot of #16930 (see pin.json and schema.test.ts), so I left it alone. user_message isn't in the protocol IR (spec/acpmux-protocol.json), so the codegen doesn't change either.

Changelog

none

Red and green

Command: cmux-ci run --class isolated --script scripts/ci/cmux-tui-rust-check.sh --arg test --arg pasted --ref <sha>

The UTF-16 test puts 👀 (a non-BMP character, two UTF-16 units) and accented letters before and inside the pastes, then checks each range with a UTF-16 slice.

Observed / Not run

  • Observed: the fleet red and green runs above; python3 scripts/cmux-next/prepush-gate.py (no new violations); rustfmt --check on the changed files.
  • Not run: the full cmux-tui test suite, clippy, and bun run check (no webviews file changed). CI covers these.

Agent session: cosmic-gray

🤖 Generated with Claude Code


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


Summary by cubic

Names pasted text blocks on a sent prompt's user_message (and on queued records) as UTF-16 {start, end} ranges of the recorded text, so the chat can fold each into a "Pasted text · N lines" chip.

  • The composer sends each paste as its own ACP text block marked _meta.cmux.pasted; previously the daemon dropped that marker, so sent messages couldn't show pastes.
  • prompt_text is now derived from a single prompt_text_parts walk that joins the text blocks and records each paste's range, so the ranges can never drift from the text.
  • pasted is added to user_message (turns and steers), the queued record, and queue_edit's queue_updated record, only when something was pasted and the record's text matches the computed text.
  • acpmux-schema.json documents pasted on user_message and queued, and also documents the previously missing images field on user_message. The webviews copy and protocol IR are untouched.