189 Commits
Author SHA1 Message Date
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
Vincent Koc 0c34a6f20f docs(cli): say how many bundled plugins are on by default, and what enabled means (#144397)
* docs(cli): say how many bundled plugins are on by default, and what enabled means

'Some are enabled by default' undersells it: 83 of 152 bundled manifests
(55%) are on by default, 57 of them model or speech providers.

Adds the distinction that matters more than the count — a provider enabled
by default is inert until its credentials are configured, so an enabled
entry in plugins list is not evidence the plugin is doing anything.

* docs(cli): account for keyless provider defaults

* docs(plugins): clarify configured enablement

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-09-25 17:32:29 +08: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 355181c0af feat(plugins): manage multiple plugins in one CLI command (#149910)
* feat(plugins): manage multiple plugins in one CLI command

* test(plugins): split multi-ID uninstall coverage

* fix(plugins): wait for rejected lifecycle admission in CLI batches

* fix(gateway): capture candidate plugin records before watcher checks
2026-09-16 04:10:52 -07:00
Peter Steinberger 8f7c272397 perf(plugins): batch cloud worker plugin activation (#149824) 2026-09-16 00:11:19 -07:00
Peter Steinberger b5134de70a feat: manage and reload plugins without Gateway restarts (#145484)
* feat: manage and reload plugins without Gateway restarts

* fix(plugins): preserve Bun loading and align lifecycle fixtures
2026-09-11 23:12:58 -07:00
Vincent Koc f575b7f4ef docs(cli,tools): fix information-architecture findings in CLI and tools pages (#143775)
Structure-only changes: no prose is added or reworded beyond the new
heading titles themselves. Every published anchor id is preserved.

- cli/doctor/checks.md: split the 42-bullet `## Notes` list into nine
  H3 groups so individual checks are addressable.
- cli/doctor/sqlite-maintenance.md: sentence-case the one Title Case H3
  (slug unchanged).
- cli/mcp/registry.md: move `Saved MCP server definitions` directly after
  the intro that introduces its command list; `Codex tool approvals` now
  follows it.
- cli/plugins/install.md: promote the nine collapsed accordions to H3
  sections (they carry scope gates, `--force`/`--pin` semantics and
  install-policy rules), lift the source/locator prose above them, and
  head the trailing local-path run.
- cli/plugins.md: add the body H1 used by the other CLI command pages.
- cli/update/how-updates-run.md: add per-topic H4s inside
  `Restart handoff`, promote `Plugin sync details` out of
  `Git checkout flow`, and head the package-manager install text that was
  sitting inside the Git checkout section.
- cli/onboard.md: give the flag list its own `## Flags` heading and demote
  `Additional non-interactive flags` under `Non-interactive setup`.
- cli/approvals.md: move the `openclaw exec-policy` section after
  `Common options` so the page opens on the command it is titled for.
- cli/infer.md: move the "turn infer into a skill" how-to off the top of
  the reference page.
- cli/index.md: file `devices` with pairing/channels to match the sidebar,
  and name the `automations` alias on the cron row.
- tools/tts/field-reference.md: drop the stray H3 nested inside the Inworld
  accordion (its id is kept as an authored anchor) and lift the SecretRef
  paragraph out from between two accordions.
- docs.json: drop the duplicate `tools/tts` nav entry, put browser
  agent-tools before troubleshooting and existing-session beside profiles,
  file `cli/wiki` with memory/models and `cli/openclaw` with onboard/setup.
2026-09-10 15:41:30 +09:00
Vincent Koc 20e0ed521c docs(cli): split the plugins command reference by reader job (#142980)
docs/cli/plugins.md was 55,872 characters and 11 H2 sections mixing a CLI
synopsis, an authoring how-to, install-policy explanation, lifecycle
reference, diagnostics, and marketplace feed trust. It is now a short index
over six children, one per reader job:

- cli/plugins/authoring             Author, Feature scaffold, Provider scaffold
- cli/plugins/install               Install, Marketplace shorthand
- cli/plugins/list                  List, Plugin index
- cli/plugins/uninstall-and-update  Uninstall, Update
- cli/plugins/inspect-and-diagnose  Inspect, Doctor, Registry
- cli/plugins/marketplace           Marketplace

The index keeps the intro, the CardGroup, the full `## Commands` synopsis with
its trace/Nix/bundled notes, and `## Related`.

Anchor strategy: per-anchor redirects are impossible, because redirectSource()
in scripts/lib/docs-redirects.mjs throws on any source containing [?#]. Every
original anchor therefore stays alive on the parent index as an authored
<a id="..." /> stub pointing at its new home. Ids were computed with
parseDocsDocument, not a slug approximation, so the nine Accordion titles, the
two Tab titles, and the three ParamField ids are covered alongside the
headings. 34 pre-split ids: 32 stubbed, 2 (commands, related) still published
by the index itself, so no duplicate authored/canonical ID is raised. All 34
verified to resolve on /cli/plugins, and all 32 stub targets verified to
resolve on their child page. Collisions are empty on the index and on each of
the six children.

Losslessness, asserted mechanically against the pre-split file:
- index prefix + the six children (frontmatter and lede removed) + index
  suffix reassemble byte-identically, sha256
  c462b672a341344fca6dc46d623f6136f337844080b97bd469faffacb12265f8
- fences 17 -> 17, every one identical on info string and body sha256
- table rows 6 -> 14 (+8 = the new index page table)
- links: 27/27 original targets retained
- words 7,266 -> 8,023 (+757 = index page table, anchor map, child ledes)
- index 55,872 -> 8,662 chars; children 3,935-22,363 chars

No prose was rewritten and no prose exception was needed. The page had zero
intra-page anchor links and zero self-route links, and the one directional
reference the orphan check finds ("the trusted plugin id replacement above")
keeps its target on the same child page.

Closes audit findings: r3-0126, r3-1163 (partially: the accordions keep their
authored anchors and are no longer buried under a 2,065-word H2)
2026-09-09 18:23:39 +09:00
Peter Steinberger b3260afd30 fix(plugins): retain SDK provider resources through host cleanup (#142838)
* fix(plugins): retain SDK provider resources through host cleanup

* refactor(plugins): distinguish SDK provider resolver implementation
2026-09-08 23:58:08 -07:00
Peter Steinberger 1ab50af6a7 fix(plugins): release doctor inspection resources before output (#141845) 2026-09-07 21:59:30 -07:00
Peter Steinberger 79b0321441 fix(plugins): release resources after runtime inspection (#141780)
Own uncached CLI inspection through projection and serialization, await
registration cleanup, then emit one result. Preserve both formatting and
cleanup failures while retaining metadata-only and raw-helper behavior.

Related: #140674
2026-09-07 19:57:25 -07:00
Vincent Koc 4d7a33874b docs: correct 8 verified factual errors (#141158)
Each fix replaces a statement that contradicts the CLI implementation,
a TypeScript type, or the tool catalog. No prose or structure changes.

docs/cli/agent.md:11 — said "The explicit `--local` flag is the only
embedded execution path". `agent exec` is also embedded: the same page
at line 21 says it "runs one embedded agent turn without connecting to
a Gateway", and src/commands/agent-exec.ts:210 documents it as "Run one
isolated embedded agent turn and project its stable CLI result."

docs/cli/secrets.md:27 — the recommended operator loop ran `openclaw
secrets configure` with no `--plan-out`, then applied
`/tmp/openclaw-secrets-plan.json` on the next line. A plan file is only
written when the flag is passed: src/cli/secrets-cli.ts:255 guards the
write with `if (opts.planOut) { ... writeFileSync(opts.planOut, ...) }`,
and there is no default plan path. Added the flag to line 27.

docs/gateway/config-tools.md:26,46 — the `coding` profile row and the
`group:media` row listed `image` as a tool id. The catalog registers
`view_image`: src/agents/tool-catalog.ts:427 `id: "view_image"`, and
src/agents/tools/image-tool.ts:807 `name: "view_image"`. No tool with
id `image` exists. The same page already says so at line 149: "The image
inspection tool is `view_image`."

docs/cli/plugins.md:36,40 — the synopsis omitted flags the commands
accept. src/cli/plugins-cli.ts:136 gives `enable` `--accept-capabilities`;
src/cli/plugins-cli.ts:180,186 give `install` `--accept-capabilities` and
`--acknowledge-install-policy-warning`.

docs/cli/devices.md — the command reference had no section for
`openclaw devices join-code`, which src/cli/devices-cli.ts:43-47
registers with the description "Mint a single-use node onboarding URL".
Added a section matching its actual option surface.

docs/cli/index.md:165,200 — the command tree omitted `secrets store`
(registered at src/cli/secrets-store-cli.ts:164 and documented in the
`openclaw secrets` table at docs/cli/secrets.md:18) and `plugins pack`
(registered at src/cli/plugins-cli.ts:277 and listed in the plugins
synopsis at docs/cli/plugins.md:49).

docs/plugins/hooks.md:497 — the `BeforeToolCallResult` type block omitted
`scope`, while docs/plugins/plugin-permission-requests.md:93 tells plugin
authors to "Set `requireApproval.scope`". The real type has it:
src/plugins/hook-before-tool-call-result.ts:21 `scope?: ApprovalScope;`.

docs/diagnostics/flags.md:51 — the multi-flag example enabled
`"gateway.*"`. No diagnostic flag lives in a `gateway.` namespace: the
call sites are `timeline`, `diagnostics.timeline`, `plugin.load-profile`,
`ingress.timing` and `health`, and the page's own Known flags table
(lines 24-34) lists none. Replaced it with `health`, a real flag.

Closes audit findings: r3-0182, r3-0198, r3-0335, r3-0128, r3-0199, r3-0195, r5-0022, r3-0281
2026-09-07 18:54:43 +08:00
Peter Steinberger 0693628402 fix(plugins): show enablement in metadata inspections (#140964)
Default info and inspect commands displayed registry status as loaded even
when the metadata report recorded imported=false. Share the existing human
enablement formatter across list and inspection views, preserving explicit
runtime labels and the raw JSON contract.

Verified the actual built CLI before and after with unchanged JSON for 151
plugin records, 95 focused cases, full changed checks, and independent review.
2026-09-07 00:49:14 -07:00
SasanandPeter Steinberger 05182b6ad8 fix(config): save config changes into the nested $include file that owns them (#116108)
Allow config commands and doctor --fix to save an eligible nested $include
fragment without flattening the root or its ancestors.

Share deepest sole-owner resolution between the writer and Doctor. Reject
canonical targets reused by another logical subtree, revalidate the captured
include graph around persistence and reload, and roll back only an unchanged
committed leaf. Preserve current authority guards, root-owned keyed-agent
sibling writes, and the optional hasArrayAncestor snapshot contract.

Validated with five pre-repair ownership failures and a passing delegation
control, 100 passing focused config/Doctor tests, the changed-file gate,
independent review, and exact-head CI. Retain the recorded full Doctor CLI
before/after proof.

Closes #116107.
Thanks to @sasan1200 for the original implementation.

Co-authored-by: Sasan Sotoodehfar <sasan1200@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-06 21:05:02 -07:00
Peter Steinberger eaa614a843 fix(plugins): retain install files when ownership expires (#138870)
* fix(plugins): retain install recovery after ownership loss

Adopt fs-safe 0.8.3 mutation guards and exact publication receipts. Share immediate and retained rollback, preserve Windows copy fallback, and refuse stale owners or substituted backup identities. Keep published recovery state explicit when cleanup cannot finish.\n\nFixes #138815.

* test(archive): verify security outcomes across parser backends

Assert the documented entry-path code rather than backend-specific TAR
wording. Change outside-file sentinels after packing and verify extraction
leaves them untouched, creates no destination entries, and installs no hooks.
2026-09-06 20:30:26 -07:00
Vincent Koc cc358246f6 docs(gateway): split the configuration reference by domain (#140440)
The configuration reference was 2,077 lines / 146,192 characters with 55
headings, roughly seven times the 20k split threshold and well past the
40-heading split signal. It is now a short index parent plus nine
domain pages. No prose was rewritten: every moved H2 section body is
byte-identical to its source.

Children (all moved verbatim from configuration-reference.md):

- gateway/config-runtime (1,117 words): worktreeRoot, Models, Discovery,
  Update, ACP, Wizard, Bridge (legacy, removed)
- gateway/config-extensions (2,221 words): MCP, Skills, Plugins,
  Canvas widget presenter
- gateway/config-browser-ui-desktop (2,012 words): Browser, UI, Desktop
- gateway/config-gateway (3,600 words): Gateway, incl. OpenAI-compatible
  endpoints, multi-instance isolation, gateway.tls, gateway.reload
- gateway/config-cloud-workers (1,495 words): Cloud worker environments
- gateway/config-hooks (3,273 words): Hooks, incl. HTTP contract, agent
  payload, session policy, mapping, retries and fan-out, Gmail
- gateway/config-secrets-env (1,042 words): Environment, Secrets,
  Auth storage, Config includes ($include)
- gateway/config-observability (1,190 words): Audit, Logging,
  Diagnostics, Telemetry
- gateway/config-automation (958 words): Automations (cron), Media model
  template variables

Anchor preservation. docs.json redirects match on pathname only - 0 of
the 281 existing redirects carry a fragment in `source`, and fragments
never reach a redirect matcher - so no path redirect is added and the
parent keeps its route. Instead every anchor stays resolvable on
/gateway/configuration-reference: all 32 original H2 headings remain as
one-line pointer sections, and all 23 original H3 anchors are retained
as authored <a id> stubs (the pattern already used in
docs/help/faq-first-run.md). All 46 anchored in-repo references across
27 files are rewritten to the child page that now owns the heading;
docs-link-audit --anchors reports 8,717 links checked, 0 broken.

Losslessness (parent + nine children vs. the old single file):

- code fences: 40 -> 40
- MDX components: 4 -> 4
- distinct config keys documented: 490 -> 511 (0 lost, 21 gained from
  the new index text)
- words: 16,756 -> 17,542 (+786, all new index and lede text)
- headings: 55 -> 83 (55 original + 27 pointer H2 + 1 index H2)
- parent page: 2,077 -> 226 lines, 146,192 -> 9,701 chars, 55 -> 33
  headings

src/docs/cloud-workers-config.test.ts pinned the cloudWorkers examples
to configuration-reference.md by path; it now names
config-cloud-workers.md. Twelve zh-CN glossary entries were added for
the new and existing "Configuration - <domain>" page titles.

Closes audit findings: r3-0286, r3-1510
2026-09-07 05:18:18 +08:00
Vincent Koc c16d4796f8 docs: give pages with duplicate titles distinct names (#140208)
Several pages shared a frontmatter title with another page, so search
results, breadcrumbs and the sidebar showed two identical entries with no
way to tell them apart. The topic page keeps the plain title; the
command-scoped CLI page takes the disambiguated one, matching the
existing sibling style in docs/cli (Attach CLI, Inference CLI, Sandbox
CLI, Transcripts CLI, Workboard CLI).

- docs/cli/dashboard.md: Dashboard -> Dashboard CLI (vs docs/web/dashboard.md)
- docs/cli/doctor.md: Doctor -> Doctor CLI (vs docs/gateway/doctor.md)
- docs/cli/hooks.md: Hooks -> Hooks CLI (vs docs/automation/hooks.md)
- docs/cli/nodes.md: Nodes -> Nodes CLI (vs docs/nodes/index.md)
- docs/cli/pairing.md: Pairing -> Pairing CLI (vs docs/channels/pairing.md)
- docs/cli/plugins.md: Plugins -> Plugins CLI (vs docs/tools/plugin.md)
- docs/cli/secrets.md: Secrets -> Secrets CLI (vs docs/tools/secrets.md)
- docs/cli/security.md: Security -> Security CLI (vs docs/gateway/security/index.md)
- docs/cli/setup.md: Setup -> Setup CLI (vs docs/start/setup.md)
- docs/cli/skills.md: Skills -> Skills CLI (vs docs/tools/skills.md)
- docs/cli/tui.md: TUI -> openclaw tui (vs docs/web/tui.md); "TUI CLI" stacks
  two acronyms, so this page uses the command-name style already used by
  docs/cli/status.md and docs/cli/tasks.md
- docs/cli/uninstall.md: Uninstall -> Uninstall CLI (vs docs/install/uninstall.md)
- docs/plugins/onepassword.md: 1Password -> 1Password plugin, matching the
  "<Name> plugin" style of its siblings (vs the docs/gateway/1password.md hub)

No H1, filename, route, nav entry or docs/docs.json change.

Closes audit findings: r4-title-001, r4-title-004, r4-title-005, r4-title-007, r4-title-010, r4-title-011, r4-title-012, r4-title-013, r4-title-014, r4-title-015, r4-title-016, r4-title-017, r4-title-018
2026-09-06 23:25:23 +08:00
64bf824613 feat(onboarding): require explicit AI provider selection (#139675)
* feat(onboarding): require explicit AI provider selection

Worked on by:
- @steipete

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* feat(onboarding): require explicit AI provider selection

Keep detection passive and route native and guided CLI setup through an explicit
provider choice. Include the official install catalog and local custom endpoints
in the shared setup flow, preserve selected runtimes and installer-owned facts,
and initialize native conversation discovery through its configuration owner.

Make skipped onboarding prepare a resumable, owner-fenced baseline. Preserve
existing authored discovery preferences and the named legacy upgrade contract.

* fix(onboarding): complete managed provider activation

Carry approved installation facts through provider discovery, verification,
and final selection without replacing the running Gateway inventory. Compare
authored configuration separately from materialized runtime defaults and bind
the exact provider artifact before and after its connection test.

Keep preparation cancellable at client prompts, honor pending expiry, and
protect credential and configuration persistence together at the final commit.

* fix(onboarding): honor discovery opt-outs in validation

Treat first-write native catalog preferences as privacy settings without
suppressing diagnostics for explicit plugin usage. Keep the existing warning
deduplication contract across subsequent writes and reads.

Remove inert native fallback state and preserve explicit selection, activation
receipt ownership, and unrelated config fields in the native flow fixtures.

* fix(onboarding): complete native validation coverage

Apply canonical formatting to the onboarding view and keep the localization
inventory test anchored to visible consent copy. Pass the existing fixture
model explicitly at both configured-agent response call sites.

* fix(onboarding): preserve bound conversations with discovery disabled

---------

Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
2026-09-06 08:04:28 -07:00
Peter Steinberger 4e0aa56271 refactor(plugins): stage managed npm installs before publication (#140145) 2026-09-06 08:02:31 -07:00
Peter Steinberger 7e6fd5d1d3 fix(plugins): avoid scoped pack failures and missing runtime entries (#140016) 2026-09-06 05:12:30 -07:00
Peter Steinberger 3fe375a94d fix(plugins): remove owned aliases before uninstalling files (#140065)
Persist the planned load-path cleanup with the guarded disable write,
while realpath identity still exists. Keep removal failures retryable,
preserve later config edits, and report the completed alias cleanup.
2026-09-06 04:38:29 -07:00
Peter Steinberger 1d9ce1ac9f fix(plugins): explain SDK incompatibilities after core updates (#139458)
* fix(doctor): detect stale runtime plugins against updated core

Post-update repair now uses the newly installed compatibility host version for both candidate detection and installation, so an updater still running old code refreshes stale configured runtime plugins. Preserve existing selector, consent, and newer-package behavior.

* fix(plugins): explain incompatible SDK imports

Annotate native SDK import failures through the existing registry diagnostic channel with the imported seam, core/build versions, and repair guidance. Preserve channel health classifications and raw-error suppression in model responses. Consolidate validation error recording and redundant formatting wrappers to keep production code net-negative across the repair.

* test(doctor): keep version-skew fixture ahead of the running core
2026-09-05 18:11:21 -07:00
Peter Steinberger 6a97159ece feat: add experimental plugin UI customization (#134943)
* feat: let plugins customize the Control UI

* fix: harden feature plugin lifecycle and artifact activation

* fix(plugins): complete native UI integration

* fix(plugins): preserve hook ownership and composer styling

* chore(workboard): refresh generated browser assets

* test(android): hold reconciliation replies until delivery checks

* refactor(plugins): simplify feature UI ownership

Share bundle validation and scoped host-handle cleanup. Consolidate
Workboard component and draft-save lifecycles, and remove unreachable
loading/enablement paths and retired select styles.

Keep both compiler regression matrices through shared fixtures, remove
duplicate tests, and regenerate the reduced locale catalog and browser
asset references.

* test(ui): return session snapshots from worker stop fixtures

* fix(ui): hydrate session rosters from selected agents

Use the application selection owner for bootstrap and reconnect, retain its filtered query for later refreshes, and remove duplicate sidebar refreshes. Cover delayed bootstrap, saved selection, and offline selection changes.

Refresh generated protocol and browser assets after the rebase, and share hydration fixtures and roster reconciliation helpers.

* perf(ui): defer plugin initialization and customization

Load plugin assets with the existing lazy SDK host and load customization controls on demand. Keep activation cleanup with the runtime and preserve dialog reload state across close and reopen.

Remove retired Workboard selectors, move glyph styling into the plugin, and regenerate its browser revision. Preserve the existing startup payload limits.

* refactor(ui): separate native asset loading from host services

* test(plugins): align UI integration with current main

Refresh canonical Workboard assets and the Control UI boot inventory after rebasing. Match the current bootstrap signature, delegated permission policy, and widget Delete label in existing regressions.

* chore(workboard): refresh browser revision after rebase

* chore(ui): refresh generated assets after main sync

* fix(plugins): preserve native UI lifetimes after main sync

Keep saved plugin panels closable while their registration is unavailable and prevent actions withdrawn during resolution from starting. Defer native view mounting code through plugin activation while preserving synchronous built-in rendering.

Integrate the shared Dashboard side-panel lifecycle, remove the session helper type cycle, reuse core Gateway classification, and consolidate menu coverage. Refresh generated assets after the main rebase.

Validated with focused Gateway/UI tests, failing/passing lifetime regressions, 14 browser scenarios, typechecks, lint, cycle and assertion guards, and the enforced Control UI performance check.

* chore(ui): refresh boot manifest after main rebase

* chore(ui): refresh feature integration after main update

Preserve current composer admission and sidebar ownership while adopting the canonical formatter output and browser assets. Complete the existing panel fixture with the new desktop-focus contract.

* test(ui): verify native plugin asset admission

* test(ui): await service worker activation in phone proof

* refactor(plugins): remove redundant UI plumbing

* feat(plugins): gate custom UI behind an experimental lab

* fix(plugins): align Labs helper types with callers

* style(ui): format retained plugin panel definitions

* test(ui): preserve minimized dashboard in native plugin flow

* fix: preserve plugin UI edits and refresh ordering

Synchronize reapplied template fields, fence shared widget reads across moves, and retain newer mutation errors through queued refreshes. Verify immutable browser assets when Windows reports a directory collision. Keep the checkout helper terminal exit outside exception handlers to avoid Python 3.9 context-cycle hangs.

* test: align plugin UI proof with current panel layout

* test: repair plugin UI validation and generated checkout helper

* test: bind session search fixtures to their selection owner

* fix: preserve session search ownership and execution denial proof

* test: use a real page element for plugin sidebar fixtures

* fix: respect native plugin UI deployment boundaries

* test: share UI fixture isolation across runners

* refactor: share the native plugin asset root

* test: check failure trailers on their owning stream
2026-09-04 09:50:51 -07:00
Peter Steinberger 7d71d26e77 docs: keep ClawHub guidance in its canonical source (#138157)
Remove competing local CLI and publishing pages while preserving OpenClaw-specific workflows and the owner primer in existing guides. Keep the ClawHub mirror and published routes unchanged, and document real-mirror anchor validation. Related: #138121.
2026-09-04 03:12:07 -07:00
Peter Steinberger 629bedd123 fix(plugins): report newer releases behind official version pins (#137578)
Use the existing exact-pin diagnostic for unchanged official bulk updates
and dry runs. Preserve the recorded selector until the operator explicitly
changes it, including ambiguous pins created by older official syncs.
Remove no-op record-spec transformations from the canonical update owner.

Regression: four official cases fail before the repair while four third-party
controls pass. All 272 owner/sibling tests, full build, changed gate and
independent review pass. A fresh Linux baseline/candidate CLI proof preserves
both pins, reports the official newer release only after the fix, and executes
the printed selector-change command without changing the other plugin.

Production LOC: +15/-37 (net -22). Tests: +71/-35. Docs: +3/-1.
Related: https://github.com/openclaw/openclaw/pull/105374
Original automatic-pin producer already repaired by #134490.
2026-09-03 15:07:02 -07:00
weiqinlandAyaan Zaidi 1af9bacfa0 fix(config): align plugin reload guidance (#136740)
Closes #136710

## Problem

`config.schema.lookup` reported `reloadKind: "hot"` for `plugins.entries.*.enabled`, but its schema help said a restart was required. Several plugin docs repeated the stale restart guidance.

## Product path

```bash
openclaw gateway call config.schema.lookup \
  --params '{"path":"plugins.entries.<plugin>.enabled"}' \
  --json
```

## Root cause

Plugin enablement moved to the in-process plugin reload path, but the older help and lifecycle docs did not move with it. The generic plugin reload rule is hot. An active plugin can still declare a restart-triggering prefix, and `gateway.reload.mode: "off"` still disables config reload.

## Fix

- Describe the default hybrid reload mode and plugin-specific restart exception in schema help.
- Align the generic plugin lifecycle docs with the existing runtime behavior.
- Move the regression from a copy-quality test into the real Gateway WebSocket lookup boundary.
- Keep reload planning, configuration defaults, schemas, and protocol behavior unchanged.

## Compatibility

This is a wording and regression-test repair. It does not change configuration, defaults, reload planning, stored data, or the Gateway protocol.

## Proof

- Current-main red: [Blacksmith run 33714053532](https://github.com/openclaw/openclaw/actions/runs/33714053532) returned `reloadKind: "hot"` beside help containing `(restart required)` for two wildcard plugin paths.
- Regression red: [Blacksmith run 33714561306](https://github.com/openclaw/openclaw/actions/runs/33714561306) failed the new WebSocket lookup test on the stale help.
- Exact-tree green: formatter, `pnpm docs:list --headings`, the WebSocket regression, 24 help-quality tests, and three plugin reload sibling tests passed in [Blacksmith run 33715965706](https://github.com/openclaw/openclaw/actions/runs/33715965706).
- Live green: [Blacksmith run 33716204027](https://github.com/openclaw/openclaw/actions/runs/33716204027) returned matching `hot` metadata and hybrid-mode help for the reported path and a second wildcard path.
- Exact-head Autoreview passed with no P0 findings.

## Credit

This repair preserves @LiuwqGit's original commit and intent.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-03 10:34:18 +05:30
Peter Steinberger 1ec63079e8 fix(plugins): preserve inspection diagnostics and configured policy (#136596) 2026-09-02 14:54:02 -07:00
xjaylingandAyaan Zaidi e861df1b16 fix(plugins): preserve uninstall intent across restart (#135729)
Keep an exact disabled marker after managed plugin uninstall so Gateway startup cannot restore a provider that the operator explicitly removed.

Keep validation and Doctor cleanup aligned with that lifecycle state, while retired plugin ids and disabled entries with retained settings remain actionable.

Update CLI, release, and lifecycle assertions to enforce the marker across every uninstall path.

Closes #135726

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-02 11:59:12 +05:30
Peter SteinbergerandJason 80ae248de1 fix(update): preserve configuration and hand failed upgrades to triage (#134490)
* fix(update): preserve configuration and verify upgrade recovery

Prefer npm before ClawHub only among declared plugin identities, preserving explicit source/version intent, artifact integrity and capability consent. Keep the exact installed beta cohort and require typed target absence before fallback.

Preserve authored environment references through both Doctor writers, resolve snapshot destinations at operation time, and keep migration-only metadata out of redacted snapshots. Avoid loading channel runtimes for unused pairing account facts while retaining captured migration-owner attribution.

Record activation safety at package/Git mutation boundaries. Keep installed-CLI recovery, verify runtime/native-service identity, fence Windows autostart, preserve child status, and avoid duplicating consumed notifications or rejecting completed install switches. Surface update-specific disconnect diagnostics without changing explicit-restart guidance in Model Setup.

Retain the upgrade-survivor first-hop, approval and installed-version oracles. Repair CI's type-only Doctor cycle and stale source-policy, final-Doctor and Teams whitespace expectations without weakening timeouts, gates or the main-owned Markdown fix.

PR: https://github.com/openclaw/openclaw/pull/134490

* test(msteams): align the corrected main whitespace fixture

* perf(ui): remove unreachable update translations

Remove superseded version-only verification copy and the unused idle label from the eager catalog. Keep identity-aware verification and all recovery guidance unchanged, align translation fixtures, and restore the existing merged startup budget without increasing its baseline or limits.

* fix(update): retain consent failures and isolate validation homes

Carry unresolved non-retained plugin capability refusals from missing-install
repair through post-core convergence as typed outcomes, preserving the existing
update failure and restart boundary. Keep usable retained artifacts and
transient fetch failures on their existing notice/warning paths.

Give test invocations a native process HOME before config imports and worker
creation. Preserve bounded live/profile context, report selection, installed
tool caches, and process-group/pipe-owned namespace cleanup or truthful
retention. Keep unknown or mixed explicit real-home selections closed.
Resolve the repo-owned staging helper from its owning cwd and await complete
PID readiness before cancelling native report fixtures.

Align the survivor recovery oracle with typed consent errors that intentionally
have no Doctor reason. Preserve strict plugin/code/version/core-step checks and
historical warning-only reports; successful-update admission still rejects
refusals. Keep the local TestHomeMode alias private and satisfy helper lint.

PR: https://github.com/openclaw/openclaw/pull/134490

* fix(plugins): preserve declared catalog identity during upgrade integration

Carry the prepared, provenance-validated ClawHub package instead of discarding
it into a boolean. Suppress the declared installed counterpart without deriving
an npm identity from overlaid display metadata or hiding an npm namesake.
Keep lazy prepared catalog facts and first-normalized-record icon behavior.

Retain explicit ClawHub-only actions and npm-first dual-source actions, and
cover the selected source's pinned inspection metadata with existing tables.
The incoming duplicate-row cases fail before the provenance fact is retained.

PR: https://github.com/openclaw/openclaw/pull/134490

* fix(ci): include home isolation in PR anchor closure

Register the three runtime dependencies in the canonical extraction and trust inventory. Extracted planners and publishers now load the real home policy, context, and selection modules without stubs or weaker assertions. The existing extracted-anchor regression fails before this change and the full wrapper suite passes afterward.

* fix(update): hand failed upgrades to local coding agents

Route interactive update failures through triage after updater ownership is
released. Preserve the captured installation, invocation directory, bounded
diagnostics and original update result while the installed coding agent
repairs and verifies the machine using its existing permissions.

Keep background and JSON guidance consistent, preserve config references,
and fix resolved consent failures and selected catalog source provenance.

Validation: complete combined P2 review, 639 focused tests, 71 UI unit
tests, and four Chromium scenarios passed. Full changed-code checks passed
all typegraphs but stopped on one no-map-spread lint error in a test fixture.

Local integration checkpoint: fix that fixture and combine the current main
triage owner before final review, package proof, publication, or landing.

* fix(update): preserve configuration and verify upgrade recovery

Prefer npm before ClawHub only among declared plugin identities, preserving explicit source/version intent, artifact integrity and capability consent. Keep the exact installed beta cohort and require typed target absence before fallback.

Preserve authored environment references through both Doctor writers, resolve snapshot destinations at operation time, and keep migration-only metadata out of redacted snapshots. Avoid loading channel runtimes for unused pairing account facts while retaining captured migration-owner attribution.

Record activation safety at package/Git mutation boundaries. Keep installed-CLI recovery, verify runtime/native-service identity, fence Windows autostart, preserve child status, and avoid duplicating consumed notifications or rejecting completed install switches. Surface update-specific disconnect diagnostics without changing explicit-restart guidance in Model Setup.

Retain the upgrade-survivor first-hop, approval and installed-version oracles. Repair CI's type-only Doctor cycle and stale source-policy, final-Doctor and Teams whitespace expectations without weakening timeouts, gates or the main-owned Markdown fix.

PR: https://github.com/openclaw/openclaw/pull/134490

* test(msteams): align the corrected main whitespace fixture

* perf(ui): remove unreachable update translations

Remove superseded version-only verification copy and the unused idle label from the eager catalog. Keep identity-aware verification and all recovery guidance unchanged, align translation fixtures, and restore the existing merged startup budget without increasing its baseline or limits.

* fix(update): retain consent failures and isolate validation homes

Carry unresolved non-retained plugin capability refusals from missing-install
repair through post-core convergence as typed outcomes, preserving the existing
update failure and restart boundary. Keep usable retained artifacts and
transient fetch failures on their existing notice/warning paths.

Give test invocations a native process HOME before config imports and worker
creation. Preserve bounded live/profile context, report selection, installed
tool caches, and process-group/pipe-owned namespace cleanup or truthful
retention. Keep unknown or mixed explicit real-home selections closed.
Resolve the repo-owned staging helper from its owning cwd and await complete
PID readiness before cancelling native report fixtures.

Align the survivor recovery oracle with typed consent errors that intentionally
have no Doctor reason. Preserve strict plugin/code/version/core-step checks and
historical warning-only reports; successful-update admission still rejects
refusals. Keep the local TestHomeMode alias private and satisfy helper lint.

PR: https://github.com/openclaw/openclaw/pull/134490

* fix(plugins): preserve declared catalog identity during upgrade integration

Carry the prepared, provenance-validated ClawHub package instead of discarding
it into a boolean. Suppress the declared installed counterpart without deriving
an npm identity from overlaid display metadata or hiding an npm namesake.
Keep lazy prepared catalog facts and first-normalized-record icon behavior.

Retain explicit ClawHub-only actions and npm-first dual-source actions, and
cover the selected source's pinned inspection metadata with existing tables.
The incoming duplicate-row cases fail before the provenance fact is retained.

PR: https://github.com/openclaw/openclaw/pull/134490

* fix(ci): include home isolation in PR anchor closure

Register the three runtime dependencies in the canonical extraction and trust inventory. Extracted planners and publishers now load the real home policy, context, and selection modules without stubs or weaker assertions. The existing extracted-anchor regression fails before this change and the full wrapper suite passes afterward.

* fix(test): preserve source home when loading profiles

Read the explicitly selected profile with a non-login Bash command so
system and user login startup cannot replace the source HOME first.
Keep positional profile quoting, child-only HOME/USERPROFILE, existing
profile opt-in and test/native-home isolation unchanged.

The existing six profile-home matrix cases failed on Linux CI run
33536959196, job 99953769387. New exact-head Linux CI remains required;
this local repair does not refresh or admit the prior native proof.

PR: https://github.com/openclaw/openclaw/pull/134490

* fix(update): complete failure triage integration

Keep landed failure diagnosis after recovery and cleanup decisions without
letting diagnostic exports authorize activation or overwrite updater exits.
Preserve exact unsafe handoff and nested foreground results, consumed
notifications, successful install-root switches, typed consent failures and
update-specific disconnected guidance alongside main's triage takeover.

Contain diagnostic read failures inside the diagnostic owner so a completed
recovery still releases its lease and sensitive files. Retain phase-labelled
updater, recovery and diagnostic exits plus helper terminal completion.
Remove the trivial aggregate-error wrapper while preserving both failures,
and consolidate launchd/notification coverage into canonical test support.

Focused CLI, Doctor, handoff, UI and profile-home proof passed under external
synthetic homes. Complete integrated P0 review is scoped-clean; exact-head
Linux CI and native/package qualification remain with the parent workflow.
The unchanged main models-cli auth-login test-type error remains a follow-up.

PR: https://github.com/openclaw/openclaw/pull/134490

* test(update): split Doctor and service recovery fixtures

Move the existing Windows Doctor recovery matrix and shared fixtures into
focused files, and keep managed terminal-outcome tests in their existing
result helper. Preserve all case bodies, assertions, and hook cleanup.

Keep Windows restore failure in a local variable and narrow the triage
prompt-write fixture path before string matching. Scoped type-aware lint,
all affected existing suites, and independent follow-up review pass.

The full repository gate and final packaged Crabbox recovery and upgrade
proof remain required before landing.

* fix(update): retain plugin attempt spec on consent failure

* test(update): preserve runtime exports in option mocks

---------

Co-authored-by: Jason (Json) <263060202+fuller-stack-dev@users.noreply.github.com>
2026-09-01 17:33:22 -06:00
Peter Steinberger f2646be7a9 docs: clarify disabled plugin reinstall behavior (#134875)
* docs: clarify disabled plugin reinstall behavior

* docs: distinguish update consent from plugin activation
2026-09-01 02:42:47 -07:00
Peter Steinberger f54f806b27 fix(plugins): exempt verified first-party plugins from capability consent (#134933) 2026-09-01 00:03:04 -07:00
Peter Steinberger 1d7937d405 fix(plugins): preserve channel ownership during uninstall (#134759) 2026-08-31 22:04:46 -07:00
Ayaan Zaidi 4cc2fe74e1 fix(plugins): report registry persistence differences
Closes #133901

## What Problem This Solves

Fixes an issue where an upgrade could refuse the plugin migration checkpoint after a registry refresh without identifying the managed plugin records that differed. Repeated Doctor runs showed one generic stale-source code per agent workspace and gave operators no direct way to identify or repair the changed package.

Reported by @yubingjiaocn.

## Why This Change Was Made

The registry selector now records sorted per-plugin differences from the same normalized persisted and derived records used for its freshness decision. Doctor keeps the fail-closed checkpoint gate, but reports each plugin ID and both sources. `openclaw plugins registry --refresh` now rereads its write and reports success only after the persisted registry is current.

Explicit inspection uses a fresh operation cache. File freshness is captured before derived discovery can cache old package bytes, so a concurrent managed-plugin update cannot produce a false `fresh` result.

Accepting a derived reread would weaken the migration checkpoint. This change keeps the durable verification introduced by #119051 and improves the owner-level diagnostic and repair path instead.

## User Impact

Operators can see which plugin records prevent registry persistence and can run one deterministic repair command after package updates stop. Scripts using `plugins registry --json` receive a `differences` array. A refresh that remains stale exits with the affected records instead of reporting a false success.

## Evidence

- Red on current main `644c895bdbe1043acc0acf1677c9076d5df4a8e2`: a real managed-plugin registry CLI run changed package metadata during the persisted write and reread. The command exited with two generic `persisted-registry-stale-source` codes for two agent workspaces and no plugin identity. [Blacksmith run](https://github.com/openclaw/openclaw/actions/runs/33370264457)
- Green on executable head `d8e523fb3f738bb9a89df9d827492c4976e94a17`: a built registry CLI run changed a managed source/install pair after the manual refresh captured version 1. Verification returned `ok: false`, `refreshed: false`, `state: stale`, `stale-package`, and the authoritative `managed-drift` difference. A stable retry returned `state: fresh` with no differences. [Blacksmith run](https://github.com/openclaw/openclaw/actions/runs/33384579451)
- Current head `fbd137cc1792aaa4f2aeadcdf38de3b318a92555` changes only `docs/cli/plugins.md` from the proved executable head; the executable tree is identical.
- `node scripts/run-vitest.mjs src/plugins/plugin-registry-snapshot.test.ts` — 38 passed.
- `node scripts/run-vitest.mjs src/plugins/plugin-registry-inspection.test.ts` — 6 passed.
- `node scripts/run-vitest.mjs src/commands/doctor-config-preflight.plugin-persistence.test.ts` — 13 passed.
- `node scripts/run-vitest.mjs src/cli/plugins-cli.list.test.ts` — 37 passed.
- Focused formatting, Oxlint, max-lines, assertion-safety, import-cycle, MDX, docs-format, docs-link, and diff checks passed.
- `pnpm deadcode:full` and `node --import ./scripts/tsx.mjs scripts/check-deadcode-exports.mts` passed after removing an unused internal type export found by the first CI run.
- Local TypeScript typecheck and build were not run under host policy. The CLI build and real behavior proof ran on Blacksmith Testbox.
- Production LOC: +321/-160, net +161. Tests and test support: +186/-30, net +156. Docs: +2/-0.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-31 16:50:18 +05:30
synthandPeter Steinberger e45ba01a95 fix(plugins): keep official plugins aligned with targeted beta updates (#124415)
* fix(plugins): propagate requested beta tag to plugin updates

When updating with an explicit beta tag, the core OpenClaw package moved
to the requested beta release, but post-update external official plugin
resolution left some official npm plugins on the latest dist-tag instead
of the requested beta version.

Pass the requested tag through the update flow so plugin resolution uses
the same beta tag as the core package.

Fixes #97680

* fix(plugins): align beta updates with installed core target

Resolve post-core plugin channels from the installed package version and select its exact beta version for eligible official npm records. Preserve explicit targeted selectors and the existing visible default fallback.

Co-authored-by: synthclaw <synthalorian@gmail.com>

* fix(plugins): derive pin guidance from recorded selectors

Do not report core-aligned floating beta or extended-stable targets as user pins. Preserve real exact-pin upgrade guidance in normal and dry-run updates.

* test(plugins): make core-aligned update cases explicit

* test(ci): load process identity through scoped TypeScript import

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: synthclaw <synthalorian@gmail.com>
2026-08-31 01:42:59 -07:00
Peter Steinberger a4f6bdf9a8 fix(plugins): show package provenance in CLI and chat inspection (#133140)
* fix(plugins): show package install metadata when inspecting child entries

* fix(plugins): share package ownership in chat inspection

* chore(plugins): remove unused chat inspection type import
2026-08-30 01:00:50 -07:00
Peter Steinberger 52e43a4a4f feat(gateway): auto-apply safe doctor config migrations at startup (#132135)
* feat(gateway): auto-apply safe doctor config migrations at startup

Gateway startup now runs the same deterministic, prompt-free legacy
config-key migrations as "openclaw doctor --fix" when an otherwise
invalid single-file config can be fully migrated, instead of refusing
readiness with a doctor hint. The write happens under the existing
startup migration lease, after state migrations consume retired
locators, only when the complete result validates including plugins,
and keeps the previous config in the .bak ring. Configs using
$include, Nix mode, newer-version configs, update-in-progress runs,
and configs that stay invalid keep the current fail-closed refusal.

This replaces the narrow two-key stable-upgrade repair with the full
migration set (which subsumes it), so headless service gateways just
work across upgrades instead of stopping on retired config keys.

* fix(doctor): keep startup repair preview off the shared state database

resolveStartupConfigSnapshot serves gateway pre-bootstrap selection and
backup discovery, which run before state-database admission. The full
planner resolves plugin doctor contracts through the installed-plugin
registry, which opens the shared SQLite store — a broken store (or
backup's pre-validation guarantee) must not break those callers. The
preview tier now applies only state-free migrations with raw validation;
the preflight committer and canonical-write matcher stay authoritative.

* test(doctor): avoid shadowing the path module in repair fixtures

* test(doctor): pin checkpoint build provenance for unbuilt test environments

CI unit shards and unbuilt checkouts have no dist/build-info.json, so the
checkpoint layer fails open by design and the startup-repair checkpoint
assertions could never hold there. Wrap the real module with a pinned
build identity so recording and needs-checks stay meaningful.

* fix(doctor): reach plugin-owned migrations from the startup trust check

The pre-bootstrap trust check admitted only state-free core migrations,
so a config whose sole repair belongs to a plugin doctor contract was
refused before the plugin-aware preflight could migrate it. The resolver
now runs the full planner first and falls back to the state-free preview
only when the installed-plugin registry store is unreachable, keeping
backup discovery and broken-store startups fail-closed.
2026-08-28 17:56:30 -07:00
Peter Steinberger 2058fd7e91 fix(plugins): preserve unreadable registry state (#131521) 2026-08-27 21:48:11 -07:00
Peter Steinberger d933395f1a fix(plugins): refuse git installs onto an existing managed checkout (#131175)
* fix(plugins): refuse git installs onto an existing managed checkout

Check the managed Git target before cloning, using the same availability guard as npm and directory installs. Preserve explicit update and force behavior, and protect existing checkout files when a repository changes its plugin id.

* docs(plugins): clarify git force reinstall identity limits

Limit the Git force example to reinstalling the same plugin id. Force replaces the checkout but does not migrate an existing install record to a different manifest id; normal ownership validation still applies.
2026-08-27 16:52:59 -07:00
Patrick Erichsen 7b7858d955 feat(clawhub): show security audit before installs (#131233)
* feat(clawhub): show audit details before install

* test(clawhub): update fixture audit contract
2026-08-27 16:20:59 -07:00
Peter SteinbergerandVincent Koc 1ea2640f54 refactor(state): consolidate wide rows, plugin index, workspace attestations, and shared auth singletons at schema v13 (#130466)
* refactor(state): make cron and subagent rows JSON-canonical

* refactor(state): make gateway origin device tokens canonical at v13

The lazy ensure predates the table joining the canonical schema; at the
v13 bump the schema owns creation, so the feature-local DDL, WeakSet
dedupe, and lazy-list entry retire. The legacy-file guard the ensure
carried stays at each call site.

* test: drop obsolete lazy-ensure coverage for origin device tokens

The table is canonical at v13; same-version lazy creation no longer
exists to protect. Origin CRUD, isolation, and rotation coverage remains
in the surviving cases.

* refactor(state): fold installed_plugin_index into config_machine_state

The singleton index row becomes one JSON value under
plugins.installedIndex with its rollback-fencing revision inside the
value; reads, CAS restore, and the lease-held write transactions use
direct Kysely on config_machine_state so the state_leases assertion
stays in-transaction. The v13 migration imports the row and drops the
table; the additive workspace_dir entry folds with it. Doctor guidance,
docker staging, and the e2e probes name the machine-state row.

* refactor(state): merge workspace_attestations into workspace_setup_state

One row per workspace now carries both setup milestones and the
attestation clock: nullable setup columns represent attestation-only
workspaces (replaceWorkspaceAttestation can precede any setup write) and
setupExists derives from a non-null version. The bootstrap-hash FK
repoints to the merged table; migration receipts keep the historical
workspace_attestations discriminator string. The v13 migration grows and
rebuilds the table, merges attestation rows (orphans without a path
alias drop — their hashes re-derive at the next bootstrap attestation),
and the consolidation kind is renamed state-consolidation-v13 to cover
the batch.

* test(state): cover the workspace merge and consolidation fallout

The v12-to-v13 regression seeds merged, attestation-only, and orphan
attestation workspaces; the 13-to-12 downgrade fixture recreates
workspace_attestations and installed_plugin_index from the folded data;
the fold-in migration gates the additive workspace_dir column for
pre-additive rows; the workspace merge now triggers on the setup table's
own shape so stable-era databases without an attestations table still
reshape; the consolidation applied-message covers the batch.

* refactor(state): fold shared auth profile singletons into config_machine_state

The shared-state auth_profile_stores/auth_profile_state rows (fixed key
'shared') become authProfiles.store/authProfiles.state machine-state
values; the agent-DB tables of the same names are untouched. Git-backup
redaction moves from table-drop to the authProfiles. secret prefix with
seeded-secret absence proof; migration receipts keep the historical
table-name discriminators; the shared-auth relocation and receipt
verification project the KV cells back to the receipt-era row shapes so
persisted digests stay byte-compatible. mcp_oauth_stores stays a table —
its multi-key fold is a named follow-up.

* test(state): finish shared-auth fold coverage and annotate boundary casts

Auth seeders and assertions across the e2e/scripts/secrets suites target
the authProfiles machine-state cells; the v12-to-v13 regression proves
payload-byte fidelity, non-shared-row drop, and insert-if-absent
precedence; the downgrade fixture recreates and repopulates both v12
tables. Boundary type assertions in the plugin-index store carry SAFETY
invariants per the ratchet.

* chore: shrink assertion-safety baseline for plugin-index store

* refactor(doctor): delete the dead onboarding-recommendations migration

Its input — the unscoped 'primary' onboarding row — existed only between
9a93a52a8a and 473962b7de, a two-day beta window; no shipped stable
can produce it and the runtime table folded away at v12. The audit
backup list keeps recognizing system-agent.jsonl artifacts because beta
installs that ran that import may still carry its backups.

* docs: sync the 13-to-12 downgrade example with the executable fixture

* style: format the synced downgrade example

* style: drop unused import and duplicate union constituent

* fix(state): keep orphan attestations across the v13 workspace merge

The merged workspace_setup_state required a workspace path, but legacy
orphan hashed-key attestations never recorded one. workspace_path is now
nullable (setup rows still enforce it via CHECK), the v13 migration and
the doctor file import keep orphans with a NULL path that heals on the
next live access, and the 13-to-12 downgrade keeps attestation-owned
hashes. Doctor test seeds move to the folded KV row.

* perf(state): retire unused cron indexes

* fix(state): preserve v13 migration recovery

* fix(state): preserve v12 lazy-table upgrade

* docs(state): document v13 auth relocation

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-27 15:26:14 +08:00
EdenandAyaan Zaidi a0abb23d00 fix(plugins): keep beta installs on gateway release (#127791)
Keep official plugins on the gateway release stream so beta gateways do not silently install stable artifacts. Resolve hosted catalog entries at the shared boundary, stop missing cohorts before hook fallback, and keep recovery notices visible.

Co-authored-by: 許元豪 <146086744+edenfunf@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-27 10:53:47 +05:30
wangyan2026andPeter Steinberger e00d46b19b fix(plugins): normalize managed npm overrides before peer planning (#124532)
* [AI] fix(plugins): filter pnpm parent-child overrides at managed npm producer

readOpenClawManagedNpmRootOverrides returned host pnpm-workspace overrides
without filtering pnpm-only parent-child selectors (parent>child). Those
selectors are invalid npm override keys and trigger EINVALIDTAGNAME before
the retry-based compatibility path can recover, breaking managed npm plugin
installs and the pre-install peer-sync that runs before the retry loop.

Filter pnpm parent-child selectors once at the shared producer so every
managed npm install/uninstall consumer receives a npm-compatible manifest
up front. The existing retry path stays as a fallback for npm alias
compatibility, which is npm-version-dependent.

Fixes #124426

* fix(plugins): normalize overrides before managed peer planning

Plan peers against the incoming compatible override set so retired selectors cannot silently retain stale pins. Remove duplicate selector retry and synchronization paths while preserving npm alias compatibility.

Co-authored-by: WangYan <wang.yan29@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-26 20:41:34 -07:00
Jesse Merhi bf40269cb7 feat(security): require acknowledgement for policy warnings (#116489) 2026-08-15 03:58:45 +10:00
Peter Steinberger 5a643e3543 fix(plugins): keep packed entries consistent through package lifecycle (#121174)
* fix(plugins): own packed entry lifecycles by package

Persist package ownership per runtime child, route lifecycle actions through one closed resolver, reconcile removed child policy during updates, and retain rollback generations until durable config/index commit.

* fix(plugins): break uninstall policy import cycle

* test(plugins): model package ownership in lifecycle fixtures
2026-08-12 00:49:29 -07:00
Peter Steinberger f4387b7a5e feat(plugins): support the Agent Plugins bundle format (#120115)
* feat(plugins): support the Agent Plugins bundle format

* docs(plugins): document the Agent Plugins bundle format

* test(agents): preserve agent bundle runtime discovery

* fix(plugins): isolate Agent Plugins data-dir failures and align MCP support reporting

* docs(plugins): list Agent Plugins in the canonical plugin-format guides

* fix(plugins): gate Agent Plugins detection on schema, pure inspection, root-relative cwd

* fix(plugins): record Agent Plugins data-dir ownership explicitly

* docs(plugins): cover Agent Plugins in the CLI install detection guide

* fix(plugins): carry Agent Plugins data-dir and transport contracts through external MCP projections
2026-08-07 02:55:08 -07:00
Vincent Koc 52b8f9be80 fix(plugins): migrate Fish Audio plugin identity (#119900)
* fix(plugins): migrate Fish Audio plugin identity

* fix(plugins): tighten Fish Audio identity migration

* fix(plugins): follow catalog selector for id replacements

* fix(plugins): reject replacement install collisions

* refactor(plugins): reuse skipped update outcomes
2026-08-06 20:50:36 +08:00
clawsweeper[bot]andclawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> ed40d0599b fix(plugins): keep targeted official updates on the core channel (#119799)
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
2026-08-06 15:06:49 +08:00
Vincent Koc 1d446ad2cc fix(plugins): remove stale load paths during uninstall (#118930)
* test(qa): prove marketplace plugin updates

* fix(plugins): clean exact install load paths on uninstall

* fix(ci): register marketplace lifecycle assertions
2026-08-03 21:57:54 +00:00
Peter Steinberger 4c7a8d412b feat(cli): support --json across reporting commands (#117928)
* feat(cli): support --json across reporting commands

* test(cli): satisfy json command checks

* test(cli): type json exception map
2026-08-02 02:56:08 -07:00
MasterSwords1andVincent Koc 732c57435c fix(cli): update plugins doctor clean message (#115073) (#117160)
* fix(cli): update plugins doctor clean message (#115073)

Root cause: plugins doctor reports 'No plugin issues detected.' even when a selected context-engine plugin is quarantined at runtime, because doctor is a fast static control-plane check.
Architectural owner: plugins-cli.runtime.ts
Canonical fix: Change clean status message to direct operators to 'openclaw health' for active runtime quarantine/fallback status.
Production LOC delta: +2 LOC

* fix(cli): update plugins doctor clean message wording (#115073)

Root cause: Refine the diagnostic text message to run openclaw health directly.
Architectural owner: src/cli/plugins-cli.runtime.ts

* fix(cli): clarify plugin doctor scope

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-01 13:54:37 +08:00