Agent pane: a message going out reads "Sending message to <target>" (acpmux send parser, live line, Background tasks)
Leo, 2026-10-24, word for word, looking at plain Bash rows (Ran acpmux "… and Running sed -i '' 's/This rule is…' 30s):
"These will be able to render as, like, I mean, not necessarily full renders of whatever, but, like, you know, sending message or sent message to X or Y instead of this thing, right? We're working on that?"
This is the first of two PRs. This one reads a shell acpmux send from its command line and names it on the turn's live line (the Running … 30s line in Leo's screenshot) and in Background tasks. The second PR (stacked on #24977 and this one) draws the transcript row itself, "Sent message to X" plus the first line, which expands to the Markdown and the raw command.
Leo, 2026-10-25, word for word, on a compound Bash call with an acpmux send in it that drew as a plain Bash row:
"Likewise in these situations, okay, I did see your message and whatnot, but like when you send messages in, I feel like, you know, those should be, like, rendered properly. You know, like, sent message to whatever"
What changes
acpmuxSends.tsreads a command line the way a shell does. It handles single and double quotes,$'…', backslashes, here-documents (<<'EOF',<<-) and here-strings,$(…)and backticks kept whole, comments, and; && || | &. It sees through these wrappers:reach HOST '…'(the target then readsHOST/name),bash -lc '…',timeout N,env X=Y,X=Y,cd dir &&,perl -e 'alarm N; exec @ARGV',nohup,nice,command,exec, andcmux acp send. Options followacpmux send --help, so--status IDand--helpsend nothing. The text counts as unknown when it comes from stdin the line doesn't contain, or when it contains an expansion. Targets are the word as given (name,host/name,host:name,reports:person). There is no list of names. Only a command in command position counts:echo "acpmux send x y",grep 'acpmux send'andacpmux lsare not sends. A send anywhere in a compound command (;,&&,||, a pipeline, a subshell, a heredoc or file on stdin) is still a send: the parser counts the other commands that do work (others, e.g.git push && acpmux send …is one more; so is a redirect that writes a file or a substitution that does more than read), so the row can say "and N more commands" instead of hiding them. Two sends, a send inside a substitution, an unclosed quote, or anexitbefore the send are not a send row.cd,export, anecho,|| true,2>&1,>/dev/nulland filters on the send's own output that read and write no file (| tail -1,| jq -r .text; not| tee outor| sed …) don't count as other work. An optionacpmux send --helpdoesn't list means no send;acpmux --json send …is one.- The live line for a send in flight reads "Sending message to " instead of
Running acpmux send --no-wait coord-deputy '…'. That covers a shell send and a cmux-subsessionssend_message, which shows the sub-session's name once the session list has it. This works in both the Codex-style line (Thinking.tsx) and the todo-list activity line. - Session Info's Background tasks and the running tray name a background send "Sending message to X", "Sent message to X" or "Couldn't send to X".
Before / after
Gallery agent-pane.sending-line shell (synthetic data), a turn whose in-flight call is acpmux send coord-deputy '…':
| Before | After | |
|---|---|---|
| Live line, dark | ![]() | ![]() |
| Live line, light | ![]() | ![]() |
Risk
Small and contained. Only the webview's labels change. There are no protocol, daemon or native changes. A command the parser can't read as exactly one send keeps its current label. The parser is a single pass over the command text (O(length)). It runs only for a call whose line contains acp, once per live-line derivation, and never per transcript row. It adds no timers, observers or animation loops.
Tests
acpmuxSends.test.tscovers every wrapper above, quoting (single, double with escapes,$'…', backslashes, spliced apostrophes, newlines in quotes), here-documents (quoted, unquoted with an expansion,<<-), a here-string, pipedechoandcat <<EOF |, options before, between and after the words,--statusand--help, the target forms, and the non-matches:acpmux ls,echo "acpmux send x y",grep 'acpmux send', a heredoc body that mentions it, a second send (also inside a substitution), other work around it, file-writing redirects, substitutions that run more than readers, filters that read or write files, an unknown option, and a perl script that only mentionsexec @ARGV. A 5000-step pipeline after the send parses in one pass. Compound commands: a send aftercd && git fetchand before areach, one in a subshell with|| echo,--from/--no-waitwith a file on stdin (target only) and with a heredoc aftergit push, andacpmux ls; echo acpmux send(no send). It also checks the call's state (running, sent, failed on a non-zero exit) and the Background tasks label.- Gallery
agent-pane.sending-line:shell,reachandsubsession. The fixtures use the exact event shapes Claude Code recorded through acpmux (Bashexecutecalls, the command cut to its title, a description), with made-up names and messages.
Agent session: cosmic-gray
🤖 Generated with Claude Code



