Skip to content

feat(web): React UI v2.0 — Phase 2 Tasks 23-25 (SSE + WS + reducer)#21

Merged
aksOps merged 3 commits into
mainfrom
feat/web-phase-2-batch-b
May 16, 2026
Merged

feat(web): React UI v2.0 — Phase 2 Tasks 23-25 (SSE + WS + reducer)#21
aksOps merged 3 commits into
mainfrom
feat/web-phase-2-batch-b

Conversation

@aksOps

@aksOps aksOps commented May 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Phase 2 Batch B of React UI v2.0 — the live-data plumbing. After this lands, Phase 2 Batch C (data hooks composing apiFetch + SSE + reducer) becomes a 7-task parallel batch.

  • Task 23useEventSource(url, onMessage, enabled) (web/src/api/sse.ts) + MockEventSource test helper. JSON-parse-and-drop-malformed pattern. Closes the connection on unmount; intentionally excludes onMessage from deps to avoid reconnect-per-render. 2 tests.
  • Task 24useWebSocket(url, onMessage, enabled) (web/src/api/ws.ts) + MockWebSocket helper. Identical signature to useEventSource so it's drop-in substitutable when SSE is blocked by a corporate proxy. 4 tests including malformed JSON skip + enabled=false no-connect.
  • Task 25sessionReducer (web/src/state/sessionReducer.ts) — pure reducer with two actions (bootstrap, event) and a vm_seq watermark that drops stale/duplicate events. Handles agent_finished, tool_invoked, approval_pending, status_changed event kinds; unknown kinds still advance vmSeq and append to the events buffer. Returns the same state reference on stale events (test asserts expect(next).toBe(state)). 7 table-driven tests.

Validation

  • cd web && npm install → 0 vulnerabilities
  • npm run typecheck → exit 0
  • npx vitest run46 passed / 0 failed (Phase 2 Batch A's 33 + 2 SSE + 4 WS + 7 reducer)
  • npm run build → clean, 194 kB JS, 8.1 kB CSS

Nothing touches src/runtime/ — no dist/app.py regen.

Design notes

  • The eslint-disable-next-line react-hooks/exhaustive-deps comments in the hooks are intentional — onMessage is omitted from the dep array to avoid reconnecting on every render. ESLint isn't installed yet (Task 20b), but the comments are harmless placeholders for when it is.
  • sessionReducer is fully pure: no closures, no async, no side effects. Same state reference returned for no-op cases.
  • The reducer doesn't yet handle every event kind the backend can emit (e.g. agent_started, session.created, session.status_changed, lessons updates). Those will be added as the canvas + monitors need them in Phases 4-5. Today's set covers the bootstrap + happy-path delta application.

Test plan

  • Vitest: 46/46 pass
  • Typecheck: exit 0
  • Build: clean
  • Pytest backend stays green (no backend changes)
  • CI: lint + type + test + sonar + bundle + skill-lint
  • CI: SonarCloud quality gate

🤖 Generated with Claude Code

@sonarqubecloud

Copy link
Copy Markdown

@aksOps aksOps merged commit ab16910 into main May 16, 2026
9 checks passed
@aksOps aksOps deleted the feat/web-phase-2-batch-b branch May 16, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant