fix: prevent session sidebar from going stale#255
fix: prevent session sidebar from going stale#255mattleaverton merged 3 commits intodanshapiro:mainfrom
Conversation
…nset The session sidebar could permanently stop updating due to a race condition: when sessions.changed WS messages arrived before bootstrap set activeSurface, queueActiveSessionWindowRefresh() silently exited and never queued a refresh. All subsequent session updates were also silently dropped. Three fixes: - Default to 'sidebar' when activeSurface is undefined in refresh thunks - Mark wsSnapshotReceived=true on any successful HTTP fetch (not just during the 30-second bootstrap window), so WS patches aren't silently discarded - Add persistedAt timestamp to tab state in localStorage and log a warning when restoring state older than 24 hours Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 837a3b23f9
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
src/store/persistMiddleware.ts
Outdated
|
|
||
| if (tabsDirty) { | ||
| const tabsPayload = { | ||
| persistedAt: Date.now(), |
There was a problem hiding this comment.
Stop forcing tab payload churn with volatile persistedAt
Adding persistedAt: Date.now() makes every tabs flush produce a brand-new raw string even when the persisted tab content is unchanged (for example tabs/updateTab updates only lastInputAt, which is stripped before persistence). Cross-tab sync dedupes by exact raw value in installCrossTabSync (tryDedupeAndMark), so this change defeats that dedupe and causes other clients to hydrate tabs repeatedly during normal typing activity, creating unnecessary cross-tab churn and avoidable UI/perf noise.
Useful? React with 👍 / 👎.
…-resolve # Conflicts: # src/store/persistMiddleware.ts # src/store/sessionsThunks.ts # src/store/tabsSlice.ts
Set persistedAt once per session instead of on every flush, so the serialized payload stays identical when tab content hasn't changed. This preserves the raw-string dedup in cross-tab sync. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
queueActiveSessionWindowRefresh()to'sidebar'whenactiveSurfaceis undefined — fixes a race condition wheresessions.changedWS messages arriving before bootstrap silently dropped all sidebar refreshes permanentlywsSnapshotReceived = trueon any successful HTTP session fetch, not just during the 30-second bootstrap window — prevents WS patches from being silently discarded after reconnect'sidebar'default torefreshActiveSessionWindow()for consistencypersistedAttimestamp to persisted tab state and log a warning when restoring state older than 24 hoursContext
Two Freshell instances on different ports showed divergent session lists — one kept updating while the other froze. Root cause was
activeSurfacebeingundefinedwhen earlysessions.changedmessages arrived, causing the refresh thunk to exit silently. A secondary issue:wsSnapshotReceivedwas only promoted during a narrow 30s bootstrap window, so any reconnect outside that window permanently blocked WS patches.Test plan
🤖 Generated with Claude Code