When replaceSession changed the session ID from pending-XXX to a
real UUID, Vue's :key="session.id" treated it as a new element,
destroyed and recreated TerminalInstance, which called connectToHost
again, got another UUID, replaced again — infinite loop.
Added a stable `key` field to sessions that never changes after
creation, used as the Vue :key instead of the mutable `id`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>