Context projection relationships
The Projects sidebar, Git graph, and Processes pane are three projections of the same project/worktree context. Focus determines which projection drives; the shared sidebar selection is the semantic join between them.
Projects sidebar Git commit Process row
selection cursor click
▲ │ │ reads lane │
│ │ ▼ │
│ │ commit lane identity │
│ │ resolves │ │ reads
│ │ context │ resolves context │ attribution
│ ╰───────────╮ │ ╭─────────────────╯
│ ▼ ▼ ▼
│ ╭────────────────────────────────╮
│ │ owning worktree or branch │
│ ╰───┬───────┬─────────────────┬──╯
│ │ │ │
╰────────╯ │ │
mirrors marker │ process drives │ sidebar or Git drives
▼ ▼
Git lineage Processes reveal
spotlight and spotlightUX rules
- Sidebar focus drives both secondary projections. A worktree or session spotlights its Git lineage and reveals/spotlights its process group. A project drives its process groups; it has no single Git lineage.
- Git focus derives context from the cursor row. A worktree row uses its path; a commit uses its lane identity. The owning worktree or unmounted local branch receives the sidebar's quiet unfocused marker. Worktree context also reveals and spotlights the corresponding process group.
- Processes focus derives context from the clicked process's worktree attribution. The owning worktree receives the sidebar marker and its Git lineage remains spotlighted while Processes keeps focus.
- A context change lands every projection regardless of focus. Session activation, a process click, or a pin arriving from outside the projections (alt+tab over a focused session, Recent's walk) moves the sidebar selection — the semantic join — and the graph and process cursors follow it. Only the driving projection's own cursor is exempt: re-landing it would yank it off the row the user chose.
- Contextual spotlighting is not the transient type-to-filter query. It does not prune rows or mutate scope; unrelated rows recede and the relevant row is revealed. After a selected-row click pins the filter, clicking another contextual row moves both selection and pin while keeping filter mode. Arrow-key navigation does the same on every new landing; it never reads as the repeated-click gesture. Clicking the pinned row again clears the filter, and
escapeclears it from any of the three projections (after backing out of any type-to-filter query/scope first, one rung per press). alt+tabis the visual filter's keyboard toggle: with no pin live it pins the focused projection's selected context, and with one live it lifts the filter. In a terminal or agent session it pins that session's owning worktree. While Recent (cmd+e) is up it pins the highlighted row's owning worktree without closing the list, and a live pin follows the walk from row to row; the close settles the join, landing the sidebar selection on the pinned context (mid-walk the panes belong to the previews). Elsewhere outside the projections it pins the sidebar selection, the semantic join. See the keyboard map's Visual filter section.- Project folders in the sidebar browse first: the first click parks the selection on the folder and lands every projection on that project; only a repeat click on the already-selected folder expands or collapses it (
returnfolds immediately — keyboard selection already sits on the row). Because that repeat click is the fold toggle, pointer-pinned filters never start from the folder itself, only from descendant worktree, branch, or agent rows — though a live pin follows folder clicks and arrow landings like any contextual row.alt+tabhas no such click conflict and may pin the project folder, receding every other project. - Branch-only Git lanes can mark an unmounted branch in the sidebar, but they cannot filter Processes because no worktree exists to own a process.
- Context changes swap pane content, never pane membership. Following a context with no session keeps the tile in place as a generic empty pane, which can be filled with any pane type — browsing from any projection must not add, remove, or resize panes.