Summary
The current web-react client manages its own idle → loading → polling → succeeded/failed state machine in useExecution.ts. Once the Traverse runtime ships the app state machine (Traverse #525), SSE endpoint (Traverse #526), and command dispatch (Traverse #527), this local state machine must be removed and replaced with a pure subscription to runtime state events.
This makes web-react the reference implementation for the SSE client pattern — all other platform clients will follow the same shape.
Blocked on
Status (2026-07-06): Traverse #525 and #526 are done. Remaining blocker is #527 only.
Traverse #525 — app state machine spec + runtime done
Traverse #526 — SSE state subscription endpoint done
- Traverse #527 — command dispatch endpoint (remaining blocker)
What changes
Remove:
src/hooks/useExecution.ts — local polling state machine
src/client/traverseClient.ts pollExecution() — no longer needed, state arrives via SSE
Add:
src/hooks/useAppState.ts — subscribes to GET /v1/workspaces/{workspace}/apps/traverse-starter/events via EventSource
src/client/traverseClient.ts sendCommand() — POSTs to /v1/workspaces/{workspace}/apps/traverse-starter/commands
- State shape driven entirely by runtime event payloads — no local transition logic
App.tsx becomes:
const { state, context, output } = useAppState(client, workspaceId)
// state: 'idle' | 'processing' | 'results' | 'error' — from runtime
// output: runtime-provided fields when state === 'results'
<button onClick={() => client.sendCommand('submit', { note })}>Start</button>
Architecture constraint
The hook must contain zero transition logic. It maps runtime state names to render states only. No if (state === 'processing') startPolling().
Definition of Done
Summary
The current
web-reactclient manages its ownidle → loading → polling → succeeded/failedstate machine inuseExecution.ts. Once the Traverse runtime ships the app state machine (Traverse #525), SSE endpoint (Traverse #526), and command dispatch (Traverse #527), this local state machine must be removed and replaced with a pure subscription to runtime state events.This makes
web-reactthe reference implementation for the SSE client pattern — all other platform clients will follow the same shape.Blocked on
Status (2026-07-06): Traverse #525 and #526 are done. Remaining blocker is #527 only.
Traverse #525 — app state machine spec + runtimedoneTraverse #526 — SSE state subscription endpointdoneWhat changes
Remove:
src/hooks/useExecution.ts— local polling state machinesrc/client/traverseClient.tspollExecution()— no longer needed, state arrives via SSEAdd:
src/hooks/useAppState.ts— subscribes toGET /v1/workspaces/{workspace}/apps/traverse-starter/eventsviaEventSourcesrc/client/traverseClient.tssendCommand()— POSTs to/v1/workspaces/{workspace}/apps/traverse-starter/commandsApp.tsx becomes:
Architecture constraint
The hook must contain zero transition logic. It maps runtime state names to render states only. No
if (state === 'processing') startPolling().Definition of Done
useExecution.tsdeleteduseAppState.tsimplemented — connects viaEventSource, dispatches state updates on eventssendCommand()added totraverseClient.tsApp.tsxupdated — submits viasendCommand, renders fromuseAppStatephase1_smoke.shupdated if endpoint paths change