even-terminal-pi
v0.1.0
Published
A pi (@earendil-works/pi-coding-agent) provider for @evenrealities/even-terminal — drive pi on Even Realities G2 glasses.
Downloads
176
Maintainers
Readme
even-terminal-pi
A pi provider for @evenrealities/even-terminal — run the pi coding agent on Even Realities G2 smart glasses + R1 ring.
even-terminal is Even's official CLI that runs an AI agent on your laptop,
normalizes its streaming output, and lets the Even phone app render it onto the
G2's 576×288 canvas while the R1 ring sends input back. It ships claude and
codex providers. This package adds pi.
Sibling project to PADD-G2 (a glasses-native pi cockpit built on
even_hub_sdk). PADD-G2 renders the canvas ourselves over our own relay; even-terminal-pi instead reuses Even's app as the renderer. Different tradeoffs, kept separate on purpose.
How it works
Even app ◄─SSE/REST─► http server ─► createPiProvider(emit)
│
pi --mode rpc ◄─JSONL─► PiRpcClient ─► PiSession ─► emit(EvenMessage)
(subprocess) (transport) (translate)PiRpcClient(src/rpc/) spawnspi --mode rpcand speaks pi's JSONL protocol with strict LF-only framing (pi warns againstnode:readline, which also splits on U+2028/U+2029 — valid inside JSON strings).PiSession(src/even/session.ts) translates pi's RPC event stream (message_update,tool_execution_*,extension_ui_request, …) into even-terminal's normalized events (text_delta,tool_start/tool_end,permission_request,user_question,result, …).createPiProvider(emit, config)(src/even/provider.ts) returns the 9-method provider object even-terminal's routes consume.
Approvals & ask_user
In RPC mode pi surfaces ctx.ui.confirm / ctx.ui.select (and pi-ask-user) as
extension_ui_request dialogs. We map:
| pi RPC dialog | even-terminal event | response |
|----------------------|-------------------------|---------------------------------------|
| confirm | permission_request | respondPermission → confirmed |
| select (ask_user) | user_question | respondQuestion → value |
| input / editor | user_question | respondQuestion → value |
| notify | notification | fire-and-forget |
In RPC mode pi's
custom()returnsundefined, so the pi-ask-user custom_ui overlay degrades to a plainselect— sidestepping the custom_ui handling PADD-G2 had to special-case.
Run it (standalone server)
This package ships its own server that speaks the same /api + SSE contract
the Even app expects — so the app connects to us directly, no fork needed. (The
official @evenrealities/even-terminal npm package is dist-only with a private,
hardcoded provider registry, so runtime injection isn't possible anyway.)
npm install
npm run build
node dist/cli.js --cwd /path/to/project --model anthropic/claude-...It prints a QR + URL like http://<lan-ip>:3456?token=<token>&defaultProvider=claude.
Open the Even app, scan it, and pi runs on your glasses. (We present as
claude on the wire because the app filters its session list to a provider it
recognizes — pi still runs underneath.)
even-terminal-pi [options]
-p, --port <n> Port (default 3456)
-t, --token <str> Fixed auth token (default: random per run)
-d, --cwd <path> Working dir for pi (default: cwd)
-a, --all-cwds List/resume sessions from ALL project dirs
-T, --tailscale Advertise the Tailscale address (cellular-reachable)
--model <id> pi model pattern
--pi-bin <path> Path to pi binary (default "pi")Remote access over Tailscale
LAN-only by default. To steer pi from anywhere (over cellular), put this Mac and
your phone on the same Tailscale tailnet and pass
--tailscale:
node dist/cli.js --cwd /path/to/project --all-cwds --tailscaleThe QR then points at the node's tailnet address (http://<magicdns>:3456?...),
which the glasses reach over WireGuard — no public exposure, the auth token is
still required. If Tailscale isn't running it warns and falls back to LAN.
Setup once (no-sudo, userspace daemon): the GUI app needs sudo to install, so this repo runs the CLI daemon in userspace mode instead:
brew install tailscale # CLI + daemon, no sudo
tailscaled --tun=userspace-networking \
--socket=$HOME/.tailscale/tailscaled.sock \
--statedir=$HOME/.tailscale/state & # start the daemon
tailscale --socket=$HOME/.tailscale/tailscaled.sock up # log in (browser)Install Tailscale on the phone too and sign both into the same tailnet. The
--tailscale flag auto-detects ~/.tailscale/tailscaled.sock (or honor an
explicit TAILSCALE_SOCKET), so no env var is needed at launch.
To keep the daemon alive across reboots, load it as a launchd agent
(~/Library/LaunchAgents/com.example.tailscaled.plist with RunAtLoad +
KeepAlive).
Reusing the provider elsewhere
The provider is also exported standalone, matching even-terminal's
createXProvider(emit) convention, in case you do wire it into a fork:
import { createPiProvider } from "even-terminal-pi";
const piProvider = createPiProvider(emit, { model: "anthropic/claude-..." });Develop
npm install
npm run build
npm test # framing + translation unit tests
# live end-to-end probe against your installed pi:
node dist/dev/rpc-probe.js "what is 2+2? just the number."Requires pi on your PATH (pi --version).
Status
Working & validated live (pi 0.79.1):
text streaming, tool calls, session lifecycle round-trip
approval / question (
ask_user) dialog mapping (unit-tested)resume:
listSessions/getHistory/getInforead pi's session.jsonlfiles under~/.pi/agent/sessions/(model, names, transcript)token & cost in
running_stats(per turn) andresult(from pi'sturn_endusage)standalone server: full
/api+ SSE contract (auth,/eventsreplay + heartbeat, prompt/permission/question/interrupt/status/messages/sessions/ info/history) wired to the pi provider — the Even app connects directlyCLI:
node dist/cli.jsprints a scannable QR + URL
26 unit/integration tests (framing, dialog mapping, session-file parsing, HTTP
routes + SSE round-trip). Validated live: an Even-app-shaped flow (POST
/api/prompt → SSE /api/events) streams a full pi turn.
TODO: richer tool summaries; account info in getInfo; model switch from
the app.
License
MIT
