Add interactive session switcher for navigating between subagent sessions
Problem
When working with subagent sessions (e.g., tasks spawned by the task tool), navigation currently requires cycling through sessions one-by-one using <leader>right / <leader>left. This becomes inefficient when:
- Multiple subagents are spawned from a single parent session
- Subagents spawn their own subagents (nested hierarchy)
- You need to jump directly to a specific session (e.g., one awaiting permission input)
There's no way to see all related sessions at once or jump directly to a specific one.
Proposed Solution
Add an interactive session switcher dialog that:
- Shows hierarchical view of parent and all descendant sessions (up to 3 levels deep)
- Displays session status - busy spinner for active sessions, permission indicator for sessions awaiting user input
- Allows direct navigation - select any session from the list instead of cycling through sequentially
- Integrates with command palette - appears in suggested commands when subagents exist
Keybind
<leader>s (configurable via session_child_list)
UI Example
Switch Session
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Parent
● Main session title 2m ago
Subagents
explore task 1m ago
code-review task 45s ago
Subagents › explore
◉ nested-search task 30s ago
-
●indicates current session -
◉(warning color) indicates session awaiting permission - Spinner shown for busy/active sessions
Why This Is Useful
Direct selection is significantly more efficient than sequential cycling when you have 5+ subagent sessions and need to:
- Check on a specific task's progress
- Respond to a permission prompt in a nested subagent
- Return to the parent session after reviewing children
Implementation Approach
The implementation reuses existing patterns from the codebase:
-
DialogSelectcomponent for the selection UI (same asDialogSessionList,DialogTimeline) -
sync.data.permission[sessionID]for pending permission detection -
sync.data.session_status[sessionID]for busy state detection -
Category grouping for hierarchical display (same pattern as date grouping in
DialogSessionList)
Style note
The implementation uses a let statement when walking up the session tree to find the root parent:
let current = currentSession()
while (current?.parentID) {
const parent = sync.session.get(current.parentID)
if (!parent) break
current = parent
}
This is a legitimate use case where let is appropriate - the variable must be reassigned during iterative traversal. Per the style guide, let should be avoided where possible, but not prohibited when it's the natural solution.