Commit Graph

289 Commits

Author SHA1 Message Date
Peter Steinberger
6921fb4ce7 refactor(ios): trim approval test fixtures (#105052) 2026-07-12 07:38:45 +01:00
Peter Steinberger
ae3008c70a fix(ios): show unavailable Watch approval state 2026-07-11 23:19:37 -07:00
Peter Steinberger
2a02ab6bbe refactor(apps): reuse Watch approval transport models (#105024)
* refactor(apps): reuse watch approval transport models

* fix(ios): satisfy exact identifier lint
2026-07-12 07:08:03 +01:00
Peter Steinberger
ac89350327 feat(apps): review durable approvals on mobile (#104913)
* feat(apps): Android, iPhone, and Watch approval clients

Squash-rebased #103912 segment onto the deep-links tip on current main.
Native approval surfaces: iOS approval presentation with gateway-switch
lease preservation and resolution fencing, watchOS inbox + approval
actions with shipped-shape payload codec, Android approval notices with
publication-tokened dismissal. Native i18n inventory regenerated.

(cherry picked from commit 428a76670ffeede54248b7bd7aa4438e2589851b)
(cherry picked from commit 80225d5707c3645eeea5435f266131037b50ede6)
(cherry picked from commit 2a23b714dc30d773a294aa45adc617e46b80732e)
(cherry picked from commit 9ff1153827769e2cbab7c11c153f0f8634662c28)
(cherry picked from commit 5b25723525bd562e5f97478af492f7b46ad30fd1)
(cherry picked from commit 8c80e8467b5fe89aad0d4c74a0573f1600ed3af9)
(cherry picked from commit ad4037bc9846bf6f082b41c129ee68aa344576c3)
(cherry picked from commit fdf767dd662cff3c8a5a6d571f38f153410651ca)
(cherry picked from commit 00c120376ffd992ea68ce29254a9bc0a25ed1740)
(cherry picked from commit f36a95213e)
(cherry picked from commit e2c25cbe2baacab44d21871d8cb6734704f065ac)
(cherry picked from commit 7c4fda519080486d341a9f4df36d63f9e24b1235)
(cherry picked from commit 1b3d4eda3dc5988012124597f9454ae21fb187a1)
(cherry picked from commit 2a60619722)
(cherry picked from commit 6f0c386567)
(cherry picked from commit 784a5857b7)
(cherry picked from commit cbf294e026841c9bc2799da0fc7db666a69c52db)

* fix(apps): harden approval reconciliation and watch states
2026-07-11 19:59:07 -07:00
xingzhou
57c2d65ad5 fix(apps): reconcile slow Apple chat replies (#97722)
* fix(apps): reconcile slow chat replies

Co-authored-by: zhang-guiping <zhang.guiping@xydigit.com>

* style(apps): wrap wait diagnostic

* chore(apps): refresh native i18n inventory

* chore: leave changelog release-owned

* style(apps): normalize Swift modifiers

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 17:01:40 -07:00
lin-hongkuan
522e253c53 fix(ios): resize oversized shared images (#103860)
* fix(ios): resize oversized shared images

* fix(ios): satisfy SwiftFormat await rules

* fix(ios): integrate share image processing

* fix(ios): type share attachment failures

---------

Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 15:16:45 -07:00
Peter Steinberger
dc42c893c3 improve(ios): redesign share extension compose sheet (#104187) 2026-07-10 22:22:15 -07:00
lin-hongkuan
f4732576bd fix(ios): preserve prefixed share text (#103453)
* fix(ios): preserve prefixed share text

* fix(ios): harden shared text normalization

---------

Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 20:01:06 -07:00
Peter Steinberger
d628e35574 fix(apple): prevent stale thinking after model switches and reconnects (#103767)
* fix(apple): prevent stale model thinking state

* test(apple): complete attachment transport fixture

* fix(apple): scope model patch ordering by route identity

* chore(apple): sync native CI metadata
2026-07-10 16:48:11 +01:00
lin-hongkuan
b2c1db4b5e fix(ios): scope session mutations to selected agent (#103415)
* fix(ios): scope session mutations to selected agent

* fix(ios): preserve agent ownership for session mutations

---------

Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 15:33:19 +01:00
NianJiu
067edbcb2d fix(ios): make Talk audio lifecycle-safe (#103072)
* fix(ios): cancel queued push-to-talk invokes

* fix(ios): make push-to-talk cancellation lifecycle-safe

* style(ios): use switch expression for PTT result

* fix(ios): bind audio capture to lifecycle owners

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

* style(ios): format rebased lifecycle changes

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

* fix(ios): preserve routing hydration across reconnects

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

* fix(ios): cancel routing hydration on target switch

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

* chore(ios): refresh native i18n inventory

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

* fix(i18n): preserve native localization IDs

* chore: leave changelog to release automation

* refactor(apple): split lifecycle and gateway helpers

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

* fix(ios): make lifecycle parsing nonisolated

* fix(ios): consume canonical Talk events

---------

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 15:03:40 +01:00
Peter Steinberger
62bd760c0e chore(swift): enforce current formatting and lint rules (#103313)
* style: apply SwiftFormat 0.62.1 rules

Refs #103202

* ci: enforce deterministic Swift lint

Refs #103202

* refactor: keep gateway connect lint-clean

Refs #103202

* style: keep iOS typography checks warning-free

* ci: route MLX Swift changes through pre-push

* fix: preserve native i18n extraction after Swift cleanup

* refactor: keep rebased Swift surfaces lint-clean

* style: format latest Swift additions

* chore: refresh native i18n inventory

* style: keep generated Swift formatter-clean

* fix: preserve node route invalidation callbacks

* fix: keep native translation IDs stable

* fix: retain native translation identifiers

* fix: preserve translations across Swift source moves
2026-07-10 11:54:08 +01:00
Peter Steinberger
7fe004d852 feat: show build identity in About screens (#103595)
* feat: show build identity in About screens

* chore: leave root changelog to release automation

* fix: translate Control UI About build details
2026-07-10 10:42:36 +01:00
NianJiu
8b49bc61a8 fix(ios): stop camera work when invoke is cancelled (#103069)
* fix(ios): stop camera work when invoke is cancelled

* fix(ios): mark AVFoundation cancellation boundary

* chore(ios): refresh native i18n inventory

* fix(camera): clean up cancelled warm-up sessions

* fix(ios): make camera cancellation lifecycle-safe

---------

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 09:44:42 +01:00
Peter Steinberger
195bec6910 feat(ios): show per-message usage metadata (#103471)
* feat(ios): show per-message usage metadata

* fix(ios): compile usage context calculation
2026-07-10 08:24:28 +01:00
Peter Steinberger
0e4c7cd155 feat(ios): render native markdown headings (#103404) 2026-07-10 06:21:46 +01:00
Sahil Satralkar
4e3d91a020 feat: iOS Privacy screen location controls (#103096)
* Fix iOS privacy location card presentation

* Refine iOS location privacy controls

* fix(ios): restore location access chooser

* style(ios): format location access dialog

* chore: keep release note in PR body

* test(ios): keep privacy coverage focused

* fix(ios): clear unresolved location mode

* chore(ios): refresh native strings

* fix(ios): localize location status copy

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 05:42:04 +01:00
Peter Steinberger
1f12e7fc87 fix(ios): replace dead-end discovered gateway connects (#103289)
* fix(ios): clarify insecure discovered gateways

* fix(ios): finish discovered gateway guidance

* fix(ios): preserve gateway failure expression
2026-07-10 05:08:58 +01:00
Peter Steinberger
20816f676f feat(voice): universal talk waveform driven by real audio levels (#102901)
* feat(voice): universal talk waveform driven by real audio levels

One shared Siri-style talk animation across iOS, watchOS, macOS, and
Android (TalkWaveformView + exact Compose port), replacing per-platform
fakes: synthetic speaking pulses, constant speech-detected power, static
Android bar rows, flat realtime listening. Listening/recording follow
live mic levels on every route; agent speech follows the real playback
envelope (AVAudioPlayer metering + playback-aligned PCM envelope +
WebRTC stats); voice-note recording shows a live capture wave.

* fix(android): order waveform imports and sync native i18n inventory

* chore(i18n): resync native inventory after rebase
2026-07-09 16:33:25 +01:00
Peter Steinberger
54f45a950b feat(watchos): connect directly to Gateway as a node (#102893)
* feat(watchos): add direct gateway node

* docs: refresh watch node docs map

* chore: leave release notes to release workflow

* chore(ios): refresh native localization inventory

* fix(watchos): keep direct node policy bounded
2026-07-09 15:53:02 +01:00
Raghav Sethi
19f42a27e5 feat(ios): redesign Control tab to a flatter, card-based layout (#98582)
* feat(ios): refresh Control tab layout

Co-authored-by: Raghav Sethi <rsraghavsethi@gmail.com>

* fix(ios): align Control card edges

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-09 15:08:07 +01:00
Peter Steinberger
6621ead871 improve(ios): manage notifications from Privacy (#102733)
* improve(ios): manage notifications from privacy

Co-authored-by: Sahil Satralkar <62758655+sahilsatralkar@users.noreply.github.com>

* fix(ios): make notification status returns explicit

---------

Co-authored-by: Sahil Satralkar <62758655+sahilsatralkar@users.noreply.github.com>
2026-07-09 12:35:29 +01:00
mahmoud
32510a3225 improve(ios): show connection progress and errors prominently in onboarding gateway step (#101921)
* fix(ios): surface connection progress and errors prominently in onboarding gateway step

* fix(ios): surface onboarding validation failures

* chore(ios): sync native string inventory

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-09 10:03:26 +01:00
Josh Avant
6438c89f05 fix(mobile): clarify gateway connection security setup (#101325)
* fix(mobile): clarify gateway connection setup

* chore(i18n): sync native mobile strings

* fix(mobile): align manual gateway previews

* chore(i18n): refresh native source inventory

* chore(android): remove unused connect tab strings

* test(i18n): drop removed connect tab sentinel

* fix(ios): brand connection security picker labels

* fix(mobile): hide gateway endpoint previews

* chore(i18n): sync native source inventory

* fix(mobile): remove redundant TLS helper copy
2026-07-07 14:43:11 -05:00
Peter Steinberger
6e792f08f8 fix(ios): serialize screen recording finalization (#101550)
* fix(ios): serialize screen recording finalization

* chore: keep release changelog out of PR
2026-07-07 11:13:46 +01:00
Peter Steinberger
cc2c6a87dc fix(ios): skip onboarding for configured gateways (#101481)
* fix(ios): skip onboarding for configured gateways

Fixes #98570

* fix(ios): prioritize saved gateway state
2026-07-07 09:31:18 +01:00
Peter Steinberger
48e77b6abf feat(ios): render inline LaTeX math in completed chat prose (#101388) 2026-07-07 08:46:31 +01:00
Ben.Li
f75782ee01 fix(ios): full-row Settings toggles on iOS 26 (#99888)
* fix(ios): use full-row Settings toggles on iOS 26

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(ios): refresh native string inventory

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 06:26:40 +01:00
Colin Johnson
632efa2d73 fix ios qr scanner lifecycle (#101235)
* fix ios qr scanner lifecycle

* fix(ios): tighten QR scanner lifecycle change

---------

Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-07-06 21:34:44 -05:00
Peter Steinberger
f95ca90378 fix(ios): persist voice notes through offline delivery (#101236)
* fix(ios): persist voice note delivery state

* fix(ios): pin chats during attachment staging

* fix(ios): keep voice notes on captured chat

* fix(ios): keep voice notes durable through staging

* fix(ios): harden voice note lifecycle

* test(ios): satisfy strict concurrency in voice note proof

* fix(ios): keep legacy attachment sends live

* fix(ios): retain legacy drafts during outbox restore

* fix(ios): pin voice note recipient presentation

* fix(ios): preserve confirmed voice note duration

* chore(i18n): refresh voice note source inventory

* chore: leave release notes to release automation
2026-07-07 01:21:16 +01:00
Peter Steinberger
4c97aa1311 feat(mobile): rename, delete, and create session groups on iOS and Android (#101234)
* feat(mobile): rename, delete, and create sidebar session groups on iOS and Android

Group section headers on the iOS Command Center sessions screen and the
Android sessions screen gain Rename/New/Delete group actions. Bulk ops
enumerate every member (active + archived, explicit high list limit since
the gateway caps an absent limit at 100 rows) and patch category per
session; delete keeps sessions and moves them to Ungrouped. Known custom
groups persist client-side (iOS UserDefaults, Android SharedPreferences)
so empty groups stay visible as move targets.

* chore(i18n): refresh native string inventory after rebase onto main
2026-07-07 01:09:57 +01:00
Peter Steinberger
b978dcc63b feat(ios): record and send voice notes from the chat composer (#100946)
* feat(ios): record and send voice notes from the chat composer

Adds tap-to-record voice notes to the shared chat composer: m4a/AAC mono
capture with a 3-minute cap, lazy mic permission, cancel/finish controls,
audio attachment chips with duration, and a voice-note transcript row.
Voice-wake suppression becomes reason-scoped so recording and Talk cannot
clobber each other. Attachments stay online-only per the outbox contract.

Related: #100709

* fix(ios): harden voice note attachment staging

* chore(ios): keep voice note changelog release-owned

* fix(ios): gate voice notes with attachment availability

* chore(ios): refresh native localization inventory
2026-07-07 00:14:05 +01:00
Peter Steinberger
36b733bf5c feat(ios): pair multiple gateways and switch between them without re-pairing (#100948)
* feat(ios): multi-gateway registry, per-gateway credentials, and switching

* fix(ios): harden multi-gateway state isolation
2026-07-06 20:29:02 +01:00
Peter Steinberger
60ce506712 feat(ios): add Listen action speaking assistant messages via gateway TTS (#100771)
* test(gateway): shift advertised-method window for tts.speak

* feat(ios): add Listen action speaking assistant messages via gateway TTS

* docs(ios): document the chat Listen action

* style(ios): keep outbox label doc comment attached and give speech chip its own

* fix(ios): harden chat Listen playback

* docs(changelog): note iOS chat Listen

* fix(ios): unwrap speech MIME before classification

* docs(changelog): keep Listen note app-scoped
2026-07-06 19:32:54 +01:00
Peter Steinberger
06789ca4c2 fix(ios): keep offline chat sends on their original route (#100942) 2026-07-06 17:53:05 +01:00
Peter Steinberger
077e35f3b2 feat(ios): read-only workspace Files browser on the Agents surface (#100767)
* feat(ios): add read-only workspace Files browser to the Agents surface

* fix(ios): keep nav bar visible on pushed workspace file routes

* fix(ios): make workspace file navigation stack-safe

* docs(ios): note workspace file browser

* fix(ios): isolate workspace share exports

* chore(i18n): refresh iOS Files inventory

* refactor(ios): encode workspace requests before dispatch

* chore(i18n): refresh iOS inventory after rebase
2026-07-06 17:47:52 +01:00
Peter Steinberger
7853aa35a4 feat(ios): per-gateway custom headers for gateways behind authenticating proxies (#100768)
* 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
2026-07-06 17:17:07 +01:00
Peter Steinberger
538d4eeb77 feat(ios): hide thinking-level control for models without reasoning support (#100875) 2026-07-06 15:59:03 +01:00
Peter Steinberger
83f0527724 feat(ios): word-paced fade-in for streaming assistant prose (#100884) 2026-07-06 15:50:58 +01:00
Peter Steinberger
88f1ec38d4 feat(sessions): grouping, unread state, and full session controls on web, iOS, and Android (#100814)
Gateway (additive, no protocol version bump): SessionEntry gains
lastReadAt/markedUnreadAt/lastActivityAt; session rows expose a derived
unread flag (explicit mark, or last read before latest activity; never-read
sessions stay read so upgrades do not light up). lastActivityAt is stamped
in the canonical post-run store update - user, channel, and cron runs count
as activity; heartbeat, internal-event, and preserved-state runs do not.
sessions.patch gains unread; sessions.create gains fork (transcript fork
from parentSessionKey under the parent lifecycle lock, refusing active,
concurrently-changed, and oversized parents, cross-agent aware).

Web sidebar: Pinned/custom-group/Ungrouped sections, unread dots, kebab and
right-click context menu (pin, mark unread/read, rename, fork, move to group,
archive, delete guarded for agent main sessions and active runs), mark-read
on view with loop-safe re-acknowledgement and failure retry; sessions page
gets unread + fork actions and shared custom-group helpers.

iOS Command Center: grouped sections, unread/pin indicators, Show Archived
gated on per-entry state, full context menu with rename/new-group alerts and
delete confirmation, current-session preview guarantee, read-episode
re-acknowledgement; new patch/delete/fork transport calls; Swift protocol
models regenerated.

Android SessionsScreen: grouped headers, unread/pin indicators, Archived
filter gated on per-entry state, long-press menu with the full control set,
agent-scoped forks, explicit label/category clears from session events,
main-session fallback when archiving/deleting the open chat, read-episode
re-acknowledgement with failure retry.

Closes #100739
2026-07-06 14:30:55 +01:00
Peter Steinberger
2a741bebb5 feat(ios): render LaTeX display math in chat via SwiftMath (#100829) 2026-07-06 12:14:38 +01:00
Peter Steinberger
1f06b890a6 feat(ios): add model picker favorites and recents with working iOS model switching (#100774) 2026-07-06 11:44:13 +01:00
Peter Steinberger
b4b1984fe7 feat(gateway): start a new chat session in a managed worktree (#100788)
Adds an additive worktree flag to sessions.create so any new chat can run in an
isolated managed worktree of the agent's git workspace, with the branch checked
out and .worktreeinclude provisioning applied. The session's spawnedCwd points at
the matching subdirectory inside the worktree so chat runs, CLI, and the file
browser execute there. agents.list gains workspaceGit (workspace or an ancestor
is a git checkout) to gate the affordance; web sidebar, iOS, and Android expose a
New-Chat-in-worktree action. Uses the method's operator.write scope, but the
.openclaw/worktree-setup.sh step runs only for operator.admin callers since it
executes repo code. Deleting the session, or leaving via a plain New Chat, clears
the cwd and lossless-removes the worktree; idle GC treats recent session activity
as worktree activity so an active session's checkout is never swept.

Live-verified end-to-end on a real gateway; follow-up to #100535 (issue #100534).
2026-07-06 10:23:41 +01:00
Peter Steinberger
8d1668c441 fix(ios): harden Apple Watch pairing activation (#100732) 2026-07-06 09:16:02 +01:00
Peter Steinberger
f1d28c855c fix(ios): unify Talk and Settings row typography on one branded detail row (#100515)
* fix(ios): unify Talk and Settings row typography on one branded detail row

* chore(i18n): sync native string inventory for iOS detail row refactor
2026-07-06 07:46:19 +01:00
Vincent Koc
75c8753a2c fix(ios): bound location permission wait 2026-07-06 04:36:10 +02:00
Peter Steinberger
443c582949 fix(ios): restore in-flight runs after reconnect (#100277)
* fix(ios): restore in-flight chat runs from gateway history

Restore active Apple chat ownership across reconnect, foreground, and sequence-gap recovery using the existing chat.history snapshot. Preserve agent/session scoping and Gateway user-turn identity across Codex and Copilot mirrors, including current offline-cache integration.

* fix(ios): restore in-flight chat runs from gateway history
2026-07-06 03:23:38 +01:00
Peter Steinberger
d2d5911c32 fix(ios): keep While Using selected after approval (#100512)
* fix(ios): preserve initial location permission selection

* chore: keep iOS location fix independent
2026-07-06 03:05:25 +01:00
Tyler Nishida
2db5bd3394 feat(ios): refresh onboarding setup flow (#98868) 2026-07-05 21:38:54 -04:00
Peter Steinberger
5d8293c1fe feat(ios): read-only offline cache for chat sessions and transcripts (#100219)
* 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
2026-07-06 01:02:15 +01:00