This was generated by AI during triage.
Summary
Add a pin toggle to each terminal pane that locks it to a specific position in the grid, independent of which session group is currently active. Pinned shells stay visible and in place when the user switches groups; non-pinned shells in the new group fill the remaining positions.
Motivation
When running several session groups it is common to have one or two "always-on" terminals (e.g. a long-running build watcher, a log tail, or a Claude session tracking an active task). Today, switching groups replaces the entire grid, so those terminals disappear. Pinning lets the user keep selected shells anchored while still navigating groups freely.
Proposed behaviour
Pinning
- Each terminal pane (and/or its sidebar entry) exposes a 📌 pin toggle.
- Pinning stores the shell's current grid slot (row × column index for the active layout) as the pinned position.
- If no slot is stored yet (e.g. the shell was just pinned from the sidebar while dormant), default to the first free slot in the current layout, or ask the user to drag it into position first.
Group switching
When the user switches to a different group:
- Pinned shells retain their grid slots and remain rendered.
- Non-pinned shells from the previous group are torn down / dormanted.
- The new group's shells fill the remaining (non-pinned) slots.
- If there are not enough free slots for the new group's shells, overflow shells go dormant (same behaviour as today when the layout is smaller than the session count).
"Out of group" UI
A pinned shell that does not belong to the active group should clearly signal this:
- Toolbar or pane border shows a distinct visual treatment (e.g. dimmed accent stripe, 📌 icon + italic group name label, or a subtle overlay banner like "Pinned · from Group X").
- The shell remains fully interactive — it is not read-only.
- The sidebar entry for a pinned-but-out-of-group shell could show a small 📌 badge and be listed under a separate Pinned heading rather than disappearing.
Persistence
- Pin state and pinned slot are persisted to
state.json alongside the ShellSession.
- On restore, pinned shells are re-launched first so they can claim their slots before the active group's shells are restored.
Out of scope (initial cut)
- Pinning a shell to a floating window rather than a grid slot.
- Per-monitor pinning.
- Dragging a pinned shell to a different slot (unpin → move → re-pin is fine for now).
Implementation hints
- Add
IsPinned: bool and PinnedSlot: (int row, int col)? to ShellSession (persisted).
LaunchSessionAsync / RefreshTerminalLayout must reserve pinned slots before distributing the active group's sessions.
BuildTerminalWrapper / UpdateActiveTerminalHighlight need to handle the "pinned, out of group" visual state.
- The sidebar's
BuildSidebarItem should expose the 📌 toggle and render it differently when out-of-group.
Summary
Add a pin toggle to each terminal pane that locks it to a specific position in the grid, independent of which session group is currently active. Pinned shells stay visible and in place when the user switches groups; non-pinned shells in the new group fill the remaining positions.
Motivation
When running several session groups it is common to have one or two "always-on" terminals (e.g. a long-running build watcher, a log tail, or a Claude session tracking an active task). Today, switching groups replaces the entire grid, so those terminals disappear. Pinning lets the user keep selected shells anchored while still navigating groups freely.
Proposed behaviour
Pinning
Group switching
When the user switches to a different group:
"Out of group" UI
A pinned shell that does not belong to the active group should clearly signal this:
Persistence
state.jsonalongside theShellSession.Out of scope (initial cut)
Implementation hints
IsPinned: boolandPinnedSlot: (int row, int col)?toShellSession(persisted).LaunchSessionAsync/RefreshTerminalLayoutmust reserve pinned slots before distributing the active group's sessions.BuildTerminalWrapper/UpdateActiveTerminalHighlightneed to handle the "pinned, out of group" visual state.BuildSidebarItemshould expose the 📌 toggle and render it differently when out-of-group.