diff --git a/src/plugins/bundle-manifest.test.ts b/src/plugins/bundle-manifest.test.ts index 542161138cb..c9961c56eeb 100644 --- a/src/plugins/bundle-manifest.test.ts +++ b/src/plugins/bundle-manifest.test.ts @@ -292,6 +292,87 @@ describe("bundle manifest parsing", () => { }); }); + it.each([ + { + name: "accepts JSON5 Codex bundle manifests", + bundleFormat: "codex" as const, + manifestRelativePath: CODEX_BUNDLE_MANIFEST_RELATIVE_PATH, + json5Manifest: `{ + // Bundle name can include comments and trailing commas. + name: "Codex JSON5 Bundle", + skills: "skills", + hooks: "hooks", +}`, + dirs: ["skills", "hooks"], + expected: { + id: "codex-json5-bundle", + name: "Codex JSON5 Bundle", + bundleFormat: "codex", + skills: ["skills"], + hooks: ["hooks"], + }, + }, + { + name: "accepts JSON5 Claude bundle manifests", + bundleFormat: "claude" as const, + manifestRelativePath: CLAUDE_BUNDLE_MANIFEST_RELATIVE_PATH, + json5Manifest: `{ + name: "Claude JSON5 Bundle", + commands: "commands-pack", + hooks: "hooks-pack", + outputStyles: "styles", +}`, + dirs: [".claude-plugin", "commands-pack", "hooks-pack", "styles"], + expected: { + id: "claude-json5-bundle", + name: "Claude JSON5 Bundle", + bundleFormat: "claude", + skills: ["commands-pack", "styles"], + hooks: ["hooks-pack"], + }, + }, + { + name: "accepts JSON5 Cursor bundle manifests", + bundleFormat: "cursor" as const, + manifestRelativePath: CURSOR_BUNDLE_MANIFEST_RELATIVE_PATH, + json5Manifest: `{ + name: "Cursor JSON5 Bundle", + commands: ".cursor/commands", + mcpServers: "./.mcp.json", +}`, + dirs: [".cursor-plugin", "skills", ".cursor/commands"], + textFiles: { + ".mcp.json": "{ servers: {}, }", + }, + expected: { + id: "cursor-json5-bundle", + name: "Cursor JSON5 Bundle", + bundleFormat: "cursor", + skills: ["skills", ".cursor/commands"], + hooks: [], + }, + }, + ] as const)( + "$name", + ({ bundleFormat, manifestRelativePath, json5Manifest, dirs, textFiles, expected }) => { + const rootDir = makeTempDir(); + setupBundleFixture({ + rootDir, + dirs: [path.dirname(manifestRelativePath), ...dirs], + textFiles: { + [manifestRelativePath]: json5Manifest, + ...textFiles, + }, + }); + + expectBundleManifest({ + rootDir, + bundleFormat, + expected, + }); + }, + ); + it.each([ { name: "resolves Claude bundle hooks from default and declared paths",