Repository navigation
fix(desktop): Antigravity Sign in opens the browser right away - #30126
wenshen18643 wants to merge 1 commit into
Conversation
Antigravity's runtime takes about a minute on Windows to produce its Google link, and the Account row only offered an Open browser button while Settings stayed open, so desktop sign-ins usually expired unseen. On desktop, Sign in now opens a local loopback page immediately; it forwards to the validated Google link when the runtime reports it, even if Settings was closed, or says that sign-in stopped. Web clients keep the button. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — Desktop Antigravity sign-in now opens a browser immediately using a bounded local waiting page. Human review is required for this default interaction change and the new file-level diagnostic suppressions in PendingSignInPage.ts. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
Problem
In the desktop app, pressing Sign in for Antigravity looks like it does nothing. The Google link does not exist yet: the Antigravity runtime creates it (OAuth state, PKCE, and a
127.0.0.1redirect to its own listener), and on Windows the runtime takes about a minute to start (measured in #30079). When the link does arrive, the Account row shows an Open browser button, but only while Settings is open. Users who leave Settings during that minute, the natural reaction to "nothing happened", never see the link. The sign-in then expires after five minutes and the account stays signed out.Reproduction: Windows 11, T3 Code desktop 0.1.6, Antigravity runtime 1.1.1. Press Sign in under Settings > Providers > Antigravity, then go back to a thread. No browser opens, and after five minutes the sign-in has expired. In my server trace:
provider.auth.startat 17:06:11, the last Settings subscription closed at 17:06:46, the link was published at 17:07:22 with no subscriber, and the flow expired at 17:11:11.Change
On desktop, Sign in now opens the browser immediately. The page there continues to Google as soon as the link exists.
apps/desktop/src/app/PendingSignInPage.ts): starts a short-lived loopback listener on127.0.0.1with a random port and a 256-bit random path, and opens the browser to it with the existingElectronShell.openExternal. It is modeled on the ChatGPT loopback helper (packages/shared/src/codexAuthCallback.ts).303to Google. Onlyhttps://accounts.google.com/o/oauth2/v2/authis accepted, and the stored URL is the parsedhref.GETon the exact path withHost: 127.0.0.1:<port>, which rules out DNS rebinding. Responses areno-store,no-referrer,nosniff, with a strict CSP.openPendingSignIn()andsettlePendingSignIn(id, url | null), with schema-validated payloads, on the main window's bridge.watchProviderSignInLinkwatchesproviderAuthStatethrough the app atom registry, so the subscription outlives the Settings view. It hands over the link for the flow this client started. It callsonEndif that flow ends, disappears after being seen (for example on a server restart), or times out.ProviderAuthenticationSectionuses it only for Antigravity Google sign-in on desktop, not for API-key connections. If the page cannot open, or forwarding fails, the link opens directly when it arrives. Web clients keep Open browser, since a tab opened without a click would be blocked.docs/user/providers-antigravity.md.Linux behaves the same in the desktop app, because Electron opens the default browser. A headless Linux server has no desktop app, so its web clients keep the button.
Related: #30079 fixes the misleading "has not reached Google" hint shown during the same startup wait. The two changes are independent.
Scope and approval
This changes desktop sign-in so the browser opens on the click instead of after a second click about a minute later. I'm submitting it as a focused fix because, today, a desktop Google sign-in only finishes if the user stays on Settings for a minute and then clicks again. Meanwhile the Account row already says "Finish signing in in your browser." while no browser is open. Nothing opens except the validated Google link the server already shows to the client that started sign-in. If you'd rather settle the behavior in an Ideas discussion first, I'm happy to move it there.
Verification
vp test run apps/desktop/src/app/PendingSignInPage.test.ts: 9/9 pass, over real loopback HTTP. They cover:404for a wrong path or a reboundHost303to the exact link, including normalization of a trailing control characterStable over three runs.
vp test run apps/web/src/providerSignInLink.test.ts: 8/8 pass. They cover:onEndwhen the flow is cancelled, vanishes after being seen, or times out, but not on an early stopproviderAuthState, staying subscribed after the "Settings" mount is released and closing after the link opens. Without the watcher, that test fails because the stream closes on unmount.vp test run apps/web/src/components/settings/ProviderSetupSection.browser.test.tsx: 6/6 pass. They check that, with a desktop bridge, Sign in opens the pending page and the watcher settles it with the link ornull. Without a bridge, neither happens. A Gemini API key Connect opens no page. With the component change reverted, the desktop case fails.Real Chromium (Playwright, with
accounts.google.commapped to NXDOMAIN so nothing reached Google): the page loaded as "Starting sign-in · T3 Code" and kept refreshing for 3 s. Within about 1 s of settling, the browser requested the exact Google link. A page settled withnullshowed "Sign-in stopped · T3 Code".vp test run apps/desktop/src/ipc apps/desktop/src/app/DesktopApp.test.tspasses.tsc --noEmitforpackages/contracts,apps/desktopandapps/web, plusvp lintandvp fmt --checkon the changed files, are clean.Not checked: I did not run the packaged or dev desktop app end to end, so the click-to-browser step through Electron's
shell.openExternalis covered by the existing bridge, not by a recording. I have no macOS or Linux desktop to try.Done with Claude Opus 5.5 in Claude Code.
🤖 Generated with Claude Code