diff --git a/README.md b/README.md
index 57eb398..ed2c08e 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
# OpenCode Mobile
**The open-source Android client for the [opencode](https://github.com/sst/opencode) AI coding agent.**
-AI-assisted coding from your phone — Android, via F-Droid or a direct APK.
+AI-assisted coding from your phone — Android, via Google Play, F-Droid, or a direct APK.
[](LICENSE)
[](https://dzianisv.github.io/opencode-mobile/fdroid/repo)
[](https://github.com/dzianisv/opencode-mobile/releases/latest)
-[](#)
+[](https://play.google.com/store/apps/details?id=cc.agentlabs.opencode)
> **Not affiliated with opencode.** OpenCode Mobile is an independent, community-built client and is
> not made by, endorsed by, or affiliated with the opencode / Anomaly team. It talks to an opencode
@@ -14,20 +14,26 @@ AI-assisted coding from your phone — Android, via F-Droid or a direct APK.
---
+**New: tap "Try a Demo" in the app to see the agent fix a real bug — reasoning, a grep, a diff, a permission prompt — in about 30 seconds, no server needed.**
+
+---
+
## Install (Android)
-There are **two working ways** to install OpenCode Mobile today, both for Android:
+There are **three working ways** to install OpenCode Mobile today, all for Android:
-1. **F-Droid (recommended)** — add our self-hosted repo to any F-Droid client, then install/update from there:
+1. **Google Play** — **https://play.google.com/store/apps/details?id=cc.agentlabs.opencode**
+
+2. **F-Droid (self-hosted repo)** — add our self-hosted repo to any F-Droid client, then install/update from there:
```
https://dzianisv.github.io/opencode-mobile/fdroid/repo
```
In the F-Droid app: **Settings → Repositories → + (add)** and paste the URL above. Current version: **v0.4.3**.
-2. **Direct signed APK** — download the latest release and install it manually:
+3. **Direct signed APK** — download the latest release and install it manually:
**https://github.com/dzianisv/opencode-mobile/releases/latest**
-> iOS is not available (see [Roadmap](#roadmap)). Google Play is in internal testing only (no public listing yet). IzzyOnDroid submission is pending.
+> iOS is not available (see [Roadmap](#roadmap)). IzzyOnDroid submission is pending.
---
@@ -45,6 +51,7 @@ OpenCode Mobile is a React Native / Expo app that brings the power of the [openc
## Features
+- **Offline demo mode** — tap "Try a Demo" to see a full bug-fix walkthrough (reasoning → grep → diff → permission prompt) with zero setup, right from the empty state
- **Multi-connection** — manage multiple opencode servers (local network, Cloudflare Tunnel, ngrok, or Tailscale)
- **Biometric unlock** — Face ID, Touch ID, or Android fingerprint protects the app and individual message sends
- **Streaming chat** — token-by-token streaming responses directly from your opencode server
@@ -61,18 +68,20 @@ Package: `cc.agentlabs.opencode` · Android only · current version v0.4.3
| Channel | Status | How |
|---|---|---|
+| **Google Play** | **Live** | [play.google.com/store/apps/details?id=cc.agentlabs.opencode](https://play.google.com/store/apps/details?id=cc.agentlabs.opencode) |
| **F-Droid (self-hosted repo)** | **Live** | Add [`https://dzianisv.github.io/opencode-mobile/fdroid/repo`](https://dzianisv.github.io/opencode-mobile/fdroid/repo) in your F-Droid client |
| **Direct APK** | **Live** | [github.com/dzianisv/opencode-mobile/releases/latest](https://github.com/dzianisv/opencode-mobile/releases/latest) |
-| Google Play | Internal testing / coming soon | No public listing yet |
| IzzyOnDroid | Submission pending | Not live yet |
| Apple App Store / iOS | Not available | See [Roadmap](#roadmap) |
-> The two live, supported install channels are the **F-Droid self-hosted repo** and the **direct signed APK**, both Android. Google Play is internal-testing only, IzzyOnDroid is pending, and there is no iOS build.
+> The three live, supported install channels are **Google Play**, the **F-Droid self-hosted repo**, and the **direct signed APK**, all Android. IzzyOnDroid is pending, and there is no iOS build.
---
## Quick Start
+**Don't have a server yet?** Install the app and tap **Try a Demo** on the Sessions screen first — no setup required. It plays back a scripted bug-fix session through the app's real chat, diff, and permission-approval UI, offline, in about 30 seconds.
+
**Step 1 — Start opencode on your machine**
```bash
@@ -83,7 +92,7 @@ npm install -g opencode
OPENCODE_SERVER_PASSWORD=yourpassword opencode serve --hostname 0.0.0.0 --port 4096
```
-**Step 2 — Install OpenCode Mobile** via the [F-Droid self-hosted repo or direct APK](#install-android) (or build from source — see [CONTRIBUTING.md](CONTRIBUTING.md)).
+**Step 2 — Install OpenCode Mobile** via [Google Play, F-Droid, or a direct APK](#install-android) (or build from source — see [CONTRIBUTING.md](CONTRIBUTING.md)).
**Step 3 — Add a connection in the app**
@@ -132,6 +141,8 @@ OpenCode Mobile is a thin client. It speaks the opencode HTTP + SSE API: listing
| Feature | Status |
|---|---|
+| Offline demo mode | Stable |
+| First-run onboarding clarity | Stable |
| Multi-connection management | Stable |
| Session list + creation | Stable |
| Streaming chat | Stable |
diff --git a/app/demo.tsx b/app/demo.tsx
index df14092..8ab03c0 100644
--- a/app/demo.tsx
+++ b/app/demo.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useMemo, useState } from "react"
+import { useCallback, useEffect, useMemo, useState } from "react"
import { View, Text, ScrollView, TouchableOpacity, StyleSheet, useColorScheme, Linking } from "react-native"
import { Stack, useRouter } from "expo-router"
import { Ionicons } from "@expo/vector-icons"
@@ -6,6 +6,13 @@ import { useTranslation } from "react-i18next"
import { MessageBubble, PermissionPrompt } from "../src/components/chat"
import { buildDemoScript, buildDemoCompletionMessage, buildDemoDenialMessage } from "../src/lib/demo-script"
import { SETUP_GUIDE_URL } from "../src/lib/links"
+import { track, AnalyticsEvent } from "../src/lib/analytics"
+import {
+ demoStepAdvancedProps,
+ demoCompletedOutcome,
+ demoExitedToConnectProps,
+ type DemoPermissionReply,
+} from "../src/lib/demo-analytics"
// Fully offline, scripted walkthrough for installers with no self-hosted
// opencode server. ISOLATION: every message/part below is hardcoded local
@@ -22,12 +29,26 @@ export default function DemoScreen() {
// Built once per mount from pure, hardcoded data (src/lib/demo-script.ts).
const script = useMemo(() => buildDemoScript(), [])
- const [reply, setReply] = useState<"once" | "always" | "reject" | null>(null)
+ const [reply, setReply] = useStateOpenCode Mobile — Privacy Policy
@@ -232,6 +232,27 @@
An agent response finishes
—
+
+
+
+ demo_startedYou open the offline "Try a Demo" screen (no server, no network)
+ —
+
+
+
+ demo_step_advancedYou reply to the demo's scripted permission prompt
+
+ step_index, step_name, reply ("once", "always", or
+ "reject")
+
+
+ demo_completedThe scripted demo reaches its end
+
+ outcome ("completed" or "denied")
+
@@ -239,7 +260,8 @@
What analytics events never contain: your server URL, hostname, IP address,
or port; prompts, messages, or AI responses; code or file contents; tokens or credentials;
raw error messages. Connection failures are reduced to a fixed list of coarse categories
- before being sent.
+ before being sent. The demo screen is fully offline and hardcoded — these events describe
+ interaction with the scripted walkthrough, never real session content.
+ demo_exited_to_connectYou tap "Connect your own server" on the demo's CTA
+
+ reached_completion (true/false)
Analytics data is sent to PostHog's EU region (eu.i.posthog.com)
@@ -462,7 +484,7 @@