Commit Graph

5249 Commits

Author SHA1 Message Date
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
Peter Steinberger 8f2253497e fix(macos): cancelled Talk sessions can spin at full CPU (#129682)
* fix(macos): stop cancelled Talk silence monitors

* fix(macos): reuse cancellable periodic task owner
2026-08-25 18:26:43 -07:00
Josh Avant 1c37c8cdc7 fix(exec): scope reusable approvals to their working directory (#129636)
* fix(exec): bind durable approvals to working directory

* chore(apps): refresh native string inventory

* test(node-host): preserve prepared working directory

* fix(exec): use shared path safety facade

* fix(exec): revalidate approved directory identity
2026-08-25 18:24:14 -07:00
Peter Steinberger 84c469a76c fix(apple): bind widget snapshots to their document owner (#129666) 2026-08-25 17:59:47 -07:00
Vincent Koc 0036788055 refactor(android): reuse node JSON param parser (#120456) 2026-08-26 08:48:50 +08:00
Vincent Koc f457c2cea1 refactor(ios): share Agent Pro detail components (#119868)
* refactor(ios): share Agent Pro detail components

* test(ios): update Agent Pro i18n source contract
2026-08-26 08:41:06 +08:00
Peter Steinberger 6a246f70d1 refactor(state): retire six dead shared-state tables at schema v10 (#129626)
* refactor(state): retire six dead shared-state tables at schema v10

agent_model_catalogs, android_notification_recent_packages,
command_log_entries, diagnostic_stability_bundles, media_blobs, and
model_capability_cache landed with the database-first squash but their
runtime writers never reached main; every stable since v2026.6.10 created
them empty (agent_model_catalogs held only rebuildable catalog cache rows
until #111173 removed its writer). State schema 10 drops all six tables
and seven indexes through both the runtime-open and doctor migration
paths, records the retirements, bumps the native reader ceiling, and
corrects stale database-first doc claims that still named these tables
as canonical stores.

* test: move cross-lane schema-version pins to v10

The v10 retirement missed current-version pins outside src/state: the
native guard vitest wrapper, placement-move and node-worker-launch
same-version assertions, and the audit outbound-progress tripwire. The
pinned pre-C04 audit reader is a v9-era build that now refuses v10
databases by the version contract, so the test projects the file back to
the exact v9 shape with the documented 10-to-9 downgrade fixture before
the reader proof; the shared fixture also seeds the v10 retirement
regression.

* test: keep only the used downgrade fixture export
2026-08-25 17:31:32 -07:00
Vincent Koc 2671eff4bf refactor(ios): share voice permission support (#120176) 2026-08-26 08:30:06 +08:00
Josh Lehman 2dbaeef693 fix(ui): keep active commentary after session navigation (#129640)
* fix(ui): restore active commentary after navigation

* test(ui): wait for responsive activity layout
2026-08-26 00:27:41 +00: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
Peter Steinberger 473b4f19e3 feat(approvals): scoped standing grants make recurring cron automations approvable once (#129526)
* feat(approvals): mint scoped standing grants for cron allow-always

When an operator resolves allow-always for an approval raised by a cron
job's isolated run, the Gateway now mints a scoped standing grant in the
same SQLite transaction that resolves the approval, instead of writing an
unbounded command digest into the JSON allowlist. Subsequent occurrences
of that job execute the exact approved operation (command text, cwd, env
hash) without prompting while the grant revalidates against authoritative
rows: 30-day expiry, revocation, the cron job still existing with the same
config revision, and the minting approval row still holding allow-always
all fail closed back to the normal prompt. Non-cron allow-always behavior
is unchanged.

- New first-use lazy STRICT table operator_approval_standing_grants in the
  shared state DB (declared canonically, no schema-version bump; older and
  downgraded readers stay valid without it).
- The cron run owner records run -> {agent, job, config revision} in a
  process-local registry at run start; exec.approval.request stamps the
  cron source and exact operation binding onto the approval at creation,
  so nothing is ever inferred from session keys or run ids.
- The gateway exec host consults grants only when policy would prompt;
  ask=always, security=deny, mutable file operands, heredoc, strict
  inline-eval, and audit-suppression approvals keep prompting. Grant use
  updates last_used_at_ms/use_count and emits the exec approval security
  event with the grant and minting approval as lineage.
- Abort-wins guard: a run with an abort tombstone never mints.

* feat(approvals): deliver cron exec approvals to approval clients and wait inline

The standing-grant mint path was unreachable end-to-end: #128031 made
cron approval requests register with delivery fully suppressed, so the
shared owner expired them as no-approval-route within milliseconds, and
even a delivered card would have died seconds later when the isolated
run finalized on the approval-pending handoff and authority-close
cancelled the parked approval.

Cron approval requests now carry deliverToApprovalClientsOnly: the
shared delivery owner broadcasts them to connected websocket approval
clients (Control UI, TUI) but skips internal chat approval runtimes,
forwarder/iOS delivery, and turn-source routes, so the per-occurrence
chat spam #128031 removed stays removed. With no approval client
connected, the request still expires no-route into the existing
headless denial. The gateway exec host additionally waits inline for
cron-triggered approvals (the same treatment native chat channels got
in #93918), keeping the isolated run and its delegated authority alive
for the full approval window; cron jobs are single-flight, so at most
one card per job is pending at a time and allow-always ends the
recurrence by minting the standing grant.

Live-proven on a hermetic gateway: card delivered with ~30-minute
window, run waited 72s for the operator click, allow-always executed
the occurrence and minted the grant with no JSON allowlist digest,
the next occurrence ran promptless (use_count 1, no new approval row),
and editing the job failed closed back to a fresh prompt.

* chore(protocol): regenerate Swift models for deliverToApprovalClientsOnly

* fix(approvals): consume standing grants at the spawn boundary; keep node cron headless

Review findings from ClawSweeper on #129526:

- Grant authority is now recorded only at the final effect. The consult
  path validates without recording a use and returns a
  revalidateBeforeExecution closure (the mutable-file-binding seam) that
  consumes the grant immediately before runExecProcess; any invalidation
  during awaited pre-spawn work (job edit/delete, revocation, parent
  approval reversal) denies with next-step text instead of executing on
  stale authority. Regression proves consult leaves use_count at 0 and a
  reversed minting approval denies at the boundary.
- Cron approval-client delivery is scoped to host=gateway. Node-host cron
  cannot mint or consume grants yet, so it keeps the fully suppressed
  headless policy from #128031 instead of raising cards whose allow-always
  could not stick; node-host grant support stays a named follow-up.

* test(agents): complete plugin-metadata-snapshot mock factories

Five explicit vi.mock factories for current-plugin-metadata-snapshot.js
exported only getCurrentPluginMetadataSnapshot. Under isolate:false shard
composition the incomplete mock can bleed into siblings that import the
real module — model-resolution-consistency.test.ts failed on CI with
'No withPluginMetadataSnapshotScope export is defined on the mock'.
Spread importOriginal so every binding prod touches stays exported, per
the repo mock-factory rule; only the snapshot getter stays overridden.

* chore: drop accidentally committed pinned swiftlint binary; ignore .build/

scripts/install-swift-tools.sh installs pinned Swift tools into
.build/swift-tools per the lint-swift.sh remediation hint; the 36MB
binary must never ride a commit. Remove it and ignore the directory.

* test(agents): shield model-resolution-consistency from leaked snapshot mocks

The agents-embedded shard still failed after completing five factories:
~20 more test files across the repo mock current-plugin-metadata-snapshot
with incomplete explicit factories, and under isolate:false composition
any of them can strip withPluginMetadataSnapshotScope from this file's
imports. Give the victim a file-local identity mock (importOriginal
spread) that always wins, and revert the static-catalog factory edit that
tipped that grandfathered file over the max-lines cap — the repo-wide
factory completion belongs to a dedicated sweep.
2026-08-25 16:17:58 -07: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 18fba50e84 fix(linux): keep first-run onboarding alive when the gateway restarts (#129502)
* fix(linux): preserve onboarding through gateway restarts

* refactor(ui): keep model setup below file-size limit

* test: isolate plugin metadata and register startup retry coverage
2026-08-25 15:30:16 -07: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
Peter Steinberger c1150936c4 fix(linux): Quick Chat ignores the configured Gateway accent (#129451)
* fix(linux): sync quick chat accent with gateway preferences

* test(linux): cover live quick chat accent updates

* test(ci): avoid cold runtime discovery in focused fixtures
2026-08-25 14:06:20 -07:00
Peter Steinberger f4d067ec07 fix(macos): paused Gateway setup loses recovery after CLI installation (#129566)
* fix(macos): keep paused gateway onboarding recovery visible

* fix(macos): preserve native onboarding translation inventory
2026-08-25 13:20:43 -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 55aa0480eb fix(macos): honor remote gateway choice during onboarding (#129572) 2026-08-25 13:16:38 -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 482fbdc161 fix(macos): prefer supported version-manager Node runtimes (#129564) 2026-08-25 12:39:44 -07:00
Peter Steinberger 955d23d6b4 fix(android): preserve document-only chat messages (#129557) 2026-08-25 12:39:10 -07:00
Peter Steinberger 1998fd8e0f fix(ios): preserve keyboard feedback during voice capture (#129462) 2026-08-25 10:22:24 -07:00
Peter Steinberger d050cf956b fix(macos): confirm closing onboarding during API key verification (#129447) 2026-08-25 10:09:21 -07:00
Peter Steinberger 830700d04b fix(macos): reject failing Gateway runtime probes (#129453) 2026-08-25 09:45:39 -07:00
Peter Steinberger 2a33d749e5 fix(macos): keep onboarding progress aligned with recommended setup (#129435) 2026-08-25 09:31:07 -07:00
Peter Steinberger 6ad7915c05 fix(macos): expose channel account failures in settings (#129400) 2026-08-25 08:55:22 -07:00
Peter Steinberger 9444aa5a0a fix(mac): skip network interfaces without an address (#129265) 2026-08-25 06:09:26 -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 22fa9f5786 fix(linux): first-run desktop onboarding automatically connects working AI (#129211)
* fix(linux): make desktop AI onboarding work automatically

* fix(linux): harden provider ownership and onboarding lifecycle

* test(ui): document partial onboarding context fixture

* fix(linux): preserve operator-owned onboarding API keys

* fix(linux): retire previously managed provider credentials

* fix(linux): retain rotated onboarding provider credentials
2026-08-25 04:47:35 -07:00
Peter Steinberger d632304dc4 fix(ios): retire stale foreground gateway health probes (#129194) 2026-08-25 02:59:27 -07:00
Peter Steinberger 7a5de93228 refactor(apple): share chat payload normalization (#129113)
Amp-Thread-ID: https://ampcode.com/threads/T-01a037b7-9244-7298-b368-3faab8a11cbf

Co-authored-by: Amp <amp@ampcode.com>
2026-08-25 02:54:40 -07:00
Peter Steinberger 2464c5c637 fix(android): preserve photo orientation in chat images (#129136) 2026-08-25 01:29:33 -07:00
Vitor Cepeda Lopes de969db2c3 fix(macos): make OpenClaw settings pane responsive (#128177) 2026-08-25 01:27:34 -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 0528f44ce4 fix(ios): settle expired background refreshes exactly once (#129097) 2026-08-25 00:35:51 -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
Peter Steinberger e861bf2cee fix(ios): report no data for throttled silent pushes (#129026) 2026-08-24 23:16:47 -07:00
Peter Steinberger 058a72fe66 fix(update): bind managed handoffs to exact targets (#128868)
* fix(update): bind managed handoffs to exact targets

* fix(update): preserve campaigns on target mismatch

* fix(update): fence active campaign updates
2026-08-24 17:01:11 -07:00
Vincent Koc e27433c22e improve(ci): shard iOS screenshot capture (#128460)
* perf(ci): shard iOS screenshot capture

* fix(ci): bind iOS screenshot shard evidence

* fix(ci): preserve screenshot capture attempts

* fix(ci): align screenshot shards with Xcode 26.6

* fix(ci): provision screenshot shard Fastlane

* fix(ci): normalize Fastlane provenance version

* fix(ci): select installed Fastlane version
2026-08-24 16:59:06 -07:00
Vitor Cepeda Lopes b71a09fd8a fix(macos): return paired-node Codex catalogs without native supervision (#126811)
* fix(macos): route Codex catalog to plugin worker

* fix(macos): freeze Codex catalog ownership per invoke

---------

Co-authored-by: Josh Lehman <550978+jalehman@users.noreply.github.com>
2026-08-24 16:24:27 -07:00
ClawSweeper a5b5920444 feat(ui): configure capabilities before session start [AI-assisted] (#128081)
* feat(ui): configure capabilities before session start

Reuse the active-chat Plus menu on new sessions, move Draft into it, and persist admin-scoped tool overrides before the initial turn. Closes #128079.

* test(ui): follow new-session Draft menu

* refactor(ui): reconcile new-session capability ownership

* fix(ui): gate terminal launch on capability overrides

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

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-24 11:47:12 -07:00
Vincent Koc 88f417d328 fix(ci): pin iOS Fastlane toolchain (#128735)
* fix(ci): pin iOS Fastlane toolchain

* fix(ci): enforce locked iOS Fastlane path

* fix(ci): route iOS docs through bundle

* fix(ci): pin all documented iOS Fastlane commands

* fix(ci): make iOS bundle selection canonical

* fix(ci): enforce the locked iOS Fastlane path

* fix(ci): pin Bundler in iOS wrapper

* fix(ci): require the iOS Fastlane Gemfile

* fix(docs): pin direct iOS Fastlane bundle
2026-08-24 11:45:05 -07:00
Peter Steinberger 053b89d80f improve(ui): open short session links without extra lookup (#128778)
* perf(ui): remove short session route waterfall

* docs: clarify short link gateway requirement
2026-08-24 09:33:20 -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