Skip to content

Sidebar: show the most urgent pane's status when panes share an agent key - #15260

Merged
teamleaderleo merged 2 commits into
mainfrom
feat/sidebar-row-aggregate-model
Sep 28, 2026
Merged

teamleaderleo merged 2 commits into
mainfrom
feat/sidebar-row-aggregate-model

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

What the sidebar row means today

A workspace row stands for the whole workspace. On current main, here is what each part of the row reflects when the workspace holds several panes (terminal, agent, browser, splits):

Row part Source today
Selection fill The selected workspace only. Pane focus inside it does not change the fill, and hover never changes it (#14941).
Title The focused pane's title, unless the workspace has a custom title.
Branch, directory, PR lines Union of all panes, de-duplicated, in spatial order.
Spinner Any pane with a running agent.
Agent status lines (claude_code, codex, ...) One entry per agent key, last writer wins across panes.
Unread badge Sum over all panes. Selecting the workspace clears only the focused pane's notifications, so a badge that stays means another pane is still unread.
Notification subtitle Latest notification in the workspace.
Which pane is focused Inside the workspace: unfocused splits are dimmed (unfocused-split-*), and a pane with unread output gets the unread ring. The row never shows focus.

The confusing case was the status line. Two panes running Claude share the claude_code key. If pane A says "Needs input" and pane B then reports "Running", the row shows "Running" and hides the pane that is waiting on you.

The model this PR sets

The row is an aggregate of the workspace, and the most urgent pane wins. The focused pane is shown inside the workspace, not on the row.

  • Each pane keeps its own last-reported entry for an agent key. For each key, the row shows the entry from the live pane that still owns the agent (lifecycle state or agent PID) and most needs you: needs input, then running, then unknown, then idle. The newest report breaks ties.
  • A pane's copy is dropped when its lifecycle for the key ends, when the pane closes, or when the key is cleared, so old text never comes back. A pane moved to another workspace takes its own entry along.
  • Among status lines with the same reporter priority, a key with a pane that needs input sorts first. Explicit --priority still wins.
  • Clearing a key still drops it for the whole workspace, as before. Claude holds one agent PID per workspace, so keeping pane B's line after pane A's session ends would need a per-pane PID model. That is out of scope here.

The title still follows the focused pane, and the badge still counts every pane. Both fit "aggregate, focus shown in-pane". Pointing the row at the source pane (for example "needs input: pane 2" in the tooltip) is a follow-up. That rendering belongs with the compact status glyph work in #14838 and #15238, which already resolves glyph precedence as a workspace aggregate (error > needs input > running > ...), so this PR leaves the row cell alone.

Dogfood

Tested on a fleet mini, release 0.64.19 against this PR's CI-built app. Two panes share claude_code: pane A reports Needs input, then pane B reports Running.

Before After
before after

Coordination

This PR changes only the model layer: Workspace status storage and ordering, and ControlSidebarPanelOwner. It stays out of files owned by other work:

Tests

WorkspaceSidebarObservationTests covers two cases:

  • Two panes share claude_code, and pane B holds the PID. A later Running from pane B does not hide pane A's Needs input. Once pane A's lifecycle ends, its old text does not linger.
  • A needs-input key sorts ahead of a newer entry of equal priority.

Companion: the agent focus-stealing fix (linked once open).

🤖 Generated with Claude Code

… key

The workspace row aggregates every pane, but agent status text was stored
once per key with the last writer winning. Two panes running Claude share
`claude_code`, so a pane reporting Running hid the other pane's Needs input,
and ending one pane's session cleared the status the other pane still owned.

Each pane now keeps its own last-reported entry for the key. The row shows
the entry of the live pane that owns the agent and most needs the person
(needs input, then running, then unknown, then idle; newest breaks ties),
and clearing one pane falls back to the pane that remains. Status lines of
equal priority sort a needs-input key first.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Sep 28, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 8 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 173e771d-f3eb-45f0-af06-47dc58271d19

📥 Commits

Reviewing files that changed from the base of the PR and between 71a921c and 361ae0c.

📒 Files selected for processing (6)
  • Sources/ControlSidebarPanelOwner.swift
  • Sources/Workspace+AgentLifecycle.swift
  • Sources/Workspace+PanelLifecycle.swift
  • Sources/Workspace+SidebarStatusVisibility.swift
  • Sources/Workspace.swift
  • cmuxTests/WorkspaceSidebarObservationTests.swift

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.

@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Dogfood build of 361ae0c6a1c451734d9b5eab08845a47701bbe15

cmux DEV pr-15260-361ae0c6.app

The link opens this exact commit in the cmux dev menu bar app. The build starts on each push and the page waits until it is ready; a newer push replaces it. It signs in against production, so Cloud or backend changes still need a tagged build with a development backend.

…nds and pane moves

Review follow-up. Every removal of an agent status key now also drops each
pane's copy, a pane's copy is dropped when its lifecycle for the key ends,
and moving a pane carries its own entry instead of whichever pane wrote the
workspace entry last. Clearing a key no longer tries to fall back to another
pane: Claude holds one PID per workspace, so that fallback could not hold on
its real SessionEnd path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

CI failure attribution

CI passes on 361ae0c6a1 (run 36401436329 attempt 2).

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.

@teamleaderleo

teamleaderleo commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator Author

Cross-model review (Codex gpt-5.6-sol)

  • Sources/Workspace+SidebarStatusVisibility.swift:44-46 (callers include FeedCoordinator.swift:749): clearStatusEntry(key:panelId:) ignores panelId and calls removeStatusEntry(forKey:), deleting the global entry and every pane-scoped copy. When two panes share claude_code and one ends, clearing that pane erases the still-running pane’s status until it emits another update, so the sidebar loses its urgent/running row. Remove only the specified pane’s copy when panelId is non-nil, and reserve the global removal for workspace-wide clears.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Dogfood (fleet mini, driven over the socket). Scenario: a workspace with two terminal panes.

  1. Pane B holds the claude_code agent PID, the way the pane that started Claude last does.
  2. Pane A reports Needs input (lifecycle needsInput).
  3. One second later, pane B reports Running (lifecycle running).
Release 0.64.19 (before) This PR head 361ae0c (CI-built app)
list_status claude_code=Running claude_code=Needs input
Row before after

Before, the row says Running, and nothing shows that the left pane is waiting on you. After, the row shows the waiting pane. Pane A then reports Running (its question was answered), and the row goes back to claude_code=Running with no stale Needs input.

Not covered here: the pane-move path. The unit tests and the review follow-up (361ae0c) cover it.

@teamleaderleo
teamleaderleo merged commit 3fd61eb into main Sep 28, 2026
99 of 103 checks passed
@teamleaderleo
teamleaderleo deleted the feat/sidebar-row-aggregate-model branch September 28, 2026 11:58
@github-actions

Copy link
Copy Markdown
Contributor

Merge receipt for 361ae0c6a1: every check was green at merge (16 verified; 16 skipped by policy). Full suite runs on main after merge.

rustybret pushed a commit to rustybret/bmux that referenced this pull request Sep 28, 2026
ee20686 fix: keep SSH exit prompt off PTY output drain (manaflow-ai#15337)
96e7a27 reload.sh: expand the empty resolver args safely under bash 3.2 (manaflow-ai#15352)
558d6b9 ci: move owned gui jobs to Blacksmith only when its queue is shorter (manaflow-ai#15336)
fff0b82 UI fuzzer: seeded action sequences, oracles, minimized repros and deduplicated issues (manaflow-ai#15297)
94a6387 Add an agent activity mode to workspace auto-reordering (manaflow-ai#15216)
e5231be CI: post screenshots and a GIF of each app PR's build in its dogfood comment (manaflow-ai#15280)
16f1270 cli: answer queued agent hooks inside the agent's hook timeout (manaflow-ai#14834)
3fd61eb Sidebar: show the most urgent pane's status when panes share an agent key (manaflow-ai#15260)
0975d0b Release discarded CodeRouter response bodies after retry (manaflow-ai#15253)
42f93d4 Re-verify the session against a body-supplied VM billing team (manaflow-ai#15339)
bdb6920 Keep the mail broker from orphaning a reply to an unknown parent (manaflow-ai#15330)

# Conflicts:
#	.github/workflows/ci-guards.yml
#	.github/workflows/ci-macos.yml
#	.github/workflows/test-e2e.yml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant