feat: redesign onboarding into a guided, interactive tour#384
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors and expands the onboarding flow into a roomier, two-column guided tour with 11 steps, introducing new steps like Clipboard, Portals, Hidden AI Commands, Emoji, and Snippets. It updates the Rust step machine, window configuration, and Svelte views, while adding several helper components and tests. Feedback on these changes highlights a bug in AiSetupStep.svelte where skipping AI setup fails to advance the step, a TypeScript mismatch in snippetsSetup.ts due to a missing pinned property, and a usability issue in HiddenCommands.svelte where updating a hotkey does not re-enable the creation button.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| async function handleAiSkip() { | ||
| try { | ||
| await onboardingService.skipAiSetup() | ||
| } catch (err) { | ||
| diagnosticsService.report({ | ||
| source: 'frontend', kind: 'manual', severity: 'warning', retryable: false, | ||
| context: { message: 'Could not skip AI setup.' }, developerDetail: String(err), | ||
| }) | ||
| } | ||
| } |
There was a problem hiding this comment.
The handleAiSkip function calls onboardingService.skipAiSetup() but does not advance the onboarding step. This will leave the user stuck on the AI Setup page when they click "Skip for now". Calling onboardingService.advance() at the end of the function ensures the user is successfully routed to the next step.
async function handleAiSkip() {
try {
await onboardingService.skipAiSetup()
} catch (err) {
diagnosticsService.report({
source: 'frontend', kind: 'manual', severity: 'warning', retryable: false,
context: { message: 'Could not skip AI setup.' }, developerDetail: String(err),
})
}
await onboardingService.advance()
}
| snippetStore.add({ | ||
| id: crypto.randomUUID(), | ||
| keyword: SAMPLE_KEYWORD, | ||
| expansion: 'you@example.com', | ||
| name: 'My email', | ||
| createdAt: Date.now(), | ||
| }) |
There was a problem hiding this comment.
The StoredSnippet interface requires the pinned property to be a boolean. Omitting it when calling snippetStore.add violates the type definition and can lead to TypeScript compilation errors or unexpected runtime behavior. Explicitly setting pinned: false resolves this type mismatch.
snippetStore.add({
id: crypto.randomUUID(),
keyword: SAMPLE_KEYWORD,
expansion: 'you@example.com',
name: 'My email',
createdAt: Date.now(),
pinned: false,
})| async function recordHotkey(detail: { modifier: string; key: string }): Promise<true> { | ||
| modifier = detail.modifier | ||
| key = detail.key | ||
| return true | ||
| } |
There was a problem hiding this comment.
Once the Grammar Fix command is successfully configured, the "Create the command" button is permanently disabled. If the user subsequently changes the hotkey in the ShortcutRecorder, they cannot re-register or update the command because the button remains disabled. Resetting configured to false in recordHotkey allows the user to save their updated hotkey.
async function recordHotkey(detail: { modifier: string; key: string }): Promise<true> {
modifier = detail.modifier
key = detail.key
configured = false
return true
}
No description provided.