cmux NEXT sidebar: rows keep their places in the session tree, with a stable/attention toggle

Draft
TE
7d ago
+34410-27774

FYI @lawrencecchen: this is in your sidebar area. It stays behind sidebar.sessionTree (off by default) and lands under Leo's merge directive; no action needed.

Stacked on manaflow-ai/cmux#21836 (deep tree), which is stacked on #21814 (sidebar.sessionTree, off by default). PR 2 of 3 for the design Leo approved in manaflow-ai/cmux-design-references#3.

Leo: the sidebar "keeps reordering sessions as they flip between in progress and not in progress", "simultaneously noisy AND low signal". He also wants the moving order kept as an option.

What changes with the tree on.

  • An agent's state no longer moves a row. The priority projection (SidebarRows) and a notification's move to the top (NotificationCenterService.moveToTop) both stand down. The row shows its state in place, on its glyph.
  • A row still moves when you drag it, create it or close it.
  • Without the tree, nothing changes: notifications.attention.moveToTop decides as before.

The toggle.

  • New setting sidebar.rowOrder, shown as "Session Tree Order" in Settings → Appearance → Sidebar. It has two choices: Keep Rows in Place (stable, the default) and Move Sessions That Need You (attention, today's behavior).
  • The sidebar menu's Options adds two items, Keep Rows in Place and Move Sessions That Need You to Top. Each sets the order for one window only (SidebarModel.rowOrder).
  • SidebarRowOrderMemory saves each window's choice in UserDefaults by window id, so it survives a relaunch. A window that never chose follows the setting.
  • Both menu items hide while the tree is off.
  • Both notification paths read the same rule: SidebarSectionsPreferences.movesRowsOnAttention(_:window:).

Size budgets.

  • CmuxNextApp shrinks by 4 lines: the Group by and Density actions now share one settings-write helper.
  • SidebarBridge and SidebarModel don't grow: the window restore rides an existing line, and a doc comment was tightened.
  • check-app-size --base and check-no-godfiles --base pass.

Strings. Six new keys (two menu titles, setting title, help and two choices), translated in all 21 locales. webviews/.../settings/generated/strings.json and the settings schema exports come from the Swift export; CI's generated-files job writes them, as on #21814.

Tests

Tests/CmuxNextAppTests/SidebarStableOrderTests.swift:

  • Fifty workspaces in a four-level tree get 500 state changes (waiting, error, working, finished, unread), half as in-place patches and half as full shows through SidebarRows. The drawn order never changes.
  • The red commit 787dec17 expects zero moves against the old default projection.
  • A window that chose attention still moves rows.
  • The decision table covers: tree off, tree on, the setting, a window's choice winning, and moveToTop off.
  • A window's choice survives a relaunch and doesn't leak to another window.

Not verified locally. No Swift toolchain on this Linux lane. The Linux-pool dev build cannot be submitted from this host (outside the tailnet), so CI is the first compile. Passed locally:

  • check-app-size --base, check-no-godfiles --base
  • check-concurrency, check-crash-safety, check-module-resources
  • lint-ios-package-conventions
  • check-l10n: no errors from the new keys

Review and known limits

  • Fixed: public import CmuxNextDesign where public API names SidebarRowOrder.
  • Fixed: the launch window restores and saves its row order under the saved id it adopts.
  • Still needed: generated files for the new setting and actions, which need a Mac test run with CMUX_UPDATE_ACTION_SURFACES=1 CMUX_UPDATE_MDM_SCHEMA=1. These are schemas/settings/*, docs/mdm/*, plans/cmux-next/action-surfaces.json and actions.md. The generated-files job or a Mac lane must regenerate them; this Linux lane can't.
  • Limit: changing Session Tree Order in Settings re-sorts on the next live update, while the sidebar menu re-sorts at once.
  • Follow-up: saved per-window choices and folds aren't pruned when windows or workspaces go away.
  • The order actions live in SidebarDensityActions, and SidebarGroupByActions is untouched (group code belongs to another lane).

Changelog

Added: With the Session Tree setting on, sidebar rows keep their places while agents work. Session Tree Order in Settings, or the sidebar menu for one window, moves sessions that need you to the top instead.

šŸ¤– Generated with Claude Code