Skip to content

Commit 33280d6

Browse files
friunscursoragent
andcommitted
Add full-access mode, background service, CI workflow, and README
- Set Codex to approval=never, sandbox=danger-full-access via config.toml - Add foreground service to keep server alive in background - Request battery optimization exemption on startup - Always re-extract server bundle from APK assets on launch - Add GitHub Action to build APK and upload to releases - Rewrite README with project documentation Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 059d619 commit 33280d6

6 files changed

Lines changed: 406 additions & 33 deletions

File tree

.github/workflows/build-apk.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Build APK
2+
3+
on:
4+
push:
5+
branches: [android]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
19+
- name: Set up Node.js
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: "21"
23+
cache: "npm"
24+
25+
- name: Install npm dependencies
26+
run: npm ci --ignore-scripts || npm install
27+
28+
- name: Build Vue frontend
29+
run: npm run build:frontend
30+
31+
- name: Build CLI server
32+
run: npm run build:cli
33+
34+
- name: Bundle server into APK assets
35+
run: bash android/scripts/build-server-bundle.sh
36+
37+
- name: Download Termux bootstrap
38+
run: bash android/scripts/download-bootstrap.sh
39+
40+
- name: Set up JDK 17
41+
uses: actions/setup-java@v4
42+
with:
43+
java-version: "17"
44+
distribution: "temurin"
45+
46+
- name: Setup Gradle
47+
uses: gradle/actions/setup-gradle@v4
48+
49+
- name: Build debug APK
50+
working-directory: android
51+
run: ./gradlew assembleDebug
52+
53+
- name: Upload APK artifact
54+
uses: actions/upload-artifact@v4
55+
with:
56+
name: codex-mobile-debug
57+
path: android/app/build/outputs/apk/debug/app-debug.apk
58+
59+
- name: Create Release
60+
if: github.ref == 'refs/heads/android'
61+
uses: softprops/action-gh-release@v2
62+
with:
63+
tag_name: v${{ github.run_number }}
64+
name: "Codex Mobile v${{ github.run_number }}"
65+
body: |
66+
🔥 **Codex Mobile** — OpenAI Codex CLI on Android
67+
68+
📱 Install the APK on any ARM64 Android 7.0+ device.
69+
No root required.
70+
71+
Built from commit ${{ github.sha }}
72+
files: android/app/build/outputs/apk/debug/app-debug.apk
73+
draft: false
74+
prerelease: false

README.md

Lines changed: 201 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,225 @@
1-
# `npx codex-web-local`
1+
<div align="center">
22

3-
A lightweight web interface for [Codex](https://github.com/openai/codex) that replicates the desktop UI and runs on top of the Codex `app-server`. It exposes Codex through a web application, allowing you to access your local Codex instance remotely from any browser.
3+
# 🔥 Codex Mobile
44

5-
## Prerequisites
5+
### 📱 OpenAI Codex CLI — In Your Pocket — On Android 📱
66

7-
- [Codex CLI](https://github.com/openai/codex) installed and available in your `PATH`
7+
[![Android](https://img.shields.io/badge/Android-24+-3DDC84?logo=android&logoColor=white&style=for-the-badge)](https://developer.android.com)
8+
[![Kotlin](https://img.shields.io/badge/Kotlin-2.1-7F52FF?logo=kotlin&logoColor=white&style=for-the-badge)](https://kotlinlang.org)
9+
[![Node.js](https://img.shields.io/badge/Node.js-21-339933?logo=nodedotjs&logoColor=white&style=for-the-badge)](https://nodejs.org)
10+
[![Vue](https://img.shields.io/badge/Vue-3-4FC08D?logo=vuedotjs&logoColor=white&style=for-the-badge)](https://vuejs.org)
11+
[![Status](https://img.shields.io/badge/Status-🔥%20WORKS-brightgreen?style=for-the-badge)](#)
12+
[![License](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](LICENSE)
813

9-
## Installation
14+
<br />
15+
16+
> **They built an AI coding agent for the terminal.**
17+
> **We put an entire Linux environment inside an Android app and ran it there.**
18+
> **One APK. No root. Full Codex.**
19+
20+
<br />
21+
22+
```
23+
╔═══════════════════════════════════════════════╗
24+
║ ██████╗ ██████╗ ██████╗ ███████╗██╗ ██╗ ║
25+
║ ██╔════╝██╔═══██╗██╔══██╗██╔════╝╚██╗██╔╝ ║
26+
║ ██║ ██║ ██║██║ ██║█████╗ ╚███╔╝ ║
27+
║ ██║ ██║ ██║██║ ██║██╔══╝ ██╔██╗ ║
28+
║ ╚██████╗╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ║
29+
║ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ║
30+
║ M O B I L E E D I T I O N ║
31+
╚═══════════════════════════════════════════════╝
32+
```
33+
34+
</div>
35+
36+
---
37+
38+
## 🤯 What Is This?
39+
40+
OpenAI shipped [Codex CLI](https://github.com/openai/codex) — a terminal-based AI coding agent that can read, write, and execute code. **But it only runs on Linux and macOS.**
41+
42+
We said: *what if it ran on your phone?*
43+
44+
This app bundles a **full Termux Linux environment**, **Node.js 21**, the **Codex CLI**, and a **Vue.js web interface** — all inside a single Android APK. No root required. No terminal knowledge needed. Open the app, authenticate with OpenAI, and start coding from your pocket.
45+
46+
**Yes, that's a real Linux userland. Yes, that's the real Codex binary. Yes, it runs on your phone.** 🧠
47+
48+
---
49+
50+
## 📱 How It Works
51+
52+
<div align="center">
53+
<table>
54+
<tr>
55+
<td align="center" width="50%">
56+
<br /><b>🏗️ Architecture</b><br />
57+
<sub>Android WebView → Vue.js frontend → Express bridge → <code>codex app-server</code> (native ARM64 binary) → OpenAI API</sub>
58+
</td>
59+
<td align="center" width="50%">
60+
<br /><b>⚡ First Launch</b><br />
61+
<sub>Extracts Termux bootstrap → installs Node.js via apt → deploys Codex CLI → downloads native binary → authenticates via OAuth → ready in ~2 minutes</sub>
62+
</td>
63+
</tr>
64+
</table>
65+
</div>
66+
67+
---
68+
69+
## 🌍 What Can You Do With This?
70+
71+
| | Use Case | Description |
72+
|---|---|---|
73+
| 💻 | **Code on the go** | Write, debug, and refactor code from your phone or tablet |
74+
| 🤖 | **AI pair programming** | Full Codex agent with tool use, file I/O, and shell access |
75+
| 📂 | **Manage projects** | Multiple threads, model selection, reasoning effort control |
76+
| 🔓 | **Full access mode** | `danger-full-access` sandbox — no approval prompts, maximum speed |
77+
| 🌐 | **OAuth login** | Browser-based OpenAI authentication, no manual API keys needed |
78+
| 📡 | **Background running** | Foreground service keeps the server alive when screen is off |
79+
| 🔌 | **Offline-capable setup** | Bootstrap and binaries cached after first install |
80+
| 🧩 | **Real Linux env** | Termux-compatible userland with apt, Node.js, npm, and more |
81+
82+
---
83+
84+
## ⚡ Quick Start
1085

1186
```bash
12-
# Run directly with npx (no install required)
13-
npx codex-web-local
87+
# 🔧 Clone and build
88+
git clone https://github.com/friuns2/codex-web-local.git
89+
cd codex-web-local
90+
91+
# 📦 Download Termux bootstrap
92+
cd android && bash scripts/download-bootstrap.sh && cd ..
1493

15-
# Or install globally
16-
npm install -g codex-web-local
94+
# 🏗️ Build Vue frontend + server bundle
95+
bash android/scripts/build-server-bundle.sh
96+
97+
# 🚀 Build APK
98+
cd android && ./gradlew assembleDebug
99+
# APK at: android/app/build/outputs/apk/debug/app-debug.apk ✈️
17100
```
18101

19-
## Usage
102+
Or grab the latest APK from [**Releases**](https://github.com/friuns2/codex-web-local/releases) 📥
103+
104+
---
20105

106+
## 📁 Project Structure
107+
108+
```
109+
codex-web-local/
110+
├── 🌐 src/ # Vue.js frontend + Express server
111+
│ ├── components/ # UI components (composer, sidebar, threads)
112+
│ ├── api/ # RPC client → codex app-server bridge
113+
│ ├── server/ # Express HTTP server + SSE events
114+
│ └── cli/ # CLI entry point
115+
├── 📱 android/ # Android app (Kotlin)
116+
│ ├── app/src/main/java/ # Kotlin source
117+
│ │ ├── MainActivity.kt # WebView + setup orchestration
118+
│ │ ├── CodexServerManager.kt # Node.js/Codex process management
119+
│ │ ├── BootstrapInstaller.kt # Termux environment extraction
120+
│ │ └── CodexForegroundService.kt # Background service
121+
│ ├── app/src/main/assets/ # proxy.js, bootstrap zip, server bundle
122+
│ └── scripts/ # Build helper scripts
123+
├── 📖 documentation/ # App-server JSON-RPC schemas
124+
└── 🔧 vite.config.ts # Frontend build config
21125
```
22-
Usage: codex-web-local [options]
23126

24-
Web interface for Codex app-server
127+
---
128+
129+
## 🏗️ Architecture
25130

26-
Options:
27-
-p, --port <port> port to listen on (default: "3000")
28-
--password <pass> set a specific password
29-
--no-password disable password protection
30-
-h, --help display help for command
131+
```
132+
┌──────────────────────────────────────────────────────┐
133+
│ Android App │
134+
│ │
135+
│ ┌─────────┐ ┌──────────────┐ ┌──────────────┐ │
136+
│ │ WebView │───▶│ Vue.js SPA │───▶│ Express │ │
137+
│ │ │ │ (frontend) │ │ HTTP Server │ │
138+
│ └─────────┘ └──────────────┘ └──────┬───────┘ │
139+
│ │ JSON-RPC │
140+
│ ┌─────────────────────────────────────────▼───────┐ │
141+
│ │ codex app-server (native ARM64) │ │
142+
│ │ approval: never | sandbox: full-access │ │
143+
│ └────────────────────┬────────────────────────────┘ │
144+
│ │ HTTPS via CONNECT proxy │
145+
│ ┌────────────────────▼────────────────────────────┐ │
146+
│ │ Node.js HTTP CONNECT Proxy │ │
147+
│ │ (DNS + TLS for musl binary) │ │
148+
│ └────────────────────┬────────────────────────────┘ │
149+
│ │ │
150+
│ ┌────────────────────▼────────────────────────────┐ │
151+
│ │ Termux Bootstrap (Linux userland) │ │
152+
│ │ /data/data/com.codex.mobile/files/usr/ │ │
153+
│ └─────────────────────────────────────────────────┘ │
154+
└──────────────────────────┬───────────────────────────┘
155+
156+
┌──────▼──────┐
157+
│ OpenAI API │
158+
└─────────────┘
31159
```
32160

33-
## Examples
161+
---
34162

35-
```bash
36-
# Start with auto-generated password on default port 3000
37-
codex-web-local
163+
## 🔧 Key Technical Challenges Solved
38164

39-
# Start on a custom port
40-
codex-web-local --port 8080
165+
> **Running a statically-linked musl Rust binary on Android? Yeah, that was fun.**
41166
42-
# Start with a specific password
43-
codex-web-local --password my-secret
167+
1. 🔌 **DNS/TLS for native binary** — The Codex Rust binary is compiled for `musl` Linux and can't use Android's DNS resolver. Solution: a Node.js HTTP CONNECT proxy that routes all traffic through Android's native network stack.
44168

45-
# Start without password protection (use only on trusted networks)
46-
codex-web-local --no-password
47-
```
169+
2. 🔒 **W^X execution policy** — Android 10+ blocks executing binaries from app data. Solution: `targetSdk = 28` (same approach as Termux F-Droid).
170+
171+
3. 📦 **Platform binary mismatch** — npm refuses to install `@openai/codex-linux-arm64` on Android (`os: android ≠ linux`). Solution: download the tarball directly via Node.js and extract it manually.
172+
173+
4. 🔑 **OAuth in embedded environment**`codex login` spawns a local callback server. The app parses the OAuth URL from stdout and opens the system browser.
174+
175+
5. 🗂️ **Termux path remapping** — All hardcoded `/data/data/com.termux` paths in apt/dpkg configs are rewritten to the app's private directory at install time.
176+
177+
---
178+
179+
## 🎯 Requirements
180+
181+
- 📱 Android 7.0+ (API 24+) — ARM64 device
182+
- 🌐 Internet connection (for OpenAI API + first-time setup)
183+
- 🔑 OpenAI account with Codex access
184+
- 💾 ~200MB storage for bootstrap + Node.js + Codex
185+
186+
---
187+
188+
## 🐛 Troubleshooting
189+
190+
| Problem | Solution |
191+
|---|---|
192+
| 🔴 "Failed to install Node.js" | Check internet connection; apt needs to download ~40MB |
193+
| 🔴 OpenSSL config error | The app handles this — if you see it in logs, it's from a stale process |
194+
| 🔴 Message disappears after sending | Force-stop and relaunch — server bundle may need re-extraction |
195+
| 🔴 "Health check failed" | Verify OpenAI account has Codex access; check proxy is running |
196+
| 🔴 App killed in background | Grant battery optimization exemption (prompted at startup) |
197+
198+
---
199+
200+
## 🤝 Contributing
201+
202+
PRs welcome! Key areas:
203+
204+
- 🎨 UI improvements for mobile form factor
205+
- 📱 Multi-architecture support (x86_64 for emulators)
206+
- 🔧 Startup time optimization
207+
- 📋 File browser / workspace management
208+
209+
---
210+
211+
## ⭐ Star This Repo
212+
213+
If you believe **AI coding agents should run everywhere** — not just on laptops with terminal access — smash that star button. ⭐
214+
215+
Your stars fuel the mass delusion that shipping a Linux distro inside an Android app is totally normal and fine. 🚀
48216

49-
When started with password protection (default), the server prints the password to the console. Open the URL in your browser, enter the password, and you're in.
217+
---
50218

51-
## Contributing
219+
<div align="center">
52220

53-
Issues and pull requests are welcome! If you have ideas, suggestions, or found a bug, please open an issue on the [GitHub repository](https://github.com/pavel-voronin/codex-web-local/issues).
221+
**Built by shoving an entire Linux userland into a WebView** 🔬
54222

55-
## License
223+
*"Can it run Codex?" — yes, even your phone can now* 😏
56224

57-
[MIT](./LICENSE)
225+
</div>

android/app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
33

44
<uses-permission android:name="android.permission.INTERNET" />
5+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
6+
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
7+
<uses-permission android:name="android.permission.WAKE_LOCK" />
58

69
<application
710
android:allowBackup="true"
@@ -22,6 +25,10 @@
2225
</intent-filter>
2326
</activity>
2427

28+
<service
29+
android:name=".CodexForegroundService"
30+
android:exported="false" />
31+
2532
</application>
2633

2734
</manifest>

0 commit comments

Comments
 (0)