* feat(node): update headless runtimes automatically when idle
Stage private packaged node runtimes and activate only after all owned work
and cleanup settle. Preserve pairing and launch options, keep automatic
activations at least 12 hours apart, and leave shared-state migration and
Gateway installation ownership with the normal updater.
Document defaults, opt-outs, runtime version discovery, and recovery.
Support recoverable Windows selector replacement across service restarts.
Refs #151462
* fix(node): complete auto-update integration and settings defaults
Capture the launcher in compiled test runtimes and trusted wrapper inventories, register the package update proof, and use the canonical Kysely read path. Preserve the inherited enabled state in the config UI and align caller tests with the node shutdown lifecycle.
* fix(node): preserve retained plugin work during automatic updates
Require an explicit idle result from plugin commands, preserve older-plugin work, and connect bundled lifetime owners to automatic node updates. Join canceled inference and failed terminal cleanup before command settlement; keep historical state repair with Doctor. Document compatibility and extend installed-package proof for retained legacy plugin work.
* test(browser): align idle-work fixtures with runtime exports
* test(browser): extract proxy request fixtures
* test(node): retain idle assertions across native cleanup
* feat: add contextual plugin help to Ask OpenClaw
Punchcard-Session: crisp-summit-lantern-qk
* fix(ui): redact URL credentials from plugin Ask drafts
Reuse the canonical URL policy in the bounded help-value scan, including
serialized map keys. Keep the editable config value intact and prove
rejected Save → Ask → Send on desktop and phone.
Punchcard-Session: crisp-summit-lantern-qk
* test: reuse the complete Custodian context fixture
Punchcard-Session: crisp-summit-lantern-qk
* refactor(ui): narrow plugin help selection input
Accept only the loaded selection facts consumed by the help controller, removing its type dependency on the complete page renderer model.
Punchcard-Session: crisp-summit-lantern-qk
* perf(ui): keep plugin help preparation off startup
Separate synchronous dock state and session ownership from lazy question preparation and session persistence helpers. Register plugin-only English copy with its lazy consumers while preserving source catalog order.
Punchcard-Session: crisp-summit-lantern-qk
* style: normalize contextual help rebase spacing
Punchcard-Session: crisp-summit-lantern-qk
* perf(ui): keep attachment media preparation off startup
Punchcard-Session: crisp-summit-lantern-qk
* test(qwen): fix the clock for default timeout assertions
Punchcard-Session: crisp-summit-lantern-qk
* test(ui): wait for side-chat opening focus
Punchcard-Session: crisp-summit-lantern-qk
* chore(pr): deduplicate wrapper dependency inventory
Punchcard-Session: crisp-summit-lantern-qk
* test(qwen): drop superseded default-clock workaround
* feat: group bundled plugin settings by authored manifest metadata
Punchcard-Session: crisp-summit-lantern-qk
* feat: give every plugin a compact chat activity icon
Separate package-owned activity SVGs from plugin identity artwork. Ship 154 defaults and seven exact tool overrides, preserving Echo and the progress claw. Include authenticated bounded delivery, safe mask rendering, packaging, and authoring guidance.
* test: declare Vite types for the activity asset browser test
* refactor: keep plugin artwork selection with catalog presentation facts
* test: scope activity browser types and simplify fixture copies
Forward-port the shipped updater, Doctor, schema, and skill snapshot fixes.
Align package metadata and the exact tagged release notes without changing
mobile release versions or any published artifact.
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Align root, native source, plugin and companion version metadata with the published stable release. Preserve newer main code and translations, regenerate the channel catalog, and copy the exact tagged release-note section without adding another release train. Native appcast and locale refreshes remain with their independent owners.
Files added to paired-node CLI terminals now insert editable paths with the correct native quoting, including spaces and apostrophes, without submitting input.
Refs #137116.
Keep dollar replacement tokens literal and reject incoming Markdown
insertion sentinel values before writes or dry-run previews. Share the
existing Markdown and JSON serializers, remove redundant Matrix context
branching, and use one ordered provider catalog auth selector.
Preserve complete selected auth results and synchronous unbound lookup.
The new private host export requires synchronized core/plugin release
preparation to advance compat.pluginApi; do not independently publish
these official plugins with the older floor.
* refactor: simplify command rendering and diagnostic plumbing
* refactor(providers): share exact effort profile parsing
Keep model overrides and API fallbacks in their provider owners. The shared helper has no runtime imports so eager policy loading retains its narrow dependency graph.
Official plugin packages gain a host runtime dependency. Publish this with the next synchronized core and plugin release, whose canonical release sync advances pluginApi floors; do not publish these plugins alone with the existing older API floor.
* chore: prune removed provider assertion allowances
* fix(google): declare bundled Gemini models in the plugin manifest model catalog
* fix(google): scope manifest catalog mirror to canonical provider and declare shared-model tiers
Address ClawSweeper review on #139243:
- drop google-gemini-cli / google-vertex manifest mirrors so legacy CLI refs
keep their Doctor migration hint and CLI/Vertex rows stay out of runtime
catalog planning (neither declares runtime discovery)
- declare explicit capable code-mode tiers on the five sibling rows newly
matched by the shared-upstream-model contract (opencode, github-copilot, gmi)
- strengthen the drift guard to full-row equality against the runtime static
catalog and pin the CLI/Vertex no-mirror boundary
- add regression test keeping the google-gemini-cli migration hint alive
* fix(google): preserve native Gemini transport in the manifest catalog mirror
* fix(google): derive catalog from manifest
* fix(google): tighten manifest catalog validation
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Related: #136257. Builds on merged #139357.
Make all bundled shared-helper catalog callers report actual acquisition failures and authoritative empty results. Preserve shipped external advisory defaults through the same transport/cache implementation.
The existing publication owner retains compatible learned inventory or degraded provider-owned starters. Static preparation consumes registered hooks with their authoritative plugin identity, without activating unknown runtimes or widening successful empty membership. No operator option, persistence schema, new cache, or auth re-observation is introduced.
Proof: retained built baseline failure, packaged CLI/Gateway fault/recovery/empty checks, public SDK/provider API compatibility, fresh/upgrade starter checks, and the decisive seven-clause downstream composite on exact shared head 5e0ecef411cc7bcabbcab2672227910a05209ffd. Composite 296bfa19ec7663044ce50b8ebb3652555900d531 adds only the unchanged separate DeepInfra/NVIDIA producer patch; that patch is not part of this PR. Controlled clock advancement and fixture-rejected background inference are disclosed. No real vendor inference or UI claim.
Production net +199; tests/support +313; docs +34; ratchet metadata -1; generated/lockfile delta zero. Growth preserves shipped API and shared failure/empty/ownership contracts rather than adding parallel provider policy.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* chore(release): carry shipped 2026.9.2 state onto main
Align main and official plugin versions with the published stable release and
preserve the exact tagged changelog. All ten canonical runtime/qualification
fix commits are already on main; retain its newer SQLite worker and Watch UI.
Refresh generated UI and native locale artifacts through their canonical
owners after provider failures left main's current inventories out of sync.
The release tag and published package bytes remain unchanged.
* chore(release): isolate generated locales from version closeout
Keep release version metadata and the exact published changelog in this PR.
Generated UI locales are covered by #139382; native locales use #139364.
Set main to the shipped stable version 2026.9.1 (root, apps, plugins, and
version-owned generated metadata via `pnpm release:prepare`), make the
`## 2026.9.1` changelog section identical to the tagged release branch, and
carry the native locale refresh that the release preflight requires.
Release: https://github.com/openclaw/openclaw/releases/tag/v2026.9.1
npm: openclaw@2026.9.1 (latest, beta); 89 @openclaw/* plugins at 2026.9.1.
* fix(opencode-go): send OpenClaw User-Agent on native OpenCode Go routes
OpenCode Go's documented client-identification contract requires coding
agents to identify themselves with a specific User-Agent. opencode-go
requests previously carried only the generic OpenAI SDK fallback.
Add a vendor-documented attribution policy for opencode-go that sets
User-Agent: openclaw/<version> only on the verified native OpenCode Go
endpoint; Zen and custom-proxy routes are unchanged. Route the Anthropic
transport through the same central policy via the plugin stream wrapper
so both Go transports identify consistently, with caller headers winning.
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* fix(opencode-go): send OpenClaw User-Agent on native OpenCode Go routes
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: 2182e49f-af02-4250-864c-f7777a89eb83
* test(opencode-go): prove User-Agent precedence
Cover configured User-Agent replacement on native OpenCode Go requests across OpenAI-compatible, Anthropic stream, and simple-completion paths. Custom proxy routes retain the configured value.
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* fix(opencode-go): send OpenClaw User-Agent on native OpenCode Go routes
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: 41cb2f26-9a12-4b40-b903-2d5b2fc3ccbd
* fix(opencode-go): scope attribution to Go routes
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* fix(ai): merge transport headers case-insensitively
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* fix(opencode-go): send OpenClaw User-Agent on native OpenCode Go routes
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: e353cea0-b205-4dde-bded-b9bf49b93cec
* test(opencode): keep Zen live replay on free model
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* Publish openclaw/openclaw-openclaw-vacinc-issue-135538
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: 2d3d8e21-99a1-4cd1-a90e-9ee00e647982
* Publish openclaw/openclaw-openclaw-vacinc-issue-135538
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: 5bffe897-9d10-4b1b-b7de-550c3b400168
* test(opencode): use replay-capable free Zen model
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* test(opencode): use interleaved free Zen model
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* test(opencode): stabilize free Zen live smoke
Worked on by:
- @VACInc
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
---------
Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* fix(models): refresh native pricing without pinning defaults
Use complete native OpenCode and Venice pricing schedules while preserving
authored zero, partial, flat and tiered costs across preparation and lookup.
Avoid generated price pins during fresh merge-mode Venice onboarding.
Follow-up to #133349 (cached long-context accounting) and #129694
(Venice runtime pricing); related to #113549 (broader OpenCode catalog drift).
* fix(pricing): preserve native schedules through resolution
Merge prepared costs beneath authored display prices, retain validated native
free schedules under exact owner policy, and compile OpenRouter overrides
with strict thresholds and source-order inheritance for each price key.
Preserve zero, partial, flat and tiered user pricing without new settings
or storage. Follow-up repairs for #133695.
* perf(plugins): keep provider policy artifacts on leaf module graphs
Provider policy artifacts (provider-policy-api.js) load eagerly whenever a
provider is resolved, but five of them imported the provider-model-shared
barrel at runtime, dragging the transports/compat/state graph into every
policy load. In contexts without a native TS require hook (Vitest workers,
non-tsx source runs) jiti compiled that whole graph: ~65s of event-loop
starvation on the first embedded run, which is what pushed
run.session-permissions.test.ts past its 120s timeout before #129582.
Add openclaw/plugin-sdk/claude-model-runtime, a narrow family-level and
local-only subpath re-exporting the Claude identity/thinking helpers from
their leaf owners (@openclaw/llm-core, plugins/provider-claude-thinking).
Switch anthropic, anthropic-vertex, and opencode policy artifacts to it, and
amazon-bedrock plus ollama to the already-plugin-visible
@openclaw/model-catalog-core leaves. The barrel keeps re-exporting the same
symbols, so no existing consumer changes.
Measured on the embedded-runner host route (first run, Vitest worker):
65540ms -> 6627ms; jiti self-time 23.4s -> 1.3s, statSync 18.6s -> 0.7s.
run.shared-integration.test.ts drops from 167s to 65s as a side effect.
Also pin run.inherited-auth-owner.test.ts to the mocked plugin-harness route
(its assertions are provider-agnostic; 37.6s -> sub-second test time) and
document the no-provider default-route trap on overflowBaseRunParams.
Follow-up to #129582.
* chore(plugins): register claude-model-runtime boundary aliases
The extension package boundary contract requires every local-only plugin-sdk
entrypoint to carry a d.ts path alias in the shared boundary map and xai's
derived override set; CI's contracts-plugin lane caught the missing entries.
* chore(release): exclude claude-model-runtime declarations from the pack
Local-only plugin-sdk entrypoints ship runtime .js only; the release check
derives the required pack exclusion from the local-only registry and CI's
core-tooling lane caught the missing package.json files entry.
* test(agents): assert the mocked harness route in auth-owner proof
ClawSweeper P2: without the agentHarnessId assertion a silent fall-back to
the built-in host harness would still pass the auth-owner assertions while
proving the wrong route; fail loudly like run.session-permissions.test.ts.
* fix(gateway): tools.invoke must carry the caller's host-minted role authority
The connect handshake resolves each connection's authority once and stores it
server-side (shared-secret operator owners mint system authority there).
tools.invoke discarded that fact and re-derived ownership from scopes, so a
shared-secret caller with no durable profile resolved to the deny-by-default
role and was refused dispatch on its own agents — while the same connection
could still mutate sessions directly.
Carry client.internal.operatorRoleActor into the synthetic dispatch client and
keep the scope-derived fallback for callers that have no connection actor
(HTTP). Regression test fails pre-fix with the FORBIDDEN agent-allowlist error.
* test(opencode): close the fake CLI before exec to stop ETXTBSY flakes
The catalog suite wrote the fake opencode executable and spawned it
immediately. Under parallel CI shards the write handle could still be open
at exec time, so the launch failed with ETXTBSY and failed the shard.
Write through an explicit file handle with an fsync before close so the
binary is fully durable before the first spawn.
* fix(ci): repair red main type and lint gates
Two gates were failing on main independently of this branch:
- extensions/qa-lab cleanup tests still built OpenClawCrablineChannelDriverSelection
with the retired smokeArtifactPath and a stale capabilityMatrixPath, so
check:test-types failed after the readiness-artifact change (#124189).
Align both fixtures with the current type and its pinned constants.
- scripts/github/release-validation-campaign.d.mts declared the Actions Octokit
client as any (#129726), tripping no-explicit-any. Declare the structural
subset the publisher actually calls instead of suppressing the rule.
Verified failing on clean origin/main before the fix.
* refactor(plugin-sdk): dedupe session-catalog cursor paging into session-catalog-runtime
The acpx Pi and opencode session catalogs carried byte-identical
boundedLimit/encodeCursor/decodeCursor/optionalRawCursor/transcriptPage
scaffolding (~114 duplicated lines each). Move one canonical copy into the
private-local session-catalog-runtime SDK subpath both plugins already may
import, and keep the plugin-named cursor guards as direct aliases.
Net -87 production LOC; no behavior change (error strings, cursor canonical
form, and byte budgets are unchanged).
* refactor(core): replace private sleep() clones with canonical sleep helpers
managed-linux readiness polling now uses @openclaw/retry sleepWithAbort with
ref:false (preserving the clone's timer.unref behavior), and the embedded
agent runner's async-task wait uses src/utils/sleep.ts. Both clones matched
canonical semantics on real inputs (positive integer poll intervals).
The update-managed-service-handoff copy stays: it lives inside a serialized
standalone handoff script (String.raw template) that cannot import repo
modules.
* fix(sessions): isolated gateways no longer inherit HOME external session catalogs
A gateway on isolated state (custom OPENCLAW_STATE_DIR/CONFIG_PATH/OPENCLAW_HOME,
relocated home, or any named profile) listed, read, continued, archived, and
reopened the operator's real Claude Code/Codex/OpenCode/Pi sessions from the
process HOME. External catalogs now require the default install identity for
process-HOME scans: every catalog verb receives the isolation policy and rejects
HOME-fallback local targets, unknown providers fail closed unless they declare
supportsProcessHomeIsolation, and one structured warning records the skip.
Paired-node hosts and explicitly rooted stores (CLAUDE_CONFIG_DIR, CODEX_HOME,
OPENCODE_DB, Pi session dirs) keep working; default-identity gateways are
unchanged.
* fix(sessions): inject catalog HOME-isolation fact at registry construction
* chore(sdk): regenerate plugin API baselines after rebase
* chore(sdk): regenerate plugin API baselines after rebase
* fix(opencode): migrate retired free model refs
Repair the shipped beta upgrade path through the provider-owned Doctor contract. Activate the migration from the canonical configured-model selector inventory so every supported selector is covered consistently.
Co-authored-by: samson1357924 <samson1357924@gmail.com>
* fix(opencode): migrate media model preferences
---------
Co-authored-by: samson1357924 <samson1357924@gmail.com>
* feat(plugins): catch code-mode drift between catalogs sharing one model
Adds a contract test that groups bundled catalog rows by shared upstream
model and requires every row in a group to declare compat.codeMode once any
sibling does. Rows sharing a model id group automatically; rows under
different ids opt in with the new manifest-only `upstreamModel` marker.
Moves the kimi catalog into its manifest so the scan can see it, and records
the tier reseller catalogs were silently missing as explicit "capable".
* docs: regenerate docs map for the shared-model code-mode section