Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  bundled.shape-guard.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest";
import { importFreshModule } from "../../../test/helpers/import-fresh.ts";
import { loadPluginManifestRegistry } from "../../plugins/manifest-registry.js";

const bundledChannelEntrypointPaths = ["index.ts", "channel-entry.ts", "setup-entry.ts"] as const;

type BundledEntrySource = { built?: string; source?: string };

function restoreBundledPluginsDir(previousBundledPluginsDir: string | undefined) {
  if (previousBundledPluginsDir === undefined) {
    delete process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
  } else {
    process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = previousBundledPluginsDir;
  }
}

function alphaChannelMetadata({ includeSetup = false }: { includeSetup?: boolean } = {}) {
  return {
    dirName: "alpha",
    manifest: {
      id: "alpha",
      channels: ["alpha"],
    },
    source: {
      source: "./index.js",
      built: "./index.js",
    },
    ...(includeSetup
      ? {
          setupSource: {
            source: "./setup-entry.js",
            built: "./setup-entry.js",
          },
        }
      : {}),
  };
}

function resolveAlphaDistExtensionEntry(
  rootDir: string,
  entry: BundledEntrySource,
  pluginDirName?: string,
) {
  return path.join(
    rootDir,
    "dist",
    "extensions",
    pluginDirName ?? "alpha",
    (entry.built ?? entry.source ?? "./index.js").replace(/^\.\//u, ""),
  );
}

function mockAlphaDistExtensionRuntime() {
  vi.doMock("../../plugins/bundled-channel-runtime.js", () => ({
    listBundledChannelPluginMetadata: () => [alphaChannelMetadata({ includeSetup: true })],
    resolveBundledChannelGeneratedPath: resolveAlphaDistExtensionEntry,
  }));
}

function collectBundledChannelEntrypointOffenders(
  bundledPluginRoots: string[],
  isOffender: (source: string, filePath: string) => boolean,
) {
  const offenders: string[] = [];
  for (const extensionDir of bundledPluginRoots) {
    for (const relativePath of bundledChannelEntrypointPaths) {
      const filePath = path.join(extensionDir, relativePath);
      if (!fs.existsSync(filePath)) {
        continue;
      }
      const source = fs.readFileSync(filePath, "utf8");
      const usesEntryHelpers =
        source.includes("defineBundledChannelEntry") ||
        source.includes("defineBundledChannelSetupEntry");
      if (usesEntryHelpers && isOffender(source, filePath)) {
        offenders.push(path.relative(process.cwd(), filePath));
      }
    }
  }
  return offenders;
}

afterEach(() => {
  vi.resetModules();
  vi.doUnmock("../../plugins/bundled-channel-runtime.js");
  vi.doUnmock("../../plugins/bundled-plugin-metadata.js");
  vi.doUnmock("../../plugins/discovery.js");
  vi.doUnmock("../../plugins/manifest-registry.js");
  vi.doUnmock("../../plugins/channel-catalog-registry.js");
  vi.doUnmock("../../infra/boundary-file-read.js");
  vi.doUnmock("jiti");
});

describe("bundled channel entry shape guards", () => {
  const bundledPluginRoots = loadPluginManifestRegistry({ cache: true, config: {} })
    .plugins.filter((plugin) => plugin.origin === "bundled")
    .map((plugin) => plugin.rootDir);

  it("treats missing bundled discovery results as empty", async () => {
    vi.doMock("../../plugins/bundled-channel-runtime.js", async (importOriginal) => {
      const actual =
        await importOriginal<typeof import("../../plugins/bundled-channel-runtime.js")>();
      return {
        ...actual,
        listBundledChannelPluginMetadata: () => [],
      };
    });

    const bundled = await importFreshModule<typeof import("./bundled.js")>(
      import.meta.url,
      "./bundled.js?scope=missing-bundled-discovery",
    );

    expect(bundled.listBundledChannelPlugins()).toEqual([]);
    expect(bundled.listBundledChannelSetupPlugins()).toEqual([]);
  });

  it("loads real bundled channel entry contracts from the source tree", async () => {
    vi.doMock("../../plugins/bundled-channel-runtime.js", async (importOriginal) => {
      const actual =
        await importOriginal<typeof import("../../plugins/bundled-channel-runtime.js")>();
      return {
        ...actual,
        listBundledChannelPluginMetadata: (params: {
          includeChannelConfigs: boolean;
          includeSyntheticChannelConfigs: boolean;
        }) =>
          actual
            .listBundledChannelPluginMetadata(params)
            .filter((metadata) => metadata.manifest.id === "slack"),
      };
    });

    const bundled = await importFreshModule<typeof import("./bundled.js")>(
      import.meta.url,
      "./bundled.js?scope=real-bundled-source-tree",
    );

    expect(bundled.listBundledChannelPluginIds()).toEqual(["slack"]);
    expect(bundled.hasBundledChannelEntryFeature("slack", "accountInspect")).toBe(true);
  });

  it("fills sparse bundled channel plugin metadata from package metadata", async () => {
    const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-metadata-"));
    const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
    const pluginDir = path.join(tempRoot, "dist", "extensions", "alpha");
    fs.mkdirSync(pluginDir, { recursive: true });
    fs.writeFileSync(
      path.join(pluginDir, "index.js"),
      [
        "const plugin = {",
        "  id: 'alpha',",
        "  meta: { id: 'alpha' },",
        "  capabilities: { chatTypes: ['direct'] },",
        "  config: {},",
        "};",
        "export default {",
        "  kind: 'bundled-channel-entry',",
        "  id: 'alpha',",
        "  name: 'Alpha',",
        "  description: 'Alpha',",
        "  register() {},",
        "  loadChannelPlugin() { return plugin; },",
        "};",
        "",
      ].join("\n"),
      "utf8",
    );

    vi.doMock("../../plugins/bundled-channel-runtime.js", () => ({
      listBundledChannelPluginMetadata: () => [
        {
          ...alphaChannelMetadata(),
          packageManifest: {
            channel: {
              id: "alpha",
              label: "Alpha",
              selectionLabel: "Use Alpha",
              docsPath: "/channels/alpha",
              blurb: "Alpha channel metadata.",
            },
          },
        },
      ],
      resolveBundledChannelGeneratedPath: (
        _rootDir: string,
        entry: { built?: string; source?: string },
      ) =>
        path.join(pluginDir, (entry.built ?? entry.source ?? "./index.js").replace(/^\.\//u, "")),
    }));

    try {
      process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = path.join(tempRoot, "dist", "extensions");

      const bundled = await importFreshModule<typeof import("./bundled.js")>(
        import.meta.url,
        "./bundled.js?scope=bundled-package-metadata",
      );

      const plugin = bundled.requireBundledChannelPlugin("alpha");
      expect(plugin.meta).toMatchObject({
        id: "alpha",
        label: "Alpha",
        selectionLabel: "Use Alpha",
        docsPath: "/channels/alpha",
        blurb: "Alpha channel metadata.",
      });
    } finally {
      restoreBundledPluginsDir(previousBundledPluginsDir);
      fs.rmSync(tempRoot, { recursive: true, force: true });
    }
  });

  it("uses the active bundled plugin root override for channel entry loading", async () => {
    const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-override-"));
    const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
    const pluginDir = path.join(tempRoot, "dist", "extensions", "alpha");
    fs.mkdirSync(pluginDir, { recursive: true });
    fs.writeFileSync(
      path.join(pluginDir, "index.js"),
      [
        "globalThis.__bundledOverrideRuntime = undefined;",
        "const plugin = { id: 'alpha', meta: {}, capabilities: {}, config: {} };",
        "export default {",
        "  kind: 'bundled-channel-entry',",
        "  id: 'alpha',",
        "  name: 'Alpha',",
        "  description: 'Alpha',",
        "  register() {},",
        "  loadChannelPlugin() { return plugin; },",
        "  setChannelRuntime(runtime) { globalThis.__bundledOverrideRuntime = runtime.marker; },",
        "};",
        "",
      ].join("\n"),
      "utf8",
    );

    let metadataRootDir: string | undefined;
    let generatedRootDir: string | undefined;

    vi.doMock("../../plugins/bundled-channel-runtime.js", () => ({
      listBundledChannelPluginMetadata: (params?: { rootDir?: string }) => {
        metadataRootDir = params?.rootDir;
        return [alphaChannelMetadata()];
      },
      resolveBundledChannelGeneratedPath: (
        rootDir: string,
        entry: { built?: string; source?: string },
        pluginDirName?: string,
      ) => {
        generatedRootDir = rootDir;
        return path.join(
          rootDir,
          "dist",
          "extensions",
          pluginDirName ?? "alpha",
          (entry.built ?? entry.source ?? "./index.js").replace(/^\.\//u, ""),
        );
      },
    }));

    try {
      process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = path.join(tempRoot, "dist", "extensions");

      const bundled = await importFreshModule<typeof import("./bundled.js")>(
        import.meta.url,
        "./bundled.js?scope=bundled-override-root",
      );

      bundled.setBundledChannelRuntime("alpha", { marker: "ok" } as never);
      const testGlobal = globalThis as typeof globalThis & {
        __bundledOverrideRuntime?: unknown;
      };

      expect(metadataRootDir).toBe(tempRoot);
      expect(generatedRootDir).toBe(tempRoot);
      expect(testGlobal.__bundledOverrideRuntime).toBe("ok");
      expect(bundled.requireBundledChannelPlugin("alpha").id).toBe("alpha");
    } finally {
      restoreBundledPluginsDir(previousBundledPluginsDir);
      fs.rmSync(tempRoot, { recursive: true, force: true });
      delete (globalThis as { __bundledOverrideRuntime?: unknown }).__bundledOverrideRuntime;
    }
  });

  it("treats direct bundled plugin-tree overrides as scan roots", async () => {
    const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-direct-override-"));
    const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
    const pluginsRoot = path.join(tempRoot, "bundled-plugins");
    const pluginDir = path.join(pluginsRoot, "alpha");
    fs.mkdirSync(pluginDir, { recursive: true });
    fs.writeFileSync(
      path.join(pluginDir, "index.js"),
      [
        "globalThis.__bundledOverrideRuntime = undefined;",
        "const plugin = { id: 'alpha', meta: {}, capabilities: {}, config: {} };",
        "export default {",
        "  kind: 'bundled-channel-entry',",
        "  id: 'alpha',",
        "  name: 'Alpha',",
        "  description: 'Alpha',",
        "  register() {},",
        "  loadChannelPlugin() { return plugin; },",
        "  setChannelRuntime(runtime) { globalThis.__bundledOverrideRuntime = runtime.marker; },",
        "};",
        "",
      ].join("\n"),
      "utf8",
    );

    let metadataScanDir: string | undefined;
    let generatedRootDir: string | undefined;
    let generatedScanDir: string | undefined;

    vi.doMock("../../plugins/bundled-channel-runtime.js", () => ({
      listBundledChannelPluginMetadata: (params?: { rootDir?: string; scanDir?: string }) => {
        metadataScanDir = params?.scanDir;
        return [alphaChannelMetadata()];
      },
      resolveBundledChannelGeneratedPath: (
        rootDir: string,
        entry: { built?: string; source?: string },
        pluginDirName?: string,
        scanDir?: string,
      ) => {
        generatedRootDir = rootDir;
        generatedScanDir = scanDir;
        return path.join(
          scanDir ?? path.join(rootDir, "dist", "extensions"),
          pluginDirName ?? "alpha",
          (entry.built ?? entry.source ?? "./index.js").replace(/^\.\//u, ""),
        );
      },
    }));

    try {
      process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = pluginsRoot;

      const bundled = await importFreshModule<typeof import("./bundled.js")>(
        import.meta.url,
        "./bundled.js?scope=bundled-direct-override-root",
      );

      bundled.setBundledChannelRuntime("alpha", { marker: "ok" } as never);
      const testGlobal = globalThis as typeof globalThis & {
        __bundledOverrideRuntime?: unknown;
      };

      expect(metadataScanDir).toBe(pluginsRoot);
      expect(generatedRootDir).toBe(pluginsRoot);
      expect(generatedScanDir).toBe(pluginsRoot);
      expect(testGlobal.__bundledOverrideRuntime).toBe("ok");
      expect(bundled.requireBundledChannelPlugin("alpha").id).toBe("alpha");
    } finally {
      restoreBundledPluginsDir(previousBundledPluginsDir);
      fs.rmSync(tempRoot, { recursive: true, force: true });
      delete (globalThis as { __bundledOverrideRuntime?: unknown }).__bundledOverrideRuntime;
    }
  });

  it("partitions bundled channel lazy caches by active bundled root without re-importing", async () => {
    const rootA = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-root-a-"));
    const rootB = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-root-b-"));
    const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
    const testGlobal = globalThis as typeof globalThis & {
      __bundledRootRuntime?: unknown;
    };

    const writeBundledRoot = (rootDir: string, label: string) => {
      const pluginDir = path.join(rootDir, "dist", "extensions", "alpha");
      fs.mkdirSync(pluginDir, { recursive: true });
      fs.writeFileSync(
        path.join(pluginDir, "index.js"),
        [
          `globalThis.__bundledRootRuntime = globalThis.__bundledRootRuntime ?? [];`,
          "export default {",
          "  kind: 'bundled-channel-entry',",
          "  id: 'alpha',",
          `  name: ${JSON.stringify(`Alpha ${label}`)},`,
          `  description: ${JSON.stringify(`Alpha ${label}`)},`,
          "  register() {},",
          "  loadChannelPlugin() {",
          "    return {",
          "      id: 'alpha',",
          `      meta: { id: 'alpha', label: ${JSON.stringify(`Alpha ${label}`)} },`,
          "      capabilities: {},",
          "      config: {},",
          `      secrets: { secretTargetRegistryEntries: [{ id: ${JSON.stringify(`channels.alpha.${label}.token`)}, targetType: 'channel' }] },`,
          "    };",
          "  },",
          "  loadChannelSecrets() {",
          `    return { secretTargetRegistryEntries: [{ id: ${JSON.stringify(`channels.alpha.${label}.entry-token`)}, targetType: 'channel' }] };`,
          "  },",
          "  setChannelRuntime(runtime) {",
          `    globalThis.__bundledRootRuntime.push(${JSON.stringify(`entry:${label}`)} + ':' + String(runtime.marker));`,
          "  },",
          "};",
          "",
        ].join("\n"),
        "utf8",
      );
      fs.writeFileSync(
        path.join(pluginDir, "setup-entry.js"),
        [
          "export default {",
          "  kind: 'bundled-channel-setup-entry',",
          "  loadSetupPlugin() {",
          "    return {",
          "      id: 'alpha',",
          `      meta: { id: 'alpha', label: ${JSON.stringify(`Setup ${label}`)} },`,
          "      capabilities: {},",
          "      config: {},",
          `      secrets: { secretTargetRegistryEntries: [{ id: ${JSON.stringify(`channels.alpha.${label}.setup-plugin-token`)}, targetType: 'channel' }] },`,
          "    };",
          "  },",
          "  loadSetupSecrets() {",
          `    return { secretTargetRegistryEntries: [{ id: ${JSON.stringify(`channels.alpha.${label}.setup-entry-token`)}, targetType: 'channel' }] };`,
          "  },",
          "};",
          "",
        ].join("\n"),
        "utf8",
      );
    };

    writeBundledRoot(rootA, "A");
    writeBundledRoot(rootB, "B");

    mockAlphaDistExtensionRuntime();

    try {
      const bundled = await importFreshModule<typeof import("./bundled.js")>(
        import.meta.url,
        "./bundled.js?scope=bundled-root-partition",
      );

      process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = path.join(rootA, "dist", "extensions");
      expect(bundled.requireBundledChannelPlugin("alpha").meta.label).toBe("Alpha A");
      expect(bundled.getBundledChannelSetupPlugin("alpha")?.meta.label).toBe("Setup A");
      expect(bundled.getBundledChannelSecrets("alpha")?.secretTargetRegistryEntries?.[0]?.id).toBe(
        "channels.alpha.A.entry-token",
      );
      expect(
        bundled.getBundledChannelSetupSecrets("alpha")?.secretTargetRegistryEntries?.[0]?.id,
      ).toBe("channels.alpha.A.setup-entry-token");
      bundled.setBundledChannelRuntime("alpha", { marker: "first" } as never);

      process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = path.join(rootB, "dist", "extensions");
      expect(bundled.requireBundledChannelPlugin("alpha").meta.label).toBe("Alpha B");
      expect(bundled.getBundledChannelSetupPlugin("alpha")?.meta.label).toBe("Setup B");
      expect(bundled.getBundledChannelSecrets("alpha")?.secretTargetRegistryEntries?.[0]?.id).toBe(
        "channels.alpha.B.entry-token",
      );
      expect(
        bundled.getBundledChannelSetupSecrets("alpha")?.secretTargetRegistryEntries?.[0]?.id,
      ).toBe("channels.alpha.B.setup-entry-token");
      bundled.setBundledChannelRuntime("alpha", { marker: "second" } as never);

      expect(testGlobal.__bundledRootRuntime).toEqual(["entry:A:first", "entry:B:second"]);
    } finally {
      restoreBundledPluginsDir(previousBundledPluginsDir);
      fs.rmSync(rootA, { recursive: true, force: true });
      fs.rmSync(rootB, { recursive: true, force: true });
      delete testGlobal.__bundledRootRuntime;
    }
  });

  it("loads setup-entry feature plugins without loading the main channel entry", async () => {
    const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-setup-only-"));
    const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
    const pluginDir = path.join(root, "dist", "extensions", "alpha");
    const testGlobal = globalThis as typeof globalThis & {
      __bundledSetupOnlyMainLoaded?: boolean;
      __bundledSetupOnlySetupLoaded?: number;
      __bundledSetupOnlyPluginLoaded?: boolean;
    };
    fs.mkdirSync(pluginDir, { recursive: true });
    fs.writeFileSync(
      path.join(pluginDir, "index.js"),
      [
        "globalThis.__bundledSetupOnlyMainLoaded = true;",
        "throw new Error('main entry loaded');",
        "",
      ].join("\n"),
      "utf8",
    );
    fs.writeFileSync(
      path.join(pluginDir, "setup-entry.js"),
      [
        "globalThis.__bundledSetupOnlySetupLoaded = (globalThis.__bundledSetupOnlySetupLoaded ?? 0) + 1;",
        "export default {",
        "  kind: 'bundled-channel-setup-entry',",
        "  features: { legacyStateMigrations: true },",
        "  loadSetupPlugin() {",
        "    globalThis.__bundledSetupOnlyPluginLoaded = true;",
        "    throw new Error('setup plugin loaded');",
        "  },",
        "  loadLegacyStateMigrationDetector() {",
        "    return ({ oauthDir }) => [{",
        "      kind: 'copy',",
        "      label: 'Alpha state',",
        "      sourcePath: oauthDir + '/legacy.json',",
        "      targetPath: oauthDir + '/alpha/legacy.json',",
        "    }];",
        "  },",
        "};",
        "",
      ].join("\n"),
      "utf8",
    );

    mockAlphaDistExtensionRuntime();

    try {
      process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = path.join(root, "dist", "extensions");

      const bundled = await importFreshModule<typeof import("./bundled.js")>(
        import.meta.url,
        "./bundled.js?scope=bundled-setup-only-feature",
      );

      expect(
        bundled.listBundledChannelLegacyStateMigrationDetectors({
          config: { channels: { alpha: { enabled: false } } },
        }),
      ).toEqual([]);
      expect(testGlobal.__bundledSetupOnlySetupLoaded).toBeUndefined();

      const detectors = bundled.listBundledChannelLegacyStateMigrationDetectors();
      expect(
        detectors.map((detector) =>
          detector({ cfg: {}, env: {}, stateDir: "/state", oauthDir: "/oauth" } as never),
        ),
      ).toEqual([
        [
          {
            kind: "copy",
            label: "Alpha state",
            sourcePath: "/oauth/legacy.json",
            targetPath: "/oauth/alpha/legacy.json",
          },
        ],
      ]);
      expect(testGlobal.__bundledSetupOnlySetupLoaded).toBe(1);
      expect(testGlobal.__bundledSetupOnlyMainLoaded).toBeUndefined();
      expect(testGlobal.__bundledSetupOnlyPluginLoaded).toBeUndefined();
    } finally {
      restoreBundledPluginsDir(previousBundledPluginsDir);
      fs.rmSync(root, { recursive: true, force: true });
      delete testGlobal.__bundledSetupOnlyMainLoaded;
      delete testGlobal.__bundledSetupOnlySetupLoaded;
      delete testGlobal.__bundledSetupOnlyPluginLoaded;
    }
  });

  it("does not load bundled setup entries through external staged runtime deps during discovery", async () => {
    const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-setup-runtime-deps-"));
    const stageRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-stage-"));
    const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
    const previousPluginStageDir = process.env.OPENCLAW_PLUGIN_STAGE_DIR;
    const pluginDir = path.join(root, "dist", "extensions", "alpha");
    const testGlobal = globalThis as typeof globalThis & {
      __bundledSetupRuntimeDepMarker?: string;
    };
    fs.mkdirSync(pluginDir, { recursive: true });
    fs.writeFileSync(
      path.join(root, "package.json"),
      JSON.stringify({ name: "openclaw", version: "2026.4.21" }),
      "utf8",
    );
    fs.writeFileSync(
      path.join(pluginDir, "package.json"),
      JSON.stringify({
        name: "@openclaw/alpha",
        version: "2026.4.21",
        type: "module",
        dependencies: {
          "alpha-runtime-dep": "1.0.0",
        },
      }),
      "utf8",
    );
    fs.writeFileSync(
      path.join(pluginDir, "setup-entry.js"),
      [
        "import { marker } from 'alpha-runtime-dep';",
        "globalThis.__bundledSetupRuntimeDepMarker = marker;",
        "export default {",
        "  kind: 'bundled-channel-setup-entry',",
        "  loadSetupPlugin() {",
        "    return { id: 'alpha', meta: { label: marker }, config: {} };",
        "  },",
        "};",
        "",
      ].join("\n"),
      "utf8",
    );

    process.env.OPENCLAW_PLUGIN_STAGE_DIR = stageRoot;
    const { resolveBundledRuntimeDependencyInstallRoot } =
      await import("../../plugins/bundled-runtime-deps.js");
    const installRoot = resolveBundledRuntimeDependencyInstallRoot(pluginDir);
    const depRoot = path.join(installRoot, "node_modules", "alpha-runtime-dep");
    fs.mkdirSync(depRoot, { recursive: true });
    fs.writeFileSync(
      path.join(depRoot, "package.json"),
      JSON.stringify({
        name: "alpha-runtime-dep",
        version: "1.0.0",
        type: "module",
        main: "index.js",
      }),
      "utf8",
    );
    fs.writeFileSync(path.join(depRoot, "index.js"), "export const marker = 'staged-alpha';\n");

    mockAlphaDistExtensionRuntime();

    try {
      process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = path.join(root, "dist", "extensions");

      const bundled = await importFreshModule<typeof import("./bundled.js")>(
        import.meta.url,
        "./bundled.js?scope=bundled-setup-runtime-deps",
      );

      expect(bundled.getBundledChannelSetupPlugin("alpha")).toBeUndefined();
      expect(testGlobal.__bundledSetupRuntimeDepMarker).toBeUndefined();
    } finally {
      restoreBundledPluginsDir(previousBundledPluginsDir);
      if (previousPluginStageDir === undefined) {
        delete process.env.OPENCLAW_PLUGIN_STAGE_DIR;
      } else {
        process.env.OPENCLAW_PLUGIN_STAGE_DIR = previousPluginStageDir;
      }
      fs.rmSync(root, { recursive: true, force: true });
      fs.rmSync(stageRoot, { recursive: true, force: true });
      delete testGlobal.__bundledSetupRuntimeDepMarker;
    }
  });

  it("swallows and caches bundled plugin and setup load failures", async () => {
    const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-load-failure-"));
    const previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
    const pluginDir = path.join(root, "dist", "extensions", "alpha");
    const testGlobal = globalThis as typeof globalThis & {
      __bundledPluginFailureLoads?: number;
      __bundledSetupFailureLoads?: number;
      __bundledSecretsFailureLoads?: number;
      __bundledSetupSecretsFailureLoads?: number;
    };
    fs.mkdirSync(pluginDir, { recursive: true });
    fs.writeFileSync(
      path.join(root, "package.json"),
      JSON.stringify({ name: "openclaw", version: "2026.4.21" }),
      "utf8",
    );
    fs.writeFileSync(
      path.join(pluginDir, "index.js"),
      [
        "export default {",
        "  kind: 'bundled-channel-entry',",
        "  id: 'alpha',",
        "  name: 'Alpha',",
        "  description: 'Alpha',",
        "  register() {},",
        "  loadChannelSecrets() {",
        "    globalThis.__bundledSecretsFailureLoads = (globalThis.__bundledSecretsFailureLoads ?? 0) + 1;",
        "    throw new Error('missing channel secrets dep');",
        "  },",
        "  loadChannelPlugin() {",
        "    globalThis.__bundledPluginFailureLoads = (globalThis.__bundledPluginFailureLoads ?? 0) + 1;",
        "    throw new Error('missing channel plugin dep');",
        "  },",
        "};",
        "",
      ].join("\n"),
      "utf8",
    );
    fs.writeFileSync(
      path.join(pluginDir, "setup-entry.js"),
      [
        "export default {",
        "  kind: 'bundled-channel-setup-entry',",
        "  loadSetupSecrets() {",
        "    globalThis.__bundledSetupSecretsFailureLoads = (globalThis.__bundledSetupSecretsFailureLoads ?? 0) + 1;",
        "    throw new Error('missing setup secrets dep');",
        "  },",
        "  loadSetupPlugin() {",
        "    globalThis.__bundledSetupFailureLoads = (globalThis.__bundledSetupFailureLoads ?? 0) + 1;",
        "    throw new Error('missing setup plugin dep');",
        "  },",
        "};",
        "",
      ].join("\n"),
      "utf8",
    );

    mockAlphaDistExtensionRuntime();

    try {
      process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = path.join(root, "dist", "extensions");

      const bundled = await importFreshModule<typeof import("./bundled.js")>(
        import.meta.url,
        "./bundled.js?scope=bundled-load-failure",
      );

      expect(bundled.getBundledChannelPlugin("alpha")).toBeUndefined();
      expect(bundled.getBundledChannelPlugin("alpha")).toBeUndefined();
      expect(bundled.getBundledChannelSetupPlugin("alpha")).toBeUndefined();
      expect(bundled.getBundledChannelSetupPlugin("alpha")).toBeUndefined();
      expect(bundled.getBundledChannelSecrets("alpha")).toBeUndefined();
      expect(bundled.getBundledChannelSecrets("alpha")).toBeUndefined();
      expect(bundled.getBundledChannelSetupSecrets("alpha")).toBeUndefined();
      expect(bundled.getBundledChannelSetupSecrets("alpha")).toBeUndefined();
      expect(testGlobal.__bundledPluginFailureLoads).toBe(1);
      expect(testGlobal.__bundledSetupFailureLoads).toBe(1);
      expect(testGlobal.__bundledSecretsFailureLoads).toBe(1);
      expect(testGlobal.__bundledSetupSecretsFailureLoads).toBe(1);
    } finally {
      restoreBundledPluginsDir(previousBundledPluginsDir);
      fs.rmSync(root, { recursive: true, force: true });
      delete testGlobal.__bundledPluginFailureLoads;
      delete testGlobal.__bundledSetupFailureLoads;
      delete testGlobal.__bundledSecretsFailureLoads;
      delete testGlobal.__bundledSetupSecretsFailureLoads;
    }
  });

  it("keeps channel entrypoints on the dedicated entry-contract SDK surface", () => {
    const offenders = collectBundledChannelEntrypointOffenders(
      bundledPluginRoots,
      (source) =>
        !source.includes('from "openclaw/plugin-sdk/channel-entry-contract"') ||
        source.includes('from "openclaw/plugin-sdk/core"') ||
        source.includes('from "openclaw/plugin-sdk/channel-core"'),
    );

    expect(offenders).toEqual([]);
  });

  it("keeps setup-entry legacy feature hints mirrored in package metadata", () => {
    const offenders: string[] = [];

    for (const extensionDir of bundledPluginRoots) {
      const setupEntryPath = path.join(extensionDir, "setup-entry.ts");
      const packageJsonPath = path.join(extensionDir, "package.json");
      if (!fs.existsSync(setupEntryPath) || !fs.existsSync(packageJsonPath)) {
        continue;
      }
      const setupEntrySource = fs.readFileSync(setupEntryPath, "utf8");
      const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as {
        openclaw?: {
          setupFeatures?: Record<string, boolean>;
        };
      };
      for (const feature of ["legacyStateMigrations", "legacySessionSurfaces"]) {
        const usesFeature = setupEntrySource.includes(`${feature}: true`);
        const hasHint = packageJson.openclaw?.setupFeatures?.[feature] === true;
        if (usesFeature !== hasHint) {
          offenders.push(`${path.relative(process.cwd(), extensionDir)}:${feature}`);
        }
      }
    }

    expect(offenders).toEqual([]);
  });

  it("keeps staged runtime-dependency setup entries on setup-only plugin barrels", () => {
    const offenders: string[] = [];

    for (const extensionDir of bundledPluginRoots) {
      const setupEntryPath = path.join(extensionDir, "setup-entry.ts");
      const packageJsonPath = path.join(extensionDir, "package.json");
      if (!fs.existsSync(setupEntryPath) || !fs.existsSync(packageJsonPath)) {
        continue;
      }
      const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as {
        openclaw?: {
          bundle?: {
            stageRuntimeDependencies?: boolean;
          };
        };
      };
      if (packageJson.openclaw?.bundle?.stageRuntimeDependencies !== true) {
        continue;
      }
      const setupEntrySource = fs.readFileSync(setupEntryPath, "utf8");
      if (/specifier:\s*["']\.\/(?:api|channel-plugin-api)\.js["']/u.test(setupEntrySource)) {
        offenders.push(path.relative(process.cwd(), setupEntryPath));
      }
    }

    expect(offenders).toEqual([]);
  });

  it("keeps bundled channel entrypoints free of static src imports", () => {
    const offenders = collectBundledChannelEntrypointOffenders(bundledPluginRoots, (source) =>
      /^(?:import|export)\s.+["']\.\/src\//mu.test(source),
    );

    expect(offenders).toEqual([]);
  });

  it("keeps channel implementations off the broad core SDK surface", () => {
    const offenders: string[] = [];

    for (const extensionDir of bundledPluginRoots) {
      for (const relativePath of ["src/channel.ts", "src/plugin.ts"]) {
        const filePath = path.join(extensionDir, relativePath);
        if (!fs.existsSync(filePath)) {
          continue;
        }
        const source = fs.readFileSync(filePath, "utf8");
        if (!source.includes("createChatChannelPlugin")) {
          continue;
        }
        if (source.includes('from "openclaw/plugin-sdk/core"')) {
          offenders.push(path.relative(process.cwd(), filePath));
        }
      }
    }

    expect(offenders).toEqual([]);
  });

  it("keeps plugin-sdk channel-core free of chat metadata bootstrap imports", () => {
    const source = fs.readFileSync(path.resolve("src/plugin-sdk/channel-core.ts"), "utf8");

    expect(source.includes("../channels/chat-meta.js")).toBe(false);
    expect(source.includes("getChatChannelMeta")).toBe(false);
  });

  it("keeps bundled hot runtime barrels off the broad core SDK surface", () => {
    const offenders = [
      "extensions/googlechat/runtime-api.ts",
      "extensions/irc/src/runtime-api.ts",
      "extensions/matrix/src/runtime-api.ts",
    ].filter((filePath) =>
      fs.readFileSync(path.resolve(filePath), "utf8").includes("openclaw/plugin-sdk/core"),
    );

    expect(offenders).toEqual([]);
  });

  it("keeps runtime helper surfaces off bootstrap-registry", () => {
    const offenders = [
      "src/config/markdown-tables.ts",
      "src/config/sessions/group.ts",
      "src/channels/plugins/setup-helpers.ts",
      "src/plugin-sdk/extension-shared.ts",
    ].filter((filePath) =>
      fs.readFileSync(path.resolve(filePath), "utf8").includes("bootstrap-registry.js"),
    );

    expect(offenders).toEqual([]);
  });

  it("keeps extension-shared off the broad runtime barrel", () => {
    const source = fs.readFileSync(path.resolve("src/plugin-sdk/extension-shared.ts"), "utf8");

    expect(source.includes('from "./runtime.js"')).toBe(false);
  });

  it("keeps nextcloud-talk's private SDK surface off the broad runtime barrel", () => {
    const source = fs.readFileSync(path.resolve("src/plugin-sdk/nextcloud-talk.ts"), "utf8");

    expect(source.includes('from "./runtime.js"')).toBe(false);
  });

  it("keeps bundled doctor surfaces off the broad runtime barrel", () => {
    const offenders = [
      "extensions/discord/src/doctor.ts",
      "extensions/matrix/src/doctor.ts",
      "extensions/slack/src/doctor.ts",
      "extensions/telegram/src/doctor.ts",
      "extensions/zalouser/src/doctor.ts",
    ].filter((filePath) =>
      fs
        .readFileSync(path.resolve(filePath), "utf8")
        .includes('from "openclaw/plugin-sdk/runtime"'),
    );

    expect(offenders).toEqual([]);
  });

  it("breaks reentrant bundled channel discovery cycles with an empty fallback", async () => {
    const pluginDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bundled-reentrant-"));
    const modulePath = path.join(pluginDir, "index.js");
    fs.writeFileSync(modulePath, "export {};\n", "utf8");

    vi.doMock("../../plugins/bundled-plugin-metadata.js", async (importOriginal) => {
      const actual =
        await importOriginal<typeof import("../../plugins/bundled-plugin-metadata.js")>();
      return {
        ...actual,
        listBundledPluginMetadata: () => [
          {
            dirName: "alpha",
            idHint: "alpha",
            source: {
              source: "./index.js",
              built: "./index.js",
            },
            manifest: {
              id: "alpha",
              channels: ["alpha"],
            },
          },
        ],
        resolveBundledPluginGeneratedPath: () => modulePath,
      };
    });
    vi.doMock("../../infra/boundary-file-read.js", () => ({
      openBoundaryFileSync: ({ absolutePath }: { absolutePath: string }) => ({
        ok: true,
        path: absolutePath,
        fd: fs.openSync(absolutePath, "r"),
      }),
    }));
    vi.doMock("../../plugins/channel-catalog-registry.js", () => ({
      listChannelCatalogEntries: () => [],
    }));

    let reentered = false;
    vi.doMock("jiti", () => ({
      createJiti: () => {
        return () => {
          if (!reentered) {
            reentered = true;
            expect(bundled.listBundledChannelPlugins()).toEqual([]);
          }
          return {
            default: {
              kind: "bundled-channel-entry",
              id: "alpha",
              name: "Alpha",
              description: "Alpha",
              configSchema: {},
              register() {},
              loadChannelPlugin() {
                return {
                  id: "alpha",
                  meta: {},
                  capabilities: {},
                  config: {},
                };
              },
            },
          };
        };
      },
    }));

    const bundled = await importFreshModule<typeof import("./bundled.js")>(
      import.meta.url,
      "./bundled.js?scope=reentrant-bundled-discovery",
    );

    expect(bundled.listBundledChannelPlugins()).toHaveLength(1);
    expect(reentered).toBe(true);
  });

  it("keeps private src runtime barrels from forwarding to parent runtime barrels that export local plugins", () => {
    const offenders: string[] = [];

    for (const extensionDir of bundledPluginRoots) {
      const privateRuntimePath = path.join(extensionDir, "src", "runtime-api.ts");
      const publicRuntimePath = path.join(extensionDir, "runtime-api.ts");
      if (!fs.existsSync(privateRuntimePath) || !fs.existsSync(publicRuntimePath)) {
        continue;
      }
      const privateRuntimeSource = fs.readFileSync(privateRuntimePath, "utf8");
      const publicRuntimeSource = fs.readFileSync(publicRuntimePath, "utf8");
      const forwardsParentRuntime =
        privateRuntimeSource.includes('export * from "../runtime-api.js"') ||
        privateRuntimeSource.includes("export * from '../runtime-api.js'");
      const exportsLocalPlugin =
        publicRuntimeSource.includes('from "./src/channel.js"') &&
        /export\s+\{\s*[\w$]+Plugin\s*\}\s+from\s+["']\.\/src\/channel\.js["']/u.test(
          publicRuntimeSource,
        );
      if (forwardsParentRuntime && exportsLocalPlugin) {
        offenders.push(path.relative(process.cwd(), publicRuntimePath));
      }
    }

    expect(offenders).toEqual([]);
  });
});

¤ Dauer der Verarbeitung: 0.29 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge