The error handler in tryHandleRootHelpFastPath only set process.exitCode=1
without calling process.exit(). When dangling async handles exist (timers,
connections, promises), the Node event loop stays open and the CLI hangs
indefinitely instead of returning to the terminal.
In tryHandleRootVersionFastPath, the default onError handler called
process.exit(1) directly, bypassing the injected exit seam that the
success path already uses. Changed to exit(1) (deps.exit ?? process.exit)
so tests and embedded callers can observe and control exit on failure.
Added rejection-path tests for version fast path: injected exit called
on resolveVersion rejection, and caller-supplied onError honored.
Fixes#97793.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>