Commit Graph

1406 Commits

Author SHA1 Message Date
Dallin Romney 972b0c4b84 chore(i18n): refresh native locales (#130270) 2026-08-26 12:25:53 -07:00
Peter Steinberger d001975d31 fix(android): require listener access before forwarding notifications (#130173)
* fix(android): require listener access before forwarding notifications

* test(android): use activity-local owner in notification settings test
2026-08-26 09:38:10 -07:00
Josh Avant e6ed7e30cc feat(audit): record session action decisions (#129093)
* feat(audit): record session action decisions

* fix(protocol): preserve session sharing client compatibility
2026-08-26 08:21:37 -07:00
Peter Steinberger ef95d8f55e feat(secrets): agent-requested credentials the model never sees (#129670)
* feat(secrets): agent-requested credentials the model never sees

The new main-session secrets tool lets the agent request a credential by
name: the human enters the value in a masked question card (Control UI,
/ask/<id> deep link, iOS/macOS/Android), and the gateway diverts the
answer straight into the shared secret store at question.resolve. The
record, broadcast, waitAnswer, tool result, transcript, and model context
only ever carry a synthetic stored marker.

- protocol: additive secretStore binding, secretStoreExisting replacement
  metadata, and resolve-time secretStoreAllowedHosts (since 2026.8)
- gateway: store-bound question validation, admin-gated minting (blocks
  questions-scope self-answer escalation past secrets.store.set), shared
  redaction-first store write service reused by secrets.store.set
- tool: secrets request/list/delete; write-only by design, delete carries
  verified agent runtime identity; channel delivery is link-only so chat
  text is never captured as a secret
- Control UI: masked composer card with requester identity, store banner,
  editable allowed hosts, replacement warning, retry-on-validation-error,
  a standalone /ask/<id> page, and a named startup-JS baseline bump
- mobile: SecureField / password transformation for isSecret questions,
  no answer echo in terminal summaries; new native string registered in
  the locale-refresh inventory (generated artifacts stay workflow-owned)
- regression: claimed harness secret input stays out of session transcripts

Live-proven on an isolated dev gateway: real model turn, masked entry via
Playwright, value present only in secret_store_entries, absent from every
transcript, log, and the DOM.

* chore(protocol): regenerate protocol models and tool display

* fix(cli): read image string options through a typed helper

PR #129463 added four commander option narrowings in image.ts without
SAFETY coverage, leaving the assertion-safety ratchet red (21 > 17) for
every branch on current main. Replace the casts with a typeof-checked
read so the assertions are removed rather than annotated; each value is
still validated by its normalizer. SAFETY comments cannot work in this
file: the ratchet's raw scanner never rescans template tokens, so
comments after the first substitution template are unreadable to it.

* chore(protocol): refresh Swift models against current main

* chore(i18n): re-baseline the native inventory on current main

* docs(secrets): state the default-on tool policy and how to disable it

* fix(secrets): tell the model what the store actually does

The shipped tool description named the three actions and nothing else,
and no parameter carried a description. The model could not tell that
request blocks a human, that reason is shown to that human, what secret
and env select, or - the silent-failure case - that a secret stored with
no allowedHosts can never be substituted, so a successful request could
produce a permanently unusable credential. Move the description to the
presets module beside ask_user and document every parameter.

* refactor(agents): share one blocking-question lifecycle between tools

ask_user and secrets each carried their own registration, wait, and
cancel logic, and they had diverged: ask_user recovers an answer that
lands between its wait timeout and the cancel, while secrets discarded
it and reported no_answer even though the Gateway had already stored the
credential. One shared canceller and answer reader fixes that race for
both, folds the two divergent gateway-call types into one, and drops two
type assertions in favour of the canonical record guard (ask_user's
assertion baseline shrinks 11 -> 8).

Net +49 production lines: the shared module costs more than the
duplication it removes, and buys the correctness fix plus a single owner
for question lifecycle.

* fix(ui): keep the allowed-hosts field readable as an input

Main's composer restructure moved the free-text input styling into the
option-row context, so the store-request hosts field - which sits outside
a row - lost its border and read as static text. It is the one field the
operator is meant to review and edit before releasing a credential, so
give it its own border and focus ring.

* fix(secrets): close two credential-boundary holes in agent requests

Requests are now protected-secret only. list renders env values, so an
agent could request kind=env, watch a human type it into a masked box
under a no-visibility promise, then read it straight back; the tool text
even claimed values are never returned. Environment values stay operator
-set in Settings or the CLI, where they are agent-readable by design.

Store-bound questions are also bound to the run that requested them. The
resolve path authorized only the answering client, so a terminated or
replaced agent run could still have a credential written on its behalf -
the recorded runId was provenance, not closure-bound authority. Minting
now requires a runId and resolution revalidates that exact live run
immediately before the store write, with no await in between, failing
closed as QUESTION_REQUESTER_INACTIVE.

Both reported by ClawSweeper as P1 credential-boundary findings.
2026-08-26 08:10:16 -07:00
Peter Steinberger c2e36eec94 fix(android): skip scoped IPv6 discovery addresses (#130165) 2026-08-26 07:52:24 -07:00
Peter Steinberger 8416469994 fix(android): preserve document attachments in offline chat history (#130163) 2026-08-26 07:43:14 -07:00
Peter Steinberger 4f563f21ac fix(android): honor low camera snapshot quality (#130160) 2026-08-26 07:30:55 -07:00
Peter Steinberger a73260a5c2 fix(android): preserve filenames for shared images (#130156) 2026-08-26 07:25:19 -07:00
RoboClaw 44d60a29e6 fix: preserve unread reminder for open sessions (#129386)
* fix: preserve manual unread markers in open sessions

* fix: distinguish explicit session reads

* fix(ui): gate unread contract on gateway capability

* perf(ui): keep server capabilities out of startup bundle

* test(gateway): keep agent fixtures roster-consistent

* fix(sessions): preserve legacy read compatibility

* test(gateway): type agent fixture configs

* fix(ui): remove unread gateway fallback

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

* test(infra): avoid fixed SSH tunnel port

* fix(ui): acknowledge unread after history commit

* docs: clarify unread upgrade boundary

* test(ui): drive mobile session menu by tap

* fix(ios): remove stale read reconciliation call

---------

Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-26 05:04:39 -07:00
Peter Steinberger 913ae20aeb fix(android): preserve photo library EXIF orientation (#129965) 2026-08-26 01:10:05 -07:00
Peter Steinberger d9506b2000 fix(android): preserve location opt-in during onboarding (#129961) 2026-08-26 01:05:36 -07:00
Peter Steinberger 36560c6a64 fix(android): restore attachment-only chat rewind and fork actions (#129951) 2026-08-26 00:45:55 -07:00
Peter Steinberger 144e4d5aeb fix(android): load chat media through gateway proxy paths (#129957) 2026-08-26 00:40:06 -07:00
Peter Steinberger 2941b3d779 fix(android): clean up cancelled camera recordings (#129948) 2026-08-26 00:22:31 -07:00
Peter Steinberger 7dcf0a54e9 refactor(android): reuse motion JSON parser (#129947)
Amp-Thread-ID: https://ampcode.com/threads/T-01a039f0-a030-77dc-8f5f-6efd2914415f

Co-authored-by: Amp <amp@ampcode.com>
2026-08-26 00:19:57 -07:00
Peter Steinberger fc64c5704a fix(android): preserve disconnected node gateway status (#129839) 2026-08-25 23:45:27 -07:00
Peter Steinberger 4048b57b7d fix(android): recover dropped gateway events (#129723) 2026-08-25 19:30:05 -07:00
Peter Steinberger c841a9958a fix(android): preserve notification forwarding consent (#129715) 2026-08-25 18:59:03 -07:00
Peter Steinberger 5af41d881e fix(android): preserve omitted image-only chat messages (#129711) 2026-08-25 18:34:23 -07:00
Vincent Koc 0036788055 refactor(android): reuse node JSON param parser (#120456) 2026-08-26 08:48:50 +08:00
WhatsSkiLL 771cd878dc feat(android): show session hierarchy in Threads (#128862)
* feat(android): show session hierarchy

* fix(android): surface collapsed descendant state

Worked on by:
- @Solvely-Colin

Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>

* fix(android): satisfy hierarchy CI gates

Worked on by:
- @Solvely-Colin

Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>
Co-authored-by: Colin Johnson <colin@solvely.net>
2026-08-25 19:46:31 -04:00
openclaw-mantis[bot] fe4554ade4 chore(i18n): refresh native locales (#129631)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-25 23:13:58 +00:00
Peter Steinberger d1b0b7732a fix(android): preserve captions when sharing multiple images (#129603) 2026-08-25 14:19:11 -07:00
ZYV5ge 43ffe41a4b fix(sessions): search visible categories across clients (#118912)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-25 14:15:52 -07:00
Peter Steinberger 52bce84ca9 fix(android): stop interrupted assistant audio and remove cached files (#129574) 2026-08-25 14:07:05 -07:00
Sasan e9620fba9d fix(gateway): usage.status no longer waits on provider HTTP (#121799)
* fix(gateway): refresh provider usage asynchronously

* fix(ui): report a stalled provider-usage refresh on Model Providers

The page observed the incomplete-usage marker but discarded the exhausted
outcome, so once the retry budget was spent it rendered ordinary provider
cards with no usage and no explanation — indistinguishable from providers
that report no usage at all. Keep the outcome and render the warning the
Usage page already owns, reusing usage.providerUsage.stalled rather than
minting a Model Providers key so no locale baseline churns.

A user-initiated refresh now restarts the retry budget. The notice tells the
operator to refresh, so the button has to hand back attempts to spend; only
the forced path resets it, or the budget could never exhaust.

Also fixes tsgo:core:test on the current head: createStore's inferred literal
had no usageStats, so the run-bookkeeping case could not stamp it, and
view.test.ts needed the new prop.

Closes the ClawSweeper P2 at model-providers-page.ts:169-175.

* fix(ui): keep the stalled usage notice when usage.status starts rejecting

loadModelProvidersData turned a rejected usage.status into providerUsage:
null, which the page read as a completed load. observe(false) then reset the
retry budget and cleared the stalled callout, so a permanently broken usage
endpoint rendered as ordinary cards with no usage and no explanation — the
same silent failure the callout was added to prevent. The reset also fired
mid-cycle: one incomplete response followed by one rejection restarted the
budget, so the notice could be deferred indefinitely.

Record the failure at its producer instead of inferring it downstream. A null
providerUsage also means "not loaded yet", and no caller can tell the two
apart, so load.ts now reports providerUsageFailed explicitly and the page
treats a failed read as unresolved rather than resolved-empty.

Found by a Codex review of 417d43b65d.

* revert(gateway): drop the opportunistic model-catalog fast path

It broke two chat.history tests on main — both assert the cold catalog loader
runs exactly once, and reading the prepared snapshot first means it never does.
checks-node-compact-small-10 was red for that reason.

The change was a separate-surface latency fix that this PR picked up in passing,
and the body already offered to split it. Dropping it is the honest resolution:
rewriting main's assertions to accommodate a drive-by optimization would trade
one concern's proof for another's convenience. optional-model-catalog.ts,
server-model-catalog-auth.ts and their test return to the merge-base.

This PR is now only the usage.status non-blocking contract and its clients.

* fix(usage): preserve incomplete retry state

* perf(ui): keep usage capability startup-neutral

* fix(ui): restore provider usage retry convergence

* fix(usage): restore retry and cache invariants

* fix(usage): stabilize provider convergence

* test(ui): exercise provider recovery path

* test(ui): remove stale usage route fixture field

* fix(macos): show provider usage errors

* fix(macos): bound usage retries per menu open

* fix(macos): end usage retries on menu close

---------

Co-authored-by: Josh Lehman <550978+jalehman@users.noreply.github.com>
2026-08-25 13:20:10 -07:00
Peter Steinberger bbfb7a9af0 fix(android): preserve background location during onboarding (#129543) 2026-08-25 13:16:20 -07:00
Peter Steinberger 7c790eedd8 fix(android): preserve contact display names without structured names (#129549) 2026-08-25 13:09:16 -07:00
Peter Steinberger 955d23d6b4 fix(android): preserve document-only chat messages (#129557) 2026-08-25 12:39:10 -07:00
WhatsSkiLL 0b867e14fe feat(android): unify agent and session pickers (#128309)
* feat(android): unify agent and session pickers

Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>

* chore:refresh-native-i18n-inventory

Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>

* fix:preserve-unknown-chat-agent-selection

Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>

* fix(android): keep unknown agent picker usable

Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>
Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-25 08:11:36 -04:00
Peter Steinberger 4dc7bb7411 chore(deps): refresh dependencies after seven-day cooldown (#129187)
* chore(deps): refresh dependencies after cooldown

* fix(gateway): emit append-only Responses content events

* chore(deps): retain unverified Sherpa runtime
2026-08-25 05:00:46 -07:00
Peter Steinberger 2464c5c637 fix(android): preserve photo orientation in chat images (#129136) 2026-08-25 01:29:33 -07:00
Peter Steinberger d1eead9e70 fix(android): preserve gateway context paths in control pages (#129087) 2026-08-25 01:07:02 -07:00
Peter Steinberger 50b3e4bc5b fix(android): keep unavailable SMS out of onboarding approval (#129077) 2026-08-25 00:35:01 -07:00
Peter Steinberger 0a04f23bc3 fix(android): select writable calendars for new events (#129055) 2026-08-24 23:53:07 -07:00
openclaw-mantis[bot] 61bc753da3 chore(i18n): refresh native locales (#128759)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-24 08:21:09 -07:00
Kaneki ca3c3db1af fix(android): preserve capture dates and requested photo resolution (#125550)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-24 06:39:43 -07:00
WhatsSkiLL fb576e3518 feat(android): group sidebar sessions (#128092)
* fix(android): group drawer sessions

* fix(android): isolate generated locale files

* fix(android): hide empty sidebar groups

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-08-24 06:34:42 -07:00
Peter Steinberger 0fbb5dd00e fix(android): normalize optional motion date ranges (#128734) 2026-08-24 06:29:54 -07:00
Peter Steinberger 898b1ce4b3 fix(android): fence canceled voice-note permission callbacks (#128733) 2026-08-24 06:23:17 -07:00
Peter Steinberger f90a9c720e fix(android): gateway accent color is fetched but never applied to the app theme (#128702)
* fix(android): apply the gateway accent color to the Claw design theme

The Android app fetched config.ui.seamColor into a StateFlow that no
Compose surface consumed, so gateway accents were silently dropped. The
accent now resolves with Control UI precedence (ui.prefs.accent over
ui.seamColor) and overrides the Claw accent/accentSoft/accentBorder
tokens in ShellScreen and OnboardingFlow; Material You system chrome is
untouched. With no gateway accent set the hardcoded ClawDark/ClawLight
palettes apply unchanged, replacing two mismatched hardcoded defaults.

* fix(android): invoke branding refresh on connect and match gateway accent precedence

ClawSweeper findings: refreshBrandingFromGateway had no call site (the
accent state stayed null), and a present non-string user accent must not
fall through to seamColor per the gateway's nullish selection. The
refresh now runs in the post-connection coroutine alongside wake-word
and exec-approval refreshes.
2026-08-24 05:42:56 -07:00
Peter Steinberger 234df15a6d chore: refresh dependencies after seven-day cooldown (#128414)
* build(deps): refresh dependencies after cooldown

Apply dependency, toolchain, action, image, and exact tool updates released by the inclusive 2026-08-16 seven-day cutoff. Adapt owner boundaries for the resulting CUA, logging, Teams, Markdown, native, and test-harness contract changes while retaining versions blocked by upstream compatibility constraints.

* fix(ui): align markdown renderer env typing

* fix(deps): align postcss and mistral peer contracts

* fix(deps): repair refreshed dependency contracts

* fix(deps): retain tslog startup budget

* fix(ci): verify Android tools with SHA-256

* fix(ci): fence Android SDK cache version
2026-08-24 03:01:54 -07:00
Peter Steinberger e834b355f2 fix(android): prevent expired subagent tasks from reappearing (#128612)
* fix(android): prevent expired subagent tasks from reappearing

Co-authored-by: 李琪0668001400 <li.qi16@xydigit.com>

* test(android): format subagent lifecycle assertions

* style(android): separate subagent lifecycle invariant comment

---------

Co-authored-by: 李琪0668001400 <li.qi16@xydigit.com>
2026-08-24 02:14:51 -07:00
Milton 9b2b195e10 fix(android): enforce location freshness across live updates (#128439)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-24 01:37:06 -07:00
Peter Steinberger 53dcaaedec feat(gateway): generic operator roles for non-maintainer access (#128548)
* feat(gateway): generic operator roles for non-maintainer access

Adds gateway.roles: named role bundles over a closed capability set —
sessions.others (none/view/suggest/write), an agents allowlist, and an
operator-scope ceiling. Roles are person-level (additive user_profiles.role
column, SQLite stays at v9); users.setRole (admin-only) assigns them. With
no gateway.roles config, behavior is unchanged for solo deployments.

Enforcement is deny-by-default from a host-minted actor identity
(system vs operator+profileId on server-only client.internal, never
accepted from the wire) and covers every entry point: WS RPCs, OpenAI-compat
and Responses HTTP, tools invocation, cron, questions, usage, task
suggestions, session catalog/sharing/reads. The agents allowlist gates both
session creation and run-start on existing sessions. Subagent completion
announce and descendant wake mint explicit system authority so role
boundaries never silently drop parent notifications.

The enforcement surface is expressed through a narrow policy vocabulary
(operatorSessionCap, hasOperatorBoundary, authorizeSessionSharing) rather
than per-handler policy internals.

* fix(gateway): heal PR CI after rebase onto main

- Break import cycles: extract GatewayOperatorRoleActor leaf contract; merge
  session-group-mutation-targets into session-sharing-target-input.
- Split sessions-suggestions.test.ts (max-lines) into a visibility suite.
- Add users.setRole to the 2026.8 train registry test and regenerate the
  Kotlin protocol client.
- Startup UNAVAILABLE gating now precedes session authorization: session
  stores are not loaded during startup, so authorization reads would deny
  with a misleading non-retryable error.
- sessions.assignOwner keeps its documented visibility-authorized contract
  when no operator role caps the caller; view/suggest-capped roles still
  cannot reassign foreign session ownership.
- Test stubs updated for main's socket readyState guard (#128144) and the
  system-authority arg on channel-native resets.

* test(gateway): chat.send pending-profile dispatch carries its required session target

chat.send requires a non-empty sessionKey at the protocol level; the mutation
pipeline now rejects targetless frames before profile-dependent dispatch, so
the pending-profile test must send a realistic frame.
2026-08-24 01:20:03 -07:00
Peter Steinberger 6530948812 fix(location): reject future-dated cached fixes (#128591) 2026-08-24 00:57:04 -07:00
Kaneki 444d79aea3 fix(android): normalize null calendar and contact write fields (#125527)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: 涧波 <jianbo@digitallifes.org>
2026-08-24 00:33:37 -07:00
hidenori-endo 10050cb07e fix(android): preserve channel sender labels across chat history (#119864)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-24 00:24:43 -07:00
Vincent Koc 9046ecea73 fix(talk): isolate cancellation ownership contract (#127186)
* fix(talk): isolate cancellation ownership contract

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): frame realtime relay output audio

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): confirm turn-bound provider cancellation

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): bind legacy iOS output cancellation

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): close cancellation ownership gaps

Drain dynamically arriving forced-consult results before terminal completion and validate legacy iOS cancellation responses against the active lifecycle.

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): require Android output identity for cancellation

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): bind Android cancellation to action turn

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* test(talk): align relay checks with current main

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): fence stale iOS output clear

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

---------

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>
2026-08-23 03:58:00 -07:00
openclaw-mantis[bot] 0978e27f9d chore(i18n): refresh native locales (#127681)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-21 20:00:27 -07:00