Skip to content

Inbox sidebar: session lifecycle, settled shelf, branch and pull request glyphs - #220

Merged
stippi merged 14 commits into
mainfrom
feature/sidebar-inbox
Oct 4, 2026
Merged

stippi merged 14 commits into
mainfrom
feature/sidebar-inbox

Conversation

@stippi

@stippi stippi commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Summary

The GPUI sidebar becomes an inbox instead of a project tree, after comparing it with T3-Code's sidebar.

  • Session lifecycle (code_assistant_core::session::lifecycle): status (what the agent does) and unread (changed since the user last looked) are separate dimensions. Visits and settlement live in sessions/lifecycle.json, never in the session file.
  • Settlement: by hand, after N idle days (default 14, Settings → General), or when the session's branch is merged. git::GitRepository::is_branch_merged also recognises squash merges. Inactivity settlement runs batched before the first listing, dated by the session's last activity.
  • Branch and pull request: a session learns its branch after a run when it has none; gh pr view supplies the pull request (open / draft / merged / closed, review, checks). A merged pull request settles the session.
  • Sidebar: unsettled sessions across projects, static order, emphasis instead of position; Needs approval flagged from permission requests of any session; a settled shelf docked at the bottom that opens upward; the header's "+" is a project picker with search, keyboard navigation and the Select dropdown's enter motion.

Details in docs/session-lifecycle.md.

Not covered

  • Fork pull requests are not found by branch name.
  • Only GitHub; other hosts show the branch alone.
  • Persisting a temporary project has no UI any more (the pin left with the project rows).
  • Snooze, pin, manual reorder, terminal frontend parity.

Test plan

  • cargo test --workspace (only web::tests::test_web_search failed, a live DuckDuckGo request)
  • cargo clippy --all-targets --all-features -- -D warnings
  • Sidebar states checked against an isolated data set (screenshots in the session)
  • Picker open/close, keyboard navigation and the shelf animation by hand

stippi added 14 commits October 4, 2026 00:13
… detection

Visits and settlement live in sessions/lifecycle.json so a visit never
rewrites a session file. ChatMetadata carries the session branch for the
merge rule; GitRepository::is_branch_merged also recognises squash merges.
Unsettled sessions list across projects, newest first and static in
order; what a session needs shows as emphasis: approval and failure in
colour, working rows receding, unread ready rows standing out. Settled
sessions wait in a collapsed shelf; project rows at the bottom start
sessions and scope the inbox. Permission requests are tracked per asking
session so the sidebar can flag them. Settings → General holds the
inactivity and merge rules; a sweeper applies them every ten minutes.
…ilding rows

A startup sweep can settle hundreds of sessions in a row; each change now
updates one row and re-sorts, and the watcher refreshes the list when
another process writes lifecycle.json.
A session learns its branch after a run when it has none (worktree
sessions already carry theirs). The lifecycle sweep and each run read the
branch's pull request through gh; rows show an open, draft, merged or
closed pull request, or the bare branch, and name what the pull request
waits for. A merged pull request also settles the session.
Project rows and the scope filter leave the sidebar: a filter that stays on
hides exactly the cross-project attention the inbox exists for. The
header's "+" opens a searchable picker (projects most recently active
first, No project, Add project…) that starts a session where it is chosen.
Rows keep naming their project.
…sions before the first listing

The shelf opens upward with a short animation, up to half the window, and
pages its rows. Inactivity settlement now runs in one batched write before
the first listing, dated by the session's last activity, so a long-unused
store no longer paints every session only to sweep it row by row.
The header holds the search field with its magnifier and the "+ Project"
button, so adding a project no longer scrolls away at the end of a long
list; typing filters, Up/Down and Enter pick, Escape closes. The trigger
lost its tooltip, which used to open over the search field.
The scroll wrapper needs a definite height; with only a maximum the rows
never scrolled. The list now sizes to its rows, capped at half the window.
The trigger uses the primary button style so it stands out like Done.
gpui-component's Popover has no animation; the fade-and-slide the Select
dropdown plays lives in a crate-private helper. The picker renders its own
surface in popover style and mirrors that motion, ring and shadow rising
with the cube of the fade.
The settled shelf gives way to a Projects view: every session in its
project's folder, settled ones receding. Folders keep a stable order that
adopts new projects at the top and changes only by drag and drop; collapsed
folders mark approval, failure or unread sessions inside. The header holds
the view switch and two buttons, new session (project picker) and new
project. View, collapsed folders and order persist in ui-settings.json.
Saving a temporary project is back on the folder header.
… header

The custom themes replaced the theme colors but left the resolved tokens
at gpui-component's stock values; the segmented tab bar paints its track
and active pill from those, nearly black on black in dark mode. Sync the
two tokens from our colors and give the track its own shade. The header
grows, the view switch and buttons move up a size, icons at 16px.
…tween folders

The switch reads Active | Projects, is taller and slides its pill on
gpui-component's move spring; drawing it ourselves lets the active segment
stand out in dark mode, so the theme token sync from the previous commit
goes again. The header takes the title bar's colour. A dragged folder no
longer highlights its target's header: a line above or below the target's
whole block shows where it lands.
@stippi
stippi marked this pull request as ready for review October 4, 2026 17:51
@stippi
stippi merged commit 8562078 into main Oct 4, 2026
4 checks passed
@stippi
stippi deleted the feature/sidebar-inbox branch October 4, 2026 18:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant