* fix(voice): show friendly error with settings link when STT model is missing
Replace technical "whisper.cpp binary not found" error with a user-friendly
message and a "Set up" link that navigates directly to Settings > Local AI
Models so non-technical users can easily download the required speech model.
* style: apply prettier formatting
Phase 1 of the upsell flow for free users:
- Shared `useUsageState` hook with module-level cache (60s TTL)
- Reusable `UpsellBanner` component (info/warning/upgrade variants)
- `UsageLimitModal` shown when user tries to send at hard limit
- `GlobalUpsellBanner` for app-level usage warnings
- Pre-limit warning banner in Conversations at 80%+ usage
- localStorage-based dismiss persistence with cooldown
Closes#403
* feat(skills): core RPC data stats, tool timeout env, ping state merge (#191)
- Add openhuman.skills_data_stats and SkillDataDirectoryStats (disk usage).
- Centralize tool execution timeout via OPENHUMAN_TOOL_TIMEOUT_SECS (tool_timeout).
- Apply timeout to skill event loop, agent tool loop, harness default, delegate.
- Ping scheduler: merge connection_error into published_state via registry.
- JSON-RPC e2e: assert skills_data_stats.
Closes#214Closes#218
Part of #213 (backend)
Made-with: Cursor
* feat(app): skills sync stats UI, reconnect resync, FE timeouts, chat errors (#191)
- useSkillDataDirectoryStats + Skills.tsx merge disk stats with skill state.
- resyncRunningSkillsAfterReconnect on socket connect; disconnectSkill OAuth cleanup in finally.
- withTimeout for callTool/triggerSync; VITE_TOOL_TIMEOUT_SECS in app .env.example.
- Structured ChatSendError in Conversations (data-chat-send-error-code).
Closes#213Closes#215Closes#216Closes#217Closes#219
Made-with: Cursor
* test(e2e): onboarding helpers and skills smoke specs (#191)
- shared-flows: 5-step onboarding, completeOnboardingIfVisible.
- auth-access-control + voice-mode use shared helpers.
- skills-registry: named skill assertion; new skill-oauth, multi-round, reconnect, lifecycle specs.
Closes#220Closes#221Closes#222Closes#223Closes#224
Part of #189 (E2E helpers)
Made-with: Cursor
* style: rustfmt + Prettier for CI (PR #282)
Fix Type Check workflow: prettier --check and cargo fmt --check.
Made-with: Cursor
* fix: PR #282 review — tool timeout config, tool_timeout module, CI diagnostics
- Centralize VITE_TOOL_TIMEOUT_SECS in config.ts (TOOL_TIMEOUT_SECS)
- Move tool_timeout to folder module; merge_published_state broadcasts SKILL_STATE_CHANGED
- Resync guard after socket reconnect; qjs_engine logs data dir stat errors
- E2E: registry/lifecycle/multi-round failure diagnostics; onboarding label constant
- chatSendError arrow export; rustfmt/import grouping in event_loop
Made-with: Cursor
* test(e2e): add Gmail skill end-to-end tests
- Introduced a comprehensive end-to-end test suite for the Gmail skill, covering the full lifecycle from discovery to OAuth completion and email management.
- Implemented two modes: a lifecycle-only mode that validates the skill's event loop without real credentials, and a live mode that interacts with the Gmail API using actual credentials.
- Added detailed environment variable requirements and usage instructions for both testing modes.
Closes #XXX (replace with relevant issue number if applicable)