fix(auth): Ctrl+C during browser sign-in exits 130 instead of 0

Merged
SA
5d ago
+159-7

Problem

altimate-code auth login -p altimate-backend --method "Altimate LLM Gateway" (and any other browser-callback OAuth method) waits for the callback under a clack spinner. Pressing Ctrl+C there did the wrong thing:

  • In a terminal it exited 0. The spinner's block() (@clack/core) puts stdin in raw mode and calls process.exit(0) on Ctrl+C, so auth login … && altimate-code link continued after a canceled sign-in and link failed with "Not signed in". Ctrl+C at the method picker already exits non-zero, so the same command was inconsistent.
  • Without a terminal (scripts, kill -INT), the spinner's SIGINT listener swallowed the signal and the process kept waiting until the sign-in timed out.

serve and run already exit 130 on SIGINT "so a SIGINT/SIGTERM isn't masked as a successful (0) run"; sign-in was the exception.

Fix

  • providers.ts: the OAuth "auto" wait prints Waiting for authorization... (Ctrl+C to cancel) instead of a spinner and races the callback against SIGINT. On cancel it fails with Sign-in canceled. and exit code 130. No credential is saved, and the callback listener closes when the process exits.
  • index.ts: the top-level catch set process.exitCode = 1 after FormatError, which overwrote a CliError's own exitCode. It now sets the default first. This also makes the existing fail("Cancelled.", 130) in learn exit 130 as intended.

Testing

  • New test/cli/auth-login-cancel.test.ts runs auth login against a fake plugin whose browser callback never completes. It covers Ctrl+C in a real PTY and SIGINT without a terminal, and both expect exit 130 plus "Sign-in canceled.". On main the PTY case exits 0 and the no-terminal case is still running 10 s after SIGINT.
  • bun test test/cli: 1173 pass. The 2 failures are --time-budget cases in test/cli/run/json-output.test.ts that also fail on main.

Not in scope

A browser sign-in that finishes with failed still exits 0 (the "auto" and "code" paths both fall through to "Done"). That's the same class of problem but a separate change.

🤖 Generated with Claude Code


Summary by cubic

Fixes Ctrl+C during auth login browser sign-in so a canceled sign-in exits 130 instead of being masked as a success (0) or hanging until the callback times out.

Bug Fixes

  • Replaces the spinner on the OAuth "auto" wait with a log line and races the callback against SIGINT; canceling now fails with "Sign-in canceled." and exit code 130.
  • Sets the default exitCode to 1 before formatting errors so a CliError's own exit code (e.g. 130) is no longer overwritten.
  • Adds subprocess tests covering Ctrl+C in a real PTY and SIGINT without a terminal, both of which fail on main; the tests are skipped on Windows and run in CI's bounded subprocess pass.

Summary by CodeRabbit

  • Bug Fixes
    • Pressing Ctrl+C during OAuth sign-in now cancels the operation, displays “Sign-in canceled,” and exits with a cancellation status. This works both in a terminal and when the CLI receives an interrupt signal.
    • CLI errors now set a failure exit status before error formatting and reporting, helping ensure failures are reflected when the command exits.
    • OAuth authorization progress, successes, and failures are displayed as direct messages rather than spinner updates.