Commit graph

914 commits

Author SHA1 Message Date
NianJiu
67be0cda44
fix: cancel Android link preview calls (#101853)
* fix: cancel Android link preview calls

* test(android): cover response cancellation stage

* fix(android): preserve link preview deadline

* docs(android): clarify cancellation contract

---------

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-09 09:21:50 +01:00
dependabot[bot]
75848adb8c
chore(deps): bump androidx.test.uiautomator:uiautomator in /apps/android (#101501)
Bumps androidx.test.uiautomator:uiautomator from 2.4.0-beta02 to 2.4.0.

---
updated-dependencies:
- dependency-name: androidx.test.uiautomator:uiautomator
  dependency-version: 2.4.0
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-09 08:29:17 +01:00
Ben.Li
3e787f3187
fix(android): preserve UTF-16 boundaries in notification text (#102442)
* fix(android): keep notification text UTF-16 safe

* test(android): cover UTF-16 notification boundaries

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-09 08:11:32 +01:00
joshavant
644aea7050
chore(android): bump 2026.7.1 Play build 2026-07-09 02:04:56 -05:00
joshavant
f163f32f85
fix(android): make release screenshots deterministic 2026-07-09 01:32:13 -05:00
joshavant
17fafcc901
chore(android): prepare 2026.7.1 Play release 2026-07-08 02:47:55 -05: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
3d53ed7ed8
fix(android): keep cold-start gateway auto-connect from overriding explicit intents (#101799)
* fix(android): keep cold-start gateway auto-connect from overriding explicit intents

NodeRuntime's init-time auto-connect now atomically claims the first gateway
lifecycle intent (CAS 0->1) and stands down permanently when any explicit
connect/disconnect/switch intent already exists, so a late discovery emission
can no longer override a user decision. This was also the root cause of the
CI-only flakes in GatewayBootstrapAuthTest (refreshGatewayConnection_* at
:616/:627 and switchToUndiscoveredGateway* on PRs #101002/#101387/#101396).

GatewaySession.Connection.sendRequestFrame now starts its response watcher
with CoroutineStart.ATOMIC: disconnect teardown cancels connectionJob right
after failPending(), and a DEFAULT-start watcher still queued for dispatch was
cancelled without running, silently dropping the terminal UNAVAILABLE onError
owed to fire-and-forget callers (root cause of the flaky
GatewaySessionInvokeTest.disconnectReportsUnknownOutcomeForFireAndForgetRpc).

Tests neutralize runtime background work (cancel+join the runtime scope)
before arming the registry and scripting lifecycle steps, and add regression
coverage for the auto-connect intent claim.

Proof: refresh flake reproduced at iteration 1 under taskset -c 0,1 on a
Blacksmith Linux box; post-fix 3 pinned stress rounds (120/150 looped
iterations) plus full :app:testPlayDebugUnitTest (109 classes, 0 failures)
and :app:ktlintCheck green on the same box.

* chore(i18n): resync native inventory line positions after NodeRuntime edits
2026-07-07 18:51:46 +01:00
Vincent Koc
cd86107a10
refactor(android): remove superseded app surfaces (#101680) 2026-07-07 06:07:36 -07:00
Peter Steinberger
16348ddec3
feat(android): render LaTeX display math in chat via bundled KaTeX (#101435)
* feat(android): render LaTeX display math in chat via bundled KaTeX

* fix(android): preserve fallback for invalid math

* docs(changelog): note Android display math

* Revert "docs(changelog): note Android display math"

This reverts commit 40356286a30ac1a7208e10ca33e6501858c82578.
2026-07-07 11:57:24 +01:00
Peter Steinberger
903a09ab85
fix(android): bound link preview image cache (#101560) 2026-07-07 11:22:52 +01:00
Peter Steinberger
354a151544
feat(gateway): archive-gated session deletes give Android delete parity (#101522)
sessions.delete gains an explicit archivedOnly param (additive protocol
schema change, Swift models regenerated): with archivedOnly=true, the
dispatcher grants operator.write and the handler requires the target to
already be archived (archive-then-delete keeps destructive intent a
two-step action). Without the flag nothing changes: deletes require
operator.admin, so internal fallback/synthetic dispatch, subagent cleanup,
and CLI minting keep their admin contracts, and the session-kill HTTP
endpoint pins admin explicitly since it terminates live runs.

Android sends archivedOnly and offers Delete only on archived rows, where
its bounded (non-admin) operator session is now authorized; active rows
archive first. iOS/web connect with admin and keep unrestricted deletes.

Refs #100712
2026-07-07 10:52:53 +01:00
Peter Steinberger
6125dd95e6
feat(android): og:image thumbnails on link preview cards (#101396) 2026-07-07 10:42:03 +01:00
Peter Steinberger
9cd29dcb9a
test(android): stabilize saved gateway reconnect proof (#101519) 2026-07-07 10:30:14 +01:00
Vincent Koc
6799b5b3d4
refactor(android): remove obsolete global cache cleanup (#101470) 2026-07-07 01:19:17 -07: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
Josh Avant
531c7a5f4c
fix(android): preserve hardware Enter key sequences (#101360) 2026-07-07 00:25:33 -05: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
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
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
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
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
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
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
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
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
Vincent Koc
70add7d31e
fix(android): restore lint validation (#101081) 2026-07-06 11:57:28 -07: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
d0dd18dd7f
feat(android): richer Settings About screen with mascot hero and project links (#100994) 2026-07-06 18:10:50 +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
61a29a7836
feat(android): read-only workspace Files browser with preview and share (#100776)
* feat(android): add read-only workspace Files browser with preview and share

* fix(android): degrade malformed base64 image payloads to no-preview instead of crashing

* fix(android): keep workspace paths verbatim from the gateway

* test(android): cover the overview Files card in shell logic tests

* fix(android): reset workspace browser across agents

* fix(android): isolate workspace share exports

* docs(android): note workspace file browser

* chore(i18n): refresh Android Files inventory

* docs(android): refresh workspace files map
2026-07-06 17:14:38 +01:00
Peter Steinberger
255b7631e6
fix(android): keep chat model selection synchronized (#100985)
* fix(android): harden chat model selection

* fix(android): bound model metadata retries

* fix(android): preserve newer model selections

* chore: leave changelog to release workflow

* chore: sync native i18n inventory
2026-07-06 17:06:02 +01:00
Peter Steinberger
063eeb69f3
feat(android): support opt-in background location (#100967)
* feat(android): support background location

Co-authored-by: Iori Kojima <iori@iori.dev>

* chore(android): refresh native i18n inventory

* docs(android): move release note to app changelog

---------

Co-authored-by: Iori Kojima <iori@iori.dev>
2026-07-06 16:36:58 +01:00
Peter Steinberger
8582895ca7
fix(android): finish onboarding after permission reapproval (#100959)
* fix(android): finish onboarding after permission reapproval

* chore(android): sync onboarding i18n inventory
2026-07-06 16:13:48 +01:00
Peter Steinberger
d375d349c8
feat(android): add in-chat model picker with favorites and recents (#100798) 2026-07-06 15:54:19 +01:00
Peter Steinberger
cd25de98b1
feat(android): tap-to-expand link previews in chat transcript (#100898) 2026-07-06 15:02:26 +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
bc49cb41e9
fix(android): open system notifications on tap (#100888)
* fix(android): open system notifications on tap

* chore(android): sync notification i18n inventory
2026-07-06 14:14:29 +01:00
Peter Steinberger
876ab9bb0b
feat(android): add chat message actions (#100879)
* fix(android): add chat message actions

* chore(android): sync native i18n inventory

* fix(i18n): collect Android action labels

* fix(i18n): preserve Android placeholders
2026-07-06 13:50:16 +01:00
Peter Steinberger
90e1ef1768
fix(android): hide internal chat history rows (#100826)
* fix(android): hide internal chat history rows

* chore(android): sync native i18n inventory
2026-07-06 12:37:39 +01:00
Peter Steinberger
a467ceb523
fix(android): finish PTT relay handoff safely (#100786)
* fix(android): finish PTT relay handoff safely

* style(android): satisfy PTT ktlint

* test(android): make relay resume tests deterministic

* fix(android): recheck PTT finishing ownership

* chore(android): refresh native i18n inventory
2026-07-06 12:20:26 +01:00