Advance onboarding on a post-checkout return (REV-1952) - #14736
Merged
Conversation
Buying a one-time credit pack on the web after leaving the onboarding offer through the plan CTA stranded the user: the confirmation page returns through `warp://settings/billing_and_usage`, which is gated on `AuthOnboardingState::Terminal` and so only produced "Auth not complete before trying to open settings page". Onboarding now takes any signal that the user can use AI as the offer being satisfied: - `checkoutSuccessful=true` on the desktop hand-off advances the AI-sell offer, whichever product was bought. - A Billing & Usage deeplink arriving mid-onboarding is read as that same return instead of reporting an error; outside onboarding it still opens the page. - Completion no longer requires a client-recorded `AwaitingCheckout`, so it works regardless of which call to action opened the browser. - Returning to the app now re-reads AI credit availability, which the focus path never did, through one shared refresh also used on auth completion. Co-Authored-By: Warp Agent <agent@warp.dev>
jefflloyd
approved these changes
Aug 5, 2026
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.
Description
During account-first onboarding, picking the Warp plan option on the "Choose how to start" offer opens
/upgradein the browser. If the user changes their mind on the web and buys a one-time credit pack instead, the confirmation page returns them throughwarp://settings/billing_and_usage. That deeplink is gated onAuthOnboardingState::Terminal, so mid-onboarding it only produced:and onboarding never left the offer slide. Nothing else picked the purchase up either: the offer's completion path required a client-recorded
CreditPurchaseState::AwaitingCheckout, which only the in-client pack CTA sets, and the app-focus refresh never re-read AI credit availability at all.This is the client half of REV-1952. The web half (making the add-on confirmation card hand off through
computeAppLaunchUrlwithcheckoutSuccessful=true) ships separately inwarpdotdev/warp-server; the two PRs share that exact param name and value.What changed
checkoutSuccessful=trueconvention (app/src/uri/mod.rs).url_reports_checkout_successrecognises the flag on any incoming deeplink, andRootView::handle_incoming_auth_urlroutes it into onboarding so the desktop hand-off advances the AI-sell stage rather than only re-initialising auth.app/src/root_view.rs). A Billing & Usage deeplink arriving while onboarding is non-Terminal is read as the same post-checkout return and advances the flow. Outside onboarding the deeplink still opens Billing & Usage exactly as before, and any other section arriving non-Terminal still reports the original error.crates/onboarding/src/model.rs). The offer completes on any observation that the user can now make an AI request — plan or pack, bought in the client or on the web — instead of tracking which purchase the client started. The head-start offer is deliberately excluded: it ships with AI usage already on the account, so availability says nothing about the user's choice there.app/src/root_view.rs).AppBecameActiveandAuthCompletenow share onerefresh_onboarding_account_state, which adds the AI-credit-availability refresh the focus path was missing. That single check is what the offer advances off, so a user who ignores the intent link and just refocuses the app is let through.AuthManager::upgrade_url()already appendsstate, which is what the confirmation page keys its onboarding detection off, and it backs every onboarding surface that opens the web upgrade page.Linked Issue
REV-1952 — labeled
triage-done(the requester declined a written spec, so the ticket's Acceptance Criteria are the contract).Testing
Regression tests added, each verified to fail before the change and pass after:
onboarding model::tests::credit_availability_advances_the_offer_without_a_pending_checkout— the exact reported path (left through the plan CTA, bought a pack on the web, no client-side checkout recorded). Confirmed failing against the oldAwaitingCheckoutgate.onboarding model::tests::the_checkout_success_handoff_advances_the_ai_sell_offeronboarding model::tests::the_checkout_success_handoff_is_inert_outside_an_ai_sell_offer— covers the head-start offer and pre-offer slides.warp uri::tests::test_url_reports_checkout_success— only an explicittruecounts, and the flag is recognised on both the auth and settings hosts.Commands run from the repo root:
./script/format— clean.cargo clippy -p onboarding -p warp --all-targets --tests -- -D warnings— clean.cargo nextest run -p onboarding --no-fail-fast— 52 passed, 0 failed.cargo nextest run -p warp -E 'test(uri::) or test(root_view)'— 78 passed, 0 failed.I have manually tested my changes locally with
./script/runScreenshots / Videos
The fixed path itself is not visually verified — treat that proof as outstanding. Reaching the "Choose how to start" offer requires a brand-new authenticated account, and exercising the crossover additionally requires a live Stripe checkout plus the paired
warpdotdev/warp-serverchange. None of those are available in this environment, so a human should confirm the rendered behaviour: new account → offer slide → Warp plan → buy a pack on the web → return to the app → onboarding advances with no auth error in the logs.What the recording below does show is a smoke test of the surrounding flow on a Linux build of this branch: the app launches and the first-run onboarding renders and navigates ("Welcome to Warp" → "Customize your Warp" → "Choose a theme" → "Create an account"), with no crash, hang, or error output beyond two benign
libEGL ... DRI3warnings. Advancing stops at the account screen, which is exactly where the unreachable post-auth offer would follow.Computer-use video recordings
View video recording - Warp onboarding walkthrough: Walking forward through the Warp first-run onboarding screens starting from "Welcome to Warp" until reaching the sign-in screen, then closing the app.
Computer-use screenshots (4)
View screenshot - Onboarding screen 1: "Welcome to Warp" with a "Get started" button and "Already have an account? Log in" link.
View screenshot - Onboarding screen 2: "Customize your Warp" with cards Tab styling/Vertical, Tools panel, Code review/Enabled, and a Next button.
View screenshot - Onboarding screen 3: "Choose a theme" with theme cards Phenomenon, Dark (selected), Light, Adeberry, and a "Sync light/dark theme with OS" checkbox.
View screenshot - Onboarding screen 4: "Create an account" with a "Use a work email to find teammates" card, Privacy Settings/Terms of Service links, and Skip/Continue buttons — the sign-in screen.
Agent Mode
CHANGELOG-BUG-FIX: Onboarding now continues past the AI offer after you buy credits or a plan on the web, instead of getting stuck.
Originating thread: https://warpdev.slack.com/archives/C0BDQDW8V5E/p1785947040574599
Conversation: https://staging.warp.dev/conversation/38020832-369f-4abd-82a6-cac6d8290474
Run: https://oz.staging.warp.dev/runs/019fd30e-587c-77c5-ae31-ed8bbc03bd6b
This PR was generated with Oz.