Sidebar: categorize and group fleet and agent sessions

Draft
TE
3d ago
+991-20

HOLD: structural sidebar change, waiting on a dogfood build

Leo said (2026-10-30 ~04:35Z): "i feel like there's still a big mess of uncategorized stuff in the sidebar", "i mean we dont want to be too opinionated by defgault", and "im saying for my particular sidebar there's a lot of wack stuff there".

Turn on Settings > Sidebar > Session Tree to group existing agent-session workspaces under foldable host headers. The setting remains off by default. Host identities come from existing tab AgentSessionRef values through SidebarSessionTreeFeed; the production SidebarLayout.make path groups the rows. No agent-open metadata or title/subtitle changes.

The window's projected workspace rows determine whether a lineage parent is present. Loose children follow their live parent, including a parent in a user group; explicit child placement stays placed. Pinned/custom boundaries and visible machine headers remain boundaries. Cross-machine lineage can follow a parent when neither machine section draws a header. With no parent here, a session becomes a root in its host group. Host badges count folded descendants once. Local-host aliases remain local; workspaces with mixed local/fleet tabs have a placement follow-up below.

While host headers show, pointer reordering inside the sidebar is refused on legacy and document paths; the lifted card is dimmed and no gap or model move occurs. Drag-out remains available. External tabs may still drop into an existing workspace, but cannot create workspace/group insertion slots in the grouped layout. Grouped reorder and keyboard parity remain follow-ups. Existing keyboard folds and sole-member group behavior are preserved.

Design: leo-workspace design/sidebar.md (category homes and lane grouping, #1666 and #1684 in that repo). SidebarCategory is an audit taxonomy: its exhaustive SidebarDocBody switch is the compiler gate for known kinds, and tests check category assignments and stored placements. Unknown kinds without placement are a future wire-format requirement, not implemented here: current Swift wire records require a section and Rust rejects unknown bodies.

Validation at a4d09dab84aa5cbed9c9e3dff64e1204d752b6eb: independent Opus 5.5 medium SHIP; fleet Linux app compile passed (job 1e6c8a8dc09833fd3dabc0a2, reported compile time 94 s); git diff --check passes. Focused category, host projection and integration suites are running in fleet step 5e7a18b42ee64d19542d44a2; display-dependent coverage is advisory. The rebase preserves the retired sidebar tab-row removal, current tab-drop API, keyboard-fold focus and sole-member groups. Dogfood validation remains outstanding, so the HOLD stays.

Nonblocking review follow-ups, owned by this PR's originating lane:

  • #29988: keyboard focus and folding for host headers.
  • #29989: keyboard reorder parity while grouped.
  • #29990: placement for workspaces with mixed local and fleet tabs.
  • #29991: preserve collapsed hosts when restoring selection at launch.
  • #29992: move the host projection into the shared Rust reducer.
  • #29993: remove redundant reset and whitespace.

Risk: structural row projection, fold/selection identity and drag behavior. The projection, its view integration and tests stay together so the behavior can be reviewed as one change. Screenshots are a follow-up, not a landing gate; the busy-sidebar flow still needs to be tried in the dogfood build.

agent session