From c3dd1370d7973dbf3a11891a0109d05d05bc16e5 Mon Sep 17 00:00:00 2001 From: Cyrus Gray <144336577+graycyrus@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:31:17 +0530 Subject: [PATCH] update onboarding (#410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(onboarding): move Tools step from onboarding to Settings Remove the Tools toggle step from onboarding (5 → 4 steps) and add it as a dedicated Tools panel under Settings > AI & Skills. This reduces onboarding friction while keeping tool configuration accessible. * feat(onboarding): remove Local AI step from onboarding Remove the Local AI download/consent step, reducing onboarding from 4 to 3 steps (Welcome → Screen Permissions → Skills). Local AI setup is already accessible from Settings and auto-bootstraps from Home. --- app/src/pages/onboarding/Onboarding.tsx | 119 +----------------------- 1 file changed, 5 insertions(+), 114 deletions(-) diff --git a/app/src/pages/onboarding/Onboarding.tsx b/app/src/pages/onboarding/Onboarding.tsx index 8656164aa..fa2a87a9c 100644 --- a/app/src/pages/onboarding/Onboarding.tsx +++ b/app/src/pages/onboarding/Onboarding.tsx @@ -1,12 +1,9 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; -import { createPortal } from 'react-dom'; +import { useState } from 'react'; import ProgressIndicator from '../../components/ProgressIndicator'; import { useCoreState } from '../../providers/CoreStateProvider'; import { userApi } from '../../services/api/userApi'; -import { bootstrapLocalAiWithRecommendedPreset } from '../../utils/localAiBootstrap'; import { getDefaultEnabledTools } from '../../utils/toolDefinitions'; -import LocalAIStep from './steps/LocalAIStep'; import ScreenPermissionsStep from './steps/ScreenPermissionsStep'; import SkillsStep from './steps/SkillsStep'; import WelcomeStep from './steps/WelcomeStep'; @@ -17,56 +14,18 @@ interface OnboardingProps { } interface OnboardingDraft { - localModelConsentGiven: boolean; - localModelDownloadStarted: boolean; accessibilityPermissionGranted: boolean; connectedSources: string[]; } -const LOCAL_AI_ERROR_DISMISS_MS = 10_000; - const Onboarding = ({ onComplete, onDefer }: OnboardingProps) => { const { setOnboardingCompletedFlag, setOnboardingTasks } = useCoreState(); const [currentStep, setCurrentStep] = useState(0); - const [downloadError, setDownloadError] = useState(null); - const retryInFlightRef = useRef(false); const [draft, setDraft] = useState({ - localModelConsentGiven: false, - localModelDownloadStarted: false, accessibilityPermissionGranted: false, connectedSources: [], }); - const totalSteps = 4; - - // Auto-dismiss the error banner after LOCAL_AI_ERROR_DISMISS_MS milliseconds. - useEffect(() => { - if (!downloadError) return; - console.debug( - '[Onboarding] Local AI download error surfaced; will auto-dismiss in', - LOCAL_AI_ERROR_DISMISS_MS, - 'ms' - ); - const timer = setTimeout(() => { - setDownloadError(null); - }, LOCAL_AI_ERROR_DISMISS_MS); - return () => clearTimeout(timer); - }, [downloadError]); - - // Re-fires both download commands when the user clicks "Retry" in the error banner. - const retryDownload = useCallback(() => { - if (retryInFlightRef.current) return; - retryInFlightRef.current = true; - console.debug('[Onboarding] User retrying Local AI download'); - setDownloadError(null); - void bootstrapLocalAiWithRecommendedPreset(false, '[Onboarding retry]') - .catch((err: unknown) => { - console.warn('[Onboarding] Retry download failed:', err); - setDownloadError('Local AI setup encountered an issue'); - }) - .finally(() => { - retryInFlightRef.current = false; - }); - }, []); + const totalSteps = 3; const handleNext = () => { if (currentStep < totalSteps - 1) { @@ -80,15 +39,6 @@ const Onboarding = ({ onComplete, onDefer }: OnboardingProps) => { } }; - const handleLocalAINext = (result: { consentGiven: boolean; downloadStarted: boolean }) => { - setDraft(prev => ({ - ...prev, - localModelConsentGiven: result.consentGiven, - localModelDownloadStarted: result.downloadStarted, - })); - handleNext(); - }; - const handleAccessibilityNext = (accessibilityPermissionGranted: boolean) => { setDraft(prev => ({ ...prev, accessibilityPermissionGranted })); handleNext(); @@ -99,8 +49,8 @@ const Onboarding = ({ onComplete, onDefer }: OnboardingProps) => { await setOnboardingTasks({ accessibilityPermissionGranted: draft.accessibilityPermissionGranted, - localModelConsentGiven: draft.localModelConsentGiven, - localModelDownloadStarted: draft.localModelDownloadStarted, + localModelConsentGiven: false, + localModelDownloadStarted: false, enabledTools: getDefaultEnabledTools(), connectedSources, updatedAtMs: Date.now(), @@ -128,16 +78,8 @@ const Onboarding = ({ onComplete, onDefer }: OnboardingProps) => { case 0: return ; case 1: - return ( - - ); - case 2: return ; - case 3: + case 2: return ; default: return null; @@ -160,57 +102,6 @@ const Onboarding = ({ onComplete, onDefer }: OnboardingProps) => { {renderStep()} - {downloadError && - createPortal( -
-
-
- {/* Warning icon */} - -
-

{downloadError}

-

- You can retry or continue — downloads can be resumed later. -

- -
- {/* Dismiss button */} - -
-
-
, - document.body - )} ); };