mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 15:00:41 +00:00
refactor: simplify plugin dependency handling
Simplify plugin installation and runtime loading around package-manager-owned dependencies, with Jiti reserved for local/TS fallback paths. Also scans npm plugin install roots so hoisted transitive dependencies are covered by dependency denylist and node_modules symlink checks.
This commit is contained in:
committed by
GitHub
parent
2e8e9cd6ca
commit
ed8f50f240
@@ -14,9 +14,6 @@
|
||||
"openclaw": {
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
],
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ describe("prepareAcpxCodexAuthConfig", () => {
|
||||
});
|
||||
|
||||
const wrapper = await fs.readFile(generated.wrapperPath, "utf8");
|
||||
expect(wrapper).toContain('"@agentclientprotocol/claude-agent-acp@0.31.1"');
|
||||
expect(wrapper).toContain('"@agentclientprotocol/claude-agent-acp@0.31.4"');
|
||||
expect(wrapper).toContain('"--", "claude-agent-acp"');
|
||||
expect(wrapper).not.toContain("@agentclientprotocol/claude-agent-acp@^0.31.0");
|
||||
expect(wrapper).not.toContain("@agentclientprotocol/claude-agent-acp@0.31.0");
|
||||
@@ -379,7 +379,7 @@ describe("prepareAcpxCodexAuthConfig", () => {
|
||||
rawConfig: {
|
||||
agents: {
|
||||
claude: {
|
||||
command: "npx -y @agentclientprotocol/claude-agent-acp@0.31.1 --permission-mode bypass",
|
||||
command: "npx -y @agentclientprotocol/claude-agent-acp@0.31.4 --permission-mode bypass",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -425,7 +425,7 @@ describe("prepareAcpxCodexAuthConfig", () => {
|
||||
const root = await makeTempDir();
|
||||
const stateDir = path.join(root, "state");
|
||||
const command =
|
||||
"node ./custom-claude-wrapper.mjs @agentclientprotocol/claude-agent-acp@0.31.1 --flag";
|
||||
"node ./custom-claude-wrapper.mjs @agentclientprotocol/claude-agent-acp@0.31.4 --flag";
|
||||
const pluginConfig = resolveAcpxPluginConfig({
|
||||
rawConfig: {
|
||||
agents: {
|
||||
|
||||
@@ -7,7 +7,7 @@ const CODEX_ACP_PACKAGE = "@zed-industries/codex-acp";
|
||||
const CODEX_ACP_PACKAGE_RANGE = "^0.12.0";
|
||||
const CODEX_ACP_BIN = "codex-acp";
|
||||
const CLAUDE_ACP_PACKAGE = "@agentclientprotocol/claude-agent-acp";
|
||||
const CLAUDE_ACP_PACKAGE_VERSION = "0.31.1";
|
||||
const CLAUDE_ACP_PACKAGE_VERSION = "0.31.4";
|
||||
const CLAUDE_ACP_BIN = "claude-agent-acp";
|
||||
const RUN_CONFIGURED_COMMAND_SENTINEL = "--openclaw-run-configured";
|
||||
const requireFromHere = createRequire(import.meta.url);
|
||||
|
||||
@@ -4,15 +4,10 @@ import { describe, expect, it } from "vitest";
|
||||
type AcpxPackageManifest = {
|
||||
dependencies?: Record<string, string>;
|
||||
devDependencies?: Record<string, string>;
|
||||
openclaw?: {
|
||||
bundle?: {
|
||||
stageRuntimeDependencies?: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
describe("acpx package manifest", () => {
|
||||
it("opts into staging bundled runtime dependencies", () => {
|
||||
it("keeps runtime dependencies in the package manifest", () => {
|
||||
const packageJson = JSON.parse(
|
||||
fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
||||
) as AcpxPackageManifest;
|
||||
@@ -21,6 +16,5 @@ describe("acpx package manifest", () => {
|
||||
expect(packageJson.dependencies?.["@zed-industries/codex-acp"]).toBe("0.12.0");
|
||||
expect(packageJson.dependencies?.["@agentclientprotocol/claude-agent-acp"]).toBe("0.31.4");
|
||||
expect(packageJson.devDependencies?.["@agentclientprotocol/claude-agent-acp"]).toBeUndefined();
|
||||
expect(packageJson.openclaw?.bundle?.stageRuntimeDependencies).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
"openclaw": {
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
],
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ export async function requirePwAi(
|
||||
501,
|
||||
[
|
||||
`Playwright is not available in this gateway build; '${feature}' is unsupported.`,
|
||||
"Repair the bundled browser plugin runtime dependencies so playwright-core is installed, then restart the gateway. In Docker, also install Chromium with the bundled playwright-core CLI.",
|
||||
"Reinstall or update OpenClaw so the core browser runtime dependency is present, then restart the gateway. In Docker, also install Chromium with the bundled playwright-core CLI.",
|
||||
"Docs: /tools/browser#playwright-requirement",
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
"openclaw": {
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
],
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ async function findManagedCodexAppServerCommandPath(params: {
|
||||
throw new Error(
|
||||
[
|
||||
`Managed Codex app-server binary was not found for ${MANAGED_CODEX_APP_SERVER_PACKAGE}.`,
|
||||
"Run OpenClaw with bundled plugin runtime dependencies enabled, or run pnpm install in a source checkout.",
|
||||
"Reinstall or update OpenClaw, or run pnpm install in a source checkout.",
|
||||
"Set plugins.entries.codex.config.appServer.command or OPENCLAW_CODEX_APP_SERVER_BIN to use a custom Codex binary.",
|
||||
].join(" "),
|
||||
);
|
||||
|
||||
@@ -4,15 +4,10 @@ import { MANAGED_CODEX_APP_SERVER_PACKAGE_VERSION } from "./app-server/version.j
|
||||
|
||||
type CodexPackageManifest = {
|
||||
dependencies?: Record<string, string>;
|
||||
openclaw?: {
|
||||
bundle?: {
|
||||
stageRuntimeDependencies?: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
describe("codex package manifest", () => {
|
||||
it("opts into staging bundled runtime dependencies", () => {
|
||||
it("keeps runtime dependencies in the package manifest", () => {
|
||||
const packageJson = JSON.parse(
|
||||
fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
||||
) as CodexPackageManifest;
|
||||
@@ -21,6 +16,5 @@ describe("codex package manifest", () => {
|
||||
expect(packageJson.dependencies?.["@openai/codex"]).toBe(
|
||||
MANAGED_CODEX_APP_SERVER_PACKAGE_VERSION,
|
||||
);
|
||||
expect(packageJson.openclaw?.bundle?.stageRuntimeDependencies).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "diffs",
|
||||
"activation": {
|
||||
"onStartup": true
|
||||
"onStartup": false
|
||||
},
|
||||
"name": "Diffs",
|
||||
"description": "Read-only diff viewer and file renderer for agents.",
|
||||
|
||||
@@ -17,11 +17,27 @@
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
],
|
||||
"install": {
|
||||
"npmSpec": "@openclaw/diffs",
|
||||
"localPath": "extensions/diffs",
|
||||
"defaultChoice": "npm",
|
||||
"minHostVersion": ">=2026.4.30"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.4.30"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.4.30"
|
||||
},
|
||||
"bundle": {
|
||||
"includeInCore": false
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
"publishToNpm": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,14 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
type DiffsPackageManifest = {
|
||||
dependencies?: Record<string, string>;
|
||||
openclaw?: {
|
||||
bundle?: {
|
||||
stageRuntimeDependencies?: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
describe("diffs package manifest", () => {
|
||||
it("opts into staging bundled runtime dependencies", () => {
|
||||
it("keeps runtime dependencies in the package manifest", () => {
|
||||
const packageJson = JSON.parse(
|
||||
fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
||||
) as DiffsPackageManifest;
|
||||
|
||||
expect(packageJson.dependencies?.["@pierre/diffs"]).toBeDefined();
|
||||
expect(packageJson.openclaw?.bundle?.stageRuntimeDependencies).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -59,9 +59,6 @@
|
||||
"build": {
|
||||
"openclawVersion": "2026.4.25"
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
"publishToNpm": true
|
||||
|
||||
@@ -48,9 +48,6 @@
|
||||
"build": {
|
||||
"openclawVersion": "2026.4.25"
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
"publishToNpm": true
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
"openclaw": {
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
],
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
}
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
],
|
||||
|
||||
@@ -80,9 +80,6 @@
|
||||
"defaultChoice": "npm",
|
||||
"minHostVersion": ">=2026.4.10",
|
||||
"allowInvalidConfigRecovery": true
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,14 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
type MatrixPackageManifest = {
|
||||
dependencies?: Record<string, string>;
|
||||
openclaw?: {
|
||||
bundle?: {
|
||||
stageRuntimeDependencies?: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
describe("matrix package manifest", () => {
|
||||
it("opts into staging bundled runtime dependencies", () => {
|
||||
it("keeps runtime dependencies in the package manifest", () => {
|
||||
const packageJson = JSON.parse(
|
||||
fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
||||
) as MatrixPackageManifest;
|
||||
|
||||
expect(packageJson.dependencies?.["fake-indexeddb"]).toBeDefined();
|
||||
expect(packageJson.openclaw?.bundle?.stageRuntimeDependencies).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,9 +10,5 @@
|
||||
"devDependencies": {
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
}
|
||||
}
|
||||
"openclaw": {}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
"contracts": {
|
||||
"memoryEmbeddingProviders": ["local"]
|
||||
},
|
||||
"runtimeDependencies": {
|
||||
"localMemoryEmbedding": ["node-llama-cpp@3.18.1"]
|
||||
},
|
||||
"commandAliases": [
|
||||
{
|
||||
"name": "dreaming",
|
||||
|
||||
@@ -59,9 +59,6 @@
|
||||
"build": {
|
||||
"openclawVersion": "2026.4.25"
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
"publishToNpm": true
|
||||
|
||||
@@ -55,9 +55,6 @@
|
||||
"build": {
|
||||
"openclawVersion": "2026.4.25"
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
"publishToNpm": true
|
||||
|
||||
@@ -65,7 +65,9 @@ function raiseMinimalReasoningForOpenAINativeWebSearch(payload: Record<string, u
|
||||
reasoning.effort = "low";
|
||||
}
|
||||
|
||||
function patchOpenAINativeWebSearchPayload(payload: unknown): OpenAINativeWebSearchPatchResult {
|
||||
export function patchOpenAINativeWebSearchPayload(
|
||||
payload: unknown,
|
||||
): OpenAINativeWebSearchPatchResult {
|
||||
if (!isRecord(payload)) {
|
||||
return "payload_not_object";
|
||||
}
|
||||
|
||||
@@ -21,11 +21,6 @@ const packageJson = JSON.parse(
|
||||
readFileSync(new URL("./package.json", import.meta.url), "utf8"),
|
||||
) as {
|
||||
dependencies?: Record<string, string>;
|
||||
openclaw?: {
|
||||
bundle?: {
|
||||
stageRuntimeDependencies?: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
function manifestComparableWizardFields(choice: {
|
||||
@@ -64,10 +59,9 @@ function providerWizardByKey() {
|
||||
}
|
||||
|
||||
describe("OpenAI plugin manifest", () => {
|
||||
it("opts into staging bundled runtime dependencies", () => {
|
||||
it("keeps runtime dependencies in the package manifest", () => {
|
||||
expect(packageJson.dependencies?.["@mariozechner/pi-ai"]).toBe("0.71.1");
|
||||
expect(packageJson.dependencies?.ws).toBe("^8.20.0");
|
||||
expect(packageJson.openclaw?.bundle?.stageRuntimeDependencies).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps removed Codex CLI import auth choice as a deprecated browser-login alias", () => {
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
|
||||
@@ -934,8 +934,8 @@ describe("qa bundled plugin dir", () => {
|
||||
).resolves.toBeTruthy();
|
||||
});
|
||||
|
||||
it("skips transient runtime dependency artifacts while staging built bundled plugins", async () => {
|
||||
const repoRoot = await mkdtemp(path.join(os.tmpdir(), "qa-bundled-runtime-deps-"));
|
||||
it("skips legacy dependency debris while staging built bundled plugins", async () => {
|
||||
const repoRoot = await mkdtemp(path.join(os.tmpdir(), "qa-bundled-legacy-deps-"));
|
||||
cleanups.push(async () => {
|
||||
await rm(repoRoot, { recursive: true, force: true });
|
||||
});
|
||||
@@ -961,7 +961,7 @@ describe("qa bundled plugin dir", () => {
|
||||
"export {};\n",
|
||||
"utf8",
|
||||
);
|
||||
const tempRoot = await mkdtemp(path.join(os.tmpdir(), "qa-bundled-runtime-deps-target-"));
|
||||
const tempRoot = await mkdtemp(path.join(os.tmpdir(), "qa-bundled-legacy-deps-target-"));
|
||||
cleanups.push(async () => {
|
||||
await rm(tempRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
"openclawVersion": "2026.4.27"
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
"includeInCore": false
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -36,9 +36,6 @@
|
||||
"specifier": "./configured-state",
|
||||
"exportName": "hasSlackConfiguredState"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +46,6 @@
|
||||
"specifier": "./configured-state",
|
||||
"exportName": "hasTelegramConfiguredState"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,6 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
type TokenjuicePackageManifest = {
|
||||
dependencies?: Record<string, string>;
|
||||
openclaw?: {
|
||||
bundle?: {
|
||||
stageRuntimeDependencies?: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type TokenjuicePluginManifest = {
|
||||
@@ -17,13 +12,12 @@ type TokenjuicePluginManifest = {
|
||||
};
|
||||
|
||||
describe("tokenjuice package manifest", () => {
|
||||
it("opts into staging bundled runtime dependencies", () => {
|
||||
it("keeps runtime dependencies in the package manifest", () => {
|
||||
const packageJson = JSON.parse(
|
||||
fs.readFileSync(new URL("./package.json", import.meta.url), "utf8"),
|
||||
) as TokenjuicePackageManifest;
|
||||
|
||||
expect(packageJson.dependencies?.tokenjuice).toBe("0.7.0");
|
||||
expect(packageJson.openclaw?.bundle?.stageRuntimeDependencies).toBe(true);
|
||||
});
|
||||
|
||||
it("declares runtime-neutral tool result middleware ownership in the manifest contract", () => {
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
"openclaw": {
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
],
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
|
||||
@@ -59,9 +59,6 @@
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.4.25"
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.4.25"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user