* feat(ios): mascot moods for onboarding and gateway quick setup
The activation glyph now takes a mood: the onboarding welcome step
shows the hard-hat working mascot while connecting, the success step
celebrates, and the gateway quick-setup header derives working/sad/
curious/idle from its connect state.
* fix(ios): quick-setup mood reflects app-level gateway problems too
The sheet renders two error surfaces — the local connect error and the
app-level gateway problem banner — and the mascot now goes sad for
either instead of only the sheet-local failure.
* feat(ios): guide first launch through pairing explainer and permissions
* fix(ios): keep first-run flow resumable and surface limited grants in onboarding
* chore(ios): regenerate native i18n after rebase
* chore(android): project refreshed native translations into strings.xml
* fix(ios): move i18n wrapper contract to shared permission row and sync catalog
* fix(ios): focus missing gateway credentials
Co-authored-by: Colin <colin@solvely.net>
* test(macos): let main actor polling suspend
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* feat(ios): support per-gateway custom headers for proxied gateway connections
Per-gateway custom request headers (Cloudflare Access-style service tokens)
for gateways behind authenticating reverse proxies. Headers are credentials:
Keychain-stored per gateway stableID, masked in settings UI, injected on the
WebSocket upgrade at connect time via a provider so edits apply on the next
reconnect without re-pairing. Reserved handshake headers and control chars
are sanitized out. TLS pinning and pairing flows unchanged. Push relay and
other non-gateway destinations proven header-free by regression test.
Related: #100698
* chore(ios): sync native i18n inventory for custom header strings
* fix(ios): harden gateway custom headers
* chore(ios): resync native i18n inventory
* fix(ios): validate custom header names
* feat(ios): read-only offline cache for chat sessions and transcripts
Cache-first cold open for the iOS chat tab: the last known transcript and
session list render immediately from a local SQLite cache, then live gateway
history replaces them wholesale through the existing reconciliation path.
When the gateway is unreachable, recent sessions and transcripts stay
browsable read-only; sending remains gated by the existing connection state.
- New OpenClawChatTranscriptCache protocol seam plus SQLite-backed store in
OpenClawChatUI (raw SQLite3, no new dependencies), scoped per gateway
stableID so transcripts never leak across paired gateways.
- Bounds: 50 sessions, 50 transcripts, 200 messages per session; text rows
only (attachment/binary payloads and tool arguments are stripped).
- Disposable cache: schema versioned via user_version; any open/schema/decode
mismatch drops and rebuilds silently. File protection
completeUntilFirstUserAuthentication on iOS.
- View model pre-paints from cache only until a live response applies
(hasAppliedLiveHistory/hasAppliedLiveSessions guards); write-through is
chained and off the render path.
- iOS wiring keys the chat view model identity on transport mode plus cache
gateway ID so switching paired gateways rebuilds the view model.
Part of #100194
* fix(ios): harden offline transcript cache
* fix(ios): expose offline cached sessions
* fix(ios): isolate transcript caches by gateway
* chore(i18n): sync native inventory
* fix(ios): allow cache extension to replace messages
Add OpenClaw design system foundations:
- Custom typography tokens (OpenClawType) using Plus Jakarta Sans,
DM Sans, and JetBrains Mono with Dynamic Type scaling
- Spacing and radius token enums (OpenClawSpacing, OpenClawRadius)
- Additive brand color tokens (accentPressed, teal, void, obsidian,
slate, textPrimary, textSecondary)
- Shared components: OpenClawToggleIndicator, OpenClawStatusBadge,
OpenClawPrimaryButtonStyle, OpenClawSecondaryButtonStyle
- Bundled font files with OFL license provenance
Migrate all iOS views to OpenClawType tokens. No behavioral, navigation,
or routing changes — this is purely visual/typographic.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(ios): make onboarding Retry Connection use current manual input
Retry Connection on the auth step replayed connectLastKnown(), which
silently returns when no last connection is stored and otherwise redials
the stale persisted endpoint, ignoring host/port/TLS and token edits made
on screen. Manual retries now dial the current form input; discovered
gateway retries keep the previous behavior.
* fix(ios): repair onboarding credential retry
Co-authored-by: Abdullah Taş <29359748+abdullahtas0@users.noreply.github.com>
---------
Co-authored-by: abdullahtas0 <“dev.abdullahtas@gmail.com”>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
handleScannedLink does not set self.step = .connect after scanning a QR
code from the welcome step. The scanner sheet dismisses and the UI
returns to the welcome screen instead of showing connection progress.
The sibling handleScannedSetupCode path correctly advances the step;
this aligns the QR scan path.
Fixes#98297
Co-authored-by: Cursor <cursoragent@cursor.com>
Move iOS accent and status colors through design tokens so raw SwiftUI color literals are blocked outside token definitions.
Set the app-wide tint in SwiftUI and UIKit from code, without relying on Assets.xcassets AccentColor.
Summary:
- Replace the legacy iOS shell with Pro Command, Chat, Agents, and Settings tabs.
- Wire iOS chat/session/settings/diagnostics and realtime Talk flows through gateway-backed APIs.
- Add gateway/session and shared chat coverage for the new iOS flow.
Verification:
- git diff --check
- node scripts/run-vitest.mjs src/gateway/server.sessions.create.test.ts src/gateway/talk-realtime-relay.test.ts
- swift test --filter ChatViewModelTests (apps/shared/OpenClawKit)
- xcodebuild build for Nimrod's iPhone succeeded; install succeeded; launch was blocked because the phone was locked
Known follow-up:
- Preserve traceLevel in sessions.create parent runtime inheritance and keep the changelog credit in the follow-up patch.