Agent pane: messages from other sessions draw as received lines

Closed
TE
17d ago
+2876-1593

Summary

A message from another session reached the agent pane as an ordinary prompt and drew as the person's own bubble. It showed the whole envelope the cmux-tui pump writes: "[cmux agent message] from …", the message id, the safety line and the reply hint, and then the words. The prompt carries _meta.provenance.kind: "agent_message" with the sender (acpmux prompt_provenance.rs, cx-55d27), but the pane never read it.

Now the message draws as Claude desktop does (refs transcript-received-messages-group.png, transcript-received-message-expanded.png and transcript-peer-session-message.png in cmux-design-references; "Messages and actions" in #21604):

  • One muted line, "Received message from ". The sender is underlined and opens that session's chat when it is a chat acpmux runs (from is acp:<id>). Any other sender is plain text.
  • The chevron, or a click on the line, opens the sender's own words under it in muted body type. The envelope is stripped at its --- line and its closing line, which repeats the message id so a body cannot fake it. Text in any other shape is kept whole.
  • A message waiting behind a busy turn stays in the composer queue, where it can be removed or sent now, as before. It draws as a received line once it lands.
  • Find searches the sender's words, not the envelope, and opens the line (and its group) to show a match. Copy copies the words. A received prompt offers no Retry or Edit, which would resend the envelope as the person's own.
  • Two or more received lines in a row fold into one "Received N messages" line, which opens to them.
  • This draws for everyone. A started task's result (offer_result) still draws as before, behind its toggle.

Out of scope, and listed in #21604:

  • Delivering a message at the agent's next step rather than after the turn. acpmux queues agent messages with steer: false.
  • The queued/submitted/done state from prompt_accepted and turn_started.

Testing

  • bun test test/received-messages.test.tsx. It drives the real AcpmuxDirectClient over a fake daemon, then shapes and renders the rows.
    • Red on 0542edc, the test commit alone: the module didn't exist.
    • Green on 0896598 and a1a20e6: 3 pass.
    • After an independent review: a new test commit went red with 4 fail and 1 pass, then green on cc686da. It covers five things:
      • The row kind that redraws on open.
      • The queue keeping waiting messages.
      • Find, copy and retry/Edit using the body.
      • The group listing its lines.
      • The review found a misplaced memo comparator, so a landed message never opened. This is now fixed. The test checks four things:
      • The parsed sender, link and body, with no envelope text in the closed or open line.
      • A queued message is not in the composer queue and draws one line before and after it lands.
      • Three lines fold, and the fold opens to them.
      • A lone line stays a line.
  • bun test on chat-find (4 files), transcript-copy, gallery-coverage, transcript-newest-last and transcript-worked-fold, with the test above: 37 pass, 1 browser test skipped.
  • bun run typecheck passes.
  • Not run: the browser tests (agent-pane-suggested-tasks). Host load was 160 to 350 today and the dev server kept timing out. The offer_result path is unchanged.
  • No app build. The change is webview only, and the screenshots come from the new gallery entry agent-pane.received-messages in headless Chromium.
  • Localization: two new strings, received.group (plural, {n}) and received.show, in all 21 locales, marked needs_review outside English. The line reuses offer.received. gen-strings.mjs agentPane reports nothing missing.

Changelog

Changed: A message from another session shows as "Received message from" its sender, which opens to the message, instead of as your own prompt

Proof

Gallery agent-pane.received-messages, dark, normal width.

One messageOpened
Three in a rowFolded line opened

Before, each of these was a right-aligned user bubble holding the full envelope text.

Checklist

  • Failing test committed before the fix
  • Gallery coverage for the new components
  • Strings in every locale
  • Browser lane run (blocked by host load, see Testing)

🤖 Generated with Claude Code