- Fix socket singleton lifecycle: add destroySocket() and auto-reset on disconnect
so page remounts always get a fresh authenticated connection
- Add explicit WebSocket transport preference to avoid polling fallback
- Filter socket events by conversationId to prevent cross-conversation bleed
when switching between conversations mid-stream
- Use activeIdRef pattern so event handlers see current activeId without
stale closures or listener re-registration on every render
- On agent:end, append accumulated text as assistant message to local state
(matching TUI pattern; Pi session is in-memory so DB reload would miss it)
- Preserve REST persist of user messages for conversation history on reload
- Clear streaming state on conversation switch
- StreamingMessage: show animated typing indicator before first token arrives
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>