feat(examples): add experimental pi harness example (#2210)
* feat(examples): add pi harness playground * refactor(pi-harness): scope to an experimental example and rebuild the UI Trim the example-local harness to what the demo and test use: drop the execution-environment type surface, routed calls, lane access, and the follow-up, next-run, cancel-queued, and lane-config transport commands. The WebSocket protocol is now snapshot, subscribe, submit, abort, and steer. Rebuild the client on the same Kumo chat layout as the other examples: a pinned header, a scrolling transcript with user bubbles and assistant tool cards, an Empty state with suggestion buttons, and an InputArea composer with a stop button while a turn runs. Rewrite the README and RFC to describe this as an experimental example on a pinned pi dev build, not a package API, and list what must land before it becomes one. Claude-Session: https://claude.ai/code/session_01KEFnjoMnZBMewsuD9qxGrL * fix(pi-harness): commit the vendored pi archives the install needs Claude-Session: https://claude.ai/code/session_01KEFnjoMnZBMewsuD9qxGrL * refactor(pi-harness): connect the UI with useAgent Build usePiSession on useAgent from agents/react instead of a hand-rolled WebSocket with its own reconnect loop. The protocol over the WebSockets capability is unchanged. Claude-Session: https://claude.ai/code/session_01KEFnjoMnZBMewsuD9qxGrL * chore(pi-harness): rename the worker and pin a dev inspector port Deploy as pi-harness-example, give the Vite dev server its own inspector port so it can run beside the other harness examples, and note CLOUDFLARE_ACCOUNT_ID for logins with several accounts. * fix(pi-harness): dedupe React so the client renders agents/react resolved a second React copy from the agents package, which broke every hook call in the browser. Also load the agents Vite plugin for the bundled skill. * fix(pi-harness): show the user's prompt and dedupe transcript messages Resync the transcript from the durable snapshot at operation boundaries so the prompt entry appears, and ignore a message event whose id is already in the transcript. Shorten the empty-state copy. * fix(pi-harness): answer a snapshot command with a snapshot message The client resyncs its transcript from the durable snapshot at operation boundaries, so the reply must arrive as a snapshot rather than a generic result. * feat(pi-harness): tools sidebar from the lane snapshot * fix(pi-harness): resubscribe when a stream is announced after a wake The hook ignored stream_start, so a stream the server reopened after hibernation with the socket still open was never tailed and the live reply stopped updating. Track the last delivered sequence per stream and subscribe from it when a stream is announced.
M
Matt committed
4e2548595036e0d9c419aa4610445818b7fc2262
Parent: dd09d44
Committed by GitHub <noreply@github.com>
on 9/8/2026, 4:37:42 PM