Skip to content

feat(self-driving): provision an account when no PostHog is found#774

Open
rafaeelaudibert wants to merge 1 commit into
mainfrom
vincent/wizard-self-driving-provisioning
Open

feat(self-driving): provision an account when no PostHog is found#774
rafaeelaudibert wants to merge 1 commit into
mainfrom
vincent/wizard-self-driving-provisioning

Conversation

@rafaeelaudibert

Copy link
Copy Markdown
Member

What

Builds on the #760 self-driving "integrate first" flow. When self-driving falls back to "no PostHog found", we now ask the user whether they already have a PostHog account, and route auth accordingly — instead of always assuming OAuth.

The merged integration-check screen now offers two answers (both still integrate the SDK first):

  • Yes — log me in → authenticate via OAuth (unchanged default).
  • No — create one for me → collect email + cloud region, flip session.signup, and let authenticate() take the existing provisioning path (askForProvisioningSignupprovisionNewAccount: create the account, email a login link). No --signup / --email flags needed — it's all interactive now.

Why

A project with no PostHog SDK is often a project whose owner has no PostHog account yet. Previously that user hit OAuth and had to go create an account out-of-band first. Now the wizard provisions one for them in place.

Notable detail — AI opt-in gate

A provisioning access token deliberately omits the organization:read scope (WIZARD_PROVISIONING_SCOPES), so apiUser stays null and organization.is_ai_data_processing_approved can never be read back. The AI opt-in gate (session.ci || aiApproved) would therefore never clear for a provisioned account and the run would hang. This treats signup as auto-consent alongside ci (they're already grouped as one non-interactive mode in shouldDisableAsk) — which also fixes the same latent hang in the base wizard --signup flow.

Changes

  • SelfDrivingIntegrationCheckScreen.tsx — rewritten to a 3-stage screen: ask → email input → region picker.
  • store.tschooseProvisionAccount(email, region) sets signup/email/region/integrate in one atomic emit.
  • ai-opt-in-gate.tssignup auto-consents like ci.
  • self-driving.ts — refreshed --integrate help text and the --signup-rejection message (points users at the interactive flow).
  • wizard-session.ts — corrected the stale integrate doc comment.
  • Tests in store.test.ts and programs.test.ts.

Testing

pnpm build ✅ · pnpm lint ✅ (0 errors) · targeted unit tests ✅. The only failing tests in the full suite are 3 pre-existing provision-cli.test.ts failures present on main before this change.

🤖 Generated with Claude Code

When self-driving falls back to "no PostHog found", the integration-check
screen now asks whether the user already has a PostHog account instead of
just confirming setup:

- "Yes — log me in" → integrate the SDK and authenticate via OAuth (unchanged
  default).
- "No — create one for me" → collect email + cloud region, flip session.signup,
  and let authenticate() take the existing provisioning path (create the
  account, email a login link). No --signup/--email flags needed.

Also treat signup as auto-consent in the AI opt-in gate: a provisioning access
token omits the organization:read scope, so apiUser stays null and the gate
would otherwise never clear (this also fixes the same latent hang in the base
`wizard --signup` flow).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci basic-integration
  • /wizard-ci error-tracking-upload-source-maps
  • /wizard-ci mcp-analytics
  • /wizard-ci misc
  • /wizard-ci revenue

Test an individual app:

  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
Show more apps
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci error-tracking-upload-source-maps/android
  • /wizard-ci error-tracking-upload-source-maps/cicd-docker-node-raw
  • /wizard-ci error-tracking-upload-source-maps/cicd-github-actions-docker-node-raw
  • /wizard-ci error-tracking-upload-source-maps/cicd-github-actions-nested-docker-node-raw
  • /wizard-ci error-tracking-upload-source-maps/cicd-github-actions-node-raw
  • /wizard-ci error-tracking-upload-source-maps/cicd-github-actions-single-stage-docker-node-raw
  • /wizard-ci error-tracking-upload-source-maps/cicd-gitlab-node-raw
  • /wizard-ci error-tracking-upload-source-maps/cicd-monorepo-pnpm-node-react
  • /wizard-ci error-tracking-upload-source-maps/cicd-monorepo-raw-node-react
  • /wizard-ci error-tracking-upload-source-maps/cicd-ssh-vps-node-raw
  • /wizard-ci error-tracking-upload-source-maps/flutter
  • /wizard-ci error-tracking-upload-source-maps/ios
  • /wizard-ci error-tracking-upload-source-maps/next
  • /wizard-ci error-tracking-upload-source-maps/next-no-posthog
  • /wizard-ci error-tracking-upload-source-maps/node-raw
  • /wizard-ci error-tracking-upload-source-maps/node-rollup
  • /wizard-ci error-tracking-upload-source-maps/node-rollup-typescript-plugin
  • /wizard-ci error-tracking-upload-source-maps/node-webpack
  • /wizard-ci error-tracking-upload-source-maps/nuxt-3-6
  • /wizard-ci error-tracking-upload-source-maps/nuxt-4-3
  • /wizard-ci error-tracking-upload-source-maps/react-native
  • /wizard-ci error-tracking-upload-source-maps/react-vite
  • /wizard-ci error-tracking-upload-source-maps/rust
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci misc/quack-quack
  • /wizard-ci revenue/stripe

Results will be posted here when complete.

@rafaeelaudibert rafaeelaudibert requested a review from a team June 30, 2026 17:12

@gewenyu99 gewenyu99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff. Some comments for sanity. I will need to test this when I get a lil time.

Thanks for doing this <3

Did you want to include provisioning logic/paths for headless here too?

Comment thread src/ui/tui/store.ts
* OAuth. The "yes, I have an account" branch uses `setIntegrate(true)` and
* leaves `signup` false so auth runs the normal OAuth login.
*/
chooseProvisionAccount(email: string, region: CloudRegion): void {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this method name. I understand it's used by the provision path, but this is business logic about how that provisioning works.

This business logic should live with the provisioning code and that provisioning code should update the store from there.


if (stage === 'region') {
return (
<Box flexDirection="column" flexGrow={1}>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we split this UI into it's own component? Flow is confusing to read. This UI shows up after you select log me in vs sign up right?

Copy link
Copy Markdown
Member Author

@gewenyu99 I don't think we need that for headless right now because the only usecase we have for it is when someone's already logged in

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants