The openclaw-mlx-tts voice helper pulls in the full mlx-swift Metal shader
stack, which some beta Xcode toolchains (e.g. Xcode 27 / macOS 27 SDK) cannot
compile: the metal compiler dies non-deterministically (a different .metal file
each run, 'Could not read serialized diagnostics file'). The main app builds
fine, so an unrelated dev/proof build should not be blocked by the helper.
Add OPENCLAW_SKIP_MLX_TTS=1 (matching the sibling SKIP_TSC/SKIP_UI_BUILD
toggles) to package the app without the voice helper, gating both the per-arch
build and the bundle copy. Refuse the flag for release builds, which must ship
the helper (notarization verifies it), so a skipped build can never become a
silently incomplete release.
Background-only Bridge and Mac-node launches keep GUI onboarding and saved Gateway-profile Keychain state cold while preserving environment/config-owned Gateway connectivity.
* feat(macos): add native camera PTZ controls
Add physical UVC pan, tilt, and zoom through the signed Mac app, with camera.ptz.control kept behind dangerous-command approval. Verified against real Insta360 Link 2 Pro hardware.
* refactor(agents): split message tool display config
* fix(mac): harden camera PTZ contracts
* docs: recommend Node 26 in quickstart, landing, and platform install docs
- Problem: the user-facing quickstart (docs/start/getting-started.md), landing
page (docs/index.md), and Linux/macOS platform install docs still mark
Node 24 as the recommended default, contradicting maintainer PR #114399
('recommend Node 26 as the OpenClaw runtime') and the installer default
(scripts/install.sh NODE_DEFAULT_MAJOR=26, openclaw.mjs
RECOMMENDED_NODE_MAJOR=26). Users following the quickstart pick a slower,
heavier runtime against the project's stated recommendation.
- Fix: align the 4 missed user-facing install surfaces to 'Node 26
recommended', matching the phrasing already in docs/install/node.md,
docs/install/index.md, docs/install/ansible.md, docs/install/bun.md, and
docs/help/faq-first-run.md. Leave docs/start/setup.md (the source/dev
workflow where CI pins Node 24) unchanged on purpose.
- Verification: docs-only diff reviewed; supported-version floors
(22.22.3+/24.15+/25.9+) unchanged; consistent across all install surfaces.
* docs: complete Node 26 installation guidance
Co-authored-by: Santhi Prakash <b.santhiprakash@gmail.com>
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* refactor(infra): move exec approvals into the shared SQLite state DB
Delete the file-runtime exec-approvals store (exec-approvals.json + .lock
sidecar machinery) on both runtimes and make the reserved
exec_approvals_config singleton row canonical. Doctor owns the one-time
import with claim/verify/receipt discipline; runtime fails closed with a
doctor instruction while un-migrated legacy state exists. The wire CAS
contract, socket semantics, and gateway auth-token derivations are
unchanged. Kills the #113929 lock-contention bug class structurally and
nets around -2.9k lines.
* fix(infra): green CI gates and retire file-era exec approvals tests
Break the migration-type import cycle with a leaf contract, regenerate the
plugin-SDK API and native i18n baselines for the intentional surface change,
drop unused exports, and replace the macOS file-era approvals test suite with
SQLite-backed behavior coverage per the obsolete-internals test policy.
* chore: green max-lines ratchet, native i18n baseline, and unused-export scan
* fix(macos): resolve OPENCLAW_STATE_DIR in openclaw-mac CLI config resolution
Add shared resolveOpenClawConfigURL() to GatewayConfig.swift with
precedence: OPENCLAW_CONFIG_PATH > OPENCLAW_STATE_DIR > default home.
Switch ConfigureRemoteCommand and loadGatewayConfig to use it.
Add focused tests for all three precedence paths.
* fix(macos): honor state directory in openclaw-mac
Use one normalized config resolver for connect, wizard, and configure-remote, with explicit config path precedence over the selected state directory.
Co-authored-by: liuhao1024 <sunsky.lau@gmail.com>
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* feat(macos): add Quick Chat power features
* docs(macos): document Quick Chat power features
* chore(i18n): refresh native locale artifacts for Quick Chat power features
* fix(macos): update DEBUG test helper sendProvider to the reasoning-threaded arity
* feat(macos): add Quick Chat capture context
* docs(macos): describe Quick Chat capture context
* fix(macos): bound the AX text walk with deadline, cancellation, and per-message timeout; keep distinct repeated text
* fix(macos): ancestry-scoped echo suppression and adapter-wide AX timeouts
* fix(macos): hard outer timeout abandons a hung AX walk
* fix(macos): truly abandon hung AX walks; hide the bar synchronously before area selection
* chore(i18n): refresh native locale artifacts for Quick Chat capture strings
* feat(clients): gateway session groups, batch operations, session inspector, and new-session options
* chore(i18n): translate session management strings and regenerate catalogs
* chore(i18n): complete translation artifacts for session management strings
* fix(clients): fail closed when a transport cannot honor agent or base-ref session options
* fix(clients): authoritative agent identity for new-session parents and revision-keyed sidebar group refresh
* fix(clients): refetch session groups on remote catalog events and correct Swedish repository-root translation
* fix(clients): resilient new-session popover, revision-keyed group manager, and popover string translations
* fix(clients): scope reset fallback to plain new-session requests and revision-key the inspector groups
* fix(clients): reject empty agent catalogs and refresh sessions on remote group events
* refactor(clients): drop unused agents fetch wrapper and runtime memberwise init flagged by periphery
* chore(i18n): realign locale artifacts after rebase onto model-controls main
* chore(clients): split session creation into the session-actions extension and realign i18n after ask-user main rebase
* chore(i18n): resync derived artifacts after question-card main rebase
* feat(clients): provider-grouped model picker with fast, verbosity, and inherited-thinking controls
* chore(i18n): translate model-control strings and regenerate platform catalogs
* feat(clients): inherited-default restore for fast mode and verbosity controls
* fix(clients): preserve control state in thinking snapshots and persist inherited verbosity
* chore(i18n): resync native inventory after rebase onto message-reader main
* chore(i18n): realign locale artifacts after rebase onto message-reader main
* refactor(clients): drop superseded fast-mode accessors and picker convenience flagged by periphery
* chore(i18n): resync inventory line refs after dead-code removal
* feat(clients): copy visible markdown, full-message reader for truncated messages, and independent reasoning/tool toggles
* chore(i18n): translate new reader and trace strings and regenerate catalogs
* test(ios): adopt reader display-options API in render smoke tests
* fix(macos): stop Canvas presents from stealing focus
Agent-driven canvas.present/canvas.navigate activated the app with
NSApp.activate(ignoringOtherApps:), yanking keyboard focus from
whatever the user was doing. The Canvas panel's elevated window level
already keeps it visible without app activation, and user entry points
(AppNavigationActions) activate explicitly, so presentation now orders
the panel front without switching apps.
* fix(macos): order Canvas front without taking key focus
* fix(macos): drop showWindow from Canvas window presentation
* fix(macos): keep Canvas hidden for agent content operations
Agent canvas.evalJS, canvas.snapshot, and canvas.a2ui.* commands routed
through CanvasManager.show, which re-presented the panel and called
NSApp.activate(ignoringOtherApps:) on every content update. After a
gateway restart the hosted A2UI page is dead, so the next agent push
always re-opened a panel the user had closed and stole focus.
Content operations now use a non-presenting ensureController/prepare
path; only canvas.present, canvas.navigate, and user actions reveal the
panel. Snapshot is read-only: it requires a visible matching panel and
returns CANVAS_HIDDEN instead of mutating panel state (WebKit cannot
render ordered-out windows).
* chore(i18n): refresh native inventory line offsets
* feat(mac): Quick Chat v2 — enable toggle, agent avatars and switching, zoom entrance, window screenshots
- Settings toggle (openclaw.quickChatEnabled) gating hotkey, menu item, recorder
- agent chip renders avatar image (data URIs only; remote URLs deliberately not
fetched to avoid SSRF), emoji, or tinted monogram; native NSMenu agent picker
routes via canonical agent:<id>:<mainKey> or global+agentId per server contract
- 'main session' capsule removed; placeholder carries the identity
- fade+zoom presentation (96% scale in, 97% out) via frame+alpha animators
- window screenshot picker: labeled overlays on renderable windows (Peekaboo
filtering + z-order hit tests), overlays torn down pre-capture, SCK window
capture, ChatImageProcessor JPEG, auto-send as chat.send attachment with the
draft or a default caption; ownership-token pipeline bound to presentation
and route; user-initiated Screen Recording alert; cancellable bounded discovery
- ⌘Return opens the accepted route's session; global-scope agent threading is a
filed follow-up; locale artifacts refreshed for new strings
* chore(mac): regenerate i18n inventory after rebase onto main
* feat(clients): session detail parity — row actions, unread auto-clear, and subagent tree in the native chat sidebar
* fix(clients): overlay pending explicit unread values over stale session snapshots
* chore(i18n): translate new session action strings and regenerate Apple/Android catalogs
* chore(clients): delete dead pin helper and worktree memberwise init
* feat(macos): honor the selected microphone in Talk and surface live level, transcript, and mic picker in chat
* chore(i18n): translate new talk activity strings and regenerate Apple/Android catalogs
* feat(mac): add Quick Chat floating composer with global shortcut
- Spotlight-style non-activating key panel on Option+Space (KeyboardShortcuts
3.0.1 exact-pinned, recorder row in Settings -> General) plus a menu bar item
- shows the main-session agent identity via agent.identity.get with a
'main session' chip; Return sends via chat.send reusing the idempotency key
on ambiguous retries; Cmd+Return also opens full chat; Shift+Return newline
- targeted permission strip (notifications/accessibility/screen recording)
with a scoped 1s status poll while visible; grant flow keeps the bar alive
and avoids PermissionMonitor's AppleScript probe
- extract shared ChatSendStatus acceptance mapping; TalkModeRuntime adopts it
- rename anchored-panel 'quick chat' wording to 'compact chat panel'; docs
* chore(mac): regenerate docs map and native i18n inventory for Quick Chat
* ci: retrigger checks after stalled push event
* chore(mac): refresh native locale artifacts for Quick Chat strings
* chore(android): regenerate locale strings for refreshed shared translations
Both settings grant local UI automation, so run PeekabooBridge only while
Allow Computer Control is on. The toggle now reflects the effective state and
is disabled when Computer Control is off; users drive Peekaboo via its own Mac
app in that case. Removes the confusing standalone bridge switch.
* feat(mac): redesign menu bar critter to match the mascot
* fix(mac): draw happy-eye arcs upward and guard stale celebration expiry
* docs(mac): update menu bar icon states for critter redesign
* fix(mac): own celebration expiry with a start-only generation counter
* fix(mac): give voice-wake antennae real headroom at 18pt
* docs(gateway): add launchd supervisor loop troubleshooting
* docs(gateway): warn before disabling node LaunchAgent
* chore: trigger CI after rebase onto main
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(gateway): modernize launchd recovery runbook
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>