* feat(linux): suspend the local gateway across host sleep via logind
Mirror the macOS sleep cycle in the Tauri companion: a logind
PrepareForSleep listener with a delay inhibitor best-effort prepares a
local gateway suspension before sleep and resumes it on wake with a
reconnect nudge and bounded retries; leases are route-bound, always
cleared on wake, and late prepare responses resume immediately.
* fix(linux): keep the sleep listener alive when inhibitor re-acquire fails
* fix(linux): activate the driver for sleep cycles and bound driver-side sleep RPCs
Sleep cycles temporarily unpark the gateway driver so prepare/resume work
without the Quick Chat window; suspend RPCs carry a 3s driver-side budget
that recycles a hung socket instead of starving wake retries; a mock-logind
integration test exercises the Linux listener end to end.
* fix(linux): count overlapping sleep cycles instead of a boolean flag
An older wake task ending late cleared the shared activation flag and
parked the driver mid-cycle; a saturating depth counter keeps the driver
active until the last cycle ends.
* fix(linux): gate sleep-cycle activation on loopback routes and never block wake on logind
Remote or unconfigured routes no longer activate the driver during
sleep, the paired end hook runs only for cycles that began, and wake
recovery is spawned before the inhibitor re-acquire so a slow logind
cannot delay reconnect/resume.
Align copyable onboarding commands with the mandatory risk acknowledgement and an explicit health disposition for config-only automation.\n\nRefs #121951.
* fix(ui): confirm disruptive Control UI updates before dispatch
Every Control UI update affordance dispatched `update.run` (or the macOS
bridge `start-update` message) on the first click, so a misclick could
install new code, restart the Gateway, and interrupt active work.
Add one canonical confirmation gate in the Control UI owner boundary and
route the sidebar/settings-sidebar/floating update card and the
Settings -> Updates row through it. The gate owns the copy, the versions,
the restart consequence, the action-specific confirm label, and the
choice between the macOS bridge and `update.run`, so the bridge fork no
longer lives in the card and no surface can drift.
CLI, API, automation, agent-driven paths, automatic update campaigns, and
the `update.run` contract are unchanged.
Addresses the Control UI portion of #117178.
* style(ui): apply oxfmt to update confirmation sources
* perf(ui): load the update confirmation lazily and share its impact copy
Keeps the Control UI startup bundle under its 317 KiB gzip ceiling: the
confirmation dialog only loads when an operator opens it.
* test(ui): drive the update confirmation in sidebar and shell wiring tests
* 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
* fix(macos): let onboarding replace an auto-connected AI
The AI page auto-tests the best detected candidate and connects without
asking, then hides every alternative route. Add 'Choose a different AI'
to the connected banner: a re-detect pass with auto-activation
suppressed that ends at the picker (candidates, provider sign-in, API
keys). Also disable the manual key Connect button while another test
runs (submitManualKey silently dropped the tap), and isolate a test
that read the machine's real resume store.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(macos): surface real daemon errors past the Node banner
Gateway daemon failures summarized as 'Node.js v26.5.1' because the
summary takes the last non-empty line and Node fatal errors end with a
version banner. Drop trailing banner lines and prefer the last
error-shaped line above them; all other output keeps its last line.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(macos): hand onboarding off to the dashboard custodian
Native onboarding now ends once inference verifies: welcome, connection,
install (when needed), AI setup. Finish opens the dashboard at
/custodian?onboarding=1, where the custodian onboarding owns memory
import, channels, app recommendations, and the hatch (browser-first per
the onboarding redesign). The native memory-import and permissions
pages leave the first-run flow; 'Set up later' keeps the native ready
page. The native navigation bridge gains a validated optional search
field so the handoff can request onboarding chrome; the URL fallback
carries the query alongside the token fragment.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor(macos): delete the unreachable native memory-import module
The dashboard handoff removed the memory-import page from every flow,
leaving the module reachable only from tests. CI's dead-code scan
rightly flagged the first orphans; remove the whole path (model, page,
mascot wiring, tests) instead of trimming symbol by symbol. The
dashboard's own memory-import surface owns the feature.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(talk): emit realtime models and voices in talk.catalog and mirror create-time readiness
* feat(ui): add curated Talk settings page with catalog-driven pickers
* docs(talk): correct stale claims and add one-page GPT-Live setup path
* fix(ui): refresh Talk catalog on config-hash advance and neutralize GPT-Live badge
* fix(ui): provider-aware Talk selection, atomic provider switch, focus refresh
* fix(ui): resolve Talk provider fallbacks via catalog and make Default a true reset
* fix(ui): provider-compatible transports and race-free Talk catalog loads
* fix(ui): never resolve an unknown explicit Talk provider to the active one
* docs(talk): note Android relay readiness caveat for browser-only models
* fix(ui): keep the relay transport when switching Talk provider to Auto
* fix(ui): align section-ownership test and drop unused export after rebase
* 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(mac): show native notification permission in dashboard Notifications settings
The Mac app's embedded Control UI showed the web-push section as
Unsupported/Not subscribed even though the app delivers notifications
natively. The dashboard now installs an openclawNotifications WebKit
bridge (status / request-permission / send-test) and the Notifications
settings page renders native permission state with Enable, Open System
Settings, and Send test actions when hosted in the Mac app. Browsers
keep the existing web-push UI. The notifications section renderer moved
out of the oversized config view module.
* fix(ui): break config view import cycle and satisfy lint/deadcode/i18n gates
Move the notifications section props to a leaf contract (no view.ts
type import), unexport the status-event constant, use bracket access
for the injected dunder global, default-case the status switch, and
refresh the native i18n inventory line offset.
* 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