v0.51.30 — Release G (offline recovery + PWA hardening + opt-in session navigation)
Three-PR contributor batch (all from @ai-ag2026), shipping browser offline recovery, PWA cache hardening, and two opt-in session navigation features previously deferred for UX gate.
Highlights
Browser offline recovery + PWA cache hardening
PR #1891 by @ai-ag2026. The app now shows a clearly-styled offline banner when the browser can't reach Hermes, probes /health automatically, and refreshes the page when the connection comes back. Stream errors are deferred while offline so a brief network drop doesn't immediately surface a terminal chat error. Service-worker shell assets switch to network-first (with cache fallback), so local hotfixes are no longer hidden behind stale cached JS/CSS — but PWA install + offline launch are preserved via install-time pre-caching of SHELL_ASSETS.
The offline banner is high-contrast, scoped to browser connectivity, and offers a single "Check now" button. Stream-error deferral only triggers when the banner is visible OR navigator.onLine===false, so Hermes-up + browser-online flows errors through normally — no swallowed auth errors.
Two opt-in session navigation features (default OFF)
Both are new toggles in the Appearance settings panel.
-
PR #1928— Session jump buttons (session_jump_buttons). StickyStartpill (loads full history and jumps to beginning) and the existing scroll-to-bottom button expanded into anEndpill. Localized text, tooltip, and aria labels. -
PR #1929— Session endless-scroll (session_endless_scroll). Auto-prefetches older transcript pages while scrolling upward, with a 1.5x viewport prefetch window so prepended pages have scroll runway. Builds on the viewport-preservation fix (#1927) shipped in v0.51.29. When the setting is OFF, users get the manual "Load earlier" button (no auto-trigger) — a deliberate UX trade-off in the PR.
Verification
- Tests: 4960 → 4977 passing (+17 net new)
- Browser API harness (port 8789): all 11 endpoints + 20 QA tests PASS
- Manual browser verification on stage-325 (port 8789): both new toggles render in Settings panel, helper functions exposed correctly, offline-banner template loads, "Check now" button present
node -cclean on all 6 modifiedstatic/*.jsfiles- Opus advisor pre-release verdict: SHIP-WITH-FIXES (explicit "Ship the batch" recommendation; both fast-follows are non-blockers)
- v0.51.29 carry-overs preserved
Conflict resolution
#1928 and #1929 both touched static/ui.js, static/i18n.js, static/index.html, static/panels.js, api/config.py. Mechanical conflicts (settings keys, locale entries, HTML toggles, accessor branches) were resolved by keeping both. The static/ui.js scroll-listener conflict required intent-based resolution: #1929 INTENTIONALLY replaces the legacy el.scrollTop<80 auto-trigger with a gated prefetch — the test test_scroll_listener_prefetches_older_messages_only_when_enabled enforces this. CHANGELOG conflicts auto-resolved during rebase.
Follow-up items filed
- Race between endless-scroll prefetch and Start-jump's
_ensureAllMessagesLoaded(narrow window when both opt-ins ON simultaneously) - #1928 locale parity:
session_jump_*keys are English literals in 8 non-en locales
Full diff
16 files, +649/-30.
Full Changelog: v0.51.29...v0.51.30