9f90624aa6
Three related bugs fixed: 1. Frontend xterm.js crash: TerminalPage rendered ALL sessions with display:none for inactive ones. xterm.js crashes when initialized in a hidden container (Viewport can't read dimensions). Fix: only render the active session's TerminalComponent using conditional rendering. 2. Backend websocket disconnect cascade: When client disconnected (due to #1), the server tried to send 'connected' status on dead socket, caught the WebSocketDisconnect in a generic except block, then tried to close() again causing RuntimeError. Fix: catch WebSocketDisconnect specifically and suppress close() errors. 3. Stale DB sessions: After server restart, DB still had old terminal session rows but no in-memory sessions. list_terminal_sessions returned these ghosts, causing the frontend to render dead tabs. Fix: skip DB-only sessions that have no live in-memory counterpart. Quality gates: pytest (15/15 passed), tsc clean, vitest (7/7 passed)