Skip to content

feat(desktop): allow skipping every onboarding step and the whole flow#4109

Merged
Kitenite merged 2 commits into
mainfrom
skip-onboarding-steps
May 5, 2026
Merged

feat(desktop): allow skipping every onboarding step and the whole flow#4109
Kitenite merged 2 commits into
mainfrom
skip-onboarding-steps

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented May 5, 2026

Summary

  • Add a per-step "Skip for now" link on the providers, permissions, and project steps (the gh-cli and adopt-worktrees steps already had one).
  • Add a "Skip onboarding" button to the setup chrome that marks every remaining step as skipped and routes the user to /welcome.
  • Update the dashboard gate so skipped required steps (providers, project) count as satisfied — previously skipping wasn't enough to leave the flow.

Test plan

  • Walk through onboarding and confirm a Skip option appears on every step
  • On each step, click Skip for now and confirm it advances to the next step
  • From any step, click Skip onboarding (top-right of chrome) and confirm it lands on /welcome and doesn't bounce back into setup
  • Re-open the app after skipping and confirm the dashboard renders without redirecting to setup

Summary by cubic

Adds skip controls to onboarding so users can bypass any step or the entire flow. Skipped required steps now unlock the dashboard and no longer bounce users back into setup.

  • New Features

    • Added “Skip for now” to providers, permissions, and project steps; marks the step as skipped and moves to the next.
    • Added “Skip onboarding” in the setup chrome; calls skipAll(), records analytics, and navigates to /welcome.
    • Dashboard gate treats skipped required steps (providers, project) as satisfied.
  • Bug Fixes

    • On the providers step, the secondary action now reads “Continue to next step” when a provider is connected (removes the misleading “Skip” prefix).

Written for commit 02b0d67. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Added a global "Skip onboarding" action to bypass all steps at once.
    • Added "Skip for now" options on individual setup steps (permissions, projects, providers).
    • Secondary action adapts label and behavior based on connection/status (Cancel / Continue / Skip).
    • Skipped steps now count toward required-step completion and onboarding records skip-all outcome/timing.

- Add `skipAll` action and let skipped steps satisfy the dashboard gate
- Always-visible "Skip for now" link on providers, permissions, and project steps
- Add "Skip onboarding" button to the setup chrome
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 5, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3a72f8c8-3e03-4bd5-a31d-1c02771b0765

📥 Commits

Reviewing files that changed from the base of the PR and between 982e216 and 02b0d67.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/routes/_authenticated/setup/providers/page.tsx

📝 Walkthrough

Walkthrough

Adds a skip-onboarding capability: a store-level skipAll() that marks remaining steps skipped and emits telemetry, step-level markSkipped handlers on permissions/project/providers pages, and a root "Skip onboarding" button that invokes skipAll() and navigates to the welcome screen.

Changes

Onboarding Skip Flow

Layer / File(s) Summary
Store Foundation
apps/desktop/src/renderer/stores/onboarding/onboardingStore.ts
Added skipAll() action and declaration; implementation marks all uncompleted steps as skipped, emits onboarding_finished with outcome "skipped_all" and duration, updates skipped, startedAt, completedAt, and manualWalkthrough. Updated selectRequiredStepsComplete() to treat skipped steps as satisfied.
Core UI Wiring
apps/desktop/src/renderer/routes/_authenticated/setup/components/OnboardingProgress/OnboardingProgress.tsx
Added skipAll access and handleSkipAll() which calls skipAll() and navigates to "/welcome" with replace: true. Replaced the right-side placeholder with a "Skip onboarding" button bound to this handler.
Step-Level Handlers
apps/desktop/src/renderer/routes/_authenticated/setup/permissions/page.tsx, apps/desktop/src/renderer/routes/_authenticated/setup/project/page.tsx, apps/desktop/src/renderer/routes/_authenticated/setup/providers/page.tsx
Each page now reads markSkipped from the onboarding store and adds a step-level skip handler that marks its step skipped and navigates to the next route. permissions and project add "Skip for now" buttons. providers rewires the secondary action to cancel reconfiguration if active, continue if providers exist, or skip otherwise and adjusts the label accordingly.
Tests / Docs / Manifest
package.json
Manifest touched (package.json entry listed in summary). No tests or docs changes present in diff.

Sequence Diagram

sequenceDiagram
  participant User as User
  participant UI as Onboarding UI
  participant Store as OnboardingStore
  participant Router as Router
  participant Telemetry as Telemetry

  User->>UI: Click "Skip onboarding" / "Skip for now"
  UI->>Store: call markSkipped(step) or skipAll()
  Store->>Store: mark steps skipped, update timestamps
  Store->>Telemetry: emit onboarding_finished (skipped_all) and per-step skip events
  UI->>Router: navigate(to: nextStep or /welcome, replace:true)
  Router-->>User: show destination screen
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
I twitched my nose and hopped right through,
A skip for steps, a shortcut new.
From store to screen with nimble art,
Onboarding light — a joyful start!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: enabling users to skip individual onboarding steps and the entire onboarding flow.
Description check ✅ Passed The PR description is well-structured and complete, covering the summary, test plan, and implementation details across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch skip-onboarding-steps

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 and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 5, 2026

Greptile Summary

This PR adds per-step "Skip for now" links to the providers, permissions, and project onboarding steps, adds a global "Skip onboarding" button in the setup chrome, and relaxes the dashboard gate so that skipping a required step (providers, project) is treated the same as completing it.

  • selectRequiredStepsComplete now returns true when required steps are either completed or skipped, removing the previous explicit guard that blocked skipping as a way to bypass the gate.
  • A new skipAll() store action marks every non-completed step as skipped in a single call, sets completedAt, clears manualWalkthrough, and fires per-step and summary analytics events; the OnboardingProgress chrome calls it then replaces history with /welcome.
  • The providers page skip/continue link is unconditionally rendered (previously hidden until at least one provider was connected), with a three-branch click handler that cancels reconfiguration, completes, or skips depending on connection state.

Confidence Score: 4/5

Safe to merge; the skip paths work correctly and the gate change is intentional. The main concern is the 'Skip onboarding' button in the chrome having no confirmation step, making it easy to accidentally skip the entire flow.

The logic in skipAll(), the per-step skip handlers, and the updated dashboard gate all behave as intended. The analytics outcome label in skipAll() will say 'skipped_all' even for users who completed some steps first, which could distort funnel metrics. The 'Skip onboarding' chrome button is permanently visible with no confirmation, so a single misclick irreversibly skips everything until the user manually resets from Settings.

onboardingStore.ts (analytics outcome accuracy) and OnboardingProgress.tsx (no guard on the global skip button)

Important Files Changed

Filename Overview
apps/desktop/src/renderer/stores/onboarding/onboardingStore.ts Adds skipAll() action and relaxes selectRequiredStepsComplete to accept skipped required steps; the analytics outcome label may be inaccurate when some steps were already completed before skipAll is invoked
apps/desktop/src/renderer/routes/_authenticated/setup/components/OnboardingProgress/OnboardingProgress.tsx Adds 'Skip onboarding' button in the chrome bar; button is always visible and fires skipAll() then replaces history with /welcome — no confirmation guard
apps/desktop/src/renderer/routes/_authenticated/setup/permissions/page.tsx Adds 'Skip for now' link that calls markSkipped('permissions') and advances to the project step; permissions is a non-required step so this is low risk
apps/desktop/src/renderer/routes/_authenticated/setup/project/page.tsx Adds 'Skip for now' to both the hasProjects and no-projects branches of the project step; correctly calls markSkipped('project') before navigating to adopt-worktrees
apps/desktop/src/renderer/routes/_authenticated/setup/providers/page.tsx Removes conditional rendering of the skip/continue link so it is always visible; three-branch click handler correctly routes to cancel, complete, or skip depending on connection state

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User enters onboarding] --> B[providers step]
    B --> C{Action}
    C -->|Complete| D[markComplete providers]
    C -->|Skip for now - NEW| E[markSkipped providers]
    C -->|Skip onboarding - NEW| SK[skipAll]
    D --> F[gh-cli step]
    E --> F
    F --> G[permissions step]
    G --> H{Action}
    H -->|Complete| I[markComplete permissions]
    H -->|Skip for now - NEW| J[markSkipped permissions]
    H -->|Skip onboarding - NEW| SK
    I --> K[project step]
    J --> K
    K --> L{Action}
    L -->|Complete| M[markComplete project]
    L -->|Skip for now - NEW| N[markSkipped project]
    L -->|Skip onboarding - NEW| SK
    M --> O[adopt-worktrees step]
    N --> O
    SK -->|sets completedAt + all skipped| W[welcome page]
    O --> P[Onboarding done]
    P --> W

    subgraph Gate[Dashboard Gate CHANGED]
        Q[selectRequiredStepsComplete\nproviders AND project\nmust be completed OR skipped]
    end

    W --> Gate
    Gate -->|pass| R[Dashboard renders]
    Gate -->|fail| B
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/desktop/src/renderer/routes/_authenticated/setup/components/OnboardingProgress/OnboardingProgress.tsx:110-119
**No confirmation on destructive action**

"Skip onboarding" marks every remaining step as skipped and sets `completedAt` — it's irreversible without going to Settings and resetting. A single accidental click during onboarding (e.g., fat-finger instead of Back) silently bypasses the whole flow. The other skip affordances ("Skip for now") are step-scoped and easy to undo by re-entering the step; this one is not. A brief confirmation popover or at minimum a `window.confirm` would prevent accidental invocations.

### Issue 2 of 2
apps/desktop/src/renderer/stores/onboarding/onboardingStore.ts:125-128
**`"skipped_all"` outcome is inaccurate when some steps were already completed**

The `outcome` is hardcoded to `"skipped_all"` even when the user had previously completed some steps before clicking "Skip onboarding". A user who finishes `providers` and `gh-cli` and then hits Skip would emit `skipped_all`, despite having done real configuration work — making funnel analysis misleading. Consider computing `anyCompleted = ONBOARDING_STEP_ORDER.some((s) => prev.completed[s])` and emitting `outcome: anyCompleted ? "partial_skip" : "skipped_all"` instead.

Reviews (1): Last reviewed commit: "feat(desktop): allow skipping every onbo..." | Re-trigger Greptile

Comment on lines +110 to +119
<button
type="button"
onClick={handleSkipAll}
className={cn(
pillBase,
"border-transparent text-[#a8a5a3] hover:bg-white/5 hover:text-[#eae8e6]",
)}
>
Skip onboarding
</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 No confirmation on destructive action

"Skip onboarding" marks every remaining step as skipped and sets completedAt — it's irreversible without going to Settings and resetting. A single accidental click during onboarding (e.g., fat-finger instead of Back) silently bypasses the whole flow. The other skip affordances ("Skip for now") are step-scoped and easy to undo by re-entering the step; this one is not. A brief confirmation popover or at minimum a window.confirm would prevent accidental invocations.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/setup/components/OnboardingProgress/OnboardingProgress.tsx
Line: 110-119

Comment:
**No confirmation on destructive action**

"Skip onboarding" marks every remaining step as skipped and sets `completedAt` — it's irreversible without going to Settings and resetting. A single accidental click during onboarding (e.g., fat-finger instead of Back) silently bypasses the whole flow. The other skip affordances ("Skip for now") are step-scoped and easy to undo by re-entering the step; this one is not. A brief confirmation popover or at minimum a `window.confirm` would prevent accidental invocations.

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

Comment on lines +125 to +128
track("onboarding_finished", {
outcome: "skipped_all",
duration_ms: prev.startedAt ? Date.now() - prev.startedAt : null,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 "skipped_all" outcome is inaccurate when some steps were already completed

The outcome is hardcoded to "skipped_all" even when the user had previously completed some steps before clicking "Skip onboarding". A user who finishes providers and gh-cli and then hits Skip would emit skipped_all, despite having done real configuration work — making funnel analysis misleading. Consider computing anyCompleted = ONBOARDING_STEP_ORDER.some((s) => prev.completed[s]) and emitting outcome: anyCompleted ? "partial_skip" : "skipped_all" instead.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/stores/onboarding/onboardingStore.ts
Line: 125-128

Comment:
**`"skipped_all"` outcome is inaccurate when some steps were already completed**

The `outcome` is hardcoded to `"skipped_all"` even when the user had previously completed some steps before clicking "Skip onboarding". A user who finishes `providers` and `gh-cli` and then hits Skip would emit `skipped_all`, despite having done real configuration work — making funnel analysis misleading. Consider computing `anyCompleted = ONBOARDING_STEP_ORDER.some((s) => prev.completed[s])` and emitting `outcome: anyCompleted ? "partial_skip" : "skipped_all"` instead.

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/routes/_authenticated/setup/permissions/page.tsx (1)

105-112: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

"Skip for now" is available even when required permissions are already granted

When requiredSatisfied is true, both "Continue" (which calls markComplete) and "Skip for now" (which calls markSkipped) are active simultaneously. A user who accidentally clicks "Skip for now" after granting all permissions will record the step as skipped rather than completed, resulting in inaccurate analytics and an inconsistent state where granted permissions are recorded as skipped.

Consider disabling or hiding the skip option once requiredSatisfied is true, or at minimum calling markComplete instead of markSkipped inside handleSkip when requiredSatisfied.

🛡️ Minimal fix — promote skip to complete when satisfied
 	const handleSkip = () => {
-		markSkipped("permissions");
+		if (requiredSatisfied) {
+			markComplete("permissions");
+		} else {
+			markSkipped("permissions");
+		}
 		navigate({ to: STEP_ROUTES.project });
 	};
🤖 Prompt for 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.

In `@apps/desktop/src/renderer/routes/_authenticated/setup/permissions/page.tsx`
around lines 105 - 112, The "Skip for now" action can record the step as skipped
even when requiredSatisfied is true; update the UI/handler so users can't
accidentally mark a completed step as skipped: either disable or hide the skip
SetupButton when requiredSatisfied is true, or change handleSkip to check
requiredSatisfied and call markComplete instead of markSkipped (or delegate to
handleContinue) when requiredSatisfied is true; locate the SetupButton for "Skip
for now" and the handleSkip/handleContinue functions to implement the
conditional behavior.
🤖 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
`@apps/desktop/src/renderer/routes/_authenticated/setup/components/OnboardingProgress/OnboardingProgress.tsx`:
- Around line 109-120: The "Skip onboarding" button currently calls
handleSkipAll which unconditionally invokes skipAll and emits
onboarding_finished with outcome "skipped_all"; change handleSkipAll in
OnboardingProgress.tsx to first check whether all steps are already completed
(e.g., using the same store/selector that marks steps as completed or
steps.every(s => s.completedAt)) and return early if so, and/or disable the
button when allStepsCompleted is true to prevent clicks; this ensures skipAll is
only called when there are incomplete steps and prevents emitting a misleading
onboarding_finished/skipped_all event or mutating the store unnecessarily.

In `@apps/desktop/src/renderer/routes/_authenticated/setup/providers/page.tsx`:
- Around line 261-280: The button label is misleading when atLeastOneConnected
&& !isReconfiguring: it says "Skip — continue to next step" while the click
handler calls handleContinueToNextStep() (which marks the step complete); update
the label logic inside the SetupButton render (the ternary that references
isReconfiguring and atLeastOneConnected) so that when atLeastOneConnected and
not isReconfiguring the text reads "Continue to next step" (or equivalent that
does not use "Skip"), leaving the onClick handlers (handleContinueToNextStep,
handleSkipStep) unchanged; locate the button/ternary near SetupButton,
isReconfiguring, atLeastOneConnected, handleContinueToNextStep, and
handleSkipStep to make the change.

---

Outside diff comments:
In `@apps/desktop/src/renderer/routes/_authenticated/setup/permissions/page.tsx`:
- Around line 105-112: The "Skip for now" action can record the step as skipped
even when requiredSatisfied is true; update the UI/handler so users can't
accidentally mark a completed step as skipped: either disable or hide the skip
SetupButton when requiredSatisfied is true, or change handleSkip to check
requiredSatisfied and call markComplete instead of markSkipped (or delegate to
handleContinue) when requiredSatisfied is true; locate the SetupButton for "Skip
for now" and the handleSkip/handleContinue functions to implement the
conditional behavior.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2938a147-ef48-4405-8930-4c2c1dd61a47

📥 Commits

Reviewing files that changed from the base of the PR and between fd82381 and 982e216.

📒 Files selected for processing (5)
  • apps/desktop/src/renderer/routes/_authenticated/setup/components/OnboardingProgress/OnboardingProgress.tsx
  • apps/desktop/src/renderer/routes/_authenticated/setup/permissions/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/setup/project/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/setup/providers/page.tsx
  • apps/desktop/src/renderer/stores/onboarding/onboardingStore.ts

Comment on lines +109 to +120
<div className="flex items-center justify-end">
<button
type="button"
onClick={handleSkipAll}
className={cn(
pillBase,
"border-transparent text-[#a8a5a3] hover:bg-white/5 hover:text-[#eae8e6]",
)}
>
Skip onboarding
</button>
</div>
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

"Skip onboarding" button remains active even when all steps are already completed

handleSkipAll calls skipAll() unconditionally. When all steps are already completed, skipAll() still fires onboarding_finished with outcome: "skipped_all" (since completedAt is reset to Date.now() and manualWalkthrough is cleared), which produces a misleading analytics event and mutates the store unnecessarily.

🛡️ Proposed guard
+	const allStepsDone = useOnboardingStore((s) =>
+		ONBOARDING_STEP_ORDER.every((step) => s.completed[step] || s.skipped[step]),
+	);
+
 	const handleSkipAll = () => {
 		skipAll();
 		navigate({ to: "/welcome", replace: true });
 	};
 			<button
 				type="button"
 				onClick={handleSkipAll}
+				disabled={allStepsDone}
 				className={cn(
 					pillBase,
 					"border-transparent text-[`#a8a5a3`] hover:bg-white/5 hover:text-[`#eae8e6`]",
 				)}
 			>
🤖 Prompt for 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.

In
`@apps/desktop/src/renderer/routes/_authenticated/setup/components/OnboardingProgress/OnboardingProgress.tsx`
around lines 109 - 120, The "Skip onboarding" button currently calls
handleSkipAll which unconditionally invokes skipAll and emits
onboarding_finished with outcome "skipped_all"; change handleSkipAll in
OnboardingProgress.tsx to first check whether all steps are already completed
(e.g., using the same store/selector that marks steps as completed or
steps.every(s => s.completedAt)) and return early if so, and/or disable the
button when allStepsCompleted is true to prevent clicks; this ensures skipAll is
only called when there are incomplete steps and prevents emitting a misleading
onboarding_finished/skipped_all event or mutating the store unnecessarily.

@Kitenite Kitenite merged commit 869dc57 into main May 5, 2026
8 of 10 checks passed
@Kitenite Kitenite deleted the skip-onboarding-steps branch May 5, 2026 21:59
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

saddlepaddle pushed a commit that referenced this pull request May 6, 2026
#4109)

* feat(desktop): allow skipping every onboarding step and the whole flow

- Add `skipAll` action and let skipped steps satisfy the dashboard gate
- Always-visible "Skip for now" link on providers, permissions, and project steps
- Add "Skip onboarding" button to the setup chrome

* fix(desktop): drop misleading "Skip" prefix when providers step is complete
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.

1 participant