Repository navigation
fix(cli): keep browser sign-in open through checkout - #6879
Open
vanceingalls wants to merge 3 commits into
Open
vanceingalls wants to merge 3 commits into
vanceingalls wants to merge 3 commits into
Conversation
The loopback listener timed out after 5 minutes, but plan checkout runs inside the OAuth flow. A slower purchase ended on ERR_CONNECTION_REFUSED. Raise the default to 60 minutes, matching pacific's plan-checkout handoff. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The waiting line now states the 60-minute limit and Ctrl+C. After a timed-out browser login the CLI says to run auth login again. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… limit Review fixes: the timeout hint no longer says purchases stay on the account (the CLI cannot observe billing); the no-timer-left test now asserts before any explicit close() and uses node:http so undici timers cannot pollute the count; docs mention the 60-minute window and Ctrl+C. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
somanshreddy
left a comment
Contributor
There was a problem hiding this comment.
Review at 664e8061d: no blockers. The change does what it says. I have two nits, plus a few notes on the "hardest look" points.
What I checked
- Callers.
startLoopbackhas exactly one caller,startAuthorizationCodeFlow(oauth.ts:148). Nothing passestimeoutMsin production code, so the new default only affectshyperframes auth login(browser).--deviceand--api-keydon't touch it. - Server side. Nothing server-side expires sooner than the new window.
/v1/oauth/authorizecarriesstateandcode_challengein the URL, and the auth code is minted at grant time, which is after checkout. So no server TTL runs during the wait. Pacific'splanCheckoutHandoff.tskeeps its sessionStorage handoff forMAX_AGE_MS = 60 * 60 * 1000, so 60 min on the CLI side is the right match. One caveat: pacific's clock starts when checkout is marked, while the CLI's clock starts when the command runs. So the CLI is always the shorter of the two, by however long sign-in and choosing a plan took. That's fine; the CLI won't keep listening after pacific has given up. - Where the 5 min came from.
git log -S300_000points at #6754 (cb2389cf3). It raised the value from 120s to 300s as part of the reverse-any-video and billing work, with no stated reason. The JSDoc still said "120s" until this PR. I don't see a security reason to keep it short. The listener binds to127.0.0.1on an ephemeral port, rejects non-GET requests and unknown paths, and checksstate. A longer window only means a stale listener sits on a local port longer, and PKCE plusstatestill protect it. - The abandoned login blocking the terminal. The
setTimeoutkeeps the process alive for up to 60 min, but Ctrl+C exits cleanly, and the new waiting line says so. Themedia-useskill tells agents to have the person run! npx hyperframes auth login, so a human is at the keyboard. An agent calling it through a Bash tool is capped by that tool's own timeout. Acceptable. - Cleanup on success. The new fake-timer test asserts
vi.getTimerCount() === 0after the result resolves and beforeclose(). That pins the behaviour that matters most now: with an hour-long timer, a leaked timer would keep the CLI alive for the full hour after "Signed in".result.finally(close)→clearTimeout(timer)makes that hold. The boundary test (-1msnot settled,+1msrejects) is also good. - Recovery line. The
timedOutregex is unchanged from the telemetry split, soflow_timeoutandflow_errorbehave as before. The negative test (CSRF mismatch → no recovery line) is a good touch.
Nits
- The waiting line hardcodes the window (
oauth.ts:166-168). It prints "up to 60 minutes" even whenopts.timeoutMsis overridden. No production caller overrides it today, but deriving the text from the effective timeout, or exportingDEFAULT_TIMEOUT_MSand formatting from it, would keep the message and the timer from drifting apart the next time someone changes one of them. - The docs line says "If it times out, run it again." It could also mention
--devicefor SSH or headless setups where the browser can't reach the loopback port, since that's the other common "never called back" case. Optional.
Not verified
- A real checkout taking more than 5 minutes end to end. Same gap as the PR states.
- Whether a purchase made during a timed-out login is visible on the account. The PR doesn't claim this either, and I agree with not printing anything about it.
- CI was still running when I reviewed. I'll check it before anyone asks for an approve.
— Somu
This branch was successfully deployed
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.
Problem
hyperframes auth loginwaits for the browser on a loopback listener that gave up after 5 minutes. The HyperFrames paywall now runs inside that OAuth flow (plan choice, Stripe checkout, return trip), so a slower purchase ended with the CLI printingSign-in failed: OAuth callback timed out after 300000ms. The browser's Authorize step then redirected to a dead port and showedERR_CONNECTION_REFUSED. Seen in production on 2026-10-31 on CLI 0.8.223.Change
loopback.ts). Pacific keeps the OAuth plan-checkout handoff for 60 minutes (MAX_AGE_MS,planCheckoutHandoff.ts), so a shorter limit leaves the same failure for slower checkouts.Run `hyperframes auth login` again.120scomments corrected;docs/packages/cli.mdxmentions the window.The 300s value came in with #6754 (re-landed as #6833); neither commit message gives a reason for it. Flagging in case its author knows one.
Cost
An abandoned login now blocks its terminal for up to an hour (Ctrl+C ends it).
Not in this PR
--deviceflow: its page has no checkout code, so no paywall wait.Tests
startLoopbackis removed); timeout fires at exactly 60 min, not before.src/auth+src/commands/auth: 238 pass. Fullpackages/clirun: 8 failures (checkSweep WebGL ×2, fileWatcher.atomic, studioServer.stampOnOpen, whisper manager.install, sherpa ×3), the same 8 fail with the original source and none import auth.🤖 Generated with Claude Code