fix: tolerate stale plugin index channel metadata

This commit is contained in:
Peter Steinberger
2026-04-28 03:23:45 +01:00
parent 28f88ab2cc
commit 4a54682275
2 changed files with 40 additions and 1 deletions

View File

@@ -55,8 +55,9 @@ function hasRuntimeContractSurface(record: PluginManifestRecord): boolean {
* startup decision so Gateway boot can avoid importing inert plugins.
*/
function isLegacyImplicitStartupSidecar(record: PluginManifestRecord): boolean {
const channels = Array.isArray(record.channels) ? record.channels : [];
return (
record.channels.length === 0 &&
channels.length === 0 &&
!hasRuntimeContractSurface(record) &&
record.activation?.onStartup === undefined
);

View File

@@ -2,6 +2,7 @@ import fs from "node:fs";
import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { PluginCandidate } from "./discovery.js";
import { buildInstalledPluginIndexRecords } from "./installed-plugin-index-record-builder.js";
import {
loadInstalledPluginIndexInstallRecordsSync,
writePersistedInstalledPluginIndexInstallRecords,
@@ -16,6 +17,7 @@ import {
refreshInstalledPluginIndex,
} from "./installed-plugin-index.js";
import { recordPluginInstall } from "./installs.js";
import type { PluginManifestRecord } from "./manifest-registry.js";
import type { OpenClawPackageManifest } from "./manifest.js";
import { cleanupTrackedTempDirs, makeTrackedTempDir } from "./test-helpers/fs-fixtures.js";
@@ -289,6 +291,42 @@ describe("installed plugin index", () => {
});
});
it("tolerates stale manifest records without normalized channels", () => {
const rootDir = makeTempDir();
writeRuntimeEntry(rootDir);
const manifestPath = path.join(rootDir, "openclaw.plugin.json");
const records = buildInstalledPluginIndexRecords({
candidates: [createPluginCandidate({ rootDir })],
registry: {
plugins: [
{
id: "stale-record",
providers: [],
cliBackends: [],
skills: [],
hooks: [],
origin: "global",
rootDir,
source: path.join(rootDir, "index.ts"),
manifestPath,
} as unknown as PluginManifestRecord,
],
diagnostics: [],
},
diagnostics: [],
installRecords: {},
});
expect(records[0]).toMatchObject({
pluginId: "stale-record",
startup: {
sidecar: true,
},
compat: ["legacy-implicit-startup-sidecar"],
});
});
it("does not classify or tag explicit startup opt-outs as deprecated implicit sidecars", () => {
const rootDir = makeTempDir();
writeRuntimeEntry(rootDir);