* perf(plugins): extend discovery threading to loader, manifest registry, installed-index, and config contracts
Follow-up to #75451. Threads optional discovery?: PluginDiscoveryResult
through the remaining helpers that still call discoverOpenClawPlugins
internally during startup:
- loadOpenClawPlugins / loadOpenClawPluginCliRegistry (src/plugins/loader.ts):
add discovery? to PluginLoadOptions and consult it before falling back to
an internal scan at both call sites.
- loadPluginManifestRegistry (src/plugins/manifest-registry.ts): accept
discovery? as a more ergonomic alternative to the existing candidates? /
diagnostics? pair; candidates? still wins when both are supplied.
- resolveInstalledPluginIndexRegistry (src/plugins/installed-plugin-index-registry.ts):
add discovery? to LoadInstalledPluginIndexParams and use it when
candidates aren't supplied.
- resolvePluginConfigContractsById (src/plugins/config-contracts.ts): add
discovery? and thread it into the bundled-fallback discovery call.
Add discovery-threading.test.ts asserting each entry point skips its
internal discoverOpenClawPlugins call when discovery is supplied, calls it
when nothing is supplied, and prefers explicit candidates over discovery
when both are present (6 tests, all pass).
discoverOpenClawPlugins remains stateless; sharing is function-scoped per
src/plugins/CLAUDE.md guidance. Backward compatible: every change is
additive (new optional param).
* perf(plugins): drop verbose JSDoc from discovery? params
* perf(plugins): scan-scoped package.json cache in discovery
Adds a per-scan Map<string, PackageManifest | null> threaded through
discoverFromPath/discoverInDirectory/readCandidatePackageManifest, keyed
by the directory's resolved real path. Within one discovery scan, a
plugin's package.json is now read from disk once and reused across the
overlapping discovery code paths (bundled overlay scan, stock-root scan,
source-checkout extensions scan, installed-path scan, global-root scan)
that previously each fired their own read.
The cache lifetime is one scan (created in runPluginDiscovery alongside
the existing realpathCache and seen Set, dies when the scan returns).
discoverOpenClawPlugins remains stateless externally; no persistent
metadata cache.
* perf(plugins): expose raw parsed package.json on PluginCandidate
Discovery already reads each plugin's package.json once and produces a
parsed PackageManifest object before distilling it into metadata via
getPackageManifestMetadata. Currently only the distilled metadata is
kept on the candidate; the full parsed manifest is discarded.
Store the full parsed manifest on rawPackageManifest so downstream
consumers iterating candidates can use it instead of re-reading from
disk. This is the candidate-side groundwork for the scenario-C followup
that routes consumers (bundled-plugin-metadata, bundle-* helpers, etc.)
through the cached field; those consumers currently do their own
directory scans and would need to be refactored to iterate
PluginCandidate arrays before they can benefit.
The field is a frozen-at-discovery-time snapshot, same lifetime semantics
as the existing packageManifest / packageName / packageVersion fields on
PluginCandidate. No new staleness window introduced.
* perf(plugins): make package-manifest cache key trust-aware
* perf(plugins): extend discovery threading to loader, manifest registry, installed-index, and config contracts
Follow-up to #75451. Threads optional discovery?: PluginDiscoveryResult
through the remaining helpers that still call discoverOpenClawPlugins
internally during startup:
- loadOpenClawPlugins / loadOpenClawPluginCliRegistry (src/plugins/loader.ts):
add discovery? to PluginLoadOptions and consult it before falling back to
an internal scan at both call sites.
- loadPluginManifestRegistry (src/plugins/manifest-registry.ts): accept
discovery? as a more ergonomic alternative to the existing candidates? /
diagnostics? pair; candidates? still wins when both are supplied.
- resolveInstalledPluginIndexRegistry (src/plugins/installed-plugin-index-registry.ts):
add discovery? to LoadInstalledPluginIndexParams and use it when
candidates aren't supplied.
- resolvePluginConfigContractsById (src/plugins/config-contracts.ts): add
discovery? and thread it into the bundled-fallback discovery call.
Add discovery-threading.test.ts asserting each entry point skips its
internal discoverOpenClawPlugins call when discovery is supplied, calls it
when nothing is supplied, and prefers explicit candidates over discovery
when both are present (6 tests, all pass).
discoverOpenClawPlugins remains stateless; sharing is function-scoped per
src/plugins/CLAUDE.md guidance. Backward compatible: every change is
additive (new optional param).
* perf(plugins): drop verbose JSDoc from discovery? params
Follow-up to #75451. Threads optional discovery?: PluginDiscoveryResult
through the remaining helpers that still call discoverOpenClawPlugins
internally during startup:
- loadOpenClawPlugins / loadOpenClawPluginCliRegistry (src/plugins/loader.ts):
add discovery? to PluginLoadOptions and consult it before falling back to
an internal scan at both call sites.
- loadPluginManifestRegistry (src/plugins/manifest-registry.ts): accept
discovery? as a more ergonomic alternative to the existing candidates? /
diagnostics? pair; candidates? still wins when both are supplied.
- resolveInstalledPluginIndexRegistry (src/plugins/installed-plugin-index-registry.ts):
add discovery? to LoadInstalledPluginIndexParams and use it when
candidates aren't supplied.
- resolvePluginConfigContractsById (src/plugins/config-contracts.ts): add
discovery? and thread it into the bundled-fallback discovery call.
Add discovery-threading.test.ts asserting each entry point skips its
internal discoverOpenClawPlugins call when discovery is supplied, calls it
when nothing is supplied, and prefers explicit candidates over discovery
when both are present (6 tests, all pass).
discoverOpenClawPlugins remains stateless; sharing is function-scoped per
src/plugins/CLAUDE.md guidance. Backward compatible: every change is
additive (new optional param).
Add optional discovery parameter to loadBundledCapabilityRuntimeRegistry,
resolveBundledPluginSources, and listChannelCatalogEntries so callers
that already hold a PluginDiscoveryResult can skip redundant filesystem
walks.
In contracts/registry.ts, the retry loop in
loadScopedCapabilityRuntimeRegistryEntries computes discovery once
and shares it across retry attempts (function-scoped, not module-scoped).
discoverOpenClawPlugins() itself remains stateless with no hidden cache.
Closes#82308
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
Summary:
- The branch adds a close lifecycle for local memory embedding providers, scoped memory search/index teardown for one agent, Active Memory timeout cleanup, focused tests, and a changelog entry.
- Reproducibility: yes. The linked issue gives a concrete OpenClaw 2026.5.18 Telegram Active Memory timeout pa ... current-main source inspection confirms there is no timeout cleanup for that local embedding provider path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(memory): close local embedding providers on timeout
Validation:
- ClawSweeper review passed for head 8e2e369b5c.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8e2e369b5c
Review: https://github.com/openclaw/openclaw/pull/84048#issuecomment-4485705481
Co-authored-by: brokemac79 <martin_cleary@yahoo.co.uk>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: hxy91819
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Summary:
- The PR changes outbound channel registry loading and bootstrap to fall back from pinned setup-only channel entries to the active runtime registry, with regression tests and a changelog entry.
- Reproducibility: yes. at source level. Current main can select a pinned setup-only channel entry and skip th ... module live output showing delivery after the fallback; I did not run local tests in this read-only review.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(outbound): resolve send-capable channel registry
Validation:
- ClawSweeper review passed for head 67c20aa72b.
- Required merge gates passed before the squash merge.
Prepared head SHA: 67c20aa72b
Review: https://github.com/openclaw/openclaw/pull/83733#issuecomment-4481084888
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Summary:
- The PR adds a 15-second default timeout for legacy `before_agent_start` modifying hooks, regression tests for hung handlers, and a changelog fix entry.
- Reproducibility: yes. Registering a `before_agent_start` handler that returns a never-settling promise is en ... ts the hook and the runner awaits directly; the linked source PR also supplies before/after terminal proof.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(plugins): default 15s timeout for before_agent_start hook (#48534)
Validation:
- ClawSweeper review passed for head 8d2c5b8808.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8d2c5b8808
Review: https://github.com/openclaw/openclaw/pull/83147#issuecomment-4471169756
Co-authored-by: Rahul <rahulnilvan43@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>