Repository navigation
Brainstorm: Project grouping view #5
Description
Brainstorm: Project Grouping View
Date: 2026-07-02
Status: active
Problem Framing
With 850+ sessions, the flat chronological list makes it hard to find sessions for a specific project. PR #2 implemented project grouping but bundled it with archiving, titles, forking, and move-to-project. We want to extract just the grouping concept, redesigned to fit the existing minimalist UI: off by default, toggle-able, and non-disruptive to the current search/filter workflow.
Approaches Considered
A: Virtual row model (chosen)
Insert ProjectHeader entries into the existing flat display_entries Vec. Headers are first-class display entries alongside session entries. Grouping is a view-layer concern; filter/search logic stays untouched. Navigation, scrolling, and click targeting work naturally because header rows have concrete positions in the list.
- Pros: Minimal change to existing architecture. Filter/search code unchanged. Easy to toggle since it just rebuilds display entries.
- Cons: Arrow key navigation must skip/stop at headers. Scroll offset calculations need to account for header rows.
B: Separate view state
Two independent display entry lists (flat and grouped), toggled between. Each with its own rendering and navigation logic.
- Pros: Clean separation, each mode is self-contained.
- Cons: Duplicates rendering and navigation logic. Filter changes need to update both models. Code drift risk.
C: Render-time grouping only
No data model changes. Detect project boundaries during rendering and insert header lines on the fly. Collapse state in a separate HashSet<String>.
- Pros: Zero data model changes. Purely cosmetic.
- Cons: Cursor position doesn't map 1:1 to display rows. Mouse click targeting and scroll calculations become complex.
Decision
Approach A: Virtual row model. Keeps the existing architecture intact while making headers first-class entries.
Key Requirements
- Toggle: Ctrl-T switches between flat (default) and grouped view
- Header style: Chevron + project name + relative time of most recent session
▶ cc-session 2 hours ago(collapsed)▼ cc-session 2 hours ago(expanded, sessions indented below)
- Default state: All groups collapsed when no filter/search is active (compact project overview)
- Filter/search active: Matching groups auto-expand, empty groups hidden
- Expand/collapse: Enter or mouse click on a project header toggles. Enter on a session row opens the conversation (unchanged)
- Content search: Works identically in both modes. Results appear under their project groups, auto-expanding those groups
- Ordering: Projects ordered by most recent session timestamp. Sessions within a project ordered newest-first
- Data model:
DisplayEntrygets aProjectHeadervariant.rebuild_display_entrieshandles insertion/grouping
Open Questions
- Should the grouped/flat preference persist across restarts (e.g., in a config file), or always start flat?
- Should Left/Right arrow keys also collapse/expand groups (in addition to Enter), or keep them free for future use?
- How should the session count be shown in the border title? Currently shows
(filtered/total). In grouped mode, should it also show project count?
Activity
mabulgu commentedon Jul 2, 2026
Nice write-up @rhuss. A few thoughts on the approaches:
The virtual row model (Approach A) is close to what PR #2 already does with
TreeRow, but I see the appeal of making headers first-class entries indisplay_entriesinstead of a separate enum. It would simplify navigation since everything lives in one flat list. The currentTreeRow+project_groupsapproach works but does add complexity around scroll offset and cursor mapping between the two models.Some things I'd push back on or want to discuss:
Default collapsed vs expanded: With 850+ sessions across many projects, all-collapsed gives a nice compact overview. But if someone has only 5-10 projects, collapsed-by-default adds an extra click every time. Maybe collapsed-by-default when project count > N (say 10), expanded otherwise?
Ctrl-T vs Tab: Tab is more discoverable and standard for toggling views in TUI apps (like htop, lazygit). Ctrl-T might conflict with terminal tab management in some setups. What's the reasoning for Ctrl-T specifically?
Unbundling from PR #2: I'm fine with extracting grouping into its own thing if that's cleaner. But archiving, move-to-project, and titles are independent features that don't depend on grouping. Should those stay in PR #2 as a separate scope, or do you want those split into individual PRs too?
On the open questions: I'd start flat on every launch (no persistence) and support both Enter and Left/Right for collapse/expand since Left/Right feels natural in tree navigation.