@clevercloud/pi-remote-control
v0.1.5
Published
pi.dev extension: bridge a live pi session to the remote-control relay
Readme
pi-remote-control extension
A pi.dev extension that bridges your live pi session to the
remote-control relay, so a remote device (the iOS app, or cli-test) can watch
the session and send prompts.
Install
pi install npm:@clevercloud/pi-remote-controlNo clone, no build, no dependencies — pi loads the extension directly (the built
dist/ is committed; the extension is dependency-free: node builtins + the
global WebSocket/fetch). Just start pi:
pi # relay defaults to wss://pidev-remote.cleverapps.ioThe session is named automatically from the project directory pi runs in (the
git repo root), plus a distinguishing word: the git worktree name when pi
runs in a linked worktree, an animal otherwise (e.g. dev-foo-4fa9c1-otter).
Your devices list your sessions and connect with a tap — nothing to configure
or share, and no hand-named sessions.
From source (dev): npm install && npm run build, then
pi --extension ./dist/index.js. Re-commit dist/ after editing src/.
Sign in — inside pi
No separate binary, no token copy-pasting:
/remote-login # opens your browser; tokens stored + auto-refreshed
/remote-status # relay state · session · auth · mode
/remote-logout
/remote-beta-invite [email protected] # join the iOS TestFlight betaCredentials live at ~/.config/pidev/credentials.json. Auth resolution order:
PIDEV_OIDC_TOKEN (env override, for CI) → stored /remote-login credentials
(auto-refreshed) → none (dev mode, loopback relay only). An off-loopback
(wss://) relay requires one of the first two.
Keycloak: the public client needs the exact loopback redirect URIs
http://127.0.0.1:8765/callback,:8766,:8767registered (ahttp://127.0.0.1/*wildcard does NOT cover the port)./remote-loginuses the first free of these ports.
Once pinned to a pi version and published, it can instead be installed with
pi install git:github.com/clevercloud/pi-dev-remote-controll (extension
sub-path TBD). The Rust pidev (../server/cli-test) shares the same credential
file and remains only as an optional device tester.
What it does (skeleton)
| Direction | Mapping |
| ---------------- | ------------------------------------------------------------------- |
| device → pi | {type:"prompt"} → pi.sendUserMessage(text, { streamingBehavior })|
| pi → device | message_update (text deltas) → {type:"delta"} |
| pi → device | tool_execution_start/end → {type:"tool"} |
| pi → device | agent_end → {type:"turn_end"} |
Transport test (no real pi / no model key)
test/harness.mjs runs the real extension against a mocked pi — only the
LLM brain is faked. With a local Pulsar + relay running, it lets a prompt from
cli-test round-trip device → pi → device through the broker:
npm run build
PIDEV_RELAY_URL=ws://localhost:8080 bun test/harness.mjs &
# then, from server/: cargo run -p cli-test -- sessions # grab the printed id
# cargo run -p cli-test -- send --session <id> --prompt "hi"
# → prints "received: hi"This was validated end-to-end against apachepulsar/pulsar:4.0.4 standalone:
both pidev-demo-to-pi and pidev-demo-from-pi topics are created and carry
the traffic (subscriptions pi and device-0).
Tool approvals (on("tool_call") → block, paired with {type:"approval"}) are
implemented with UUID request ids and default-deny on timeout/disconnect.
History replay (ctx.sessionManager.getEntries()) is still pending.
Transport policy: off-loopback the extension requires wss:// and
PIDEV_OIDC_TOKEN, failing closed otherwise (see
../docs/SECURITY.md).
The ExtensionAPI type here is modelled loosely from pi's docs/extensions.md;
tighten it once we pin a pi release and depend on its published types.
