refactor(plugins): decouple bundled plugin runtime loading

This commit is contained in:
Peter Steinberger
2026-03-29 09:08:06 +01:00
parent 1738d540f4
commit 8e0ab35b0e
582 changed files with 8057 additions and 22869 deletions

View File

@@ -7,6 +7,7 @@ import { clearRuntimeAuthProfileStoreSnapshots } from "../agents/auth-profiles.j
import { resetCliCredentialCachesForTest } from "../agents/cli-credentials.js";
import type { OpenClawConfig } from "../config/config.js";
import { resetProviderRuntimeHookCacheForTest } from "../plugins/provider-runtime.js";
import { resolveRelativeBundledPluginPublicModuleId } from "../test-utils/bundled-plugin-public-surface.js";
// Avoid exporting vitest mock types (TS2742 under pnpm + d.ts emit).
// oxlint-disable-next-line typescript/no-explicit-any
@@ -158,12 +159,17 @@ const webSessionMocks = getSharedMocks("openclaw.trigger-handling.web-session-mo
readWebSelfId: vi.fn().mockReturnValue({ e164: "+1999" }),
}));
const whatsappRuntimeApiModuleId = resolveRelativeBundledPluginPublicModuleId({
fromModuleUrl: import.meta.url,
pluginId: "whatsapp",
artifactBasename: "runtime-api.js",
});
export function getWebSessionMocks(): AnyMocks {
return webSessionMocks;
}
const installWebSessionMock = () =>
vi.doMock("../../extensions/whatsapp/runtime-api.js", () => webSessionMocks);
const installWebSessionMock = () => vi.doMock(whatsappRuntimeApiModuleId, () => webSessionMocks);
installWebSessionMock();

View File

@@ -34,8 +34,7 @@ describe("ACP install hints", () => {
const cfg = withAcpConfig({ backend: "acpx" });
const hint = resolveAcpInstallCommandHint(cfg);
expect(hint).toContain("openclaw plugins install ");
expect(hint).toContain(path.join("extensions", "acpx"));
expect(hint).toBe(`openclaw plugins install ${path.join(tempRoot, "extensions", "acpx")}`);
});
it("falls back to scoped install hint for acpx when local extension is absent", () => {

View File

@@ -1,6 +1,8 @@
import { existsSync } from "node:fs";
import path from "node:path";
import type { OpenClawConfig } from "../../../config/config.js";
import { resolveBundledPluginWorkspaceSourcePath } from "../../../plugins/bundled-plugin-metadata.js";
import { resolveBundledPluginInstallCommandHint } from "../../../plugins/bundled-sources.js";
export function resolveConfiguredAcpBackendId(cfg: OpenClawConfig): string {
return cfg.acp?.backend?.trim() || "acpx";
@@ -11,11 +13,30 @@ export function resolveAcpInstallCommandHint(cfg: OpenClawConfig): string {
if (configured) {
return configured;
}
const workspaceDir = process.cwd();
const backendId = resolveConfiguredAcpBackendId(cfg).toLowerCase();
if (backendId === "acpx") {
const localPath = path.resolve(process.cwd(), "extensions/acpx");
if (existsSync(localPath)) {
return `openclaw plugins install ${localPath}`;
const workspaceLocalPath = resolveBundledPluginWorkspaceSourcePath({
rootDir: workspaceDir,
pluginId: backendId,
});
if (workspaceLocalPath && existsSync(workspaceLocalPath)) {
return `openclaw plugins install ${workspaceLocalPath}`;
}
const bundledInstallHint = resolveBundledPluginInstallCommandHint({
pluginId: backendId,
workspaceDir,
});
if (bundledInstallHint) {
const localPath = bundledInstallHint.replace(/^openclaw plugins install /u, "");
const resolvedLocalPath = path.resolve(localPath);
const relativeToWorkspace = path.relative(workspaceDir, resolvedLocalPath);
const belongsToWorkspace =
relativeToWorkspace.length === 0 ||
(!relativeToWorkspace.startsWith("..") && !path.isAbsolute(relativeToWorkspace));
if (belongsToWorkspace && existsSync(resolvedLocalPath)) {
return bundledInstallHint;
}
}
return "openclaw plugins install acpx";
}

View File

@@ -1,6 +1,9 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { installedPluginRoot } from "../../../test/helpers/bundled-plugin-paths.js";
import { createPluginRecord, createPluginStatusReport } from "../../plugins/status.test-helpers.js";
const WORKSPACE_PLUGIN_ROOT = installedPluginRoot("/tmp/workspace/.openclaw", "superpowers");
const {
readConfigFileSnapshotMock,
validateConfigObjectWithPluginsMock,
@@ -70,7 +73,7 @@ describe("handleCommands /plugins toggle", () => {
createPluginRecord({
id: "superpowers",
format: "bundle",
source: "/tmp/workspace/.openclaw/extensions/superpowers",
source: WORKSPACE_PLUGIN_ROOT,
enabled: false,
status: "disabled",
}),
@@ -110,7 +113,7 @@ describe("handleCommands /plugins toggle", () => {
createPluginRecord({
id: "superpowers",
format: "bundle",
source: "/tmp/workspace/.openclaw/extensions/superpowers",
source: WORKSPACE_PLUGIN_ROOT,
enabled: true,
}),
],