Skip to content

Agent pane: other agents' messages draw as cards from their sender, not your prompt - #22013

Merged
teamleaderleo merged 25 commits into
feat-cmux-nextfrom
next-xsession-msgs
Oct 20, 2026
Merged

teamleaderleo merged 25 commits into
feat-cmux-nextfrom
next-xsession-msgs

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

When another agent messages a cmux NEXT chat, the pane drew the message as if the person had typed it. That covers acpmux's own deliveries (send_to_session from #21858 and cmux agent message, which carry _meta.provenance.kind: "agent_message"), and an adopted Claude Code session (acpmux records its history with client: "adopt") showed its history's <cross-session-message from=… from-name=…>, <task-notification> and <system-reminder> prompts as raw XML.

Now:

  • A message from another agent draws as the existing message card (MessageCard's look, cv-message), turned around: sender → This agent, two lines with Show more. With acpmux provenance the sender is a chat here, so the card has Open , which opens it beside this chat (chat.offer.open, the same path a started task's row uses).
  • A Claude Code <cross-session-message> shows its from-name (else its address) and the body only. Claude Code's trailing note to the agent is dropped from the card. Opening the card shows the whole prompt as the agent got it.
  • A <task-notification> draws as one quiet tool-row line with its summary. A prompt that's only reminders, local-command caveats or prompt-submit hook text gets no row. A typed prompt behind them draws without them.
  • These text envelopes are read only from adopted history. A live prompt's text is always the person's, so a client can't pass its words off as another agent's. Only acpmux's socket-only provenance can do that (prompt_provenance.rs).
  • A row keeps the sender's words, or the cleaned prompt, as its text, so copy and the minimap don't show raw XML.
  • A message from another agent doesn't come back through ↑ prompt recall. Task results (offer_result) are excluded from it now too.

No new strings: the card reuses message.label, message.self, message.more/less and subagents.open. Nothing new is gated, since the session tools ship on by default.

Parsing is in conversation/incomingMessage.ts. direct.ts sets row.incoming on a user_message row and App.tsx draws it.

Verification

  • conversation/incomingMessage.test.ts (bun): red on 7ccd9e8 (the module didn't exist yet), green on the fix. It covers provenance with and without fromName, a person's prompt that quotes an envelope (stays the person's), an unclosed envelope, entity decoding, and the notification and hidden cases.
  • test/agent-pane-suggested-tasks.test.ts gains a "messages from other agents" block in the real pane against the stand-in daemon, with the suggested-tasks toggle off: the provenance card with Open, the cross-session card with no raw XML and the envelope reachable when opened, and the notification and reminder cases. It's a browser-lane test, so it runs in CI only. I haven't run it locally.
  • tsc --noEmit and the existing conversation/ bun tests pass. verify-local.py --affected fails only at localization, with 34k parity errors in catalogs this PR doesn't touch (same on base).
  • A correctness review subagent found four issues: a reminder before a typed prompt hid the prompt, bookkeeping-only rows left an empty focusable gap, live prompts could forge a card, and numeric entities didn't decode. All four are fixed in 3d13829, with unit and browser cases added.
  • Also: send_to_session calls from the cmux-sessions MCP server (acpmux: agents start, list, read and message other sessions (cmux-sessions MCP) #21858) draw as message cards, not raw MCP rows (agentMessages.test.ts, red on 7c2f0e9).
  • Not dogfooded in the app. A queued agent message still shows in the composer queue as an ordinary queued prompt.

Changelog

  • Changed: cmux NEXT draws another agent's message to a chat as a card from that agent, not as your own prompt, and no longer shows Claude Code's raw message envelopes.

🤖 Generated with Claude Code

teamleaderleo and others added 2 commits October 18, 2026 23:37
…prompts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A prompt acpmux delivered from another agent (agent_message provenance:
send_to_session, cmux agent message) drew as the person's own bubble, and an
adopted Claude session's <cross-session-message>, <task-notification> and
<system-reminder> prompts drew as raw XML. They now draw as a message card
from the sender (Open beside for a chat here; the raw envelope once opened),
a quiet task line, or nothing, and stay out of the prompt history.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: ade7cc05-c899-4db5-9787-a279c9a22e72

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-eibkk created for this PR by the cmux coordinator.

teamleaderleo and others added 2 commits October 18, 2026 23:49
The cmux-sessions MCP tool from #21858 drew as a raw MCP tool row; it now draws
as the SendMessage card does, to the chat it names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w for bookkeeping

Review fixes: a reminder before a typed prompt hid the prompt; it now draws
without the reminder. Bookkeeping alone gets no row instead of an empty,
focusable 34px one. Envelopes are read only from adopted Claude history
(client: adopt), so a live prompt can't pass itself off as another agent's.
Rows keep the sender's words as their text, so copy and the minimap don't
show raw XML. Numeric entities decode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 19, 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.

- vp fmt webviews/src/agent-session/acpmux/replyHref.ts
- vp fmt webviews/src/pages/markdown/README.md
- vp fmt webviews/src/pages/markdown/links.ts
- vp fmt webviews/test/markdown-cmux-app-links.test.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39212708861
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 8d37e25: 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=pr22013 -f ref=next-xsession-msgs -f platform=macos -f backend_mode=local

Unclear: web / react-apps-check (3) failed: no known signature; failed step: Test webviews. This PR merged before its CI finished: fix forward on main.

CI failed on 8d37e2558d (run 39508831122 attempt 1): 3 code, 2 unknown.

Job Verdict Why
web / react-apps-check (2) code a web test failed
web / react-apps-check (4) code a web test failed
web / react-apps-check (3) unknown no known signature; failed step: Test webviews
web / react-apps-check (1) code a Python test failed
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Failures:

  • seen on other PRs categories.test.ts every page row has exactly one home: failed (job)
  • seen on other PRs editors.test.tsx editors > every schema row renders the editor for its kind: failed (job)
  • seen on other PRs new-tab-composer-still.test.ts chromium: the default page's composer stays put in a 900px window: failed (job)
  • seen on other PRs new-tab-composer-still.test.ts webkit: the default page's composer stays put in a 900px window: failed (job)
  • seen on other PRs new-tab-composer-still.test.ts chromium: the default page's composer stays put in a 560px window: failed (job)
  • seen on other PRs new-tab-composer-still.test.ts webkit: the default page's composer stays put in a 560px window: failed (job)
  • seen on other PRs agent-pane-no-capsules.test.ts agent pane page > rounds its controls as small-radius rects, not capsules: failed (job)
  • seen on other PRs agent-pane-question-records.test.ts answered live, the card goes and the record takes its place: failed (job)
  • seen on other PRs chat-find.test.ts Find in Chat > finds command output and edit diffs inside a closed Worked for fold: failed (job)
  • seen on other PRs new-tab-warm-first-frame.test.ts chromium: Cmd-T paints its final chats and project on its first frame: failed (job)
  • ... 7 more in the job logs
Matched log lines
web / react-apps-check (2): (fail) every page row has exactly one home [1.10ms]
web / react-apps-check (4): (fail) agent pane page > rounds its controls as small-radius rects, not capsules [15.92ms]
web / react-apps-check (1): FAIL: test_coverage_base_gap_warns_on_a_pr_changing_the_gallery_format (__main__.ScopedChecksTests.test_coverage_base_gap_warns_on_a_pr_changing_the_gallery_format)

Not re-run automatically: web / react-apps-check (2), web / react-apps-check (4), web / react-apps-check (3), web / react-apps-check (1), web / react-apps-check are not machine failures.

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.

red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 2cd6ae1 to compare; do not merge until green; see lane-rules
red: web / Web status; NEW: green on the base 2cd6ae1; do not merge until green; see lane-rules
red: web / react-apps-check; no finished base run on 2cd6ae1 to compare; do not merge until green; see lane-rules
red: web / react-apps-check (1); no finished base run on 2cd6ae1 to compare; do not merge until green; see lane-rules
red: web / react-apps-check (2); no finished base run on 2cd6ae1 to compare; do not merge until green; see lane-rules
red: web / react-apps-check (3); no finished base run on 2cd6ae1 to compare; do not merge until green; see lane-rules
red: web / react-apps-check (4); no finished base run on 2cd6ae1 to compare; do not merge until green; see lane-rules

CI fast guards failed on 2c3c47fb7e (https://github.com/manaflow-ai/cmux/actions/runs/39457270393). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

…on-msgs

# Conflicts:
#	webviews/src/agent-session/acpmux/replyHref.ts
#	webviews/src/pages/markdown/links.ts
…on-msgs

# Conflicts:
#	webviews/src/agent-session/acpmux/App.tsx
@greptile-apps

greptile-apps Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes affect how messages and prompt history appear in the cmux NEXT agent pane.

Fix the sender’s Open action before merging.

Findings

  1. P1 Sender chat will not open ▶

Summary

This PR draws incoming agent messages as sender cards instead of user prompts.

  • Messages from other agents appear as cards from their sender.
  • Prompt recall skips messages and results the person did not type.
  • Messages sent with cmux-sessions tools appear as agent message cards.

Reviews (7) · Last reviewed commit: "Merge feat-cmux-next into next-xsession-..." · Reviewed by Greptile

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

The react-apps-check red ("Check diff viewer eager JS budget") is a base red. On feat-cmux-next db370d0 the markdown page measures 1,407,890 of its 1,400,000-byte budget, the same as this branch. This PR changes no markdown-page code. The other web check failures on the earlier head (settings/icons.tsx formatting, CookieImportConsentPanel.swift focus ring, syncMotion.gallery.css raw font sizes) are in base files too.

…on-msgs

# Conflicts:
#	webviews/src/agent-session/acpmux/model.ts
@cursor

cursor Bot commented Oct 19, 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.

@blacksmith-sh

This comment has been minimized.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Webview tests at head 4b38b4a, run on big-red. CI skips these because the base's markdown-page eager JS budget step fails before them.

  • CMUX_BROWSER_TESTS=1 bun test test/agent-pane-suggested-tasks.test.ts src/agent-session/acpmux/conversation/: 46 pass, 0 fail. This covers the three "messages from other agents" browser cases: the provenance card with the Open button, the adopted cross-session card with its raw envelope folded, and notifications and reminders with no raw XML.
  • bun run typecheck: no type errors in 1603 files.

Observed / Not run

Observed: the runs above. Not run: a native app dogfood. The change is webview-only.

teamleaderleo and others added 3 commits October 19, 2026 19:15
…ges and steer for incoming messages

A Claude Code prompt that is only bookkeeping keeps an empty row that draws nothing, so the
answer it brought stays its own turn instead of joining the previous prompt's. Retry on another
agent's message sends the prompt as the agent got it, sender and envelope included. A task's
result never comes back with the up arrow, whether suggested tasks show or not. Another agent's
message card shows the images it sent and a steer's read state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r prompt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@blacksmith-sh

blacksmith-sh Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Found 35 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp9y_8nlzu/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpvdfe45tm/summary-fail.json (live):/summary-fail.json (live): View Logs
bundle-map.json does not require CEF's LICENSE.txt/
bundle-map.json does not require CEF's LICENSE.txt
View Logs
bundle-map.json does not require CEF's LICENSE.txt/
bundle-map.json does not require CEF's LICENSE.txt
View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
src/pages/settings/categories.test.ts/categories.test View Logs
src/pages/settings/categories.test.ts/categories.test View Logs
src/pages/settings/editors.test.tsx/editors.test.tsx View Logs
src/pages/settings/editors.test.tsx/editors.test.tsx View Logs
test/agent-pane-no-capsules.test.ts/agent-pane-no-capsules.test View Logs

...and 25 more test failures. View all on Blacksmith: run 39457270393, run 39457270230

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

teamleaderleo and others added 2 commits October 19, 2026 19:53
# Conflicts:
#	webviews/src/agent-session/acpmux/direct.ts
…ices

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › Browser chrome icons is red on 11 of 11 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › Capability texts never say update the app is red on 11 of 11 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@cursor

cursor Bot commented Oct 20, 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.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

CI / web / react-apps-check (3) is red on 9 of 15 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › Checks job structure is red on 10 of 11 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › Main-thread concurrency is red on 10 of 11 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

CI / web / react-apps-check (2) is red on 8 of 12 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

CI / web / react-apps-check (4) is red on 8 of 12 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › No process scanning (holders register themselves, plans/cmux-next/pty-holder.md 4) is red on 9 of 11 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

CI / web / react-apps-check (1) is red on 9 of 14 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › Package conventions lint is red on 11 of 11 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › Phone lane field allowlist is red on 10 of 10 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

turns.ts keeps the hidden-bookkeeping skip and passes the base's
sessionStatus; direct.ts imports both incomingPrompt and
startedCardsShown; model.ts keeps the incoming/resend/untyped fields and
the base's started field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue
@teamleaderleo
teamleaderleo merged commit 793e1c0 into feat-cmux-next Oct 20, 2026
@teamleaderleo
teamleaderleo deleted the next-xsession-msgs branch October 20, 2026 22:32
teamleaderleo added a commit that referenced this pull request Oct 21, 2026
…reply

Hunk by hunk: incomingPrompt keeps #22013's acp: sender id and rendered
body and adds this branch's msgId/threadId; the card takes both the sent
images and Reply; App passes images, steer and onReply; direct.ts takes
#22013's row (hidden bookkeeping kept, untyped); conversation.css keeps
both the Reply and steer rules; the gallery entry is #22013's plus a
reply variant; Localizable.xcstrings is #22013's file plus the four
message.reply* keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue
teamleaderleo added a commit that referenced this pull request Oct 21, 2026
…ext-incoming-reply

direct.ts keeps the reply's IncomingMessage import and prompt_accepted
handler next to the base's startedCardsShown and harnesses_changed start
mode refresh; Localizable.xcstrings is #22013's file plus the four
message.reply* keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue
teamleaderleo added a commit that referenced this pull request Oct 21, 2026
The base's incoming message files are #22013's squash unchanged, so each
conflict keeps this branch's Reply edit of those lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue
teamleaderleo added a commit that referenced this pull request Oct 21, 2026
…card fields

#22013 opens and answers only a chat's cmux address (acp:<id>) and the
card now carries the message's msgId and threadId, so the fixtures send
from acp:child-3 and the incomingPrompt expectations include both ids.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

teamleaderleo added a commit that referenced this pull request Oct 21, 2026
* Agent pane: test that other agents' messages draw as theirs, not raw prompts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Agent pane: other agents' messages draw as cards from their sender

A prompt acpmux delivered from another agent (agent_message provenance:
send_to_session, cmux agent message) drew as the person's own bubble, and an
adopted Claude session's <cross-session-message>, <task-notification> and
<system-reminder> prompts drew as raw XML. They now draw as a message card
from the sender (Open beside for a chat here; the raw envelope once opened),
a quiet task line, or nothing, and stay out of the prompt history.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Agent pane: test that send_to_session calls draw as message cards

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Agent pane: send_to_session calls draw as message cards

The cmux-sessions MCP tool from #21858 drew as a raw MCP tool row; it now draws
as the SendMessage card does, to the chat it names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Agent pane: read Claude Code envelopes only in adopted history; no row for bookkeeping

Review fixes: a reminder before a typed prompt hid the prompt; it now draws
without the reminder. Bookkeeping alone gets no row instead of an empty,
focusable 34px one. Envelopes are read only from adopted Claude history
(client: adopt), so a live prompt can't pass itself off as another agent's.
Rows keep the sender's words as their text, so copy and the minimap don't
show raw XML. Numeric entities decode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(next): PR autofix at 3d13829

- vp fmt webviews/src/agent-session/acpmux/replyHref.ts
- vp fmt webviews/src/pages/markdown/README.md
- vp fmt webviews/src/pages/markdown/links.ts
- vp fmt webviews/test/markdown-cmux-app-links.test.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39212708861

* Agent pane: Reply in place on another agent's message card

An incoming agent message card (IncomingMessageCard, cx-eibkk) gets a Reply
action (button, or R with the card focused). The answer goes to the sending
chat as send_to_session sends a message: a session/prompt to that chat,
attached hidden, with an agent_message provenance naming this chat, the
message's threadId and replyTo the message, so it lands in the sender's chat
as a threaded reply.

acpmux took provenance only over the unix socket. The app pane (LocalApp)
may now send one only as a reply: replyTo set, from another chat of this
daemon, to the prompt's chat. Web and peers are still refused. The pane
relay allows `provenance` in session/prompt's _meta.acpmux.

Follow-up to cx-eibkk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* acpmux: let the app pane's reply past the origin guard, only for a received message

The remote guard refused any provenance from LocalApp before the reply rule
ran. It now leaves LocalApp to prompt_provenance, and Hub::app_reply_fits
requires the replying chat's log to hold the agent message (`replyTo`) the
target chat sent it. The shared pane policy lists `provenance` as the Swift
table does. A `cmux agent message` sender (`acp:<id>`) is answered by its id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* acpmux: move the app reply check out of requests.rs (god-file budget); rustfmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Agent pane: a reminder-only prompt keeps its turn; Retry, recall, images and steer for incoming messages

A Claude Code prompt that is only bookkeeping keeps an empty row that draws nothing, so the
answer it brought stays its own turn instead of joining the previous prompt's. Retry on another
agent's message sends the prompt as the agent got it, sender and envelope included. A task's
result never comes back with the up arrow, whether suggested tasks show or not. Another agent's
message card shows the images it sent and a steer's read state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Agent pane: test that a reminder's turn offers no Retry of the earlier prompt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Agent pane: gallery entry for the incoming message card and its Reply

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(next): PR autofix at c426d09

- webviews/src/agent-session/acpmux/conversation/IncomingMessageCard.tsx

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39359952105

* Agent pane: gallery entry for messages from other agents and task notices

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix agent message cards: open by session id, show the sender words

A message cmux delivers to an acpmux chat carries the sender address as
provenance from: acp:<session id> for a chat, term_... for a terminal
agent, cli for a person at a shell. The card used it verbatim as the chat
to open, so Open asked the host for acp:<id>. Strip acp: for the session
id, and give no Open for any other address.

The prompt text is cmux rendered message (agent_message_prompt.rs
render): a header, a delivery note, ---, the body, and a closing line
naming the message id. The card now shows the body, read only when the
whole render matches and the closing line names provenance msgId, and
keeps the full render as raw. Any other text shows whole.

A task notification turn no longer offers Retry, which resent the
notification XML as the person prompt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(agent-pane): the reply tests follow #22013's sender address and card fields

#22013 opens and answers only a chat's cmux address (acp:<id>) and the
card now carries the message's msgId and threadId, so the fixtures send
from acp:child-3 and the incomingPrompt expectations include both ids.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue

* test(acpmux): an app pane reply signs only as a chat the pane shows, in its thread, under its name (red)

The app pane's reply in place (Origin::LocalApp) is refused unless its
from chat is one this connection shows (attached and not held unseen),
its threadId is the answered message's thread, and its fromName is that
chat's title, name or id. Today app_reply_fits checks only that from got
the message, so the pane could sign as any chat that did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue

* fix(acpmux): an app pane reply signs only as a chat the pane shows, in its thread, under its name

Hub::app_reply_fits is default deny for what the app pane signs: from
must be a chat this connection shows (attached, not held unseen), the
reply's threadId must be the answered message's thread (its threadId,
else its msgId), and a fromName must be the chat's own title, name or id
as the pane writes one. Before, any chat that got the message could be
named as the sender under any name and thread.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue

* style(acpmux): rustfmt the app reply check

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=c1a6da4a-9c34-4cea-864c-8b045b51ac46&host=huge-blue

* Agent pane: Reply on the received-message line uses the type tokens; the catalog keeps base key order

Follows the adoption review:
- The Reply key hint and its sent/failed note use --text-caption and
  --text-detail instead of literal font sizes (check-type-scale).
- The App.tsx props are one per line (oxfmt).
- Localizable.xcstrings is base plus the four message.repl* keys, in base
  order, instead of a reordered rewrite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Agent pane: Reply's test opens it with its button, not the removed R key; the sent note wraps

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* agent pane: keep the strings catalog in base order; add only the four Reply strings

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* agent pane: tool output under a message keeps base margins; the reply editor lines up with the body

The base merge swapped the two margins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* acpmux, agent pane: a reply in place arrives as a cmux agent message, linked back and signed by acpmux

The pane sends from and to as acp:<id> addresses, as cmux agent message does, so the
sender chat links the reply and can answer it; acpmux refuses a bare id. The text is
wrapped as cmux renders a message (sender, id, the message it answers, the not-your-
operator note). acpmux signs fromName with the replying chat own name instead of
matching the pane one, so a stale title is never refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* agent pane: closing a message closes its reply and keeps the draft; reply state survives scrolling

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant