feat(web): read projects, chat history and the agent roster from watches and retire their seq 0 events

Merged
GN
6d ago
+971-773

Summary

  • The web client still rebuilt the project list, the chat-history index and the agent roster from seq = 0 events. 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 projects watch. 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_history index from the watch state. It refetches the index on each delta. The reconnect refetch stays as a retrying path.
  • The agent store reads the agents watch. 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. An agent_removed delta disconnects an agent that another client killed.
  • The relay no longer sends projects_changed, chat_history_changed, or agent events without a session as seq = 0 events. 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_VERSION goes 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_VERSION bumps 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.