Commit Graph

926 Commits

Author SHA1 Message Date
Peter Steinberger
1696366f88 feat(android): add safe cron job management (#102997)
* feat(android): add safe cron job management

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>

* fix(android): harden cron editor state

* fix(android): preserve cron state across lifecycle

* fix(android): satisfy cron release gates

* fix(android): retain cron drafts outside saved state

* fix(android): scope cron auto-delete to one-shot jobs

* fix(android): use Compose activity owner

* docs(changelog): note Android cron management

* fix(cron): harden Android job management

* chore(i18n): refresh Android cron inventory

* test(cron): cover enriched read views

* chore(changelog): defer Android cron note to release

---------

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
2026-07-10 04:12:18 +01:00
NianJiu
05d17289c9 fix(android): order disconnect after in-flight gateway work (#103068)
* fix(android): drain gateway events before disconnect callback

* chore(android): refresh native i18n inventory

* chore(android): refresh native i18n inventory

---------

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-10 01:51:51 +01:00
Peter Steinberger
c6d7088035 refactor(android): align talk levels and thinking state with iOS/macOS (#103130)
* refactor(android): align talk levels and thinking state with iOS/macOS

TalkAudioLevel.kt ports OpenClawKit's level scale exactly: PCM16 RMS
through the shared 50 dB window replaces mean-abs (mic/talk/playback)
and linear peak (voice notes), so Android waveforms read identically to
iOS/macOS at the same loudness. The waveform's Thinking phase now comes
from a typed awaitingAgent StateFlow set alongside every status change
in TalkModeManager instead of the UI matching status string literals;
forgetting the flag at a new status site fails safe to Listening/Idle.

* fix(android): keep awaiting-agent flag intact on no-op status republishes

* chore(i18n): resync native inventory
2026-07-09 23:59:12 +01:00
Peter Steinberger
af6a58a2ba refactor(android): remove orphaned sheet composer (#103094) 2026-07-09 21:25:22 +01:00
Ben.Li
1d4c17073c fix(android): keep link preview metadata UTF-16 safe (#102988)
* fix(android): keep link preview metadata UTF-16 safe

* refactor(android): share UTF-16-safe truncation

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-09 20:58:18 +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
d9f8fc6322 feat(android): add system app language selection (#102876)
Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
2026-07-09 15:27:36 +01:00
Vincent Koc
cb7468fc58 refactor(android): remove orphaned legacy screens (#102809) 2026-07-09 06:02:30 -07:00
Peter Steinberger
411bf2ad4b test(android): cover discovery and startup gates (#102758)
* test(android): cover discovery and startup gates

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

* test(android): keep startup gate tests keystore-free
2026-07-09 13:25:40 +01:00
Peter Steinberger
66db3024bc test(android): cover main activity lifecycle gates (#102764) 2026-07-09 13:04:57 +01:00
snowzlmbot
6fef79a28d feat(android): add Skill Workshop settings panel (#101911)
* feat(android): add Skill Workshop settings

* fix(android): scope Skill Workshop state by agent

* fix(android): confirm Skill Workshop proposal actions

* fix(android): strengthen Skill Workshop action proof gates

* fix(android): satisfy Skill Workshop action ktlint

* fix(android): serialize Skill Workshop lifecycle actions

* chore(android): refresh native i18n inventory

---------

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-09 12:07:04 +01:00
Josh
ff031149f3 chore: align Android icons with favicon mark (#101423)
* chore: align Android icons with favicon mark

* fix(android): keep launcher mark inside adaptive safe zone

* docs(changelog): note Android launcher icon refresh

* chore: keep release changelog unchanged

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-09 11:37:24 +01:00
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 40356286a3.
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