Files
openclaw-android-assistant/docs/index.html
T

827 lines
35 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AnyClaw — OpenClaw + Codex + Claude Code on Android</title>
<meta name="description" content="OpenClaw + Codex CLI + Claude Code (via Claw Code / OpenClaude) in a single Android APK. Three AI agents, one app, your pocket. No root. No Termux." />
<meta property="og:title" content="AnyClaw — Claude Code on Android" />
<meta property="og:description" content="OpenClaw + Codex + Claude Code running natively on Android. Three agents, 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); }
/* ─── RELEASE NOTES ─── */
.release-body h3 {
font-family: var(--body);
font-size: 1rem;
font-weight: 700;
color: var(--amber);
margin: 1.5rem 0 .5rem;
}
.release-body ul {
list-style: none;
padding: 0;
}
.release-body li {
position: relative;
padding-left: 1.2em;
margin-bottom: .4rem;
}
.release-body li::before {
content: '';
position: absolute;
left: 0;
color: var(--amber-soft);
font-weight: 700;
}
.release-body code {
font-family: var(--mono);
font-size: .82em;
color: var(--amber);
background: var(--surface);
padding: .1em .4em;
border-radius: 3px;
}
.release-body a { color: var(--amber); }
.release-body a:hover { 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 + Claude Code &middot; Android</p>
<p class="hero-desc fade-in d4">
Three AI coding agents in <strong>one APK</strong>. OpenClaw gateway, Codex CLI,
and <strong>Claude Code</strong> (via Claw Code / OpenClaude) &mdash; all running
in a full Linux environment on your phone. <strong>No root. No server. No PC.</strong>
</p>
<div class="cta-group fade-in d5">
<a href="https://github.com/friuns2/openclaw-android-assistant/releases/latest/download/app-prod-release.apk" class="btn btn-primary">Download APK</a>
<a href="https://play.google.com/store/apps/details?id=gptos.intelligence.assistant&hl=en" class="btn btn-primary" style="background:var(--crimson)">Google Play</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>Three agents, <em>one pocket</em></h2>
<p class="section-intro">
AnyClaw bundles OpenClaw (personal AI gateway), OpenAI Codex CLI (terminal coding agent),
and <strong>Claude Code</strong> (via Claw Code / OpenClaude &mdash; the leaked Claude Code architecture, 48K+ stars)
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>Claude Code (OpenClaude)</h3>
<p>Full Claw Code agent &mdash; 19 tools, query engine, MCP integration, multi-agent swarms. Claude Code architecture on your phone.</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, Python, 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> <span class="dim"></span> <span class="dim"></span>
<span class="dim"></span> <span class="dim"></span> <span class="grn">claw-code agent</span> → Claude Code (OpenClaude) <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>Claw Code / OpenClaude</h3>
<p>Install Claude Code agent (Claw Code). 19 tools, query engine, MCP, multi-agent swarms.</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 just <a href="https://github.com/friuns2/openclaw-android-assistant/releases/latest/download/app-prod-release.apk">download the latest APK</a> directly.
</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>AI Agent</td><td>Claw Code / OpenClaude (Claude Code)</td><td>latest</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>
<!-- ═══════════════ RELEASE NOTES ═══════════════ -->
<div class="section" id="release">
<p class="section-label">Latest upstream release</p>
<!-- RELEASE_START -->
<h2><em>openclaw 2026.6.1</em></h2>
<p class="release-date" style="font-family:var(--mono);font-size:.8rem;color:var(--text-dim);margin-bottom:2rem">Released Jun 03, 2026</p>
<div class="release-body" style="color:var(--text-dim);font-size:.92rem;line-height:1.75;max-width:800px">
<h3>Changes</h3>
<ul>
<li>Docs: add a dedicated Skill Workshop guide covering governed skill creation, reviewable proposals, CLI, Gateway, agent tool behavior, approval policy, support files, and recovery, and refresh the ClawHub showcase cards. and @vyctorbrzezowski</li>
<li>Skills: let the `skill_workshop` agent tool apply, reject, and quarantine explicit proposals through the guarded review flow</li>
<li>Skills: let proposals carry approved support files under standard skill folders, with scanner, hash, and rollback safeguards</li>
<li>Skills: let pending proposals be revised in place with versioned, dated proposal frontmatter before approval</li>
<li>Skills: add Skill Workshop with pending proposals, CLI/Gateway review actions, rollback metadata, and the `skill_workshop` agent tool</li>
<li>Skill Workshop: add the Control UI navigation, styled dashboard, proposal today view, revision dialog, file preview modal, searchable preview files, reusable session handoff, and localized strings</li>
<li>Plugins: externalize Tokenjuice as the official `@openclaw/tokenjuice` plugin with npm and ClawHub publish metadata</li>
<li>Plugins: externalize the GitHub Copilot agent runtime as the official `@openclaw/copilot` plugin with npm and ClawHub publish metadata</li>
<li>iOS: add hosted push relay defaults, realtime Talk playback, and a guarded WebSocket ping path for more reliable mobile sessions. (#88096, #88105, #88231)</li>
<li>iOS: support native iPad display layouts</li>
<li>Workboard: add orchestration primitives and agent coordination tools for multi-agent planning and run tracking</li>
<li>Workboard: wire task-backed board runs and show task comments in the edit modal</li>
<li>Code mode: add internal namespaces for scoped agent/global sessions and exact namespace tool dispatch</li>
<li>Code mode: add MCP API files and docs for code-mode integrations</li>
<li>Control UI: add a Dreaming-tab agent selector and propagate the selected agent through Dreaming status, diary, and diary actions</li>
<li>Control UI: add calmer chat composer controls, local draft typing state, and first-output latency instrumentation for active chat entry. (#88772, #88998)</li>
<li>Plugins: add a SecretRef provider integration manifest contract and extract shared LLM core packages for provider/plugin reuse. (#82326, #88117)</li>
<li>Plugins: persist the plugin install index in SQLite so installed package lookup survives reloads with less filesystem scanning</li>
<li>Providers: add MiniMax M3 model support</li>
<li>Doctor: add disk space health checks and stabilize post-upgrade JSON probes</li>
<li>Channels: store inbound queues in SQLite and migrate iMessage monitor state to SQLite-backed tracking</li>
<li>Skills: add the core skills index and centralize skills runtime loading, status, filtering, and prompt formatting</li>
</ul>
<h3>Fixes</h3>
<ul>
<li>Release/CI/E2E: fail early when Crabbox sparse-sync full checkouts do not have enough local disk, with guidance for moving the sync root</li>
<li>Build: render independent CLI startup metadata help snapshots concurrently to cut cold build-all metadata time</li>
<li>Plugins: stop timed-out package-boundary prep steps by process group so descendant TypeScript/helper processes do not survive local check cleanup</li>
<li>Control UI: serve static assets asynchronously after safe-open checks so large UI files do not block Gateway request handling</li>
<li>Scripts/UI: forward direct wrapper SIGHUP shutdown to child processes so terminal hangups do not leave wrapped dev commands running</li>
<li>Gateway: return the post-expiration pending-work revision from node drains so reconnecting nodes do not observe stale queue revisions after expired items are pruned</li>
<li>Release/CI/E2E: keep temporary full-sync checkouts alive while slow Crabbox leases boot, so sparse worktree runs do not lose their sync source before file-list generation</li>
<li>Release/CI/E2E: normalize inherited Linux `C.UTF-8` locale settings before raw AWS macOS Crabbox bootstrap commands, avoiding macOS locale warnings during package-manager hydration</li>
<li>Release/CI/E2E: keep gateway watch regression checks from copying large static plugin assets inside the measured idle window</li>
<li>Update: keep core updates nonblocking when a missing external plugin repair download stalls, while still blocking installed active plugin payload smoke failures</li>
<li>Agents/providers: keep streaming tool-call argument parsing record-shaped when providers emit valid non-object JSON such as `null` or arrays</li>
<li>Release/CI/E2E: reset incremental log readers when watched log files rotate without shrinking, so same-size replacements do not hide new readiness or RPC lines</li>
<li>Talk: preserve explicit `null` payloads on controller-created turn and output-audio lifecycle events</li>
<li>Agents/TUI: keep local custom provider runs from loading plugin runtime and auth alias metadata when plugins are disabled</li>
<li>Agents/TUI: restore in-flight TUI run switch-back behavior, keep no-policy native hook fallback available, guard vanished workspaces, and keep lightweight isolated subagents lightweight</li>
<li>Agents/media: keep async image, music, and video generation starts from ending the Codex turn, so mixed requests can continue with summaries or other work while media renders in the background</li>
<li>Agents/Codex: keep public OpenAI API-key profiles from being treated as native Codex app-server auth while preserving persisted Codex OAuth sessions</li>
<li>Agents/Codex: stream Codex app-server final-answer partials to live reply previews, preserve ACP metadata in SQLite, prefer real tool results over synthetic repair output, prevent aborted app-server turn handles from lingering, migrate legacy OpenAI Codex `lastGood` auth state, and preserve workspace/session metadata through ACP runtime refactors. (#88405, #88724, #88730)</li>
<li>Control UI: keep collapsed tool cards labeled with the tool name and action instead of generic output text</li>
<li>Agents/Codex: surface Skill Workshop guidance in Codex app-server prompts when `skill_workshop` is available</li>
<li>Skill Workshop: restore and localize the Control UI board/today view switcher so review workflows keep their intended layout toggle across locales</li>
<li>Agents/auth: write auth profiles atomically, dispatch auth failures by type, add force re-login recovery, preserve workspaces during state-only uninstall, and compact before oversized turns so recovery paths avoid partial state</li>
<li>Skills: skip disabled skill env overrides from stale persisted snapshots so disabled skill `apiKey` SecretRefs cannot abort embedded or channel turns. (#79072, #79173)</li>
<li>Skill Workshop: render the Control UI tab from filtered navigation state and keep filtered fallback routing stable</li>
<li>CLI: avoid live catalog validation during `openclaw agents add`, so adding a secondary agent no longer depends on provider catalog availability. (#76284, #88314)</li>
<li>CLI: keep `plugins list --json` on the snapshot-only path so plugin sweeps avoid loading the full runtime status graph</li>
<li>CLI/desktop: bridge WSL clipboard operations through the shell, recognize manual-update launchd jobs, and keep machine-readable startup output parseable during progress setup. (#88764, #88689)</li>
<li>Plugins: make PixVerse external-plugin ClawHub metadata explicit and keep it out of bundled dist builds</li>
<li>Plugins: clarify plugin loader failure guidance so missing or incompatible plugin packages point operators at the right repair path</li>
<li>Plugins: preserve npm plugin roots after blocked installs, skip plugin-local `openclaw` peer symlinks during rollback snapshots, relink those peers after restore, isolate cached tool runtime siblings, and isolate web-provider factory failures so one bad plugin does not poison sibling runtime paths. (#77237, #88807)</li>
<li>Cron: keep SQLite cron migrations compatible with legacy run-log tables, archived job stores, diagnostic cron names, and legacy one-shot delete-after-run behavior</li>
<li>Cron: keep update delivery validation scoped, harden restart state, and retire MCP runtimes on isolated cron cleanup</li>
<li>Memory: serialize QMD update/embed writes per store, reduce Linux watcher fan-out, retry transient FileProvider-backed reads, preserve phase signals on read errors, harden envelope metadata sanitization, reattach Linux native watchers when directories are recreated, and rewrite generated transcript paths on rollover so memory/search state survives concurrent gateway and CLI activity. (#66339, #85931, #89185, #89188, #85351) @amittell, @RomneyDa, and @NianJiuZst</li>
<li>Memory: keep vector-disabled FTS indexes from resolving embedding providers during sync and search</li>
<li>Providers: bound generated media downloads from OpenAI, Runway, xAI, MiniMax, BytePlus, DashScope-compatible, FAL, OpenRouter, Google, Vydra, and Comfy providers</li>
<li>Providers: resolve Google defaults to `google-generative-ai`, register Vertex static catalog rows, align Foundry reasoning metadata, skip DeepSeek V4 thinking params on Foundry fallback, use MiniMax account OAuth endpoints, preserve Copilot Claude 1M capabilities, suppress disabled Ollama reasoning output, forward Gemini stop sequences, strip Kimi-incompatible Anthropic cache markers, keep OpenAI stop-finished tool calls, and avoid replay ids when the Responses store is disabled. (#88480, #88512, #76612) @BryanTegomoh, and @vliuyt</li>
<li>Providers: cap GitHub Copilot OAuth request timeouts before creating abort signals</li>
<li>Cron: retry recurring jobs after transient model rate limits before waiting for the next scheduled slot</li>
</ul>
</div>
<!-- RELEASE_END -->
<p style="margin-top:2rem">
<a href="https://github.com/openclaw/openclaw/releases" class="btn btn-ghost" style="display:inline-flex">All Releases</a>
</p>
</div>
<div class="divider"></div>
<!-- ═══════════════ FOOTER ═══════════════ -->
<footer>
<div class="tagline">Three agents. One APK. Your pocket.</div>
<div class="sub">They leaked Claude Code. We put it on a phone.</div>
<div class="links">
<a href="https://github.com/friuns2/openclaw-android-assistant">GitHub</a>
<a href="https://github.com/friuns2/openclaw-android-assistant/releases/latest/download/app-prod-release.apk">Download</a>
<a href="https://play.google.com/store/apps/details?id=gptos.intelligence.assistant&hl=en">Google Play</a>
<a href="https://openclaw.ai">OpenClaw</a>
<a href="https://claw-code.codes">Claw Code</a>
<a href="https://github.com/openai/codex">Codex CLI</a>
</div>
</footer>
</body>
</html>