Commit graph

724 commits

Author SHA1 Message Date
Peter Steinberger
01e328528a
feat(macos): add Gateway hosting controls and Node migration (#161779) 2026-10-01 09:02:40 -07:00
Peter Steinberger
fffa1d0ac1
fix(macos): native tests leak spinning MLX reads and reconnecting Gateway channels (#162590)
TalkMLXSpeechSynthesizer races each stream read against a stall timeout with
AsyncTimeout, which cancels and abandons the losing read. The test fake's
nextEvent() busy-polled with Task.yield() and ignored cancellation, and its stale
modes never close, so every full suite run kept an orphaned read spinning a
cooperative thread for the rest of the process. The fake now stops waiting when
its read is cancelled, as the production stream transport does, and the
stale-stream-timeout test asserts the abandoned read retires.

Two GatewayChannelRequestTests never shut down their channel. Its 30 s watchdog
kept reconnecting through the test's start gate, and each attempt replaced the
parked continuation, printing 10-24 "wait() leaked its continuation" warnings
per run and accumulating parked connect tasks. Both tests now shut the channel
down, and the gate stays released so a late reconnect passes through.

The native-test doc records the rule: work a test starts must end with it.
2026-10-01 06:39:04 -07:00
Vincent Koc
9bf17b16a8
fix(macos): stop push-to-talk capture when its hold ends (#143064)
* fix(macos): stop push-to-talk capture when its hold ends

* fix(macos): remove unused push-to-talk key codes

* fix(macos): bind voice lifecycle to app-owned runtime

* style(mac): format voice runtime test catalog arguments
2026-10-01 12:59:11 +00:00
Peter Steinberger
1128a4ae92
feat(ios): snooze sessions from the session menu (#162399)
* feat(ios): snooze sessions from the session menu

Add shared calendar presets and identity-bound snooze/wake patches while preserving existing Swift transport call sites. iOS gains Active, Snoozed, and Archived scopes, wake labels, and deadline-driven updates for Sessions, the sidebar, and Overview. Snoozing keeps ongoing work and the open conversation intact.

* test(ios): capture session snooze proof states

Extend the synthetic Gateway with awake and snoozed sessions. Capture Active and Snoozed lists, snooze presets, and Wake through the real iOS session menu, using All Sessions navigation and a row selector that excludes the retained sidebar.

* fix(ios): show the weekday for the next-week snooze preset

* chore(ios): record snooze strings in the native i18n source inventory

* fix(ios): format snooze wake labels through the localized catalog

Apple i18n verification rejects runtime-interpolated localized strings
because they bypass the generated catalog, so the "Wake session" menu item
and the "tomorrow" wake description now use the repository's
String(format: String(localized: "… %@")) pattern, and the native string
inventory records the format sources.

* refactor(ios): drop the superseded mutation lease initializer

* fix(ios): keep snoozed sessions browsable offline

Separate cached browsing scopes from connected mutation controls. Keep Archived connected-only and reset an archived selection to Active on disconnect. Cover scope availability and the offline cached roster, including snoozed rows and wake labels.
2026-10-01 10:22:22 +00:00
Peter Steinberger
6e8b53a522
feat(android): show and place emoji reactions in native chat (#162307)
The native Android chat shows reaction chips under saved prompts and
replies (emoji, count, highlighted when the viewer reacted, TalkBack
lists who reacted) plus an add-reaction chip; tapping a chip toggles the
viewer's own reaction, and the add chip or message actions open a Quick
reactions sheet with the Control UI's palette plus "More…" for any single
emoji. Updates arrive live from the session.reaction event; nothing
notifies.

Reaction wire models are selected into the generated GatewayProtocol.kt,
the hello summary retains sessionCap, sessions carry sharingRole and
visibility, and ChatReactions.kt owns state, the permission projection
ported from the web's canReactToSession, the palette and the
single-grapheme rule. Writes run FIFO per message with per-emoji response
guards, list snapshots advance revisions so late set responses cannot
overwrite refreshed state, and message ids are canonical entry ids from
__openclaw.id. Generated locale artifacts are left to the refresh
workflow.

Proof: pnpm android:assemble, focused Robolectric/Compose tests (hello
summary, controller list/set/event/race regressions, chips/palette),
ktlint and Android lint, protocol and i18n checks, emulator before/after
screenshots in the PR, Codex branch review with its findings fixed.
2026-10-01 08:40:40 +00:00
Peter Steinberger
085fd8799b
fix(macos): stop native tests livelocking when provider setup overlaps readiness probes (#162317)
The provider wizard tests wrapped their bodies in ConcurrencyExtras'
withMainSerialExecutor, which installs a process-global enqueue hook while
Swift Testing runs other suites in the same process. A concurrently running
Gateway readiness fixture answered every handshake receive immediately, so
GatewayChannelActor.waitForConnectResponse spun on the main thread while the
AsyncTimeout wakeup that would cancel it sat behind it on the main queue.

Provider wizard actions now return the task that settles their reply, like
submitManualKey(), so the tests await the exact stale work instead of a global
executor drain. The readiness fixtures park their unanswered connect like a
real socket, and the AX inspection fixture records an issue if its detached
request ever runs on the main thread again.
2026-10-01 00:01:06 -07:00
Peter Steinberger
ca42a8bda3
feat(ios): show and place emoji reactions in native chat (#162296)
The native iOS chat shows reaction chips under saved prompts and replies
(emoji, count, highlighted when the viewer reacted, VoiceOver lists who
reacted), toggles the viewer's own reaction on tap, and offers "Add
Reaction" in the message long-press menu with the Control UI's quick
palette plus "More…" for any single emoji. Updates arrive live from the
session.reaction event; nothing notifies.

Reaction state is route-bound (ChatViewModel+Reactions): listed on load,
switch and reconnect, applied from events, written with stale-response
guards keyed by route, agent, session, session id, message id and a
per-message revision. The permission projection ports the web's
canReactToSession rule from hello role/scopes/sessionCap/methods and the
session sharing role; the viewer's profile id comes from presence or
users.self. Message ids are transcript ids from __openclaw.id, never local
row UUIDs or optimistic rows. Every row now carries the long-press menu
on every platform.

Proof: pnpm ios:build, 48 Xcode unit tests, 2 snapshot UI tests with
before/after screenshots in the PR, 14 shared Swift Testing cases,
swiftlint clean, protocol and native i18n checks, Codex branch review
clean.
2026-09-30 23:07:34 -07:00
Peter Steinberger
2fd8e321ba
feat(android): snooze sessions from the thread menu (#162293)
* feat(android): snooze sessions from the thread menu

Session rows now carry the Gateway's snoozedUntil/snoozedAt facts in the
hand-written ChatSessionEntry (parsed from sessions.list, merged from
sessions.changed with null receipts clearing them), and sessions.patch can
set a wake time or clear it with the session's expected identity. The
Threads page gains a Snoozed pill and long-press Snooze presets (In 1 hour,
In 3 hours, This evening, Tomorrow, Next week) or "Wake session" with the
wake time; Recent, Current, and the sidebar's recent list hide snoozed rows
until the wake instant, which the existing expiry scheduler now awaits.
The screenshot fixture gains a snoozed session so the owned-emulator lane
captures the states.

* fix(android): keep snooze strings in the native i18n source inventory

The native locale refresh workflow owns the generated string resources, so
the new snooze strings are recorded in apps/.i18n/native-source.json and
the generated NativeStringResources.kt / values/strings.xml are restored to
main; nativeString falls back to the source text until the refresh lands.
2026-09-30 20:38:08 -07:00
Peter Steinberger
271702bb8d
feat(macos): host the Gateway on bundled Bun (#161709)
* feat(macos): host the Gateway on bundled Bun

Prepare the bundled runtime inside each app profile and run fresh Gateways as app-owned children with readiness checks, bounded shutdown, and crash recovery. Keep terminal commands on the current shim while services pin matching concrete runtime, package, and SQLite builds. Reseed app-owned installations after updates and preserve operator runtime selections. Bundled onboarding no longer downloads Node or runs the CLI installer.

* fix(macos): preserve legacy app update retry receipts

* fix(macos): preserve Gateway update and service ownership

* fix(macos): preserve paused legacy Gateway service hosting

* fix(macos): defer service migration inspection to hosting controls

* fix(macos): revalidate service authority and admit runtime pin reads

* fix(macos): preserve legacy updater authority and older state reads

* fix(macos): preserve service ownership and paused intent

* fix(macos): bind service changes to retained ownership

Preserve a service when Pause cannot retain its command, and carry the originally selected service definition through install, uninstall, and restart dispatch. Surface refused teardown without overwriting a replacement service.

* test(macos): model active recovery and restorable services

Give onboarding a restorable managed Node command and isolate its retained state. Model an active, unpaused Gateway with matching listener and service ownership in recovery fixtures, and retire startup before teardown. Preserve the original recovery and cancellation assertions.

* test(macos): preserve ownership in pause fixtures

Use a restorable managed Node command and assert that Pause uninstalls only the managed service. Preserve the stopped-state and installation checks, model named-profile ownership, and restore retained preferences after the fixture.
2026-09-30 18:16:02 -07:00
Peter Steinberger
a83c49bf63
feat(macos): show online people and session viewers in the sidebar (#162022)
Render the self-inclusive Online roster, cross-agent owner counts, and other-viewer facepiles from the window-owned people model. Person cards use the existing Dashboard Activity handoff and keep visible recent-session identities stable while open. Keep iOS, palette behavior, and roster queries unchanged.
2026-09-30 11:21:08 -07:00
Peter Steinberger
96af591f74
feat(macos): align native sidebar rows with the web Control UI (#161973)
* feat(macos): align native sidebar rows with Control UI

Give macOS sidebar rows web-compatible titles, persistent channel labels,
leading unread and run state, critical subtitle precedence, safe session icons,
sharing and placement badges, and inline Pin and Archive/Restore actions.
Prefer supplied server message previews with the native cache as a fallback.
Keep child failure context, descendant unread, and workspace conflicts visible
on parents, and keep elapsed timing stable across metadata updates.

Preserve iOS and command-palette behavior through a macOS-only row projection
and eligibility policy. Retain the native disconnected-activity guard.
Attribution remains with the grouping lane; the menus lane can adopt the same
eligibility policy during integration.

Build on the sidebar extraction in #161538 and row decoding in #161589.

* fix(macos): use theme colors for native sidebar rows
2026-09-30 17:22:51 +00:00
Peter Steinberger
d7f8b2c3fd
feat(gateway): honor host lifetime and install ownership (#161583)
* feat(gateway): honor host lifetime and install ownership

* fix(codex): preserve hosted child process grouping

* fix(update): keep install kinds outside update check cycles

* fix(update): check retained recovery before install discovery

* fix(update): admit retained recovery before repair discovery

* fix(gateway): tolerate unavailable cwd during update admission
2026-09-30 06:33:45 -07:00
Peter Steinberger
16be7f0f27
feat(macos): run the private app runtime on the OpenClaw Bun fork (#161603)
* feat(macos): run the private app runtime on the OpenClaw Bun fork

* fix(macos): let the bundled runtime load unsigned plugin addons

* test(macos): remove obsolete worker pruning closure tests

* test(macos): drop stale packaging test imports

* test(macos): migrate CI scope cases to runtime paths
2026-09-30 01:27:03 -07:00
Peter Steinberger
bc6039c578
fix(macos): sign in to Access-protected dashboard embeds (#161474)
* fix(macos): sign in to Access-protected dashboard embeds

* fix(macos): prevent embedded Access sign-in loops

* fix(macos): preserve cookie blocking and detect rejected embeds

* test(macos): update sandbox navigation expectations for trusted embeds

* fix(macos): bind Access sign-in to dashboard embeds

* fix(macos): cancel embed sign-in for retired documents
2026-09-29 21:34:34 -07:00
Peter Steinberger
0703c215a4
fix: refuse incompatible Windows 9.4 schema upgrades (#160718)
* fix: refuse incompatible Windows 9.4 schema upgrades

Refuse shared-state migration during the shipped Windows 9.4 raw Doctor preflight while its recorded updater drivers have not positively stopped. Keep the existing delegated Doctor and 9.2 publication paths unchanged. Split manual recovery text so the shipped canary retains the reason and commands within its per-line capture limit. This contains the old callback failure; it does not complete automatic 9.4 updates.

* fix: refuse legacy Windows migration during package staging

* fix(update): load package lifecycle guard only at runtime
2026-09-29 02:59:38 -07:00
Peter Steinberger
0eb99b350e
fix(ios): gateway screenshot shows pairing prompt while connected (#160857)
* fix(ios): gateway screenshot shows pairing prompt while connected

The connected App Store screenshot fixture rendered Settings > Gateway as
"Connected / online" next to the red "Scan QR to Pair" first-run hero and an
empty "Pair a gateway" list, and Settings read the saved gateway registry and
manual-gateway credentials from the Keychain even under a local fixture.

NodeAppModel now owns the rule that local gateway fixtures (screenshot and
Apple Review demo mode) never read or expose saved gateways; the sidebar picker
and Settings both load the registry through it. Settings derives the active
entry from that registry instead of a second Keychain read, skips the
credential read under a fixture, and keys the pairing hero and the Paired
Gateways list off the same fixture predicate. The release settings screenshot
test now fails if the hero reappears.

* fix(ios): keep fixture Settings from overwriting saved gateway credentials

A local gateway fixture no longer loads the saved token/password pair, so
the blank credential fields could save over it: their bindings persist the
whole visible pair. Disable both fields while a fixture owns the connection,
and re-sync Settings when fixture mode changes so leaving a fixture reloads
the saved registry and credentials before the fields become editable.

The release settings screenshot test now also asserts, after capture, that
both credential fields are disabled under the fixture.

* fix(ios): hide saved manual Gateway settings under fixtures

Under a local gateway fixture, Settings derives the manual context path from
the fixture-empty registry, so Connect Manual could target the host's root
path and load another Gateway's credentials and trust. The disabled credential
fields also still sat on screen as dimmed rows.

Hide every control that acts on the saved manual Gateway while a fixture owns
the connection: the Manual Gateway card, the credential fields, and the Custom
Headers link, matching the hidden Paired Gateways list. Scan QR, setup codes,
and discovered Gateways carry their own route and stay available. The release
settings screenshot test now asserts at every scroll position that these
controls are absent.
2026-09-29 03:36:53 +00:00
Peter Steinberger
bc4a18ac08
fix(ios): preserve setup after bootstrap preparation refuses (#160218)
* test(ios): reproduce bootstrap setup refusal

* test(ios): target visible setup input after scrolling

* fix(ios): stop setup after bootstrap preparation refuses

* test(ios): retain release coverage after bootstrap proof
2026-09-28 09:25:24 -07:00
Peter Steinberger
733ceac1a7
fix(windows): discover Gateway Startup-folder launchers (#151674)
* fix(build): refuse dist rebuild under a live managed Gateway

Stop pnpm build and run-node auto-build from deleting hashed dist modules
while a managed Gateway ExecStart still points at this checkout.

* chore(build): drop unused fence message field

* fix(build): also fence direct tsdown and run-node rebuilds

Cover the cleanTsdownOutputRoots path and refuse early in run-node so
live managed Gateway dist cannot be wiped outside build-all.

* fix(build): keep live Gateway stop off the rebuild path

Dispatch gateway stop/restart from existing dist, apply --profile
before service inspection, and fence only physically overlapping
checkouts.

* fix(build): keep live dist fence off tsdown declaration graph

Load daemon inspection lazily so tsdown fixtures and plugin-sdk dts
generation do not import service-layout. Move run-node recovery tests
to a sibling file so the line-cap ratchet does not grow.

* fix(build): use import type for SpawnOptions in live-dist tests

* fix(build): dispatch source-only QA reports before the live dist fence

qa parity-report and qa coverage already run from source without
rebuilding private QA dist. Check that path before refusing a live
managed Gateway rebuild.

* fix(daemon): discover managed Gateway bindings across profiles

The live-dist fence needs every installed managed selector, not only the
current OPENCLAW_PROFILE. Reuse includeManagedOpenClaw scans and leave
findExtraGatewayServices semantics unchanged.

* fix(build): refuse live dist rebuild for every overlapping Gateway profile

A default-env build could still replace dist under a sibling profile
Gateway. Inspect all managed bindings, name offenders, and point operators
at stop or openclaw update.

* fix(daemon): keep managed Gateway binding discovery under lint limits

Move profile binding mapping out of inspect.ts, list managed services via
listManagedOpenClawGatewayServices, and use toSorted for profile naming.

* fix(build): keep live-dist refusal out of updater restore and system census

Propagate admissionRefused so update-gateway-build does not rm live output
roots after a pre-mutation fence refuse. Enumerate system-scope managed
units with explicit systemdReadTarget so user and system siblings both reach
the fence.

* test(build): pass a compare function to toSorted in the fence fixture

* fix(build): satisfy live-dist fence CI type, knip, and assertion gates

Treat toSorted comparators as possibly undefined, stop re-exporting the
unused binding type, and read launchd profile env through the record
owner instead of a type assertion.

* fix(daemon): inspect systemd template instances in the live-dist census

Discovered `openclaw@.service` files were forwarded as unit names, so the
fence queried a non-runnable template and fail-opened past a live instance
when a separate user Gateway was installed. Reuse the existing instance
resolution owner and cover user+system template inspection through the
service reader.

* fix(tooling): pin foreign-cwd tsconfig and clear CI gates

- pin TSX_TSCONFIG_PATH in the CLI shim only when the cwd lacks one, so
  fixture-spawned run-node.mts resolves workspace profile imports
- pass --import scripts/tsx.mjs to live-updater spawns and pin the
  tsconfig in run-node-lifecycle fixture envs (production loader parity)
- drop the unused systemd re-export for knip and move the template-
  instance test to service.systemd-scope.test.ts for the line cap

* fix(daemon): inspect registered Gateway services accurately

Read strict Windows service commands from registered actions and preserve
supported launcher encodings without treating dynamic CMD expansion as a
verified command. Retain exact task identity and bound systemd selection.

Use one platform inventory collector for the existing full and diagnostic
projections. Report incomplete inspection through Doctor while preserving
status JSON and the existing managed-service filters. Keep load-state
inspection behind a leaf capability instead of reverse facade imports.

Refs #151608, #151463.

* fix(daemon): classify service commands by position

Share runtime and root-option parsing so Node display names and profile values
cannot classify a Node service as a Gateway. Preserve literal shell, env and
generated launchd wrappers, and honor the executable selected by launchd.

Read systemd's single-quoted arguments through the existing parser and preserve
literal apostrophes when rendering. Keep strict Windows command rejection
separate from lenient diagnostics, and align the native-boundary fixtures with
that contract without weakening ownership or source-preservation assertions.

* fix(daemon): inspect direct registered task actions

Read literal executable actions from their registered Scheduled Task and
revalidate the action before returning command facts. Strict runtime inspection
uses the same registered command instead of a default launcher.

Keep executable paths out of managed launcher provenance. Direct actions remain
outside automatic update service management when no restorable CMD/VBS launcher
exists, preserving the prior stop and definition ownership boundary.

* test(windows): prove installed service upgrade paths

Extend the existing native Scheduled Task proof with verified immutable package
handoff and fixed fresh, published 2026.9.3, and published 2026.9.4 CLI cells.
Require live version/build identity, selected PID replacement, peer continuity,
strict registered-action inspection, and settled cleanup before evidence
publication and disposable installation retirement.

Keep source-only and repair modes, permissions, deadlines, and native lifecycle
owners intact. Direct executable fixtures remain disabled and preserve the
updater's unsupported-mutation boundary. Native execution remains pending.

* test(doctor): retain managed Windows launcher provenance

Keep the generated CMD path on the existing managed-service fixture before
and after reinstall so Doctor admission sees the installation it models.
Preserve all stop, install, restart, rollback, and direct-action refusal
expectations without changing production behavior.

* test(windows): exercise native autostart ownership boundaries

Extend the existing published-updater cell with its stopped, task-owned
Scheduled Task. Capture real admission, exercise native enable/disable,
and preserve the definition and files after foreign-owner refusal.

Test retained admission separately from restoration so legitimate same-root
refresh remains supported. Restore the original XML through the existing
fixture lifetime; do not broaden product control or workflow permissions.

Modeled owner tests, selected source checks, and independent review pass.
Actual Windows execution remains required before a native proof claim.

* test(windows): retain sanitized installed command failures

Keep unexpected command stdout and stderr in bounded failure diagnostics so
JSON-mode CLI errors survive native proof failures. Reuse the existing
terminal and support redaction owners before clipping; withhold incomplete
captures while preserving the existing truncation failure.

Move the existing command runner into its own test-support module and update
both consumers without changing timeout, exit, signal, or cleanup semantics.
Real-child regressions reproduce both privacy defects and pass with the
correction. The original installed Gateway failure remains undiagnosed.

* fix(daemon): preserve Windows probe budgets and Doctor cleanup eligibility

Use the existing cold PowerShell startup budget for Task Scheduler queries
without an explicit deadline. Keep periodic activation checks bounded and
preserve unknown results rather than treating timeouts as task absence.
The native probe test now exercises the production default.

Share Doctor's existing legacy cleanup classification with its registered
preview. Keep unsupported platforms, scopes and unrecognized Linux unit
names as findings without advertising removal or invoking unrelated cleanup.
Extract the classifier and complete cleanup test group without dropping
assertions or changing native mutation ownership.

Retain the failed installed Windows runs and their source identities;
new package and native upgrade qualification remain separate requirements.

* chore(daemon): retire stale Doctor size baseline

The split Doctor service module no longer needs a max-lines suppression.
Remove only its stale baseline entry so the shrink-only ratchet matches
actual source. Product, dependency, workflow and fixture bytes are unchanged.

* fix(build): keep native fixture import closures complete

Keep the legacy source-update transaction at its existing direct CLI call
site so native declaration-library consumers do not load its CLI-only source
resolver closure. Copy the exact PID helper inputs into the runtime fixture.

Use the real legacy-loader file URL in its existing subprocess invocation,
so execution and unused-file analysis share the same dependency reference.
Preserve all assertions, lifecycle guards and package runtime behavior.

Co-authored-by: Donnie Fiander <44792682+DonnieFi@users.noreply.github.com>

* test(windows): retain sanitized service proof observations

Record bounded install and status facts before semantic assertions so a
successful CLI exit cannot hide the native inspection reason. Exclude
free-form stderr and private response fields, and preserve existing
execution, deadline, and cleanup assertions.

* fix(windows): discover exact Startup Gateway launchers

Carry the focused Startup discovery changes from #151674 onto the current
service inventory owner. Preserve exact file identities, selected fallback
classification, Scheduler inspection failures, and published updater
fingerprints. Extend the existing installed Windows cells with read-only
Startup diagnostics and owned-file cleanup.

Focused local regressions pass, including Doctor failure on the original
collector and success with Startup discovery. Native Windows qualification
and the managed binding/fence integration remain pending.

* test(windows): retain safe installed-service observations

Retain allowlisted install/status JSON before strict semantic assertions,
without copying private response fields or opaque successful stderr.
Compose service observation and exact sibling-refusal checks through one
internal options record and migrate every test/support caller together.

Preserve native process cleanup, readiness assertions and command budgets.

Co-authored-by: Donnie Fiander <44792682+DonnieFi@users.noreply.github.com>

* test(update): isolate source updater fixture inputs

Give the synthetic compiler declared memory capacity through the existing
memory owner instead of inheriting competing CI workers. Keep real build
heap admission and all lifecycle assertions unchanged.

Use the established TypeScript loader for the Linux-only live-updater CLI
case so it reaches the platform refusal rather than failing during import.

Refs #152875. Retains the exact failing Linux CI evidence and contributor work.

Co-authored-by: Donnie Fiander <44792682+DonnieFi@users.noreply.github.com>

* fix(windows): preserve native status inspection defaults

Keep the CLI RPC default distinct from an explicit timeout so Windows
service inspection can use its existing cold-start budget. Forward
explicit load-query deadlines through the Task Scheduler owner while
preserving lifecycle defaults and timeout diagnostics.

* fix(windows): preserve native status inspection defaults

Keep the CLI RPC default distinct from an explicit timeout so Windows
service inspection can use its existing cold-start budget. Forward
explicit load-query deadlines through the Task Scheduler owner while
preserving lifecycle defaults and timeout diagnostics.

(cherry picked from commit 9c3bb9c32a)

* fix(daemon): remove inventory file-helper type cycle

* fix(models): retain discovered models after refresh failures

Record successful legacy catalog results at the producer boundary so unavailable refreshes retain the accepted inventory. Preserve explicit outcomes, advisory SDK fallback behavior, and first-discovery starter policy.

* fix(models): preserve skipped catalog outcome semantics

Mark bundled static, configured, and advisory catalog projections with
explicit empty outcomes so legacy success inference cannot promote them
to observed account inventory. Preserve live outcomes and helper types.

Keep exact auth provenance histories and move existing fixture/policy
code into focused owners where required by the line-cap ratchet.

Validation: 447 producer and sibling cases, 56 shared self-hosted cases,
95 auth/policy cases, causal missing-outcome failures, maintained checks,
and independent review.

* test(plugin-sdk): keep discovery loader types acyclic

Move the shared loader type into a leaf consumed by both discovery
contract helpers. Preserve its public provider-test-contracts export
without a child-to-parent type import cycle.

Validation: maintained Madge check reports zero cycles; core, all core
test graphs, extension test types, lint, formatting and independent
review pass. Runtime behavior and previous catalog proof are unchanged.

* fix(plugin-sdk): mark generated static catalogs explicitly

Keep the generated non-live, non-strict catalog adapter from claiming
successful acquisition for manifest or configured rows. Preserve null,
errors, strict and custom callbacks, static catalogs, and public types.

Validation: three existing controls fail before the correction; all49
owner and sibling cases pass afterward, with types, lint, line caps and
fresh independent review clean.

* fix(models): remove unlanded catalog outcome inference

* test(windows): handle omitted scheduled task settings

* test(windows): handle exported task defaults and reuse pinned packages

Preserve disabled-task and cleanup assertions when Task Scheduler omits default settings. Bind the package to its source commit and permit only the reviewed fixture paths to differ in tooling. Includes the canonical sharing-fixture retirement correction from cd2f12e (#158205).

* test(windows): retain installed proof before native cleanup

Persist settled commands and the original inspection failure before awaited cleanup. Prepare the existing compiled worker cache before each installed campaign and give installed Actions steps room for the unchanged native test and teardown bounds.

* test(windows): diagnose native probe context after cleanup

Compare read-only PowerShell probes under native and isolated OS contexts only after failed cold acceptance and verified cleanup. Preserve probe deadlines, process ownership, original results and package identity. Carry the canonical failure-only Gateway hook phase observer for the separate CI recurrence without claiming a causal repair.

* test(windows): record native module cache context

Retain only projected environment key names and module-cache path kind/hash so the diagnostic can distinguish an actual caller-selected cache from an absent one without recording values or changing launch behavior.

* test(windows): preserve native context in installed fixtures

Replace the duplicate OS environment filter with the existing native service projection and case-aware merge. Preserve caller-selected PowerShell module cache routing while retaining private application, temporary and npm paths and excluding application credentials and Node options. Two old-code regression failures and 23 fixed owner/parity cases pass; native timing remains to be verified without changing deadlines.

* test(windows): preserve native context and failure evidence

* test(windows): await installed readiness and guarded cleanup

Installation acknowledges service activation without certifying runtime readiness. Await the existing HTTP readiness owner after install and update before the unchanged Task/PID/RPC/build assertions. Stop installed supervisors through the guarded service owner before generic task deletion; the probe PID-file cleanup does not own those processes. Preserve original failures, cleanup authority and all existing native deadlines.

* test(windows): distinguish absent tasks during fixture cleanup

Use authoritative Scheduler inspection before guarded stop. Confirmed absence after uninstall or failed registration skips only stop; unknown inspection still fails, and full process/port cleanup remains required. Preserve task authority on a genuine stop failure.

* test(daemon): wait for installed gateway readiness before inspection

* test(daemon): stop installed fixtures through their profiled CLI

* fix(daemon): give actionable Startup refusal guidance

* fix(update): retain native custody during partial-stop recovery

Compensate a failed native stop through the existing guarded service restart,
revalidating the original binding inside its operation lock. Require completed
recovery and preserve the original failure without starting a build or custom
shell command. Successful and failed-build custom restart contracts stay intact.

Four published-shell regressions fail on the former path and pass after this
repair; 21 unchanged controls, selected checks, and independent review pass.

Co-authored-by: Donnie Fiander <44792682+DonnieFi@users.noreply.github.com>

* fix(daemon): inspect extra Windows services before removal

Keep verified Node and legacy diagnostics visible while offering read-only
Scheduled Task inspection in Doctor and deep status. Preserve the existing
service cleanup owners and diagnostic JSON shape.

Carry the canonical SQLite fixture host-context and dependency-selection
repairs from #158209 and #158409 for the inherited CI collection failure.

* test(windows): expect informational Startup fallback findings

* fix: restore asynchronous harness task completion

Complete the shared task-content projection cutover for asynchronous finalization and delivery. Preserve the captured Incognito policy and exact task-assignment fences.

The unchanged worker suite reproduced six ReferenceError failures before the fix and passes all seven cases afterward; the sibling SDK runtime suite passes all 30 cases. Independent review is clean through P2.

* fix(daemon): compose read-only Windows inspection hints

Preserve exact Startup file inspection while adopting read-only Scheduled Task advice and Inspection headings. Keep Node diagnostics visible without suggesting deletion. Combine both owner behaviors and reuse the qualified lower correction without unrelated fixture changes.

* test(windows): accept omitted PID for stopped Startup runtime

* test(windows): budget installed lifecycle phases separately

Give the fixed installed cells room for their serial setup, unchanged updater command window, native assertions and cleanup. Keep source-native and command deadlines, the quiet-run detector and the hard job limit unchanged. Record real completed phases after durable evidence writes, and verify workflow envelopes against the actual body and teardown configuration.

* fix(qa): retain the current Telegram renderer reference

Carry the canonical one-line metadata correction from #158313. The retired formatter was moved into format.ts, already listed by this scenario; execution and all assertions are unchanged. The owning catalog suite passes all 56 cases and fresh review is clean.

* test(windows): budget installed service phases and retain progress

* test(daemon): retain installed update failure progress

* test(windows): retain failed installed update progress

Read failed published-updater progress through the existing asynchronous SQLite owner before native cleanup. Retain only safe phase, status and step timings; preserve all command, body and teardown deadlines.

Validation: five installed-fixture tests, services types, targeted changed checks and independent review through P2 passed. Shared diagnostic implementation qualified in the Windows fixture owner.

* test(daemon): budget the full published Windows update

* chore(ci): carry canonical line-cap repairs

Carry the necessary kernel environment and publication alias hunks from #158625 (8f22acdd), and the interrupted replay fixture extraction from #158538 (25f4dfa5). Preserve their assertions, state contracts, and Peter Steinberger attribution. Update installed workflow comments to match the already-qualified body budgets.

* test(windows): retain final updater verification diagnostics

* test(windows): verify stale admission refuses foreign task resume

* fix(daemon): bound aggregate Windows service inventory

Carry one monotonic deadline through Scheduler discovery, launcher reads, registration revalidation, and missing-launcher metadata. Preserve completed findings and report incomplete inventory when the shared budget is exhausted.

* fix(windows): share inspection deadlines with Startup launchers

Compose the shared Windows inventory deadline through Startup directory inspection, launcher reads, and definition revalidation. Preserve completed discoveries and report every exhausted scan, including arbitrary filenames and the final completed Task.

Use the same caller deadline for exact Startup state capture and reread. Stalled file operations remain unknown diagnostics without extending the native inspection allowance. Retain immediate Task-query failure fallback, profile bindings, and process cleanup propagation.

* test(openrouter): split Fusion prompt coverage below line limit

* test(daemon): complete system template runtime fixture

Provide the loaded-runtime reader's required ControlGroup metadata. The missing
native response correctly made inspection unavailable and broke the template
regression after main integration; production behavior is unchanged.

Validation: the original fixture fails locally for the CI assertion, then all
76 service-scope and loaded-runtime cases pass after correction. Independent
P2 review is clean. No assertion, timeout, or package source changed.

* test(openrouter): align the canonical Fusion suite label

* fix(daemon): classify registered helpers without profile admission

Let read-only registered inventory classify faithfully revalidated commands
without requiring an OpenClaw profile. Keep selected-service profile
admission strict and preserve launcher, Task, script and deadline checks.

Native disabled-discovery exposed a false warning for a static node --version
helper. The actual collector regression fails before this fix and passes
with all 206 owner and sibling cases afterward.

* fix(daemon): separate task discovery from profile admission

Registered inventory must classify fully inspected unrelated commands without requiring an OpenClaw profile. Preserve resolved matching profiles for selected-service reads and all native definition revalidation. Reproduced through the real inventory collector after the installed Windows discovery fixture failed; retain the selected-service refusal control.

* fix(build): retain Startup identity in external recovery guidance

Carry the shared stop, successful rebuild, and start guidance while keeping Startup-only siblings tied to their exact entry paths. An already-current update does not repair stale output. Fence tests pass 44 cases with one existing skip; script types, lint, formatting and independent P2 review pass. This copy-only successor is separate from the frozen f919 Windows package source.

* fix(daemon): recognize released waiting task launchers

Recognize the exact waiting VBS wrapper shipped by 2026.9.3 during
owned service reconciliation. Keep custom launcher behavior unknown and
preserve all command, root, Task and authority checks.

The real audit entry point rejected this released form as TaskLauncher
unknown-edit before repair. The causal regression and edited-launcher
control pass with 55 audit and 140 backup/rewrite sibling cases.

* test(windows): preserve primary installed update failure facts

Retain bounded sanitized fields from the original published-update JSON before unchanged failure assertions. This preserves primary reasons and failed checks that the output tail can omit, without changing capture ceilings, command deadlines, process ownership, or cleanup.

* fix(test): read Windows proof archive members portably

* test(windows): normalize native task export line endings

* fix(windows): enable verified disabled tasks on explicit start

Preserve captured autostart policy during update recovery; an explicit Gateway or Node start revalidates the selected task and its launcher/package or recorded wrapper before enabling and running it. Keep stronger local start fingerprints out of published update drivers serialized command shape.

* fix(windows): retain starts with unavailable enable metadata

Only an explicit disabled policy admits enabling. Preserve native Run for readable Tasks whose optional Enabled field is absent, while retaining typed failures for failed inspections. Keep the finalization fixture original gateway-entrypoint exports when replacing its install resolver.

* docs(windows): explain partial effects of an explicit start

A successful enable can remain after a later launch failure. Preserve the existing independently audited enable contract and require current authority for any further control; do not imply automatic rollback of a failed start.

* fix(build): bound exact Startup service inspections

Pass the existing Windows inspection allowance when the build fence reads an exact Startup entry. A stalled launcher read now aborts within that budget so the fence can still inspect and refuse a later live sibling. Preserve ordinary reader defaults and the cold native-Node import boundary.

The real fence/state/file-reader regression fails before the fix and passes afterward. All 122 fence and Startup/deadline cases, selected type/lint/export checks, native Node import, and independent scoped review pass.

* docs(update): clarify existing-build recovery commands

Source-runner gateway stop and restart use the existing CLI by default. Explain that applying source changes requires the documented stop, build, and start sequence.

---------

Co-authored-by: Donnie Fiander <44792682+DonnieFi@users.noreply.github.com>
2026-09-28 04:58:29 -07:00
Peter Steinberger
4e97ea310b
fix(macos): keep saved Gateway runtime pins without automatic replacement (#160127)
* fix(apps): stop clearing Gateway runtime pins and pin the app's Bun

The macOS app enabled its LaunchAgent with an explicit `--runtime node`.
Since runtime pins exist, that flag clears pin intent, so every launch-agent
toggle wiped a runtime pinned with `openclaw gateway install --runtime-path`.
Drop it: the service configuration owns runtime selection, fresh installs
still default to Node, and forced reinstall keeps a pinned or recorded runtime.

When the app's resolved CLI runs under an absolute Bun executable, both the
macOS and Linux apps now pass `--runtime bun --runtime-path <bun>`, so a
Bun-only app install pins its own Bun.

* fix(apps): keep runtime pins when the macOS app enables its Gateway

Leave runtime selection with the service installer. Remove both apps' Bun
runtime-path overrides, which could replace an operator pin, while retaining
the macOS fix that omits the pin-clearing explicit runtime node selection.

Enabling preserves an installed service's pin. Disabling still uninstalls the
LaunchAgent and removes the pin. CLI fallback on Bun-only hosts is separate.

Validation: 59 focused native tests passed in an isolated test-helper run;
SwiftFormat, docs formatting, and diff checks passed. Independent review of
the complete candidate is scoped-clean for P0-P2.

* fix(apps): recover an invalid runtime pin when the macOS app enables its Gateway

Classify both CLI pin inspection and validation failures as runtime-pin-invalid
in JSON while preserving the existing human errors and exit code 1.

The macOS app keeps valid runtime pins, but retries an install once with
--runtime node when the CLI reports that typed failure. Log successful repair,
return retry failures, and leave unrelated failures unchanged.

Validation: CLI output and response tests passed 19/19 in 23.11s wall; the
install-output file passed 6 cases. Core typechecking, 60 focused native tests,
SwiftFormat, oxfmt, and whitespace checks passed. Independent P0-P2 review of
the complete candidate is scoped-clean. Both regressions failed before the fix.

* fix(daemon): only flag definitely invalid runtime pins for app recovery

Give a saved pin's changed service definition a dedicated error class. Only
that inspection failure emits runtime-pin-invalid; transient IO/SQLite and
other inspection failures remain untagged so the app preserves the pin and
returns the error without resetting runtime selection.

Keep the invalid executable classification and all human errors unchanged.
Exercise the real pin reader with an IO-like state read failure and a changed
saved definition. The transient-read regression fails before this fix.

Validation: 10 focused tests passed in 97.32s wall (7 install-output cases and
3 pin-state cases), pnpm tsgo:core, oxfmt, and whitespace checks passed. Swift
is unchanged; existing coverage rejects retries for untagged failures.

* fix(macos): keep saved Gateway runtime pins without automatic replacement

Automatic runtime retries could discard an operator pin after transient validation failures or a changed service definition. Preserve the existing explicit replacement contract by returning the CLI error and naming the reinstall action instead.
2026-09-28 04:10:30 -07:00
Peter Steinberger
f319fd36a3
feat(macos): show the web conversation in native chat windows (#159946)
* refactor(macos): extract the Control UI document host from the Dashboard

* feat(macos): show the web conversation in native chat windows

* fix(macos): preserve web conversation state during navigation

Keep native outbox work draining for unselected sessions and retain send
exclusion until the retiring web document commits about:blank or terminates.
Bind opening drafts to their source conversation and preserve native focus
during background readiness.

Keep the pane visible through bounded navigation, reconcile failed selections
with the web's settled state, defer sidebar updates beyond table callbacks,
and remove duplicate native title chrome. Add opt-in bridge metadata tracing
with OPENCLAW_DEBUG_CONVERSATION_BRIDGE=1.

* fix(macos): reconcile the latest web conversation route

Retain web route and state reports during asynchronous reservations. Recheck
the latest reported context after each await, reserve it before selecting it,
and let newer routes supersede both success and failure of an older attempt.

Read the bridge's current state when publishing the admitted route. Keep
native navigation and document retirement fences, without echoing web routes
back into the page. Cover B-to-C handoff during a paused reservation for both
admitted and refused B outcomes.

* fix(macos): unify the web conversation titlebar

* refactor(macos): simplify conversation browser-store selection

* fix(macos): keep native drafts and Dashboard titlebar through web conversation handoffs

* fix(macos): preserve independent sends and web-route drafts

* test(macos): wait for the hosted conversation detail

* test(macos): wait for complete native toolbar restoration
2026-09-28 02:14:51 -07:00
Peter Steinberger
c5aaedd78f
feat(macos): match the web sidebar's roster defaults and view options (#160141)
* feat(macos): match the web sidebar's roster defaults and view options

Add profile-local Created/Last updated sorting and message preview,
automation, and system visibility choices to the native Threads header.
Default to Created with all three toggles off, preserve selected filtered
threads and critical status text, and let available agent navigation own
main while keeping loaded children reachable and recovery usable.

Decode existing creation provenance without changing Gateway protocol,
roster ownership, shared organizer defaults, or iOS behavior. Document the
native sidebar defaults and regenerate the native localization inventory.

* fix(macos): keep sidebar rows one line when previews are hidden

* fix(macos): keep the sidebar view-options icon visible in inactive windows
2026-09-27 23:54:53 -07:00
RoboClaw
8fba459460
fix(android): new chats appear under the previous session (#159984)
Show ordinary Android New chats independently using existing creation and lineage metadata, while retaining real child-session hierarchy. Preserve provider/model, thinking, Fast Mode, stored parent links and conversation history.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-27 20:54:26 -07:00
RoboClaw
eec06229e4
improve(android): align icons and separate work pages from settings (#159961)
Align Android navigation icons with the Web UI, separate work pages from Settings, and keep Settings accessible through the footer gear. Use the Pages pencil for navigation and pin customization without a redundant More row.

Preserve existing work-page pins and their order; restore defaults for a legacy Settings-only selection. Update the guide, native string inventory, license notices, and regression coverage.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-27 17:45:10 -07:00
RoboClaw
f651a47ed7
feat(android): control the agent browser inside chat (#159767)
* feat(android): control the agent browser inside chat

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* feat(android): control the agent browser inside chat

Worked on by:
- @IWhatsskill

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
OpenClaw-Publication: 10c156ed-14ec-44c8-802d-ea9a601695a7

* fix(android): collapse and dismiss the agent browser

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* fix(android): handle unsupported Gateway browser views

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* test(browser): await click delivery before changing capture mode

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* test(ui): report the first unexpected transcript measurement

Keep the native getter, input sequence, timing, and zero-read assertion unchanged. Capture only the first violating read stack so an intermittent CI failure identifies its caller.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-27 15:57:47 -07:00
Peter Steinberger
8777448a9f
feat(apple): attach files and audio in native chat (#159667)
* feat(apple): support file and audio attachments in native chat

Admit documents, archives, and disk audio through the existing native file
loader, with picker types and hello-advertised size limits matching the web
composer. Route macOS pasted file URLs through that same owner and remove
the image-only paste reader and fixed video cap. iOS Files uses the shared
picker and admission rules; recorded voice notes keep their separate flow.

Show removable filename/size chips and preserve canonical media facts in
history after refresh. The existing durable outbox and chat.send payload
retain filename, MIME type, and bytes without schema changes. Inbound upload
downloads remain a separate native limitation; managed artifact downloads
keep their current behavior.

Web references: chat-attachments.ts, chat-attachment-admission.ts,
attachment-api.ts, and chat-send-request.ts under ui/src/pages/chat.
Update native chat docs and regenerate the native localization inventory.

Validation: macOS product build and test compilation; iOS Simulator shared
kit build; focused shared-kit admission, request, history, and outbox tests;
Swift lint/format, check-changed, native i18n verify, and both i18n script
suites. Independent review and visual/live-flow proof remain with the
coordinator under this work order.

* fix(apple): bound attachments for legacy gateways

Gateways without hello attachment policy now use the named native fallback:
20 MiB for source files and 5,000,000 bytes for images after resizing.
Advertised limits keep precedence. Require a concrete byte ceiling in the
file reader and remove readToEnd so legacy uploads cannot allocate an
unbounded file before base64 encoding.

Extend the no-policy transport regression to reject an oversized PDF and
preserve resizing for a source image larger than the final image ceiling.
Document the legacy limits on macOS and iOS.

* fix(apple): stage every file when several are attached at once

Capture one attachment-policy snapshot for each file selection and carry it
through file reads and image processing. Reacquiring policy between files
could pause a partially staged batch while the Mac transport resolved or
recovered its endpoint, leaving only the first file visible with no error.

Read Mac attachment limits from the current admitted hello without endpoint
recovery, preserving publication, selected revision, and expiry checks.
Picker and pasted file URLs continue through the same public staging owner.

Add deterministic PDF/CSV/WAV regressions for direct multi-selection and
private pasteboard extraction, plus Mac policy-read lifecycle coverage.
The coordinator owns independent review and the live recheck for this
campaign. Builds, focused shared-kit tests, and Swift lint/format passed;
the macOS app test bundle was compiled only.

* fix(apple): bound advertised attachment limits

A malformed hello advertising Int.max made the bounded file read compute
maximumBytes + 1 and trap. Accept only positive ceilings and clamp them far
above any valid Gateway value (one WebSocket frame), so staging reports an
attachment error instead of crashing.

* fix(apple): bound native attachment batches before send

Share the decoded attachment budget across files, resized images, and
voice notes. Recheck the captured draft before durable admission or live
send, preserving oversized drafts and preventing connection-closing retries.
Propagate image admission errors into mixed-file error summaries.

Clamp hello attachment ceilings to the advertised WebSocket payload budget
with base64 and envelope overhead. Match web attachment action labels.

Regression tests fail before the repair. Both macOS builds, 17 focused
shared-kit tests, Swift lint/format, localization verification, docs
formatting, and diff checks pass. No schema or configuration changes.

* fix(apple): make attachment fallback budgets frame-safe

Use one overflow-safe decoded-frame helper for the legacy fallback and
advertised attachment clamps. Missing policy or payload limits use the
Gateway's 25 MiB default frame with 256 KiB envelope slack, yielding
19,464,192 decoded bytes. Keep the processed-image fallback at 5 MB.

Update docs and regressions for missing payload limits, source-file
admission, and an oversized no-policy batch rejected before durable storage.
Both macOS builds, focused shared-kit tests, lint, format, localization,
and docs checks pass. Codex autoreview is scoped-clean through P2.

* fix(apple): preserve image resizing before upload admission

Bound source photos by the general file budget, then apply the image
ceiling after JPEG processing and the combined budget before staging.
Cover file and paste paths with advertised and legacy attachment limits.

Remove the unused chat UI import reported by the macOS dead-code scan.
Both macOS builds, focused shared-kit tests, lint, format, localization,
and diff checks pass. Codex autoreview is scoped-clean through P2.

* test(macos): use a real frame budget in attachment policy fixture

* fix(apple): separate image source and upload budgets

Bound image resize inputs to 64 MiB independently of the frame-safe upload
budget. Preserve the processed-image ceiling and combined attachment
budget; non-image files retain frame-safe source reads.

Cover file and paste admission for a 20 MiB image that resizes into budget,
and reject inputs exceeding 64 MiB. The regression fails before the fix.
Both macOS builds, focused shared-kit tests, lint, formatting, localization,
and docs checks pass. Codex autoreview is scoped-clean through P2.

* fix(apple): preserve history with malformed optional media

Decode optional media facts independently through the existing payload
codec, preserving nil slots used by inline-image layout indices. Invalid
optional layout no longer invalidates a readable message or cached row.

Exercise the actual history decoder with malformed facts and valid siblings,
and prove existing cached transcripts survive malformed optional metadata
across reopen. The regressions fail before the fix. Both macOS builds,
focused shared-kit tests, lint, format, localization, and diff checks pass.
Codex autoreview is scoped-clean through P2.
2026-09-27 15:17:07 -07:00
RoboClaw
19254bf236
improve(android): move context usage into the session menu (#159733)
* improve(android): move context usage into chat actions

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* docs(android): describe context in chat actions

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-27 13:29:56 -07:00
Peter Steinberger
8d4d13c9e4
fix(macos): stop native tests aborting on WebKit Screen Time teardown (#159535)
WKWebView starts a Screen Time configuration observer once it is in a
window with an HTTP(S) main frame. ScreenTime delivers configuration via
KVO on WebKit's private update queue while -[WKWebView dealloc] removes
the observer on the main thread, so tearing a web view down during its
initial reply throws NSInternalInconsistencyException and aborts the
Swift Testing process (macos-swift run 36289828982, job 108537817128).

Link a test-only OpenClawWebKitTestSupport target into OpenClawIPCTests
that replaces WebKit's Screen Time install hook with a recorder, add a
regression test for windowed HTTP web views, and document the guard.
Product builds keep Screen Time.
2026-09-27 12:33:21 -07:00
Peter Steinberger
1948afd60d
feat(macos): renew Gateway browser sign-in before it expires (#159381)
* feat(macos): renew Cloudflare Access browser sign-in automatically

Saved Gateways behind Cloudflare Access stored an app-scoped Access token
that hard-expired, after which the dashboard showed the blocking signed-out
page. Nothing renewed it ahead of time.

While the user is present and a saved Gateway is in use, the app now runs
the existing browser sign-in in the background during the last quarter of
the token lifetime (15 minutes to 7 days), at most once per profile per day.
A same-account renewal of a still-live session keeps the dashboard document
and route and quietly reconnects the native socket; expired sessions and
account changes keep the full sign-in path. A user-initiated sign-in cancels
and joins an in-flight automatic attempt first.

* refactor(macos): keep renewal status out of native Gateway settings

* refactor(macos): remove dead command, approval, tunnel, chat, and permission paths

Deletes production code with no remaining callers, found with Periphery and
confirmed by repository search and a clean build: the retired SSH node
command builder in CommandResolver, the unused outbound approval-policy
snapshot conversion, ExecApprovals.parseDecision, the port-only
RemoteTunnelManager.ensureControlTunnel wrapper, the old cron transcript
opener in WebChatManager, and the computer-control permission diagnostic
renderer with its two localization inventory entries. Tests that only
exercised the removed code are removed or pointed at the live owners.

* fix(macos): let each renewed Access token renew inside its own window

The automatic attempt throttle was one per profile per day, so a 24-hour token renewed at hour 18 blocked the renewed token's own window until it had already expired. Attempts are now keyed to the session token; retries of one token wait half its renewal window, at most a day.

* fix(macos): check Access renewal often enough for 15-minute windows

The periodic check slept an hour, so a short or legacy session's 15-minute renewal window could pass unchecked while the app stayed active, and returning from idle triggered no check. Check every five minutes instead.

* fix(macos): keep the Gateway socket when an Access renewal cannot be saved

A same-account renewal disconnected the native socket before device-token retirement and the Keychain save, so a failure there left chat and push offline although the old session stayed valid. Renewals now disconnect only after the save; browser-session sockets never use or persist device tokens, so the old socket can stay up until then.

* fix(macos): never switch accounts during automatic Access renewal

An automatic renewal whose browser returned a different Access subject was saved and took the account-change path, retiring the old account's windows and credentials. Automatic renewals now commit only a same-account renewal of a still-live session and are rejected before any side effect otherwise. The renewal window reuses the existing Access JWT decoder.
2026-09-27 11:43:34 -07:00
RoboClaw
8bfc0ce8e1
fix(android): keep automation runs out of pinned chats (#159737)
Keep cron and system conversations out of ordinary Android chat navigation while preserving saved pins and selected-session access. Reuse Gateway creation facts and the Web visibility policy, and expose retained automation conversations through Threads → Automations and the existing transcript-opening route.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-27 11:40:31 -07:00
RoboClaw
1ff9d2c4bc
feat(android): give saved gateways persistent local names (#159714)
Allow saved Android Gateways to have persistent phone-local display names.
Preserve names across metadata updates and document the accepted downgrade limitation.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-27 10:44:31 -07:00
Peter Steinberger
6652f7eac8
refactor: remove Tasks and TaskFlow runtime (#159179)
Remove Tasks and TaskFlow runtime, APIs, CLI, SDK surfaces and panels after the Cron, session, native execution and media completion ownership cutovers. Preserve stored rows and import provable legacy native assignments through Doctor; ambiguous ownership stays untouched with a warning.

Follows #158221, #158217, #158225, #158222, #158702 and #158776. Related: #156532. Task-specific public APIs retire immediately; retained responsibilities use their existing owners.

Maintainer-authorized administrative landing after full CI run 36312986498 attempt 2 passed on 274595e2, with subsequent actual conflicts reviewed and focused checks passing. Current PR CI preflight hits the 64 KiB changed-path metadata limit before tests (run 36335042695); its duplicate security-review status mirrors that planning failure. Review and scoped proof are recorded in the PR. Published 9.4 native import is proven; remaining native completion and 9.4 rollback witnesses are explicitly unproven.
2026-09-27 10:40:29 -07:00
RoboClaw
1fe2f5007d
improve(android): find models despite typos and multiple search terms (#159725)
Improve Android model search with conservative typo tolerance and multi-term ranking while preserving provider groups, selection, and availability.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-27 09:37:11 -07:00
RoboClaw
b157245501
improve(android): put Settings beside the gateway selector (#159718)
* improve(android): put Settings beside the gateway selector

Default to Home, Threads, Skills, and Overview while preserving personalized pins and the existing navigation owner.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* test(android): make sidebar drag fixtures independent of defaults

Pin Settings explicitly for fold gesture scenarios and configure the catalog drag order. Use the footer gear for Settings navigation without changing production code or assertions.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-27 08:59:32 -07:00
Peter Steinberger
8b16e5328e
fix: prevent temporary-file exhaustion from SQLite coordination (#157413)
Use transactions on the actual SQLite state and device databases for ordinary writes. Remove redundant coordination databases, transport, and exclusion layers while preserving bounded process ownership for startup, schema work, and offline maintenance.

Tie test and QA scratch retirement to settled workers and native resources, preserve active plugin captures, and join SDK declaration compiler processes before synchronous semantic rendering.

Validation: main-tier CI on 5e731c1f64 had 144 successful jobs and one Windows ACP initialization timeout. Qualified unchanged replay 36314027585 passed all 896 tests with the original 48-file order, six projects, toolchain, and deadlines. The original timeout remains unexplained and recorded in the PR. Reviewed main-conflict integration through 39caa592ef passes focused SQLite, Doctor, image, and Cron proof plus affected typechecks and lint. No accepted actionable independent-review findings remain.

Squash landing of #157413 under explicit maintainer authority to resolve logical main drift and admin-merge using the completed CI evidence. No PR-specific schema or public configuration migration.
2026-09-27 05:30:41 -07:00
Peter Steinberger
32dcd02906
feat(apple): show agent identities in native chat (#159528)
* feat(apple): resolve native chat agent identities

Resolve agent names and bounded text or emoji avatars in the native macOS chat sidebar, toolbar subtitle, composer, and New Thread picker. Configured roster names win over resolved identities, and unnamed agents display Assistant.

Extend the existing shared agent catalog and choices with agent.identity.get requests by agentId. Refresh identities with the roster, preserve its order and routing metadata, and fence publication to the captured Gateway connection. The iOS New Thread picker uses the same owner. Keep image avatar loading and Quick Chat outside this change.

Web references: ui/src/lib/assistant-identity.ts, ui/src/lib/agents/identity.ts, and the configured-name precedence in ui/src/lib/agents/display.ts. Shared normalization/request tests pass; macOS app and test bundle compile; localization and changed-file checks pass. Native UI screenshots and independent review remain with the campaign coordinator.

* fix(apple): publish agent rosters before identity hydration

Keep the native sidebar and shared New Thread picker usable while optional agent identities load. Publish each identity on its captured connection, preserve picker selection, and clamp badge text to two complete graphemes while retaining normalized identity data. Cover availability, route retirement, selection, and badge rendering with shared regressions.
2026-09-27 05:06:21 -07:00
Peter Steinberger
907b4fbd5d
fix(apple): keep paragraph breaks before lists in native chat (#159517)
Preserve paragraph boundaries in stored and streaming native chat messages
on macOS and iOS instead of joining the list introduction to prior prose.
Extend ChatMarkdownProse's existing parser to materialize Foundation block
presentation intents as separators before display and reveal preparation,
while retaining inline formatting and document-scoped reference links.

Match the separate paragraph blocks rendered by the web Control UI's
ui/src/components/markdown-parser.ts. Cover the reported message, adjacent
block transitions, styles, links, soft breaks, and streaming reconstruction;
document the shared Apple behavior.
2026-09-27 02:58:49 -07:00
Peter Steinberger
244d441972
fix(daemon): inspect registered Gateway services accurately (#151608)
* fix(daemon): inspect registered Gateway services accurately

Read strict Windows service commands from registered actions and preserve
supported launcher encodings without treating dynamic CMD expansion as a
verified command. Retain exact task identity and bound systemd selection.

Use one platform inventory collector for the existing full and diagnostic
projections. Report incomplete inspection through Doctor while preserving
status JSON and the existing managed-service filters. Keep load-state
inspection behind a leaf capability instead of reverse facade imports.

Refs #151608, #151463.

* fix(daemon): classify service commands by position

Share runtime and root-option parsing so Node display names and profile values
cannot classify a Node service as a Gateway. Preserve literal shell, env and
generated launchd wrappers, and honor the executable selected by launchd.

Read systemd's single-quoted arguments through the existing parser and preserve
literal apostrophes when rendering. Keep strict Windows command rejection
separate from lenient diagnostics, and align the native-boundary fixtures with
that contract without weakening ownership or source-preservation assertions.

* fix(daemon): inspect direct registered task actions

Read literal executable actions from their registered Scheduled Task and
revalidate the action before returning command facts. Strict runtime inspection
uses the same registered command instead of a default launcher.

Keep executable paths out of managed launcher provenance. Direct actions remain
outside automatic update service management when no restorable CMD/VBS launcher
exists, preserving the prior stop and definition ownership boundary.

* test(windows): prove installed service upgrade paths

Extend the existing native Scheduled Task proof with verified immutable package
handoff and fixed fresh, published 2026.9.3, and published 2026.9.4 CLI cells.
Require live version/build identity, selected PID replacement, peer continuity,
strict registered-action inspection, and settled cleanup before evidence
publication and disposable installation retirement.

Keep source-only and repair modes, permissions, deadlines, and native lifecycle
owners intact. Direct executable fixtures remain disabled and preserve the
updater's unsupported-mutation boundary. Native execution remains pending.

* test(doctor): retain managed Windows launcher provenance

Keep the generated CMD path on the existing managed-service fixture before
and after reinstall so Doctor admission sees the installation it models.
Preserve all stop, install, restart, rollback, and direct-action refusal
expectations without changing production behavior.

* test(windows): exercise native autostart ownership boundaries

Extend the existing published-updater cell with its stopped, task-owned
Scheduled Task. Capture real admission, exercise native enable/disable,
and preserve the definition and files after foreign-owner refusal.

Test retained admission separately from restoration so legitimate same-root
refresh remains supported. Restore the original XML through the existing
fixture lifetime; do not broaden product control or workflow permissions.

Modeled owner tests, selected source checks, and independent review pass.
Actual Windows execution remains required before a native proof claim.

* test(windows): retain sanitized installed command failures

Keep unexpected command stdout and stderr in bounded failure diagnostics so
JSON-mode CLI errors survive native proof failures. Reuse the existing
terminal and support redaction owners before clipping; withhold incomplete
captures while preserving the existing truncation failure.

Move the existing command runner into its own test-support module and update
both consumers without changing timeout, exit, signal, or cleanup semantics.
Real-child regressions reproduce both privacy defects and pass with the
correction. The original installed Gateway failure remains undiagnosed.

* fix(daemon): preserve Windows probe budgets and Doctor cleanup eligibility

Use the existing cold PowerShell startup budget for Task Scheduler queries
without an explicit deadline. Keep periodic activation checks bounded and
preserve unknown results rather than treating timeouts as task absence.
The native probe test now exercises the production default.

Share Doctor's existing legacy cleanup classification with its registered
preview. Keep unsupported platforms, scopes and unrecognized Linux unit
names as findings without advertising removal or invoking unrelated cleanup.
Extract the classifier and complete cleanup test group without dropping
assertions or changing native mutation ownership.

Retain the failed installed Windows runs and their source identities;
new package and native upgrade qualification remain separate requirements.

* chore(daemon): retire stale Doctor size baseline

The split Doctor service module no longer needs a max-lines suppression.
Remove only its stale baseline entry so the shrink-only ratchet matches
actual source. Product, dependency, workflow and fixture bytes are unchanged.

* test(windows): retain sanitized service proof observations

Record bounded install and status facts before semantic assertions so a
successful CLI exit cannot hide the native inspection reason. Exclude
free-form stderr and private response fields, and preserve existing
execution, deadline, and cleanup assertions.

* fix(windows): preserve native status inspection defaults

Keep the CLI RPC default distinct from an explicit timeout so Windows
service inspection can use its existing cold-start budget. Forward
explicit load-query deadlines through the Task Scheduler owner while
preserving lifecycle defaults and timeout diagnostics.

* fix(models): retain discovered models after refresh failures

Record successful legacy catalog results at the producer boundary so unavailable refreshes retain the accepted inventory. Preserve explicit outcomes, advisory SDK fallback behavior, and first-discovery starter policy.

* fix(models): preserve skipped catalog outcome semantics

Mark bundled static, configured, and advisory catalog projections with
explicit empty outcomes so legacy success inference cannot promote them
to observed account inventory. Preserve live outcomes and helper types.

Keep exact auth provenance histories and move existing fixture/policy
code into focused owners where required by the line-cap ratchet.

Validation: 447 producer and sibling cases, 56 shared self-hosted cases,
95 auth/policy cases, causal missing-outcome failures, maintained checks,
and independent review.

* test(plugin-sdk): keep discovery loader types acyclic

Move the shared loader type into a leaf consumed by both discovery
contract helpers. Preserve its public provider-test-contracts export
without a child-to-parent type import cycle.

Validation: maintained Madge check reports zero cycles; core, all core
test graphs, extension test types, lint, formatting and independent
review pass. Runtime behavior and previous catalog proof are unchanged.

* fix(plugin-sdk): mark generated static catalogs explicitly

Keep the generated non-live, non-strict catalog adapter from claiming
successful acquisition for manifest or configured rows. Preserve null,
errors, strict and custom callbacks, static catalogs, and public types.

Validation: three existing controls fail before the correction; all49
owner and sibling cases pass afterward, with types, lint, line caps and
fresh independent review clean.

* test(windows): handle omitted scheduled task settings

* test(windows): preserve native context and failure evidence

* test(daemon): wait for installed gateway readiness before inspection

* test(daemon): stop installed fixtures through their profiled CLI

* fix(daemon): inspect extra Windows services before removal

Keep verified Node and legacy diagnostics visible while offering read-only
Scheduled Task inspection in Doctor and deep status. Preserve the existing
service cleanup owners and diagnostic JSON shape.

Carry the canonical SQLite fixture host-context and dependency-selection
repairs from #158209 and #158409 for the inherited CI collection failure.

* fix: restore asynchronous harness task completion

Complete the shared task-content projection cutover for asynchronous finalization and delivery. Preserve the captured Incognito policy and exact task-assignment fences.

The unchanged worker suite reproduced six ReferenceError failures before the fix and passes all seven cases afterward; the sibling SDK runtime suite passes all 30 cases. Independent review is clean through P2.

* test(windows): budget installed service phases and retain progress

* test(windows): retain failed installed update progress

Read failed published-updater progress through the existing asynchronous SQLite owner before native cleanup. Retain only safe phase, status and step timings; preserve all command, body and teardown deadlines.

Validation: five installed-fixture tests, services types, targeted changed checks and independent review through P2 passed. Shared diagnostic implementation qualified in the Windows fixture owner.

* fix(daemon): bound aggregate Windows service inventory

Carry one monotonic deadline through Scheduler discovery, launcher reads, registration revalidation, and missing-launcher metadata. Preserve completed findings and report incomplete inventory when the shared budget is exhausted.

* fix(daemon): classify registered helpers without profile admission

Let read-only registered inventory classify faithfully revalidated commands
without requiring an OpenClaw profile. Keep selected-service profile
admission strict and preserve launcher, Task, script and deadline checks.

Native disabled-discovery exposed a false warning for a static node --version
helper. The actual collector regression fails before this fix and passes
with all 206 owner and sibling cases afterward.

* fix(daemon): recognize released waiting task launchers

Recognize the exact waiting VBS wrapper shipped by 2026.9.3 during
owned service reconciliation. Keep custom launcher behavior unknown and
preserve all command, root, Task and authority checks.

The real audit entry point rejected this released form as TaskLauncher
unknown-edit before repair. The causal regression and edited-launcher
control pass with 55 audit and 140 backup/rewrite sibling cases.

* test(daemon): cover retained Task ownership refusal

* test(windows): preserve XML bytes around enabled export lines
2026-09-27 02:55:51 -07:00
Peter Steinberger
e5b57e2f01
feat(apple): show message times and models in native chat (#159366)
* feat(apple): show chat message timestamps and originating models

Show one quiet timestamp per transcript message group, with locale-aware
relative dates and exact dates for accessibility and macOS tooltips. Show
the recorded originating model for assistant replies when available, without
adding metadata to streaming text or ordinary commentary/tool activity.

Extend the existing transcript row projection and message footer owners.
Preserve model and source grouping fields through the existing offline cache
shaper, and retain all message metadata when merging tool results.

Mirror the grouping and historical model contract in the web Control UI's
chat-thread-grouping.ts, chat-message-group.ts, and chat-message-timestamp.ts.
Apply the same presentation to iOS and update both platform docs and the
native localization inventory. Transcript export remains unchanged.

* perf(apple): reuse native transcript metadata work

Prepare visible rows and footer metadata from the same tool-merged,
onboarding-trimmed transcript before completed-work collapse. Share that
snapshot with rendering, search, visibility checks, and navigation chrome.

Reuse a bounded locale/time-zone formatter set under a mutex instead of
allocating formatters for each footer. Preserve the existing templates and
relative-time output, with coverage for switching locales and returning.

* fix(apple): keep message footers on visible group members

* fix(apple): tolerate malformed optional message attribution

* fix(apple): retain completed overlapping run footers
2026-09-26 23:28:40 -07:00
Peter Steinberger
c2c6852e80
feat(macos): add a command palette to native chat windows (#159350)
* feat(macos): add native chat command palette

Open Navigate > Command Palette with Command-K in the key native chat
window. Search agents, loaded threads and available sidebar previews, then
merge older active threads through the existing fetchSessionList request.
Keep exact/prefix/substring ranking, keyboard selection, sidebar badges,
existing window actions, and composer focus within the window's Gateway.

Extend WebChatManager's window routing and ChatWindowShell presentation;
share the sidebar's group and preview state without another session cache.
The palette and focus wiring are macOS-only. Web reference:
ui/src/components/command-palette-session-search.ts,
command-palette-result.ts, and command-palette-view.ts.

Five pure palette tests pass; app and native test bundle compile. Shared-kit
build, Swift lint/format, localization checks/tests, and changed-file gate
pass. Independent review and live screenshots belong to the campaign
coordinator; the app and native app test bundle were not run locally.

* fix(macos): align command palette thread details with sidebar

Use one row presentation owner for sidebar and palette timestamps and
secondary text. Preserve the sidebar's timestamp source and preformatted
relative date, removing the palette's separate SwiftUI date formatting.

Show activity and attention before cached previews, retain thread badges,
and display the agent name only when it differs from the selected agent.
Refresh the palette on the sidebar's cadence so timestamps and expiring
attention remain current. All changed UI remains macOS-only.

Validate the app build, compile the native app tests, and pass six pure
palette tests, Swift lint/format, and localization verification. No new
localization strings. The coordinator owns the live screenshot recheck;
no local app launch, native app test execution, or push was performed.
2026-09-26 22:55:03 -07:00
RoboClaw
b5f3444b44
fix(ios): keep agent narration visible during runs (#156944)
* fix(ios): keep agent narration visible during runs

Render completed narration inline and replay it after reconnect. Preserve the existing completed-work disclosure, use compact duration text, and enable top-aligned iOS agent avatars. Related: #156926. Requested by @IWhatsskill.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* style(ios): apply native SwiftFormat result to narration tests

Mechanical try-keyword placement from pinned SwiftFormat0.63.0 on Xcode27. Production sources remain byte-identical; reuse the 93 passing focused Apple tests from run35949129389.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* fix(apple): group narration and tool activity by response ownership

Keep native narration, tool activity, and final replies in one correlated response while preserving per-message actions and input scroll anchors. Match tool results across narration within their turn and retire unsaved narration only on settled current history. Resolve overlapping output through its own input boundary, never the latest unrelated input.

Preserve main's scroll commands, iPad reading column, prepared streaming views, and history invalidation lifecycle. Related: #156926 and #156944.

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: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com>
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* test(apple): remove obsolete bubble expression source assertion

The Dynamic Type guard asserted the exact old bubble condition, not a typography contract. Grouped responses intentionally moved that decision to their presentation owner. Keep the font and composer assertions; native captures and grouping behavior tests cover the response rendering. CI run36287411547 executed1817 shared tests with only this obsolete assertion failing. No production source changes.

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: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com>
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* fix(apple): include disclosure controls in response accessibility bounds

The new response container reported only its final text as its accessibility frame, excluding the visible completed-work disclosure and message actions. Native Mac run 36288843438 reproduced an unhittable disclosure in the correctly scoped window. Match the existing message-container accessibility shape at the response owner; preserve all native interaction assertions.

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: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com>
Co-authored-by: VACInc <3279061+VACInc@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: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com>
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
2026-09-26 20:51:40 -07:00
Peter Steinberger
6ee9eb39cf
fix(doctor): compare Windows task definitions by Task Scheduler semantics (#158422)
Treat omitted documented Task Scheduler defaults as equivalent in the shared Doctor and transactional publication audit. Preserve explicit disabled flags and missing-trigger drift. Refs #158386.
2026-09-26 00:26:02 +00:00
Dallin Romney
348bd81b55
docs: keep release policy public and maintainer procedures in skills (#156946)
* docs: make the release guide readable and correct closeout policy

* docs: address release guide review feedback

* test: decouple release workflow checks from public guide prose

* docs: finish release procedure link migration

* docs: repair release procedure destinations and preserve packager steps

* docs: preserve release recovery procedures and legacy destinations
2026-09-26 00:18:17 +00:00
Peter Steinberger
d8e679a08c
perf(process): avoid OOM shell execs in spawn helpers (#158367)
Let the Linux spawn broker and service-child anchor pass OOM priority through inheritance while preserving their original scores. Keep direct and PTY wrappers so the Gateway score never changes. Validate shell elimination, child scores, opt-outs, and failed-spawn restoration on Linux.
2026-09-25 15:12:21 -07:00
RoboClaw
84e57221b7
improve(android): streamline the chat composer and attachment menu (#157799)
Give drafts a full-width row and use anchored attachment, model, reasoning,
and context menus. Add direct native photo/video capture while preserving
drafts, attachment permissions, and explicit model-selection semantics.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-25 14:32:58 -07:00
Peter Steinberger
c926e83c8e
fix(update): show progress after the Gateway startup check (#157329)
* fix(update): show why post-canary verification is waiting

Record previous-Gateway readiness and disposable-copy cleanup at their owners, with explicit budgets and bounded native observations. Preserve ownership checks and warn when readiness remains unverified.

Applies to updates running the repaired driver on the next hop. Refs #153401; thanks @WG-Mojo for the Windows/npm evidence. The separate gateway-lifecycle contention remains tracked by #156917.

* test(update): isolate Windows runtime probe budget coverage

* test(update): validate the Windows census fixture command

* style(update): avoid shadowing the readiness observation

* fix(update): preserve readiness ownership and probe allowances

* test(update): use the cleanup deferred default type

* fix(update): scope native probe budgets to readiness
2026-09-25 10:25:32 +00:00
stevenlee-oai
cb64558f80
fix(macos): stop repeated Keychain prompts after access is denied (#157951)
* fix(macos): stop repeated Keychain prompts after denial

* fix(macos): allow temporary Keychain errors to recover
2026-09-24 23:52:31 -07:00
Josh Avant
d5b9c6bf3a
fix(android): finish setup after enabling phone capabilities (#157830)
* fix(android): finish setup after enabling phone capabilities

* fix(android): leave generated locales to refresh workflow
2026-09-25 00:55:11 -05:00
Peter Steinberger
056f6278dd
fix: expose plugin state failure causes and reader identity (#157004)
Preserve bounded nested causes, native errno, and the process/thread/version that captured plugin-state errors in structured logs. Share cause capture with worker transport and document updating the private Mac app worker after a Gateway schema upgrade.

Refs #156930. Reported by @Fuma2013.
2026-09-24 19:38:10 +00:00
RoboClaw
ed96ab858b
docs(android): explain app and Gateway version compatibility (#157467)
* docs(android): explain app and Gateway version compatibility

Clarify protocol negotiation, separate operator and node requirements, and the limits of successful pairing without promising a release-version matrix.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* docs(android): explain app and Gateway version compatibility

Worked on by:
- @IWhatsskill

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
OpenClaw-Publication: a3e17061-63e3-4e33-840e-2cc9b54582f4

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-24 11:22:19 -07:00
RoboClaw
3e58afe691
fix(android): sidebar label matches Overview screen (#157434)
* fix(android): sidebar label matches Overview screen

Keep the persisted work page ID and route unchanged. Update existing sidebar interaction expectations, the generated native source inventory, and the Android navigation documentation.

Fixes #157320

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* test(android): scope Overview return assertion to page content

Reuse the existing Overview content matcher because the sidebar and screen now share the Overview label.

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-09-24 11:10:31 -07:00