mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:40:49 +00:00
fix: preserve bundle format in plugin index
This commit is contained in:
@@ -55,6 +55,8 @@ const InstalledPluginIndexRecordSchema = z
|
|||||||
packageInstall: z.unknown().optional(),
|
packageInstall: z.unknown().optional(),
|
||||||
manifestPath: z.string(),
|
manifestPath: z.string(),
|
||||||
manifestHash: z.string(),
|
manifestHash: z.string(),
|
||||||
|
format: z.string().optional(),
|
||||||
|
bundleFormat: z.string().optional(),
|
||||||
source: z.string().optional(),
|
source: z.string().optional(),
|
||||||
setupSource: z.string().optional(),
|
setupSource: z.string().optional(),
|
||||||
packageJson: z
|
packageJson: z
|
||||||
|
|||||||
@@ -66,12 +66,16 @@ function createPluginCandidate(params: {
|
|||||||
packageVersion?: string;
|
packageVersion?: string;
|
||||||
packageDir?: string;
|
packageDir?: string;
|
||||||
packageManifest?: OpenClawPackageManifest;
|
packageManifest?: OpenClawPackageManifest;
|
||||||
|
format?: PluginCandidate["format"];
|
||||||
|
bundleFormat?: PluginCandidate["bundleFormat"];
|
||||||
}): PluginCandidate {
|
}): PluginCandidate {
|
||||||
return {
|
return {
|
||||||
idHint: params.idHint ?? "demo",
|
idHint: params.idHint ?? "demo",
|
||||||
source: path.join(params.rootDir, "index.ts"),
|
source: params.format === "bundle" ? params.rootDir : path.join(params.rootDir, "index.ts"),
|
||||||
rootDir: params.rootDir,
|
rootDir: params.rootDir,
|
||||||
origin: params.origin ?? "global",
|
origin: params.origin ?? "global",
|
||||||
|
format: params.format,
|
||||||
|
bundleFormat: params.bundleFormat,
|
||||||
packageName: params.packageName,
|
packageName: params.packageName,
|
||||||
packageVersion: params.packageVersion,
|
packageVersion: params.packageVersion,
|
||||||
packageDir: params.packageDir ?? params.rootDir,
|
packageDir: params.packageDir ?? params.rootDir,
|
||||||
@@ -198,6 +202,39 @@ describe("installed plugin index", () => {
|
|||||||
expect(index.plugins[0]?.installRecordHash).toBeUndefined();
|
expect(index.plugins[0]?.installRecordHash).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps bundle format metadata needed for manifest reconstruction", () => {
|
||||||
|
const rootDir = makeTempDir();
|
||||||
|
fs.mkdirSync(path.join(rootDir, ".claude-plugin"), { recursive: true });
|
||||||
|
fs.mkdirSync(path.join(rootDir, "commands"), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(rootDir, ".claude-plugin", "plugin.json"),
|
||||||
|
JSON.stringify({
|
||||||
|
name: "Claude Bundle",
|
||||||
|
commands: "commands",
|
||||||
|
}),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
|
||||||
|
const index = loadInstalledPluginIndex({
|
||||||
|
candidates: [
|
||||||
|
createPluginCandidate({
|
||||||
|
rootDir,
|
||||||
|
idHint: "claude-bundle",
|
||||||
|
format: "bundle",
|
||||||
|
bundleFormat: "claude",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
env: hermeticEnv(),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(index.plugins[0]).toMatchObject({
|
||||||
|
pluginId: "claude-bundle",
|
||||||
|
format: "bundle",
|
||||||
|
bundleFormat: "claude",
|
||||||
|
source: rootDir,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("keeps packageJson paths root-relative when packageDir is reached through a symlink", () => {
|
it("keeps packageJson paths root-relative when packageDir is reached through a symlink", () => {
|
||||||
const fixture = createRichPluginFixture();
|
const fixture = createRichPluginFixture();
|
||||||
const linkParent = makeTempDir();
|
const linkParent = makeTempDir();
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ export type InstalledPluginIndexRecord = {
|
|||||||
packageInstall?: PluginInstallSourceInfo;
|
packageInstall?: PluginInstallSourceInfo;
|
||||||
manifestPath: string;
|
manifestPath: string;
|
||||||
manifestHash: string;
|
manifestHash: string;
|
||||||
|
format?: PluginManifestRecord["format"];
|
||||||
|
bundleFormat?: PluginManifestRecord["bundleFormat"];
|
||||||
source?: string;
|
source?: string;
|
||||||
setupSource?: string;
|
setupSource?: string;
|
||||||
packageJson?: {
|
packageJson?: {
|
||||||
@@ -516,6 +518,12 @@ function buildInstalledPluginIndex(
|
|||||||
startup: buildStartupInfo(record),
|
startup: buildStartupInfo(record),
|
||||||
compat: collectCompatCodes(record),
|
compat: collectCompatCodes(record),
|
||||||
};
|
};
|
||||||
|
if (record.format && record.format !== "openclaw") {
|
||||||
|
indexRecord.format = record.format;
|
||||||
|
}
|
||||||
|
if (record.bundleFormat) {
|
||||||
|
indexRecord.bundleFormat = record.bundleFormat;
|
||||||
|
}
|
||||||
if (record.enabledByDefault === true) {
|
if (record.enabledByDefault === true) {
|
||||||
indexRecord.enabledByDefault = true;
|
indexRecord.enabledByDefault = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,4 +89,52 @@ describe("loadPluginManifestRegistryForInstalledIndex", () => {
|
|||||||
modelPrefixes: ["installed-"],
|
modelPrefixes: ["installed-"],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("reconstructs bundle candidates with their bundle manifest format", () => {
|
||||||
|
const rootDir = makeTempDir();
|
||||||
|
fs.mkdirSync(path.join(rootDir, ".claude-plugin"), { recursive: true });
|
||||||
|
fs.mkdirSync(path.join(rootDir, "commands"), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(rootDir, ".claude-plugin", "plugin.json"),
|
||||||
|
JSON.stringify({
|
||||||
|
name: "Claude Bundle",
|
||||||
|
commands: "commands",
|
||||||
|
}),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
|
||||||
|
const index = createIndex(rootDir);
|
||||||
|
const registry = loadPluginManifestRegistryForInstalledIndex({
|
||||||
|
index: {
|
||||||
|
...index,
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
...index.plugins[0],
|
||||||
|
pluginId: "claude-bundle",
|
||||||
|
manifestPath: path.join(rootDir, ".claude-plugin", "plugin.json"),
|
||||||
|
source: rootDir,
|
||||||
|
format: "bundle",
|
||||||
|
bundleFormat: "claude",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE: "1",
|
||||||
|
OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE: "1",
|
||||||
|
OPENCLAW_VERSION: "2026.4.25",
|
||||||
|
VITEST: "true",
|
||||||
|
},
|
||||||
|
includeDisabled: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(registry.diagnostics).toEqual([]);
|
||||||
|
expect(registry.plugins).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "claude-bundle",
|
||||||
|
format: "bundle",
|
||||||
|
bundleFormat: "claude",
|
||||||
|
skills: ["commands"],
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ function toPluginCandidate(record: InstalledPluginIndexRecord): PluginCandidate
|
|||||||
...(record.setupSource ? { setupSource: record.setupSource } : {}),
|
...(record.setupSource ? { setupSource: record.setupSource } : {}),
|
||||||
rootDir: record.rootDir,
|
rootDir: record.rootDir,
|
||||||
origin: record.origin,
|
origin: record.origin,
|
||||||
|
...(record.format ? { format: record.format } : {}),
|
||||||
|
...(record.bundleFormat ? { bundleFormat: record.bundleFormat } : {}),
|
||||||
...(record.packageName ? { packageName: record.packageName } : {}),
|
...(record.packageName ? { packageName: record.packageName } : {}),
|
||||||
...(record.packageVersion ? { packageVersion: record.packageVersion } : {}),
|
...(record.packageVersion ? { packageVersion: record.packageVersion } : {}),
|
||||||
packageDir: record.rootDir,
|
packageDir: record.rootDir,
|
||||||
|
|||||||
Reference in New Issue
Block a user