mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:50:43 +00:00
refactor: accept supplied plugin manifest registry
This commit is contained in:
@@ -60,6 +60,7 @@ import {
|
||||
useNoBundledPlugins,
|
||||
writePlugin,
|
||||
} from "./loader.test-fixtures.js";
|
||||
import { loadPluginManifestRegistry } from "./manifest-registry.js";
|
||||
import {
|
||||
listMemoryEmbeddingProviders,
|
||||
registerMemoryEmbeddingProvider,
|
||||
@@ -897,6 +898,31 @@ afterAll(() => {
|
||||
});
|
||||
|
||||
describe("loadOpenClawPlugins", () => {
|
||||
it("can load scoped plugins from a supplied manifest registry without rereading manifests", () => {
|
||||
useNoBundledPlugins();
|
||||
const plugin = writePlugin({
|
||||
id: "supplied-manifest",
|
||||
body: `module.exports = { id: "supplied-manifest", register() {} };`,
|
||||
});
|
||||
const config = {
|
||||
plugins: {
|
||||
load: { paths: [plugin.file] },
|
||||
allow: [plugin.id],
|
||||
},
|
||||
};
|
||||
const manifestRegistry = loadPluginManifestRegistry({ config, cache: false });
|
||||
fs.rmSync(path.join(plugin.dir, "openclaw.plugin.json"));
|
||||
|
||||
const registry = loadOpenClawPlugins({
|
||||
cache: false,
|
||||
config,
|
||||
manifestRegistry,
|
||||
onlyPluginIds: [plugin.id],
|
||||
});
|
||||
|
||||
expect(registry.plugins.find((entry) => entry.id === plugin.id)?.status).toBe("loaded");
|
||||
});
|
||||
|
||||
it("refreshes bundled plugin-sdk aliases without deleting the shared alias directory", () => {
|
||||
const distRoot = makeTempDir();
|
||||
const pluginSdkDir = path.join(distRoot, "plugin-sdk");
|
||||
|
||||
@@ -68,7 +68,7 @@ import {
|
||||
type NormalizedPluginsConfig,
|
||||
type PluginActivationState,
|
||||
} from "./config-state.js";
|
||||
import { discoverOpenClawPlugins } from "./discovery.js";
|
||||
import { discoverOpenClawPlugins, type PluginCandidate } from "./discovery.js";
|
||||
import { getGlobalHookRunner, initializeGlobalHookRunner } from "./hook-runner-global.js";
|
||||
import { toSafeImportPath } from "./import-specifier.js";
|
||||
import { loadInstalledPluginIndexInstallRecordsSync } from "./installed-plugin-index-records.js";
|
||||
@@ -79,7 +79,11 @@ import {
|
||||
} from "./interactive-registry.js";
|
||||
import { getCachedPluginJitiLoader, type PluginJitiLoaderCache } from "./jiti-loader-cache.js";
|
||||
import { PluginLoaderCacheState } from "./loader-cache-state.js";
|
||||
import { loadPluginManifestRegistry, type PluginManifestRecord } from "./manifest-registry.js";
|
||||
import {
|
||||
loadPluginManifestRegistry,
|
||||
type PluginManifestRecord,
|
||||
type PluginManifestRegistry,
|
||||
} from "./manifest-registry.js";
|
||||
import type { PluginBundleFormat, PluginDiagnostic, PluginFormat } from "./manifest-types.js";
|
||||
import type { PluginManifestContracts } from "./manifest.js";
|
||||
import {
|
||||
@@ -173,6 +177,7 @@ export type PluginLoadOptions = {
|
||||
installBundledRuntimeDeps?: boolean;
|
||||
throwOnLoadError?: boolean;
|
||||
bundledRuntimeDepsInstaller?: (params: BundledRuntimeDepsInstallParams) => void;
|
||||
manifestRegistry?: PluginManifestRegistry;
|
||||
};
|
||||
|
||||
const CLI_METADATA_ENTRY_BASENAMES = [
|
||||
@@ -253,6 +258,20 @@ const LAZY_RUNTIME_REFLECTION_KEYS = [
|
||||
"modelAuth",
|
||||
] as const satisfies readonly (keyof PluginRuntime)[];
|
||||
|
||||
function createPluginCandidatesFromManifestRegistry(
|
||||
manifestRegistry: PluginManifestRegistry,
|
||||
): PluginCandidate[] {
|
||||
return manifestRegistry.plugins.map((record) => ({
|
||||
idHint: record.id,
|
||||
rootDir: record.rootDir,
|
||||
source: record.source,
|
||||
origin: record.origin,
|
||||
...(record.workspaceDir !== undefined ? { workspaceDir: record.workspaceDir } : {}),
|
||||
...(record.format !== undefined ? { format: record.format } : {}),
|
||||
...(record.bundleFormat !== undefined ? { bundleFormat: record.bundleFormat } : {}),
|
||||
}));
|
||||
}
|
||||
|
||||
export function clearPluginLoaderCache(): void {
|
||||
pluginLoaderCacheState.clear();
|
||||
clearBundledRuntimeDependencyNodePaths();
|
||||
@@ -2311,21 +2330,29 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
|
||||
activateGlobalSideEffects: shouldActivate,
|
||||
});
|
||||
|
||||
const discovery = discoverOpenClawPlugins({
|
||||
workspaceDir: options.workspaceDir,
|
||||
extraPaths: normalized.loadPaths,
|
||||
cache: options.cache,
|
||||
env,
|
||||
});
|
||||
const manifestRegistry = loadPluginManifestRegistry({
|
||||
config: cfg,
|
||||
workspaceDir: options.workspaceDir,
|
||||
cache: options.cache,
|
||||
env,
|
||||
candidates: discovery.candidates,
|
||||
diagnostics: discovery.diagnostics,
|
||||
installRecords: Object.keys(installRecords).length > 0 ? installRecords : undefined,
|
||||
});
|
||||
const suppliedManifestRegistry = options.manifestRegistry;
|
||||
const discovery = suppliedManifestRegistry
|
||||
? {
|
||||
candidates: createPluginCandidatesFromManifestRegistry(suppliedManifestRegistry),
|
||||
diagnostics: [] as PluginDiagnostic[],
|
||||
}
|
||||
: discoverOpenClawPlugins({
|
||||
workspaceDir: options.workspaceDir,
|
||||
extraPaths: normalized.loadPaths,
|
||||
cache: options.cache,
|
||||
env,
|
||||
});
|
||||
const manifestRegistry =
|
||||
suppliedManifestRegistry ??
|
||||
loadPluginManifestRegistry({
|
||||
config: cfg,
|
||||
workspaceDir: options.workspaceDir,
|
||||
cache: options.cache,
|
||||
env,
|
||||
candidates: discovery.candidates,
|
||||
diagnostics: discovery.diagnostics,
|
||||
installRecords: Object.keys(installRecords).length > 0 ? installRecords : undefined,
|
||||
});
|
||||
pushDiagnostics(registry.diagnostics, manifestRegistry.diagnostics);
|
||||
warnWhenAllowlistIsOpen({
|
||||
emitWarning: shouldActivate,
|
||||
|
||||
Reference in New Issue
Block a user