fix(ui): correct mirrored chat empty-state + clipped IP placeholder; add readiness-check skill; privacy page nav/meta

- app/session/[id].tsx: chat empty-state rendered mirrored on Android (inverted FlatList) — now an untransformed overlay
- app/connection/add.tsx: shortened clipped host placeholder
- .agents/skills/readiness-check: production-readiness gate (Play+F-Droid published, app+site health)
- docs/privacy: back-nav + canonical/theme-color/description meta
Verified: tsc clean, CUA smoke green (run 26814702062)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
engineer
2026-06-03 06:16:22 -07:00
parent c46f273ecd
commit 6563f5ef53
5 changed files with 415 additions and 13 deletions

View File

@@ -0,0 +1,74 @@
---
name: readiness-check
description: Verify OpenCode Mobile is PRODUCTION READY end-to-end. Triggers like "check production readiness", "are we ready to ship", "readiness check", "is opencode-mobile live", "is the app published". Runs a script that confirms both Google Play and F-Droid (self-hosted + mainline) are PUBLISHED and the app/site are healthy.
category: release
version: 1.0.0
---
# OpenCode Mobile — Readiness Check
Single command that answers one question: **is OpenCode Mobile production ready?**
"Production ready" has a precise definition of done:
- The app is **PUBLISHED on Google Play** (`cc.agentlabs.opencode`).
- The app is **PUBLISHED on F-Droid mainline** (`f-droid.org/packages/cc.agentlabs.opencode`).
- The **self-hosted F-Droid repo** serves the latest APK.
- The **app builds and tests green** (typecheck + node:test suite).
- The **web presence** (landing, guide, privacy, sitemap, robots, OG image, QR codes) is all live.
If, and only if, every REQUIRED gate passes, the verdict is `PRODUCTION READY`.
## How to run
From the repo root:
```bash
bash .agents/skills/readiness-check/check.sh
```
Fast mode — skip the slow npm app-health gates, only check live published-status URLs:
```bash
bash .agents/skills/readiness-check/check.sh --quick
```
The script needs only `curl` and `git`. It opportunistically uses `python3` or `jq`
to parse the F-Droid index, and `gh` for the optional repo-discoverability gate.
Missing optional tools degrade gracefully (gate reports `WARN` or `UNKNOWN`, never crashes).
## What it checks
Gates are grouped. REQUIRED gates decide the verdict; nice-to-have gates only WARN.
- **A. App health** (REQUIRED, skipped with `--quick`)
- `npm run typecheck` exits clean.
- `npm test` passes.
- **B. F-Droid self-hosted repo LIVE** (REQUIRED)
- `https://dzianisv.github.io/opencode-mobile/fdroid/repo/index-v1.json` parses and contains `cc.agentlabs.opencode`; prints served versionName.
- `https://github.com/dzianisv/opencode-mobile/releases/latest` returns 200/3xx.
- **C. F-Droid MAINLINE published** (REQUIRED, headline)
- `https://f-droid.org/packages/cc.agentlabs.opencode/` returns 200. A 404 means not yet merged on f-droid.org → this gate FAILS. Do not confuse with the self-hosted gate (B).
- **D. Google Play PUBLISHED** (REQUIRED, headline)
- `https://play.google.com/store/apps/details?id=cc.agentlabs.opencode` returns 200 with a real store page. While in-review/draft it 404s → gate FAILS.
- **E. Web presence** (REQUIRED)
- landing `/`, `/guide/`, `/privacy/`, `sitemap.xml`, `robots.txt`, `og.png`, `fdroid-qr.png`, `apk-qr.png` under `https://dzianisv.github.io/opencode-mobile/` all return 200.
- **F. Repo discoverability** (nice-to-have, WARN only)
- `gh repo view dzianisv/opencode-mobile --json repositoryTopics,homepageUrl` shows topics + homepage. Skipped gracefully if `gh` is missing/unauthenticated.
## Interpreting results
Each gate prints one line: `[PASS] / [FAIL] / [WARN] / [UNKNOWN] <gate> — <detail>`.
The summary at the bottom is the answer:
- **`PRODUCTION READY ✅`** — every REQUIRED gate passed. Both stores are live, app and site healthy. Script exits `0`.
- **`NOT READY ❌`** — at least one REQUIRED gate failed; the failing gates are listed. Script exits `1`.
The two headline gates are **D (Google Play)** and **C (F-Droid mainline)** because
"published on both stores" is the definition of done. Until Play review completes and
the F-Droid mainline MR is merged, expect those two to FAIL and the verdict to be NOT READY —
that is correct behavior, not a script bug.
`UNKNOWN` means a network/tool problem prevented the check (e.g. offline). UNKNOWN on a
REQUIRED gate is treated as not-passing, so the verdict will be NOT READY.