






















@@ -7,18 +7,22 @@ import {
77createTypedHook,
88HOOK_ONLY_MESSAGE,
99LEGACY_BEFORE_AGENT_START_MESSAGE,
10+LEGACY_IMPLICIT_STARTUP_SIDECAR_MESSAGE,
1011} from "./status.test-helpers.js";
11121213const loadConfigMock = vi.fn();
1314const loadOpenClawPluginsMock = vi.fn();
1415const loadPluginMetadataRegistrySnapshotMock = vi.fn();
16+const loadPluginRegistrySnapshotWithMetadataMock = vi.fn();
17+const loadPluginManifestRegistryForInstalledIndexMock = vi.fn();
1518const applyPluginAutoEnableMock = vi.fn();
1619const resolveBundledProviderCompatPluginIdsMock = vi.fn();
1720const withBundledPluginAllowlistCompatMock = vi.fn();
1821const withBundledPluginEnablementCompatMock = vi.fn();
1922const listImportedBundledPluginFacadeIdsMock = vi.fn();
2023const listImportedRuntimePluginIdsMock = vi.fn();
2124let buildPluginSnapshotReport: typeof import("./status.js").buildPluginSnapshotReport;
25+let buildPluginRegistrySnapshotReport: typeof import("./status.js").buildPluginRegistrySnapshotReport;
2226let buildPluginDiagnosticsReport: typeof import("./status.js").buildPluginDiagnosticsReport;
2327let buildPluginInspectReport: typeof import("./status.js").buildPluginInspectReport;
2428let buildAllPluginInspectReports: typeof import("./status.js").buildAllPluginInspectReports;
@@ -45,6 +49,16 @@ vi.mock("./runtime/metadata-registry-loader.js", () => ({
4549loadPluginMetadataRegistrySnapshotMock(...args),
4650}));
475152+vi.mock("./plugin-registry.js", () => ({
53+loadPluginRegistrySnapshotWithMetadata: (...args: unknown[]) =>
54+loadPluginRegistrySnapshotWithMetadataMock(...args),
55+}));
56+57+vi.mock("./manifest-registry-installed.js", () => ({
58+loadPluginManifestRegistryForInstalledIndex: (...args: unknown[]) =>
59+loadPluginManifestRegistryForInstalledIndexMock(...args),
60+}));
61+4862vi.mock("./providers.js", () => ({
4963resolveBundledProviderCompatPluginIds: (...args: unknown[]) =>
5064resolveBundledProviderCompatPluginIdsMock(...args),
@@ -95,6 +109,23 @@ function setSinglePluginLoadResult(
95109});
96110}
97111112+function createInstalledPluginIndexSnapshot(
113+plugins: Array<Record<string, unknown>>,
114+): Record<string, unknown> {
115+return {
116+version: 1,
117+warning: "test",
118+hostContractVersion: "test",
119+compatRegistryVersion: "test",
120+migrationVersion: 1,
121+policyHash: "test",
122+generatedAtMs: 0,
123+installRecords: {},
124+ plugins,
125+diagnostics: [],
126+};
127+}
128+98129function expectInspectReport(
99130pluginId: string,
100131): NonNullable<ReturnType<typeof buildPluginInspectReport>> {
@@ -321,6 +352,7 @@ describe("plugin status reports", () => {
321352 buildPluginDiagnosticsReport,
322353 buildPluginCompatibilityWarnings,
323354 buildPluginInspectReport,
355+ buildPluginRegistrySnapshotReport,
324356 buildPluginSnapshotReport,
325357 formatPluginCompatibilityNotice,
326358 summarizePluginCompatibility,
@@ -331,13 +363,24 @@ describe("plugin status reports", () => {
331363loadConfigMock.mockReset();
332364loadOpenClawPluginsMock.mockReset();
333365loadPluginMetadataRegistrySnapshotMock.mockReset();
366+loadPluginRegistrySnapshotWithMetadataMock.mockReset();
367+loadPluginManifestRegistryForInstalledIndexMock.mockReset();
334368applyPluginAutoEnableMock.mockReset();
335369resolveBundledProviderCompatPluginIdsMock.mockReset();
336370withBundledPluginAllowlistCompatMock.mockReset();
337371withBundledPluginEnablementCompatMock.mockReset();
338372listImportedBundledPluginFacadeIdsMock.mockReset();
339373listImportedRuntimePluginIdsMock.mockReset();
340374loadConfigMock.mockReturnValue({});
375+loadPluginRegistrySnapshotWithMetadataMock.mockReturnValue({
376+snapshot: createInstalledPluginIndexSnapshot([]),
377+source: "derived",
378+diagnostics: [],
379+});
380+loadPluginManifestRegistryForInstalledIndexMock.mockReturnValue({
381+plugins: [],
382+diagnostics: [],
383+});
341384applyPluginAutoEnableMock.mockImplementation((params: { config: unknown }) => ({
342385config: params.config,
343386changes: [],
@@ -393,6 +436,41 @@ describe("plugin status reports", () => {
393436});
394437});
395438439+it("carries installed-index compatibility metadata into registry snapshot reports", () => {
440+loadPluginRegistrySnapshotWithMetadataMock.mockReturnValue({
441+snapshot: createInstalledPluginIndexSnapshot([
442+{
443+pluginId: "legacy-sidecar",
444+manifestPath: "/tmp/legacy-sidecar/openclaw.plugin.json",
445+manifestHash: "manifest-hash",
446+rootDir: "/tmp/legacy-sidecar",
447+origin: "workspace",
448+enabled: true,
449+startup: {
450+sidecar: true,
451+memory: false,
452+deferConfiguredChannelFullLoadUntilAfterListen: false,
453+agentHarnesses: [],
454+},
455+compat: ["legacy-implicit-startup-sidecar"],
456+},
457+]),
458+source: "derived",
459+diagnostics: [],
460+});
461+loadPluginManifestRegistryForInstalledIndexMock.mockReturnValue({
462+plugins: [{ id: "legacy-sidecar", name: "Legacy Sidecar" }],
463+diagnostics: [],
464+});
465+466+const report = buildPluginRegistrySnapshotReport({ config: {} });
467+468+expect(report.plugins[0]).toMatchObject({
469+id: "legacy-sidecar",
470+compat: ["legacy-implicit-startup-sidecar"],
471+});
472+});
473+396474it("uses a metadata snapshot load for snapshot reports", () => {
397475buildPluginSnapshotReport({ config: {}, workspaceDir: "/workspace" });
398476@@ -755,6 +833,38 @@ describe("plugin status reports", () => {
755833});
756834});
757835836+it("builds compatibility warnings for deprecated implicit startup sidecar metadata", () => {
837+setSinglePluginLoadResult(
838+createPluginRecord({
839+id: "legacy-sidecar",
840+name: "Legacy Sidecar",
841+compat: ["legacy-implicit-startup-sidecar"],
842+}),
843+);
844+845+expectCompatibilityOutput({
846+notices: [
847+createCompatibilityNotice({
848+pluginId: "legacy-sidecar",
849+code: "legacy-implicit-startup-sidecar",
850+}),
851+],
852+warnings: [`legacy-sidecar ${LEGACY_IMPLICIT_STARTUP_SIDECAR_MESSAGE}`],
853+});
854+});
855+856+it("does not warn when explicit startup-lazy metadata avoids legacy startup compatibility", () => {
857+setSinglePluginLoadResult(
858+createPluginRecord({
859+id: "modern-startup-lazy",
860+name: "Modern Startup Lazy",
861+compat: [],
862+}),
863+);
864+865+expectNoCompatibilityWarnings();
866+});
867+758868it("returns no compatibility warnings for modern capability plugins", () => {
759869setSinglePluginLoadResult(
760870createPluginRecord({
@@ -819,10 +929,14 @@ describe("plugin status reports", () => {
819929expect(
820930summarizePluginCompatibility([
821931notice,
932+createCompatibilityNotice({
933+pluginId: "legacy-plugin",
934+code: "legacy-implicit-startup-sidecar",
935+}),
822936createCompatibilityNotice({ pluginId: "legacy-plugin", code: "hook-only" }),
823937]),
824938).toEqual({
825-noticeCount: 2,
939+noticeCount: 3,
826940pluginCount: 1,
827941});
828942});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。