SIGN IN SIGN UP

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