Sidebar: group the inbox by environment, project or provider — with rows that stop repeating themselves #7836
BarretoDiego
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The problem
The v2 sidebar inbox is one flat list. Once you run more than one environment, a handful of projects and two providers, it stops answering the questions you actually have:
Today the only lever is the project scope menu, which narrows to exactly one project. Everything else is scrolling. And every card repeats its project name whether or not that is the useful bit, which costs the title the space it needs.
Same window, same data. Nine threads become eleven threads plus four labelled sections, and you can tell at a glance which machine and which project each one belongs to.
What I built
A compact bar under the project selector, with three menus. Everything persists to client settings.
Group by splits the inbox into collapsible sections along one axis — environment, project or provider — and an optional second axis nests inside the first.
Nothingkeeps today's flat list and stays the default, so nobody gets a new sidebar they did not ask for.Provider filter narrows every shelf, not just the inbox. A filter that left pinned or settled rows from other providers on screen would be lying about what "only Claude" means.
Sort is last activity or date created. The existing
sidebarProjectGroupingMode(repository / folder / project) is surfaced here too, instead of living only in Settings.Each trigger reads out its current choice —
Env › Project,All,Activity— so the bar doubles as the readout of how the list is arranged. No need to open a menu to find out.Rows say each thing once
The part I am happiest with. A grouped card drops whatever a section header above it already states:
Environment › ProjectEnvironment › ProviderProject › ProviderProvideronlySo the same thread is a 78px card in the flat list and a 36px row under a project header — without a second card component to maintain.
pinGlyphandstatusSlotare shared, so the compact row keeps exactly the same affordances (settle, snooze, pin, PR badge). Branch and diff move to the hover tooltip.Start a thread where you are looking
Grouping by project surfaces every project as a header, so the header is the natural place to start work in it — no trip back up to the project selector to change scope. A New thread button sits beside the collapse arrow on project sections, revealed on hover and on keyboard focus.
Environment and provider sections span several projects, so they have no unambiguous target and get no button rather than a guess.
Attention rollup on collapsed sections
A collapsed header is the only time the header is the whole story, so that is the only time it carries the rollup: coloured dots with counts for approvals (amber), input requests (indigo), failures (red), unread completions (green) and running work (blue), in that order. Open sections leave it to the rows.
The classifier is injected into the grouping as a function, and it is the same
resolveSidebarThreadStatus+hasUnseenCompletionthe rows use — a header can never claim something its rows would not show. Unread finished threads also get a green dot next to their title, in both the flat and grouped layouts.Indent guides
Nesting is drawn with editor-style indent guides: each row emits a 1px segment per ancestor level at that ancestor's indent column, so consecutive rows form one continuous guide with no per-group bookkeeping and no elbow/last-child logic.
Implementation notes
apps/web/src/components/sidebarThreadGrouping.ts— pure, no React. Sections come out in first-appearance order and threads keep their incoming order, so sorting and grouping stay orthogonal: changing one never reshuffles the other. 18 unit tests.packages/contracts/src/settings.ts— four client-local settings (sidebarThreadPrimaryGrouping,sidebarThreadSecondaryGrouping,sidebarThreadProviderFilter,sidebarThreadCollapsedGroups), all with decoding defaults so old and new clients interop.useMemo, O(n) over threads already in memory. No new websocket traffic, no polling, no animation.docs/user/thread-sidebar.mdupdated.What I deliberately did not do
Subagent counts per thread. I wanted this and stopped. Subagents are folded from
activeThread.activities, which only exists for the open thread; the sidebar works offOrchestrationThreadShell, which carries no such field. Doing it properly means a new shell field materialised by the projector — a contract change touching server, web, mobile and desktop. That is its own proposal, and presumably what "Sidebar sub-agent visualization" on the roadmap already covers.The flat-list card. Untouched. It is your design and already polished; changing it here would have been a second concern in one change.
Try it
Everything defaults to today's behaviour, so the difference you feel is exactly what you opt into.
Why a discussion and not a PR
CONTRIBUTING.mdsays feature proposals belong here and that large feature PRs are unwelcome without a conversation first. This is ~1.9k lines and it is a feature, so: is this a direction you want at all, and if so, how would you want it split? Happy to cut it into smaller pieces, drop parts of it, or drop it entirely if the answer is no.All reactions