Previously the queue drain guard (currentConversation.id === convId) meant
that if the user navigated to ChatView while a workspace stream was running,
the workspace's queued messages were silently abandoned — they sat in
localStorage indefinitely with no code path to resume them.
- Extract _tryDrainQueue(convId) with the same guard logic
- Call it at stream-end (replaces the inline block)
- Call it in fetchConversation after _loadQueue, so returning to a
conversation with orphaned queue messages drains them automatically
- Order is now preserved: messages drain in the order they were queued,
even across navigation events
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>