Keep the session list consistent across browser tabs #73

Merged
lucas merged 1 commit from agent/issue-27-session-list-sync into main 2026-10-26 13:58:32 +01:00
Collaborator

Closes: #27

Implements the plan in the issue:

  • SessionSummary.live and a sessions_changed broadcast frame.
  • Bridge: notifySessionsChanged() clears the cache and broadcasts. It runs on create, resume, dispose, delete, title regeneration, rename, auto-title, extension setSessionName, and agent_end. listSessions now builds fresh copies with live on every call, and adds active sessions that are not on disk yet.
  • Routes: GET /sessions no longer mutates cached objects. Archive and unarchive now broadcast.
  • Web: the store refetches on sessions_changed. The archive, unarchive and rename actions refetch instead of editing the list locally. archivedAt is removed from the live session state. The Sidebar partitions on server data only. SessionView navigates to /session when the open session becomes archived.
  • Not in the issue's file list: SessionPicker.tsx read archivedAt from the live session state. It now reads archive state from sessions.

Small deviations:

  • The synthesized live entries and the Sidebar scope filter use workspacePath ?? cwd, to match the existing scoping for trigger sessions.

Verification: bun run typecheck passes, and bun test in apps/server passes (873 tests). I have not done the manual two-tab check, because this session ran unattended.

Closes: #27 Implements the plan in the issue: - `SessionSummary.live` and a `sessions_changed` broadcast frame. - Bridge: `notifySessionsChanged()` clears the cache and broadcasts. It runs on create, resume, dispose, delete, title regeneration, rename, auto-title, extension `setSessionName`, and `agent_end`. `listSessions` now builds fresh copies with `live` on every call, and adds active sessions that are not on disk yet. - Routes: `GET /sessions` no longer mutates cached objects. Archive and unarchive now broadcast. - Web: the store refetches on `sessions_changed`. The archive, unarchive and rename actions refetch instead of editing the list locally. `archivedAt` is removed from the live session state. The Sidebar partitions on server data only. `SessionView` navigates to `/session` when the open session becomes archived. - Not in the issue's file list: `SessionPicker.tsx` read `archivedAt` from the live session state. It now reads archive state from `sessions`. Small deviations: - The synthesized live entries and the Sidebar scope filter use `workspacePath ?? cwd`, to match the existing scoping for trigger sessions. Verification: `bun run typecheck` passes, and `bun test` in `apps/server` passes (873 tests). I have **not** done the manual two-tab check, because this session ran unattended.
The server's GET /sessions is now the only source for the list: each
summary carries a `live` flag derived from the bridge's active handles,
and every list-changing event broadcasts `sessions_changed` so all tabs
refetch. GET /sessions no longer mutates the shared cache objects, so
archive flags cannot go stale. A tab viewing a session that gets
archived elsewhere navigates to /session.

Co-Authored-By: Claude Opus 5.5 via omp-deck
lucas merged commit aab7eadcc6 into main 2026-10-26 13:58:32 +01:00
lucas deleted branch agent/issue-27-session-list-sync 2026-10-26 13:58:33 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
lucas/omp-deck!73
No description provided.