7bed91c9c2
## Motivation When frequently switching between models, it's tedious to search through the full model list to find ones you've used before. A "Recent" tab provides quick access to previously launched models. ## Changes - **New store** (`dashboard/src/lib/stores/recents.svelte.ts`): `RecentsStore` class persisting recently launched model IDs with timestamps to localStorage (key: `exo-recent-models`). Caps at 20 entries, deduplicates on re-launch (moves to top). - **FamilySidebar**: Added "Recent" tab between Favorites and Hub, conditionally shown when there are recent models. - **FamilyLogos**: Added clock/history icon for the recents tab. - **ModelPickerModal**: Added `recentModelIds`/`hasRecents` props. Derives single-variant `ModelGroup[]` from recent IDs and renders them using the same `ModelPickerGroup` component as all other tabs — consistent styling, memory grey-out, favorites, info button, download indicators. - **+page.svelte**: Calls `recordRecentLaunch(modelId)` after successful instance launch. Passes reactive recent state to the modal. ## Why It Works Follows the exact same pattern as the existing Favorites feature (localStorage persistence, conditional tab display, reactive Svelte 5 `$state`/`$derived`). Recent models are wrapped as single-variant `ModelGroup` objects so they reuse `ModelPickerGroup` for identical row rendering across all tabs. ## Test Plan ### Manual Testing <!-- Hardware: MacBook Pro --> - Launch a model instance → reopen model picker → "Recent" tab appears with the launched model - Launch a second model → it appears at top of the Recent list - Re-launch the first model → it moves back to top - Search within the Recent tab filters the list - Models that don't fit in memory are greyed out (same as All tab) - Close/reopen browser → recents persist from localStorage ### Automated Testing - Dashboard builds successfully (`npm run build`) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: rltakashige <rl.takashige@gmail.com>