Repository navigation
cmux NEXT: a subagent's pane is named after the subagent, not its parent chat - #28497
Conversation
…ent chat Leo, 2026-10-30: "subagents shouldn't be tab-named the exact same as the parent." A subagent's pane is an agent tab on its chat's own acpmux session, so the tab strip and the sidebar's tab rows, which name an agent tab by its session (TabTitleResolver -> AgentChatTabTitle), named it exactly like the chat. The page now sends the subagent's own name with chat.subagentPane (Subagent.name: its task, the Agent tool's description), and the app keeps it per tab (SubagentTabTitles: recorded by session and subagent when the request arrives, bound to the tab once it is created). The title rule reads it before the chat's title, after any name the person gave the tab. No name (an older page, a workflow agent) leaves the tab as before. The openSubagent hook keeps its signature. A restored subagent tab after a relaunch shows its chat in full, so it is named like the chat again. Tests: SubagentTabTitleTests (the subagent's tab reads its own name while the chat keeps its own; blank, unnamed, other-session, over-long and closed-tab cases; the request decodes with and without `title`) and webviews/test/subagent-pane-tab-title.test.ts (the request carries it). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0c8df2029ad2a028c4e7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0c8df2029ad2a028c4e7
|
Review (codex gpt-6-astra high, router-review): BLOCK at 995299f BLOCK Visual verdict: BLOCK — no after screenshots were supplied, so the required visual review cannot be completed.
Tests could not run: this Linux box has neither Bun nor Swift installed. |
…nt of" the chat when it has no name - SubagentTabTitles.swift: `public import Observation`. A public @observable class needs it under InternalImportsByDefault (the fleet compile of the stills build failed there). - Review of #28497 at 995299f (router-review, P2): a subagent pane shows the chat's other subagents in place, and its "Subagent of" pill goes back to the chat, but the tab kept the name it got at open. The page now sends chat.subagentShown {subagent?, title?} whenever the pane it opened on a subagent shows another one, or the chat again (only after its first subagent has shown, so the open-time name never flashes away). The app sets or clears the tab's name (header hook showsSubagent -> SubagentTabTitles.show). - Leo, 2026-10-30: "the sidebar tab shouldn't just be named claude sr2 coord if you can just say it's SUbagent of sr2 coord". A subagent with no name of its own (only its id) is named "Subagent of <chat>", from the page's already-translated subagents.of label (subagentTabTitle). The tab strip and the sidebar's tab rows both read it. Tests: SubagentTabTitleTests (the name follows what the pane shows; the request decodes) and webviews/test/subagent-pane-tab-title.test.ts (own name, else "Subagent of" the chat). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0c8df2029ad2a028c4e7
…t subagent's rows A pane's page loads its subagent's rows after it opens (and a showcase fixture's rows live only in the chat's page): until then it would report the "Subagent of" fallback over the name the chat's page gave the tab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0c8df2029ad2a028c4e7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0c8df2029ad2a028c4e7
|
Review (codex gpt-6-astra high, router-review): BLOCK at c4a360b BLOCK Visual verdict: BLOCK — no after screenshot is available (
|
…he page's method list Fleet build of the #28497 stills (ae1c050) failed: AgentPaneModel.respond's switch over AgentPaneRequest was not exhaustive without .subagentShown. It joins the header requests (respondToHeader) and the passive ones that do not mark the pane as touched by the person. AgentPageProvider.methods also lists chat.subagentShown, or the page's report would never reach the pane. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0c8df2029ad2a028c4e7
|
Review (codex gpt-6-astra high, router-review): BLOCK at 9d12f81 BLOCK Visual verdict: BLOCK — no after screenshot was provided (
|
|
Visual verdict (Claude Opus 5.5, independent, opened the after stills): SHIP at 9d12f81 — the four subagent rows and tabs now carry their own names (Reviewer, Auditor, Helper 1, Helper 2) where before every one read the chat's ("Agent" rows, "Right c…" tabs), and nothing else in the window changes. One follow-up, not this PR's: at this pane width the tab chips clip, so "Helper 1" and "Helper 2" both read "Helper" in the tab bar (the sidebar shows them in full). The same clipping cut "Right column" to "Right c" before. Worth a tab-bar follow-up (middle truncation, or keeping the trailing number), since two equal-looking tabs is what Leo complained about. Fleet stills, state
|
….session is optional) Fleet compile-check of #28497 at 9d12f81: CmuxNextAppTests failed on passing ref.session (String?) where String is needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0c8df2029ad2a028c4e7
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Gallery before/after for
States
Pick other states with a Passes: CI passes on CI passes on Written by web and size checks: green Shipped in:
|
|
Review (codex, router-review): SHIP at dfa690a SHIP Visual verdict: SHIP — viewed both after screenshots; no visual regressions.
|




Leo, 2026-10-30:
And, when asked which subtitle he meant (20:05Z):
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
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).chat.subagentShown, only once it has that subagent's rows), and the tab takes that subagent's name, or the chat's again.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.openSubagenthook keeps its signature.Nothing else is removed or restyled. The "Subagent of …" pill and the sidebar subtitle are unchanged here.
Tests
SubagentTabTitleTests: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 debugopen_subagentaction and fixtureagentscount, which a showcase capture needs to open a subagent pane at all:23db08cd511072ca368bbb397a2d302f4e67e671= basedf3ee368+ debug(next): the subagents fixture can start more than two subagents (agents), plus capture states #282136e063290.e2bd98ef1e9f624fa9a8d6f02e3cb52eb4e63629= this PR9d12f819+ debug(next): the subagents fixture can start more than two subagents (agents), plus capture states #28213, plus one stills-only line. debug(next): the subagents fixture can start more than two subagents (agents), plus capture states #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 debug(next): the subagents fixture can start more than two subagents (agents), plus capture states #28213 and this PR lands second.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