Commit Graph

3808 Commits

Author SHA1 Message Date
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
Peter Steinberger
0a488bd30b fix: device pairing floods stacked approval alerts for a retrying device and stale approvals no-op (#100976)
* fix(gateway): stop device pairing approval alert floods from retrying devices

A device retrying with a broken token minted a new pending requestId (and
approval alert broadcast) every 5-minute TTL window because refresh preserved
ts and expiry keyed on ts. Pending requests now stay alive via an internal
refreshedAtMs keepalive (ts still owns ordering/--latest), superseded device
requests broadcast device.pair.resolved like node pairing already did, and the
Mac app keeps one alert per device, closes superseded visible alerts, and
resyncs its queue when approving a stale request.

Closes #100974

* chore: satisfy swiftformat and refresh native i18n inventory for pairing prompter changes
2026-07-06 17:20:06 +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
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
github-actions[bot]
4c38d89c0c chore(i18n): refresh native locales 2026-07-06 16:02:42 +00:00
Peter Steinberger
30e5dfcf02 feat(gateway): read-only agents.workspace list/get browsing RPCs (#100738)
* feat(gateway): add read-only agents.workspace list/get browsing RPCs

* fix(gateway): gate workspace image reads on sniffed magic bytes, not extension

* fix(gateway): tighten workspace browsing boundary

* docs(gateway): clarify workspace read trust scope

* chore(gateway): leave release notes to release flow
2026-07-06 16:41:24 +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
github-actions[bot]
bdc98f482a chore(i18n): refresh native locales 2026-07-06 15:34:33 +00: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
538d4eeb77 feat(ios): hide thinking-level control for models without reasoning support (#100875) 2026-07-06 15:59:03 +01:00
Peter Steinberger
04b5d627a4 chore(swabble): stop tracking Package.resolved clobbered by Xcode resolution (#100961)
Xcode syncs the iOS project supergraph pins (ElevenLabsKit, WebRTC, cmark,
swift-markdown) into the local swabble package's Package.resolved on every
resolve, leaving permanent dirty-worktree noise. Match the existing
OpenClawKit convention: ignore the file. Reproducibility is unaffected -
swabble's only runtime dependency is exact-pinned (Commander 0.2.2) and CI
cache keys hash Package.swift + Sources, not this file.
2026-07-06 15:58:47 +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
83f0527724 feat(ios): word-paced fade-in for streaming assistant prose (#100884) 2026-07-06 15:50:58 +01:00
github-actions[bot]
9997c534b8 chore(i18n): refresh native locales 2026-07-06 14:24:16 +00:00
Peter Steinberger
cd25de98b1 feat(android): tap-to-expand link previews in chat transcript (#100898) 2026-07-06 15:02:26 +01:00
github-actions[bot]
52f1e05600 chore(i18n): refresh native locales 2026-07-06 13:58:53 +00:00
Peter Steinberger
8af88e2fcc fix(tests): restore shared-kit test module compilation after NSNull coalesce (#100903) 2026-07-06 14:56:34 +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
Vincent Koc
8b86645f5c fix(macos): keep node invokes responsive during system.run (#100842)
* fix(macos): keep app node connected after system.run invoke

* fix(macos): document node invoke receive isolation

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-07-06 05:06:34 -07:00
Vincent Koc
aabf68606a fix(macos): preserve launchd Node gateway in PortGuardian (#100867)
* fix(macos): preserve launchd Node gateway in PortGuardian

Co-authored-by: lsr911 <18230762+lsr911@users.noreply.github.com>

* fix(macos): tighten PortGuardian gateway matcher

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: lsr911 <18230762+lsr911@users.noreply.github.com>
2026-07-06 05:00:43 -07: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
f53346944d feat: correlate native search outcomes in audit history (#98704)
* feat: correlate native search outcomes in audit history

Metadata-only audit ledger for agent runs and tool actions in the shared
state DB: stable event identity, closed action/status/error vocabularies,
one-way-hashed tool-call ids, never-inferred terminal outcomes for native
web-search (explicit completed/failed only; otherwise unknown), bounded
retention, audit.list gateway RPC and openclaw audit CLI. Squashed from
the 82-commit audit stack for replay onto current main.

* feat(audit): add audit.enabled config gate (default on)

The metadata-only audit ledger records by default: an audit trail enabled
only after an incident cannot explain the incident, and the rows are
strictly less sensitive than the transcripts every install already
stores. audit.enabled=false stops new writes at the gateway subscription
seam; audit.list and openclaw audit keep serving existing records until
they expire. Documented in the configuration reference, protocol page,
and CLI reference.

* fix: repair full-matrix CI findings after rebase

- break the dynamic-tools/dynamic-tool-execution import cycle by
  extracting resolveCodexToolAbortTerminalReason into a leaf module
- restore main's session-worktree protocol exports lost in the
  index.ts auto-merge
- register the audit event writer worker as a knip entry point
- docs table formatting; subagent wait-cancellation test scoped to its
  audit intent (outcome + timing) and advanced past main's new
  lifecycle-timeout retry grace
2026-07-06 12:30:12 +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
Peter Steinberger
2a741bebb5 feat(ios): render LaTeX display math in chat via SwiftMath (#100829) 2026-07-06 12:14:38 +01:00