feat(web): read projects, chat history and the agent roster from watches and retire their seq 0 events
Summary
- The web client still rebuilt the project list, the chat-history index and the agent roster from
seq = 0events. A client could miss one, and a socket with no session subscription never received them. - The previous change added state watches for these three. This change makes the web client read them and removes the old events from the relay.
Related Issue
Refs #1070
Searched open and closed PRs for the same problem. No PR covers it. This is the fifth of several PRs for the read-model work in #1070. It builds on the state watch PR (#1094).
Type of Change
- feat: new feature
- fix: bug fix
- docs: documentation only
- style: formatting or non-functional styling changes
- refactor: internal cleanup with no behavior change
- perf: performance improvement
- test: adds or updates tests
- build: build or dependency changes
- ci: CI/CD workflow changes
- chore: maintenance or tooling
- revert: reverts a previous change
What Changed
- The project switcher takes its list from the
projectswatch. The state and each delta carry the full list. A late HTTP answer never overwrites a newer watched list. - The chat-history sidebar installs the
chat_historyindex from the watch state. It refetches the index on each delta. The reconnect refetch stays as a retrying path. - The agent store reads the
agentswatch. A delta goes to the same reducers a desktop event uses. A fresh state spawns agents the store lacks and disconnects connected agents the host dropped. Anagent_removeddelta disconnects an agent that another client killed. - The relay no longer sends
projects_changed,chat_history_changed, or agent events without a session asseq = 0events. The Rust and TypeScript registries drop the two event names. The mutation sites publish to the watches only. - Desktop is unchanged. The Tauri transport has no watches and keeps its
acp:agent_*listeners. WS_PROTOCOL_VERSIONgoes from 5 to 6. An old client reloads once.
How It Was Tested
-
bun run ci(Biome lint + format + imports, strict mode) -
bun run typecheck -
bun run test -
cargo clippy --all-targets -- -D warnings(in src-tauri) -
cargo test(in src-tauri) - Manual verification completed
- Not applicable
New tests cover: the project list from a watch state and delta with the active project kept; a stale HTTP list dropped; the history index installed from state and refetched on a delta; the roster reducers reached through a delta, a fresh state and a kill; the store wiring on a transport with and without watches; the relay sending no seq = 0 event for the retired types.
Screenshots or Recordings
No user-visible UI change. The web client shows the same lists. They now stay correct after a missed change or a reconnect. The tests above cover the behavior.
CI & Review Gate
- All CI checks pass (PR Validation, Rust Checks, Build Verification, Security Scans)
- Code review comments from CodeRabbit / Claude have been addressed or resolved
- No unresolved review findings remain
Checklist
- My PR title follows the conventional commit format used by this repo
- I linked the related issue or explained why none exists
- I updated docs when needed
- I added or updated tests when needed
- I verified the change does not introduce unrelated modifications
- I read AGENTS.md and followed the contributor guidelines
- A human reviewed the complete diff before submission
Summary by cubic
Makes the web client build the project list, chat-history index, and agent roster from the state watches added in #1094, and retires the missable seq = 0 events that carried the same data. A client that missed an event or never subscribed a session now gets fresh state on subscribe and deltas afterward.
- Watch state and deltas go through the same store reducers as before; a stale HTTP list response can't overwrite newer watched state, and the auto-save subscriber never writes a host-sent list back as local edits. A fresh roster state spawns agents the store lacks and disconnects any tracked agent the host removed.
- The relay stops sending
projects_changed,chat_history_changed, and sid-less agent roster events; desktop and session-scoped events are unchanged. WS_PROTOCOL_VERSIONbumps to 6, so an older client reloads once and picks up the new contract.
Summary by CodeRabbit
- Improvements
- Project lists and chat history now update through live state watches, helping keep web and remote views in sync without relying on legacy change notifications.
- Agent lifecycle and roster updates are delivered through agent watches, while session event streams no longer receive those roster notifications as extra events.
- The WebSocket protocol version is now 6.