Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/guardrail-pulse-history.jsonl
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
{"date": "2026-07-23", "metrics": {"brand_ui_purple": {"baseline": 1776, "count": 1776}, "deferred_work_markers": {"baseline": 837, "count": 837}, "lifecycle_unlabeled_scripts": {"baseline": 17, "count": 17}, "mapless_packages": {"baseline": 6, "count": 3}, "union_return_isinstance": {"baseline": 0, "count": 0}, "version_prefixed_files": {"baseline": 42, "count": 42}}}
{"date": "2026-08-17", "metrics": {"brand_ui_purple": {"baseline": 1763, "count": 1763}, "deferred_work_markers": {"baseline": 829, "count": 829}, "lifecycle_unlabeled_scripts": {"baseline": 10, "count": 10}, "mapless_packages": {"baseline": 6, "count": 2}, "union_return_isinstance": {"baseline": 0, "count": 0}, "version_prefixed_files": {"baseline": 38, "count": 38}}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"changes": [
"Signing in with a different account now resets the onboarding wizard so the new user sees the full setup flow instead of being dropped straight to the home screen."
]
}
13 changes: 11 additions & 2 deletions desktop/windows/src/renderer/src/lib/authTeardown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ const h = vi.hoisted(() => ({
invalidateConversationsCache: vi.fn(),
clearPendingConversations: vi.fn(),
clearUserScopedPreferences: vi.fn(),
clearMemoryCache: vi.fn()
clearMemoryCache: vi.fn(),
resetOnboarding: vi.fn()
}))

vi.mock('./pageCache', () => ({
invalidateConversationsCache: h.invalidateConversationsCache,
clearPendingConversations: h.clearPendingConversations
}))
vi.mock('./preferences', () => ({ clearUserScopedPreferences: h.clearUserScopedPreferences }))
vi.mock('./preferences', () => ({
clearUserScopedPreferences: h.clearUserScopedPreferences,
resetOnboarding: h.resetOnboarding
}))
vi.mock('./localAgentMemoryCache', () => ({ clearMemoryCache: h.clearMemoryCache }))

import { reconcileAccountForSignIn, teardownUserData } from './authTeardown'
Expand All @@ -38,6 +42,7 @@ beforeEach(() => {
h.clearPendingConversations.mockClear()
h.clearUserScopedPreferences.mockClear()
h.clearMemoryCache.mockClear()
h.resetOnboarding.mockClear()
;(globalThis as { window: { omi: unknown } }).window.omi = {
wipeUserData,
byokClearAll,
Expand Down Expand Up @@ -120,6 +125,8 @@ describe('reconcileAccountForSignIn — account-switch guard', () => {
// The prior account's BYOK keys + Gmail session are cleared before B hydrates.
expect(byokClearAll).toHaveBeenCalledTimes(1)
expect(gmailSessionDisconnect).toHaveBeenCalledTimes(1)
// Onboarding is reset so the incoming account sees the wizard (new user on this device).
expect(h.resetOnboarding).toHaveBeenCalledTimes(1)
expect(localStorage.getItem(LAST_UID_KEY)).toBe('userB')
// The uid pointer must survive teardown (it's machine-scoped, not in the
// user-scoped key list) so the NEXT switch is still detected.
Expand All @@ -131,6 +138,7 @@ describe('reconcileAccountForSignIn — account-switch guard', () => {
await reconcileAccountForSignIn('userA')

expect(wipeUserData).not.toHaveBeenCalled()
expect(h.resetOnboarding).not.toHaveBeenCalled()
expect(localStorage.getItem(LAST_UID_KEY)).toBe('userA')
})

Expand All @@ -139,6 +147,7 @@ describe('reconcileAccountForSignIn — account-switch guard', () => {
await reconcileAccountForSignIn('userA')

expect(wipeUserData).not.toHaveBeenCalled()
expect(h.resetOnboarding).not.toHaveBeenCalled()
expect(localStorage.getItem(LAST_UID_KEY)).toBe('userA')
})

Expand Down
7 changes: 5 additions & 2 deletions desktop/windows/src/renderer/src/lib/authTeardown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// (authSession.forceReauth) and never wipes data.
import { clearMemoryCache } from './localAgentMemoryCache'
import { clearPendingConversations, invalidateConversationsCache } from './pageCache'
import { clearUserScopedPreferences } from './preferences'
import { clearUserScopedPreferences, resetOnboarding } from './preferences'
import { CHAT_INFINITE_ID_KEY } from './chatStorageKeys'
import { POST_HISTORY_KEY } from './sync/backfillStorageKey'
import { resetByokKeys } from './byokKeys'
Expand Down Expand Up @@ -117,7 +117,10 @@ export async function reconcileAccountForSignIn(uid: string | null): Promise<voi
} catch {
/* privacy mode */
}
if (stored && stored !== uid) await teardownUserData()
if (stored && stored !== uid) {
resetOnboarding()
await teardownUserData()
}
try {
localStorage.setItem(LAST_UID_KEY, uid)
} catch {
Expand Down