diff --git a/src/components/WelcomeScreen.test.tsx b/src/components/WelcomeScreen.test.tsx
index ac5f398c..23017b28 100644
--- a/src/components/WelcomeScreen.test.tsx
+++ b/src/components/WelcomeScreen.test.tsx
@@ -94,9 +94,9 @@ describe('WelcomeScreen', () => {
expect(screen.getByText(/could not be found on disk/)).toBeInTheDocument()
})
- it('shows the missing vault path in a badge', () => {
+ it('does not show the missing vault path in a badge', () => {
render()
- expect(screen.getByText('~/Laputa')).toBeInTheDocument()
+ expect(screen.queryByText('~/Laputa')).not.toBeInTheDocument()
})
it('shows "Choose a different folder" instead of "Open existing vault"', () => {
diff --git a/src/components/WelcomeScreen.tsx b/src/components/WelcomeScreen.tsx
index b9446b1a..8ab7af7c 100644
--- a/src/components/WelcomeScreen.tsx
+++ b/src/components/WelcomeScreen.tsx
@@ -103,14 +103,6 @@ const OPTION_DESC_STYLE: React.CSSProperties = {
marginTop: 2,
}
-const PATH_BADGE_STYLE: React.CSSProperties = {
- width: '100%',
- background: 'var(--sidebar)',
- borderRadius: 6,
- padding: '8px 12px',
- textAlign: 'center',
-}
-
const ERROR_STYLE: React.CSSProperties = {
fontSize: 13,
color: 'var(--destructive, #e03e3e)',
@@ -155,7 +147,7 @@ function OptionButton({ icon, iconBg, label, description, onClick, disabled, loa
)
}
-export function WelcomeScreen({ mode, missingPath, defaultVaultPath, onCreateVault, onCreateNewVault, onOpenFolder, creating, error }: WelcomeScreenProps) {
+export function WelcomeScreen({ mode, defaultVaultPath, onCreateVault, onCreateNewVault, onOpenFolder, creating, error }: WelcomeScreenProps) {
const isWelcome = mode === 'welcome'
return (
@@ -185,14 +177,6 @@ export function WelcomeScreen({ mode, missingPath, defaultVaultPath, onCreateVau
- {!isWelcome && missingPath && (
-
-
- {missingPath}
-
-
- )}
-
diff --git a/src/hooks/useOnboarding.test.ts b/src/hooks/useOnboarding.test.ts
index 5c271f97..662215b6 100644
--- a/src/hooks/useOnboarding.test.ts
+++ b/src/hooks/useOnboarding.test.ts
@@ -87,6 +87,38 @@ describe('useOnboarding', () => {
})
})
+ it('clears the persisted active vault when the saved path no longer exists', async () => {
+ localStorage.setItem('laputa_welcome_dismissed', '1')
+
+ mockInvokeFn.mockImplementation(async (cmd: string) => {
+ if (cmd === 'get_default_vault_path') return '/mock/Documents/Getting Started'
+ if (cmd === 'check_vault_exists') return false
+ if (cmd === 'load_vault_list') {
+ return {
+ vaults: [{ label: 'Old Vault', path: '/vault/deleted' }],
+ active_vault: '/vault/deleted',
+ hidden_defaults: [],
+ }
+ }
+ if (cmd === 'save_vault_list') return null
+ return null
+ })
+
+ const { result } = renderHook(() => useOnboarding('/vault/deleted'))
+
+ await waitFor(() => {
+ expect(result.current.state.status).toBe('vault-missing')
+ })
+
+ expect(mockInvokeFn).toHaveBeenCalledWith('save_vault_list', {
+ list: {
+ vaults: [{ label: 'Old Vault', path: '/vault/deleted' }],
+ active_vault: null,
+ hidden_defaults: [],
+ },
+ })
+ })
+
it('handleCreateVault creates vault and transitions to ready', async () => {
mockInvokeFn.mockImplementation(async (cmd: string) => {
if (cmd === 'get_default_vault_path') return '/mock/Documents/Getting Started'
diff --git a/src/hooks/useOnboarding.ts b/src/hooks/useOnboarding.ts
index fd768c29..cf7dd7d2 100644
--- a/src/hooks/useOnboarding.ts
+++ b/src/hooks/useOnboarding.ts
@@ -15,6 +15,12 @@ function tauriCall
(command: string, args: Record): Promise
+ active_vault?: string | null
+ hidden_defaults?: string[]
+}
+
function wasDismissed(): boolean {
try {
return localStorage.getItem(DISMISSED_KEY) === '1'
@@ -31,6 +37,22 @@ function markDismissed(): void {
}
}
+async function clearMissingActiveVault(missingPath: string): Promise {
+ try {
+ const list = await tauriCall('load_vault_list', {})
+ if (!list || list.active_vault !== missingPath) return
+ await tauriCall('save_vault_list', {
+ list: {
+ vaults: list.vaults ?? [],
+ active_vault: null,
+ hidden_defaults: list.hidden_defaults ?? [],
+ },
+ })
+ } catch {
+ // Best effort only — onboarding should still proceed
+ }
+}
+
export function useOnboarding(initialVaultPath: string) {
const [state, setState] = useState({ status: 'loading' })
const [creating, setCreating] = useState(false)
@@ -48,7 +70,16 @@ export function useOnboarding(initialVaultPath: string) {
if (exists) {
setState({ status: 'ready', vaultPath: initialVaultPath })
- } else if (wasDismissed()) {
+ } else {
+ await clearMissingActiveVault(initialVaultPath)
+ if (cancelled) return
+ }
+
+ if (exists) {
+ return
+ }
+
+ if (wasDismissed()) {
// User previously dismissed — show vault-missing instead of welcome
setState({ status: 'vault-missing', vaultPath: initialVaultPath, defaultPath })
} else {