Both read activeSessionId at the END of an async gap, so switching tabs
in between sent the input to the wrong session:
- An image upload inserted its paths with sendInput(), which re-reads
activeSessionId after the uploads finish. It now inserts into the
session the batch was uploaded to, through the same durable queue.
- Voice dictation read the target when the transcript arrived and again
when the send button or the compose overlay's Send was pressed. The
target is now captured in start() (via _focusedPane()), the local-echo
overlay is only used when that target is the active session, and a
target that closed meanwhile gets a toast instead of a 404.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>