Commit graph

3884 commits

Author SHA1 Message Date
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
Vincent Koc
6799b5b3d4
refactor(android): remove obsolete global cache cleanup (#101470) 2026-07-07 01:19:17 -07:00
Peter Steinberger
48e77b6abf
feat(ios): render inline LaTeX math in completed chat prose (#101388) 2026-07-07 08:46:31 +01:00
Peter Steinberger
cb9de7d361
chore(android): update dependencies and compile with API 37 (#101356)
* build(deps): bump the android-deps group across 1 directory with 14 updates

Bumps the android-deps group with 14 updates in the /apps/android directory:

| Package | From | To |
| --- | --- | --- |
| [gradle-wrapper](https://github.com/gradle/gradle) | `9.5.1` | `9.6.1` |
| androidx.compose:compose-bom | `2026.05.01` | `2026.06.01` |
| androidx.core:core-ktx | `1.18.0` | `1.19.0` |
| androidx.lifecycle:lifecycle-runtime-ktx | `2.10.0` | `2.11.0` |
| [org.commonmark:commonmark](https://github.com/commonmark/commonmark-java) | `0.28.0` | `0.29.0` |
| [org.commonmark:commonmark-ext-autolink](https://github.com/commonmark/commonmark-java) | `0.28.0` | `0.29.0` |
| [org.commonmark:commonmark-ext-gfm-strikethrough](https://github.com/commonmark/commonmark-java) | `0.28.0` | `0.29.0` |
| [org.commonmark:commonmark-ext-gfm-tables](https://github.com/commonmark/commonmark-java) | `0.28.0` | `0.29.0` |
| [org.commonmark:commonmark-ext-task-list-items](https://github.com/commonmark/commonmark-java) | `0.28.0` | `0.29.0` |
| [org.junit.vintage:junit-vintage-engine](https://github.com/junit-team/junit-framework) | `6.1.0` | `6.1.1` |
| [io.kotest:kotest-assertions-core-jvm](https://github.com/kotest/kotest) | `6.1.11` | `6.2.1` |
| [io.kotest:kotest-runner-junit5-jvm](https://github.com/kotest/kotest) | `6.1.11` | `6.2.1` |
| [com.squareup.okhttp3:mockwebserver](https://github.com/square/okhttp) | `5.3.2` | `5.4.0` |
| [com.squareup.okhttp3:okhttp](https://github.com/square/okhttp) | `5.3.2` | `5.4.0` |



Updates `gradle-wrapper` from 9.5.1 to 9.6.1
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](https://github.com/gradle/gradle/compare/v9.5.1...v9.6.1)

Updates `androidx.compose:compose-bom` from 2026.05.01 to 2026.06.01

Updates `androidx.core:core-ktx` from 1.18.0 to 1.19.0

Updates `androidx.lifecycle:lifecycle-runtime-ktx` from 2.10.0 to 2.11.0

Updates `org.commonmark:commonmark` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.commonmark:commonmark-ext-autolink` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.commonmark:commonmark-ext-gfm-strikethrough` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.commonmark:commonmark-ext-gfm-tables` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.commonmark:commonmark-ext-task-list-items` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.commonmark:commonmark-ext-autolink` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.commonmark:commonmark-ext-gfm-strikethrough` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.commonmark:commonmark-ext-gfm-tables` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.commonmark:commonmark-ext-task-list-items` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.28.0...commonmark-parent-0.29.0)

Updates `org.junit.vintage:junit-vintage-engine` from 6.1.0 to 6.1.1
- [Release notes](https://github.com/junit-team/junit-framework/releases)
- [Commits](https://github.com/junit-team/junit-framework/compare/r6.1.0...r6.1.1)

Updates `io.kotest:kotest-assertions-core-jvm` from 6.1.11 to 6.2.1
- [Release notes](https://github.com/kotest/kotest/releases)
- [Commits](https://github.com/kotest/kotest/compare/6.1.11...6.2.1)

Updates `io.kotest:kotest-runner-junit5-jvm` from 6.1.11 to 6.2.1
- [Release notes](https://github.com/kotest/kotest/releases)
- [Commits](https://github.com/kotest/kotest/compare/6.1.11...6.2.1)

Updates `io.kotest:kotest-runner-junit5-jvm` from 6.1.11 to 6.2.1
- [Release notes](https://github.com/kotest/kotest/releases)
- [Commits](https://github.com/kotest/kotest/compare/6.1.11...6.2.1)

Updates `com.squareup.okhttp3:mockwebserver` from 5.3.2 to 5.4.0
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-5.3.2...parent-5.4.0)

Updates `com.squareup.okhttp3:okhttp` from 5.3.2 to 5.4.0
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-5.3.2...parent-5.4.0)

Updates `com.squareup.okhttp3:okhttp` from 5.3.2 to 5.4.0
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-5.3.2...parent-5.4.0)

---
updated-dependencies:
- dependency-name: androidx.compose:compose-bom
  dependency-version: 2026.06.01
  dependency-type: direct:production
  dependency-group: android-deps
- dependency-name: androidx.core:core-ktx
  dependency-version: 1.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: androidx.lifecycle:lifecycle-runtime-ktx
  dependency-version: 2.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: com.squareup.okhttp3:mockwebserver
  dependency-version: 5.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: com.squareup.okhttp3:okhttp
  dependency-version: 5.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: com.squareup.okhttp3:okhttp
  dependency-version: 5.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: gradle-wrapper
  dependency-version: 9.6.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: io.kotest:kotest-assertions-core-jvm
  dependency-version: 6.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: io.kotest:kotest-runner-junit5-jvm
  dependency-version: 6.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: io.kotest:kotest-runner-junit5-jvm
  dependency-version: 6.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark-ext-autolink
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark-ext-autolink
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark-ext-gfm-strikethrough
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark-ext-gfm-strikethrough
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark-ext-gfm-tables
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark-ext-gfm-tables
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark-ext-task-list-items
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.commonmark:commonmark-ext-task-list-items
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.junit.vintage:junit-vintage-engine
  dependency-version: 6.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: android-deps
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(android): compile dependencies against API 37

* chore(android): refresh native i18n inventory

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 08:00:55 +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
Josh Avant
531c7a5f4c
fix(android): preserve hardware Enter key sequences (#101360) 2026-07-07 00:25:33 -05:00
Peter Steinberger
5d7a451b15
fix(tests): reorder initializer arguments so the shared-kit test module compiles (#101372) 2026-07-07 06:25:06 +01:00
Peter Steinberger
b337164916
ci: fail Android PRs on ktlint formatting drift (#101275)
* style(android): fix ktlint drift in ShellScreen.kt

Formatting drift landed via #101161; :app:ktlintCheck fails on main
without this. Generated with ./gradlew :app:ktlintFormat.

* ci(android): add ktlint lane to the Android CI job

Android formatting drift kept landing on main because CI never ran
ktlintCheck (see the #100304 manual sweep). Adds an android-ktlint
matrix lane mirroring pnpm android:lint.

* chore(i18n): sync native inventory after ShellScreen.kt format

The ktlint format fix shifted line numbers tracked in
apps/.i18n/native-source.json; regenerated via pnpm native:i18n:sync.

* style(android): fix new ktlint drift in NodeRuntime and ChatHardwareKeyTest

Import-order/blank-line drift landed via the hardware-Enter changes
(#101321 and follow-up) while this PR was open — the exact recurrence
the new android-ktlint lane prevents. Generated with ktlintFormat;
native i18n inventory resynced for the shifted line numbers.
2026-07-07 05:01:26 +01:00
Yuval Dinodia
7900ff4731
fix(macos): preserve device identity storage (#101105)
* fix(macos): preserve device identity storage

Avoid selecting App Group identity storage when the running app lacks the matching application-groups entitlement, so unentitled macOS builds fall back to the legacy writable identity directory. Existing unrecognized identity files are now preserved instead of being replaced by a newly generated identity, matching the no-overwrite behavior already used for recognized invalid identity data.

* fix(macos): repair identity CI coverage

Limit the App Group entitlement probe to macOS builds so iOS keeps its existing App Group path behavior. Update the state-dir identity regression to assert the new no-overwrite contract for invalid identity-shaped files.

* fix(macos): migrate existing app group identity on legacy fallback

Unentitled macOS builds now migrate a readable App Group device identity
into the selected legacy store before falling back, so an upgrade preserves
the existing device id instead of minting a new one.

* fix(macos): migrate device auth store with identity on app group fallback

The app group to legacy identity migration now carries the sibling
device-auth store file, so an unentitled build keeps its stored device
tokens (keyed by the migrated deviceId) instead of re-pairing. The
process-immutable entitlement check is resolved once per process rather
than creating a SecTask on every state-dir lookup, and the migration
source API returns an identity+auth pair struct.

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 04:49:46 +01:00
Vincent Koc
de8db74058
fix(android): handle hardware enter in chat sheet 2026-07-07 05:48:25 +02:00
Peter Steinberger
780ca1d253
fix(android): send chat with hardware Enter (#101321) 2026-07-07 04:36:06 +01:00
Blaine Perry
06c18e232d
feat(android): add chat agent selector (#80422)
* feat(android): add live chat agent selector

Co-authored-by: Blaine Perry <blainecperry@gmail.com>

* fix(android): keep agent selector on canonical session

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 04:14:55 +01:00
Peter Steinberger
ad833d7883 fix(protocol): regenerate swift curator models 2026-07-06 22:52:15 -04: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
b2cecd8ece
feat(android): hide thinking control and gate sends for models without reasoning support (#101002) 2026-07-07 03:23:08 +01:00
Vincent Koc
7bbe75089a
test(android): isolate gateway bootstrap prefs 2026-07-07 03:35:58 +02:00
Colin Johnson
82106a18b3
fix(android): stabilize recent sessions overview (#101161) 2026-07-06 21:20:06 -04:00
Peter Steinberger
bb658d0a6d
feat(macos): redesign chat window as native shell with sessions sidebar, toolbar pickers, slash commands, and context usage (#101103)
* feat(chat-ui): native macOS chat window shell with sessions sidebar, context usage, and slash commands

* feat(macos): host redesigned chat window shell and complete gateway chat transport

* fix(chat-ui): gate slash panel on catalog support and register window shell shortcuts outside menus

* fix(chat-ui): make sidebar selection tags optional and sync programmatic composer text into the focused NSTextView

* fix(macos): track in-window session switches for chat window reuse

* fix(chat-ui): re-bootstrap in place when deleting the active main session

* docs(macos): describe the redesigned native chat window

* fix(macos): scope bare global session RPCs to the routing default agent

* style(chat-ui): restore blank line between rebased helpers

* fix(macos): scope selected global session actions

* fix(macos): refresh chat routing identity

* fix(chat-ui): hide delete for main sessions

* fix(macos): remove duplicate session patch path

* fix(chat-ui): resolve sidebar session aliases

* fix(chat-ui): isolate sidebar alias resolution

* fix(chat-ui): reconcile active session aliases

* fix(chat-ui): prefer selected session aliases

* chore(i18n): refresh chat window inventory

* fix(chat-ui): return sidebar filter result

* refactor(chat-ui): split session actions
2026-07-07 02:06:10 +01:00
WhatsSkiLL
4b3941c7f2
fix(android): tune screenshot mode visual sizing (#100895)
* fix(android): tune screenshot mode visual sizing

* chore(android): refresh screenshot i18n inventory

* refactor(android): simplify screenshot mode sizing

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 02:01:02 +01: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
WhatsSkiLL
bce414d8b8
improve(android): align command palette row affordances (#101072)
* android: tidy command palette row affordances

* docs(android): credit command palette polish

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 01:14:46 +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
2b3a985b11
chore(i18n): refresh native source inventory (#101232) 2026-07-07 00:58:03 +01:00
Peter Steinberger
054e3675e1
feat(android): publish signed APKs with stable releases (#101212)
* feat(android): publish signed release APKs

* fix(android): preserve fallback corrections

* test(android): isolate APK signer fixtures

* docs: refresh generated docs map
2026-07-07 00:39:59 +01:00
Peter Steinberger
c5161f96ce
fix(macos): keep onboarding green across gateway plugin restart (#101218)
* fix(macos): keep onboarding green across gateway plugin restart

Activating the Codex candidate installs the codex plugin and the gateway
restarts itself to load it, dropping the activate RPC socket after the
server already persisted success. Onboarding then claimed every option
failed. Reconcile transport drops against crestodian.setup.detect before
reporting failure, and stop latching the finish-page skills load error
that fires while the pager pre-builds pages before the gateway exists.

* chore(i18n): refresh native inventory line numbers
2026-07-07 00:32:34 +01:00
Peter Steinberger
91d4e8ed8e
feat(apple): session search, archived browsing, and sheet management actions (#101053)
The shared chat session sheet (iOS chat + macOS webchat) gains server-backed
search (sessions.list search param, 250ms debounce, cancellation-safe local
fallback when offline), an Active/Archived scope, swipe/context actions for
pin/rename/archive with optimistic updates and rollback, pin indicators, and
restore-on-open for archived rows. Archiving the open session switches back
to the main session so the composer never points at a send-rejecting session.

OpenClawChatTransport consolidates the two list requirements into canonical
listSessions(limit:search:archived:) with forwarding sugars (unreleased
internal API; all in-repo conformers updated: iOS gateway transport, demo and
fixture transports, previews, macOS webchat, test fakes). macOS webchat also
implements patchSession, giving the sheet's controls a live transport there.

OpenClawChatSessionEntry becomes var-based and gains pinnedAt/archivedAt;
the two full-init rebuild blocks in ChatViewModel collapse to copy-mutation
(the pattern that silently dropped newly added fields), preserving main's
model-identity/thinking-metadata semantics. A shared session list organizer
mirrors gateway ordering (pinnedAt desc, updatedAt desc, key) for cached and
offline lists, and pinned sessions survive the 24h recency cutoff in the
session picker.

Refs #100712
2026-07-07 00:28:38 +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
93eaf5affb
feat(android): server-backed session search with offline fallback (#101102)
The sessions screen gains a debounced search field under the filter pills,
wired to server-side sessions.list search in Recent and Archived scopes.
Results flow through the existing filter/sort/grouping pipeline so pinned
and grouped rendering stay intact while searching.

ChatController.fetchSessionList performs the one-shot search without touching
live list state, falls back to locally filtering the cached active list when
the gateway is unreachable (archived rows exist only server-side, so archived
search is empty offline), and rethrows CancellationException before the
fallback so a superseded search never repaints stale rows over a newer query.

Refs #100712
2026-07-07 00:03:28 +01:00
Peter Steinberger
ef1767baca
feat(android): record and send voice notes from the chat composer (#101193)
* feat(android): record and send voice notes from the chat composer

Adds tap-to-record voice notes to both Android chat composers: MediaRecorder
AAC/m4a mono capture with a 3-minute cap, lazy RECORD_AUDIO permission,
cancel/finish controls, audio attachment chips with duration, and voice-note
transcript rows. Recording is mutually exclusive with MicCaptureManager voice
capture (no mic arbiter exists), and the MPEG-4 container brand is normalized
to M4A so gateway byte sniffing classifies the upload as audio, not video.
Attachments stay online-only per the outbox contract.

Related: #100709

* fix(android): coordinate voice note microphone ownership

* chore(android): refresh native localization inventory
2026-07-06 23:54:44 +01:00
Peter Steinberger
66c764b269
feat(ios): tap-to-expand link previews in chat transcript (#101198) 2026-07-06 23:47:33 +01:00
Peter Steinberger
4babbb2f6f
feat(ios): context-window usage indicator in the chat composer (#101183) 2026-07-06 23:43:19 +01:00
Peter Steinberger
d931839e0c
feat(android): multi-gateway registry, per-gateway credentials, and switching (#100947) 2026-07-06 23:31:49 +01:00
Peter Steinberger
b05001a68b
fix(android): prevent native channel notification duplicates (#101170) 2026-07-06 21:12:08 +01:00
Peter Steinberger
80537c1ba4
feat(macos): load provider catalog during AI onboarding (#101132)
* feat(macos): load onboarding providers from gateway

* test(crestodian): widen setup config mock

* fix(crestodian): satisfy onboarding lint gate

* chore(macos): refresh onboarding localization inventory

* test(plugins): cover guided Copilot secret metadata
2026-07-06 20:57:56 +01:00
Peter Steinberger
2638113c68
feat(android): add Listen action speaking assistant messages via gateway TTS (#100772)
* docs(android): document the chat Listen action

* feat(android): add Listen action for assistant messages
2026-07-06 20:30:54 +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
Vincent Koc
70add7d31e
fix(android): restore lint validation (#101081) 2026-07-06 11:57:28 -07:00
github-actions[bot]
01465340f6 chore(i18n): refresh native locales 2026-07-06 18:53:27 +00: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
github-actions[bot]
a9b0a9a12b chore(i18n): refresh native locales 2026-07-06 17:57:37 +00:00
Peter Steinberger
c4c4caadfe
fix(android): clarify SMS command authorization (#100993) 2026-07-06 18:36:05 +01:00
Colin Johnson
9c2bbd0750
fix(android): stabilize chat refresh loading (#100966) 2026-07-06 13:33:05 -04:00
Peter Steinberger
f8307bb44c
style(android): apply ktlint to landed changes (#100304)
* style(android): apply current ktlint fixes

* style(android): format current app sources

* style(android): refresh native i18n inventory
2026-07-06 18:26:47 +01:00
Peter Steinberger
553acdfc1a
feat(gateway): add tts.speak method returning synthesized audio inline (#100770)
* feat(gateway): add tts.speak method returning synthesized audio inline

* test(gateway): type tts.speak synthesis mock for failure shapes

* fix(gateway): restore lowercase normalizer import used by talk catalog

* test(gateway): shift advertised-method window for tts.speak

* fix(gateway): ready tts speak for landing

* docs(changelog): record tts speak gateway API

* test(agents): stabilize fast auto startup synchronization

* test(crabbox): stabilize sparse checkout exit guard
2026-07-06 18:25:08 +01:00
Peter Steinberger
d0dd18dd7f
feat(android): richer Settings About screen with mascot hero and project links (#100994) 2026-07-06 18:10:50 +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
5b5a540e34
feat(android): per-gateway custom headers for gateways behind authenticating proxies (#100765)
* feat(android): 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:
EncryptedSharedPreferences-stored per endpoint stableId, masked in the manual
connection UI, injected on the OkHttp WebSocket upgrade at connect time via a
provider so edits apply on the next reconnect without re-pairing. Reserved
handshake headers and non-printable-ASCII are sanitized out (OkHttp throws on
them). TLS fingerprint pinning and pairing flows unchanged. Cross-gateway
isolation proven by MockWebServer upgrade-capture test.

Related: #100698

* chore(android): sync native i18n for custom header strings

* fix(android): harden gateway custom headers

* chore(android): resync native i18n inventory

* docs(changelog): defer Android release note

* fix(android): validate custom header names

* chore(android): refresh native i18n inventory
2026-07-06 17:48:57 +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
84f21bd9fc
feat(ui): clickable file links in chat with a workspace file viewer sidebar (#100679)
* feat(ui): link file paths in chat and add workspace file viewer sidebar

Auto-detect file paths in chat markdown (plain paths, path:line, inline
code, explicit/absolute links) and render them as clickable links that
open a dedicated file viewer sidebar with line numbers, highlight.js
syntax highlighting, scroll-to-line, in-file search, reveal-in-rail,
open-in-editor, and copy actions. Workspace rail browser entries are
now previewable even when the transcript never touched them;
sessions.files.get serves any file inside the workspace root with the
existing containment, symlink/hardlink, and size guards.

Closes #100615

* feat(ui): linkify file paths in sidebar markdown and fix file-view gutter width

Markdown rendered in the chat detail sidebar now gets the same clickable
file links as chat messages, opening files via the panel's own click
delegation. File viewer gutter uses a fixed per-file digit width so
short lines no longer indent their code past longer ones.

* fix(ui): keep browser-entry active highlight and narrow file content for editor open

loadWorkspace no longer clears the rail active marker for browser-only
entries, so Show in Files keeps the revealed file highlighted after the
forced reload. openInEditor narrows the sidebar content kind before use,
fixing the tsgo type error.

* chore(ui): fix lint findings in file viewer helpers

* fix(ui): harden workspace file previews

* fix(ui): wire file previews through chat panes

* fix(ui): preserve workspace file targets

* fix(ui): preserve workspace file targets
2026-07-06 17:47:28 +01:00
github-actions[bot]
6b99fd9a94 chore(i18n): refresh native locales 2026-07-06 16:41:42 +00:00