- lib/crashRecovery.ts: window.onerror + unhandledrejection handlers,
dedupe identical messages within 10s, burst-reload after 8 distinct
errors in 30s
- components/CrashToast.tsx: portal stack in bottom-right, max 3 visible,
auto-dismiss after 7s, per-entry close button
- Wired in main.tsx before bootstrap so crypto/i18n errors are captured,
rendered from App.tsx alongside UpdateToast
Covers the async layer ErrorBoundary misses (realtime handlers, stray
Promises, setTimeout callbacks, LiveKit listeners).