feat(impersonate): nudge to billing add-on when impersonation is blocked#376
Conversation
When `clerk impersonate` is blocked by billing — 402 (plan gate) or 422 (billing-period limit) — surface a value-framed, numberless message and point to the account-level billing page (`<dashboard>/settings/billing`) as docsUrl. In an interactive terminal, offer to open the page (default Yes); `--yes` opens it directly, while `--print` and agent mode surface the URL without opening a browser. Every branch still exits non-zero since no session was created. Drops the used/limit quota templating (and the now-unused BillingError limit/used fields) since BAPI has no quota-read endpoint to make counts reliable.
🦋 Changeset detectedLatest commit: 086b8d3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🔗 Linked repositories identifiedCodeRabbit considers these linked repositories for cross-repo context during reviews:
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe impersonate command now maps HTTP 402 and 422 billing failures to Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Warning Review ran into problems🔥 ProblemsLinked repositories: Your configuration references 7 linked repositories, but your current plan allows 1. Analyzed Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/cli-core/src/commands/impersonate/impersonate.test.ts`:
- Around line 287-344: The non-TTY billing test is missing an assertion that the
upgrade nudge is skipped, so it could still pass even if nudgeToBilling()
wrongly prompts. Update the impersonate tests around BillingError handling to
assert the billing prompt/mockConfirm call count or exact calls, ensuring only
the pre-flight confirmation runs in the non-TTY case and no upgrade prompt is
shown.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 266cbca4-2603-4c52-866f-481a1a365c96
📒 Files selected for processing (6)
.changeset/impersonate-upgrade-nudge.mdpackages/cli-core/src/commands/impersonate/README.mdpackages/cli-core/src/commands/impersonate/impersonate.test.tspackages/cli-core/src/commands/impersonate/impersonate.tspackages/cli-core/src/lib/errors.test.tspackages/cli-core/src/lib/errors.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
clerk/clerk_go(manual)
The prior assertion only checked that the browser never opened, which would still pass if nudgeToBilling() incorrectly prompted in non-TTY mode. Assert the confirm call count so a regression there is caught.
Summary
Kyle asked (via the Slack thread on
clerk impersonate) whether hitting the impersonation limit nudges customers toward the add-on. Today it doesn't. This adds that nudge so the upgrade path is as frictionless as possible now that the CLI makes it easier to hit the limit.When
POST /v1/actor_tokensis rejected by billing,clerk impersonatenow guides you to the billing page instead of just printing a terse error:Impersonation is available as an add-on.You've reached your impersonation limit this billing period.Both attach the account-level billing page (
<dashboard>/settings/billing, fromgetDashboardUrl(), honoringCLERK_DASHBOARD_URL) asdocsUrl, and the command still exits non-zero (no session was ever created). How the URL is surfaced follows the output mode:docsUrl. Never opens a browser.--print--yes--yes--yesOther changes
(used X/Y this billing period)templating — the copy is deliberately numberless (BAPI has no quota-read endpoint, so counts can't be shown proactively or reliably).limit/usedfields fromBillingError(impersonate was the only consumer and no longer passes them).Out of scope
Test Plan
bun run format:check·bun run lint·bun run typecheck— all cleanbun run test— 1896 pass (adds gating-branch coverage for agent /--print/--yes/ TTY-prompt / non-TTY, plus wire-level 402/422 mapping and docsUrl assertions)bapiRequest → BapiError(402/422) → nudgestack against a local stub BAPI: 402 → add-on message, 422 → limit message, both withdocsUrl = <dashboard>/settings/billing; confirmedopenBrowseris invoked with the billing URL on the--yesbranch.bun run test:e2e:op— not run locally: the runner needs theAI Enablement1Password vault, which this environment can't access. The e2e suite has no impersonate coverage, so it wouldn't exercise this change regardless; CI will run it on the PR.Notes
Minor bump changeset included (
clerk).