MCP server exits cleanly when its parent disconnects — no more zombie processes
Until this release the Orbit MCP server didn't watch for the signals that mean 'your parent's gone, stop running.' The result was zombie server/index.js processes accumulating in the background after Claude Desktop quit — each burning 50–80% CPU, sitting around for days. Reliability fix: every shutdown signal now funnels into a single idempotent exit path, including a parent-alive watchdog for the rare case where stdio events don't fire. Routine fix; you'll notice it as 'Activity Monitor stops filling up with old Orbit processes.'
What shipped
•Added handlers for SIGTERM, SIGINT, SIGHUP, stdin 'end', stdin 'close', and the MCP transport's onclose hook. Any of these now triggers a graceful exit.
•Replaced the previous uncaughtException handler that swallowed fatal errors and kept running. The handler now logs and exits with code 1, so a crashed server actually dies and Claude Desktop respawns it cleanly on the next call. Same treatment for unhandledRejection.
•Added a parent-alive watchdog that polls process.ppid every 30 seconds and exits if the parent has been reaped (process.ppid === 1 means we're orphaned to launchd). Belt-and-braces for the rare case where stdio events don't fire on abnormal parent termination. Uses .unref() so it can never keep the process alive on its own.
•Shutdown is idempotent and bounded — a 200ms grace window after triggering, then process.exit. If anything is keeping the event loop alive (timers, sockets, pending I/O), the hard exit ensures we still terminate.
•Verified locally: SIGTERM now produces '[Orbit] shutdown: SIGTERM' on stderr and exits with code 0 within ~200ms, vs the previous behaviour of running forever.