An open API service indexing awesome lists of open source software.

https://github.com/lhr0909/pi-mobile

Mobile client and SDK host MVP for Pi coding-agent sessions
https://github.com/lhr0909/pi-mobile

pi-coding-agent react-native slop

Last synced: 18 days ago
JSON representation

Mobile client and SDK host MVP for Pi coding-agent sessions

Awesome Lists containing this project

README

          

# Pi Mobile

Pi Mobile is a pnpm-workspace MVP for controlling `pi` coding-agent sessions from an iPhone-first native app. The repository now contains both sides of the prototype:

- `apps/host` — a Node/TypeScript mobile host that embeds Pi through the SDK (`AgentSessionRuntime` + `AgentSession`).
- `apps/mobile` — an Expo / React Native app that connects to a configured host, opens a session, streams timeline updates, and sends prompt/steer/follow-up/abort commands.
- `packages/shared` — shared protocol types, validation helpers, timeline projection, and mobile client reducer logic used by both apps.

The implementation follows the research decision: **SDK-hosted TypeScript daemon first, `pi --mode rpc` only as a future fallback**.

## Current MVP capabilities

### Host daemon

- Embeds `@earendil-works/pi-coding-agent` with `AgentSessionRuntime`.
- Creates, opens, continues, and lists Pi sessions through `SessionManager`.
- Binds a mobile-compatible extension UI context for `select`, `confirm`, `input`, `editor`, `notify`, `setStatus`, `setWidget`, `setTitle`, and `set_editor_text`.
- Projects raw Pi SDK events into mobile timeline updates.
- Exposes HTTP APIs for host status, session list/open/snapshot/events, prompt, steer, follow-up, abort, and extension UI responses.
- Broadcasts live host/session events over WebSocket at `/ws`.
- Supports optional bearer-token auth through `PI_MOBILE_HOST_TOKEN` and explicit dev CORS through `PI_MOBILE_HOST_CORS_ORIGIN`.

### Mobile app

- Expo / React Native + TypeScript.
- iPhone-first MVP with separate connection and session screens.
- Connects to a configured host URL and optional token.
- Uses Expo Router / React Navigation native-stack pages for Home, Host, Workspace, Path Explorer, Stored Sessions, and active Session navigation instead of one stacked setup form.
- Presents a recents-first mobile home for resuming sessions, connecting hosts, and jumping into the relevant navigation page only when needed.
- Persists recent hosts and recent host/path/session combinations on the client for quick reconnects, with client-side remove-from-recents actions for keeping the mobile home concise without deleting anything on the host machine.
- Seeds directory browsing from `~/Documents` by default, includes quick Home (`~`) and Documents shortcuts, and supports `~/...` workspace paths.
- Lists stored Pi sessions for the selected workspace path so desktop sessions can be continued from mobile.
- Opens a new Pi session for the selected workspace path, opens a listed stored session, or reopens a previous persisted session when a saved session file is available, then switches into the session view.
- Shows live status, expanded tool, thinking, user, and assistant timeline items with a dark monospaced style based on Pi's session export/TUI palette.
- Keeps streamed thinking/text blocks and tool calls in event order, with exact tool-call arguments and tool input/output shown fully expanded for now.
- Renders bash/read tool cards with TUI-like call lines, command output, read path/range headers, and syntax-highlighted read file contents.
- Renders user, thinking, and assistant text as Markdown with Pi TUI-inspired colors.
- Records accepted mobile prompts as user timeline cards so the submitted message appears before assistant output.
- Shows a compact animated TUI-style `Working...` spinner while Pi is streaming/compacting instead of adding `Agent started` / `Agent finished` timeline prompts.
- Includes a collapsible session header for reducing metadata height during active chat.
- Sends prompt, steer, follow-up, and abort commands from a TUI-like composer.

## Repository layout

```text
.
├── apps/
│ ├── host/ # Node/TS SDK host daemon
│ └── mobile/ # Expo React Native app
├── packages/
│ └── shared/ # Shared protocol and reducers
├── package.json # Root scripts
├── pnpm-workspace.yaml
├── tsconfig.base.json
└── vitest.config.ts
```

## Setup

```bash
pnpm install
```

Pi itself must be configured on the host machine before running real sessions:

```bash
npm install -g @earendil-works/pi-coding-agent
pi
```

## Run the SDK host

```bash
pnpm dev:host
```

Defaults:

- Bind: `localhost`
- Port: `4739`
- URL: `http://localhost:4739`

Environment:

```bash
PI_MOBILE_HOST_BIND=0.0.0.0 \
PI_MOBILE_HOST_PORT=4739 \
PI_MOBILE_HOST_TOKEN=dev-secret \
pnpm dev:host
```

If `PI_MOBILE_HOST_TOKEN` is set, HTTP clients must send `Authorization: Bearer ` and WebSocket clients may connect with `/ws?token=`.

For local Expo Web smoke tests, opt into browser CORS explicitly:

```bash
pnpm dev:host:web
```

## Run the mobile app

```bash
pnpm dev:app
```

The app defaults to `http://localhost:4739`, which works for an iOS simulator talking to a host daemon running on the same Mac. For a physical phone, use a LAN/Tailscale-reachable host URL and set `PI_MOBILE_HOST_BIND=0.0.0.0` on the host.

Flow:

1. Open the mobile home. It is now a navigation hub rather than a long setup form.
2. Resume from a saved session row, connect to a recent host row, or remove stale recent host/session references from this client device.
3. Open **Host** to enter the host URL/token and tap **Connect host**. The app reads `/api/host/status`, remembers the host locally, and advances to **Workspace**.
4. Use **Workspace** to paste or confirm an absolute/`~/...` path, open a new session, jump to **Path explorer**, or browse **Stored sessions** for the selected path.
5. Use **Path explorer** with **Documents**, **Home ~**, and **Up** shortcuts or folder rows, then tap **Use this path** to return to **Workspace**.
6. Use **Stored sessions** / **Refresh** to list desktop/mobile Pi sessions for the selected path, then **Continue** a listed session, choose **New here** from recents, or open a fresh session from **Workspace**.
7. Use the active **Session** page bottom composer to send prompts, steer/follow up, or abort the active turn.

When simulator tapping is unreliable, use Expo Web for browser-based mobile viewport smoke tests. Start these in separate terminals:

```bash
pnpm dev:host:web
pnpm web:test
```

Then open `http://localhost:8082`, or drive it with `agent-browser`:

```bash
agent-browser --session pi-mobile-web batch "set device \"iPhone 14\"" "open http://localhost:8082" "snapshot -i"
```

Expo Web is a fast UI/protocol smoke test; keep the iOS simulator or a dev-client/device run for native-specific behavior.

## Host API sketch

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/api/health` | unauthenticated health check |
| `GET` | `/api/host/status` | host metadata |
| `GET` | `/api/sessions?cwd=/path` | list stored sessions for a workspace path (`~/...` paths are expanded by the host) |
| `GET` | `/api/directories?path=~` | list child directories for the mobile path explorer (`~/Documents` is the mobile default) |
| `POST` | `/api/sessions` | open/create a session with `{ cwd, mode?, sessionFile? }` |
| `GET` | `/api/sessions/:id/snapshot` | current session snapshot |
| `GET` | `/api/sessions/:id/events?since=N` | replay host events after `N` |
| `POST` | `/api/sessions/:id/commands/prompt` | send `{ message, streamingBehavior? }` |
| `POST` | `/api/sessions/:id/commands/steer` | send `{ message }` |
| `POST` | `/api/sessions/:id/commands/follow-up` | send `{ message }` |
| `POST` | `/api/sessions/:id/commands/abort` | abort current turn |
| `POST` | `/api/sessions/:id/extension-ui/:requestId` | answer extension UI |
| WS | `/ws` | live `HostEvent` stream |

## Test and validation commands

```bash
pnpm typecheck
pnpm test
pnpm build
pnpm test:coverage
```

The tests cover:

- Shared timeline projection, mobile reducer, and protocol validation.
- SDK host runner behavior with fake SDK sessions.
- Host HTTP/WebSocket API behavior and auth.
- Mobile host-client URL handling and app view-model transitions.

## iOS simulator e2e

The intended e2e loop is:

```bash
agent-device ensure-simulator --platform ios
pnpm dev:host
pnpm --filter @pi-mobile/app start:metro
agent-device open "Expo Go" --platform ios
agent-device snapshot -i --platform ios
```

This depends on local simulator/Expo availability. If Expo Go reports an SDK-version mismatch, uninstall the simulator's old Expo Go and let Expo CLI install the SDK-matched build:

```bash
xcrun simctl uninstall host.exp.Exponent
CI=1 pnpm --filter @pi-mobile/app exec expo start --ios --go --localhost --port 8081
```

If the simulator automation runner cannot interact with the app, capture a screenshot with `agent-device screenshot` and use an Expo dev build (`expo run:ios`) for deeper follow-up testing.

## MVP limitations

- No hosted relay yet; use direct LAN, localhost, Tailscale, or an SSH tunnel.
- No QR pairing yet; recent hosts/sessions are saved locally on the mobile client only. Removing recents clears only the client-side reference records and never deletes host sessions, files, or directories.
- No push notifications yet.
- Mobile extension UI requests are emitted by the host, but the current app does not yet render response dialogs.
- SDK host process owns active turns; a daemon crash ends in-flight work, while persisted Pi sessions can be reopened.
- `pi --mode rpc` subprocess fallback is not implemented in this MVP.