cmux NEXT sidebar: the session tree's needs-you tray

Closed
TE
10d ago
+3227-47

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.

Status: in progress. Adopted by stack-lander (2026-10-21) and rebuilt: its own 6 commits are cherry-picked onto #21836's head (d51b2ae), so this PR now stacks on #21836 alone. The stable-order PR (#21944) is dropped: base went manual-order-only in #22907 and #22912, so nothing re-sorts rows any more. When #21836 squash-merges, this branch gets rebased onto feat-cmux-next, compiled on CI, captured, reviewed and merged.

Stacked on manaflow-ai/cmux#21836 (deep tree). Part of the design Leo approved in manaflow-ai/cmux-design-references#3.

Leo: the sidebar "still doesn't surface what actually needs him".

With sidebar.sessionTree on, a tray docked at the bottom of the list shows only what's blocked on you.

What enters the tray.

  • Blocked: a question, a permission or a sign-in waiting (acpmux's input lane, or a hook's waiting).
  • Failed: a failed or lost agent.
  • Running, idle and merely unread sessions never enter the list. A coordinator waiting on its own children isn't waiting on you.
  • Finished sessions you haven't read get one quiet line: "7 finished, unread". Clicking it goes to the first of them.

What an item shows.

  • Up to three items, each with its title, why it waits ("Question", "Approve", "Sign In", "Waiting", "Failed") and the path of sessions that started it ("Release week › Settings pass").
  • Items come in the tree's drawn order, so the tray doesn't reshuffle either. Anything beyond three shows as "+N more".
  • A folded parent never hides an item. Clicking one opens every fold above it (SidebarSessionTree.reveal) and selects the row.

Rows never move. The tray floats over the list's bottom, and the list's scroll range grows by the tray's height. Rows stay put when the tray appears, grows or empties. This differs from the mock, which put the tray at the top: there, every change in its height would push the whole list down.

When it updates. On every structural change, every in-place row patch (it chains the list's onRowsPatched) and every tree pass. A drag moves rows, never the tray.

Data. SidebarNeedsYou.make is the one place that decides. It reuses SidebarAgentState.of from #21836, so the tray, the roll-up chips and the strict rule agree.

Strings. Nine new keys, translated in all 21 locales.

Tests

Tests/CmuxNextAppTests/SidebarNeedsYouTests.swift. The red commit 611a1fd6 fails to compile without SidebarNeedsYou.

  • Fifty sessions in every state: exactly the blocked and failed ones are listed, in drawn order, and finished unread ones are counted.
  • An item's path is right, and a fold doesn't hide it.
  • A row without a lane is blocked only when it says it waits. Unread alone isn't enough.
  • Without the tree, the tray is empty.
  • The tray is the same however the rows were dragged.
  • Revealing an item opens every fold above it and no other.

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

  • check-no-godfiles --base, check-app-size --base
  • check-concurrency, check-crash-safety, check-motion, check-module-resources, check-scrollbars, check-state-roots
  • package conventions
  • check-l10n: no errors from the new keys

Follow-ups, not here.

  • A Cmd-J "next needs you" shortcut. It needs a catalog shortcut and App binding, and the App is at its size cap.
  • A hidden descendant without an acpmux lane (a hook-only agent) refreshes its parent's roll-up on the next structural pass, not on its own patch.

Review

  • The tray reads each group's members once.
  • Its last line goes to the first session it has no room for, else to the first finished unread one.
  • The tray draws on an opaque base, so rows under it never show through.

Changelog

Added: With the Session Tree setting on, a tray at the bottom of the sidebar lists the sessions waiting on you or failed, with the path to each, and counts finished sessions you haven't read.

No capture: pending until this is rebased onto feat-cmux-next after #21836 merges; the capture is taken on that final head.

🤖 Generated with Claude Code

Agent session: cosmic-gray