Commit graph

71 commits

Author SHA1 Message Date
RoboClaw
67c3c3abfa
fix(plugins): plugin MCP accounts cannot be signed out and reconnect after reinstall
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
2026-10-31 07:03:49 +00:00
Alix-007
022048904b
fix(plugins): keep scoped scaffold package names valid (#186901)
fix(plugins): generate valid package names for scoped plugin scaffolds

The plugin scaffold put its openclaw-plugin- prefix in front of the whole name, so a scoped name like @scope/pkg became openclaw-plugin-@scope/pkg, which npm rejects. Scoped names now keep their scope, giving @scope/openclaw-plugin-pkg. Unscoped names are unchanged.

Evidence: built CLI on Node 24.22.1 with tool and provider scaffolds and scoped and unscoped names (16 scaffolds, each checked with an offline npm publish dry run). Main generated openclaw-plugin-@scope/pkg, which npm rejected (twice); with this change it generated @scope/openclaw-plugin-pkg, which npm accepted (twice). Unscoped names are unchanged and accepted on both refs. Plugin IDs, output paths and install metadata were checked, and nothing was published. Details: https://github.com/openclaw/openclaw/pull/186901#issuecomment-6475755167.

Thanks @Alix-007.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-28 23:10:14 +05:30
Patrick Erichsen
d1c8d42588
refactor: rename Claws to Templates throughout OpenClaw (#186457)
* refactor: rename Claws feature to Templates

* docs: repair historical Templates guide links

* fix(templates): preserve state upgrades and published artifacts

* test(templates): preserve fresh identity in additive repair fixture

* fix(templates): complete migration consumers and wrapper closure

* test(templates): allocate explicit safety regression budget

CI e447f0bf (73fa01a3 merged into f38f7e73) counts 6,301,355 test lines against a 6,299,646 ceiling: +1,709. Its actual main base already contains 6,300,241 lines (+595 debt); this PR contributes +1,114 net lines.

Retain independent shared-state upgrade/data/rollback, real plural-lease revocation, immutable-archive authoring-boundary and cold extracted-wrapper regressions. They are already parameterized/shared where their contracts match. Removing 1,709 lines would exceed all PR net growth and force unrelated cleanup or weaker coverage. Allocate exactly the measured total, with no slack or counting/gating changes; account separately for the 2,715 upstream ceiling advance over source 73fa01a3.

* docs(templates): preserve frozen release history and mirror

Restore the historical2026.9.5 Claw-package link to its baseline bytes and regenerate the owned mirror through changelog:from-docs. Normal PR release-artifact scope is now empty; no release-automation override or native prep metadata change.

The unchanged global docs route audit separately reports the frozen /cli/claws historical link as missing. Preserve that concrete failure for the owner policy decision; do not add an alias, redirect or audit exception.

* docs(templates): retain published Claws documentation URL

Keep the verified published2026.9.5 documentation URL through one existing docs-host redirect from /cli/claws to canonical /cli/templates. Frozen release source and mirror remain baseline-exact. This is not a CLI, Gateway/API or Control UI alias, and does not add a runtime handler or audit exception.

* test(templates): reserve bounded regression budget headroom

CI40663216626 measured6,301,549 lines against6,301,539, over by ten upstream lines while PR net remained+1,114. Round to the next1,000 at the owner-approved fixed6,302,000 ceiling:451 reserve lines (0.0072%) for ordinary main advancement during exact-head CI and required regression maintenance.

Actual CI base already contains789 debt lines against6,299,646. The total manual allocation is2,354=789 existing debt+1,114 required PR lines+451 bounded reserve. Latest inspected main5eeafd8d merges at6,301,531 after18 lines of upstream shrink, leaving469; no extra ceiling was added for it. Cases, assertions, counting/gating logic, all runtime/source/prep metadata and permission guards are unchanged.

* test(ui): await responsive appearance grid geometry

Viewport resize schedules shell invalidation and async rendering, followed by the existing grid-track transition. Poll actual geometry within the unchanged100ms/15000ms expect.poll budget, then reread and retain the original3/1 column and minimum150px assertions plus every heading, accent, focus and color-mode check.

Parent-qualified normal secretless native Mac browser at exactCImerge c876: original3a30c3fd red outer1/26.873s expected3 got1; exact staged test blob9db27bab green outer0/19.779s, full case1143ms. Host performed static checks only. No runtime CSS/code, expected values, sleeps, timeouts, skips or guards changed.
2026-10-28 03:54:54 -07:00
Ayaan Zaidi
3bcca4f468
fix(cli): sweep terminal value escaping and bidi controls in report families (#186502)
fix(cli): route remaining CLI reports through the terminal-text owner

After #185927 added one owner for escaping untrusted values in CLI output, contributors kept opening one PR per command to escape the next report. This moves the remaining human-readable reports in the plugins, secrets, sessions, memory and memory-wiki, workboard, backup, pairing, oc-path, config and setup commands onto `terminalText` / `displayPath`, and extends the owner to neutralize bidirectional control characters. JSON output, persisted identities, raw exports and the CLI's own colors are unchanged, and the trusted styling of `renderTable` is untouched.

This absorbs the per-site fixes from @Leon-SK668 (#184454, #184379, #185374, #186449, #184396, #184788, #184813, #184394), @huwei-xydt (#185895, #185719), @wangmiao0668000666 (#175600, #175181, #175179), @SunnyShu0925 (#184747), @KrasimirKralev (#184597) and @arpe1618 (#150599), whose original commits are kept. Families no PR touched (update, Doctor, install-trust producers and others) are listed under "Not fixed here".

Evidence: 85 built-CLI invocations per ref with crafted control and bidi characters in the reported values, captured as raw stdout bytes. Main printed the raw sequences; this change printed them neutralized, with identical normal colors and unchanged JSON. Details: https://github.com/openclaw/openclaw/pull/186502#issuecomment-6460632667.

Co-authored-by: 胡伟0668000622 <hu.wei94@xydigit.com>
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: Leon-SK668 <0668001470@xydigit.com>
Co-authored-by: wangmiao0668000666 <wangmiao0668000666@users.noreply.github.com>
Co-authored-by: SunnyShu <0668000539@local>
Co-authored-by: Krasimir Kralev <263465593+KrasimirKralev@users.noreply.github.com>
Co-authored-by: arpe1618 <razark2978@naver.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-28 10:42:57 +05:30
RoboClaw
de50262a1f
feat: enable native plugin UI without a Labs opt-in
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
2026-10-28 03:41:15 +00:00
Josh Lehman
0957af2568
feat(plugins): plugins can hand running turns to their reloaded version (#185315)
* feat(plugins): hand running turns to a reloaded plugin at step boundaries

A reload that reserves a plugin now tells work holding it. A running turn
on a plugin that hands over stops at its next model step through the
existing plugin-runtime refresh and continues on the new generation;
whole-run leases yield their work count. The refresh continuation waits
out pending publication instead of failing after three gates.

* feat(plugins): opt in to turn handover with manifest reload.turnHandover

openclaw-a71.5: a plugin declares reload: { turnHandover: true } in
openclaw.plugin.json; the retiring generation's record decides whether a
reload hands running turns to the new generation. Plugins without the
field keep today's wait for the turn. Replaces the prototype env var.

* feat(plugins): explain what a plugin reload waits for during turn handover

openclaw-a71.6: reload status says when running turns continue on the new
version at their next step, and names plugins that keep whole turns because
they do not declare reload.turnHandover. Documents why a refresh
continuation waits through back-to-back reloads and covers it with a test.

* fix(agents): tell a handed-over turn a plugin reloaded instead of asking it to verify a change

openclaw-a71.7: the refresh records whether the run's own plugins tool or an
outside reload requested it; a reload-driven continuation no longer tells the
model to verify a change it never asked for.

* fix(agents): end a refresh continuation's reload wait when a gate never gives way

Autoreview: an unbounded wait for back-to-back reloads still needs each
settled gate to clear, so a stuck gate fails the continuation instead of
spinning.

* fix(plugins): hand a turn over only when every reloaded plugin can, and finish it as one turn

ClawSweeper on #185315:
- decide after the reload reserves all of its plugins; one undeclared plugin
  keeps the whole turn waiting, so parking can't deadlock on a retained hold
- context-engine owners keep the default wait until logical-turn custody can
  move with the turn
- agent_end and llm_output fire once, from the attempt that ends the turn
- a refresh continuation doesn't redeliver next-turn injections or rerun
  agent_turn_prepare, and prompt hooks see the user's prompt

* test(plugins): prove turn handover on a real Gateway with declared, undeclared and mixed reloads

* docs(plugins): document reload.turnHandover and encourage reload-safe plugins

* fix(agents): let a reload hand a turn over only at a real step boundary

Autoreview: a reload can land during the final, tool-free model step or be
cancelled before the next step. The step boundary now rechecks that the
reload is still pending, and a reload-sourced refresh continues the turn
(and defers completion hooks) only when the attempt actually stopped there.

* fix(plugins): list the replacement watchers in the PR wrapper inventory

* fix(knowledge): give the bundled Knowledge plugin its memory category

Every bundled plugin needs exactly one purpose category. Knowledge was
bundled without one; the check only runs when manifest code changes.

* fix(agents): let admitted calls finish while a reload waits for the step boundary

A reload's handover request no longer fences tool calls: the reloading
plugin keeps serving this generation until the turn reaches its step
boundary. Only the run's own plugins-tool refresh invalidates the catalog.

* fix(gateway): report effective turn handover in reload status

Reload status now uses the same eligibility decision as the handover, so a
context-engine plugin that declares reload.turnHandover is reported as
waiting for whole turns.

* fix(agents): show authorized prompt hooks the user's request on a reload continuation

Authorized prompt enrichment such as memory recall received the synthetic
continuation prompt. Both prompt-build phases now share one event carrying
the user's request; the model still gets the continuation prompt.
2026-10-27 00:08:51 -07:00
wangmiao0668000666
a8f146a71e
fix(cli): keep plugin manifest display names safe in the uninstall preview (#183708)
Co-authored-by: wangmiao0668000666 <wangmiao0668000666@users.noreply.github.com>
2026-10-25 18:25:43 -07:00
Peter Steinberger
7d887b9939
fix(plugins): identify Gateway preparation lease owners (#183885)
* fix(plugins): identify Gateway preparation lease owners

Attribute preparation references to the run and Gateway turn service through the existing diagnostic frame. Keep active work and disposal semantics intact; retain log owner redaction. The completed-run leak did not reproduce in the isolated Gateway fixture, so this change repairs attribution only.

* test(plugins): isolate preparation ownership observations

Use the exact test-local owner observations instead of asserting a cumulative mock call count shared with earlier agent handler tests. The full 412-test agent handler file passes.
2026-10-25 15:37:59 -07:00
SunnyShu
5d973f1079
feat(cli): show plugin trust status in plugins list output (#178483)
Show recorded plugin provenance in the compact plugins list and share the trust formatter with verbose output. Keep listing metadata-only and state that provenance is not a safety guarantee.

The verbose and narrow-terminal regressions fail on the base and pass on the reviewed head. Exact-head CI is green; inspected synthetic before/after images are in the PR. An installed CLI/Gateway run was not performed because it required a full build.

Co-authored-by: SunnyShu <265248434+SunnyShu0925@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-10-24 23:45:59 -07:00
Leon-SK668
8b1ceb600e
fix(plugins): avoid waiting on authoring metadata pipes (#181762)
## What Problem This Solves

Fixes plugin metadata builds and validation hanging when `package.json` or `openclaw.plugin.json` is a FIFO with no writer.

## User Impact

Authoring commands reject pipes and special files promptly without rewriting project metadata. Regular files, supported symlinks, valid Unicode, and malformed-JSON diagnostics retain their existing behavior.

## Why This Change Was Made

The shared authoring reader resolves symlinks and delegates admission to `readRegularFileSync`. It also uses `decodeUtf8Input` for the existing strict UTF-8 requirement, removing the duplicate byte check and the proposed custom descriptor-management code.

Thanks to @Leon-SK668 for the original fix and Linux CLI reproduction.

## Evidence

- Red on the unchanged main reader: the special-device package regression reached JSON parsing instead of rejecting the nonregular input. Green with the fix.
- Real-filesystem FIFO regressions cover both metadata files, without I/O mocks, and verify that the pipe and sibling metadata remain unchanged.
- `node scripts/run-vitest.mjs src/cli/plugins-authoring-command.utf8.test.ts --maxWorkers=1`: all 7 tests pass, including existing malformed UTF-8 refusal, metadata preservation, and valid Unicode controls. Wrapper wall time 25.37 s; Vitest duration 13.10 s. These tests import a synthetic plugin through the production build/validation owners.
- Production +5/-6 (net -1), tests +33, documentation +3.

The contributor's built Linux CLI evidence at `c023e6b5c3a04c8dddb7a2c042ba5d158ea42b62` reports baseline timeouts, prompt FIFO refusals after the fix, successful regular-file builds, and validation through a linked package file. This revision was exercised through real filesystem/build/validation owners; the built CLI and live Gateway were not rerun because they require a separate full build, and this path does not use a model or channel.

Targeted oxlint, oxfmt, and diff checks passed. Independent P0–P2 review found no actionable defects. Additional authoring controls passed for stable JSON and malformed JSON. The symlink-root permission control fails identically with the unchanged reader and this change on macOS: directory mode is `01770`, expected `03770` (`plugins-authoring-command.test.ts:564`). This reader does not change directory permissions; the failure is retained as baseline evidence rather than weakened.

After merging current main, the final diff remained byte-identical to the reviewed candidate. All 7 encoding and special-file tests passed again (21.09 s wrapper wall time; 12.14 s Vitest duration).

Known diagnostic limitation: the canonical reader's nonregular-file error does not name which metadata file was rejected. The P3 suggestion to add authoring-specific error wrapping is left as a follow-up to keep this fix at the shared admission boundary; FIFO refusal and file preservation are covered above. Fresh built-CLI proof remains unrun as noted above.

Co-authored-by: Leon-SK668 <0668001470@xydigit.com>
2026-10-24 20:56:57 -07:00
Peter Steinberger
aae13944bd
feat(plugins): inspect runtime compatibility before activation (#182419)
* feat(plugins): report runtime compatibility hazards

* fix(plugins): cover optional calls and host-link diagnostics
2026-10-24 05:06:12 -07:00
Peter Steinberger
ae81c0703e
fix(plugins): resolve embedded auth and require restart for bundled code changes (#182403)
* fix(plugins): keep bundled code host-owned during reload

Resolve authentication runtime helpers through literal lazy imports so embedded code does not require physical JavaScript discovery. Refresh bundled registrations without recapturing code and report the existing Gateway restart requirement. Preserve external plugin source reload and recovery.

* fix(plugins): complete immutable bundled reload cutover
2026-10-24 04:49:41 -07:00
Josh Lehman
240045417c
fix(plugins): reload edited bundled code without restarting the gateway (#180466)
* fix(plugins): reload edited bundled code without restarting the gateway

Capture explicitly replaced bundled generations while preserving canonical host modules and unaffected siblings. Carry source ownership through worker preparation and recovery.

* fix(plugins): repair bundled reload CI fixtures and wrapper closure
2026-10-22 15:48:52 -07:00
Dallin Romney
5e6d56ae46
fix(doctor): prioritize unresolved findings and explain repairs (#169299)
* fix(doctor): retain plugin files before state migrations

* fix: give Doctor findings priorities and useful repair steps

* fix(doctor): prioritize actionable current findings and explain recovery notices

* fix(doctor): report actionable auth and browser outcomes

* fix(doctor): clarify service and install policy findings

* fix(doctor): preserve migration originals and classify diagnostics

* fix(doctor): explain unresolved auth migration findings

* fix(doctor): retain findings across startup refusal

* test(doctor): retain findings after read-only config refusal

* test(doctor): preserve workspace mock contracts

* refactor(doctor): finish structured finding cutover

* fix(doctor): satisfy browser diagnostic lint contracts

* test(doctor): provide capture roots and assert the final gateway summary

* fix(doctor): reacquire invalidated update-ledger read admission

* test(doctor): preserve real inspection worker exports

* fix(doctor): align credential guard and bound legacy migration fixture

* fix(doctor): reuse update recovery capture without supplemental backups

* test(doctor): assert retained capture refusal after backup removal

* fix(doctor): show actionable problems by default

* fix(doctor): align CI callers and settle custody before results
2026-10-22 00:37:27 -07:00
Peter Steinberger
3fb666f233
fix(plugins): reject ambiguous marketplace selections (#117416) 2026-10-21 18:06:24 +00:00
Peter Steinberger
f9b097a8d3
fix(plugins): clear warnings after removing unreadable load paths (#168913) 2026-10-21 10:02:20 -07:00
Peter Steinberger
d1b9f9033c
fix(plugins): restore the package when held files block an in-place update (#178747)
Fixes #169842. When held files (Windows EPERM) block a plugin package swap, the transaction now restores missing files, preserves surviving ones, and keeps a named recovery backup if restoration cannot finish; it retires the displaced directory identity so inode reuse cannot erase recovery details. Resolved-version and pin guidance unchanged. Supersedes #170993, thanks @libaojiang.

Co-authored-by: libaojiang <2461443384@qq.com>
2026-10-20 16:37:55 -07:00
Josh Lehman
bd2dbfdeb4
feat(plugins): identify retained references blocking reload (#167456)
* feat(plugins): identify retained references blocking reload

* fix(plugins): simplify retention diagnostics and break type cycle

* fix(plugins): include retention modules in wrapper inventory

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
2026-10-20 22:19:54 +00:00
Dallin Romney
36b28bb0f5
fix(plugins): defer startup registration until data migrations finish (#178165)
* fix(plugins): defer startup registration until data migrations finish

* fix(agents): await plugin admission in prepared catalogs

* test(gateway): keep worker Goal fixture on async registry path
2026-10-20 08:30:39 +00:00
yash
55ce16b61c
fix(plugins): stop reload waits from blocking agent runs indefinitely (#175686)
* fix(status): show plugin reloads that block new agent runs

A parked `openclaw plugins reload --wait` holds the plugin replacement gate,
so new agent runs wait, but status and status --json reported nothing.
Project the Gateway's existing plugin reload record into the status RPC with
its start time and whether new runs are blocked, and show it in the overview.

* fix(plugins): bound reload waits and report blocked work

Limit --wait to the existing ten-minute plugin lifecycle wait budget, preserve admitted work through rollback, and project owner reload status into CLI status. Consolidate regression coverage in existing fake-clock and Gateway reader fixtures.

Co-authored-by: yxshee <84263676+yxshee@users.noreply.github.com>

* test(status): isolate plugin reload overview coverage

* docs(status): clarify reload rollback visibility

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: yxshee <84263676+yxshee@users.noreply.github.com>
2026-10-18 18:09:45 -07:00
Patrick Erichsen
d6d7435f59
feat(plugins): default package installs to ClawHub (#173669)
* feat(plugins): default unprefixed packages to ClawHub

Use the shared source planner for CLI, chat, and assistant installs. Keep explicit npm and local sources, preserve canonical built-in shortcuts, and retain the selected registry in update and repair records.

Autoreview findings addressed:
- [P2] Preserve ClawHub provenance in search hints that match aliases
  Route scoped packages through ClawHub and add @latest to ambiguous unscoped search hints.
- [P2] Preserve usable search hints for scoped names with file suffixes
  Treat file-suffixed package names as registry specs, migrate source-selection tests, and retain npm in retry guidance.
- [P2] Update the remaining source-selection test expectations
  Treat file-suffixed package names as registry specs, migrate source-selection tests, and retain npm in retry guidance.
- [P2] Keep npm prerelease retry hints on npm
  Treat file-suffixed package names as registry specs, migrate source-selection tests, and retain npm in retry guidance.
- [P2] Restrict catalog shortcuts to canonical plugin IDs
  Restrict bare shortcuts to canonical IDs and retain npm in shared hook-pack prerelease guidance.
- [P2] Preserve npm in hook-pack prerelease guidance
  Restrict bare shortcuts to canonical IDs and retain npm in shared hook-pack prerelease guidance.

* docs(plugins): show ClawHub as the default install source

Update setup examples and generated inventory instructions to omit the ClawHub prefix. Document explicit npm selection and canonical plugin-ID shortcuts.

* fix(plugins): keep recovery tied to the selected source

* test(plugins): cover search commands and saved registry choices

* test(plugins): align pre-action recovery with selected sources

* test(plugins): prove source-bound recovery through the CLI

* fix(plugins): retain official identity during config recovery
2026-10-16 22:07:52 +00:00
Patrick Erichsen
f469f6da56
feat: show Claw contents and open new agent chat after Add (#171600)
* Show Claw catalog details and hand off Add to agent chat

* fix(ui): keep Claw route identity and recovery labels accurate

* fix(claws): align UI safety and E2E timeout guards

* fix(ui): retire pending Claw Add on route change

* fix(ui): repair Claws catalog CI failures

* docs(claws): leave Lobster approval docs unchanged

* fix(ui): preserve Solid catalog mount during restack

* fix(ui): load Claw config on default Agents route
2026-10-15 13:34:03 -07:00
Yuval Dinodia
7b33c8babd
fix(plugins): skip operator-managed load-path plugins in plugins update (#172432)
A plugin selected through plugins.load.paths has no install owner, so
plugins update resolved it with resolveLifecycle, recorded an ownership
rejection, and aborted the whole --all run with refresh-registry advice.

Use the ownership resolver's resolveUpdate like openclaw update already
does. Operator-managed plugins are reported with the shared
plugin-operator-managed warning and skipped, so remaining plugins still
update and a named update no longer fails.
2026-10-15 14:23:02 +03:00
RoboClaw
00b330babd
fix: avoid agent plugin reloads waiting on their own turn (#171257)
* fix: hand off plugin reloads after agent turn cleanup

Co-authored-by: jacobtomlinson <1610850+jacobtomlinson@users.noreply.github.com>

* fix(tooling): include session display dependencies in PR wrapper

Restore the materialized wrapper runtime closure after session previews began importing the chat media display helper. Include the five existing runtime files reached through that helper.

Proof: all three affected inventory/extraction assertions fail on main and pass with this inventory-only repair. Focused closure checks: 4 passed in 22.37s; extracted dependency check: 1 passed in 16.21s. Independent isolated review found no actionable issues.
Co-authored-by: jacobtomlinson <1610850+jacobtomlinson@users.noreply.github.com>

* test: prepare session creation before loopback RPC deadlines

Prepare the real sessions-create handler alongside chat before request deadlines begin. Cold handler import consumed 6.3 seconds in the pinned baseline fixture; preparation keeps the lifecycle reply assertion from depending on module-load speed without increasing RPC timeouts or changing production behavior.

Co-authored-by: jacobtomlinson <1610850+jacobtomlinson@users.noreply.github.com>

* fix(tooling): use the upstream wrapper inventory at merge

The current-main merge already contains the session display inventory repair. Carrying the older insertion independently duplicates chat-display-projection.helpers.ts when Git combines its moved context. Remove the redundant carry-forward so current main remains the sole inventory source; no handoff implementation changes.

Co-authored-by: jacobtomlinson <1610850+jacobtomlinson@users.noreply.github.com>

---------

Co-authored-by: jacobtomlinson <1610850+jacobtomlinson@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-10-14 03:30:42 -07:00
Peter Steinberger
3b75b18b13
fix: use same-commit plugins in development macOS builds (#170776)
* fix: stage same-commit plugins in development macOS builds

* style: satisfy desktop plugin staging lint checks

* fix: preserve explicit registry choices with staged plugins

* fix: make staged Codex voice runtime portable

* test: preserve built plugin entries in dependency fixtures
2026-10-13 01:43:20 -07:00
Peter Steinberger
29f9c533eb
fix(plugins): keep incompatible plugins inspectable (#168977) 2026-10-11 06:16:13 -07:00
Peter Steinberger
5cb977c8dd
fix(plugins): keep incompatible Codex runtimes unavailable after updates (#168930)
A partial update could leave @openclaw/codex 2026.9.5 installed on a newer host; its open-ended pluginApi range admitted it and every turn failed on the removed agent-harness-task-runtime SDK subpath. Version-bound official runtimes below a published compatibility floor (codex 2026.9.7) are now unavailable at admission with update repair / plugins update guidance; compatible older versions keep loading while update and repair converge them to the host cohort. plugins update now prints failure reasons. Fixes #168748, #168749. Refs #168498.
2026-10-11 00:00:39 -07:00
Dallin Romney
f231397fb4
docs: simplify cli and troubleshooting docs (#168694) 2026-10-10 22:18:10 -07:00
Dallin Romney
9e444e1078
fix(plugins): registry warns after removing the last load path (#168167) 2026-10-10 21:52:56 -07:00
Peter Steinberger
31b1db6273
fix(cli): guard local plugin state writes at command boundaries (#168757)
Guard local plugin install and hook fallback, uninstall, enable/disable, registry repair, updates, marketplace snapshot writes, and hook configuration writes with the existing local-state owner. Preserve existing Gateway lifecycle RPC routes and offline behavior; refuse local writes while the Gateway owns state with stop-and-rerun guidance.

Reuse effect-time ownership checks without adding cancellation settlement, compensation, fencing, or a new lease protocol. A Gateway starting mid-command is covered by the existing guard at the effect.

Supersedes #168420. Focused remote tests cover the command boundaries and existing migration behavior.
2026-10-10 18:53:29 -07:00
Peter Steinberger
73fdd3d2c6
fix(plugins): reload bundled plugins with dormant registry records (#167647)
After an upgrade Doctor keeps an old registry install record but selects the bundled copy of a plugin; openclaw plugins reload then routed through package-owner validation and refused with 'no authoritative package-owner metadata', so a config change needed a full Gateway restart. Reload now follows the selected bundled plugin; any record whose path or owner claims that root still requires strict package validation. Closes #161193. Reported by @mbelinky.
2026-10-08 23:21:25 -07:00
Peter Steinberger
5ac5bfe1b3
fix(plugins): install the official plugin build matching the running OpenClaw on stable (#167485)
Stable official ClawHub installs (catalog and plugins.install source=official) resolved ClawHub's newest release, so after 2026.9.9 shipped a 2026.9.7 host received @openclaw/perplexity-plugin@2026.9.9 (pluginApiRange >=2026.9.9) and refused it. Managed installs now opt into the existing release-channel resolver's same-version selection for official stable installs and fall back to the default spec only when that build is not published; plugin updates and drift detection keep their registry target. Incompatible refusals now tell the operator to upgrade OpenClaw or choose an explicit plugin version. Beta and extended-stable behavior unchanged; operator pins stay strict. Closes #167382. Reported by @charlesBerg-ux.
2026-10-08 16:40:52 -07:00
Peter Steinberger
9dbc8d4feb
perf(gateway): refresh derived plugin metadata after readiness (#166617)
* perf(gateway): refresh derived plugin metadata after readiness

Serve validated startup metadata without persisting its optional cold registry cache first. Reuse the existing post-ready lifecycle and registry refresh owner, retaining synchronous config recovery and database compatibility checks.

* fix(plugins): preserve leased registry refresh across workers

Refresh derived registry metadata through the existing shared-state worker
without delaying Gateway readiness or replacing its active plugin snapshot.
Retain the lifecycle lease through transaction and commit, preserve pinned
install roots and candidate ownership, and exclude Doctor callbacks from the
worker payload. Keep process-bound crash reclamation for startup maintenance.

Remove the unused synchronous writer export and cover real worker transport,
Doctor repair, cancellation, and admitted source preservation.

* test(startup): preserve recovery and lease custody coverage

Use real backup recovery to acquire the startup lease before racing an
active-config change. Keep refusal, file-preservation, and cleanup checks.
Allow the refresh owner to wrap assertCurrent while retaining the original
lease fields in plugin update custody assertions.

* fix(plugins): preserve registry refresh worker contracts

Send Windows environment entries across the worker boundary and restore
case-insensitive semantics at the consumer without changing lease fencing.
Prepare the deferred commit-failure fixture once, and cover read failures at
the shared persistence kernel used by workers and install transactions.

Proof: Blacksmith Testbox tbx_01m4bv9q8rzrttx7ytw5a8288t; 206 registry,
Doctor, and environment tests plus 59 worker error tests. Selected changed
gates and final lint replay passed. Independent review through P2 is clean.
2026-10-07 19:51:57 +00:00
Peter Steinberger
b2d6842c54
fix(plugins): preserve replacement installs across watcher echoes (#166618)
Reconcile unchanged config observations through the config owner after retained
work drains, before testing replacement authority. Busy forced installs now
apply their own replacement while newer config still supersedes stale work.

Cover retained work, active calls, and consumers with the real config reload
owner. Keep the synchronous publication check and consolidate repeated checks.
2026-10-07 14:21:15 +00:00
Dallin Romney
e560dccc6d
docs: use plain language for connection checks (#165736) 2026-10-05 22:52:53 -07:00
Peter Steinberger
edebc47742
fix(plugins): load Doctor contracts from the inventory-owned package loader after an in-place plugin replacement (#165049)
Refs #157415

Reported by @ADLBAS26 and @Torsie.
2026-10-04 11:59:10 -07:00
Peter Steinberger
4cdbab75c3
fix(plugins): resolve mixed-case plugin IDs through canonical identity (#164683)
## What Problem This Solves

Plugins whose manifest ID contains uppercase letters (for example `MiXeD-demo`) behaved inconsistently across the plugin lifecycle, because some code paths looked them up by their case-preserved manifest ID in maps keyed by the canonical lowercase policy ID:

- Offline `openclaw plugins disable/enable` failed with "Plugin not found".
- Uninstall succeeded but left a conflicting enabled policy entry behind.
- Enabling the plugin reported success, but its runtime methods were never registered ("unknown method"), both on live enable and on cold start.
- Invalid plugin settings (for example a number in a string field) validated as `valid: true`.
- Per-plugin LLM overrides/allowlists and memory-slot enablement settings were not applied to such plugins.

## Why This Change Was Made

Since `f94a7dc183`, plugin policy entries are keyed by a canonical lowercase identity while manifests keep their original casing; several consumers kept indexing with the raw manifest ID. This change routes every one of those lookups through the existing canonical metadata identity resolver (one shared policy-key helper), while preserving the exact case-sensitive runtime and package IDs:

- offline toggles (`src/plugins/management-mutations.ts`)
- uninstall policy cleanup (`src/plugins/uninstall-package-config.ts`, `uninstall-package-plan.ts`)
- Gateway startup/activation policy (`src/plugins/config-normalization-shared.ts` and consumers)
- settings validation (`src/config/validation-plugin-config.ts`)
- LLM policy lookup (`src/plugins/runtime/runtime-llm.runtime.ts`)
- memory slot policy (`src/plugins/memory-runtime.ts`)

## User Impact

Plugins with mixed-case IDs now toggle, uninstall, activate, validate, and receive their configured LLM and memory settings exactly like lowercase-ID plugins.

## Evidence

- Each site has a regression with a mixed-case plugin ID that fails before and passes after (toggles, uninstall, live and cold-start activation including disabled/denied plugins staying unavailable, eight validation cases, LLM overrides/allowlists, memory slot enablement).
- Final head: 540 tests across 27 related files, core typecheck, all 27 test TypeScript graphs, formatting, and oxlint pass on Blacksmith Testbox; earlier: full build, 503 unit, 124 Gateway, and 46 browser E2E tests, plus live CLI install/update/uninstall flows across copy/link/archive/git/npm/bundled sources.
- Full `check-changed` was cancelled by the Testbox provider during its last phase; exact-head CI is the final gate.
- Production +165/-114 LOC (mostly moving lookups onto the shared resolver); tests +386/-74.

Not changed here: a concurrent enable/disable pair can surface only a generic "The CLI command failed" message (`src/cli/failure-output.ts`); improving that copy is a separate product change.
2026-10-03 23:19:58 -07:00
Peter Steinberger
b5a41c2001
perf(plugins): share host code identity for bundled TypeScript plugins (#163639)
Bundled plugins only shared the host loader when their entry was compiled
JavaScript, so a source checkout captured all 87 bundled packages (copy, hash,
and dependency materialization) on every prepared model runtime publication:
79.5 s of plugin discovery per agent turn, which exceeded the 120 s budget on
a loaded host. Bundled plugins now take the shared host loader regardless of
entry extension, the edited-code warning keys on the canonical export so it
survives loader interop wrappers, and the docs describe source and compiled
bundled identity together.

Discovery for the live embedded-runner case fell from 79.5 s to 12-13 s and the
case from ~100 s to ~25 s on the same host. Editing a bundled plugin's
TypeScript source now needs a Gateway restart, matching compiled bundled code;
installed, external, workspace-path, and standalone plugins keep captured
source reload semantics.
2026-10-02 17:05:16 +00:00
Erick Kinnee
5c4041708d
fix(plugins): let session_end hooks read ended transcripts (#161451)
* fix(plugins): expose bounded ended-session transcripts

* fix(plugins): bound ended transcript reads by content and retirement

* fix(plugins): avoid ended transcript dependency cycle

* fix(sessions): discover closing resets without payload budgets

* test(gateway): decouple sign-in retry from provider prompts

Keep real WebSocket ownership, activation and revoked retry assertions while dropping incidental prompt order and timing diagnostics. Removing post-await authority validation makes the retained no-session assertion fail. Tracks local task openclaw-1e6.

---------

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
2026-09-30 16:33:04 -07:00
Peter Steinberger
e1ea50caf7
fix: preserve plugin install records during legacy updates (#161485)
The v13 wide-row state migration conflated a missing installed_plugin_index row with a row whose JSON was unparseable or shape-drifted, and dropped the table in both cases. An invalid row is now preserved in full in the existing diagnostic_events quarantine with repair guidance recorded, valid install records are retained independently of damaged metadata, and a preservation failure rolls the step back to v12. No schema change.

Closes #161329.

Landed under the pre-existing-red rule: the remaining CI failures were current main reds at this base (Codex app-server settlement fixture drift, fixed on main by 52e60fb42b; the subagent kill-tombstone / descendant-cancellation intermittent first seen on main hourly 36619831492).
2026-09-30 09:15:11 -07:00
Peter Steinberger
216798c496
fix: preserve listener settings when plugins update (#160682)
* fix: migrate retained plugin settings before update activation

Complete selected plugin-owned config repairs through the existing update and replacement-install lifecycle before activation. Preserve pending obligations with actual config rollback, retain published package generations when rollback is unconfirmed, and refuse unresolved active inputs without suppressing committed partial updates.

* test: align replacement-install warning fixture snapshots
2026-09-28 14:07:32 -07:00
Peter Steinberger
3e88e97f9f
chore(deps): update fs-safe to 0.21.1 (#159882)
* chore(deps): update fs-safe to 0.21.1

* test: satisfy archive collision fixture lint

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-27 16:11:51 -07:00
Peter Steinberger
87f2e6371b
fix(plugins): stop deleting sources after cleanup is revoked (#159563)
* fix(plugins): keep cleanup under source ownership

* test(plugins): model managed config activation during cleanup
2026-09-27 10:42:55 +00:00
Patrick Erichsen
2d5c68187a
fix(plugins): allow reloads to wait for long-running work (#158688)
* fix(plugins): allow reloads to wait for long-running work

* test(plugins): await reload drain readiness without polling

* test(sessions): await resource retirement before reopening cleanup fixtures
2026-09-26 08:08:14 +00:00
Peter Steinberger
2a1402cd3e
fix(startup): keep legacy state repair in Doctor (#151025)
* fix(startup): keep legacy state repair in doctor

Separate current-state startup readiness from explicit Doctor migrations.
Preserve current config recovery, quarantine, device identity checks,
lease fencing and updater completion ownership.

Remove automatic startup migration/checkpoint and node-host import paths.
Keep shipped read-only context and roster projections unchanged.

* test(doctor): align proof callers with repair ownership

Keep survivor fixture setup in caller order and select the shared Doctor
flow separately from the channel-specific proof. Include the complete
isolated diagnostics dependency closure.

Prove ordinary startup preserves legacy directories before explicit
Doctor repair, and await SQLite worker closure before test cleanup.

* test(startup): verify index repair through gateway maintenance

* test(doctor): align cutover fixtures with state owners

Reacquire the database after Doctor retires its generation, retain real session history for startup refusal, and keep pending reads at their actual owners. Distinguish the reused readonly reader from independent snapshot-token children and verify every child settles.

* fix(doctor): preserve image activation and published migration receipts

Run the shared noninteractive Doctor owner before default and Compose Gateway
activation so retained Docker volumes keep their published upgrade path while
ordinary Gateway startup stays readiness-only. Preserve root selectors and
settle interrupted repair before executing the original command.

Retain the path-wide tombstones emitted by the published restart-sentinel
importer, including consumed notices, and validate completed source decisions
before retiring recreated inputs. Add the root-image activation lane and causal
receipt coverage without introducing a schema, option, or second importer.

* test(docker): preserve release state pairs in upgrade proof

Use the existing synthetic v2026.9.2 corpus instead of combining a July shared database with a later agent schema. Preserve its deletion journal, registry, both transcript payloads, paired backups, and unsafe-state controls. Register the two shell-launched helpers with Knip.

* test(docker): normalize persisted schema snapshot rows

Compare node:sqlite schema rows using the same plain-object representation as the saved JSON preimage. Keep strict schema, row, and value-type assertions intact.

* fix(models): retain discovered models after refresh failures

Record successful legacy catalog results at the producer boundary so unavailable refreshes retain the accepted inventory. Preserve explicit outcomes, advisory SDK fallback behavior, and first-discovery starter policy.

* fix(models): preserve skipped catalog outcome semantics

Mark bundled static, configured, and advisory catalog projections with
explicit empty outcomes so legacy success inference cannot promote them
to observed account inventory. Preserve live outcomes and helper types.

Keep exact auth provenance histories and move existing fixture/policy
code into focused owners where required by the line-cap ratchet.

Validation: 447 producer and sibling cases, 56 shared self-hosted cases,
95 auth/policy cases, causal missing-outcome failures, maintained checks,
and independent review.

* test(plugin-sdk): keep discovery loader types acyclic

Move the shared loader type into a leaf consumed by both discovery
contract helpers. Preserve its public provider-test-contracts export
without a child-to-parent type import cycle.

Validation: maintained Madge check reports zero cycles; core, all core
test graphs, extension test types, lint, formatting and independent
review pass. Runtime behavior and previous catalog proof are unchanged.

* fix(plugin-sdk): mark generated static catalogs explicitly

Keep the generated non-live, non-strict catalog adapter from claiming
successful acquisition for manifest or configured rows. Preserve null,
errors, strict and custom callbacks, static catalogs, and public types.

Validation: three existing controls fail before the correction; all49
owner and sibling cases pass afterward, with types, lint, line caps and
fresh independent review clean.

* test(gateway): cover restart import during state retirement

Exercise canonical database close while a legacy notice read is paused. Verify admission rejection, retained canonical and source bytes, no migration receipt, and joined maintenance custody without changing the accepted sidecar-stop drain contract.

* fix(test): drain sharing fixtures before removing state

* test: bind retirement regression to its own worker

* docs(docker): clarify automatic Doctor activation

* test(doctor): keep readiness fixture runtime private

* test: stabilize shared skill watcher fixture roots

(cherry picked from commit 15606be10ed61be99931fcf3bb300ebdb475ad89)

* perf(tooling): share indexed scope parsing for artifact scans

(cherry picked from commit 6e6eef9f5b556e0005b16363169e6a85cd310ad0)

* fix(team-reports): use source owners in scheduler tests

The source barrel retired in #157819, but the scheduler tests still imported
it, breaking the extension test typecheck on main. Import the Discord and
GitHub owners directly, matching the production caller.

Validated the original TS2307/TS7006 failure, the corrected extension type
graph, all 36 scheduler tests, changed checks, and independent P2 review.

(cherry picked from commit 7c4866c73b)

* test(install): isolate global npm configuration in version fixtures

Use a controlled absent global config inside the fixture home so the
release helper does not query the deliberately narrow npm stub. Keep
predecessor selection, fresh-install behavior, and expected exits intact.

(cherry picked from commit 0a9eefc76c82d81bd134add3ac3d269ae1b607bd)

* test(docker): verify the complete image activation entrypoint
2026-09-25 13:43:40 -07:00
Peter Steinberger
1ae730f675
fix(plugins): repair archive plugin host links after upgrades (#158002)
Include registered archive installs in the existing host-link repair owner so Doctor and post-update convergence can recover stale or dangling SDK links without the original archive. Preserve canonical install-root, path ownership, and lifecycle authority checks.
2026-09-25 01:56:26 -07:00
Peter Steinberger
88fff4ed5a
perf(plugins): admit reloads while retained work drains (#157796)
Reserve busy plugin replacements before gating new agent work, then let
admitted runs finish on their original instance before teardown. Report
queued retained work and completed publication through existing diagnostics.

Preserve the 60-second pre-stop budget, timeout recovery, and shared-resource
cleanup before replacement registration. Cover overlapping runs, installed
version publication, and retained cleanup without introducing configuration.
2026-09-25 02:35:18 +00:00
stevenlee-oai
6a8547cfcc
fix: preserve plugin restrictions during managed installation (#152020)
* fix: preserve plugin policy during managed installation

* test: fix plugin install policy CI coverage

* test: route plugin install policy through isolated CLI suite
2026-09-24 15:15:41 -07:00
Peter Steinberger
c8eab36020
refactor: run plugins and tooling without TypeScript 6 (#156829)
* refactor: remove TypeScript 6 from plugin runtime and tooling

Keep source plugin loading on Jiti and native module transforms, move development analysis and declaration builds to TypeScript 7, and preserve captured loader and input ownership contracts. Scaffolds compile to the same entry path without shipping a compiler in production.

* refactor: use native checker for restart preflight detection

* fix: keep test-directory docs out of native helper scans

* fix: preserve native compiler tooling across CI runtimes

Keep compiler-backed tests on the supported Node transport, preserve declared Windows aliases and partial-source analysis, and bind relocated SDK reports to their installed compiler. Retain strict package input admission and the existing fixture assertions.

* test: compare messaging guard diagnostics without sorting

* fix: bound native tooling memory and preserve bootstrap loading

* fix: bound native declaration builds with tsdown scheduling

* fix: retire compiler-only helpers from installed packages

* test: migrate routing import scan to native parser

* test(ui): wait for recovered model catalog receipt
2026-09-23 22:34:20 -07:00
Peter Steinberger
d9d8f0829d
fix(plugins): show the selected entry after reload (#156902)
* fix(plugins): show the selected entry after reload

Expose the loader-owned selectedEntries map in runtime receipts. Add bounded CLI and tool guidance to rebuild compiled output after source edits while preserving success and restart outcomes.

* fix(protocol): sync generated plugin reload receipt

Regenerate the protocol outputs for optional selectedEntries. The Swift model gains the field, default-nil initializer argument, and wire coding key; Kotlin outputs remain unchanged.
2026-09-24 02:16:04 +00:00