Review findings from the first round: - ui-settings renders its full-viewport panel as a fixed-position DESCENDANT of the sidebar column, so `pointerleave` never fires when the pointer moves onto it and the bars stayed drawn after it closed. Leaving is now decided against the column's box from a document-level pointermove that exists only while the bars are drawn; the element's own leave stays for the pointer that leaves the window. - The rebind gate judges the rule rather than each declaration, so a pair that mixes `transparent` with an l2 hover no longer passes, and the elevation half compares whole values instead of token shape. - Hiding no longer exempts a sheet from the elevated-surface rebind check. - The e2e polls the reveal before reading a colour for the golden, and pins that a pointerless scroll draws no thumb.
@deepseek-ai/dsh-client-ui-sidebar
English | 中文
Sidebar plugin: real Host Workspaces in stable Host order, each containing its sessionIds in Workspace order with parentId nesting; Sessions outside every Workspace appear in a trailing Ungrouped section. Search, state dots, and collapse into the layout-owned 56px rail are presentation-local. Contract: the slot system standard.
New Session starts the runtime's page-local frontend Session Intent; a real Workspace's "+" starts one targeted to that Workspace. The Workspace header "+" opens ui-workspace's shared picker, whose selection also targets a frontend Session. A Workspace Intent does not appear in the sidebar.
SidebarRootComponentProps composes the layout owner share, the global useSessions and useWorkspaces hooks, the declared sidebar.workspace and sidebar.settings child slots, and injected startSession, open, and sidebar-toggle callbacks. There is no plugin store: deriveGroups consumes object-layer snapshots and component-local expansion/search state.
Scrollbars in the column are a pointer affordance: the shell rebinds ui-theme's scrollbar indirection to transparent whenever the pointer is outside it, and keeps the thumb drawn for 2s after the pointer leaves, so a list nobody is pointing at carries no bar. The reservation that keeps rows from moving belongs to the scrolling region (ui-workspace), so revealing a thumb never reflows.
The foot is the sidebar.settings seat: the sidebar renders only the bottom-pinned layout slot and shares its column state (wide); ui-settings registers the trigger row and settings panel there.
The /client export surface is the plugin body (apply/inject) plus the contract types only — SidebarRoot, the row components, and the tree derivation are internal (the slot registration closes over them; tests import src paths directly).
Model Experience
None, as the sidebar renders the browser session list; nothing here reaches a model request.
KV Cache effect
None; this package neither assembles nor sends a provider request.
Known Limitations and Deferred Work
- Session state-dot rendering is owned by ui-workspace — done/error notification sources remain deferred.
- Group-by menu ships by-workspace only — Update/Status grouping strategies are drawn without specs and deferred.
- "New task completed" unread marking is local viewing state — completion-time > last-seen never reaches the host.