Skip to content

refactor(desktop): derive working/attention session sets from $sessionStates - #66454

Merged
OutThisLife merged 1 commit into
mainfrom
ethie/session-status-sync
Jul 17, 2026
Merged

OutThisLife merged 1 commit into
mainfrom
ethie/session-status-sync

Conversation

@ethernet8023

Copy link
Copy Markdown
Collaborator

What does this PR do?

$workingSessionIds and $attentionSessionIds were independently-maintained
atoms that updateSessionState had to manually keep in sync with the session
cache — paired setSessionWorking/setSessionAttention calls on every state
tick, plus a rotation special-case in ensureSessionState. This is the classic
"projection atom drifted from the cache" bug class: two sources of truth that
must agree but nothing enforces agreement.

This PR makes them pure computed() projections of $sessionStates,
so the data flow is one-directional:

gateway event → cache → $sessionStates → computed views ($working, $attention)

All transition side-effects (watchdog arm/disarm, settle grace, unread
marker, compression id rotation signal) move into a single handleTransition
function fired from publishSessionState by diffing previous vs next — one
choke point instead of per-callsite bookkeeping.

The watchdog's force-clear (8 min of stream silence) now reaches the cache
through a setWatchdogClearFn callback the cache wires on mount, instead of
a listener set.

Related Issue

No issue — self-driven refactor found during review of the session-status
data flow.

Type of Change

  • ♻️ Refactor (no behavior change)

Changes Made

  • store/session-states.ts

    • $workingSessionIds / $attentionSessionIds are now computed($sessionStates) projections — deleted the independently-maintained atoms + their setters (setWorkingSessionIds, setAttentionSessionIds, setSessionWorking, setSessionAttention)
    • Watchdog, settle-grace, unread-finished, and compression id-rotation logic consolidated into handleTransition(prev, next, runtimeId), called from publishSessionState
    • clearAllSessionStates() now disarms all watchdog timers and drops settle-grace entries — a gateway switch can no longer leak stale 8-min timers or let the old gateway's sessions squat in the sidebar merge keep-set for 30s
    • dropSessionState() disarms the dropped runtime's watchdog timer
    • setWatchdogClearFn replaces onSessionWatchdogClear listener pattern
  • store/session.ts — removed ~180 lines of now-dead watchdog/settle/attention/unread code that moved to session-states.ts

  • app/session/hooks/use-session-state-cache.ts

    • updateSessionState no longer manually calls setSessionWorking/setSessionAttention/noteSessionActivitypublishSessionState handles all transitions
    • ensureSessionState creates a new state object on stored-id rotation (instead of mutating in place) so updateSessionState can detect the transition
    • Watchdog clear wired via setWatchdogClearFn effect
  • Import sites — 8 files updated to import $workingSessionIds/$attentionSessionIds/getRecentlySettledSessionIds from session-states instead of session

How to Test

  1. npm run typecheck — both tsconfigs clean
  2. npm run lint — eslint clean
  3. npm test214 files, 1792 passed / 1 skipped
  4. Watchdog tests now exercise the real timer→callback wiring (via setWatchdogClearFn) instead of manually simulating the clear — and a new test asserts clearAllSessionStates disarms all timers

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run npm test and all tests pass
  • I've added tests for my changes — watchdog tests rewritten to test transitions through publishSessionState (the real public surface), plus a new clearAllSessionStates disarm test
  • I've tested on my platform: NixOS 25.05, Hyprland

Documentation & Housekeeping

  • N/A — no config keys, no tool changes, no new skills

…nStates

$workingSessionIds and $attentionSessionIds were independently maintained
atoms that updateSessionState had to manually keep in sync with the session
cache (paired setSessionWorking/setSessionAttention calls, plus a rotation
special-case in ensureSessionState). Make them computed() projections of
$sessionStates instead, so the data flow is one-directional:
gateway event → cache → $sessionStates → computed views.

Transition side-effects (watchdog arm/disarm, settle grace, unread marker,
compression id rotation signal) move into handleTransition, fired from
publishSessionState by diffing previous vs next — one choke point instead
of per-callsite bookkeeping. The watchdog's force-clear reaches the cache
through setWatchdogClearFn rather than a listener set.

Also:
- clearAllSessionStates disarms all watchdog timers and drops settle-grace
  entries so a gateway switch can't leak stale timers or keep-set rows
- dropSessionState disarms the dropped runtime's watchdog timer
- watchdog tests now exercise the real timer→callback wiring instead of
  manually simulating the clear
@OutThisLife
OutThisLife merged commit cf52edb into main Jul 17, 2026
23 checks passed
@OutThisLife
OutThisLife deleted the ethie/session-status-sync branch July 17, 2026 18:46
@alt-glitch alt-glitch added type/refactor Code restructuring, no behavior change comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 17, 2026
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…-status-sync

refactor(desktop): derive working/attention session sets from $sessionStates
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…-status-sync

refactor(desktop): derive working/attention session sets from $sessionStates
prmartinow pushed a commit to prmartinow/hermes-agent that referenced this pull request Aug 26, 2026
…-status-sync

refactor(desktop): derive working/attention session sets from $sessionStates
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
…-status-sync

refactor(desktop): derive working/attention session sets from $sessionStates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/refactor Code restructuring, no behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants