feat(cmux-next): Group the sidebar by status (Labs)
Group by Status for the Projects list, behind Labs (Help > Labs…, off by default). Chrome-style groups stay the default. Turn on Group Sidebar by Status in Settings > Labs, then pick Group Projects By > Status (or run "Group by Status").
Stacked on #20452 (the Labs registry); it merges after that one.
What changes
- Sections. Every computer's rows sit under Needs you, Working, Done and No agent, with a count on each header. Chrome groups dissolve in this mode only; the pinned area stays as it is.
- Live moves. Rows move between sections as their status changes. The status is the row's merged one (acpmux turn state, hooks, OSC 7501,
cmux status set), so it works the same for Claude, Codex and every ACP harness. - Stable order. Inside a section, rows keep their list order. The row you're on keeps its section while it stays active; it moves once you switch to another row, so nothing jumps under you.
- Folding. Working, Done and No agent fold and keep their counts; Needs you never folds.
- Row marks (status mode only). A status glyph on every row, a trailing ⚠ on Needs you rows (attention color, danger when it errored), and a laptop, cloud or remote glyph for where the session runs. Colors are Palette tokens, so they follow dark themes and stay apart from group colors. Rows in other modes draw exactly as before.
- Elbow children (second Labs flag, Nest Child Agent Sessions). A child agent session's row hangs off its parent row with the CLI connector
⎿, not an indent, inside the parent's section; its own status still shows on it. The link comes from each chat's acpmux session and itsmux.parenttag. Sessions from an older acpmux, or a peer's sessions, get no elbow. - No bold anywhere in the sidebar.
The two flags are read in one place (SidebarSectionsSetting.parse): with Group Sidebar by Status off, a saved status reads as no grouping, and the elbow needs both flags.
Design panel note: the judges' panel voted Chrome default 4-0 and status grouping as Labs 4-0, and dropped the elbow 0/4. The elbow is Leo's own ask, so it ships as its own Labs sub-option, off by default. Modeled on the session list in Claude Code desktop's 10-14 release (reference captures are in the private screenshots repo only).
Evidence
Each piece's behavior test failed before its fix and passed after, on the fleet (run-swift-testing-suites.sh):
| Tests | Red | Green |
|---|---|---|
SidebarStatusGroupingTests (sections, counts, live move, held active row) | e6c50f3f76ad | 5214f119d8e2 |
SidebarStatusGroupingLabsTests, SidebarGroupByStatusActionTests (flags, Settings choice, action) | a69afbf098b4 | a6c674f65b43 |
status marks test in SidebarStatusGroupingTests | 7950ca2d03a2 | ee33486cddb2 |
SidebarStatusElbowTests, SidebarAgentParentTests | 5421acc77a1a | c0fe7e9c334c |
On the head (33a4247dcccd) every suite passed. The step was marked failed only by the fleet's same-tree skip guard on two daemon suites this PR doesn't touch (AcpmuxBundleReplacedTests, AcpmuxOtherHomeDaemonTests).
Not yet established:
SidebarInsertWhileDisplayAsleepTestsfailed on two macOS 26 display hosts at earlier heads of this branch; it skips on headless hosts. This PR doesn't touch row-removal motion, and a base run on a display host is in progress to tell whether it fails on base too. I'll update here.- Light and dark stills and a clip are pending: capture-slot DEV builds currently die on the Debug watchdog (op-next-continuity is fixing it). They'll be added to this body before merge.
Pre-push checks pass on the head: crash ratchet, concurrency, god files (no type or file grew past its limit), system blue, generated settings sources.
Changelog
- Added: Group by Status for the sidebar's Projects list (Labs), with optional nesting of child agent sessions.
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Group the sidebar's Projects list by agent status behind labs.sidebarStatusGrouping (Labs, off by default; Chrome-style folder groups remain the default). Rows sit under Needs you, Working, Done and No agent headers with counts, stay in list order inside each section, and move between sections as their merged status changes; the active row keeps its section until another row is selected. Needs you never folds. Rows in this mode gain a status glyph, a trailing warning on needs-you rows, and a glyph for where the session runs.
Labs behavior
- Without
labs.sidebarStatusGrouping, a savedsidebar.groupBy: "status"reads as no grouping, and the Group by Status action points to the Labs toggle. - A second Labs flag,
labs.sidebarStatusElbow(Nest Child Agent Sessions, off by default), hangs a child agent session's row off its parent row with the⎿connector, in the parent's section; parent links come from each chat's acpmux session and itsmux.parenttag.