feat(web): first-run welcome wizard with agent setup and project import - #5362
feat(web): first-run welcome wizard with agent setup and project import#5362t3dotgg wants to merge 2 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Effect service conventions review of the new agent-session scanner service, its contract error, and the WS wiring. Three convention violations found; details inline.
Posted via Macroscope — Effect Service Conventions
|
|
||
| ## Set up your agents | ||
|
|
||
| The wizard checks the connected machine for Claude Code and Codex and shows |
There was a problem hiding this comment.
🟢 Low user/welcome-wizard.md:19
The documentation states that after the install command runs, the user can "complete the CLI's own sign-in in the same terminal." This does not match the actual wizard flow: AgentInstallTerminal only pre-types the install command and does not follow it with a login command. After installation, the user must close the terminal, wait for providers to refresh, and use the separate Sign in action — they cannot stay in the same terminal to sign in. Update this section to describe the actual sequence the user must follow.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @docs/user/welcome-wizard.md around line 19:
The documentation states that after the install command runs, the user can "complete the CLI's own sign-in in the same terminal." This does not match the actual wizard flow: `AgentInstallTerminal` only pre-types the install command and does not follow it with a login command. After installation, the user must close the terminal, wait for providers to refresh, and use the separate `Sign in` action — they cannot stay in the same terminal to sign in. Update this section to describe the actual sequence the user must follow.
ApprovabilityVerdict: Needs human review This PR introduces a substantial new feature (first-run welcome wizard) with new user-facing workflows, server-side scanning, and app gating logic. Additionally, multiple unresolved high-severity review comments identify potential bugs in terminal session handling and import error handling that should be addressed before merge. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
One convention issue found in the new server service module. The three items flagged on the previous revision (redundant failure singleton on AgentSessionScanError, message-derived wrapper in ws.ts, unexported make) are all resolved.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
Effect service conventions review of the new AgentSessionScanner service and its RPC wiring. The three findings from the previous run (namespace import for ProjectionSnapshotQuery, structural operation discriminator on the scan error, exported make) are all addressed. Two remaining items below.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
One remaining convention deviation on the new contract error; everything else (namespace imports, single-module service layout with inline interface + make/layer, environment-based dependency acquisition, Foo["Service"] usage) looks consistent with the conventions.
Posted via Macroscope — Effect Service Conventions
New onboarding flow for fresh installs: choose how to connect (Local Only / T3 Connect / Direct), verify Claude Code and Codex with live probe status and an inline install terminal, then import existing projects discovered from Claude/Codex home directories. - FirstRunGate at the root holds back the entire authenticated tree until the first-run decision is known, so fresh installs see nothing before /welcome (no shell flash, no EventRouter thread navigation) - New read-only agentSessions.scan RPC discovers project candidates from ~/.claude/projects and Codex session rollouts (cwd read from transcript first lines, never the lossy dir slug; T3-managed worktrees excluded; stat and read work both bounded) - Import creates projects via existing project.create dispatch; default window is last 30 days, full checklist behind Choose - onboardingCompletedAt client setting gates the wizard; installs that predate the field only qualify when the workspace is fresh Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8e67f03 to
986f1f5
Compare
| ]); | ||
|
|
||
| useEffect(() => { | ||
| if (decision !== "pending") return; |
There was a problem hiding this comment.
🟡 Medium onboarding/FirstRunGate.tsx:91
The fallback timer fires even before client settings have hydrated, so a slow hydration (over 4s) sets decision to "app" and the decision effect can never inspect onboardingCompletedAt or the workspace — it only runs while decision === "pending". A genuinely fresh install with slow settings hydration permanently skips the welcome wizard for that mount. Consider gating the timer on hydrated so it only starts after settings are available.
| if (decision !== "pending") return; | |
| if (decision !== "pending" || !hydrated) return; |
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/onboarding/FirstRunGate.tsx around line 91:
The fallback timer fires even before client settings have hydrated, so a slow hydration (over 4s) sets `decision` to `"app"` and the decision effect can never inspect `onboardingCompletedAt` or the workspace — it only runs while `decision === "pending"`. A genuinely fresh install with slow settings hydration permanently skips the welcome wizard for that mount. Consider gating the timer on `hydrated` so it only starts after settings are available.
| desktop app and locally served web app. | ||
| - **T3 Connect** — sign in and reach any of your machines from anywhere. | ||
| Machines signed into your account connect automatically. If none are | ||
| connected yet, the wizard shows the command to run on the machine with your |
There was a problem hiding this comment.
🟢 Low user/welcome-wizard.md:12
The docs say the wizard "advances when" a connected machine appears, but the wizard only enables a Continue button — it does not advance automatically. A user following these instructions waits indefinitely instead of clicking Continue. Consider rewording to match the actual behavior, e.g. "advances when you click Continue after a machine appears."
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @docs/user/welcome-wizard.md around line 12:
The docs say the wizard "advances when" a connected machine appears, but the wizard only enables a **Continue** button — it does not advance automatically. A user following these instructions waits indefinitely instead of clicking **Continue**. Consider rewording to match the actual behavior, e.g. "advances when you click **Continue** after a machine appears."
| if (result._tag === "Failure" && !isAtomCommandInterrupted(result)) { | ||
| failures += 1; | ||
| } |
There was a problem hiding this comment.
🟠 High onboarding/WelcomeWizard.tsx:812
runImport treats interrupted createProject results as success: it excludes them from failures via isAtomCommandInterrupted, so when every selected import is interrupted (e.g. the environment disconnects mid-import), failures stays 0 and the wizard calls onDone(), closing onboarding as though all projects were imported. No projects are actually created in that case. Consider counting interrupted results as failures (or tracking them separately) so a partial or fully interrupted import does not silently complete onboarding.
| if (result._tag === "Failure" && !isAtomCommandInterrupted(result)) { | |
| failures += 1; | |
| } | |
| if (result._tag === "Failure") { | |
| failures += 1; | |
| } |
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/onboarding/WelcomeWizard.tsx around lines 812-814:
`runImport` treats interrupted `createProject` results as success: it excludes them from `failures` via `isAtomCommandInterrupted`, so when every selected import is interrupted (e.g. the environment disconnects mid-import), `failures` stays `0` and the wizard calls `onDone()`, closing onboarding as though all projects were imported. No projects are actually created in that case. Consider counting interrupted results as failures (or tracking them separately) so a partial or fully interrupted import does not silently complete onboarding.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 986f1f5. Configure here.
| input: { threadId: AGENT_ONBOARDING_THREAD_ID, terminalId }, | ||
| }); | ||
| }; | ||
| }, [closeTerminal, environmentId, terminalId]); |
There was a problem hiding this comment.
Install terminal effect race
Medium Severity
preparedRef is set after a successful open, while PTY teardown lives in a separate unmount-only effect with no matching reset. Under React Strict Mode’s setup/cleanup/setup cycle, a fast open can set the ref and then get closed by cleanup; the second setup sees the ref and skips reopen, leaving a dead install terminal and no pre-typed command.
Reviewed by Cursor Bugbot for commit 986f1f5. Configure here.
The fixture is an exhaustive ClientSettings literal, so the new field broke both desktop typecheck and the persist/reload assertion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>


Fresh installs currently drop users at an empty screen with no guidance: desktop silently pairs and shows nothing, web shows a bare token box. There was no path from "installed T3 Code" to "my agents and projects are here."
This adds a first-run welcome wizard: choose how to connect, verify your agent CLIs, and import the projects you already work on.
Flow
1. Connection choice — Local Only (preselected when a local server serves the app), T3 Connect (when cloud is configured), Direct (always).
2. Remote paths — T3 Connect signs in via Clerk then blocks until a machine connects (
npx t3 connect, list fills in live); machines already on the account get a confirmation list instead. Direct is the existing server-mintedt3 pairflow:3. Agent setup — Claude Code and Codex as cards with live probe status from the existing provider snapshots (correctly checks the connected machine on remote paths). Install/Sign-in opens the embedded terminal inline with the command pre-typed, which also handles the interactive CLI logins:
4. Project import — new read-only
agentSessions.scanRPC discovers directories Claude Code and Codex have worked in (cwd read from transcript first lines — the dir-name slug is lossy and never decoded; T3-managed worktree sandboxes excluded). Default imports the last 30 days; Choose shows everything. Projects are created through the normalproject.createdispatch, so dedupe and validation come free. Projects only; thread history import is a follow-up.How it gates
FirstRunGatewraps the authenticated tree at the root and renders nothing until the decision is known — no shell flash, no EventRouter navigating into the bootstrap thread. Completed flag set → app as soon as client settings hydrate. Flag null (also true for every install predating the field) → only a workspace with nothing beyond the server's cwd auto-bootstrap counts as fresh; anything else goes straight to the app. 4s timeout falls back to the app if shells never bootstrap.Steps after the connection choice are skippable; skipping still sets the flag.
Testing
Built by Claude Fable 5 on Claude Code.
Note
Medium Risk
Large new onboarding surface and filesystem scan RPC affect first-load routing and server I/O; logic is mostly read-only with tests, but the gate timeout can skip the wizard on slow boots.
Overview
Adds a first-run welcome flow so fresh installs are guided instead of landing on an empty app.
FirstRunGatewraps the authenticated root tree, blocks the shell until onboarding is decided, and redirects to/welcomewhenonboardingCompletedAtis unset and the workspace looks fresh (with a 4s fallback if bootstrap never completes). Completion is stored via newonboardingCompletedAtclient settings.WelcomeWizardwalks through connection choice (local / T3 Connect / direct pair), optional remote machine setup, agent CLI install/sign-in with an inline terminal, and project import. Import uses a new read-onlyagentSessions.scanWebSocket RPC backed byAgentSessionScanner, which reads Claude and Codex transcript prefixes forcwd, merges sources, flags paths already imported, excludes T3 worktree sandboxes, and returns candidates sorted by recency; the UI creates projects via existingproject.create.Reviewed by Cursor Bugbot for commit ef31f17. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add first-run welcome wizard with connection setup, agent install, and project import
/welcomeonboarding wizard (WelcomeWizard.tsx) guiding new users through environment connection (local, T3 Connect, or direct pairing), agent CLI setup (Claude Code, Codex), and optional project import from existing agent sessions./welcome, with a 4-second fallback to the normal app.agentSessions.scanWebSocket RPC.onboardingCompletedAttoClientSettingsSchema(null by default) to persist wizard completion state.FirstRunGateresolves its decision, which may delay startup by up to 4 seconds on slow environments.Macroscope summarized ef31f17.