# Pi Mobile Remote control for [Pi](https://pi.dev/docs/latest) coding agents from your phone. Phone connects to a hub running on your computer over the local network. The hub embeds the Pi SDK in-process and exposes session management plus streaming chat over Socket.IO. ## Quick start (developers) ### 1. Start the hub on your computer No clone required: ```bash npx pi-mobile-hub@latest ``` Or from this repo during development: ```bash npm install npm run dev:api ``` The hub listens on `0.0.0.0:8787` by default and prints: - LAN URLs to connect from your phone - A **pairing code** - A **QR code** encoding a `pimobile://connect` deep link Custom port: ```bash npx pi-mobile-hub --port 9000 ``` Disable pairing auth on trusted networks only: ```bash npx pi-mobile-hub --no-auth ``` ### 2. Install the mobile app **Option A — Prebuilt app (recommended)** Install the Pi Mobile app from TestFlight (iOS) or the APK link (Android). See [Releasing](#releasing) if you are building it yourself. **Option B — Expo Go (development)** ```bash npm run dev:mobile ``` Scan the QR code with Expo Go. ### 3. Pair and connect 1. Open Pi Mobile on your phone 2. Scan the QR code printed by `pi-mobile-hub` in your terminal - Or enter your computer's LAN IP, port (`8787`), and pairing code manually 3. Tap **Connect** 4. Create a session by choosing a folder under `~/` 5. Send prompts and watch streamed assistant text + tool activity 6. Resume persisted Pi sessions from the list Saved computers remember the pairing code for one-tap reconnect. ## Prerequisites - Node.js 20+ - Pi installed and authenticated on the host machine (`pi` CLI with `/login` or provider API keys) - Phone and computer on the same LAN - For prebuilt mobile installs: iOS or Android device ## Project structure ``` apps/api/ Express + Socket.IO hub (`pi-mobile-hub` npm package) apps/mobile/ Expo Router mobile app ``` ## Development ```bash npm install npm run dev:api # hub on :8787 npm run dev:mobile # Expo dev server npm run build:api # compile hub for publishing ``` ## API surface ### HTTP - `GET /health` — liveness check (`authRequired` indicates whether pairing is enabled) - `GET /fs/list?path=~` — folder-only explorer rooted at home (requires pairing token) - `POST /fs/mkdir` — create folder under home (requires pairing token) Authenticated HTTP requests must include header `x-pi-mobile-token: `. ### Socket.IO (client → server) | Event | Payload | |-------|---------| | `sessions:list` | — | | `runtime:create` | `{ cwd, name?, model?, thinkingLevel? }` | | `runtime:open` | `{ sessionFile }` | | `runtime:attach` | `{ runtimeId }` | | `runtime:model:set` | `{ runtimeId, model }` | | `runtime:thinking:set` | `{ runtimeId, level }` | | `runtime:thinking:cycle` | `{ runtimeId }` | | `models:list` | `{ runtimeId?, cwd? }` | | `chat:prompt` | `{ runtimeId, message }` | | `chat:abort` | `{ runtimeId }` | Socket connections must pass `auth: { token: "" }` when pairing is enabled. ### Socket.IO (server → client) | Event | Payload | |-------|---------| | `sessions:list:result` | `{ persisted, live }` | | `runtime:created` / `runtime:opened` | `{ runtimeId, sessionId, cwd, sessionName?, sessionFile? }` | | `chat:event` | `{ runtimeId, event }` | | `chat:history` | `{ runtimeId, messages }` | | `error` | `{ message }` | ## Pairing & security Each hub start generates a fresh pairing token unless `--no-auth` is passed. The token is required for: - Socket.IO connections (`handshake.auth.token`) - Folder HTTP endpoints (`x-pi-mobile-token` header) The mobile app stores the token per saved computer. Scanning the terminal QR code auto-fills host, port, and token via `pimobile://connect?host=...&port=...&token=...`. This is LAN pairing, not full remote access over the internet. Do not expose the hub to untrusted networks without additional hardening. ## Releasing ### Hub (`pi-mobile-hub` on npm) From `apps/api`: ```bash npm run build npm version patch npm publish ``` Users can then run `npx pi-mobile-hub@latest`. ### Mobile app (EAS) One-time setup: ```bash cd apps/mobile npm install -g eas-cli eas login eas init ``` Update `app.json` → `extra.eas.projectId` with the ID from `eas init`. Build for internal testing: ```bash # iOS (TestFlight via internal distribution) eas build --platform ios --profile preview # Android (shareable APK) eas build --platform android --profile preview ``` Submit to stores: ```bash eas build --platform ios --profile production eas submit --platform ios eas build --platform android --profile production eas submit --platform android ``` Optional OTA updates for JS-only changes: ```bash eas update --branch production --message "Describe the change" ``` ## Notes - The folder browser only exposes directories under your home folder. - Pi credentials are read from the host environment / Pi auth storage — the mobile app does not handle login. - Multiple live runtimes can run concurrently; switch between them from the Sessions screen. ## Success checklist - [ ] Start hub via `npx pi-mobile-hub` - [ ] Pair via QR code or manual pairing code - [ ] Connect from phone via LAN IP - [ ] Browse folders starting at `~/` - [ ] Create a new Pi session - [ ] Send a prompt and see streamed text + tool rows - [ ] Resume a persisted session - [ ] Open a second live runtime without stopping the first