feat(auth): attempt browser login flow in non-TTY#1100
Draft
betegon wants to merge 1 commit into
Draft
Conversation
Contributor
|
Contributor
Codecov Results 📊❌ Patch coverage is 0.00%. Project has 5015 uncovered lines. Files with missing lines (1)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
- Coverage 81.20% 81.19% -0.01%
==========================================
Files 383 383 —
Lines 26651 26656 +5
Branches 17354 17355 +1
==========================================
+ Hits 21639 21641 +2
- Misses 5012 5015 +3
- Partials 1799 1798 -1Generated by Codecov Action |
The OAuth device flow (which opens the browser) was gated on a stdin TTY check, so an unauthenticated command run in a non-TTY (piped output, redirected stdin, CI) failed immediately instead of trying to authenticate. Attempt the device flow regardless of TTY. It's already TTY-agnostic: openBrowser is best-effort and falls back to printing the verification URL + QR code, and the copy-key listener stays gated on process.stdin.isTTY. If login doesn't complete (e.g. nobody authorizes), a non-TTY re-throws the original auth error so the standard "Not authenticated" message and exit code still surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9bee57b to
cb2c8cc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When an unauthenticated command needed auth, the OAuth device flow (the bit that opens the browser) was gated on a stdin TTY check. So in a non-TTY — piped output, redirected stdin, CI — we'd skip it entirely and fail immediately with exit 10. This makes the CLI try to launch the browser in those cases too.
Changes
Dropped the TTY gate from
autoAuthMiddlewareso the device flow runs regardless of TTY. The flow is already TTY-agnostic:openBrowseris best-effort and falls back to printing the verification URL + QR code, and the copy-ckey listener stays gated onprocess.stdin.isTTYinsiderunInteractiveLogin.The recovery logic moved into a small
recoverWithAutoAuthhelper (keeps the middleware under the cognitive-complexity limit). On failure it branches on interactivity: an interactive terminal exits 1 (the flow already reported why), while a non-TTY re-throws the originalAuthErrorso its standard message and exit code surface — exit 10 fornot_authenticated, 11 forexpired— matching the prior non-TTY behavior.Heads up on the tradeoff: against live Sentry, an unauthenticated command in CI will now open a device-flow URL and poll until the timeout (~10 min) before failing, instead of failing instantly. That's intentional. If it ever becomes a problem, the natural follow-up is a
--no-auto-auth/ env opt-out.auth statusand the rc-import / scope-recovery prompts are unaffected — they opt out viaskipAutoAuthor stay TTY-gated since they need interactive prompts.Test Plan
test/e2e/auth.test.ts: a non-TTY unauthapi organizations/run now prints "Starting login flow…" yet still exits 10 with the not-authenticated message (the device-code request fails fast against the mock's 404).requestDeviceCodeusesgetSentryUrl()(= mock) and the mock 404s unknown routes.biome checkandtsc --noEmitclean.