Skip to content

feat(agent): overhaul onboarding launch flow#464

Open
felarof99 wants to merge 3 commits intomainfrom
feat/new-onboarding-codex
Open

feat(agent): overhaul onboarding launch flow#464
felarof99 wants to merge 3 commits intomainfrom
feat/new-onboarding-codex

Conversation

@felarof99
Copy link
Contributor

@felarof99 felarof99 commented Mar 11, 2026

Summary

  • replace the old onboarding + demo path with a five-step setup that asks who the user is, imports Chrome context, connects Google apps, previews BrowserOS power features, and launches directly into /home
  • seed the first home-page chat with onboarding context, a LinkedIn tab, consent-based Gmail/Calendar follow-up, and a suggested 09:00 AM daily briefing task
  • surface BrowserOS differentiators during onboarding, including SOUL.md, custom skills, bring-your-own model keys, and scheduled tasks
  • scope the new-tab chat bootstrap to the launching tab so the onboarding handoff cannot be consumed by the wrong /home tab when multiple tabs are open

Key Changes

  • redesigned the onboarding landing page and step shell to make the flow feel like product setup instead of a generic intro
  • expanded onboarding profile data with assistant naming and Chrome import state, and sync the assistant name into saved profile preferences
  • replaced the old sign-in step with Google sign-in plus Gmail / Google Calendar managed app connection cards
  • added a launch step that opens LinkedIn in the background, writes the initial BrowserOS prompt, and redirects straight to the main home page
  • taught /home inline chat to consume targeted onboarding search actions, while sidepanel chat ignores new-tab-targeted actions

Verification

  • bunx biome check apps/agent/entrypoints/app/App.tsx apps/agent/entrypoints/newtab/index/NewTab.tsx apps/agent/entrypoints/onboarding/demo/OnboardingDemo.tsx apps/agent/entrypoints/onboarding/index/Onboarding.tsx apps/agent/entrypoints/onboarding/steps/CapabilitiesStep.tsx apps/agent/entrypoints/onboarding/steps/ImportChromeStep.tsx apps/agent/entrypoints/onboarding/steps/LaunchStep.tsx apps/agent/entrypoints/onboarding/steps/ManagedAppConnectionCard.tsx apps/agent/entrypoints/onboarding/steps/StepOne.tsx apps/agent/entrypoints/onboarding/steps/StepScaffold.tsx apps/agent/entrypoints/onboarding/steps/StepTransition.tsx apps/agent/entrypoints/onboarding/steps/StepTwo.tsx apps/agent/entrypoints/onboarding/steps/StepsLayout.tsx apps/agent/entrypoints/onboarding/steps/steps.ts apps/agent/entrypoints/sidepanel/index/useChatSession.ts apps/agent/lib/onboarding/buildOnboardingLaunchPrompt.ts apps/agent/lib/onboarding/launchOnboardingChat.ts apps/agent/lib/onboarding/onboardingStorage.ts apps/agent/lib/onboarding/syncOnboardingProfile.ts apps/agent/lib/search-actions/searchActionsStorage.ts
  • bun run --filter @browseros/agent typecheck
  • live-verified the onboarding routes in the dev BrowserOS instance, including:
    • landing page and steps 1 / 3 / 5 rendering
    • launch button opening LinkedIn in the background and redirecting to /home
    • inline /home chat auto-starting with the personalized onboarding prompt
    • targeted handoff still landing in the correct tab even with multiple /home tabs open

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 11, 2026

Greptile Summary

This PR wires first-run users through the feature tour before setup, introduces explicit revisit flows from Settings, extracts a shared OnboardingProgress step header used across setup steps and the demo screen, and fixes auth redirect handling so magic-link and Google sign-in both resume back into the correct onboarding screen after authentication.

Key changes:

  • New onboardingFlow.ts module centralises all onboarding path helpers and the source query-param contract, replacing scattered hardcoded strings across five files.
  • OnboardingProgress extracted as a standalone component (replacing the inline progress indicator in StepsLayout) and reused on OnboardingDemo so step 3 ("First Task") feels like a cohesive last step.
  • Onboarding.tsx (welcome screen) branches between first-run and revisit UI based on a ?source=revisit param or an async storage read of onboardingCompletedStorage. The storage read starts with false, causing a brief flash of first-run copy for returning users who navigate directly to /onboarding without the source param.
  • StepOne pre-populates the profile form from storage on revisit so users don't lose previously entered data.
  • StepTwo now correctly sets authRedirectPathStorage for the magic-link flow (previously only Google) and clears it on skip/error.
  • SettingsSidebar fixes the active-state detection to strip query params before pathname comparison.

Confidence Score: 4/5

  • Safe to merge with minor polish; no data-loss or security risks, one mild UX flash for returning users.
  • The core routing logic is sound, auth redirect handling is improved and cleans up after errors/skips, and the shared progress component is a clean extraction. The main concern is a cosmetic flash of first-run UI for returning users who navigate directly to /onboarding without the ?source=revisit param — a one-line initialisation fix resolves it. The currentStep as 1 | 2 cast is low-risk given internal navigation only ever produces valid values.
  • apps/agent/entrypoints/onboarding/index/Onboarding.tsx — hasCompletedOnboarding initialisation can cause a first-run flash for returning users.

Important Files Changed

Filename Overview
apps/agent/lib/onboarding/onboardingFlow.ts New module centralising all onboarding paths and the flow-source mapping. Clean, well-typed; the 'revisit'→'settings' normalisation in getOnboardingFlowSource is intentional and consistent across callers.
apps/agent/entrypoints/onboarding/index/Onboarding.tsx Welcome screen now branches between first-run and revisit flows. Has a flash issue: hasCompletedOnboarding initialises to false, so returning users navigating directly to /onboarding briefly see first-run copy before storage resolves.
apps/agent/entrypoints/onboarding/steps/OnboardingProgress.tsx New shared progress-indicator component extracted from StepsLayout. Logic is sound; lacks horizontal connector lines between step circles (cosmetic gap inherited from the original inline implementation).
apps/agent/entrypoints/onboarding/steps/StepsLayout.tsx Switched to shared OnboardingProgress and onboardingFlow helpers. Minor: `currentStep as 1
apps/agent/entrypoints/onboarding/steps/StepOne.tsx Adds a useEffect to pre-populate the form from stored profile data on revisit. Pattern (cancelled flag + form.reset) is correct and handles the async read safely.
apps/agent/entrypoints/onboarding/steps/StepTwo.tsx Correctly derives redirectPath from flow source and uses it for both magic-link and Google sign-in. authRedirectPathStorage is cleaned up on skip and on auth errors. handleSkip is now async and consistently wraps skip buttons with void.
apps/agent/entrypoints/app/login/MagicLinkCallback.tsx Reads authRedirectPathStorage after auth to resume into the correct onboarding screen. Cleanup/cancelled-flag pattern is correct; early-return branches for error/pending don't need cleanup since the async redirect is never started in those paths.
apps/agent/entrypoints/onboarding/features/Features.tsx Adds isSetupFlow flag gated on query-param source. Setup flow renders "Continue Setup" + "Back to Welcome" CTA; non-setup flow renders "Start Using BrowserOS" + "Revisit Guided Setup". Logic is clean.
apps/agent/entrypoints/onboarding/demo/OnboardingDemo.tsx Integrates OnboardingProgress (step 3) and adds a Back button to step 2. Source-aware navigation is correct; layout refactor is clean with no functional regressions.
apps/agent/components/sidebar/SettingsSidebar.tsx Delegates sidebar nav paths to onboardingFlow helpers and fixes active-state detection to strip query params before pathname comparison. Both changes are correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["/onboarding\nWelcome Screen"] -->|first-run| B["/onboarding/features?source=setup\nFeature Tour"]
    A -->|returning user\n?source=revisit| C["/onboarding/features?source=settings\nFeature Tour"]
    A -->|returning user\nOpen BrowserOS| H["/home"]

    B -->|Continue Setup| D["/onboarding/steps/1?source=setup\nStep 1 · About You"]
    C -->|Revisit Guided Setup| D2["/onboarding/steps/1?source=settings\nStep 1 · About You"]
    C -->|Start Using BrowserOS| H

    D --> E["/onboarding/steps/2?source=setup\nStep 2 · Sign In"]
    D2 --> E2["/onboarding/steps/2?source=settings\nStep 2 · Sign In"]

    E -->|Skip| F["/onboarding/demo?source=setup\nStep 3 · First Task"]
    E2 -->|Skip| F2["/onboarding/demo?source=settings\nStep 3 · First Task"]

    E -->|Magic Link / Google| G[(authRedirectPathStorage\n= /onboarding/demo?source=...)]
    E2 -->|Magic Link / Google| G
    G -->|auth completes| CB[MagicLinkCallback\nreads stored path]
    CB --> F
    CB --> F2

    F --> H
    F2 --> H

    I[Settings Sidebar] -->|Explore Features| C
    I -->|Revisit Onboarding| A
Loading

Last reviewed commit: 65afe99

Comment on lines 21 to 32
const [hasCompletedOnboarding, setHasCompletedOnboarding] = useState(false)
const isRevisit = searchParams.get('source') === 'revisit'
const usesManualFlow = hasCompletedOnboarding
const showRevisitCopy = hasCompletedOnboarding || isRevisit

useEffect(() => {
setMounted(true)
track(ONBOARDING_STARTED_EVENT)
onboardingCompletedStorage
.getValue()
.then((completed) => setHasCompletedOnboarding(completed))
}, [])
Copy link
Contributor

Choose a reason for hiding this comment

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

Flash of first-run UI for returning users

hasCompletedOnboarding initialises to false, so showRevisitActions is false on every first render. For a returning user who navigates to /onboarding directly (without ?source=revisit), the page paints the first-run copy ("Open-Source Agentic Browser", "Get Started") before the storage promise resolves and setHasCompletedOnboarding(true) triggers a re-render to the revisit copy. The fade-in animation makes this flash more visible rather than less.

Consider initialising the state as null to delay rendering until the storage read resolves, or at minimum keeping an isLoading flag:

const [hasCompletedOnboarding, setHasCompletedOnboarding] = useState<boolean | null>(null)
...
// defer content until storage resolves
if (hasCompletedOnboarding === null && !isRevisit) return null

This avoids the mid-animation content swap for direct /onboarding visits from returning users.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/agent/entrypoints/onboarding/index/Onboarding.tsx
Line: 21-32

Comment:
**Flash of first-run UI for returning users**

`hasCompletedOnboarding` initialises to `false`, so `showRevisitActions` is `false` on every first render. For a returning user who navigates to `/onboarding` directly (without `?source=revisit`), the page paints the first-run copy ("Open-Source Agentic Browser", "Get Started") before the storage promise resolves and `setHasCompletedOnboarding(true)` triggers a re-render to the revisit copy. The fade-in animation makes this flash more visible rather than less.

Consider initialising the state as `null` to delay rendering until the storage read resolves, or at minimum keeping an `isLoading` flag:

```tsx
const [hasCompletedOnboarding, setHasCompletedOnboarding] = useState<boolean | null>(null)
...
// defer content until storage resolves
if (hasCompletedOnboarding === null && !isRevisit) return null
```

This avoids the mid-animation content swap for direct `/onboarding` visits from returning users.

How can I resolve this? If you propose a fix, please make it concise.

@felarof99 felarof99 changed the title feat: guide onboarding through product tour feat(agent): overhaul onboarding launch flow Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant