Added
- Focus switching — configurable
focusShortcut(defaultalt+\``) toggles focus between overlay and main chat. Same shortcut inside the overlay unfocuses back. Overlay usesnonCapturing` mode with handle-based focus control. /spawncommand — launch pi in an overlay with/spawn(fresh session) or/spawn fork(fork current session with platform-aware shell quoting).Alt+Shift+Pshortcut — quick-launch a fresh pi session overlay.- Return-to-agent control — after taking over a hands-free session, press
Ctrl+Gor select "Return control to agent" from theCtrl+Qmenu to resume agent monitoring. Re-registers session in streaming mode and restarts hands-free update timers. agent-resumedstatus — newHandsFreeUpdate.statusvalue emitted when the user returns control to the agent. Handled in both streaming and non-blocking notification paths.- Transfer output from commands —
Ctrl+Ttransfer results from/spawnand/attachnow flow back into the agent conversation via sharedemitTransferredOutput()helper, matching the tool-call behavior. - Per-session completion suppression —
agentHandledCompletionmoved from a single flag to aSet<string>on the coordinator, so concurrent sessions can't interfere with each other's notification paths. - Stale monitor cleanup —
disposeStaleMonitor()helper cleans up orphan headless monitors and their active-session registrations when a background session has already been removed. - 3 new test files (10 tests):
spawn-command.test.ts(fresh, fork, quoting, persist guard, transfer forwarding),command-session-selection.test.ts(IDs containing delimiters),kill-session-suppression.test.ts(conditional mark on incomplete/complete sessions).
Changed
/attachand/dismissselection uses structured{ id, label }option mapping with.find()instead of parsing rendered label strings by delimiter. Session IDs containing-or(no longer break selection.- Kill suppression is conditional on completion state —
markAgentHandledCompletiononly set whensession.getResult()is not yet available, preventing leaked suppression tokens for already-completed sessions. spawn-helper.tsuses inline ENOENT narrowing instead of single-usegetErrnoCodehelper.- Dynamic dialog footer height (
dialogOptions.length + 2) in the overlay accommodates the variable return-to-agent option. Reattach overlay keeps the staticFOOTER_LINES_DIALOGconstant (always 4 options). - Flattened nested if/else in footer rendering for both overlay components.
createOverlayUiOptions()deduplicates overlay UI configuration across all call sites.runtime-coordinator.tsmanages overlay focus viaOverlayHandle(focus, unfocus, set, clear).- Config parse errors now pass the full error object to
console.errorinstead ofString(error). - Shutdown kill failure preserves slug reservation to prevent ID collision with potentially still-running sessions.
- Removed legacy
session_switchlifecycle setup and rely on immutable-sessionsession_startreinitialization for background widget setup.
Fixed
- Duplicate completion notifications on monitored attach + transfer (transfer now marks
agentHandledCompletionbefore monitor fires). - Cancelled dispatch sessions reported as "completed" — now correctly reports "was killed".
- Stale headless monitors leaked when the corresponding background session was already cleaned up.
- Zombie active-session registrations left behind on stale monitor disposal.
- PTY event handlers not reset on attach failure recovery, causing stale overlay callbacks on disposed components.