






















@@ -18,12 +18,21 @@ function writeJson(filePath: string, value: unknown) {
1818}
19192020function writeBundledChannelPlugin(root: string, id: string, dependencies: Record<string, string>) {
21+writeBundledChannelOwnerPlugin(root, id, [id], dependencies);
22+}
23+24+function writeBundledChannelOwnerPlugin(
25+root: string,
26+id: string,
27+channels: string[],
28+dependencies: Record<string, string>,
29+) {
2130writeJson(path.join(root, "dist", "extensions", id, "package.json"), {
2231 dependencies,
2332});
2433writeJson(path.join(root, "dist", "extensions", id, "openclaw.plugin.json"), {
2534 id,
26-channels: [id],
35+ channels,
2736configSchema: { type: "object" },
2837});
2938}
@@ -259,16 +268,16 @@ describe("doctor bundled plugin runtime deps", () => {
259268expect(result.conflicts).toEqual([]);
260269});
261270262-it("reports default-enabled bundled plugin deps", () => {
271+it("reports default-enabled gateway startup sidecar deps", () => {
263272const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-doctor-bundled-"));
264273writeJson(path.join(root, "package.json"), { name: "openclaw" });
265-writeJson(path.join(root, "dist", "extensions", "openai", "package.json"), {
274+writeJson(path.join(root, "dist", "extensions", "browser", "package.json"), {
266275dependencies: {
267-"openai-only": "1.0.0",
276+"browser-only": "1.0.0",
268277},
269278});
270-writeJson(path.join(root, "dist", "extensions", "openai", "openclaw.plugin.json"), {
271-id: "openai",
279+writeJson(path.join(root, "dist", "extensions", "browser", "openclaw.plugin.json"), {
280+id: "browser",
272281enabledByDefault: true,
273282configSchema: { type: "object" },
274283});
@@ -281,7 +290,39 @@ describe("doctor bundled plugin runtime deps", () => {
281290});
282291283292expect(result.missing.map((dep) => `${dep.name}@${dep.version}`)).toEqual([
284-"openai-only@1.0.0",
293+"browser-only@1.0.0",
294+]);
295+expect(result.conflicts).toEqual([]);
296+});
297+298+it("reports explicitly enabled provider deps", () => {
299+const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-doctor-bundled-"));
300+writeJson(path.join(root, "package.json"), { name: "openclaw" });
301+writeJson(path.join(root, "dist", "extensions", "bedrock", "package.json"), {
302+dependencies: {
303+"bedrock-only": "1.0.0",
304+},
305+});
306+writeJson(path.join(root, "dist", "extensions", "bedrock", "openclaw.plugin.json"), {
307+id: "bedrock",
308+enabledByDefault: true,
309+providers: ["bedrock"],
310+configSchema: { type: "object" },
311+});
312+313+const result = scanBundledPluginRuntimeDeps({
314+packageRoot: root,
315+config: {
316+plugins: {
317+enabled: true,
318+allow: ["bedrock"],
319+entries: { bedrock: { enabled: true } },
320+},
321+},
322+});
323+324+expect(result.missing.map((dep) => `${dep.name}@${dep.version}`)).toEqual([
325+"bedrock-only@1.0.0",
285326]);
286327expect(result.conflicts).toEqual([]);
287328});
@@ -352,6 +393,78 @@ describe("doctor bundled plugin runtime deps", () => {
352393expect(result.conflicts).toEqual([]);
353394});
354395396+it("does not repair inactive default-enabled provider deps", async () => {
397+const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-doctor-bundled-"));
398+writeJson(path.join(root, "package.json"), { name: "openclaw" });
399+writeJson(path.join(root, "dist", "extensions", "bedrock", "package.json"), {
400+dependencies: {
401+"bedrock-only": "1.0.0",
402+},
403+});
404+writeJson(path.join(root, "dist", "extensions", "bedrock", "openclaw.plugin.json"), {
405+id: "bedrock",
406+enabledByDefault: true,
407+providers: ["bedrock"],
408+configSchema: { type: "object" },
409+});
410+const installed = createInstalledRuntimeDeps();
411+412+await maybeRepairBundledPluginRuntimeDeps({
413+runtime: { error: () => {} } as never,
414+prompter: createNonInteractivePrompter(),
415+packageRoot: root,
416+config: {
417+plugins: { enabled: true },
418+},
419+installDeps: (params) => {
420+installed.push(params);
421+},
422+});
423+424+expect(installed).toEqual([]);
425+});
426+427+it("repairs explicitly enabled provider deps", async () => {
428+const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-doctor-bundled-"));
429+writeJson(path.join(root, "package.json"), { name: "openclaw" });
430+writeJson(path.join(root, "dist", "extensions", "bedrock", "package.json"), {
431+dependencies: {
432+"bedrock-only": "1.0.0",
433+},
434+});
435+writeJson(path.join(root, "dist", "extensions", "bedrock", "openclaw.plugin.json"), {
436+id: "bedrock",
437+enabledByDefault: true,
438+providers: ["bedrock"],
439+configSchema: { type: "object" },
440+});
441+const installed = createInstalledRuntimeDeps();
442+443+await maybeRepairBundledPluginRuntimeDeps({
444+runtime: { error: () => {} } as never,
445+prompter: createNonInteractivePrompter(),
446+packageRoot: root,
447+config: {
448+plugins: {
449+enabled: true,
450+allow: ["bedrock"],
451+entries: { bedrock: { enabled: true } },
452+},
453+},
454+installDeps: (params) => {
455+installed.push(params);
456+},
457+});
458+459+expect(installed).toEqual([
460+{
461+installRoot: resolveBundledRuntimeDependencyPackageInstallRoot(root),
462+missingSpecs: ["bedrock-only@1.0.0"],
463+installSpecs: ["bedrock-only@1.0.0"],
464+},
465+]);
466+});
467+355468it("repairs missing deps during non-interactive doctor", async () => {
356469const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-doctor-bundled-"));
357470writeJson(path.join(root, "package.json"), { name: "openclaw" });
@@ -383,6 +496,35 @@ describe("doctor bundled plugin runtime deps", () => {
383496expect(readRetainedRuntimeDepsManifest(installRoot)).toEqual(["grammy@1.37.0"]);
384497});
385498499+it("repairs deps for configured channel owner plugins", async () => {
500+const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-doctor-bundled-"));
501+writeJson(path.join(root, "package.json"), { name: "openclaw" });
502+writeBundledChannelOwnerPlugin(root, "chat-bridge", ["telegram"], { grammy: "1.37.0" });
503+const installed = createInstalledRuntimeDeps();
504+505+await maybeRepairBundledPluginRuntimeDeps({
506+runtime: { error: () => {} } as never,
507+prompter: createNonInteractivePrompter(),
508+packageRoot: root,
509+config: {
510+plugins: { enabled: true },
511+channels: { telegram: { enabled: true } },
512+},
513+installDeps: (params) => {
514+installed.push(params);
515+},
516+});
517+518+const installRoot = resolveBundledRuntimeDependencyPackageInstallRoot(root);
519+expect(installed).toEqual([
520+{
521+ installRoot,
522+missingSpecs: ["grammy@1.37.0"],
523+installSpecs: ["grammy@1.37.0"],
524+},
525+]);
526+});
527+386528it("throws when bundled runtime dependency repair fails", async () => {
387529const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-doctor-bundled-"));
388530const errors: string[] = [];
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。