Skip to content

feat(web): first-run welcome wizard with agent setup and project import - #5362

Open
t3dotgg wants to merge 2 commits into
mainfrom
t3code/overhaul-onboarding-flow
Open

feat(web): first-run welcome wizard with agent setup and project import#5362
t3dotgg wants to merge 2 commits into
mainfrom
t3code/overhaul-onboarding-flow

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Aug 4, 2026

Copy link
Copy Markdown
Member

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).

Connection choice

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-minted t3 pair flow:

Direct pairing

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:

Agents

4. Project import — new read-only agentSessions.scan RPC 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 normal project.create dispatch, so dedupe and validation come free. Projects only; thread history import is a follow-up.

Import
Import choose

How it gates

FirstRunGate wraps 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

  • Scanner: 7 unit tests (transcript parsing, cwd grouping, source merge, dead-path drop, malformed lines, missing homes, worktree exclusion)
  • RPC scope exhaustiveness test passes; contracts/server/web typecheck and lint clean
  • Screenshots above are from a real fresh-state run: paired browser → auto-redirect to /welcome → full flow against live provider probes and a real home-dir scan

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. FirstRunGate wraps the authenticated root tree, blocks the shell until onboarding is decided, and redirects to /welcome when onboardingCompletedAt is unset and the workspace looks fresh (with a 4s fallback if bootstrap never completes). Completion is stored via new onboardingCompletedAt client settings.

WelcomeWizard walks 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-only agentSessions.scan WebSocket RPC backed by AgentSessionScanner, which reads Claude and Codex transcript prefixes for cwd, merges sources, flags paths already imported, excludes T3 worktree sandboxes, and returns candidates sorted by recency; the UI creates projects via existing project.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

  • Adds a multi-step /welcome onboarding 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.
  • Adds FirstRunGate.tsx that defers rendering the main app shell until freshness is determined; fresh workspaces are redirected to /welcome, with a 4-second fallback to the normal app.
  • Adds AgentSessionScanner.ts on the server to scan Claude and Codex transcript directories, filter managed worktrees, deduplicate by real path, mark already-imported projects, and return sorted candidates via a new agentSessions.scan WebSocket RPC.
  • Adds onboardingCompletedAt to ClientSettingsSchema (null by default) to persist wizard completion state.
  • Behavioral Change: the authenticated app shell and event routing are blocked from mounting until FirstRunGate resolves its decision, which may delay startup by up to 4 seconds on slow environments.

Macroscope summarized ef31f17.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 38f0f01c-f73b-4d26-819e-cdb1d5f1e8ca

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 4, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Comment thread packages/contracts/src/agentSessions.ts Outdated
Comment thread apps/server/src/ws.ts Outdated
Comment thread apps/server/src/project/AgentSessionScanner.ts Outdated
Comment thread apps/server/src/project/AgentSessionScanner.ts
Comment thread apps/server/src/project/AgentSessionScanner.ts
Comment thread apps/server/src/project/AgentSessionScanner.ts
Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx Outdated
Comment thread apps/web/src/components/onboarding/FirstRunGate.tsx Outdated
Comment thread apps/server/src/project/AgentSessionScanner.ts Outdated
Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx
Comment thread docs/user/welcome-wizard.md Outdated

## Set up your agents

The wizard checks the connected machine for Claude Code and Codex and shows

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 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.

Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx Outdated
Comment thread apps/web/src/components/onboarding/FirstRunGate.tsx Outdated
Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx
Comment thread apps/server/src/project/AgentSessionScanner.ts
@macroscopeapp

macroscopeapp Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx
Comment thread apps/server/src/project/AgentSessionScanner.ts

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Comment thread apps/server/src/project/AgentSessionScanner.ts Outdated
Comment thread apps/server/src/project/AgentSessionScanner.ts Outdated
Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Comment thread apps/server/src/project/AgentSessionScanner.ts Outdated
Comment thread apps/server/src/project/AgentSessionScanner.ts Outdated
Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx Outdated
Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx Outdated
Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx
Comment thread apps/server/src/project/AgentSessionScanner.ts Outdated
Comment thread apps/server/src/project/AgentSessionScanner.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Comment thread packages/contracts/src/agentSessions.ts Outdated
Comment thread apps/web/src/components/onboarding/WelcomeWizard.tsx
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>
@t3dotgg
t3dotgg force-pushed the t3code/overhaul-onboarding-flow branch from 8e67f03 to 986f1f5 Compare August 4, 2026 23:41
]);

useEffect(() => {
if (decision !== "pending") return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 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.

Suggested change
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 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."

Comment on lines +812 to +814
if (result._tag === "Failure" && !isAtomCommandInterrupted(result)) {
failures += 1;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 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.

Suggested change
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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ 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]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Fix in Cursor Fix in Web

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant