Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/JAVA/Openclaw/src/plugins/   (KI Agentensystem Version 22©)  Datei vom 26.3.2026 mit Größe 25 kB image not shown  

Quelle  status.test.ts

  Sprache: JAVA
 

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

import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import {
  createCompatibilityNotice,
  createCustomHook,
  createPluginLoadResult,
  createPluginRecord,
  createTypedHook,
  HOOK_ONLY_MESSAGE,
  LEGACY_BEFORE_AGENT_START_MESSAGE,
} from "./status.test-helpers.js";

const loadConfigMock = vi.fn();
const loadOpenClawPluginsMock = vi.fn();
const loadPluginMetadataRegistrySnapshotMock = vi.fn();
const applyPluginAutoEnableMock = vi.fn();
const resolveBundledProviderCompatPluginIdsMock = vi.fn();
const withBundledPluginAllowlistCompatMock = vi.fn();
const withBundledPluginEnablementCompatMock = vi.fn();
const listImportedBundledPluginFacadeIdsMock = vi.fn();
const listImportedRuntimePluginIdsMock = vi.fn();
let buildPluginSnapshotReport: typeof import("./status.js").buildPluginSnapshotReport;
let buildPluginDiagnosticsReport: typeof import("./status.js").buildPluginDiagnosticsReport;
let buildPluginInspectReport: typeof import("./status.js").buildPluginInspectReport;
let buildAllPluginInspectReports: typeof import("./status.js").buildAllPluginInspectReports;
let buildPluginCompatibilityNotices: typeof import("./status.js").buildPluginCompatibilityNotices;
let buildPluginCompatibilityWarnings: typeof import("./status.js").buildPluginCompatibilityWarnings;
let formatPluginCompatibilityNotice: typeof import("./status.js").formatPluginCompatibilityNotice;
let summarizePluginCompatibility: typeof import("./status.js").summarizePluginCompatibility;

vi.mock("../config/config.js", () => ({
  loadConfig: () => loadConfigMock(),
}));

vi.mock("../config/plugin-auto-enable.js", () => ({
  applyPluginAutoEnable: (...args: unknown[]) => applyPluginAutoEnableMock(...args),
}));

vi.mock("./loader.js", () => ({
  loadOpenClawPlugins: (...args: unknown[]) => loadOpenClawPluginsMock(...args),
}));

vi.mock("./runtime/metadata-registry-loader.js", () => ({
  loadPluginMetadataRegistrySnapshot: (...args: unknown[]) =>
    loadPluginMetadataRegistrySnapshotMock(...args),
}));

vi.mock("./providers.js", () => ({
  resolveBundledProviderCompatPluginIds: (...args: unknown[]) =>
    resolveBundledProviderCompatPluginIdsMock(...args),
}));

vi.mock("./bundled-compat.js", () => ({
  withBundledPluginAllowlistCompat: (...args: unknown[]) =>
    withBundledPluginAllowlistCompatMock(...args),
  withBundledPluginEnablementCompat: (...args: unknown[]) =>
    withBundledPluginEnablementCompatMock(...args),
}));

vi.mock("../plugin-sdk/facade-runtime.js", () => ({
  listImportedBundledPluginFacadeIds: (...args: unknown[]) =>
    listImportedBundledPluginFacadeIdsMock(...args),
}));

vi.mock("./runtime.js", () => ({
  getActivePluginChannelRegistry: () => null,
  listImportedRuntimePluginIds: (...args: unknown[]) => listImportedRuntimePluginIdsMock(...args),
}));

vi.mock("../agents/agent-scope.js", () => ({
  resolveAgentWorkspaceDir: () => undefined,
  resolveDefaultAgentId: () => "default",
}));

vi.mock("../agents/workspace.js", () => ({
  resolveDefaultAgentWorkspaceDir: () => "/default-workspace",
}));

function setPluginLoadResult(overrides: Partial<ReturnType<typeof createPluginLoadResult>>) {
  const result = createPluginLoadResult({
    plugins: [],
    ...overrides,
  });
  loadOpenClawPluginsMock.mockReturnValue(result);
  loadPluginMetadataRegistrySnapshotMock.mockReturnValue(result);
}

function setSinglePluginLoadResult(
  plugin: ReturnType<typeof createPluginRecord>,
  overrides: Omit<Partial<ReturnType<typeof createPluginLoadResult>>, "plugins"> = {},
) {
  setPluginLoadResult({
    plugins: [plugin],
    ...overrides,
  });
}

function expectInspectReport(
  pluginId: string,
): NonNullable<ReturnType<typeof buildPluginInspectReport>> {
  const inspect = buildPluginInspectReport({ id: pluginId });
  expect(inspect).not.toBeNull();
  if (!inspect) {
    throw new Error(`expected inspect report for ${pluginId}`);
  }
  return inspect;
}

function expectPluginLoaderCall(params: {
  config?: unknown;
  activationSourceConfig?: unknown;
  autoEnabledReasons?: Record<string, string[]>;
  workspaceDir?: string;
  env?: NodeJS.ProcessEnv;
  logger?: unknown;
  loadModules?: boolean;
}) {
  expect(loadOpenClawPluginsMock).toHaveBeenCalledWith(
    expect.objectContaining({
      ...(params.config !== undefined ? { config: params.config } : {}),
      ...(params.activationSourceConfig !== undefined
        ? { activationSourceConfig: params.activationSourceConfig }
        : {}),
      ...(params.autoEnabledReasons !== undefined
        ? { autoEnabledReasons: params.autoEnabledReasons }
        : {}),
      ...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
      ...(params.env ? { env: params.env } : {}),
      ...(params.logger !== undefined ? { logger: params.logger } : {}),
      ...(params.loadModules !== undefined ? { loadModules: params.loadModules } : {}),
    }),
  );
}

function expectMetadataSnapshotLoaderCall(params: {
  config?: unknown;
  activationSourceConfig?: unknown;
  workspaceDir?: string;
  env?: NodeJS.ProcessEnv;
  logger?: unknown;
  loadModules?: boolean;
}) {
  expect(loadPluginMetadataRegistrySnapshotMock).toHaveBeenCalledWith(
    expect.objectContaining({
      ...(params.config !== undefined ? { config: params.config } : {}),
      ...(params.activationSourceConfig !== undefined
        ? { activationSourceConfig: params.activationSourceConfig }
        : {}),
      ...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
      ...(params.env ? { env: params.env } : {}),
      ...(params.logger !== undefined ? { logger: params.logger } : {}),
      ...(params.loadModules !== undefined ? { loadModules: params.loadModules } : {}),
    }),
  );
}

function expectAutoEnabledStatusLoad(params: { rawConfig: unknown }) {
  expect(applyPluginAutoEnableMock).toHaveBeenCalledWith({
    config: params.rawConfig,
    env: process.env,
  });
}

function createCompatChainFixture() {
  const config = { plugins: { allow: ["telegram"] } };
  const pluginIds = ["anthropic", "openai"];
  const compatConfig = { plugins: { allow: ["telegram", ...pluginIds] } };
  const enabledConfig = {
    plugins: {
      allow: ["telegram", ...pluginIds],
      entries: {
        anthropic: { enabled: true },
        openai: { enabled: true },
      },
    },
  };
  return { config, pluginIds, compatConfig, enabledConfig };
}

function expectBundledCompatChainApplied(params: {
  config: unknown;
  pluginIds: string[];
  compatConfig: unknown;
  enabledConfig: unknown;
  loadModules: boolean;
}) {
  expect(withBundledPluginAllowlistCompatMock).toHaveBeenCalledWith({
    config: params.config,
    pluginIds: params.pluginIds,
  });
  expect(withBundledPluginEnablementCompatMock).toHaveBeenCalledWith({
    config: params.compatConfig,
    pluginIds: params.pluginIds,
  });
  if (params.loadModules) {
    expectPluginLoaderCall({ config: params.enabledConfig, loadModules: true });
    return;
  }
  expectMetadataSnapshotLoaderCall({ config: params.enabledConfig, loadModules: false });
}

function createAutoEnabledStatusConfig(
  entries: Record<string, unknown>,
  rawConfigOverrides?: Record<string, unknown>,
) {
  const rawConfig = {
    plugins: {},
    ...rawConfigOverrides,
  };
  const autoEnabledConfig = {
    ...rawConfig,
    plugins: {
      entries,
    },
  };
  return { rawConfig, autoEnabledConfig };
}

function expectAutoEnabledDemoCompatibilityNoticesPreserveRawConfig() {
  const { rawConfig, autoEnabledConfig } = createAutoEnabledStatusConfig(
    {
      demo: { enabled: true },
    },
    { channels: { demo: { enabled: true } } },
  );
  const autoEnabledReasons = {
    demo: ["demo configured"],
  };
  applyPluginAutoEnableMock.mockReturnValue({
    config: autoEnabledConfig,
    changes: [],
    autoEnabledReasons,
  });
  setSinglePluginLoadResult(
    createPluginRecord({
      id: "demo",
      name: "Demo",
      description: "Auto-enabled plugin",
      origin: "bundled",
      hookCount: 1,
    }),
    {
      typedHooks: [createTypedHook({ pluginId: "demo", hookName: "before_agent_start" })],
    },
  );

  expect(buildPluginCompatibilityNotices({ config: rawConfig })).toEqual([
    createCompatibilityNotice({ pluginId: "demo", code: "legacy-before-agent-start" }),
    createCompatibilityNotice({ pluginId: "demo", code: "hook-only" }),
  ]);

  expectAutoEnabledStatusLoad({
    rawConfig,
  });
  expectPluginLoaderCall({
    config: autoEnabledConfig,
    activationSourceConfig: rawConfig,
    autoEnabledReasons,
    loadModules: true,
  });
}

function expectNoCompatibilityWarnings() {
  expect(buildPluginCompatibilityNotices()).toEqual([]);
  expect(buildPluginCompatibilityWarnings()).toEqual([]);
}

function expectCompatibilityOutput(params: { notices?: unknown[]; warnings?: string[] }) {
  if (params.notices) {
    expect(buildPluginCompatibilityNotices()).toEqual(params.notices);
  }
  if (params.warnings) {
    expect(buildPluginCompatibilityWarnings()).toEqual(params.warnings);
  }
}

function expectCapabilityKinds(
  inspect: NonNullable<ReturnType<typeof buildPluginInspectReport>>,
  kinds: readonly string[],
) {
  expect(inspect.capabilities.map((entry) => entry.kind)).toEqual(kinds);
}

function expectInspectShape(
  inspect: NonNullable<ReturnType<typeof buildPluginInspectReport>>,
  params: {
    shape: string;
    capabilityMode: string;
    capabilityKinds: readonly string[];
  },
) {
  expect(inspect.shape).toBe(params.shape);
  expect(inspect.capabilityMode).toBe(params.capabilityMode);
  expectCapabilityKinds(inspect, params.capabilityKinds);
}

function expectInspectPolicy(
  inspect: NonNullable<ReturnType<typeof buildPluginInspectReport>>,
  expected: Record<string, unknown>,
) {
  expect(inspect.policy).toEqual(expected);
}

function expectBundleInspectState(
  inspect: NonNullable<ReturnType<typeof buildPluginInspectReport>>,
  params: {
    bundleCapabilities: readonly string[];
    shape: string;
  },
) {
  expect(inspect.bundleCapabilities).toEqual(params.bundleCapabilities);
  expect(inspect.mcpServers).toEqual([]);
  expect(inspect.shape).toBe(params.shape);
}

describe("plugin status reports", () => {
  beforeAll(async () => {
    ({
      buildAllPluginInspectReports,
      buildPluginCompatibilityNotices,
      buildPluginDiagnosticsReport,
      buildPluginCompatibilityWarnings,
      buildPluginInspectReport,
      buildPluginSnapshotReport,
      formatPluginCompatibilityNotice,
      summarizePluginCompatibility,
    } = await import("./status.js"));
  });

  beforeEach(() => {
    loadConfigMock.mockReset();
    loadOpenClawPluginsMock.mockReset();
    loadPluginMetadataRegistrySnapshotMock.mockReset();
    applyPluginAutoEnableMock.mockReset();
    resolveBundledProviderCompatPluginIdsMock.mockReset();
    withBundledPluginAllowlistCompatMock.mockReset();
    withBundledPluginEnablementCompatMock.mockReset();
    listImportedBundledPluginFacadeIdsMock.mockReset();
    listImportedRuntimePluginIdsMock.mockReset();
    loadConfigMock.mockReturnValue({});
    applyPluginAutoEnableMock.mockImplementation((params: { config: unknown }) => ({
      config: params.config,
      changes: [],
      autoEnabledReasons: {},
    }));
    resolveBundledProviderCompatPluginIdsMock.mockReturnValue([]);
    withBundledPluginAllowlistCompatMock.mockImplementation(
      (params: { config: unknown }) => params.config,
    );
    withBundledPluginEnablementCompatMock.mockImplementation(
      (params: { config: unknown }) => params.config,
    );
    listImportedBundledPluginFacadeIdsMock.mockReturnValue([]);
    listImportedRuntimePluginIdsMock.mockReturnValue([]);
    setPluginLoadResult({ plugins: [] });
  });

  it("forwards an explicit env to plugin loading", () => {
    const env = { HOME: "/tmp/openclaw-home" } as NodeJS.ProcessEnv;

    buildPluginSnapshotReport({
      config: {},
      workspaceDir: "/workspace",
      env,
    });

    expectMetadataSnapshotLoaderCall({
      config: {},
      workspaceDir: "/workspace",
      env,
      loadModules: false,
    });
  });

  it("forwards an explicit logger to plugin loading", () => {
    const logger = {
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
    };

    buildPluginSnapshotReport({
      config: {},
      logger,
      workspaceDir: "/workspace",
    });

    expectMetadataSnapshotLoaderCall({
      config: {},
      logger,
      workspaceDir: "/workspace",
      loadModules: false,
    });
  });

  it("uses a metadata snapshot load for snapshot reports", () => {
    buildPluginSnapshotReport({ config: {}, workspaceDir: "/workspace" });

    expect(loadPluginMetadataRegistrySnapshotMock).toHaveBeenCalledWith(
      expect.objectContaining({
        loadModules: false,
      }),
    );
    expect(loadOpenClawPluginsMock).not.toHaveBeenCalled();
  });

  it("loads plugin status from the auto-enabled config snapshot", () => {
    const { rawConfig, autoEnabledConfig } = createAutoEnabledStatusConfig(
      {
        demo: { enabled: true },
      },
      { channels: { demo: { enabled: true } } },
    );
    applyPluginAutoEnableMock.mockReturnValue({
      config: autoEnabledConfig,
      changes: [],
      autoEnabledReasons: {
        demo: ["demo configured"],
      },
    });

    buildPluginSnapshotReport({ config: rawConfig });

    expectAutoEnabledStatusLoad({
      rawConfig,
    });
    expectMetadataSnapshotLoaderCall({
      config: autoEnabledConfig,
      activationSourceConfig: rawConfig,
      loadModules: false,
    });
  });

  it("uses the auto-enabled config snapshot for inspect policy summaries", () => {
    const { rawConfig, autoEnabledConfig } = createAutoEnabledStatusConfig(
      {
        demo: {
          enabled: true,
          subagent: {
            allowModelOverride: true,
            allowedModels: ["openai/gpt-5.5"],
            hasAllowedModelsConfig: true,
          },
        },
      },
      { channels: { demo: { enabled: true } } },
    );
    applyPluginAutoEnableMock.mockReturnValue({
      config: autoEnabledConfig,
      changes: [],
      autoEnabledReasons: {
        demo: ["demo configured"],
      },
    });
    setSinglePluginLoadResult(
      createPluginRecord({
        id: "demo",
        name: "Demo",
        description: "Auto-enabled plugin",
        origin: "bundled",
        providerIds: ["demo"],
      }),
    );

    const inspect = buildPluginInspectReport({ id: "demo", config: rawConfig });

    expect(inspect).not.toBeNull();
    expectInspectPolicy(inspect!, {
      allowPromptInjection: undefined,
      allowConversationAccess: undefined,
      allowModelOverride: true,
      allowedModels: ["openai/gpt-5.5"],
      hasAllowedModelsConfig: true,
    });
    expectPluginLoaderCall({ loadModules: true });
  });

  it("preserves raw config activation context when compatibility notices build their own report", () => {
    expectAutoEnabledDemoCompatibilityNoticesPreserveRawConfig();
  });

  it("applies the full bundled provider compat chain before loading plugins", () => {
    const { config, pluginIds, compatConfig, enabledConfig } = createCompatChainFixture();
    loadConfigMock.mockReturnValue(config);
    resolveBundledProviderCompatPluginIdsMock.mockReturnValue(pluginIds);
    withBundledPluginAllowlistCompatMock.mockReturnValue(compatConfig);
    withBundledPluginEnablementCompatMock.mockReturnValue(enabledConfig);

    buildPluginSnapshotReport({ config });

    expectBundledCompatChainApplied({
      config,
      pluginIds,
      compatConfig,
      enabledConfig,
      loadModules: false,
    });
  });

  it("preserves raw config activation context for compatibility-derived reports", () => {
    expectAutoEnabledDemoCompatibilityNoticesPreserveRawConfig();
  });

  it("normalizes bundled plugin versions to the core base release", () => {
    setSinglePluginLoadResult(
      createPluginRecord({
        id: "whatsapp",
        name: "WhatsApp",
        description: "Bundled channel plugin",
        version: "2026.3.22",
        origin: "bundled",
        channelIds: ["whatsapp"],
      }),
    );

    const report = buildPluginDiagnosticsReport({
      config: {},
      env: {
        OPENCLAW_VERSION: "2026.3.23-1",
      } as NodeJS.ProcessEnv,
    });

    expect(report.plugins[0]?.version).toBe("2026.3.23");
  });

  it("marks plugins as imported when runtime or facade state has loaded them", () => {
    setPluginLoadResult({
      plugins: [
        createPluginRecord({ id: "runtime-loaded" }),
        createPluginRecord({ id: "facade-loaded" }),
        createPluginRecord({ id: "bundle-loaded", format: "bundle" }),
        createPluginRecord({ id: "cold-plugin" }),
      ],
    });
    listImportedRuntimePluginIdsMock.mockReturnValue(["runtime-loaded", "bundle-loaded"]);
    listImportedBundledPluginFacadeIdsMock.mockReturnValue(["facade-loaded"]);

    const report = buildPluginSnapshotReport({ config: {} });

    expect(report.plugins).toEqual(
      expect.arrayContaining([
        expect.objectContaining({ id: "runtime-loaded", imported: true }),
        expect.objectContaining({ id: "facade-loaded", imported: true }),
        expect.objectContaining({ id: "bundle-loaded", imported: false }),
        expect.objectContaining({ id: "cold-plugin", imported: false }),
      ]),
    );
  });

  it("marks snapshot-loaded plugin modules as imported during full report loads", () => {
    setPluginLoadResult({
      plugins: [
        createPluginRecord({ id: "runtime-loaded" }),
        createPluginRecord({ id: "bundle-loaded", format: "bundle" }),
      ],
    });

    const report = buildPluginDiagnosticsReport({ config: {} });

    expect(report.plugins).toEqual(
      expect.arrayContaining([
        expect.objectContaining({ id: "runtime-loaded", imported: true }),
        expect.objectContaining({ id: "bundle-loaded", imported: false }),
      ]),
    );
  });

  it("marks errored plugin modules as imported when full diagnostics already evaluated them", () => {
    setPluginLoadResult({
      plugins: [createPluginRecord({ id: "broken-plugin", status: "error" })],
    });
    listImportedRuntimePluginIdsMock.mockReturnValue(["broken-plugin"]);

    const report = buildPluginDiagnosticsReport({ config: {} });

    expect(report.plugins).toEqual(
      expect.arrayContaining([
        expect.objectContaining({ id: "broken-plugin", status: "error", imported: true }),
      ]),
    );
  });

  it("builds an inspect report with capability shape and policy", () => {
    loadConfigMock.mockReturnValue({
      plugins: {
        entries: {
          google: {
            hooks: { allowPromptInjection: false, allowConversationAccess: true },
            subagent: {
              allowModelOverride: true,
              allowedModels: ["openai/gpt-5.5"],
            },
          },
        },
      },
    });
    setPluginLoadResult({
      plugins: [
        createPluginRecord({
          id: "google",
          name: "Google",
          description: "Google provider plugin",
          origin: "bundled",
          providerIds: ["google"],
          mediaUnderstandingProviderIds: ["google"],
          imageGenerationProviderIds: ["google"],
          webSearchProviderIds: ["google"],
        }),
      ],
      diagnostics: [{ level: "warn", pluginId: "google", message: "watch this surface" }],
      typedHooks: [createTypedHook({ pluginId: "google", hookName: "before_agent_start" })],
    });

    const inspect = buildPluginInspectReport({ id: "google" });

    expect(inspect).not.toBeNull();
    expectInspectShape(inspect!, {
      shape: "hybrid-capability",
      capabilityMode: "hybrid",
      capabilityKinds: ["text-inference", "media-understanding", "image-generation", "web-search"],
    });
    expect(inspect?.usesLegacyBeforeAgentStart).toBe(true);
    expect(inspect?.compatibility).toEqual([
      createCompatibilityNotice({ pluginId: "google", code: "legacy-before-agent-start" }),
    ]);
    expectInspectPolicy(inspect!, {
      allowPromptInjection: false,
      allowConversationAccess: true,
      allowModelOverride: true,
      allowedModels: ["openai/gpt-5.5"],
      hasAllowedModelsConfig: true,
    });
    expect(inspect?.diagnostics).toEqual([
      { level: "warn", pluginId: "google", message: "watch this surface" },
    ]);
  });

  it("builds inspect reports for every loaded plugin", () => {
    setPluginLoadResult({
      plugins: [
        createPluginRecord({
          id: "lca",
          name: "LCA",
          description: "Legacy hook plugin",
          hookCount: 1,
        }),
        createPluginRecord({
          id: "microsoft",
          name: "Microsoft",
          description: "Hybrid capability plugin",
          origin: "bundled",
          providerIds: ["microsoft"],
          webSearchProviderIds: ["microsoft"],
        }),
      ],
      hooks: [createCustomHook({ pluginId: "lca", events: ["message"] })],
      typedHooks: [createTypedHook({ pluginId: "lca", hookName: "before_agent_start" })],
    });

    const inspect = buildAllPluginInspectReports();

    expect(inspect.map((entry) => entry.plugin.id)).toEqual(["lca", "microsoft"]);
    expect(inspect.map((entry) => entry.shape)).toEqual(["hook-only", "hybrid-capability"]);
    expect(inspect[0]?.usesLegacyBeforeAgentStart).toBe(true);
    expectCapabilityKinds(inspect[1], ["text-inference", "web-search"]);
  });

  it("treats a CLI-command-only plugin as a plain capability", () => {
    setSinglePluginLoadResult(
      createPluginRecord({
        id: "anthropic",
        name: "Anthropic",
        cliBackendIds: ["claude-cli"],
      }),
    );

    const inspect = expectInspectReport("anthropic");

    expectInspectShape(inspect, {
      shape: "plain-capability",
      capabilityMode: "plain",
      capabilityKinds: ["cli-backend"],
    });
    expect(inspect.capabilities).toEqual([{ kind: "cli-backend", ids: ["claude-cli"] }]);
  });

  it("treats a context-engine plugin as a plain capability", () => {
    setPluginLoadResult({
      plugins: [
        createPluginRecord({
          id: "moon",
          name: "Moon",
          kind: "context-engine",
          contextEngineIds: ["moon-engine"],
          hookCount: 1,
        }),
      ],
      hooks: [createCustomHook({ pluginId: "moon", events: ["message"] })],
    });

    const inspect = expectInspectReport("moon");

    expectInspectShape(inspect, {
      shape: "plain-capability",
      capabilityMode: "plain",
      capabilityKinds: ["context-engine"],
    });
    expect(inspect.capabilities).toEqual([{ kind: "context-engine", ids: ["moon-engine"] }]);
    expect(inspect.compatibility).toEqual([]);
    expectNoCompatibilityWarnings();
  });

  it("builds compatibility warnings for legacy compatibility paths", () => {
    setPluginLoadResult({
      plugins: [
        createPluginRecord({
          id: "lca",
          name: "LCA",
          description: "Legacy hook plugin",
          hookCount: 1,
        }),
      ],
      typedHooks: [createTypedHook({ pluginId: "lca", hookName: "before_agent_start" })],
    });

    expectCompatibilityOutput({
      warnings: [`lca ${LEGACY_BEFORE_AGENT_START_MESSAGE}`, `lca ${HOOK_ONLY_MESSAGE}`],
    });
  });

  it("builds structured compatibility notices with deterministic ordering", () => {
    setPluginLoadResult({
      plugins: [
        createPluginRecord({
          id: "hook-only",
          name: "Hook Only",
          hookCount: 1,
        }),
        createPluginRecord({
          id: "legacy-only",
          name: "Legacy Only",
          providerIds: ["legacy-only"],
          hookCount: 1,
        }),
      ],
      hooks: [createCustomHook({ pluginId: "hook-only", events: ["message"] })],
      typedHooks: [createTypedHook({ pluginId: "legacy-only", hookName: "before_agent_start" })],
    });

    expectCompatibilityOutput({
      notices: [
        createCompatibilityNotice({ pluginId: "hook-only", code: "hook-only" }),
        createCompatibilityNotice({ pluginId: "legacy-only", code: "legacy-before-agent-start" }),
      ],
    });
  });

  it("returns no compatibility warnings for modern capability plugins", () => {
    setSinglePluginLoadResult(
      createPluginRecord({
        id: "modern",
        name: "Modern",
        providerIds: ["modern"],
      }),
    );

    expectNoCompatibilityWarnings();
  });

  it.each([
    {
      name: "populates bundleCapabilities from plugin record",
      plugin: createPluginRecord({
        id: "claude-bundle",
        name: "Claude Bundle",
        description: "A bundle plugin with skills and commands",
        source: "/tmp/claude-bundle/.claude-plugin/plugin.json",
        format: "bundle",
        bundleFormat: "claude",
        bundleCapabilities: ["skills", "commands", "agents", "settings"],
        rootDir: "/tmp/claude-bundle",
      }),
      expectedId: "claude-bundle",
      expectedBundleCapabilities: ["skills", "commands", "agents", "settings"],
      expectedShape: "non-capability",
    },
    {
      name: "returns empty bundleCapabilities and mcpServers for non-bundle plugins",
      plugin: createPluginRecord({
        id: "plain-plugin",
        name: "Plain Plugin",
        description: "A regular plugin",
        providerIds: ["plain"],
      }),
      expectedId: "plain-plugin",
      expectedBundleCapabilities: [],
      expectedShape: "plain-capability",
    },
  ])("$name", ({ plugin, expectedId, expectedBundleCapabilities, expectedShape }) => {
    setSinglePluginLoadResult(plugin);

    const inspect = expectInspectReport(expectedId);

    expectBundleInspectState(inspect, {
      bundleCapabilities: expectedBundleCapabilities,
      shape: expectedShape,
    });
  });

  it("formats and summarizes compatibility notices", () => {
    const notice = createCompatibilityNotice({
      pluginId: "legacy-plugin",
      code: "legacy-before-agent-start",
    });

    expect(formatPluginCompatibilityNotice(notice)).toBe(
      `legacy-plugin ${LEGACY_BEFORE_AGENT_START_MESSAGE}`,
    );
    expect(
      summarizePluginCompatibility([
        notice,
        createCompatibilityNotice({ pluginId: "legacy-plugin", code: "hook-only" }),
      ]),
    ).toEqual({
      noticeCount: 2,
      pluginCount: 1,
    });
  });
});

¤ Dauer der Verarbeitung: 0.2 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.