Commit Graph

804 Commits

Author SHA1 Message Date
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
Vitor Cepeda Lopes de969db2c3 fix(macos): make OpenClaw settings pane responsive (#128177) 2026-08-25 01:27:34 -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
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
Peter Steinberger 33b10fe4aa fix(macos): user accent from Control UI is clobbered by config snapshots and never live-updates the chat window (#128703)
* fix(macos): honor user accent precedence in config snapshot and live-update chat window

The Control UI user accent (ui.prefs.accent) landed in #128432/#128577 with
precedence user accent -> operator ui.seamColor -> theme default, and the
gateway's talk.config payload already applies it. The macOS app had two gaps:

- ChannelsStore.applyUIConfig read raw ui.seamColor from the config.get
  snapshot and clobbered the user accent set from talk.config depending on
  arrival order. It now resolves ui.prefs.accent ?? ui.seamColor via a
  testable helper mirroring the gateway precedence.
- The native chat window read AppStateStore.seamColorHex once at window
  construction, so accent changes never live-updated. MacChatSurface now
  reads the @Observable store in body, deleting the one-shot userAccent
  plumbing.

Docs: configuration-reference.md documents the precedence for native-app
chrome. Regression test fails pre-fix (snapshot returned the operator seam
color instead of the user accent).

* fix(macos): refresh config from gateway config.changed events

Addresses the review finding that no macOS consumer turned the gateway's
hash-only config.changed broadcast into refreshed shared state, so a
Control UI accent change never reached an open native chat window while
the app ran. ChannelsStore now subscribes to gateway pushes and re-fetches
config.get on config.changed, reconnect snapshots, and sequence gaps.

The refresh applies non-force so an in-progress local settings draft wins
(the gateway rejects stale-hash writes anyway). The in-flight reload queue
gains a closed pending level (none/refresh/force) so a refresh arriving
during a load is coalesced instead of dropped, and a requeued refresh
cannot clobber a dirty draft the way the old boolean force-pending did.
2026-08-24 05:37:59 -07:00
Peter Steinberger 234df15a6d chore: refresh dependencies after seven-day cooldown (#128414)
* build(deps): refresh dependencies after cooldown

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

* fix(ui): align markdown renderer env typing

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

* fix(deps): repair refreshed dependency contracts

* fix(deps): retain tslog startup budget

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

* fix(ci): fence Android SDK cache version
2026-08-24 03:01:54 -07:00
Peter Steinberger 554fb212c9 fix(nodes): report camera positions the hardware actually reached (#128595)
* fix(nodes): report camera positions the hardware actually reached

`camera.ptz.control` returned a position it never verified, and
`camera.snap`/`camera.clip` could capture from a camera the caller did
not ask for. Both told the agent an action succeeded when it had not.

PTZ read its post-write status from the same UVC connection that issued
the write. Gimbal cameras echo a pending setpoint back on the writing
connection, so the check confirmed its own write. Those cameras also
service camera-terminal controls only while a video stream is active, and
no capture session was held, so writes could be discarded entirely while
reads returned phantom values.

Hold a frame-discarding capture session across every PTZ operation, close
the writing controller, and verify through a fresh connection against each
axis's advertised resolution. An axis that misses now reports through the
existing CAMERA_PTZ_PARTIAL outcome with observed versus requested values
and what to check next.

Apple camera selection accepted an explicit deviceId and silently fell
back to the default camera when nothing matched. Linux already rejected
this, and CameraPTZService already rejected it in the same app. Centralize
exact selection in OpenClawKit so macOS and iOS both fail with a
device-not-found error; the facing/default fallback stays only for
requests that supply no deviceId.

camera.ptz.status now activates the camera and its privacy indicator for
the duration of the read. That is the cost of returning real positions.

* fix(nodes): tell callers how to recover from an unknown camera ID

Device IDs change when cameras are reconnected, so a bare
device-not-found error dead-ends the caller. Both Apple errors and the
docs now point at camera.list for current IDs.

Addresses the ClawSweeper P2 finding on #128595.
2026-08-24 01:56:12 -07:00
Peter Steinberger 1299ced0c2 fix(macos): escape all login LaunchAgent plist paths (#128378) 2026-08-23 14:42:19 -07:00
Peter Steinberger a85db8cea7 fix(macos): resolve the onboarding install prompt when the gateway is already running (#128273)
Fixes #128194.

Local-mode onboarding has two rightful actors on the CLI page: the page's
own install flow, which may open an install-target prompt on unreleased
builds, and the connection-mode commit, which starts the gateway through
ConnectionModeCoordinator the moment the user picks This Mac. When the
gateway comes up on its own (dev-root builds, or an externally attached
gateway), AI setup auto-connects and finish() runs — but close() was
silently ineffective because AppKit ignores NSWindow.close() while a sheet
is attached. The result, reproduced live with os_log instrumentation: a
completed onboarding (dashboard open, onboardingSeen set) with a zombie
onboarding window showing a dead CLI page and a stale channel-choice sheet.

Two coupled fixes. OnboardingController.close() now ends any attached sheet
before closing, so completion always tears the window down. And a running
local gateway now resolves a pending install prompt directly: a new tested
static (shouldResolveInstallPromptForRunningGateway) extends the existing
gateway-status revise path to the choosingTarget phase, marking the step
installed and dismissing the moot sheet; runCLIInstall returns quietly in
that case instead of writing a cancellation over a resolved step. Genuine
declines keep the cancelled status.
2026-08-23 09:46:16 -07:00
Peter Steinberger bf91e00d36 fix(macos): reject invalid gateway ports before tunnel setup (#128260) 2026-08-23 09:21:05 -07:00
zhilong1115 df7e6f1c44 macOS: surface realtime Talk settings (#118505)
* feat(talk): link realtime settings surfaces

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

* fix(talk): clear forced routing for GPT-Live relay

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

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-23 08:34:23 -07:00
Vincent Koc 000db97c82 feat(talk): add macOS realtime Gateway relay (#128204)
* feat(talk): add macOS realtime relay transport

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

* feat(talk): integrate realtime relay with macOS Talk

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

* fix(talk): keep realtime bootstrap config redacted

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

* fix(talk): surface failed native fallback

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

* test(talk): inject deterministic relay capture

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

---------

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>
2026-08-23 07:30:30 -07:00
Chris Allbritton 3a50b7a448 fix(macos): restore Settings pane scrolling (#118831)
* fix(macos): restore Settings pane scrolling

* test(macos): stabilize Settings dashboard handoff check

* test(macos): scope Settings layout regression

---------

Co-authored-by: Vitor Cepeda Lopes <vitor@vitorcepedalopes.com>
2026-08-23 04:48:51 -07:00
Peter Steinberger 47436e447e fix(macos): attach the onboarding CLI install prompt to the window (#128183)
* fix(macos): attach the onboarding CLI install prompt to the window

On an unreleased build, the onboarding CLI page resolved its install target
through NSAlert.runModal() — a detached app-modal panel that is absent from
the app's AX window list and freely covered by system permission dialogs.
Live repro: with two TCC prompts stacked over it, the main thread sat parked
in runModal for 30+ minutes while the page showed an active "Install
OpenClaw" spinner, the close button was disabled, and busyReason claimed an
install was in flight — before the user had chosen anything. A spinner that
means "answer a dialog you cannot see" is a silent-failure trap.

The prompt (both the confirm-stable alert and the channel chooser) is now a
sheet attached to the onboarding window via beginSheetModal, so it stays
z-ordered with the window and AX-visible. The busy state is honest: a new
.choosingTarget phase renders the install row as pending instead of running,
and installingCLI/close-disabled/busyReason only engage after a target is
actually chosen. Non-onboarding callers (checkAndPromptIfNeeded) keep
runModal by passing no window. All alert text and button order unchanged.

* style(macos): wrap sheetPresentationWindow property body
2026-08-23 04:09:08 -07:00
Peter Steinberger 3cb52f4bb8 fix(macos): preserve externally owned attach-only gateway (#128134) 2026-08-23 02:00:39 -07:00
ClawSweeper 7d95cff39d fix: macOS onboarding waits for Gateway restart (#127713)
* fix(onboarding): wait for inference gateway restart

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* fix(onboarding): preserve custodian handoff after restart

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* refactor(macos): share activation restart finalization

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* style(macos): format restart reconciliation

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* fix(macos): compile restart finalization

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* test(macos): sequence onboarding restart proof

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* test(macos): finish onboarding after activation

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

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* test(macos): reuse managed restart proof

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

Co-authored-by: Hannes Rudolph <49103247+hannesrudolph@users.noreply.github.com>

* test(macos): assert receipt before handoff cleanup

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

Co-authored-by: Hannes Rudolph <49103247+hannesrudolph@users.noreply.github.com>

* fix(onboarding): keep restart verification bounded

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

Co-authored-by: Hannes Rudolph <49103247+hannesrudolph@users.noreply.github.com>

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>
2026-08-22 15:51:04 -07:00
Peter Steinberger 8b5a02cbf6 fix(mac): serialize persistent node service lifecycle operations (#127732) 2026-08-21 18:17:30 -07:00
Peter Steinberger 51649aa1fa fix(mac): keep local gateway failures on their active route (#127723) 2026-08-21 17:59:35 -07:00
Peter Steinberger ee468b8038 fix(macos): prevent stale port sweeps from killing remote tunnels (#127665) 2026-08-21 15:42:39 -07:00
Peter Steinberger 1257279de6 fix(macos): suppress SIGPIPE on process pipe write ends (#127666)
Writing to a pipe whose reader has already exited raises SIGPIPE, which
kills the whole process instead of throwing. MacNodeHostWorker already
guarded its stdin pipe with F_SETNOSIGPIPE; the codex App Server client
and the MLX TTS helper transport did not, so a child exiting mid-write
could take down the app. Suppressing the signal exposed that an
undelivered App Server request write was reported as appServerUnavailable
even though the frame was provably never sent, so it now requeues once
onto a fresh child instead of failing the caller.

Test-side pipe write ends whose readers are spawned children (or a
readability handler that can close the pipe mid-test) get the same
suppression so a racing reader exit fails the assertion instead of
killing swiftpm-testing-helper with signal 13, which is what caused the
macos-swift CI lane's intermittent unrelated-test crashes (e.g. PR
#126559, run 32341197738 job 96340683947).
2026-08-21 15:40:50 -07:00
Peter Steinberger 7625443195 fix(macos): fence stale Gateway connection-mode transitions (#127609) 2026-08-21 14:46:59 -07:00
Peter Steinberger 887b9dd5e8 fix(macos): keep Cron run history matched to the selected job (#127266)
* fix(macos): own Cron history refreshes

* fix(macos): preserve Gateway recovery across cancellation
2026-08-21 11:13:54 -07:00
Peter Steinberger 0e75204f05 fix(macos): keep first-run onboarding visible after Gateway changes (#127038) 2026-08-20 22:45:44 -07:00
Peter Steinberger 9a64770ea6 fix(macos): unblock remote onboarding after local Gateway failure (#127033) 2026-08-20 22:32:36 -07:00
Peter Steinberger df8fedcc00 fix(macos): isolate profiles and report direct Gateway failures (#127007)
* fix(macos): isolate named-profile development project roots

* fix(macos): report actual direct gateway connection failures

* fix(macos): satisfy SwiftLint remote recovery line limit

* fix(macos): sync native IPv6 endpoint localization inventory

* fix(macos): keep IPv6 endpoint formatting out of localization inventory
2026-08-20 22:08:01 -07:00
Peter Steinberger c7322d761a fix(macos): preserve session kind metadata (#126807) 2026-08-20 12:19:28 -07:00
Peter Steinberger e20a3298b1 fix(macos): install CLI automatically during remote onboarding (#126723) 2026-08-20 09:14:55 -07:00
Dallin Romney d40cbfef47 chore(i18n): refresh native locales (#126696)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-20 09:06:59 -07:00
Peter Steinberger eb84b56766 fix(macos): fail promptly after terminal gateway startup errors (#126697) 2026-08-20 08:25:29 -07:00
Peter Steinberger 923e972564 fix(apple): gate gateway RPC polling on the hello method catalog (#126559)
* fix(apple): gate gateway RPC polling on the hello method catalog

Released 2026.7.x gateways authorize before method dispatch and reject
unknown methods with INVALID_REQUEST / "missing scope: operator.admin",
which never names the method, so the shared Swift kit's error-text
matchers could not detect an unsupported gateway: queued sends wedged in
a delay-free sessions.branches.list reconcile loop, question.list burned
its retry budget per health event, and progressCard.get fired a rejected
fetch per event.

Port the Android fix pattern (#126540): generalize the progressCard-only
transport seam into tri-state gatewayAdvertisesMethod(_:), make hello
catalog parsing distinguish absent (nil) from empty, route branch
listing through a catalog-checking dispatch point with a typed
BranchListingUnadvertisedError, tighten error-text matching to the
modern "unknown method:" shape, and skip question.list/progressCard.get
when unadvertised. Regression tests encode the exact 2026.7.1-2 wire
shape and fail pre-fix (A/B verified).

* fix(apple): keep explicit unsupported branch-listing replies releasing sends

ClawSweeper P1: the tightened matcher dropped the shipped acceptance of
explicit unsupported/unimplemented GatewayResponseError replies that
name sessions.branches.list, which would wedge queued sends on a
pre-catalog gateway emitting that shape. Collapse the matcher onto the
bridged localizedDescription (errorDescription always prefixes the
method name), preserving both legacy qualifier shapes while still
rejecting bare missing-scope denials and the old false-positive-prone
INVALID_REQUEST arm; add the releasing-send regression test.
2026-08-20 07:31:04 -07:00
Peter Steinberger 4b32275970 fix(macos): keep elevation computer control active (#126674) 2026-08-20 06:39:06 -07:00
chelsealong b886eed3de fix(macos): surface concrete Gateway start failure reason in onboarding (#121306)
* fix(macos): surface concrete Gateway start failure reason in onboarding

GatewayProcessManager already retains the specific registration/readiness
failure (e.g. "launchd disabled", a launchd enable error, a readiness
timeout) in lastFailureReason, and Settings/menu bar UI already read it.
Onboarding discarded it: LocalGatewayActivation.failed collapses every
cause to the same generic "Retry setup" message, so a missing LaunchAgent
registration is indistinguishable from any other startup failure.

Surface the retained reason in the onboarding status text so the failure
is diagnosable without going through Settings.

* fix(macos): record command-resolution failures in lastFailureReason

GatewayProcessManager set status but not lastFailureReason when
GatewayEnvironment.resolveGatewayCommand() returns no command (missing
runtime/CLI), unlike the launchd-disabled and launchd-enable-error
branches a few lines below. Onboarding's new failure message therefore
rendered the generic text or a stale reason from an earlier attempt
for this failure class. Mirror the sibling branches and record
resolution.status.message.

Also fixes the macos-swift SwiftFormat lint failure: the comment block
directly above gatewayStartFailureMessage needed to be a doc comment
(///), matching the repo's existing convention for declaration-adjacent
comments.

* fix(macos): bind Gateway start failure reason to its activation attempt

LocalGatewayActivation.failed carried no data, so both onboarding call
sites reread the mutable GatewayProcessManager.shared.lastFailureReason
singleton after activateLocalGateway() returned. A later gateway-start
attempt can overwrite that singleton before the caller gets around to
reading it, so a stale wait could surface a newer attempt's reason (or
vice versa) attributed to the wrong onboarding attempt.

Widen LocalGatewayActivation.failed to carry reason: String?, captured
inside activateLocalGateway() the instant waitUntilReady() resolves to
false, and have both onboarding call sites map that bound value instead
of rereading the singleton. CLIInstallPrompter's two `!= .failed`
comparisons become `if case .failed = activation` pattern matches since
`.failed` is no longer a payload-free value; its existing `case .failed:`
message switch is unaffected, since bare-case patterns still match
regardless of associated data.

* fix(macos): satisfy SwiftFormat lint on CLIInstaller.swift

Converts the LocalGatewayActivation.failed declaration comment to a
doc comment and wraps activateLocalGateway's closing signature per
config/swiftformat, matching the same docComments convention already
applied elsewhere in this PR. No behavior change.
2026-08-20 01:08:12 -07:00
Josh Avant a4f17833ad fix(gateway): make config revision tokens opaque (#126464)
* fix(gateway): make config revision tokens opaque

* test(gateway): cover config revision key startup phase
2026-08-19 16:10:27 -07:00
Peter Steinberger ae55a4090c refactor(canvas): make the panel a widget presenter (#126030)
* refactor(canvas): retire legacy host and commands

* refactor(apple): narrow shared Canvas contracts

* refactor(macos): keep Canvas as widget presenter

* refactor(ios): remove Canvas client

* refactor(android): remove Canvas client

* refactor(linux): remove Canvas client

* fix(ci): isolate native locale artifacts

* fix(linux): regenerate companion lockfile

* fix(canvas): refresh native tool display metadata

* test(canvas): align coverage with presenter surface

* test(canvas): remove obsolete asset root seam

* test(canvas): stabilize retirement CI coverage

* refactor(swift): remove orphaned resource wrapper

* test(ios): remove retired canvas layout assertion

* fix(macos): reserve retired canvas command namespace

* refactor(macos): isolate canvas command policy

* fix(canvas): select only eligible macOS panels

* fix(canvas): keep panel selection plugin-owned
2026-08-19 08:21:07 -07:00
Peter Steinberger 3e0c980aaf fix(models): honor per-agent model metadata (#126194)
* fix(models): honor per-agent model metadata

Resolve per-agent aliases, bare providers, fallbacks, and catalog tags consistently across runtime, CLI, Gateway, sessions, and the Control UI.

* fix(models): preserve projection ownership

* fix(models): carry agent scope through fallbacks

* test(models): complete compaction fallback mock

* test(models): complete startup fallback mock

* test(agents): isolate recovery id expectations

* refactor(protocol): split public schema barrel

* test(cron): await child readiness events

* fix(models): scope native catalogs to session agent

* perf(ui): tighten agent model option projection

* perf(ui): reduce agent model projection overhead
2026-08-19 06:04:24 -07:00
Peter Steinberger 57e5ab7a87 fix(apps): show native gateway and notification failures (#125909)
* fix(apps): surface native action failures

Make iOS gateway reconnect attempts return visible closed outcomes, route macOS gateway deep links through primary setup confirmation, and expose pending/sent/error notification test results across native and Dashboard settings.

* chore(apps): refresh native i18n inventory

* test(macos): isolate gateway cancel state

* fix(ui): accept permission-only notification status

* test(gateway): drain accepted agent run before fixture reset

* fix(ui): notify clients after service worker claim

* test(gateway): wait for accepted root work to drain

* test(ui): isolate widget theme observer window

* test(ui): await durable attachment draft before teardown

* test(agents): use race-safe MCP process cleanup

* test(ui): await cloud startup runtime before error probe

* test(ui): align startup and teardown probes with current owners
2026-08-18 20:15:52 -07:00
Peter Steinberger 4e61d49c42 test(macos): remove NodeInfo encoding contract (#125926) 2026-08-18 11:43:56 -07:00
Hannes Rudolph 34c3d15a6b fix(macos): complete Codex onboarding and model picker (#124829)
* fix(setup): refresh Codex registry with staged install

* fix(macos): verify inference before onboarding handoff

* fix(setup): use native Codex home for subscription auth

* fix(codex): honor attempt-scoped setup config

* fix(macos): align onboarding handoff with reopen

* fix(setup): await prepared model convergence

* fix(ui): avoid false auth state for empty catalog

* fix(setup): scope catalog convergence to Codex gateway

* fix(setup): publish the committed runtime catalog

* fix(models): project configured static runtime models

* fix(codex): expose app-server model catalog

* fix(models): preserve Codex auth across reloads

* fix(ci): align Codex onboarding checks

* test(ui): stabilize dock suppression environment

* fix(codex): honor discovery config in app-server model catalog

The manifest documents discovery.enabled (bundled fallback list) and
discovery.timeoutMs (default 2500ms) for model discovery; the new catalog
path used the generic 60s request timeout and ignored the enable gate.
Also drop the test-only listModels injection seam in favor of vi.mock.

* fix(setup): refuse prepared Codex auth over an explicit remote transport

configureCodexCliPreparedAuth silently rewrote an explicitly configured
websocket/unix app-server to local stdio (keeping a dangling url), moving
the credential boundary onto this host. Fail setup with actionable
guidance instead; also surface the root cause when the prepared model
catalog refresh fails after activation.

* refactor(agents): one canonical model-catalog identity key

Three near-identical key helpers existed (models-list-result,
models-list-configured-static, harness/model-catalog). Export
resolveModelCatalogIdentityKey from the route-policy owner, collapse the
duplicate dedupe loops into dedupeByKey, make donor enrichment Map-based,
and inline the one-off harness-augment wrapper.

* fix(macos): restore custodian handoff for fresh activations

Landing every finish on the plain dashboard stranded the custodian
first-run flow (memory import, channels, permissions, hatch). Fresh
activations now hand off to custodian onboarding; live-verified
pre-existing setups reopen the normal dashboard, matching the removed
already-configured shortcut. Tests pin the destination per path.

Also isolate the post-startup Codex login test from developer machines:
ambient OPENAI_API_KEY and a real Codex login made it assert-fail.

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-17 23:31:12 -07:00
Peter Steinberger 122fc1c786 fix(apps): render legacy plan events when the Gateway lacks the progress-card store (#125588)
* fix(apps): render legacy plan events when the Gateway lacks the progress-card store

progressCard.get ships in no released Gateway tag, so iOS/macOS on any current
release silently showed no status card after the durable-card migration. Restore
legacy stream:"plan" rendering, synthesized into the unified progress card and
gated on a tri-state capability probe so a dual-emitting Gateway never fights the
durable store. Mirrors the Android fix in #125444.

* fix(apps): invalidate progress-card capability on gateway route replacement

A replacement route may be a different Gateway, so a cached known-absent store
must not authorize the legacy plan fallback against a new Gateway that dual-emits
both sources. Clear and re-probe on .routeChanged.
2026-08-17 22:40:55 -07:00
Peter Steinberger 60920998c0 feat(apps): migrate iOS/macOS plan surface to the durable progress card (#125442)
* feat(apps): migrate iOS/macOS plan surface to the durable progress card

Replace the legacy stream:"plan" agent-event pipeline (runId-scoped state,
run-gated pill) with the sessionKey-scoped progress-card store: the shared
chat surface now renders progressCard.get snapshots, refetches on
progressCard.changed pokes with revision dedupe, clears on null-revision
pokes, and persists the card after the run completes. The card renders
markdown through the shared markdown view plus typed steps. Legacy Apple-side
plan handling (agent-event case, run-snapshot plan reconciliation,
OpenClawChatPlanStep parsing) is deleted; gateway emission stays for Android.
Removes the ios progressCard.changed coverage allowlist entry so the check
enforces the handler.

* chore(i18n): refresh native inventory for the progress-card rename

* fix(apps): keep the last progress card when a refresh fails

A transient progressCard.get failure no longer clears an already-rendered
durable card; only a successful null fetch or a null-revision poke clears it.
2026-08-17 18:07:17 -07:00
Peter Steinberger 04c9924c45 fix(macos): keep elevation host CUA-free (#125408)
* fix(macos): isolate elevation host from CUA

* fix(macos): fail closed on unsafe elevation rollback

* fix(macos): quarantine unsafe elevation state before recovery

* fix(macos): bind elevation recovery ownership
2026-08-17 17:03:04 -07:00
openclaw-mantis[bot] 5fe5d26007 chore(i18n): refresh native locales (#125353)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-17 11:00:25 -07:00
Peter Steinberger a2c857ea0e fix: model setup detects CLI logins when AI access checks time out (#125114)
* fix(system-agent): detect CLI logins on setup timeout

* style(macos): format setup detection timeout

* fix(macos): bound setup restart reconciliation
2026-08-17 02:27:18 -07:00
Peter Steinberger b77671ced2 feat(mac): harden Peekaboo elevation cutovers (#124564)
* feat(mac): harden elevation cutovers

* fix(mac): make elevation recovery transactional

* fix(mac): revalidate elevation owner shutdown

* fix(mac): quiesce elevation recovery owners

* fix(mac): close elevation artifact and recovery races

* fix(mac): use signed exclusive app renames

* fix(mac): defer elevation hangup signals

* fix(mac): restore receipts during elevation rollback

* fix(mac): bind elevation receipts to both architectures

* fix(mac): close elevation attestation races

* fix(mac): bind elevation proof to final objects

* fix(mac): keep elevation rollback independently trusted

* fix(mac): validate every rollback generation

* fix(mac): authenticate legacy elevation recovery

* fix(mac): attest recursive Peekaboo sources

* fix(mac): recover when elevation app is unavailable

* fix(mac): preserve raced recovery custody

* test(mac): preserve missing-tool coverage

* test(mac): register recursive gitlink fixture

* fix(mac): authenticate all elevation custody

* fix(mac): bind elevation build and recovery inputs

* fix(mac): persist elevation recovery transactions

* fix(mac): durably publish elevation custody

* fix(mac): complete elevation transaction durability
2026-08-17 02:20:55 -07:00
Peter Steinberger fb32d5df47 fix(macos): stop Talk MLX helpers after shutdown or replacement (#124604)
* fix(macos): reap replaced MLX speech helpers

* fix(macos): scope stale MLX cleanup to requests
2026-08-16 07:13:59 -07:00
Peter Steinberger c82dfdb43a fix(macos): stop idle node setup CPU loop (#124599)
Make validated CLI cache writes idempotent and reuse the startup-scoped node worker launch across route retries, keeping the signed menu-bar app near-zero CPU while idle.\n\nCloses #124592
2026-08-16 06:40:56 -07:00
Peter Steinberger 243f51d314 refactor(macos): name computer-use executors for their scope (#124586)
The computer.act v1 wire contract is gone, but the naming that survived it
still described a version split instead of the real one: screen-coordinate
execution versus window/element-scoped execution. Both are live rungs of the
same ladder.

- Extract the screen-coordinate half of the 1334-line ComputerActionService
  into ComputerScreenActionExecutor (dispatch, typing, scroll, coordinate
  mapping, button-hold watchdog, raw CoreGraphics primitives). Moved code is
  unchanged apart from threading the queue authority check as a parameter
  instead of reaching back into the queue.
- ComputerActionService keeps its name and becomes the coordinator that owns
  the execution queue, the permission probe, and the shared error vocabulary.
- Rename ComputerActionServiceV2 to ComputerWindowActionExecutor, isV2Request
  to isWindowScopedRequest, isComputerActV2Only to isWindowScopedOnly, and
  ComputerActionError.invalidV2Request to .invalidRequest. The emitted
  COMPUTER_INVALID_REQUEST: prefix is unchanged.
- cua-computer: v2-actions.ts becomes window-actions.ts, handleV2Act becomes
  handleWindowAct, and the stale v1Params local in handleDesktopAct becomes
  desktopParams.
- Note at the computer.act idempotency key that its v1 prefix versions the key
  composition, not the wire contract.

Behavior-neutral: no logic edits, no new branches, no changed error strings.
2026-08-16 06:17:31 -07:00