docs: update mobile app release messaging (#98843)

This commit is contained in:
Josh Avant 2026-07-01 21:11:56 -05:00 committed by GitHub
parent 313560d5b9
commit 0cdce79221
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 351 additions and 358 deletions

View file

@ -1,8 +1,8 @@
## OpenClaw Android App
Status: **extremely alpha**. The app is actively being rebuilt from the ground up.
OpenClaw Android is the officially released Google Play app. It connects to an OpenClaw Gateway as a companion node for chat, voice, approvals, screen, and device-aware automation.
### Rebuild Checklist
### Current App Surface
- [x] New 4-step onboarding flow
- [x] Connect tab with `Setup Code` + `Manual` modes
@ -18,7 +18,6 @@ Status: **extremely alpha**. The app is actively being rebuilt from the ground u
- [x] Authenticated background presence beacons
- [x] Voice tab full functionality
- [x] Screen tab full functionality
- [ ] Full end-to-end QA and release hardening
## Open in Android Studio
@ -343,5 +342,4 @@ Common failure quick-fixes:
## Contributions
This Android app is currently being rebuilt.
Maintainer: @obviyus. For issues/questions/contributions, please open an issue or reach out on Discord.

View file

@ -39,7 +39,7 @@ When generating `apps/android/fastlane/metadata/android/en-US/release_notes.txt`
Recommended workflow:
- while iterating on a Play internal testing train, keep pending notes under `## Unreleased`
- while iterating on a Google Play release train, keep pending notes under `## Unreleased`
- before the production release, move or copy the final notes under `## <pinned version>` and run sync again
## Release Workflow
@ -51,8 +51,8 @@ Recommended workflow:
5. Run `pnpm android:release:preflight` to validate Play auth, signing, synced versioning, and release notes.
6. Run `ANDROID_SCREENSHOT_AVD=<avd-name> pnpm android:screenshots` to refresh raw Google Play screenshots with a script-managed emulator, or run `pnpm android:screenshots` when exactly one ADB device is already connected.
7. Run `pnpm android:release:archive` to produce the signed Play AAB and third-party APK.
8. Run `pnpm android:release:upload` to upload metadata, screenshots, and the Play AAB to Google Play internal testing.
9. Promote to production manually in Google Play Console.
8. Run `pnpm android:release:upload` to upload metadata, screenshots, and the Play AAB to the configured Google Play track.
9. Complete production rollout manually in Google Play Console when needed.
If `pnpm android:release:upload` fails, stop at that failure. Do not continue by
uploading archived artifacts through `pnpm android:release:archive`,

View file

@ -76,7 +76,7 @@ uses it. With `ANDROID_SCREENSHOT_AVD` or `--avd <name>`, the script can boot a
headless emulator, wait for boot completion, stabilize animation settings,
capture screenshots, and shut down only the emulator it started.
Upload metadata, release notes, and the Play AAB to the internal testing track:
Upload metadata, release notes, and the Play AAB to the configured Google Play track:
```bash
pnpm android:release:upload

View file

@ -2,13 +2,13 @@
## 2026.6.11 - 2026-07-01
Maintenance update for the current OpenClaw beta release.
Maintenance update for the current OpenClaw release.
- Refreshed iOS 26 visual styling, Talk controls, Gateway recovery, localization, and App Store screenshots.
## 2026.6.10 - 2026-06-21
Maintenance update for the current OpenClaw beta release.
Maintenance update for the current OpenClaw release.
- Improved notification cleanup, Watch app compatibility, and native file input handling.

View file

@ -1,19 +1,18 @@
# OpenClaw iOS (Super Alpha)
# OpenClaw iOS
This iOS app is super-alpha and internal-use only. The first public App Store release targets iPhone and connects to an OpenClaw Gateway as a `role: node`.
OpenClaw iOS is the officially released iPhone app. It connects to an OpenClaw Gateway as a `role: node` for chat, voice, approvals, sharing, and device-aware automation.
## Distribution Status
- Public distribution: App Store Connect app created; production signing is configured through the App Store release Fastlane path.
- Internal TestFlight distribution: uses the same App Store distribution archive uploaded to App Store Connect.
- Local/manual deploy from source via Xcode remains the default development path.
- Public distribution: App Store.
- App Store Connect uploads use the App Store release Fastlane path.
- Local/manual deploy from source via Xcode remains the default development path for app development.
## Super-Alpha Disclaimer
## Support Notes
- Breaking changes are expected.
- UI and onboarding flows can change without migration guarantees.
- Foreground use is the only reliable mode right now.
- Treat this build as sensitive while permissions and background behavior are still being hardened.
- UI and onboarding changes ship through normal app releases.
- Some node commands require foreground access because of iOS platform limits.
- Permissions, background behavior, and push delivery are documented below so release and support checks stay explicit.
## Exact Xcode Manual Deploy Flow
@ -191,7 +190,7 @@ pnpm ios:release:upload -- --version 2026.6.11 --build-number 3
- generates `apps/ios/build/AppStoreRelease.xcconfig`
- archives `OpenClaw`
- validates the exported IPA's push mode, signed entitlements, and embedded App Store profile
- uploads the IPA to App Store Connect for TestFlight/App Review use
- uploads the IPA to App Store Connect for processing and App Review use
- leaves App Review submission for a maintainer to complete manually
8. Expected outputs after a successful run:
@ -220,12 +219,12 @@ pnpm ios:version:sync -- --version 2026.6.11
Recommended flow:
### TestFlight iteration on an existing train
### App Store Connect iteration on an existing train
1. Choose the App Store train explicitly, for example `2026.6.11`.
2. Update `apps/ios/CHANGELOG.md`, usually under `## Unreleased` while iterating.
3. Run `pnpm ios:version:sync -- --version 2026.6.11` after changelog changes.
4. Upload more TestFlight builds with `pnpm ios:release:upload -- --version 2026.6.11`.
4. Upload additional App Store Connect builds with `pnpm ios:release:upload -- --version 2026.6.11`.
5. Let Fastlane bump only the numeric build number.
### Starting the next production release train
@ -254,7 +253,7 @@ See `apps/ios/VERSIONING.md` for the detailed spec.
## APNs Expectations For Official Builds
- Official/TestFlight builds register with the external push relay before they publish `push.apns.register` to the gateway.
- Official App Store builds register with the external push relay before they publish `push.apns.register` to the gateway.
- The gateway registration for relay mode contains an opaque relay handle, a registration-scoped send grant, relay origin metadata, and installation metadata instead of the raw APNs token.
- The relay registration is bound to the gateway identity fetched from `gateway.identity.get`, so another gateway cannot reuse that stored registration.
- The app persists the relay handle metadata locally so reconnects can republish the gateway registration without re-registering on every connect.
@ -269,7 +268,7 @@ See `apps/ios/VERSIONING.md` for the detailed spec.
- The operator session is used to fetch `gateway.identity.get`.
- `iOS -> relay`
- The app registers with the relay over HTTPS using App Attest plus a StoreKit app transaction JWS.
- The relay requires the official production/TestFlight distribution path, which is why local
- The relay requires the official App Store distribution path, which is why local
Xcode/dev installs cannot use the hosted relay.
- `gateway delegation`
- The app includes the gateway identity in relay registration.

View file

@ -125,7 +125,7 @@ pnpm ios:version:sync -- --version 2026.6.11
pnpm ios:release:upload -- --version 2026.6.11 --build-number 3
```
## Normal TestFlight iteration workflow
## Normal App Store Connect build iteration workflow
1. choose the App Store release train explicitly, for example `2026.6.11`
2. update `apps/ios/CHANGELOG.md` under `## <release version>` or `## Unreleased`
@ -156,9 +156,9 @@ not appear on GitHub release or tag pages, and they do not participate in the
core OpenClaw release machinery.
`pnpm ios:release:upload` checks the ref before archive/upload work and records
it only after `upload_to_testflight` succeeds. Existing refs are immutable: the
same ref at the same SHA is accepted, while the same ref at a different SHA
fails.
it only after the App Store Connect upload succeeds. Existing refs are
immutable: the same ref at the same SHA is accepted, while the same ref at a
different SHA fails.
Do not create this ref after a manual fallback upload. The ref is release-lane
evidence, not a repair mechanism for a failed `pnpm ios:release:upload` run.

View file

@ -1392,7 +1392,7 @@ platform :ios do
desc "Generate screenshots, update App Store metadata and review attachment, then upload an App Store build"
lane :release_upload do |options|
unless ENV["OPENCLAW_IOS_RELEASE_WRAPPER"] == "1"
UI.user_error!("Use `pnpm ios:release:upload`; direct Fastlane TestFlight upload is disabled.")
UI.user_error!("Use `pnpm ios:release:upload`; direct Fastlane upload is disabled.")
end
release_sha = release_git_sha

View file

@ -112,9 +112,9 @@ Upload to App Store Connect:
pnpm ios:release:upload -- --version 2026.6.11
```
Direct Fastlane TestFlight upload is disabled. Use the package script so the
release wrapper, App Store push mode, and exported-IPA validation gate all run
in the same path.
Direct Fastlane upload is disabled. Use the package script so the release
wrapper, App Store push mode, and exported-IPA validation gate all run in the
same path.
Maintainer recovery path for a fresh clone on the same Mac:
@ -152,7 +152,7 @@ Quick verification after upload:
- confirm `apps/ios/build/app-store/OpenClaw-<version>.ipa` exists
- confirm Fastlane validates the exported IPA before upload
- confirm Fastlane prints `Uploaded iOS App Store build: version=<version> short=<short> build=<build>`
- remember that App Store Connect/TestFlight processing can take a few minutes after the upload succeeds
- remember that App Store Connect processing can take a few minutes after the upload succeeds
Versioning rules:

View file

@ -47,7 +47,7 @@ Or set `APP_STORE_CONNECT_API_KEY_PATH`.
- Locale files live under `metadata/<locale>/`, for example `metadata/en-US/` and `metadata/sv-SE/`. Each locale directory should use the public metadata filenames consumed by the `ios metadata` lane.
- `release_notes.txt` is generated from `apps/ios/CHANGELOG.md`; after changelog updates, run `pnpm ios:version:sync -- --version <release-version>`.
- `apps/ios/APP-REVIEW-NOTES.md` is rendered to `apps/ios/build/app-review/APP-REVIEW-NOTES.pdf` and uploaded as the App Review attachment when metadata is uploaded.
- Release notes resolve from `## <release version>` first, then fall back to `## Unreleased` while a TestFlight train is still in progress.
- Release notes resolve from `## <release version>` first, then fall back to `## Unreleased` while an App Store Connect build train is still in progress.
- When starting a new production release train, sync metadata with `pnpm ios:version:sync -- --version <release-version>`.
- The release upload flow uploads release notes, screenshots, and the App Review PDF attachment before the IPA, and never submits for App Review.
- `privacy_url.txt` is set to `https://openclaw.ai/privacy`.

View file

@ -1,3 +1,3 @@
Maintenance update for the current OpenClaw beta release.
Maintenance update for the current OpenClaw release.
- Refreshed iOS 26 visual styling, Talk controls, Gateway recovery, localization, and App Store screenshots.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

View file

@ -613,7 +613,7 @@ See [Inferred commitments](/concepts/commitments).
- `remote.transport`: `ssh` (default) or `direct` (ws/wss). For `direct`, `remote.url` must be `wss://` for public hosts; plaintext `ws://` is accepted only for loopback, LAN, link-local, `.local`, `.ts.net`, and Tailscale CGNAT hosts.
- `remote.remotePort`: gateway port on the remote SSH host. Defaults to `18789`; use this when the local tunnel port differs from the remote gateway port.
- `gateway.remote.token` / `.password` are remote-client credential fields. They do not configure gateway auth by themselves.
- `gateway.push.apns.relay.baseUrl`: base HTTPS URL for the external APNs relay used after relay-backed iOS builds publish registrations to the gateway. Public App Store/TestFlight builds use the hosted OpenClaw relay. Custom relay URLs must match a deliberately separate iOS build/deployment path whose relay URL points at that relay.
- `gateway.push.apns.relay.baseUrl`: base HTTPS URL for the external APNs relay used after relay-backed iOS builds publish registrations to the gateway. Public App Store builds use the hosted OpenClaw relay. Custom relay URLs must match a deliberately separate iOS build/deployment path whose relay URL points at that relay.
- `gateway.push.apns.relay.timeoutMs`: gateway-to-relay send timeout in milliseconds. Defaults to `10000`.
- Relay-backed registrations are delegated to a specific gateway identity. The paired iOS app fetches `gateway.identity.get`, includes that identity in the relay registration, and forwards a registration-scoped send grant to the gateway. Another gateway cannot reuse that stored registration.
- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`: temporary env overrides for the relay config above.

View file

@ -337,7 +337,7 @@ candidate contains redacted secret placeholders such as `***`.
</Accordion>
<Accordion title="Enable relay-backed push for official iOS builds">
Relay-backed push for public App Store/TestFlight builds uses the hosted OpenClaw relay: `https://ios-push-relay.openclaw.ai`.
Relay-backed push for public App Store builds uses the hosted OpenClaw relay: `https://ios-push-relay.openclaw.ai`.
Custom relay deployments require a deliberately separate iOS build/deployment path whose relay URL matches the gateway relay URL. If you are using a custom relay build, set this in gateway config:
@ -373,7 +373,7 @@ candidate contains redacted secret placeholders such as `***`.
End-to-end flow:
1. Install an official/TestFlight iOS build.
1. Install the official iOS app.
2. Optional: configure `gateway.push.apns.relay.baseUrl` on the gateway only when using a deliberately separate custom relay build.
3. Pair the iOS app to the gateway and let both node and operator sessions connect.
4. The iOS app fetches the gateway identity, registers with the relay using App Attest plus the app receipt, and then publishes the relay-backed `push.apns.register` payload to the paired gateway.

View file

@ -21,16 +21,16 @@ Use this page to answer one question: which OpenClaw surfaces are credible choic
<div className="maturity-summary-grid">
<div className="maturity-summary-item maturity-score-alpha">
<div className="maturity-summary-heading">
<span className="maturity-summary-value">67%</span>
<span className="maturity-summary-value">68%</span>
<span>Maturity score</span>
</div>
<div className="maturity-summary-bar" style={{ "--score": "67" }}><span /></div>
<div className="maturity-summary-bar" style={{ "--score": "68" }}><span /></div>
<div className="maturity-summary-meta">
<span className="maturity-level-pill maturity-level-alpha">Alpha</span>
<span>Quality + completeness</span>
<span>Coverage Experimental - 4%</span>
<span>Quality Alpha - 63%</span>
<span>Completeness Beta - 70%</span>
<span>Quality Alpha - 64%</span>
<span>Completeness Beta - 71%</span>
</div>
</div>
</div>
@ -92,6 +92,20 @@ Surfaces are ordered by maturity level, completeness, and quality. LTS support i
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>87%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "87%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-partial">Partial - 4</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#android-app"><span className="maturity-surface-title">Android app</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-stable"><span className="maturity-level-code">M4</span><span>Stable</span></span><span>7 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Quality</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#ios-app"><span className="maturity-surface-title">iOS app</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-stable"><span className="maturity-level-code">M4</span><span>Stable</span></span><span>8 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Quality</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#agent-runtime"><span className="maturity-surface-title">Agent Runtime</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-beta"><span className="maturity-level-code">M3</span><span>Beta</span></span><span>9 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>33%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "33%" }} /></span></span></div>
@ -288,13 +302,6 @@ Surfaces are ordered by maturity level, completeness, and quality. LTS support i
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>67%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "67%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#android-app"><span className="maturity-surface-title">Android app</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-alpha"><span className="maturity-level-code">M2</span><span>Alpha</span></span><span>7 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Quality</span><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#google-chat"><span className="maturity-surface-title">Google Chat</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-alpha"><span className="maturity-level-code">M2</span><span>Alpha</span></span><span>5 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
@ -365,13 +372,6 @@ Surfaces are ordered by maturity level, completeness, and quality. LTS support i
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>53%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "53%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#ios-app"><span className="maturity-surface-title">iOS app</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-experimental"><span className="maturity-level-code">M1</span><span>Experimental</span></span><span>8 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Quality</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#nix-install-path"><span className="maturity-surface-title">Nix install path</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-experimental"><span className="maturity-level-code">M1</span><span>Experimental</span></span><span>5 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
@ -536,6 +536,20 @@ Surfaces are ordered by maturity level, completeness, and quality. LTS support i
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>88%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "88%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#android-app"><span className="maturity-surface-title">Android app</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-stable"><span className="maturity-level-code">M4</span><span>Stable</span></span><span>7 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Quality</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#ios-app"><span className="maturity-surface-title">iOS app</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-stable"><span className="maturity-level-code">M4</span><span>Stable</span></span><span>8 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Quality</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#docker-and-podman-hosting"><span className="maturity-surface-title">Docker and Podman hosting</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-beta"><span className="maturity-level-code">M3</span><span>Beta</span></span><span>4 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>7%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "7%" }} /></span></span></div>
@ -564,13 +578,6 @@ Surfaces are ordered by maturity level, completeness, and quality. LTS support i
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-beta"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-beta">Beta</span><span>78%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "78%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#android-app"><span className="maturity-surface-title">Android app</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-alpha"><span className="maturity-level-code">M2</span><span>Alpha</span></span><span>7 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Quality</span><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#native-windows"><span className="maturity-surface-title">Native Windows</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-alpha"><span className="maturity-level-code">M2</span><span>Alpha</span></span><span>4 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
@ -585,13 +592,6 @@ Surfaces are ordered by maturity level, completeness, and quality. LTS support i
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>61%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "61%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#ios-app"><span className="maturity-surface-title">iOS app</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-experimental"><span className="maturity-level-code">M1</span><span>Experimental</span></span><span>8 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Quality</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Completeness</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-surface-support"><span className="maturity-lts maturity-lts-none">None</span></div>
</div>
<div className="maturity-surface-row">
<a className="maturity-surface-name" href="/maturity/taxonomy#nix-install-path"><span className="maturity-surface-title">Nix install path</span><span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-experimental"><span className="maturity-level-code">M1</span><span>Experimental</span></span><span>5 areas</span></span></a>
<div className="maturity-surface-metric"><span className="maturity-surface-metric-label">Coverage</span><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>

View file

@ -121,6 +121,14 @@ A surface is a product area such as Gateway runtime, Discord, or the macOS app.
<span className="maturity-surface-title">macOS Gateway host</span>
<span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-stable"><span className="maturity-level-code">M4</span><span>Stable</span></span><span>7 areas - 88% complete</span></span>
</a>
<a className="maturity-surface-link" href="#android-app">
<span className="maturity-surface-title">Android app</span>
<span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-stable"><span className="maturity-level-code">M4</span><span>Stable</span></span><span>7 areas - 80% complete</span></span>
</a>
<a className="maturity-surface-link" href="#ios-app">
<span className="maturity-surface-title">iOS app</span>
<span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-stable"><span className="maturity-level-code">M4</span><span>Stable</span></span><span>8 areas - 80% complete</span></span>
</a>
<a className="maturity-surface-link" href="#docker-and-podman-hosting">
<span className="maturity-surface-title">Docker and Podman hosting</span>
@ -142,10 +150,6 @@ A surface is a product area such as Gateway runtime, Discord, or the macOS app.
<span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-beta"><span className="maturity-level-code">M3</span><span>Beta</span></span><span>8 areas - 78% complete</span></span>
</a>
<a className="maturity-surface-link" href="#android-app">
<span className="maturity-surface-title">Android app</span>
<span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-alpha"><span className="maturity-level-code">M2</span><span>Alpha</span></span><span>7 areas - 66% complete</span></span>
</a>
<a className="maturity-surface-link" href="#native-windows">
<span className="maturity-surface-title">Native Windows</span>
@ -157,10 +161,6 @@ A surface is a product area such as Gateway runtime, Discord, or the macOS app.
<span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-alpha"><span className="maturity-level-code">M2</span><span>Alpha</span></span><span>4 areas - 61% complete</span></span>
</a>
<a className="maturity-surface-link" href="#ios-app">
<span className="maturity-surface-title">iOS app</span>
<span className="maturity-surface-meta"><span className="maturity-level-pill maturity-level-experimental"><span className="maturity-level-code">M1</span><span>Experimental</span></span><span>8 areas - 44% complete</span></span>
</a>
<a className="maturity-surface-link" href="#nix-install-path">
<span className="maturity-surface-title">Nix install path</span>
@ -1697,6 +1697,180 @@ A surface is a product area such as Gateway runtime, Discord, or the macOS app.
</div>
</div>
</Accordion>
<Accordion title="Android app - M4 Stable - 7 areas">
<a id="android-app" />
Official Google Play distribution exists, source build/run docs are maintained, and the Android app is documented as a normal companion node for users.
<div className="maturity-surface-rollup"><span>Coverage Experimental - 0%</span><span>Quality Stable - 80%</span><span>Completeness Stable - 80%</span><span><span className="maturity-lts maturity-lts-none">None</span></span></div>
<div className="maturity-category-list">
<div className="maturity-category-row maturity-category-row-header"><span>Area</span><span>Coverage</span><span>Quality</span><span>Completeness</span><span>Docs</span></div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Media Capture</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android), [Camera](/nodes/camera)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Mobile Chat</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Connection Setup</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android), [Bonjour](/gateway/bonjour), [Pairing](/gateway/pairing)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Distribution</span>
<span>3 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Settings</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Voice</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android), [Talk](/nodes/talk)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Device Runtime</span>
<span>2 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android), [Troubleshooting](/nodes/troubleshooting), [Protocol](/gateway/protocol)</div>
</div>
</div>
</Accordion>
<Accordion title="iOS app - M4 Stable - 8 areas">
<a id="ios-app" />
Official App Store distribution exists, relay-backed push is documented, and the iOS app is documented as a normal companion node for users.
<div className="maturity-surface-rollup"><span>Coverage Experimental - 0%</span><span>Quality Stable - 80%</span><span>Completeness Stable - 80%</span><span><span className="maturity-lts maturity-lts-none">None</span></span></div>
<div className="maturity-category-list">
<div className="maturity-category-row maturity-category-row-header"><span>Area</span><span>Coverage</span><span>Quality</span><span>Completeness</span><span>Docs</span></div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Media and Sharing</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Camera](/nodes/camera)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Canvas and Screen</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Canvas](/plugins/reference/canvas)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Chat and Sessions</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Webchat](/web/webchat), [Protocol](/gateway/protocol)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Gateway Setup and Diagnostics</span>
<span>7 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Pairing](/channels/pairing)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Distribution</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Device Commands</span>
<span>2 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Protocol](/gateway/protocol)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Notifications and Background</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Configuration](/gateway/configuration)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Voice</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-stable"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-stable">Stable</span><span>80%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "80%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Talk](/nodes/talk)</div>
</div>
</div>
</Accordion>
<Accordion title="Docker and Podman hosting - M3 Beta - 4 areas">
@ -1971,89 +2145,6 @@ A surface is a product area such as Gateway runtime, Discord, or the macOS app.
</Accordion>
<Accordion title="Android app - M2 Alpha - 7 areas">
<a id="android-app" />
Public Google Play path exists, but app docs still describe the rebuild as extremely alpha and call out release hardening work.
<div className="maturity-surface-rollup"><span>Coverage Experimental - 0%</span><span>Quality Alpha - 59%</span><span>Completeness Alpha - 66%</span><span><span className="maturity-lts maturity-lts-none">None</span></span></div>
<div className="maturity-category-list">
<div className="maturity-category-row maturity-category-row-header"><span>Area</span><span>Coverage</span><span>Quality</span><span>Completeness</span><span>Docs</span></div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Media Capture</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android), [Camera](/nodes/camera)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Mobile Chat</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Connection Setup</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android), [Bonjour](/gateway/bonjour), [Pairing](/gateway/pairing)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Distribution</span>
<span>3 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Settings</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Voice</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android), [Talk](/nodes/talk)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Device Runtime</span>
<span>2 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>59%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "59%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-alpha"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-alpha">Alpha</span><span>66%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "66%" }} /></span></span></div>
<div className="maturity-category-docs">[Android](/platforms/android), [Troubleshooting](/nodes/troubleshooting), [Protocol](/gateway/protocol)</div>
</div>
</div>
</Accordion>
<Accordion title="Native Windows - M2 Alpha - 4 areas">
<a id="native-windows" />
@ -2160,99 +2251,6 @@ A surface is a product area such as Gateway runtime, Discord, or the macOS app.
</Accordion>
<Accordion title="iOS app - M1 Experimental - 8 areas">
<a id="ios-app" />
Internal preview / super-alpha. TestFlight and relay-backed push flows exist, but no public distribution yet.
<div className="maturity-surface-rollup"><span>Coverage Experimental - 0%</span><span>Quality Experimental - 41%</span><span>Completeness Experimental - 44%</span><span><span className="maturity-lts maturity-lts-none">None</span></span></div>
<div className="maturity-category-list">
<div className="maturity-category-row maturity-category-row-header"><span>Area</span><span>Coverage</span><span>Quality</span><span>Completeness</span><span>Docs</span></div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Media and Sharing</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Camera](/nodes/camera)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Canvas and Screen</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Canvas](/plugins/reference/canvas)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Chat and Sessions</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Webchat](/web/webchat), [Protocol](/gateway/protocol)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Gateway Setup and Diagnostics</span>
<span>7 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Pairing](/channels/pairing)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Distribution</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Device Commands</span>
<span>2 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Protocol](/gateway/protocol)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Notifications and Background</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Configuration](/gateway/configuration)</div>
</div>
<div className="maturity-category-row">
<div className="maturity-category-area">
<span className="maturity-category-title">Voice</span>
<span>1 capabilities</span>
</div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>0%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "0%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>41%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "41%" }} /></span></span></div>
<div><span className="maturity-score maturity-score-experimental"><span className="maturity-score-label"><span className="maturity-level-pill maturity-level-experimental">Experimental</span><span>44%</span></span><span className="maturity-meter" aria-hidden="true"><span style={{ width: "44%" }} /></span></span></div>
<div className="maturity-category-docs">[Ios](/platforms/ios), [Talk](/nodes/talk)</div>
</div>
</div>
</Accordion>
<Accordion title="Nix install path - M1 Experimental - 5 areas">
<a id="nix-install-path" />

View file

@ -75,7 +75,7 @@ openclaw gateway call node.list --params "{}"
Official distributed iOS builds use the external push relay instead of publishing the raw APNs
token to the gateway.
Official/TestFlight builds from the public App Store release lane use the hosted relay at `https://ios-push-relay.openclaw.ai`.
Official App Store builds from the public release lane use the hosted relay at `https://ios-push-relay.openclaw.ai`.
Custom relay deployments require a deliberately separate iOS build/deployment path whose relay URL matches the gateway relay URL. The public App Store release lane does not accept custom relay URL overrides. If you are using a custom relay build, set the matching gateway relay URL:
@ -106,11 +106,11 @@ How the flow works:
What the gateway does **not** need for this path:
- No deployment-wide relay token.
- No direct APNs key for official/TestFlight relay-backed sends.
- No direct APNs key for official App Store relay-backed sends.
Expected operator flow:
1. Install the official/TestFlight iOS build.
1. Install the official iOS app.
2. Optional: set `gateway.push.apns.relay.baseUrl` on the gateway only when using a deliberately separate custom relay build.
3. Pair the app to the gateway and let it finish connecting.
4. The app publishes `push.apns.register` automatically after it has an APNs token, the operator session is connected, and relay registration succeeds.
@ -180,7 +180,7 @@ Why this design was created:
- To keep production APNs credentials out of user gateways.
- To avoid storing raw official-build APNs tokens on the gateway.
- To allow hosted relay usage only for official/TestFlight OpenClaw builds.
- To allow hosted relay usage only for official OpenClaw iOS builds.
- To prevent one gateway from sending wake pushes to iOS devices owned by a different gateway.
Local/manual builds remain on direct APNs. If you are testing those builds without the relay, the
@ -193,7 +193,7 @@ export OPENCLAW_APNS_PRIVATE_KEY_P8="$(cat /path/to/AuthKey_KEYID.p8)"
```
These are gateway-host runtime env vars, not Fastlane settings. `apps/ios/fastlane/.env` only stores
App Store Connect / TestFlight auth such as `APP_STORE_CONNECT_KEY_ID` and
App Store Connect auth such as `APP_STORE_CONNECT_KEY_ID` and
`APP_STORE_CONNECT_ISSUER_ID`; it does not configure direct APNs delivery for local iOS builds.
Recommended gateway-host storage:

View file

@ -106,11 +106,9 @@ Upload to Cloudflare R2/S3 and generate secure presigned download links. Useful
</Card>
<Card title="iOS app via Telegram" icon="mobile">
**@coard** • `ios` `xcode` `testflight`
**@coard** • `ios` `xcode` `app-store`
Built a complete iOS app with maps and voice recording, deployed to TestFlight entirely via Telegram chat.
<img src="/assets/showcase/ios-testflight.jpg" alt="iOS app on TestFlight" />
Built a complete iOS app with maps and voice recording, prepared for App Store distribution entirely via Telegram chat.
</Card>
<Card title="Oura Ring health assistant" icon="heart-pulse">

View file

@ -5,19 +5,19 @@ counts:
category_scores: 281
rollups:
surface_average:
quality:
score: 63
label: Alpha
completeness:
score: 70
label: Beta
category_average:
quality:
score: 64
label: Alpha
completeness:
score: 71
label: Beta
category_average:
quality:
score: 66
label: Alpha
completeness:
score: 72
label: Beta
surfaces:
- id: gateway-runtime
name: Gateway runtime
@ -2168,16 +2168,16 @@ surfaces:
name: Android app
family: platform-app
level:
id: alpha
code: M2
label: Alpha
id: stable
code: M4
label: Stable
scores:
quality:
score: 59
label: Alpha
score: 80
label: Stable
completeness:
score: 66
label: Alpha
score: 80
label: Stable
lts:
status: none
supported_categories: 0
@ -2191,77 +2191,77 @@ surfaces:
categories:
- name: Media Capture
quality:
score: 59
label: Alpha
score: 80
label: Stable
completeness:
score: 66
label: Alpha
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Mobile Chat
quality:
score: 59
label: Alpha
score: 80
label: Stable
completeness:
score: 66
label: Alpha
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Connection Setup
quality:
score: 59
label: Alpha
score: 80
label: Stable
completeness:
score: 66
label: Alpha
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Distribution
quality:
score: 59
label: Alpha
score: 80
label: Stable
completeness:
score: 66
label: Alpha
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Settings
quality:
score: 59
label: Alpha
score: 80
label: Stable
completeness:
score: 66
label: Alpha
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Voice
quality:
score: 59
label: Alpha
score: 80
label: Stable
completeness:
score: 66
label: Alpha
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Device Runtime
quality:
score: 59
label: Alpha
score: 80
label: Stable
completeness:
score: 66
label: Alpha
score: 80
label: Stable
lts:
supported: false
reason: none
@ -2270,16 +2270,16 @@ surfaces:
name: iOS app
family: platform-app
level:
id: experimental
code: M1
label: Experimental
id: stable
code: M4
label: Stable
scores:
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
status: none
supported_categories: 0
@ -2293,88 +2293,88 @@ surfaces:
categories:
- name: Media and Sharing
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Canvas and Screen
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Chat and Sessions
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Gateway Setup and Diagnostics
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Distribution
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Device Commands
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Notifications and Background
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
supported: false
reason: none
human_override: false
- name: Voice
quality:
score: 41
label: Experimental
score: 80
label: Stable
completeness:
score: 44
label: Experimental
score: 80
label: Stable
lts:
supported: false
reason: none

View file

@ -567,11 +567,11 @@ export const FIELD_HELP: Record<string, string> = {
"gateway.push":
"Push-delivery settings used by the gateway when it needs to wake or notify paired devices. Configure relay-backed APNs here for official iOS builds; direct APNs auth remains env-based for local/manual builds.",
"gateway.push.apns":
"APNs delivery settings for iOS devices paired to this gateway. Use relay settings for official/TestFlight builds that register through the external push relay.",
"APNs delivery settings for iOS devices paired to this gateway. Use relay settings for official App Store builds that register through the external push relay.",
"gateway.push.apns.relay":
"External relay settings for relay-backed APNs sends. The gateway uses the hosted OpenClaw relay by default, or this custom relay for push.test, wake nudges, and reconnect wakes after a paired official iOS build publishes a relay-backed registration.",
"gateway.push.apns.relay.baseUrl":
"Optional custom base HTTPS URL for the external APNs relay service used by official/TestFlight iOS builds. Keep this aligned with the relay URL baked into the iOS build so registration and send traffic hit the same deployment.",
"Optional custom base HTTPS URL for the external APNs relay service used by official App Store iOS builds. Keep this aligned with the relay URL baked into the iOS build so registration and send traffic hit the same deployment.",
"gateway.push.apns.relay.timeoutMs":
"Timeout in milliseconds for relay send requests from the gateway to the APNs relay (default: 10000). Increase for slower relays or networks, or lower to fail wake attempts faster.",
"gateway.http.endpoints.chatCompletions.enabled":

View file

@ -5670,9 +5670,9 @@ surfaces:
- id: android-app
name: Android app
family: platform-app
level: alpha
level_code: M2
rationale: Public Google Play path exists, but app docs still describe the rebuild as extremely alpha and call out release hardening work.
level: stable
level_code: M4
rationale: Official Google Play distribution exists, source build/run docs are maintained, and the Android app is documented as a normal companion node for users.
completeness_instructions: references/completeness/android-app.md
categories:
- name: Media Capture
@ -5800,9 +5800,9 @@ surfaces:
- id: ios-app
name: iOS app
family: platform-app
level: experimental
level_code: M1
rationale: Internal preview / super-alpha. TestFlight and relay-backed push flows exist, but no public distribution yet.
level: stable
level_code: M4
rationale: Official App Store distribution exists, relay-backed push is documented, and the iOS app is documented as a normal companion node for users.
completeness_instructions: references/completeness/ios-app.md
categories:
- name: Media and Sharing
@ -5893,13 +5893,13 @@ surfaces:
- name: Distribution
id: distribution
features:
- name: Internal preview status
- name: App distribution
coverageIds: [ios.internal-preview-status]
description: Internal preview status, source/Xcode manual deploy, local signing, XcodeGen project generation, Fastlane TestFlight archive/upload, versioning/changelog/metadata, release artifacts, and official-vs-local build flags
description: App Store distribution, source/Xcode manual deploy, local signing, XcodeGen project generation, Fastlane App Store archive/upload, versioning/changelog/metadata, release artifacts, and official-vs-local build flags
docs:
- docs/platforms/ios.md
search_anchors:
- TestFlight
- App Store
- Xcode manual deploy
- signing
category_note: install-signing-and-testflight-distribution.md
@ -6033,7 +6033,7 @@ surfaces:
description: Watch app and WatchKit extension targets
- name: Signing/profile variables
coverageIds: [watchos.signing-profile-variables]
description: Signing/profile variables, bundle identifiers, icon assets, and iOS beta release flow
description: Signing/profile variables, bundle identifiers, icon assets, and iOS App Store release flow
- name: Public/support status
coverageIds: [watchos.public-support-status]
description: Public/support status for the watch companion as distributed through the iOS app
@ -6042,7 +6042,7 @@ surfaces:
description: Changelog and repo-history evidence for watchOS companion maturity
- name: Release metadata
coverageIds: [watchos.release-metadata]
description: Release metadata and app-store/TestFlight preparation evidence
description: Release metadata and App Store preparation evidence
- name: Historical bug/regression themes relevant to scoring
coverageIds: [watchos.historical-bug-regression-themes-relevant-to-scoring]
description: Historical bug/regression themes relevant to scoring current source quality