fix(desktop): prevent stored-id rotations from stealing session focus (rebase of #66122) - #67118
Merged
Merged
Conversation
# Conflicts: # apps/desktop/src/app/session/hooks/use-session-state-cache.ts
Collaborator
Related to closed-unmerged #66122: this is its current-main salvage, with the rotation emission re-homed after the session-state refactor. It remains an active implementation, not a duplicate. |
17 tasks
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
…rch#67118) # Conflicts: # apps/desktop/src/app/session/hooks/use-session-state-cache.ts Co-authored-by: UnathiCodex <theunathi@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Salvage / rebase of #66122 (by @UnathiCodex) onto current
main, which the original PR conflicts with. Same fix and tests, re-homed to where the rotation-signal code now lives onmain.Prevents a delayed auto-compression stored-id rotation on a background session from stealing the foreground route. Previously the rotation signal carried only the next stored id and the route-follow effect navigated unconditionally, so a fast A → B → C switch could be overwritten by A's delayed
session.infoevent — snapping both the sidebar selection and the transcript back to A.What changed vs the original PR
The original PR emitted the rotation signal from
use-session-state-cache.ts'sensureSessionState. On currentmain, that emit logic has since moved intohandleTransitioninstore/session-states.ts(per #66454's$sessionStatesrefactor). The salvage adapts accordingly:store/session.ts— replace the bare$activeSessionStoredId: string | nullatom with a one-shot$activeSessionStoredIdRotationcarrying{ previousStoredSessionId, nextStoredSessionId, runtimeSessionId }. The provenance is load-bearing: a bare next-id cannot tell whether the user already navigated away while React is waiting to run the effect.store/session-states.ts—handleTransitionnow emits the provenance-carrying rotation event (instead ofsetActiveSessionStoredId(next.storedSessionId)).use-session-state-cache.ts— drops the obsolete stored→runtime reverse mapping in the cache hook as soon as the id rotates (the emit itself is centralized inhandleTransition).use-session-actions/index.ts— the consumer effect now follows a rotation only while the exact runtime, current selection, and route intent still belong to the rotating conversation; consumes the event even when stale so it can't replay after a remount; and updates the underlying selection in place (without navigating) when a route overlay/page is open. Threads the existinggetRoutedStoredSessionIdhelper (already present inwiring.tsx) into the hook.wiring.tsx— one line: passgetRoutedStoredSessionIdintouseSessionActions.Consumer logic and all four route-following test cases are preserved verbatim from the original PR.
Reproduction
session.inforeports its continuation stored id.navigate(..., { replace: true }), snapping selection + transcript back to A.Tests
npx vitest run --project ui use-session-actions.test.tsx use-session-state-cache.test.tsx— 32 passednpm run typecheck(tsc-p .+ electron project) — cleaneslinton all five changed source files — cleanSupersedes #66122. Credit to @UnathiCodex — commit authorship preserved.
Co-authored-by: UnathiCodex theunathi@gmail.com