The Tauri bridge connected to the daemon once at startup and held a single
stream with no recovery: when the daemon exited (Restart/Stop, crash, or an
update), the reader emitted spacesh:disconnected and died, and every later
request went through the dead writer forever — the GUI was permanently stuck
(settings frozen, offline). Since the bridge is Rust-side state that survives
a webview reload, even Cmd+R didn't recover it.
- bridge.rs: requests now reconnect-and-retry on failure with a single-flight
guard (generation counter) so concurrent failures collapse into one
reconnect and never open duplicate connections; a 5s reply timeout catches
silently-dropped connections. ensure_daemon respawns the daemon if it
exited. On success the bridge emits spacesh:reconnected.
- App.tsx: on spacesh:reconnected, bump a connection epoch that keys
LayoutEngine, remounting terminals so they re-attach (snapshot + live stream)
to the restarted daemon; also reload health/config/status.
- Settings: drop the Stop button — with lazy daemon spawn any GUI request
resurrects the daemon, so an in-GUI "stop" is contradictory. Restart now
works end to end (shutdown → reconnect respawns → panels re-attach).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Font change now applies to already-open terminals: the WebGL renderer
caches glyphs in a texture atlas keyed by the old font/size, so the live
re-apply effect now calls webglAddon.clearTextureAtlas() (via a new ref)
after updating fontFamily/fontSize, before refitting.
- Daemon uptime now reflects a restart: the Settings daemon section ticks
every second for live uptime, and Stop/Restart trigger an onReload callback
that re-fetches health/status in App so a restarted daemon's new
started_at_ms is shown instead of the stale value.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>