|
| 1 | +# Pocket Pi |
| 2 | + |
| 3 | +A [Pi coding agent](https://pi.dev/) shipped as an Android APK. No Termux install, no shell setup — install the APK, paste an LLM key, chat. |
| 4 | + |
| 5 | +> POC, fast-tracked. We bundle Termux's Linux runtime inside an Android app so the team can try a single-tap Pi install on a phone. Whether this approach is worth productizing (vs. building a proper native Android client) is the open question — that's what the POC is for. |
| 6 | +
|
| 7 | +## Install (team testers) |
| 8 | + |
| 9 | +1. Grab the latest APK from the [Releases page](https://github.com/CelestialCreator/pocket-pi/releases/latest). |
| 10 | +2. Sideload — tap the APK on the phone (allow install from unknown sources for your browser/file manager), or `adb install pocket-pi-vX.Y.Z.apk`. |
| 11 | +3. Open the app. First launch runs the bootstrap (3–5 min on Wi-Fi: extracts Termux, installs Node + npm packages, registers Pi extensions). |
| 12 | +4. When you see "Send a message to your Pi agent" — tap the ⚙ at the top right. |
| 13 | +5. Paste at least one provider API key (NVIDIA NIM is free; OpenRouter / OpenAI / Anthropic / Groq also wired up), then tap **Save keys** → **Restart Pi**. |
| 14 | +6. Tap **Re-run setup** once if extensions are missing (it's idempotent and safe). |
| 15 | +7. Chat away. |
| 16 | + |
| 17 | +If anything wedges, tap **⚙ → Re-run setup**. As a last resort, force-stop the app from Android Settings and reopen — the install state on disk is preserved. |
| 18 | + |
| 19 | +## What's inside |
| 20 | + |
| 21 | +| Layer | Component | |
| 22 | +|---|---| |
| 23 | +| App shell | Android (Kotlin + Jetpack Compose) — `android/` | |
| 24 | +| Linux runtime | Termux bootstrap (Node 25, Python, git, ripgrep, openssl) — `bootstrap/` | |
| 25 | +| Chat UI | [`@e9n/pi-mobile`](https://www.npmjs.com/package/@e9n/pi-mobile) PWA served by [`@e9n/pi-webserver`](https://www.npmjs.com/package/@e9n/pi-webserver), rendered in a WebView | |
| 26 | +| Agent engine | [`@earendil-works/pi-coding-agent`](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) | |
| 27 | +| Pi extensions | `pi-web-access`, `pi-subagents`, `oh-pi`, `@aliou/pi-guardrails`, `pi-mcp-adapter`, `pk-pi-hermes-evolve` | |
| 28 | +| Native config | Compose `ModalBottomSheet` with sections for API keys, AGENTS.md, models.json, Restart Pi, Re-run setup | |
| 29 | +| Providers wired | NVIDIA NIM (free), OpenRouter, OpenAI, Anthropic, Groq — keys go to `~/.config/<provider>/api-key`; the model registry lives in `~/.pi/agent/models.json` | |
| 30 | + |
| 31 | +## Repo layout |
| 32 | + |
| 33 | +``` |
| 34 | +. |
| 35 | +├── android/ Gradle Android project for the APK |
| 36 | +├── bootstrap/ Termux bootstrap zip generator + postinstall |
| 37 | +│ ├── build-bootstrap.sh Layer our payload on upstream Termux's aarch64 zip |
| 38 | +│ ├── postinstall.sh First-run install: apt, npm, pip, pi install loop |
| 39 | +│ ├── npm-packages.txt Pi engine + extensions + peer deps |
| 40 | +│ ├── packages.txt Termux apt packages |
| 41 | +│ ├── pip-packages.txt Python deps (dspy etc, best-effort) |
| 42 | +│ └── patches/ One-shot post-update patches (e.g. hermes-evolve) |
| 43 | +├── config/ Baked into the bootstrap at build time |
| 44 | +│ ├── AGENTS.md Always-on Pi context |
| 45 | +│ ├── models.json Provider/model registry (NVIDIA pre-filled) |
| 46 | +│ └── claude-bridge.json Wrapper config (legacy; not active) |
| 47 | +├── extensions/ Our own Pi extensions (TypeScript) |
| 48 | +│ ├── pi-termux-tools/ Phone surface tools (TTS, notify, share, camera) |
| 49 | +│ └── pi-skill-learner/ Hermes-style learning loop |
| 50 | +├── python/skill_learner_dspy DSPy reflection backend |
| 51 | +├── skills/ Pi Skills bundled into the bootstrap |
| 52 | +└── scripts/ Misc dev helpers |
| 53 | +``` |
| 54 | + |
| 55 | +## Build from source |
| 56 | + |
| 57 | +```bash |
| 58 | +# 1. Bootstrap zip (produces bootstrap/dist/bootstrap-aarch64.zip, ~30M) |
| 59 | +cd bootstrap && ./build-bootstrap.sh aarch64 |
| 60 | + |
| 61 | +# 2. (Optional) the custom Pi extensions |
| 62 | +cd ../extensions/pi-termux-tools && pnpm install && pnpm build |
| 63 | +cd ../pi-skill-learner && pnpm install && pnpm build |
| 64 | + |
| 65 | +# 3. APK |
| 66 | +cd ../../android && ./gradlew :app:assembleDebug |
| 67 | +# Output: android/app/build/outputs/apk/debug/app-debug.apk (~67 MB) |
| 68 | +``` |
| 69 | + |
| 70 | +The current build uses `applicationId = com.termux` so the upstream Termux bootstrap binaries (which bake in the path `/data/data/com.termux/files/usr`) work without recompiling. To ship under a real app id, run `bootstrap/rebuild-with-prefix.sh` (Docker, 4–12 h on Apple Silicon) to produce a bootstrap pinned to a custom prefix, then flip `applicationId` in `android/app/build.gradle.kts`. |
| 71 | + |
| 72 | +## What works / what doesn't (v0.1) |
| 73 | + |
| 74 | +| | Status | |
| 75 | +|---|---| |
| 76 | +| Single-APK install on aarch64 phones | ✓ | |
| 77 | +| 8 Pi extensions registered, 17 tools online | ✓ | |
| 78 | +| NVIDIA NIM + OpenRouter end-to-end (chat, tool use, cost tracking) | ✓ | |
| 79 | +| Native ⚙ Config sheet — keys, AGENTS.md, models.json, restart, re-run setup | ✓ | |
| 80 | +| Recovery UI when pi-webserver doesn't bind within 15s | ✓ | |
| 81 | +| Slash commands `/session`, `/clear`, `/model`, `/threads` intercepted client-side | not yet — currently sent to LLM as text | |
| 82 | +| Chat history persistence across tab switches | not yet — JSONL on disk, no resume | |
| 83 | +| `applicationId` ≠ `com.termux` | not yet — requires custom bootstrap rebuild | |
| 84 | +| Cosmetic phantom-icon row on some Android WebView builds | accepted — known compositor artifact, no functional impact | |
| 85 | + |
| 86 | +## License |
| 87 | + |
| 88 | +MIT. Third-party runtime components keep their own licenses (Termux GPL, Pi MIT) — see `LICENSE` for the list. |
| 89 | + |
| 90 | +## Status |
| 91 | + |
| 92 | +v0.1 — POC. The Termux-fork-inside-an-APK approach works. Whether to invest in productizing it (custom prefix bootstrap, real applicationId, signed release builds, Play Store, etc.) or rewrite this as a proper native Android client that talks to Pi over the network is the question this POC is meant to inform. |
0 commit comments