2009 Commits

Author SHA1 Message Date
Eric
0f3f8a4680 docs: widget add/remove behavior doc 2026-02-10 17:43:38 -05:00
Eric
074a6e3a72 feat: widget add/remove MVP — add/remove widgets from dashboard
- '+' button in header opens popover listing hidden widgets with Add button
- Per-widget kebab menu (⋮) with 'Remove from dashboard' option
- Kebab menu appears on hover, keeps UI clean
- Visible widget set persisted to localStorage (v1 key)
- Reset Layout restores both grid positions AND visible widgets
- Uses widget-meta.ts to show labels + Demo tier badge
- No new endpoints, no new widget types, no search/filter
2026-02-10 17:43:20 -05:00
Eric
6101e2aaa6 feat: workspace-first routing + dashboard shell separation
ROUTING:
- / → /chat/main (was /dashboard)
- Sessions is the default landing, not Dashboard
- Dashboard is for observing, Workspace is for working

DASHBOARD HEADER:
- Removed Quick Actions (New Chat, Terminal, Skills, Files)
  Navigation belongs in the WorkspaceShell sidebar, not dashboard
- Added 'Workspace →' cross-link button (goes to /chat/main)
- Header is now: Identity | Context Strip | Workspace→ | Utilities

WIDGET METADATA (structural prep):
- New widget-meta.ts: scope, tier, defaultVisible per widget
- No UI built — data structure only for future widget management

DOCS:
- NAVIGATION_ARCHITECTURE.md: routing map, sidebar IA spec,
  shell descriptions, design principles

SIDEBAR (existing):
- Already has Dashboard link — no changes needed
- Already has all workspace routes organized

NOT CHANGED:
- No sidebar redesign (separate PR if needed)
- No dashboard widget changes
- No new features or interactions
2026-02-10 17:31:15 -05:00
Eric
ce52c86f9b dashboard: promote system status to header, remove redundant widget
WHY REMOVED:
System Status widget showed: connection state, model, uptime, sessions.
All four are now in the header context strip. The widget was pure
duplication — removing it makes the dashboard calmer with no information
loss.

HEADER CONTEXT (left-aligned after product name):
  ● Connected · Opus 4.6 · 9 sessions · Up 7m

GRID (7 widgets, was 8):
  Row 0: Active Agents + Cost Tracker
  Row 1: Usage Meter + Recent Sessions
  Row 2: Activity Log + Notifications
  Row 3: Tasks (Demo)

REMOVED:
  - system-status from WidgetId type
  - system-status from WIDGET_REGISTRY
  - system-status from lg layout
  - SystemStatusWidget grid child + import
  - Widget file NOT deleted (available for debug page)

NO NEW: widgets, data sources, interactions, or indicators.
2026-02-10 17:21:54 -05:00
Eric
db0af30f9b dashboard: header system context strip + shortcut rationalization
THREE-ZONE HEADER:

LEFT — Identity (locked):
  Logo + 'OpenClaw Studio', no subtitle, no marketing

CENTER — System Context Strip (new, text-only):
  '● Opus 4.6 · SESSIONS 9 · UP 2h 15m'
  - Green/red dot for gateway status
  - Model name in semibold
  - Labels uppercase tracking-wide, values normal
  - Tabular numerals, subtle · separators
  - Hidden on mobile, truncates uptime first

RIGHT — Utilities (rationalized):
  - Quick Actions → icon-only (15px) with aria-labels
  - Theme toggle → ghost style (no border/bg)
  - Reset + Settings → ghost icons
  - Vertical separator between nav and tool icons
  - Removed 'Add Widget' disabled button (noise)
  - All icons size-7, consistent ghost treatment

STYLE:
  - Header: rounded-xl→rounded-lg, py-3→py-2.5
  - No shadows, no glass, no backdrop-blur
  - Single flex row, no wrapping

HERO METRICS: Intentionally NOT removed. Header provides
context; hero row provides numeric snapshot. If hero row
feels redundant after this, it can be removed in a future
pass (not this PR).

WHAT IS NOT IN THE HEADER:
  - Cost/spend (belongs in cards)
  - Activity/events (belongs in stream)
  - Notifications (secondary)
2026-02-10 17:16:19 -05:00
Eric
e4db61aa97 dashboard: enterprise visual pass — OpenAI-style density
Header:
- Killed subtitle (marketing copy, not a dashboard element)
- Title: text-xl, tighter
- Quick Actions: compact pill buttons (text-xs), flex-wrap not grid
- Reduced header padding and border-radius (2xl→xl)

Hero Metrics:
- Removed colored accent borders (emerald/amber/blue → neutral)
- Flat cards: border-primary-200, no backdrop-blur
- Icon inline (no container box), muted primary-400
- Labels: 10px uppercase tracking-wide (instrument style)

Widget Cards (DashboardGlassCard):
- Killed description line from all cards — title only
- Header: icon inline (no container), title uppercase tracking-wide
- Border radius: rounded-2xl → rounded-xl
- Removed shadow-sm and backdrop-blur-xl (flat, not glass)
- Tighter header margin (mb-2.5→mb-2)

Agent Status:
- Progress bars: amber → primary-500 (neutral, not warning)

System Status:
- Removed 'Authoritative' description
- Removed extra border-primary-300 emphasis

Cost Tracker:
- Inner containers: rounded-xl → rounded-lg, consistent opacity

Net: -43 lines. Leaner, flatter, enterprise.
2026-02-10 17:05:37 -05:00
Eric
c54687acd8 fix: weather popover z-index — renders above grid widgets 2026-02-10 16:58:16 -05:00
Eric
231544a2f9 dashboard: final polish lock-in — density pass + normalized headers
DashboardGlassCard (all widgets):
- Padding: p-4/p-5 → px-3.5 py-3 / px-4 py-3.5
- Header: mb-3→mb-2.5, icon size-8→size-7 (16px), rounded-lg→rounded-md
- Title: text-sm→text-[13px], description: text-xs→text-[11px]
- Badge: smaller padding, 10px font
- Drag handle: removed border/bg, ghost style (just icon)

Activity Log:
- 'View all' → subtle text link (no button chrome)
- Row spacing: space-y-1.5→space-y-px (tight rows)
- Empty/loading: h-[220px]→h-32, text-sm→text-xs
- Removed unused Button import

Agent Status:
- Card rows: rounded-xl py-2.5→rounded-lg py-2, tighter gaps
- Name+task: single truncated line, text-xs
- Model badge: smaller (10px), elapsed: 10px muted
- Status badge: rounded-md→rounded, 10px font
- Progress bar: h-1.5→h-1, bg-200/70→bg-200/50
- Empty state: h-40→h-32

System Status:
- Inner rows: rounded-xl→rounded-lg, px-3 py-2→px-2.5 py-1.5

Dashboard locked. No further dashboard changes planned.
2026-02-10 16:54:42 -05:00
Eric
5e365df07c dashboard: single-row header — logo+title left, controls right
- Logo + 'OpenClaw Studio' + subtitle on the left
- Ambient pill + theme + reset + add + settings on the right
- All vertically centered in one row
- Subtitle hidden on xs for tight screens
- Quick Actions row below, tighter mt-3 gap
2026-02-10 16:42:32 -05:00
Eric
d557fdce53 dashboard: use brand logo, remove Studio Overview pill
- Replaced static SVG with OpenClawStudioIcon (orange gradient claw)
- Removed 'Studio Overview' pill — cleaner header
- Title: 'OpenClaw Studio' with semibold/medium weight split
- Same icon used in chat sidebar for brand consistency
2026-02-10 16:41:01 -05:00
Eric
c19ea8b5b9 dashboard: branded header with logo
- Logo icon in 'Studio Overview' pill (replaces generic dashboard icon)
- Large logo (10/12px) next to title with 'OpenClaw Studio' branded text
- 'Studio' in muted primary-500 for visual hierarchy
- Shortened subtitle for cleaner header
- Removed unused DashboardSquare01Icon import
2026-02-10 16:39:53 -05:00
Eric
3ea8746197 fix: settings dialog always shows scrollbar 2026-02-10 16:38:03 -05:00
Eric
3cc8543558 dashboard: settings popup dialog instead of page redirect
- New SettingsDialog component: scrollable overlay with all settings sections
  (Gateway, Appearance, Editor, Notifications, Smart Suggestions)
- Gear icon opens dialog instead of navigating to /settings
- Compact layout: smaller icons, tighter spacing, fits 80vh
- Auto-saves to localStorage like the full settings page
- Fetches available models on open for dropdowns
2026-02-10 16:36:30 -05:00
Eric
491f5688a1 dashboard: bordered ambient pill with edit popover, icon-only header buttons
Ambient status:
- Bordered pill matching 'Studio Overview' style
- Pencil icon opens popover with ZIP/city input + 12h/24h toggle
- Save invalidates weather query for immediate refresh
- Reset to auto-detect option

Header declutter:
- Reset Layout → icon only (refresh)
- Add Widget → icon only (+), disabled with opacity
- New Settings gear → navigates to /settings
- All icons 16px, consistent size-8 buttons
- Removed Button component dependency from dashboard
2026-02-10 16:34:11 -05:00
Eric
faa8045529 dashboard: header ambient time/weather — remove from grid
New HeaderAmbientStatus component in dashboard header shows:
  '04:12 PM · Feb 10 · 🌤 62°'

- Compact inline readout, muted text-xs, tabular numerals
- Hidden on xs (<640px) to avoid header wrapping
- Reuses same weather query key + dashboard settings (location, clock format)
- Ticks every 30s (minute-level precision)
- Positioned left of theme toggle

Grid cleanup:
- Removed time-date and weather from WidgetId, WIDGET_REGISTRY, lg layout
- Removed grid children + unused imports
- Dashboard bundle: 84KB → 77KB (-7KB)

Widget files NOT deleted (trivial cleanup for later).
2026-02-10 16:28:01 -05:00
Eric
2886b7a711 dashboard: cost/usage visual priority tune
Cost Tracker:
- Period Spend total → text-2xl font-bold (was text-lg font-medium)
- Label → uppercase tracking-wide to match System Status style

Usage Meter:
- Loading state → spinner + softer text instead of plain 'Loading usage data...'
2026-02-10 16:17:56 -05:00
Eric
15af5222ef dashboard: system status visual authority pass
- Stronger border (primary-300) to stand out as authoritative panel
- Labels → uppercase tracking-wide for instrument-panel feel
- Gateway dot has subtle glow shadow
- Values → font-semibold for scanability
- Tighter py (2.5→2) to fit more in card
- Debug button → subtle text link instead of outlined button (visually secondary)
- Description updated: 'Authoritative gateway health and runtime'
2026-02-10 16:17:14 -05:00
Eric
bdc5cd9460 dashboard: enterprise default layout reorder
Above fold (ops-first):
- Row 0: System Status + Active Agents
- Row 1: Cost Tracker + Usage Meter

Mid (context):
- Row 2: Recent Sessions + Activity Log (single primary stream)

Below fold (ambient):
- Row 3: Notifications + Time + Weather
- Row 4: Tasks (Demo)

Time/Weather demoted from row 0 to row 3.
Notifications demoted below Activity Log (no longer competing).
Tasks (Demo) dead last.

Docs: DASHBOARD_DEFAULT_LAYOUT.md added with full spec.
2026-02-10 16:16:42 -05:00
Eric
e6fdbf271d fix: dark mode readability — boosted contrast, dark variants on all semantic colors
- Bumped dark theme CSS variables: primary-200 from 0.2078→0.26, primary-300 from 0.3→0.34, etc.
- Surface now warm dark (oklch 0.11) instead of pure black
- Added dark: variants to hero metrics accent colors (emerald, amber, blue)
- Fixed bg-white references in Quick Actions, theme toggle, weather input
- Added dark variants to error states (red), badges (amber), agent status pills
- Activity log connected badge dark-aware
- Glass card wrapper slightly more opaque in dark mode
2026-02-10 15:57:29 -05:00
Eric
f9170683fa feat: sun/moon theme toggle in dashboard header
- New ThemeToggle component (src/components/theme-toggle.tsx)
- Uses existing Zustand theme store (persisted)
- Toggles dark↔light, applies class to document root
- Placed next to Reset Layout button in dashboard header
2026-02-10 15:50:45 -05:00
Eric
0c55186368 fix: default layout priority — time+weather+status top, cost+usage mid, secondary below fold 2026-02-10 15:48:27 -05:00
Eric
16537fd52c PR4: Dashboard bug bash — overflow containment, compact headers, intentional default layout
Fixes:
- DashboardGlassCard: flex column + overflow-hidden prevents content bleed
- Children wrapped in scrollable flex-1 container (min-h-0 + overflow-auto)
- Header compacted: 18px icon, sm title, xs description, 16px drag handle
- Hand-crafted lg layout: Agents+Usage top, Cost+Activity second, Time+Weather bottom
- Recent Sessions widened to 9-col at lg (fills row with 3-col System Status)
- Widget registry reordered by operational priority

QA: docs/QA/phase-dashboard-polish-4_TESTPLAN.md + RESULTS.md
Security: grep clean, build passes (1.09s, 0 errors)
2026-02-10 15:40:50 -05:00
Eric
388b2165e4 PR3: Hero metrics row, persistent Quick Actions, weather below fold
- Add HeroMetricsRow component (Model, Sessions, Uptime, Period Spend)
- Move Quick Actions from draggable grid to persistent header buttons
- Remove quick-actions from WidgetId type and WIDGET_REGISTRY
- Move weather widget to bottom of grid (below the fold)
- Wire hero row to live gateway data (sessions, cost, system status)
- Use AiChipIcon for model metric
2026-02-10 15:32:53 -05:00
Eric
f86faa4cf3 docs: dashboard golden path + smoke test
- docs/QA/DASHBOARD_GOLDEN_PATH.md: full widget audit, RPC map, manual test steps
- scripts/dashboard-smoke.mjs: automated API shape validation (6/6 pass)
- All 10/11 widgets confirmed wired to real gateway data
- Tasks widget labeled Demo (no backend exists)
- Answers all wiring questions from production wiring plan
2026-02-10 15:24:28 -05:00
Eric
e1c95726b6 PR2: Grid discipline + responsive breakpoints
- New grid-config.ts: size tiers (S/M/L/XL), widget registry, per-breakpoint layouts
- Breakpoints: lg=12col, md=8col, sm=4col, xs=1col
- Widgets locked to tier sizes (minW=maxW, minH=maxH)
- Auto-generated layouts for all 4 breakpoints
- No widget exceeds cols at any breakpoint
- Layout persistence v2 (multi-breakpoint, clears legacy v1)
- Removed hardcoded DEFAULT_LAYOUT from dashboard-screen
- Removed unused SystemStatus type import
- Build passes, zero dashboard TS errors, no secrets
- QA test plan: docs/QA/dashboard_polish_PR2_TESTPLAN.md
2026-02-10 15:16:50 -05:00
Eric
284ad75fe7 PR1: Unified widget wrapper + visual cleanliness
- Unified DashboardGlassCard as single widget wrapper with optional draggable prop
- Drag handle now integrated in widget header (grab icon, no text)
- Removed hover-float effect (translateY + shadow-md) from all cards
- Replaced with subtle border highlight on hover
- Deleted dead code: widget-chrome.tsx
- Removed DragHandle overlay component from dashboard-screen
- Simplified grid items: widgets receive draggable prop directly
- All 11 widgets updated with draggable prop pass-through
- Build passes, no secrets exposed
- Docs: DASHBOARD_PRODUCTION_POLISH_PLAN.md + QA test plan
2026-02-10 15:07:21 -05:00
Eric
b37f9a0941 fix: replace Drag text with hand icon, tighten grid margins
- DragHandle: icon-only (no 'Drag' text), smaller padding
- widget-chrome: same treatment, added widget-drag-handle class
- Grid margin: 12px → 10px for tighter layout
2026-02-10 14:51:59 -05:00
Eric
a5542c728d fix: remove resize, make drag handle visible with label + border 2026-02-10 14:46:10 -05:00
Eric
d730bfb824 feat: drag-and-drop dashboard with react-grid-layout — draggable widgets, resize, layout persistence in localStorage, Reset Layout wired 2026-02-10 14:42:41 -05:00
Eric
71c64a1e8d feat: configurable weather location (ZIP/city) + 12h/24h clock toggle — persisted in localStorage 2026-02-10 14:34:56 -05:00
Eric
ce8b0537d0 fix: usage meter shows input/output tokens separately from cache — accurate cost breakdown 2026-02-10 14:28:32 -05:00
Eric
da79644408 fix: system status shows active session model (not gateway default) 2026-02-10 14:21:31 -05:00
Eric
f064311af2 fix: usage/cost/notifications consistency — clear labels, data source docs, session preview copy 2026-02-10 14:17:21 -05:00
Eric
edf7d792a4 docs: dashboard gateway wiring map — full inventory + field mappings 2026-02-10 14:14:58 -05:00
Eric
f68b08f770 fix: dashboard a11y, microcopy, header buttons disabled, system status truthfulness, activity log friendly disconnect, weather °F 2026-02-10 14:01:54 -05:00
Eric
be4c21390d fix: usage/cost/notifications consistency — clear labels, data source docs, session preview copy 2026-02-10 13:59:53 -05:00
Eric
6af663aac4 docs: dashboard finalization plan + QA log 2026-02-10 13:58:02 -05:00
Eric
31c2d0fb8a Phase 6: Beta Execution Pack complete
Step 1 deliverables:
- BETA_EXECUTION_GUIDE.md (10KB) - Complete beta execution playbook
- BETA_FEEDBACK_TEMPLATE.md (6.6KB) - Structured issue reporting template

BETA_EXECUTION_GUIDE.md includes:
- Tester recruitment guide
- Timeline (Week 1: Golden Path, Week 2: Full suite, Week 3: Hardening)
- Feedback classification (BLOCKER/IMPORTANT/NICE-TO-HAVE)
- Fix workflow and PR checklist
- Stop conditions (when to escalate vs. defer)
- Success metrics

BETA_FEEDBACK_TEMPLATE.md includes:
- Complete issue report structure
- Environment info checklist
- Steps to reproduce format
- Console errors and diagnostics
- Severity rationale guidance
- Example of good report

Phase 6 mode: QA Lead + Stabilization Engineer
- NO new features allowed
- ONLY: bug fixes, UX clarity, reliability
- Every change must be minimal, isolated, traceable

Ready for Step 2: Assist Beta Testing (await feedback)
2026-02-08 16:19:25 -05:00
Eric
4caab8eb22 Add comprehensive Phase 5 review document
Single file review covering:
- All deliverables (checklist, instructions, scripts, report)
- Golden Path (12 steps) breakdown
- Full test suite (35 cases) details
- Build verification output
- Security scan results
- Script details and usage
- Known issues
- Next steps
- Merge checklist

File: PHASE_5_REVIEW.md (~14 KB)
For Eric's review before merge
2026-02-08 16:14:08 -05:00
Eric
5d2c024b27 Add Golden Path as required first test
Golden Path (12 mandatory steps):
1. Fresh install / reset state
2. Start Studio + Gateway
3. Add provider credentials
4. Open Chat
5. Send simple message
6. Switch model (idle)
7. Enable Smart Suggestions
8. Trigger downgrade suggestion
9. Save current state as Mode
10. Apply Mode
11. Restart Studio
12. Verify state restored correctly

Critical rule: If ANY step fails, STOP and report before continuing.

Updated files:
- BETA_CHECKLIST_v2.1.2.md: Added Golden Path section at top
- TESTER_INSTRUCTIONS.md: Emphasized Golden Path requirement
- BETA_READINESS_REPORT.md: Updated test count (35 total)

Total: 35 test cases (12 Golden Path + 23 full suite)
2026-02-08 15:14:06 -05:00
Eric
0afb07811b Phase 5: Beta readiness for v2.1.2
Deliverables:
- Comprehensive test checklist (23 test cases, ~16KB)
- Tester instructions (installation, troubleshooting, reporting, ~9KB)
- Beta QA scripts (reset state, export diagnostics + scan)
- Beta readiness report (build verification, security scan proof)

Scripts:
- scripts/beta/reset_local_state.(sh|ps1) - Clear localStorage/cache safely
- scripts/beta/export_diagnostics_and_scan.(sh|ps1) - Export + secret scan
- npm scripts: beta:reset-state, beta:export-diagnostics

Build verification:
 Client build: 4.23s
 Server build: 985ms
 Exit code: 0

Security scan:
 No secrets found in diagnostics export
 8 patterns checked (API keys, tokens, passwords, etc.)

Files: 10 changed (~1,500 lines added)
Status: Ready for external beta testing
2026-02-08 15:12:09 -05:00
Eric
aa932c4a7d v2.1.2 release notes with smoke test results 2026-02-08 14:54:50 -05:00
Eric
709262eb53 Phase 4.3: Update QA results with complete test verification 2026-02-08 14:54:50 -05:00
Eric
e58e541f2e Phase 4.3: Add PR summary and complete QA documentation 2026-02-08 14:54:50 -05:00
Eric
de195c2441 Phase 4.3: Session Presets (Modes) implementation
- Add use-modes hook (localStorage CRUD, drift detection, apply logic)
- Add ModeSelector component (dropdown UI near model switcher)
- Add SaveModeDialog (capture current settings as new mode)
- Add ManageModesModal (rename/delete modes, show settings)
- Add RenameDialog (rename existing mode)
- Add ApplyModeDialog (confirm model switch when applying mode)
- Integrate ModeSelector into chat composer

Features:
- Mode CRUD (save, rename, delete, apply)
- Optional model preference per mode
- Smart Suggestions + cost filter settings per mode
- Model switch confirmation (skip if streaming)
- Unavailable model warning with edit option
- Settings drift detection (indicator in mode UI)
- Full keyboard navigation + ARIA labels
- localStorage persistence

Build:  Passes
Security:  No secrets/API keys
QA: Next step
2026-02-08 14:54:50 -05:00
Eric
349c5817ee Phase 4.3 spec: Session Presets (Modes)
- Add PHASE_4.3_SESSION_PRESETS.md spec
- Add QA test plan with 17 test cases
- Add empty QA results template

Depends on Phase 4.2 (pinned models + preferred defaults)

Spec includes:
- Mode CRUD (save, rename, delete)
- Mode application with model switch confirmation
- localStorage persistence
- Accessibility (keyboard nav, ARIA labels)
- Edge cases (unavailable models, duplicate names, settings drift)

Implementation in follow-up PR.
2026-02-08 14:54:50 -05:00
Eric
25ff9ddaf9 Merge pull request #7 from outsourc-e/phase4.2-pinned-models
Phase4.2 pinned models
2026-02-08 14:08:59 -05:00
Eric
2db86642a0 fix(pinned-models): add validation for unavailable pins + accessibility
Validation:
- Track unavailable pinned models (not in /api/models)
- Show as "Unavailable" with Remove button
- Red styling to indicate issue

Accessibility:
- All pin/unpin buttons have descriptive aria-labels
- Keyboard focus styles (focus:ring-2)
- focus:opacity-100 on pin button for keyboard users
- Remove button for unavailable pins is keyboard accessible

Changes:
- availableModelIds Set tracks currently available models
- unavailablePinnedModels computed from pinned - available
- Unavailable pins shown in pinned section with Remove button
- aria-label on all model select + pin/unpin buttons
- focus:ring-2 + focus:outline-none for keyboard navigation
2026-02-08 14:06:52 -05:00
Eric
e4d340f710 feat: Phase 4.2 - pinned models + preferred defaults
Goal: Make model switching personal and intentional

Features:
1) Pinned Models in Model Switcher
   - Star icons (☆ unpinned,  pinned) to pin/unpin models
   - Pinned section at top of dropdown
   - localStorage persistence + cross-tab sync
   - Empty section hidden when no pins

2) Preferred Models in Settings
   - Preferred Budget Model dropdown
   - Preferred Premium Model dropdown
   - Used as primary targets for Smart Suggestions
   - Falls back to tier logic if unavailable

3) Only Suggest Cheaper Toggle
   - New setting: onlySuggestCheaper (default OFF)
   - When enabled: never suggest upgrades, only downgrades
   - Provides granular control over suggestion behavior

Implementation:
- usePinnedModels hook (NEW)
  - togglePin(modelId), isPinned(modelId)
  - storage event listener for cross-tab sync

- useModelSuggestions (UPDATED)
  - Check preferred budget/premium models first
  - Fall back to tier-based logic
  - Skip upgrades when onlySuggestCheaper enabled

- ChatComposer (UPDATED)
  - Pinned section renders at top
  - Star emoji buttons (no icon dependency)
  - Hover to show pin, always visible to unpin

- Settings (UPDATED)
  - Smart Suggestions section with 4 controls
  - Fetches models via /api/models for dropdowns
  - Auto-detect option (empty string)

Storage:
- localStorage.pinnedModels: string[] of model IDs
- settings.preferredBudgetModel: string (model ID or '')
- settings.preferredPremiumModel: string (model ID or '')
- settings.onlySuggestCheaper: boolean

Bundled with Phase 4.1:
- Smart Suggestions (ModelSuggestionToast, useModelSuggestions)
- Not merged to main yet, included here as prerequisite

Docs:
- PHASE_4.2_PINNED_MODELS.md (spec)
- QA test plan (16 tests + 3 edge cases)
- QA results (all build pass)

Build:  Passes in 807ms
Security:  Clean (no secrets)
Bundle: 369.88 kB (+6.68 kB from Phase 4.1)

What changed: Pinned models + preferred defaults + only-cheaper toggle
How to test: Pin models in dropdown, set preferred in Settings, toggle only-cheaper
Risks: None - additive only, no breaking changes
Security: Clean - localStorage only, no sensitive data
2026-02-08 14:04:56 -05:00
Eric
30fea9ffd4 Merge pull request #6 from outsourc-e/phase4.1-smart-suggestions
Phase4.1 smart suggestions
2026-02-08 13:50:42 -05:00