mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 11:12:54 +00:00
* 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
141 lines
4.5 KiB
TypeScript
141 lines
4.5 KiB
TypeScript
import type { OpenClawConfig } from "../config/types.js";
|
|
import type { PluginInstallRecord } from "../config/types.plugins.js";
|
|
import type { PluginCompatCode } from "./compat/registry.js";
|
|
import type { PluginCandidate, PluginDiscoveryResult } from "./discovery.js";
|
|
import type { PluginInstallSourceInfo } from "./install-source-info.js";
|
|
import type { InstalledPluginFileSignature } from "./installed-plugin-index-hash.js";
|
|
import type { PluginManifestRecord } from "./manifest-registry.js";
|
|
import type { PluginDiagnostic } from "./manifest-types.js";
|
|
import type { PluginPackageChannel } from "./manifest.js";
|
|
|
|
export const INSTALLED_PLUGIN_INDEX_VERSION = 1;
|
|
export const INSTALLED_PLUGIN_INDEX_MIGRATION_VERSION = 1;
|
|
export const INSTALLED_PLUGIN_INDEX_WARNING =
|
|
"DO NOT EDIT. This file is generated by OpenClaw from plugin manifests, install records, and config policy. Use `openclaw plugins registry --refresh`, `openclaw plugins install/update/uninstall`, or `openclaw plugins enable/disable` instead.";
|
|
|
|
export type InstalledPluginIndexRefreshReason =
|
|
| "missing"
|
|
| "stale-manifest"
|
|
| "stale-package"
|
|
| "source-changed"
|
|
| "policy-changed"
|
|
| "migration"
|
|
| "host-contract-changed"
|
|
| "compat-registry-changed"
|
|
| "manual";
|
|
|
|
export type InstalledPluginStartupInfo = {
|
|
sidecar: boolean;
|
|
memory: boolean;
|
|
deferConfiguredChannelFullLoadUntilAfterListen: boolean;
|
|
agentHarnesses: readonly string[];
|
|
};
|
|
|
|
export type InstalledPluginInstallRecordInfo = Pick<
|
|
PluginInstallRecord,
|
|
| "source"
|
|
| "spec"
|
|
| "sourcePath"
|
|
| "installPath"
|
|
| "version"
|
|
| "resolvedName"
|
|
| "resolvedVersion"
|
|
| "resolvedSpec"
|
|
| "integrity"
|
|
| "shasum"
|
|
| "resolvedAt"
|
|
| "installedAt"
|
|
| "clawhubUrl"
|
|
| "clawhubPackage"
|
|
| "clawhubFamily"
|
|
| "clawhubChannel"
|
|
| "artifactKind"
|
|
| "artifactFormat"
|
|
| "npmIntegrity"
|
|
| "npmShasum"
|
|
| "npmTarballName"
|
|
| "clawpackSha256"
|
|
| "clawpackSpecVersion"
|
|
| "clawpackManifestSha256"
|
|
| "clawpackSize"
|
|
| "gitUrl"
|
|
| "gitRef"
|
|
| "gitCommit"
|
|
| "marketplaceName"
|
|
| "marketplaceSource"
|
|
| "marketplacePlugin"
|
|
>;
|
|
|
|
export type InstalledPluginPackageChannelInfo = PluginPackageChannel;
|
|
|
|
export type InstalledPluginIndexRecord = {
|
|
pluginId: string;
|
|
packageName?: string;
|
|
packageVersion?: string;
|
|
/**
|
|
* Legacy embedded install record accepted when reading earlier index files.
|
|
* New index writes keep install records in InstalledPluginIndex.installRecords.
|
|
*/
|
|
installRecord?: InstalledPluginInstallRecordInfo;
|
|
/** Hash of the top-level installRecords entry; used to detect source-changed invalidation. */
|
|
installRecordHash?: string;
|
|
/**
|
|
* Package-authored openclaw.install metadata. This describes catalog/package
|
|
* install intent and must not be treated as the durable install record.
|
|
*/
|
|
packageInstall?: PluginInstallSourceInfo;
|
|
packageChannel?: InstalledPluginPackageChannelInfo;
|
|
manifestPath: string;
|
|
manifestHash: string;
|
|
manifestFile?: InstalledPluginFileSignature;
|
|
format?: PluginManifestRecord["format"];
|
|
bundleFormat?: PluginManifestRecord["bundleFormat"];
|
|
source?: string;
|
|
setupSource?: string;
|
|
packageJson?: {
|
|
path: string;
|
|
hash: string;
|
|
fileSignature?: InstalledPluginFileSignature;
|
|
};
|
|
rootDir: string;
|
|
origin: PluginManifestRecord["origin"];
|
|
enabled: boolean;
|
|
enabledByDefault?: boolean;
|
|
enabledByDefaultOnPlatforms?: readonly string[];
|
|
syntheticAuthRefs?: readonly string[];
|
|
startup: InstalledPluginStartupInfo;
|
|
compat: readonly PluginCompatCode[];
|
|
};
|
|
|
|
export type InstalledPluginIndex = {
|
|
version: typeof INSTALLED_PLUGIN_INDEX_VERSION;
|
|
warning?: string;
|
|
hostContractVersion: string;
|
|
compatRegistryVersion: string;
|
|
migrationVersion: typeof INSTALLED_PLUGIN_INDEX_MIGRATION_VERSION;
|
|
policyHash: string;
|
|
generatedAtMs: number;
|
|
refreshReason?: InstalledPluginIndexRefreshReason;
|
|
installRecords: Readonly<Record<string, InstalledPluginInstallRecordInfo>>;
|
|
plugins: readonly InstalledPluginIndexRecord[];
|
|
diagnostics: readonly PluginDiagnostic[];
|
|
};
|
|
|
|
export type LoadInstalledPluginIndexParams = {
|
|
config?: OpenClawConfig;
|
|
workspaceDir?: string;
|
|
env?: NodeJS.ProcessEnv;
|
|
stateDir?: string;
|
|
pluginIndexFilePath?: string;
|
|
installRecords?: Record<string, PluginInstallRecord>;
|
|
candidates?: PluginCandidate[];
|
|
diagnostics?: PluginDiagnostic[];
|
|
discovery?: PluginDiscoveryResult;
|
|
now?: () => Date;
|
|
};
|
|
|
|
export type RefreshInstalledPluginIndexParams = LoadInstalledPluginIndexParams & {
|
|
reason: InstalledPluginIndexRefreshReason;
|
|
policyPluginIds?: readonly string[];
|
|
};
|