Files
openclaw-android-assistant/docs/index.html
2026-02-27 06:56:54 +07:00

695 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AnyClaw — AI Agents on Android</title>
<meta name="description" content="OpenClaw + Codex CLI in a single Android APK. Two AI agents, one app, your pocket. No root. No Termux." />
<meta property="og:title" content="AnyClaw" />
<meta property="og:description" content="OpenClaw + Codex running natively on Android. One APK, zero dependencies." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://friuns2.github.io/openclaw-android-assistant/" />
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🦞</text></svg>" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Instrument+Serif:ital@0;1&family=Syne:wght@400;600;700;800&display=swap" rel="stylesheet" />
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #08080c;
--surface: #0f0f15;
--surface-raised: #151520;
--border: #1c1c2a;
--border-glow: #2a1a10;
--text: #e8e4df;
--text-dim: #8a8680;
--amber: #e8941a;
--amber-soft: #c4782a;
--crimson: #c93535;
--crimson-deep: #8a1f1f;
--cream: #f0e6d6;
--mono: 'DM Mono', 'SF Mono', monospace;
--display: 'Instrument Serif', Georgia, serif;
--body: 'Syne', sans-serif;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--body);
background: var(--bg);
color: var(--text);
line-height: 1.65;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
a { color: var(--amber); text-decoration: none; transition: color .2s; }
a:hover { color: var(--cream); }
.grain {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9999;
opacity: .035;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* ─── HERO ─── */
.hero {
position: relative;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 4rem 1.5rem;
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
top: -30%;
left: 50%;
transform: translateX(-50%);
width: 140%;
height: 80%;
background: radial-gradient(ellipse at center, rgba(232, 148, 26, .06) 0%, rgba(201, 53, 53, .03) 40%, transparent 70%);
pointer-events: none;
}
.hero::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent 0%, var(--border-glow) 30%, var(--amber-soft) 50%, var(--border-glow) 70%, transparent 100%);
}
.hero-claw {
font-size: clamp(4rem, 12vw, 8rem);
line-height: 1;
margin-bottom: 1rem;
animation: float 6s ease-in-out infinite;
filter: drop-shadow(0 0 40px rgba(232, 148, 26, .15));
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-12px); }
}
.hero h1 {
font-family: var(--display);
font-size: clamp(3.5rem, 10vw, 7rem);
font-weight: 400;
letter-spacing: -.03em;
line-height: .9;
color: var(--cream);
margin-bottom: .75rem;
}
.hero h1 em {
font-style: italic;
color: var(--amber);
}
.hero-sub {
font-family: var(--mono);
font-size: clamp(.75rem, 1.4vw, .9rem);
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: .2em;
margin-bottom: 2.5rem;
}
.hero-desc {
max-width: 560px;
font-size: clamp(1rem, 2vw, 1.15rem);
color: var(--text-dim);
margin-bottom: 3rem;
line-height: 1.75;
}
.hero-desc strong { color: var(--text); font-weight: 600; }
.cta-group { display: flex; gap: 1rem; flex-wrap: wrap; justify-content: center; }
.btn {
display: inline-flex;
align-items: center;
gap: .6rem;
padding: .85rem 2rem;
border-radius: 4px;
font-family: var(--body);
font-weight: 600;
font-size: .95rem;
letter-spacing: .02em;
transition: all .25s ease;
cursor: pointer;
border: none;
}
.btn-primary {
background: var(--amber);
color: #080808;
}
.btn-primary:hover {
background: var(--cream);
color: #080808;
transform: translateY(-2px);
box-shadow: 0 8px 30px rgba(232, 148, 26, .25);
}
.btn-ghost {
background: transparent;
color: var(--text);
border: 1px solid var(--border);
}
.btn-ghost:hover {
border-color: var(--amber-soft);
color: var(--amber);
transform: translateY(-2px);
}
/* ─── SECTION ─── */
.section {
max-width: 1000px;
margin: 0 auto;
padding: 6rem 1.5rem;
}
.section-label {
font-family: var(--mono);
font-size: .75rem;
text-transform: uppercase;
letter-spacing: .25em;
color: var(--amber-soft);
margin-bottom: .75rem;
}
.section h2 {
font-family: var(--display);
font-size: clamp(2rem, 5vw, 3.2rem);
font-weight: 400;
color: var(--cream);
margin-bottom: 1.5rem;
line-height: 1.1;
}
.section h2 em { font-style: italic; color: var(--amber); }
.section-intro {
max-width: 640px;
color: var(--text-dim);
font-size: 1.05rem;
line-height: 1.75;
margin-bottom: 3rem;
}
/* ─── FEATURE GRID ─── */
.feat-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1px;
background: var(--border);
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
}
.feat {
background: var(--surface);
padding: 2rem;
transition: background .3s;
}
.feat:hover {
background: var(--surface-raised);
}
.feat-icon {
font-size: 1.6rem;
margin-bottom: .75rem;
display: block;
}
.feat h3 {
font-family: var(--body);
font-size: .95rem;
font-weight: 700;
margin-bottom: .5rem;
color: var(--cream);
}
.feat p {
font-size: .85rem;
color: var(--text-dim);
line-height: 1.6;
}
/* ─── ARCH ─── */
.arch-wrap {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
}
.arch-header {
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: .5rem;
}
.arch-dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
.arch-dot:nth-child(1) { background: var(--crimson); }
.arch-dot:nth-child(2) { background: var(--amber); }
.arch-dot:nth-child(3) { background: #22c55e; }
.arch-body {
padding: 1.5rem;
overflow-x: auto;
}
.arch-body pre {
font-family: var(--mono);
font-size: .78rem;
line-height: 1.7;
color: var(--amber-soft);
white-space: pre;
margin: 0;
}
.arch-body .hl { color: var(--amber); }
.arch-body .dim { color: var(--text-dim); }
.arch-body .grn { color: #22c55e; }
/* ─── STEPS ─── */
.steps {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1px;
background: var(--border);
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
counter-reset: step;
}
.step {
background: var(--surface);
padding: 2rem;
counter-increment: step;
position: relative;
transition: background .3s;
}
.step:hover { background: var(--surface-raised); }
.step::before {
content: counter(step, decimal-leading-zero);
font-family: var(--mono);
font-size: .7rem;
color: var(--amber-soft);
letter-spacing: .1em;
display: block;
margin-bottom: .75rem;
}
.step h3 {
font-size: .95rem;
font-weight: 700;
margin-bottom: .4rem;
color: var(--cream);
}
.step p {
font-size: .85rem;
color: var(--text-dim);
line-height: 1.6;
}
/* ─── QUICK START CODE ─── */
.code-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
}
.code-tab {
padding: .75rem 1.5rem;
border-bottom: 1px solid var(--border);
font-family: var(--mono);
font-size: .75rem;
color: var(--text-dim);
letter-spacing: .05em;
}
.code-body {
padding: 1.5rem;
overflow-x: auto;
}
.code-body code {
font-family: var(--mono);
font-size: .82rem;
line-height: 1.8;
color: #22c55e;
white-space: pre;
}
.code-body .cmt { color: var(--text-dim); }
/* ─── STACK TABLE ─── */
.stack-table {
width: 100%;
border-collapse: collapse;
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
}
.stack-table th,
.stack-table td {
padding: .85rem 1.25rem;
text-align: left;
font-size: .88rem;
border-bottom: 1px solid var(--border);
}
.stack-table th {
background: var(--surface);
font-family: var(--mono);
font-size: .7rem;
text-transform: uppercase;
letter-spacing: .15em;
color: var(--text-dim);
font-weight: 500;
}
.stack-table td { background: var(--surface); }
.stack-table tr:hover td { background: var(--surface-raised); }
.stack-table td:first-child { font-weight: 600; color: var(--cream); }
/* ─── DIVIDER ─── */
.divider {
max-width: 1000px;
margin: 0 auto;
height: 1px;
background: linear-gradient(90deg, transparent 0%, var(--border) 20%, var(--border-glow) 50%, var(--border) 80%, transparent 100%);
}
/* ─── FOOTER ─── */
footer {
text-align: center;
padding: 5rem 1.5rem 4rem;
color: var(--text-dim);
font-size: .9rem;
}
footer .tagline {
font-family: var(--display);
font-size: 1.5rem;
font-style: italic;
color: var(--amber-soft);
margin-bottom: .75rem;
}
footer .sub { font-family: var(--mono); font-size: .75rem; letter-spacing: .1em; }
footer .links {
margin-top: 2rem;
display: flex;
gap: 2rem;
justify-content: center;
flex-wrap: wrap;
}
footer .links a {
font-family: var(--mono);
font-size: .8rem;
color: var(--text-dim);
letter-spacing: .05em;
transition: color .2s;
}
footer .links a:hover { color: var(--amber); }
/* ─── ANIMATIONS ─── */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in {
opacity: 0;
animation: fadeUp .7s ease forwards;
}
.d1 { animation-delay: .1s; }
.d2 { animation-delay: .2s; }
.d3 { animation-delay: .35s; }
.d4 { animation-delay: .5s; }
.d5 { animation-delay: .65s; }
/* ─── RESPONSIVE ─── */
@media (max-width: 768px) {
.feat-grid { grid-template-columns: 1fr; }
.steps { grid-template-columns: 1fr; }
.hero { min-height: auto; padding: 6rem 1rem 4rem; }
.section { padding: 4rem 1rem; }
}
@media (max-width: 480px) {
.cta-group { flex-direction: column; align-items: stretch; }
.btn { justify-content: center; }
}
</style>
</head>
<body>
<div class="grain"></div>
<!-- ═══════════════ HERO ═══════════════ -->
<div class="hero">
<div class="hero-claw fade-in d1">🦞</div>
<h1 class="fade-in d2">Any<em>Claw</em></h1>
<p class="hero-sub fade-in d3">OpenClaw + Codex &middot; Android</p>
<p class="hero-desc fade-in d4">
Two AI coding agents in <strong>one APK</strong>. Full Linux environment,
Node.js runtime, native Rust binary &mdash; all on your phone.
<strong>No root. No Termux.</strong>
</p>
<div class="cta-group fade-in d5">
<a href="https://play.google.com/store/apps/details?id=gptos.intelligence.assistant" class="btn btn-primary">Get it on Google Play</a>
<a href="https://github.com/friuns2/openclaw-android-assistant/releases/latest/download/anyclaw.apk" class="btn btn-ghost">Download APK</a>
<a href="https://github.com/friuns2/openclaw-android-assistant" class="btn btn-ghost">GitHub</a>
<a href="https://github.com/friuns2/openclaw-android-assistant#quick-start" class="btn btn-ghost">Quick Start</a>
</div>
</div>
<!-- ═══════════════ SCREENSHOTS ═══════════════ -->
<div class="section" style="text-align:center">
<p class="section-label">In action</p>
<h2>See it <em>running</em></h2>
<div style="display:flex;gap:2rem;justify-content:center;flex-wrap:wrap;margin-top:2rem">
<img src="https://raw.githubusercontent.com/friuns2/openclaw-android-assistant/main/screenshots/screenshot.png" alt="OpenClaw Dashboard" style="width:260px;border-radius:12px;border:1px solid var(--border);box-shadow:0 8px 40px rgba(0,0,0,.5)" />
<img src="https://raw.githubusercontent.com/friuns2/openclaw-android-assistant/main/screenshots/screenshot2.png" alt="Codex Coding Agent" style="width:260px;border-radius:12px;border:1px solid var(--border);box-shadow:0 8px 40px rgba(0,0,0,.5)" />
</div>
</div>
<div class="divider"></div>
<!-- ═══════════════ FEATURES ═══════════════ -->
<div class="section">
<p class="section-label">Capabilities</p>
<h2>Two agents, <em>one pocket</em></h2>
<p class="section-intro">
AnyClaw bundles OpenClaw (personal AI gateway with agents, skills &amp; Canvas)
and OpenAI Codex CLI (terminal coding agent) inside a self-contained Android app.
</p>
<div class="feat-grid">
<div class="feat">
<span class="feat-icon">🦞</span>
<h3>OpenClaw Dashboard</h3>
<p>Full Control UI &mdash; chat, agents, sessions, skills, Canvas. Runs locally on your device.</p>
</div>
<div class="feat">
<span class="feat-icon">💬</span>
<h3>Codex Chat</h3>
<p>Conversational coding agent with streaming, reasoning visibility, and multi-thread sessions.</p>
</div>
<div class="feat">
<span class="feat-icon">🦀</span>
<h3>Native Binary</h3>
<p>73MB Rust binary (aarch64-musl) running natively. Full <code style="color:var(--amber);font-family:var(--mono);font-size:.8rem">codex app-server</code> with JSON-RPC.</p>
</div>
<div class="feat">
<span class="feat-icon">🐧</span>
<h3>Embedded Linux</h3>
<p>Complete Termux-derived userland &mdash; sh, apt, Node.js 24, npm, SSL certs. Extracted from APK.</p>
</div>
<div class="feat">
<span class="feat-icon">🔓</span>
<h3>Full Auto-Approval</h3>
<p>No permission popups. <code style="color:var(--amber);font-family:var(--mono);font-size:.8rem">danger-full-access</code> sandbox mode by default.</p>
</div>
<div class="feat">
<span class="feat-icon">🔋</span>
<h3>Background Execution</h3>
<p>Foreground service + battery exemption. Keeps running when you switch apps.</p>
</div>
</div>
</div>
<div class="divider"></div>
<!-- ═══════════════ ARCHITECTURE ═══════════════ -->
<div class="section">
<p class="section-label">Under the hood</p>
<h2>Four layers, <em>one device</em></h2>
<div class="arch-wrap">
<div class="arch-header">
<span class="arch-dot"></span>
<span class="arch-dot"></span>
<span class="arch-dot"></span>
</div>
<div class="arch-body">
<pre>
<span class="dim">┌────────────────────────────────────────────────────────┐</span>
<span class="dim"></span> <span class="hl">Android APK</span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="grn">WebView (Vue.js)</span> ←→ <span class="hl">CodexServerManager</span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim">┌──────────────────────────────────────────────────┐</span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span> <span class="grn">codex-web-local</span> → :18923 (HTTP + Vue UI) <span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span> └─ codex app-server (Rust/musl, JSON-RPC) <span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span> <span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span> <span class="hl">openclaw gateway</span> → :18789 (WebSocket) <span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span> <span class="hl">openclaw ctrl UI</span> → :19001 (Static files) <span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span> <span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span> proxy.js → :18924 (CONNECT, DNS/TLS) <span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim">└──────────────────────────────────────────────────┘</span> <span class="dim"></span>
<span class="dim">└────────────────────────────────────────────────────────┘</span>
</pre>
</div>
</div>
</div>
<div class="divider"></div>
<!-- ═══════════════ STARTUP ═══════════════ -->
<div class="section">
<p class="section-label">Boot sequence</p>
<h2>From cold start to <em>ready</em></h2>
<div class="steps">
<div class="step">
<h3>Battery &amp; Service</h3>
<p>Request Doze exemption. Start foreground service with persistent notification.</p>
</div>
<div class="step">
<h3>Bootstrap Extraction</h3>
<p>Extract Termux bootstrap zip into app&rsquo;s private storage. Fix hardcoded paths.</p>
</div>
<div class="step">
<h3>Node.js &amp; Toolchain</h3>
<p>Install Node.js 24, Python, clang/cmake/make/lld for native module builds.</p>
</div>
<div class="step">
<h3>OpenClaw + koffi</h3>
<p>Install OpenClaw globally. Build koffi FFI module from source with Termux toolchain.</p>
</div>
<div class="step">
<h3>Codex CLI + Binary</h3>
<p>Extract server bundle. Download native Rust binary from npm registry.</p>
</div>
<div class="step">
<h3>Proxy + Auth + Launch</h3>
<p>Start CONNECT proxy, OAuth login, gateway, Control UI server, then load WebView.</p>
</div>
</div>
</div>
<div class="divider"></div>
<!-- ═══════════════ QUICK START ═══════════════ -->
<div class="section">
<p class="section-label">Get started</p>
<h2>Build from <em>source</em></h2>
<div class="code-card">
<div class="code-tab">terminal</div>
<div class="code-body">
<code><span class="cmt"># clone</span>
git clone https://github.com/friuns2/openclaw-android-assistant.git
cd openclaw-android-assistant
<span class="cmt"># build frontend</span>
npm install && npm run build
<span class="cmt"># prepare android</span>
cd android && bash scripts/download-bootstrap.sh
<span class="cmt"># build + install + launch</span>
bash scripts/build-server-bundle.sh && ./gradlew assembleDebug \
&& adb install -r app/build/outputs/apk/debug/app-debug.apk \
&& adb shell am start -n com.codex.mobile/.MainActivity</code>
</div>
</div>
<p style="margin-top:1.5rem;color:var(--text-dim);font-size:.9rem">
Or install from <a href="https://play.google.com/store/apps/details?id=gptos.intelligence.assistant">Google Play</a>, or <a href="https://github.com/friuns2/openclaw-android-assistant/releases/latest/download/anyclaw.apk">download the latest APK</a>.
</p>
</div>
<div class="divider"></div>
<!-- ═══════════════ TECH STACK ═══════════════ -->
<div class="section">
<p class="section-label">Stack</p>
<h2>What&rsquo;s <em>inside</em></h2>
<table class="stack-table">
<thead><tr><th>Layer</th><th>Technology</th><th>Version</th></tr></thead>
<tbody>
<tr><td>AI Gateway</td><td>OpenClaw</td><td>2026.2.21</td></tr>
<tr><td>AI Agent</td><td>OpenAI Codex CLI</td><td>0.104.0</td></tr>
<tr><td>Model</td><td>gpt-5.3-codex (via Codex OAuth)</td><td>&mdash;</td></tr>
<tr><td>Runtime</td><td>Node.js (Termux)</td><td>24.13.0</td></tr>
<tr><td>Native</td><td>Rust (musl, aarch64)</td><td>&mdash;</td></tr>
<tr><td>Frontend</td><td>Vue.js 3 + Vite + Tailwind</td><td>3.x</td></tr>
<tr><td>Android</td><td>Kotlin + WebView</td><td>2.1.0</td></tr>
<tr><td>Linux</td><td>Termux bootstrap (aarch64)</td><td>&mdash;</td></tr>
</tbody>
</table>
</div>
<!-- ═══════════════ FOOTER ═══════════════ -->
<footer>
<div class="tagline">Two agents. One APK. Your pocket.</div>
<div class="sub">Built by shoving an entire Linux distro into an APK and refusing to give up.</div>
<div class="links">
<a href="https://github.com/friuns2/openclaw-android-assistant">GitHub</a>
<a href="https://play.google.com/store/apps/details?id=gptos.intelligence.assistant">Google Play</a>
<a href="https://github.com/friuns2/openclaw-android-assistant/releases/latest/download/anyclaw.apk">Download APK</a>
<a href="https://openclaw.ai">OpenClaw</a>
<a href="https://github.com/openai/codex">Codex CLI</a>
</div>
</footer>
</body>
</html>