cmux NEXT: a subagent's pane is named after the subagent, not its parent chat
Leo, 2026-10-30:
"subagents shouldn't be tab-named the exact same as the parent. and we dont want that subtitle text"
And, when asked which subtitle he meant (20:05Z):
"i mean the sidebar tab shouldn't just be named claude sr2 coord if you can just say it's SUbagent of sr2 coord / and yes ofc remove the second line a)"
This PR is the tab names: a subagent's pane is named after the subagent, else "Subagent of ", never the chat's bare name. The second line is #28510.
What was wrong
A subagent's pane is an agent tab on its chat's own acpmux session (AgentSubagentPanes). The tab strip and the sidebar's tab rows name an agent tab by its session (TabTitleResolver → AgentChatTabTitle), so the subagent's tab got exactly the chat's name, e.g. two "claude-sr2-coord" tabs.
What changes
- The page sends the subagent's name with
chat.subagentPane(title): its own (Subagent.name: its task, which for the Agent tool is the call's description), else "Subagent of " from the page's already-translatedsubagents.oflabel (subagentTabTitle). - The name follows what the pane shows. A pane opened on a subagent shows the chat's other subagents in place, and its "Subagent of" pill goes back to the chat. The page reports each change (
chat.subagentShown, only once it has that subagent's rows), and the tab takes that subagent's name, or the chat's again. - The app keeps it per tab (
SubagentTabTitles, CmuxNextAgentPane). It's recorded by session and subagent id when the request arrives, then bound to the tab once that tab is created. TabTitleResolver.untitledreads it before the chat's title. A name the person gives the tab still wins, becausedisplayTitleis read first. The strip and the sidebar's tab rows share that rule, so both change together.- An older page that sends no name leaves the tab as before. The
openSubagenthook keeps its signature. - A subagent tab restored after a relaunch shows its whole chat, so it's named like the chat again.
Nothing else is removed or restyled. The "Subagent of …" pill and the sidebar subtitle are unchanged here.
Tests
SubagentTabTitleTests:- the subagent's tab reads its own name while the chat keeps its own (before: identical);
- the name follows what the pane shows, and clears back on the chat;
- blank, unnamed, other-session, over-long and closed-tab cases;
- both requests decode.
webviews/test/subagent-pane-tab-title.test.ts: the request carries the name; a subagent with no name of its own gets "Subagent of ". 2 pass on cmux-ci, and lint passes.
Screenshots
Capture state scripts/cmux-next/media/states/subagents-four-panes.json (four fixture subagents opened beside a chat). Both sides carry #28213's debug open_subagent action and fixture agents count, which a showcase capture needs to open a subagent pane at all:
- before:
23db08cd511072ca368bbb397a2d302f4e67e671= basedf3ee368+ #282136e063290. - after:
e2bd98ef1e9f624fa9a8d6f02e3cb52eb4e63629= this PR9d12f819+ #28213, plus one stills-only line. #28213's debug action calls the open hook directly and so skipschat.subagentPane; the line makes it record the fixture subagent's name ("Reviewer", "Auditor", "Helper N") the way a tray click's request does. That line goes into whichever of #28213 and this PR lands second.
| Light | Dark | |
|---|---|---|
| Before: every subagent's tab ("Right c…") and sidebar row ("Agent") reads like its chat | ![]() | ![]() |
| After: sidebar rows Reviewer, Auditor, Helper 1, Helper 2; tabs Review…, Audito…, Helper, Helper | ![]() | ![]() |
Each subagent's sidebar row reads its own name (Reviewer, Auditor, Helper 1, Helper 2); the chat keeps its own row. The tab strip shows the same names, cut at this pane width. Nothing else in the window changes.
Viewed after image: yes
Visual verdict: SHIP: each subagent's row and tab carry its own name, as Leo would expect next to ChatGPT or Claude.
Not this PR: at this pane width the tab chips cut "Helper 1" and "Helper 2" to the same "Helper" (base cut "Right column" to "Right c" the same way). A tab-strip follow-up should keep a trailing number or truncate in the middle.
Agent session: agent session
🤖 Generated with Claude Code



