diff --git a/.openclaw-sync/source.json b/.openclaw-sync/source.json index 1d090ffa1..5587a1f4a 100644 --- a/.openclaw-sync/source.json +++ b/.openclaw-sync/source.json @@ -1,5 +1,5 @@ { "repository": "openclaw/openclaw", - "sha": "f42645037ffb33ca2471e54c994f93a00e4334ef", - "syncedAt": "2026-05-01T07:23:37.739Z" + "sha": "250376f8857709054a511934f863ceabc7ac6781", + "syncedAt": "2026-05-01T07:50:08.202Z" } diff --git a/docs/cli/channels.md b/docs/cli/channels.md index 3af98b8be..438cb3ee9 100644 --- a/docs/cli/channels.md +++ b/docs/cli/channels.md @@ -51,6 +51,8 @@ openclaw channels remove --channel telegram --delete `openclaw channels add --help` shows per-channel flags (token, private key, app token, signal-cli paths, etc). +`channels remove` only operates on installed/configured channel plugins. Use `channels add` first for installable catalog channels. + Common non-interactive add surfaces include: - bot-token channels: `--token`, `--bot-token`, `--app-token`, `--token-file` @@ -132,6 +134,7 @@ Notes: - Use `--kind user|group|auto` to force the target type. - Resolution prefers active matches when multiple entries share the same name. - `channels resolve` is read-only. If a selected account is configured via SecretRef but that credential is unavailable in the current command path, the command returns degraded unresolved results with notes instead of aborting the entire run. +- `channels resolve` does not install channel plugins. Use `channels add --channel ` before resolving names for an installable catalog channel. ## Related diff --git a/docs/cli/configure.md b/docs/cli/configure.md index 207bc526c..69daa2b19 100644 --- a/docs/cli/configure.md +++ b/docs/cli/configure.md @@ -52,6 +52,7 @@ Available sections: Notes: - Choosing where the Gateway runs always updates `gateway.mode`. You can select "Continue" without other sections if that is all you need. +- After local config writes, configure materializes newly required bundled plugin runtime dependencies. This is a narrow package-manager repair step, not a full `openclaw doctor` run. Remote gateway config does not install local plugin dependencies. - Channel-oriented services (Slack/Discord/Matrix/Microsoft Teams) prompt for channel/room allowlists during setup. You can enter names or IDs; the wizard resolves names to IDs when possible. - If you run the daemon install step, token auth requires a token, and `gateway.auth.token` is SecretRef-managed, configure validates the SecretRef but does not persist resolved plaintext token values into supervisor service environment metadata. - If token auth requires a token and the configured token SecretRef is unresolved, configure blocks daemon install with actionable remediation guidance. diff --git a/docs/cli/gateway.md b/docs/cli/gateway.md index 01d662516..e88f859c1 100644 --- a/docs/cli/gateway.md +++ b/docs/cli/gateway.md @@ -146,7 +146,7 @@ When you set `--url`, the CLI does not fall back to config or environment creden openclaw gateway health --url ws://127.0.0.1:18789 ``` -The HTTP `/healthz` endpoint is a liveness probe: it returns once the server can answer HTTP. The HTTP `/readyz` endpoint is stricter and stays red while startup sidecars, channels, or configured hooks are still settling. Local or authenticated detailed readiness responses include an `eventLoop` diagnostic block with event-loop delay, event-loop utilization, CPU core ratio, and a `degraded` flag. +The HTTP `/healthz` endpoint is a liveness probe: it returns once the server can answer HTTP. The HTTP `/readyz` endpoint is stricter and stays red while startup plugin runtime dependencies, sidecars, channels, or configured hooks are still settling. Local or authenticated detailed readiness responses include an `eventLoop` diagnostic block with event-loop delay, event-loop utilization, CPU core ratio, and a `degraded` flag. ### `gateway usage-cost` diff --git a/docs/cli/onboard.md b/docs/cli/onboard.md index 718eb1e32..01c9f29e1 100644 --- a/docs/cli/onboard.md +++ b/docs/cli/onboard.md @@ -119,6 +119,8 @@ Gateway token options in non-interactive mode: - With `--install-daemon`, if token mode requires a token and the configured token SecretRef is unresolved, onboarding fails closed with remediation guidance. - With `--install-daemon`, if both `gateway.auth.token` and `gateway.auth.password` are configured and `gateway.auth.mode` is unset, onboarding blocks install until mode is set explicitly. - Local onboarding writes `gateway.mode="local"` into the config. If a later config file is missing `gateway.mode`, treat that as config damage or an incomplete manual edit, not as a valid local-mode shortcut. +- Local onboarding materializes newly required bundled plugin runtime dependencies after writing config, before workspace/bootstrap, daemon install, or health checks continue. This is a narrow package-manager repair step, not a full `openclaw doctor` run. +- Remote onboarding only writes connection info for the remote Gateway and does not install local bundled plugin dependencies. - `--allow-unconfigured` is a separate gateway runtime escape hatch. It does not mean onboarding may omit `gateway.mode`. Example: diff --git a/docs/cli/plugins.md b/docs/cli/plugins.md index 43b76d256..493b45ed1 100644 --- a/docs/cli/plugins.md +++ b/docs/cli/plugins.md @@ -33,6 +33,7 @@ openclaw plugins list --verbose openclaw plugins list --json openclaw plugins install openclaw plugins inspect +openclaw plugins inspect --runtime openclaw plugins inspect --json openclaw plugins inspect --all openclaw plugins info @@ -234,7 +235,7 @@ directory remains inert so normal packaged installs still use compiled dist. For runtime hook debugging: -- `openclaw plugins inspect --json` shows registered hooks and diagnostics from a module-loaded inspection pass. +- `openclaw plugins inspect --runtime --json` shows registered hooks and diagnostics from a module-loaded inspection pass. Runtime inspection never downloads missing bundled runtime dependencies; use `openclaw plugins deps --repair` when repair is needed. - `openclaw gateway status --deep --require-rpc` confirms the reachable Gateway, service/process hints, config path, and RPC health. - Non-bundled conversation hooks (`llm_input`, `llm_output`, `before_agent_finalize`, `agent_end`) require `plugins.entries..hooks.allowConversationAccess=true`. @@ -269,6 +270,8 @@ openclaw plugins deps --json Use `--repair` when a packaged install reports missing bundled runtime dependencies during Gateway startup or `plugins doctor`. Repair installs only missing enabled bundled-plugin deps with lifecycle scripts disabled. Use `--prune` to remove stale unknown external runtime-dependency roots left behind by older packaged layouts. +For the full plan, staging, and repair lifecycle, see [Plugin dependency resolution](/plugins/dependency-resolution). + ### Uninstall ```bash @@ -319,10 +322,11 @@ Updates apply to tracked plugin installs in the managed plugin index and tracked ```bash openclaw plugins inspect +openclaw plugins inspect --runtime openclaw plugins inspect --json ``` -Deep introspection for a single plugin. Shows identity, load status, source, registered capabilities, hooks, tools, commands, services, gateway methods, HTTP routes, policy flags, diagnostics, install metadata, bundle capabilities, and any detected MCP or LSP server support. +Inspect shows identity, load status, source, manifest capabilities, policy flags, diagnostics, install metadata, bundle capabilities, and any detected MCP or LSP server support without importing plugin runtime by default. Add `--runtime` to load the plugin module and include registered hooks, tools, commands, services, gateway methods, and HTTP routes. Runtime inspection fails with a repair hint when bundled runtime dependencies are missing; use `openclaw plugins deps --repair` to repair them explicitly. Each plugin is classified by what it actually registers at runtime: diff --git a/docs/docs.json b/docs/docs.json index 5d3b5a847..086782318 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -1197,6 +1197,7 @@ "tools/plugin", "plugins/community", "plugins/bundles", + "plugins/dependency-resolution", "plugins/codex-harness", "plugins/codex-computer-use", "plugins/google-meet", @@ -2673,6 +2674,7 @@ "zh-TW/tools/plugin", "zh-TW/plugins/community", "zh-TW/plugins/bundles", + "zh-TW/plugins/dependency-resolution", "zh-TW/plugins/codex-harness", "zh-TW/plugins/codex-computer-use", "zh-TW/plugins/google-meet", @@ -3534,6 +3536,7 @@ "ja-JP/tools/plugin", "ja-JP/plugins/community", "ja-JP/plugins/bundles", + "ja-JP/plugins/dependency-resolution", "ja-JP/plugins/codex-harness", "ja-JP/plugins/codex-computer-use", "ja-JP/plugins/google-meet", @@ -4395,6 +4398,7 @@ "es/tools/plugin", "es/plugins/community", "es/plugins/bundles", + "es/plugins/dependency-resolution", "es/plugins/codex-harness", "es/plugins/codex-computer-use", "es/plugins/google-meet", @@ -5256,6 +5260,7 @@ "pt-BR/tools/plugin", "pt-BR/plugins/community", "pt-BR/plugins/bundles", + "pt-BR/plugins/dependency-resolution", "pt-BR/plugins/codex-harness", "pt-BR/plugins/codex-computer-use", "pt-BR/plugins/google-meet", @@ -6117,6 +6122,7 @@ "ko/tools/plugin", "ko/plugins/community", "ko/plugins/bundles", + "ko/plugins/dependency-resolution", "ko/plugins/codex-harness", "ko/plugins/codex-computer-use", "ko/plugins/google-meet", @@ -6978,6 +6984,7 @@ "de/tools/plugin", "de/plugins/community", "de/plugins/bundles", + "de/plugins/dependency-resolution", "de/plugins/codex-harness", "de/plugins/codex-computer-use", "de/plugins/google-meet", @@ -7839,6 +7846,7 @@ "fr/tools/plugin", "fr/plugins/community", "fr/plugins/bundles", + "fr/plugins/dependency-resolution", "fr/plugins/codex-harness", "fr/plugins/codex-computer-use", "fr/plugins/google-meet", @@ -8700,6 +8708,7 @@ "ar/tools/plugin", "ar/plugins/community", "ar/plugins/bundles", + "ar/plugins/dependency-resolution", "ar/plugins/codex-harness", "ar/plugins/codex-computer-use", "ar/plugins/google-meet", @@ -9561,6 +9570,7 @@ "it/tools/plugin", "it/plugins/community", "it/plugins/bundles", + "it/plugins/dependency-resolution", "it/plugins/codex-harness", "it/plugins/codex-computer-use", "it/plugins/google-meet", @@ -10422,6 +10432,7 @@ "vi/tools/plugin", "vi/plugins/community", "vi/plugins/bundles", + "vi/plugins/dependency-resolution", "vi/plugins/codex-harness", "vi/plugins/codex-computer-use", "vi/plugins/google-meet", @@ -11283,6 +11294,7 @@ "nl/tools/plugin", "nl/plugins/community", "nl/plugins/bundles", + "nl/plugins/dependency-resolution", "nl/plugins/codex-harness", "nl/plugins/codex-computer-use", "nl/plugins/google-meet", @@ -12144,6 +12156,7 @@ "tr/tools/plugin", "tr/plugins/community", "tr/plugins/bundles", + "tr/plugins/dependency-resolution", "tr/plugins/codex-harness", "tr/plugins/codex-computer-use", "tr/plugins/google-meet", @@ -13005,6 +13018,7 @@ "uk/tools/plugin", "uk/plugins/community", "uk/plugins/bundles", + "uk/plugins/dependency-resolution", "uk/plugins/codex-harness", "uk/plugins/codex-computer-use", "uk/plugins/google-meet", @@ -13866,6 +13880,7 @@ "id/tools/plugin", "id/plugins/community", "id/plugins/bundles", + "id/plugins/dependency-resolution", "id/plugins/codex-harness", "id/plugins/codex-computer-use", "id/plugins/google-meet", @@ -14727,6 +14742,7 @@ "pl/tools/plugin", "pl/plugins/community", "pl/plugins/bundles", + "pl/plugins/dependency-resolution", "pl/plugins/codex-harness", "pl/plugins/codex-computer-use", "pl/plugins/google-meet", diff --git a/docs/gateway/doctor.md b/docs/gateway/doctor.md index 71659e9ee..63fe501cc 100644 --- a/docs/gateway/doctor.md +++ b/docs/gateway/doctor.md @@ -342,7 +342,7 @@ That stages grounded durable candidates into the short-term dreaming store while Doctor verifies runtime dependencies only for bundled plugins that are active in the current config or enabled by their bundled manifest default, for example `plugins.entries.discord.enabled: true`, legacy `channels.discord.enabled: true`, configured `models.providers.*` / agent model refs, or a default-enabled bundled plugin without provider ownership. If any are missing, doctor reports the packages and installs them in `openclaw doctor --fix` / `openclaw doctor --repair` mode. External plugins still use `openclaw plugins install` / `openclaw plugins update`; doctor does not install dependencies for arbitrary plugin paths. - During doctor repair, bundled runtime-dependency npm installs report spinner progress in TTY sessions and periodic line progress in piped/headless output. The Gateway and local CLI can also repair active bundled plugin runtime dependencies on demand before importing a bundled plugin. These installs are scoped to the plugin runtime install root, run with scripts disabled, do not write a package lock, and are guarded by an install-root lock so concurrent CLI or Gateway starts do not mutate the same `node_modules` tree at the same time. + During doctor repair, bundled runtime-dependency npm installs report spinner progress in TTY sessions and periodic line progress in piped/headless output. The Gateway and local CLI can also repair active bundled plugin runtime dependencies on demand before importing a bundled plugin. These installs are scoped to the plugin runtime install root, run with scripts disabled, do not write a package lock, and are guarded by an install-root lock so concurrent CLI or Gateway starts do not mutate the same `node_modules` tree at the same time. Stale legacy locks from killed Docker/container starts are reclaimed when their owner metadata cannot prove a current process incarnation and the lock files are old. diff --git a/docs/plugins/dependency-resolution.md b/docs/plugins/dependency-resolution.md new file mode 100644 index 000000000..2f77f9be9 --- /dev/null +++ b/docs/plugins/dependency-resolution.md @@ -0,0 +1,214 @@ +--- +summary: "How OpenClaw plans, stages, and repairs bundled plugin runtime dependencies" +read_when: + - You are debugging bundled plugin runtime dependency repair + - You are changing plugin startup, doctor, or package-manager install behavior + - You are maintaining packaged OpenClaw installs or bundled plugin manifests +title: "Plugin dependency resolution" +sidebarTitle: "Dependencies" +--- + +OpenClaw does not install every bundled plugin dependency tree at package install +time. It first derives an effective plugin plan from config and plugin metadata, +then stages runtime dependencies only for bundled OpenClaw-owned plugins that +the plan can actually load. + +This page covers packaged runtime dependencies for bundled OpenClaw plugins. +Third-party plugins and custom plugin paths still use explicit plugin +installation commands such as `openclaw plugins install` and +`openclaw plugins update`. + +## Responsibility split + +OpenClaw owns the plan and policy: + +- which plugins are active for this config +- which dependency roots are writable or read-only +- when repair is allowed +- which plugin ids are staged for startup +- final checks before importing plugin runtime modules + +The package manager owns dependency convergence: + +- package graph resolution +- production, optional, and peer dependency handling +- `node_modules` layout +- package integrity +- lock and install metadata + +In practice, OpenClaw should decide what needs to exist. `pnpm` or `npm` should +make the filesystem match that decision. + +OpenClaw also owns the per-install-root coordination lock. Package managers +protect their own install transaction, but they do not serialize OpenClaw's +manifest writes, isolated-stage copy/rename, final validation, or plugin import +against another Gateway, doctor, or CLI process touching the same runtime +dependency root. + +## Effective plugin plan + +The effective plugin plan is derived from config plus discovered plugin +metadata. These inputs can activate bundled plugin runtime dependencies: + +- `plugins.entries..enabled` +- `plugins.allow`, `plugins.deny`, and `plugins.enabled` +- legacy channel config such as `channels.telegram.enabled` +- configured providers, models, or CLI backend references that require a plugin +- bundled manifest defaults such as `enabledByDefault` +- the installed plugin index and bundled manifest metadata + +Explicit disablement wins. A disabled plugin, denied plugin id, disabled plugin +system, or disabled channel does not trigger runtime dependency repair. Persisted +auth state alone also does not activate a bundled channel or provider. + +The plugin plan is the stable input. The generated dependency materialization is +an output of that plan. + +## Startup flow + +Gateway startup parses config and builds the startup plugin lookup table before +plugin runtime modules are loaded. Startup then stages runtime dependencies only +for the `startupPluginIds` selected by that plan. + +For packaged installs, dependency staging is allowed before plugin import. After +staging, the runtime loader imports startup plugins with install repair disabled; +at that point missing dependency materialization is treated as a load failure, +not another repair loop. + +When startup dependency staging is deferred behind the HTTP bind, Gateway +readiness stays blocked on the `plugin-runtime-deps` reason until the selected +startup plugin dependencies are materialized and the startup plugin runtime has +loaded. + +## When repair runs + +Runtime dependency repair should run when one of these is true: + +- the effective plugin plan changed and adds bundled plugins that need runtime + dependencies +- the generated dependency manifest no longer matches the effective plan +- expected installed package sentinels are missing or incomplete +- `openclaw doctor --fix` or `openclaw plugins deps --repair` was requested + +Runtime dependency repair should not run just because OpenClaw started. A normal +startup with an unchanged plan and complete dependency materialization should +skip package-manager work. + +Commands that edit config, enable plugins, or repair doctor findings can enter +plugin plan mode once, materialize the newly required bundled dependencies, then +return to the normal command flow. Local `openclaw onboard` and +`openclaw configure` do this automatically after they successfully write config, +so the next Gateway run does not discover missing bundled plugin packages after +startup has already begun. Remote onboarding/configure stays read-only for local +runtime deps. + +## Hot reload rule + +Hot reload paths that can change active plugins must go back through plugin plan +mode before loading plugin runtime. The reload should compare the new effective +plugin plan with the previous one, stage missing dependencies for newly active +bundled plugins, then load or restart the affected runtime. + +If a config reload does not change the effective plugin plan, it should not +repair bundled runtime dependencies. + +## Package manager execution + +OpenClaw writes a generated install manifest for the selected bundled runtime +dependencies and runs the package manager in the runtime dependency install +root. It prefers `pnpm` when available and falls back to the Node-bundled `npm` +runner. + +The `pnpm` path uses production dependencies, disables lifecycle scripts, ignores +the workspace, and keeps the store inside the install root: + +```bash +pnpm install \ + --prod \ + --ignore-scripts \ + --ignore-workspace \ + --config.frozen-lockfile=false \ + --config.minimum-release-age=0 \ + --config.store-dir=/.openclaw-pnpm-store \ + --config.node-linker=hoisted \ + --config.virtual-store-dir=.pnpm +``` + +The `npm` fallback uses the safe npm install wrapper with production +dependencies, lifecycle scripts disabled, workspace mode disabled, audit +disabled, fund output disabled, legacy peer dependency behavior, and package-lock +output enabled for the generated install root. + +After install, OpenClaw validates the staged dependency tree before making it +visible to the runtime dependency root. Isolated staging is copied into the +runtime dependency root and validated again. + +The whole repair/materialization section is guarded by an install-root lock. +Current lock owners record PID, process start-time when available, and creation +time. Legacy locks without process start-time or creation-time evidence are only +reclaimed by filesystem age, so recycled Docker PID 1 locks recover without +expiring normal long-running current installs by age alone. + +## Install roots + +Packaged installs must not mutate read-only package directories. OpenClaw can +read dependency roots from packaged layers, but writes generated runtime +dependencies to a writable stage such as: + +- `OPENCLAW_PLUGIN_STAGE_DIR` +- `$STATE_DIRECTORY` +- `~/.openclaw/plugin-runtime-deps` +- `/var/lib/openclaw/plugin-runtime-deps` in container-style installs + +The writable root is the final materialization target. Older read-only roots are +kept as compatibility layers only when needed. + +When a packaged OpenClaw update changes the versioned writable root but the +selected bundled-plugin dependency plan is still satisfied by a previous staged +root, repair reuses that previous `node_modules` tree instead of running the +package manager again. The new versioned root still gets its own current package +runtime mirror, so plugin code comes from the current OpenClaw package while +unchanged dependency trees are shared across updates. Reuse skips previous roots +with an active OpenClaw runtime-dependency lock, so a new root does not link to a +dependency tree that another Gateway, doctor, or CLI process is currently +repairing. + +## Doctor and CLI commands + +Use `plugins deps` to inspect or repair bundled plugin runtime dependency +materialization: + +```bash +openclaw plugins deps +openclaw plugins deps --json +openclaw plugins deps --repair +openclaw plugins deps --prune +``` + +Use doctor when the dependency state is part of broader install health: + +```bash +openclaw doctor +openclaw doctor --fix +``` + +`plugins deps` and doctor operate on OpenClaw-owned bundled plugin runtime +dependencies selected by the effective plugin plan. They are not third-party +plugin install or update commands. + +## Troubleshooting + +If a packaged install reports missing bundled runtime dependencies: + +1. Run `openclaw plugins deps --json` to inspect the selected plan and missing + packages. +2. Run `openclaw plugins deps --repair` or `openclaw doctor --fix` to repair the + writable dependency stage. +3. If the install root is read-only, set `OPENCLAW_PLUGIN_STAGE_DIR` to a + writable path and rerun repair. +4. Restart Gateway after repair if the missing dependency blocked startup plugin + loading. + +In source checkouts, the workspace install usually provides bundled plugin +dependencies. Run `pnpm install` for source dependency repair instead of using +packaged runtime dependency repair as the first step. diff --git a/docs/tools/acp-agents.md b/docs/tools/acp-agents.md index 34111c2ff..9c076687c 100644 --- a/docs/tools/acp-agents.md +++ b/docs/tools/acp-agents.md @@ -41,7 +41,8 @@ directly to existing OpenClaw channel conversations, use Usually yes. Fresh installs ship the bundled `acpx` runtime plugin enabled by default with a plugin-local pinned `acpx` binary that OpenClaw probes -and self-repairs on startup. Run `/acp doctor` for a readiness check. +and self-repairs immediately after the Gateway HTTP listener is live. Run +`/acp doctor` for a readiness check. OpenClaw only teaches agents about ACP spawning when ACP is **truly usable**: ACP must be enabled, dispatch must not be disabled, the current diff --git a/docs/tools/plugin.md b/docs/tools/plugin.md index c0dfbbe43..31ff50d71 100644 --- a/docs/tools/plugin.md +++ b/docs/tools/plugin.md @@ -93,6 +93,8 @@ repair; explicit bundled channel enablement (`channels..enabled: true`) can still repair that channel's plugin dependencies. External plugins and custom load paths must still be installed through `openclaw plugins install`. +See [Plugin dependency resolution](/plugins/dependency-resolution) for the full +planning and staging lifecycle. ## Plugin types @@ -309,7 +311,7 @@ do not run in live chat traffic, check these first: - Restart the live Gateway after plugin install/config/code changes. In wrapper containers, PID 1 may only be a supervisor; restart or signal the child `openclaw gateway run` process. -- Use `openclaw plugins inspect --json` to confirm hook registrations and +- Use `openclaw plugins inspect --runtime --json` to confirm hook registrations and diagnostics. Non-bundled conversation hooks such as `llm_input`, `llm_output`, `before_agent_finalize`, and `agent_end` need `plugins.entries..hooks.allowConversationAccess=true`. @@ -336,7 +338,7 @@ Debug steps: - Run `openclaw plugins list --enabled --verbose` to see every enabled plugin and origin. -- Run `openclaw plugins inspect --json` for each suspected plugin and +- Run `openclaw plugins inspect --runtime --json` for each suspected plugin and compare `channels`, `channelConfigs`, `tools`, and diagnostics. - Run `openclaw plugins registry --refresh` after installing or removing plugin packages so persisted metadata reflects the current install. @@ -381,7 +383,8 @@ openclaw plugins list # compact inventory openclaw plugins list --enabled # only enabled plugins openclaw plugins list --verbose # per-plugin detail lines openclaw plugins list --json # machine-readable inventory -openclaw plugins inspect # deep detail +openclaw plugins inspect # static detail +openclaw plugins inspect --runtime # registered hooks/tools/diagnostics openclaw plugins inspect --json # machine-readable openclaw plugins inspect --all # fleet-wide table openclaw plugins info # inspect alias