9d84e28692
When an uncaught exception fires in interactive mode, the process dies with stdin still in raw mode and the cursor hidden, leaving the user with a "borked" terminal that needs `stty sane && reset` to recover. The most common trigger is an extension's async ChildProcess `exit` callback that throws (e.g. from accessing a stale ctx after session replacement), but this affects any uncaught throw from anywhere in pi. Add an uncaughtException handler in registerSignalHandlers that calls ui.stop() before exiting, mirroring the existing emergencyTerminalExit pattern. The handler is registered with prependListener and tracked in signalCleanupHandlers, so it is removed on graceful shutdown the same way the other handlers are. Unlike emergencyTerminalExit (used for SIGHUP / dead-terminal EIO), the terminal is still alive on uncaughtException, so we run the normal ui.stop() to restore cooked mode, the cursor, bracketed paste mode, and Kitty / modifyOtherKeys sequences.