cmux NEXT sidebar: group by status, ported onto the Priority state (Debug toggle, off)

Merged
TE
15d ago
+523-31

The sidebar's computer sections can be grouped by agent status, behind the Debug toggle Group by status (sidebar.groupByStatus), which is off by default. Turn it on in Debug Settings > Sidebar (palette: Open Debug Settings). With the toggle off, the sidebar lays out exactly as before.

Leo, 2026-10-21: "#20905: adopt it rather than building a second auto-sections. Keep it behind the Debug toggle, off by default, then bring it current, get a review and land it."

This PR is now ported onto current feat-cmux-next. Since #20905 was first written, base gained the Priority state (AgentPriorityRanking), the session tree, S1/S3 row status, the Done fold (#23633) and Show more (#23671). The port builds on those instead of carrying its own copies.

What changes

  • Sections. Each computer's workspaces sit under one header per Priority state. The sections are, in Priority's tier order: Needs you, Done, Failed, CI failing, Working, Idle.
    • The state is the row's agentChip (AgentPriorityRanking.state and .tier). A row with no chip falls back to Working or Idle.
    • Headers reuse the Priority view's strings, so the string catalog is unchanged.
    • Each header shows a count.
  • Stable order. Inside a section, rows keep their manual order.
    • The active row keeps its section until another row becomes active, so nothing jumps under you.
    • A plain click doesn't relayout ("a click moves no row", #22960), so a released row moves at the next relayout.
  • Folding. Each header folds and keeps its count, except Needs you, which never folds.
    • Turning the toggle off forgets the held row and the folds.
  • Locked while grouped. Drag reorder is locked while the list is grouped, as it already is under Group by Folder.
  • No Done fold or Show more inside status sections. A Done workspace shows under its own state. A status section lists every row even when sidebar.groupRowLimit is set.
  • Dropped from the original #20905:
    • its own status classifier (SidebarStatusBucket): the Priority state replaces it;
    • the row status marks: S1/S3 already draw row status;
    • the agent-parent elbow and its toggle (sidebar.statusElbow): the session tree replaces it;
    • the Package.swift and ci-target-graph.json edits.
  • Supporting changes.
    • Group by Folder's bucketing moved to SidebarLayout+Folder.swift.
    • Both god files shrink: SidebarLayout.swift goes from 461 to 459 lines, and SidebarModel.swift stays at 565.

No capture: the change is behind a Debug toggle that is off by default, and with it off nothing draws differently. Stills will go on #16541 once someone dogfoods it.

Evidence

  • SidebarStatusGroupingTests (8 cases) drives a real SidebarView and reads the drawn rows and header labels. It covers:
    • tier and manual order;
    • toggle off giving the old list, with reorder unlocked;
    • a row moving when its state changes, while the active row waits;
    • folding, and Needs you never folding;
    • toggle off clearing the folds and the held row;
    • Done staying under its state;
    • no Show more row at a row limit of 10 with 14 rows;
    • the classifier end to end.
  • Red: the test commit 05389f2 alone doesn't compile, because it calls the new toggle and types. Green: the port.
  • The fleet compile-check --app passed at 31d66cd and again at 55cf9cc, which only disambiguates SidebarSection in the test. The focused suite run had not reported when this merged; a red there would be fixed forward.
  • prepush-gate.py reports no new violations.

Observed / Not run

Observed: the fleet compile at the head, the pre-push gate, and an independent review (receipt in the comments). Not run: a confirmed focused suite result, a capture, and a live dogfood of the toggle in a DEV build.

Takes back #23671: not a take-back. The .showMore cases that S5 added to row-key switches gain a .status case beside them, and Show more's behavior is unchanged.
Takes back #23633: not a take-back. The .doneFold cases that S4 added to row-key switches gain a .status case beside them, and the Done fold's behavior outside status sections is unchanged.

Changelog

none (behind a Debug toggle, off by default)

Agent session: cosmic-gray

🤖 Generated with Claude Code