Changes
- Exec approvals: remove the old
cat SKILL.md && printf ... && <skill-wrapper>allowlist compatibility path so skill files must be loaded with the read tool and only the real skill executable is auto-allowed. - Discord: let voice sessions follow configured Discord users into voice channels, with allowed-channel checks, multi-user handoff, bounded reconciliation, and DAVE recovery preservation. (#84264) Thanks @fuller-stack-dev.
- Discord/voice: include bounded
IDENTITY.md,USER.md, andSOUL.mdprofile context in realtime voice session instructions by default, withvoice.realtime.bootstrapContextFiles: []available to disable it. (#84499) Thanks @fuller-stack-dev. - Dependencies: bump the bundled Codex harness to
@openai/codex0.132.0and refresh the app-server model-list docs for the new catalog. - CLI/policy: add the bundled Policy plugin for policy-backed channel conformance checks, doctor lint findings, and opt-in workspace repair. (#80407) Thanks @giodl73-repo.
- Agents/config: allow
agents.list[].experimental.localModelLeanso lean local-model mode can be enabled for one configured agent instead of globally. - Providers/xAI: add device-code OAuth login so remote and headless setups can authorize xAI without a localhost browser callback. (#84005) Thanks @fuller-stack-dev.
- Providers/OpenRouter: honor provider-level
params.providerrouting policy for OpenRouter requests, with model and agent params overriding the defaults. Thanks @amknight.
Fixes
- CLI/tasks: include stale-running task maintenance decisions in
openclaw tasks maintenance --jsonso retained and reconcile candidates explain backing-session, cron, CLI, and wedged-subagent state. (#84691) Thanks @efpiva. - Codex app-server: keep system-prompt reports working when bootstrap hooks provide workspace files with only a path and content, so hook-supplied SOUL/IDENTITY/TOOLS/USER context still reports injected characters correctly. (#84736) Thanks @JARVIS-Glasses.
- Providers/MiniMax music: stop advertising
durationSecondscontrol and remove prompt-injected duration hints, somusic_generatereports MiniMax duration as an unsupported override instead of suggesting MiniMax can enforce track length. Fixes #84508. Thanks @neeravmakwana. - Doctor: warn when sandbox tool policy hides configured MCP server tools before provider requests. (#84699) Thanks @nxmxbbd.
- WhatsApp: update Baileys to
7.0.0-rc12. - Build: suppress per-locale
rolldown-plugin-dts:fake-jsCommonJS dts warnings emitted while bundling the intentionally-inlinedzod/v4/locales/*.d.ctsfiles, sopnpm buildoutput stays readable after the 0.25.1 plugin bump. Thanks @RomneyDa. - CLI/nodes: route lazy plugin-registration logs to stderr for JSON-mode
openclaw nodescommands so stdout stays parseable. (#84684) Thanks @TurboTheTurtle. - Approvals: route manual
/approvedecisions through the trusted approval runtime so active exec and plugin approvals no longer look unknown or expired. - Mac app: update the About settings copyright year to 2026. (#84385) Thanks @pejmanjohn.
- Dependencies: update
@openclaw/fs-safeto0.2.7so OpenClaw's default Python-helper-off policy keeps best-effort Node write fallbacks for private stores, secret writes, run logs, and media attachments on Linux/macOS. - Infra/secrets: restore the fail-closed contract for
tryReadSecretFileSyncso credential loaders that passrejectSymlink: true(Telegram, LINE, Zalo, IRC, Nextcloud Talk tokens) refuse symlinked credential files instead of silently accepting them, and the infra-state CI shard's secret-file symlink test passes again. Thanks @RomneyDa. - Browser: honor the configured image sanitization limit for screenshots and labeled snapshots so browser-captured images follow the same resize policy as other image results. (#84595)
- Doctor: remove unrecognized
models.providers.*.models[*].compat.thinkingFormatvalues duringdoctor --fixso stale provider model config can validate after upgrade. Fixes #77803. - Doctor: warn when
openclaw.jsonstores plaintext secret-bearing config fields, including model provider API keys and sensitive provider headers. (#84718) Thanks @lukaIvanic. - Status: show the configured default, session-selected model, reason, clear hint, and docs link when a session remains pinned to a model that differs from
agents.defaults.model.primary. - WebChat: clear stale typing indicators when session change events mark the active chat run complete.
- Mac app: keep local packaging signed with a stable app identity for permission testing and fix Control UI production builds under current Vite/Highlight.js exports.
- macOS app: update the embedded Peekaboo bridge to 3.2.1 so OpenClaw-hosted UI automation works with current Peekaboo CLI capture flows.
- Cron: deliver preferred final assistant output for successful scheduled runs when trailing plain tool warnings remain in diagnostics instead of marking the run failed.
- fix(mattermost): fail closed on missing channel type [AI]. (#84091) Thanks @pgondhi987.
- Recheck rebuilt system.run argv [AI]. (#84090) Thanks @pgondhi987.
- CLI: keep the private QA subcommand out of exported command descriptors unless
OPENCLAW_ENABLE_PRIVATE_QA_CLI=1, so root help and subcommand markers match runtime registration. (#84519) - CLI/cron: bound
openclaw cron showjob lookup pagination so non-advancing or unboundedcron.listresponses fail instead of hanging the command. Fixes #83856. (#83989) - Agents/messages: stop message-tool-only turns after a successful source-channel
messagesend while keeping transcript mirrors under the session write lock. (#84289) - Agents: filter silent heartbeat response-tool transcript artifacts out of embedded context snapshots so later user turns are not polluted by heartbeat no-op messages. (#83477) Thanks @fuller-stack-dev.
- Agents/OpenAI: log repeated strict tool-schema downgrade diagnostics once per provider/model/tool signature, reducing duplicate debug noise while preserving
strict=falsefallback behavior. Fixes #82930. (#82933) Thanks @galiniliev. - Agents/code mode: spell out the
exectool's JavaScript/TypeScript, no Node module, and catalog-bridge constraints in model-visible schema text so agents can use enabled tools without trial-and-error. (#84269) Thanks @Kaspre. - Codex: give
image_generatedynamic-tool calls a 120s default watchdog when no per-call or configured image timeout is set, so image generation no longer falls back to the generic 30s bridge timeout. (#84254) Thanks @moritzmmayerhofer. - Codex: avoid duplicate dynamic tool terminal diagnostics while large diagnostic backlogs drain without blocking tool responses. (#82937) Thanks @galiniliev.
- CLI/message: include a stable top-level
messageIdinopenclaw message --jsonoutput when channel sends return one. (#84191) Thanks @100menotu001. - Cron: preserve legacy top-level array
jobs.jsonstores when loading or adding scheduled jobs so old cron jobs are no longer treated as an empty store during upgrade. Fixes #60799. (#84433) Thanks @IWhatsskill. - Gateway/agents: use an agent's
identity.namein Gateway agent summaries whenagents.list[].nameis unset, so configured agent labels remain visible in clients. (#84355; refs #57835) Thanks @luoyanglang. - Channels/replies: keep normal
/verbosefailed-tool progress compact in message-tool replies and prevent late text-only tool output from appearing after the final answer. (#84303) Thanks @VACInc. - Plugins/hooks: apply a default 30-second timeout to
before_compactionandafter_compactionhooks so a hung plugin handler no longer blocks compaction completion. (#84153) - Discord: preserve disabled presentation buttons when adapting and rendering Discord message controls. (#84188) Thanks @100menotu001.
- Twitch: add a test-only client-manager registry reset helper so non-isolated Twitch tests can clear cached managers between cases. Fixes #83887. (#84244) Thanks @hclsys.
- Cron: run main-session scheduled work on a cron-owned wake lane while preserving reply delivery context, so background cron turns no longer block human main-session chat. Fixes #82766. (#82767) Thanks @galiniliev.
- Cron: use structured embedded-run denial metadata for isolated scheduled tasks so blocked exec requests fail the job without treating ordinary assistant prose as a denial. (#84067) Thanks @abnershang.
- Cron: keep recovered tool warnings diagnostic for successful scheduled runs so final cron output is delivered instead of being replaced by a post-processing warning. (#84045) Thanks @abnershang.
- Plugins/perf: thread explicit plugin discovery results through
loadBundledCapabilityRuntimeRegistry,resolveBundledPluginSources, andlistChannelCatalogEntriesso callers that already hold a discovery result skip redundant filesystem walks. Thanks @SebTardif. - harden update restart script creation [AI]. (#84088) Thanks @pgondhi987.
- Docker: keep the bundled Codex plugin in official release image keep lists so the default OpenAI agent harness remains available after Docker pruning. Fixes #83613. (#83626) Thanks @YuanHanzhong.
- CLI/channels: preserve the first line of
openclaw channels logsoutput when the rolling tail window starts exactly on a line boundary, mirroring the already-fixedreadLogSlicebehavior insrc/logging/log-tail.ts. - Control UI: treat terminal session status as authoritative over stale active-run flags so completed terminal runs stop showing abort/live UI. (#84057)
- CLI: preserve embedded equals signs in inline root option values instead of truncating after the second separator. (#83995) Thanks @ThiagoCAltoe.
- Matrix/config: accept
messages.queue.byChannel.matrixqueue overrides and keep queue provider schema/type keys aligned for Matrix, Google Chat, and Mattermost. Thanks @bdjben. - CLI: format
openclaw acp clientfailures through the shared error formatter so object-shaped errors stay readable instead of printing[object Object]. Fixes #83904. (#84080) - Providers/Ollama: default unknown-capabilities models to tool-capable so discovered native Ollama models can use tools when
/api/showomits capabilities. (#84055) Thanks @dutifulbob. - Installer/Windows: launch
install.ps1onboarding as an attached child process so fresh native Windows installs do not freeze visibly atStarting setup...or corrupt the wizard's terminal rendering. - CLI/update: keep restart health checks working across one-version CLI/Gateway protocol skew and use the managed Gateway service Node for all follow-up commands even when the package root is unchanged, so
openclaw updateno longer silently switches the gateway to a different Node binary when multiple Node installations are present. Thanks @amknight. - CLI/gateway: include the running Gateway version in
gateway statusJSON output, preserving existing server metadata while falling back to status RPC data for read probes. Fixes #56222. Thanks @galiniliev. - Memory/search: close local embedding providers when active-memory searches time out so pending local model loads and embedding contexts are aborted and released. (#83858) Thanks @brokemac79.
- CLI/nodes: request pending node surface approval scopes before
openclaw nodes approveso exec-capable node approval can use admin-scoped Gateway credentials instead of failing withmissing scope: operator.admin. (#84392) Thanks @joshavant. - Gateway: reject slow node event sends before outbound buffers grow unbounded and log the rejected payload diagnostic. (#84387) Thanks @samzong.
- Agents: include bounded trajectory queued-writer diagnostics in
pi-trajectory-flushtimeout warnings so flush stalls show pending writes, queued bytes, and append state. Fixes #82961. (#82962) Thanks @galiniliev. - Agents/subagents: recover stale completion announces by retrying unsupported transcript-wait wakes without transcript waiting and forcing a message-tool handoff when the requester run is already stale. Fixes #83699. (#83700) Thanks @galiniliev.
- Agents/subagents: constrain wildcard subagent target allowlists to configured agents while preserving explicitly listed compatibility targets. Fixes #84040. (#84357) Thanks @joshavant.
- Providers/Anthropic: route Anthropic model refs selected with Claude CLI auth through the Claude CLI runtime so shorthand refs such as
anthropic/opus-4.7no longer fall back to embedded Anthropic billing. Fixes #84222. (#84374) Thanks @joshavant. - Agents: honor explicit
models.providers.<id>.timeoutSecondsvalues above the default idle watchdog for cloud and self-hosted providers, so long first-token waits no longer fall back at ~120s when the provider timeout is higher. (#83979) Thanks @yujiawei. - Agents/Codex: keep encrypted Responses reasoning replay provenance-bound so stale mirrored Codex transcripts drop invalid encrypted content before request assembly while preserving matching same-session replay. Fixes #83836. (#84367) Thanks @joshavant.
- Agents/subagents: skip stale embedded-run wake probes for dormant completion requesters, so late subagent completions go straight to requester-agent/direct handoff instead of producing
reason=no_active_runqueue noise. (#82964) Thanks @galiniliev. - CLI: retry config snapshot reads after a transient failure so one rejected read no longer poisons later commands in the same process. (#83931) Thanks @honor2030.
- Media: decode URL path basenames before using them as remote media fallback filenames, so files like
My%20Report.pdfare surfaced asMy Report.pdf. Fixes #84050. (#84052) Thanks @jbetala7. - WhatsApp: clarify inbound group diagnostics so observed but unregistered groups point to
channels.whatsapp.groupswithout changing routing or sender authorization. (#83846) Thanks @neeravmakwana. - WhatsApp: drain pending outbound deliveries on a 30s periodic timer in addition to the reconnect handler, so messages enqueued while the provider is already connected no longer wait for the next reconnect to send. (#79083) Thanks @Oviemudiaga.
- CLI/TUI: include gateway plugin slash commands in TUI autocomplete, so connected sessions can suggest plugin-owned commands exposed by the running Gateway. (#83640) Thanks @se7en-agent.
- Gateway/mobile: restore QR setup-code handoff of bounded operator tokens for iOS and Android onboarding while keeping admin and pairing scopes out of bootstrap. (#83684) Thanks @ngutman.
- iOS: repair Release archive compilation for the TestFlight build. (#84255) Thanks @ngutman.
- Agents/compaction: bound plugin-owned CLI transcript compaction with the host safety timeout so a hung context engine can no longer stall post-turn cleanup. (#84083) Thanks @100yenadmin.
- Control UI/usage: truncate long context skill, tool, and file names in the usage panel while keeping the full name available on hover. (#42197) Thanks @Rain120.
- Codex: respect explicit
models auth order setandconfig.auth.orderprecedence over stalelastGoodin/codex account, and showno working credentialwhen every explicit-order profile is ineligible instead of marking a lower-ranked profile as active. Fixes #84386. (#84412) Thanks @openperf. - Agents: honor
messages.suppressToolErrorsfor mutating tool failures so configured chat surfaces do not receive separate warning payloads. (#81561) Thanks @moeedahmed. - Agents/fallback: surface billing guidance for mixed rate-limit plus billing fallback exhaustion instead of generic failure copy. Fixes #79396. (#79489) Thanks @aayushprsingh.
Release verification
- npm package: https://www.npmjs.com/package/openclaw/v/2026.5.20
- registry tarball: https://registry.npmjs.org/openclaw/-/openclaw-2026.5.20.tgz
- integrity:
sha512-cgshS76CxS3Vp9NGtJR2UGtVZxVR5/4rvok8DKGGL19DugAftNabsXfYajyAEiJ3dC8QTXNqF62MdQNzUnQe8Q== - release publish: https://github.com/openclaw/openclaw/actions/runs/26251157671
- npm preflight: https://github.com/openclaw/openclaw/actions/runs/26248551138
- full release validation: https://github.com/openclaw/openclaw/actions/runs/26248546974
- plugin npm publish: https://github.com/openclaw/openclaw/actions/runs/26251316669
- plugin ClawHub publish: dispatched separately, not awaited by this proof: https://github.com/openclaw/openclaw/actions/runs/26251319171
- OpenClaw npm publish: https://github.com/openclaw/openclaw/actions/runs/26251677950
- npm Telegram beta E2E: not supplied