## Problem Every time you switch away from the Shell tab and come back, you get a completely fresh bash session. If claude is running in that session, it's gone — and depending on OAuth token state, it asks for re-authentication. For Claude Code users, this means re-authenticating multiple times per day just from normal tab switching. ## Root Cause In `src/server.ts`, the WebSocket close handler unconditionally kills the PTY: ```typescript ws.on('close', () => { sessions.delete(sessionId); try { ptyProc.kill(); } catch { /* ignore */ } }); ``` There is no reconnect path — every new WebSocket connection spawns a fresh shell with a new session ID. The client-side code includes the comment *"Sessions persist across mount/unmount (tab switching)"*, but the server does not honor that intent. ## Impact - Any long-running process in the Shell tab (claude, a build, a server) is killed on every tab switch - Claude Code users must re-run `claude` each time they return to the tab; if the OAuth access token is near expiry, this triggers the full re-authentication flow - The "--- reconnected ---" message shown in the terminal gives the false impression that the session is preserved ## Proposed Fix Keep the PTY alive on WebSocket disconnect and reconnect to it on the next connection. A per-session timeout (e.g. 30 minutes) would handle cleanup for truly abandoned sessions: ```typescript // On disconnect: detach WebSocket but keep PTY alive ws.on('close', () => { const session = sessions.get(sessionId); if (session) { session.ws = null; session.cleanupTimer = setTimeout(() => { try { session.pty.kill(); } catch { /* ignore */ } sessions.delete(sessionId); }, 30 * 60 * 1000); } }); // On new connection: reuse existing session if available wss.on('connection', (ws) => { const existingEntry = [...sessions.entries()].find(([, s]) => s.ws === null); if (existingEntry) { const [sessionId, session] = existingEntry; clearTimeout(session.cleanupTimer); session.ws = ws; // Reattach data handlers and send ready return; } // No existing session — spawn fresh }); ``` ## Workaround Until this is fixed, users can add a tmux auto-attach to `.bashrc` gated on `$TERM_PROGRAM=web-terminal`. The web-terminal kills the PTY (tmux client), but the tmux server keeps running, so long-running processes survive tab switches: ```bash # At the end of ~/.bashrc if [ -z "$TMUX" ] && [ "$TERM_PROGRAM" = "web-terminal" ]; then exec tmux new-session -A -s main fi ```