agentpacks 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +8 -1
  2. package/dist/api.js +98 -19
  3. package/dist/cli/export-cmd.js +76 -19
  4. package/dist/cli/generate.js +29 -0
  5. package/dist/cli/install.js +7 -0
  6. package/dist/cli/models-explain.js +7 -0
  7. package/dist/cli/pack/list.js +7 -0
  8. package/dist/cli/pack/validate.js +7 -0
  9. package/dist/cli/publish.js +7 -0
  10. package/dist/core/config.d.ts +7 -0
  11. package/dist/core/config.js +7 -0
  12. package/dist/core/index.js +7 -0
  13. package/dist/core/metarepo.js +7 -0
  14. package/dist/core/pack-loader.js +7 -0
  15. package/dist/exporters/cursor-plugin.d.ts +18 -18
  16. package/dist/exporters/cursor-plugin.js +117 -29
  17. package/dist/exporters/index.js +117 -29
  18. package/dist/index.js +98 -19
  19. package/dist/node/api.js +98 -19
  20. package/dist/node/cli/export-cmd.js +76 -19
  21. package/dist/node/cli/generate.js +29 -0
  22. package/dist/node/cli/install.js +7 -0
  23. package/dist/node/cli/models-explain.js +7 -0
  24. package/dist/node/cli/pack/list.js +7 -0
  25. package/dist/node/cli/pack/validate.js +7 -0
  26. package/dist/node/cli/publish.js +7 -0
  27. package/dist/node/core/config.js +7 -0
  28. package/dist/node/core/index.js +7 -0
  29. package/dist/node/core/metarepo.js +7 -0
  30. package/dist/node/core/pack-loader.js +7 -0
  31. package/dist/node/exporters/cursor-plugin.js +117 -29
  32. package/dist/node/exporters/index.js +117 -29
  33. package/dist/node/index.js +98 -19
  34. package/dist/node/targets/cursor.js +67 -7
  35. package/dist/node/targets/index.js +22 -0
  36. package/dist/node/targets/registry.js +22 -0
  37. package/dist/targets/cursor.d.ts +1 -1
  38. package/dist/targets/cursor.js +67 -7
  39. package/dist/targets/index.js +22 -0
  40. package/dist/targets/registry.js +22 -0
  41. package/package.json +4 -4
package/README.md CHANGED
@@ -256,10 +256,17 @@ Options:
256
256
  ```
257
257
 
258
258
  ```bash
259
- # Export all packs as a single Cursor plugin
259
+ # Export all packs as Cursor plugins
260
260
  agentpacks export --format cursor-plugin --output ./cursor-plugin-dist
261
261
  ```
262
262
 
263
+ Each exported plugin follows Cursor's native plugin layout:
264
+
265
+ - `.cursor-plugin/plugin.json`
266
+ - `rules/*.mdc`, `agents/*.md`, `skills/*/SKILL.md`, `commands/*.md`
267
+ - `hooks/hooks.json` (when hooks are defined)
268
+ - `.mcp.json` (when MCP servers are defined)
269
+
263
270
  ---
264
271
 
265
272
  ### `agentpacks pack create <name>`
package/dist/api.js CHANGED
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -1910,6 +1917,28 @@ class CursorTarget extends BaseTarget {
1910
1917
  filesWritten.push(filepath);
1911
1918
  }
1912
1919
  }
1920
+ if (effective.includes("hooks")) {
1921
+ const hooksFilepath = resolve8(cursorDir, "hooks.json");
1922
+ if (deleteExisting) {
1923
+ removeIfExists(hooksFilepath);
1924
+ filesDeleted.push(hooksFilepath);
1925
+ }
1926
+ const mergedHooks = {};
1927
+ for (const hookSet of features.hooks) {
1928
+ const events = resolveHooksForTarget(hookSet, TARGET_ID2);
1929
+ for (const [event, entries] of Object.entries(events)) {
1930
+ if (!mergedHooks[event]) {
1931
+ mergedHooks[event] = [];
1932
+ }
1933
+ mergedHooks[event].push(...entries);
1934
+ }
1935
+ }
1936
+ if (Object.keys(mergedHooks).length > 0) {
1937
+ const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
1938
+ writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
1939
+ filesWritten.push(hooksFilepath);
1940
+ }
1941
+ }
1913
1942
  if (effective.includes("mcp")) {
1914
1943
  const mcpEntries = Object.entries(features.mcpServers);
1915
1944
  if (mcpEntries.length > 0) {
@@ -2777,23 +2806,41 @@ import { resolve as resolve15, join as join17 } from "path";
2777
2806
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
2778
2807
  function exportCursorPlugin(pack, outputDir) {
2779
2808
  const filesWritten = [];
2780
- const pluginDir = resolve15(outputDir, pack.manifest.name);
2809
+ const pluginName = normalizeCursorPluginName(pack.manifest.name);
2810
+ const pluginDir = resolve15(outputDir, pluginName);
2781
2811
  mkdirSync4(pluginDir, { recursive: true });
2782
2812
  const manifest = {
2783
- name: pack.manifest.name,
2784
- version: pack.manifest.version,
2785
- description: pack.manifest.description
2813
+ name: pluginName
2786
2814
  };
2787
- if (pack.manifest.author) {
2788
- manifest.author = typeof pack.manifest.author === "string" ? pack.manifest.author : pack.manifest.author.name;
2815
+ if (pack.manifest.version) {
2816
+ manifest.version = pack.manifest.version;
2817
+ }
2818
+ if (pack.manifest.description) {
2819
+ manifest.description = pack.manifest.description;
2820
+ }
2821
+ const author = toCursorPluginAuthor(pack.manifest.author);
2822
+ if (author) {
2823
+ manifest.author = author;
2824
+ }
2825
+ if (pack.manifest.homepage) {
2826
+ manifest.homepage = pack.manifest.homepage;
2827
+ }
2828
+ if (pack.manifest.repository) {
2829
+ manifest.repository = typeof pack.manifest.repository === "string" ? pack.manifest.repository : pack.manifest.repository.url;
2830
+ }
2831
+ if (pack.manifest.license) {
2832
+ manifest.license = pack.manifest.license;
2833
+ }
2834
+ if (pack.manifest.logo) {
2835
+ manifest.logo = pack.manifest.logo;
2789
2836
  }
2790
2837
  if (pack.manifest.tags.length > 0) {
2791
- manifest.tags = pack.manifest.tags;
2838
+ manifest.keywords = pack.manifest.tags;
2792
2839
  }
2793
2840
  if (pack.rules.length > 0) {
2794
2841
  const rulesDir = join17(pluginDir, "rules");
2795
2842
  ensureDir(rulesDir);
2796
- manifest.rules = [];
2843
+ manifest.rules = "rules";
2797
2844
  for (const rule of pack.rules) {
2798
2845
  const cursorMeta = rule.meta.cursor ?? {};
2799
2846
  const fm = {
@@ -2807,13 +2854,12 @@ function exportCursorPlugin(pack, outputDir) {
2807
2854
  const filepath = join17(rulesDir, filename);
2808
2855
  writeFileSync4(filepath, serializeFrontmatter(fm, rule.content));
2809
2856
  filesWritten.push(filepath);
2810
- manifest.rules.push(filename);
2811
2857
  }
2812
2858
  }
2813
2859
  if (pack.agents.length > 0) {
2814
2860
  const agentsDir = join17(pluginDir, "agents");
2815
2861
  ensureDir(agentsDir);
2816
- manifest.agents = [];
2862
+ manifest.agents = "agents";
2817
2863
  for (const agent of pack.agents) {
2818
2864
  const fm = {
2819
2865
  name: agent.name,
@@ -2823,13 +2869,12 @@ function exportCursorPlugin(pack, outputDir) {
2823
2869
  const filepath = join17(agentsDir, filename);
2824
2870
  writeFileSync4(filepath, serializeFrontmatter(fm, agent.content));
2825
2871
  filesWritten.push(filepath);
2826
- manifest.agents.push(filename);
2827
2872
  }
2828
2873
  }
2829
2874
  if (pack.skills.length > 0) {
2830
2875
  const skillsDir = join17(pluginDir, "skills");
2831
2876
  ensureDir(skillsDir);
2832
- manifest.skills = [];
2877
+ manifest.skills = "skills";
2833
2878
  for (const skill of pack.skills) {
2834
2879
  const skillSubDir = join17(skillsDir, skill.name);
2835
2880
  ensureDir(skillSubDir);
@@ -2840,34 +2885,68 @@ function exportCursorPlugin(pack, outputDir) {
2840
2885
  const filepath = join17(skillSubDir, "SKILL.md");
2841
2886
  writeFileSync4(filepath, serializeFrontmatter(fm, skill.content));
2842
2887
  filesWritten.push(filepath);
2843
- manifest.skills.push(skill.name);
2844
2888
  }
2845
2889
  }
2846
2890
  if (pack.commands.length > 0) {
2847
2891
  const commandsDir = join17(pluginDir, "commands");
2848
2892
  ensureDir(commandsDir);
2849
- manifest.commands = [];
2893
+ manifest.commands = "commands";
2850
2894
  for (const cmd of pack.commands) {
2895
+ const fm = {
2896
+ name: cmd.name
2897
+ };
2898
+ if (cmd.meta.description) {
2899
+ fm.description = cmd.meta.description;
2900
+ }
2851
2901
  const filename = `${cmd.name}.md`;
2852
2902
  const filepath = join17(commandsDir, filename);
2853
- writeFileSync4(filepath, cmd.content);
2903
+ writeFileSync4(filepath, serializeFrontmatter(fm, cmd.content));
2904
+ filesWritten.push(filepath);
2905
+ }
2906
+ }
2907
+ if (pack.hooks) {
2908
+ const events = resolveHooksForTarget(pack.hooks, "cursor");
2909
+ if (Object.keys(events).length > 0) {
2910
+ const hooksDir = join17(pluginDir, "hooks");
2911
+ ensureDir(hooksDir);
2912
+ const filepath = join17(hooksDir, "hooks.json");
2913
+ writeFileSync4(filepath, JSON.stringify({ version: pack.hooks.version ?? 1, hooks: events }, null, 2) + `
2914
+ `);
2854
2915
  filesWritten.push(filepath);
2855
- manifest.commands.push(filename);
2916
+ manifest.hooks = "hooks/hooks.json";
2856
2917
  }
2857
2918
  }
2858
2919
  if (pack.mcp && Object.keys(pack.mcp.servers).length > 0) {
2859
- manifest.mcp = true;
2860
- const filepath = join17(pluginDir, "mcp.json");
2920
+ manifest.mcpServers = ".mcp.json";
2921
+ const filepath = join17(pluginDir, ".mcp.json");
2861
2922
  writeFileSync4(filepath, JSON.stringify({ mcpServers: pack.mcp.servers }, null, 2) + `
2862
2923
  `);
2863
2924
  filesWritten.push(filepath);
2864
2925
  }
2865
- const manifestPath = join17(pluginDir, "manifest.json");
2926
+ const manifestDir = join17(pluginDir, ".cursor-plugin");
2927
+ ensureDir(manifestDir);
2928
+ const manifestPath = join17(manifestDir, "plugin.json");
2866
2929
  writeFileSync4(manifestPath, JSON.stringify(manifest, null, 2) + `
2867
2930
  `);
2868
2931
  filesWritten.push(manifestPath);
2869
2932
  return { outputDir: pluginDir, filesWritten, manifest };
2870
2933
  }
2934
+ function normalizeCursorPluginName(name) {
2935
+ const normalized = name.toLowerCase().replace(/[^a-z0-9.-]+/g, "-").replace(/-+/g, "-").replace(/^[^a-z0-9]+/, "").replace(/[^a-z0-9]+$/, "");
2936
+ return normalized.length > 0 ? normalized : "agentpacks-plugin";
2937
+ }
2938
+ function toCursorPluginAuthor(author) {
2939
+ if (!author) {
2940
+ return null;
2941
+ }
2942
+ if (typeof author === "string") {
2943
+ return { name: author };
2944
+ }
2945
+ return {
2946
+ name: author.name,
2947
+ ...author.email ? { email: author.email } : {}
2948
+ };
2949
+ }
2871
2950
 
2872
2951
  // src/importers/rulesync.ts
2873
2952
  import { existsSync as existsSync10, readFileSync as readFileSync10, copyFileSync, writeFileSync as writeFileSync5 } from "fs";
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -780,23 +787,41 @@ import { resolve as resolve3, join as join8 } from "path";
780
787
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
781
788
  function exportCursorPlugin(pack, outputDir) {
782
789
  const filesWritten = [];
783
- const pluginDir = resolve3(outputDir, pack.manifest.name);
790
+ const pluginName = normalizeCursorPluginName(pack.manifest.name);
791
+ const pluginDir = resolve3(outputDir, pluginName);
784
792
  mkdirSync2(pluginDir, { recursive: true });
785
793
  const manifest = {
786
- name: pack.manifest.name,
787
- version: pack.manifest.version,
788
- description: pack.manifest.description
794
+ name: pluginName
789
795
  };
790
- if (pack.manifest.author) {
791
- manifest.author = typeof pack.manifest.author === "string" ? pack.manifest.author : pack.manifest.author.name;
796
+ if (pack.manifest.version) {
797
+ manifest.version = pack.manifest.version;
798
+ }
799
+ if (pack.manifest.description) {
800
+ manifest.description = pack.manifest.description;
801
+ }
802
+ const author = toCursorPluginAuthor(pack.manifest.author);
803
+ if (author) {
804
+ manifest.author = author;
805
+ }
806
+ if (pack.manifest.homepage) {
807
+ manifest.homepage = pack.manifest.homepage;
808
+ }
809
+ if (pack.manifest.repository) {
810
+ manifest.repository = typeof pack.manifest.repository === "string" ? pack.manifest.repository : pack.manifest.repository.url;
811
+ }
812
+ if (pack.manifest.license) {
813
+ manifest.license = pack.manifest.license;
814
+ }
815
+ if (pack.manifest.logo) {
816
+ manifest.logo = pack.manifest.logo;
792
817
  }
793
818
  if (pack.manifest.tags.length > 0) {
794
- manifest.tags = pack.manifest.tags;
819
+ manifest.keywords = pack.manifest.tags;
795
820
  }
796
821
  if (pack.rules.length > 0) {
797
822
  const rulesDir = join8(pluginDir, "rules");
798
823
  ensureDir(rulesDir);
799
- manifest.rules = [];
824
+ manifest.rules = "rules";
800
825
  for (const rule of pack.rules) {
801
826
  const cursorMeta = rule.meta.cursor ?? {};
802
827
  const fm = {
@@ -810,13 +835,12 @@ function exportCursorPlugin(pack, outputDir) {
810
835
  const filepath = join8(rulesDir, filename);
811
836
  writeFileSync2(filepath, serializeFrontmatter(fm, rule.content));
812
837
  filesWritten.push(filepath);
813
- manifest.rules.push(filename);
814
838
  }
815
839
  }
816
840
  if (pack.agents.length > 0) {
817
841
  const agentsDir = join8(pluginDir, "agents");
818
842
  ensureDir(agentsDir);
819
- manifest.agents = [];
843
+ manifest.agents = "agents";
820
844
  for (const agent of pack.agents) {
821
845
  const fm = {
822
846
  name: agent.name,
@@ -826,13 +850,12 @@ function exportCursorPlugin(pack, outputDir) {
826
850
  const filepath = join8(agentsDir, filename);
827
851
  writeFileSync2(filepath, serializeFrontmatter(fm, agent.content));
828
852
  filesWritten.push(filepath);
829
- manifest.agents.push(filename);
830
853
  }
831
854
  }
832
855
  if (pack.skills.length > 0) {
833
856
  const skillsDir = join8(pluginDir, "skills");
834
857
  ensureDir(skillsDir);
835
- manifest.skills = [];
858
+ manifest.skills = "skills";
836
859
  for (const skill of pack.skills) {
837
860
  const skillSubDir = join8(skillsDir, skill.name);
838
861
  ensureDir(skillSubDir);
@@ -843,34 +866,68 @@ function exportCursorPlugin(pack, outputDir) {
843
866
  const filepath = join8(skillSubDir, "SKILL.md");
844
867
  writeFileSync2(filepath, serializeFrontmatter(fm, skill.content));
845
868
  filesWritten.push(filepath);
846
- manifest.skills.push(skill.name);
847
869
  }
848
870
  }
849
871
  if (pack.commands.length > 0) {
850
872
  const commandsDir = join8(pluginDir, "commands");
851
873
  ensureDir(commandsDir);
852
- manifest.commands = [];
874
+ manifest.commands = "commands";
853
875
  for (const cmd of pack.commands) {
876
+ const fm = {
877
+ name: cmd.name
878
+ };
879
+ if (cmd.meta.description) {
880
+ fm.description = cmd.meta.description;
881
+ }
854
882
  const filename = `${cmd.name}.md`;
855
883
  const filepath = join8(commandsDir, filename);
856
- writeFileSync2(filepath, cmd.content);
884
+ writeFileSync2(filepath, serializeFrontmatter(fm, cmd.content));
857
885
  filesWritten.push(filepath);
858
- manifest.commands.push(filename);
886
+ }
887
+ }
888
+ if (pack.hooks) {
889
+ const events = resolveHooksForTarget(pack.hooks, "cursor");
890
+ if (Object.keys(events).length > 0) {
891
+ const hooksDir = join8(pluginDir, "hooks");
892
+ ensureDir(hooksDir);
893
+ const filepath = join8(hooksDir, "hooks.json");
894
+ writeFileSync2(filepath, JSON.stringify({ version: pack.hooks.version ?? 1, hooks: events }, null, 2) + `
895
+ `);
896
+ filesWritten.push(filepath);
897
+ manifest.hooks = "hooks/hooks.json";
859
898
  }
860
899
  }
861
900
  if (pack.mcp && Object.keys(pack.mcp.servers).length > 0) {
862
- manifest.mcp = true;
863
- const filepath = join8(pluginDir, "mcp.json");
901
+ manifest.mcpServers = ".mcp.json";
902
+ const filepath = join8(pluginDir, ".mcp.json");
864
903
  writeFileSync2(filepath, JSON.stringify({ mcpServers: pack.mcp.servers }, null, 2) + `
865
904
  `);
866
905
  filesWritten.push(filepath);
867
906
  }
868
- const manifestPath = join8(pluginDir, "manifest.json");
907
+ const manifestDir = join8(pluginDir, ".cursor-plugin");
908
+ ensureDir(manifestDir);
909
+ const manifestPath = join8(manifestDir, "plugin.json");
869
910
  writeFileSync2(manifestPath, JSON.stringify(manifest, null, 2) + `
870
911
  `);
871
912
  filesWritten.push(manifestPath);
872
913
  return { outputDir: pluginDir, filesWritten, manifest };
873
914
  }
915
+ function normalizeCursorPluginName(name) {
916
+ const normalized = name.toLowerCase().replace(/[^a-z0-9.-]+/g, "-").replace(/-+/g, "-").replace(/^[^a-z0-9]+/, "").replace(/[^a-z0-9]+$/, "");
917
+ return normalized.length > 0 ? normalized : "agentpacks-plugin";
918
+ }
919
+ function toCursorPluginAuthor(author) {
920
+ if (!author) {
921
+ return null;
922
+ }
923
+ if (typeof author === "string") {
924
+ return { name: author };
925
+ }
926
+ return {
927
+ name: author.name,
928
+ ...author.email ? { email: author.email } : {}
929
+ };
930
+ }
874
931
 
875
932
  // src/cli/export-cmd.ts
876
933
  import { resolve as resolve4 } from "path";
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -1383,6 +1390,28 @@ class CursorTarget extends BaseTarget {
1383
1390
  filesWritten.push(filepath);
1384
1391
  }
1385
1392
  }
1393
+ if (effective.includes("hooks")) {
1394
+ const hooksFilepath = resolve4(cursorDir, "hooks.json");
1395
+ if (deleteExisting) {
1396
+ removeIfExists(hooksFilepath);
1397
+ filesDeleted.push(hooksFilepath);
1398
+ }
1399
+ const mergedHooks = {};
1400
+ for (const hookSet of features.hooks) {
1401
+ const events = resolveHooksForTarget(hookSet, TARGET_ID2);
1402
+ for (const [event, entries] of Object.entries(events)) {
1403
+ if (!mergedHooks[event]) {
1404
+ mergedHooks[event] = [];
1405
+ }
1406
+ mergedHooks[event].push(...entries);
1407
+ }
1408
+ }
1409
+ if (Object.keys(mergedHooks).length > 0) {
1410
+ const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
1411
+ writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
1412
+ filesWritten.push(hooksFilepath);
1413
+ }
1414
+ }
1386
1415
  if (effective.includes("mcp")) {
1387
1416
  const mcpEntries = Object.entries(features.mcpServers);
1388
1417
  if (mcpEntries.length > 0) {
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -25,6 +25,13 @@ export declare const PackManifestSchema: z.ZodObject<{
25
25
  name: z.ZodString;
26
26
  email: z.ZodOptional<z.ZodString>;
27
27
  }, z.core.$strip>]>>;
28
+ homepage: z.ZodOptional<z.ZodString>;
29
+ repository: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
30
+ url: z.ZodString;
31
+ type: z.ZodOptional<z.ZodString>;
32
+ }, z.core.$strip>]>>;
33
+ license: z.ZodOptional<z.ZodString>;
34
+ logo: z.ZodOptional<z.ZodString>;
28
35
  tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
29
36
  dependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
30
37
  conflicts: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -48,6 +48,13 @@ var PackManifestSchema = z.object({
48
48
  z.string(),
49
49
  z.object({ name: z.string(), email: z.string().optional() })
50
50
  ]).optional(),
51
+ homepage: z.string().optional(),
52
+ repository: z.union([
53
+ z.string(),
54
+ z.object({ url: z.string(), type: z.string().optional() })
55
+ ]).optional(),
56
+ license: z.string().optional(),
57
+ logo: z.string().optional(),
51
58
  tags: z.array(z.string()).default([]),
52
59
  dependencies: z.array(z.string()).default([]),
53
60
  conflicts: z.array(z.string()).default([]),
@@ -1,29 +1,29 @@
1
1
  import type { LoadedPack } from '../core/pack-loader.js';
2
- /**
3
- * Cursor plugin manifest shape.
4
- */
2
+ interface CursorPluginAuthor {
3
+ name: string;
4
+ email?: string;
5
+ }
5
6
  interface CursorPluginManifest {
6
7
  name: string;
7
- version: string;
8
- description: string;
9
- author?: string;
10
- tags?: string[];
11
- rules?: string[];
12
- agents?: string[];
13
- skills?: string[];
14
- commands?: string[];
15
- mcp?: boolean;
8
+ version?: string;
9
+ description?: string;
10
+ author?: CursorPluginAuthor;
11
+ homepage?: string;
12
+ repository?: string;
13
+ license?: string;
14
+ logo?: string;
15
+ keywords?: string[];
16
+ rules?: string | string[];
17
+ agents?: string | string[];
18
+ skills?: string | string[];
19
+ commands?: string | string[];
20
+ hooks?: string | Record<string, unknown>;
21
+ mcpServers?: string | Record<string, unknown> | (string | Record<string, unknown>)[];
16
22
  }
17
- /**
18
- * Export result.
19
- */
20
23
  export interface CursorPluginExportResult {
21
24
  outputDir: string;
22
25
  filesWritten: string[];
23
26
  manifest: CursorPluginManifest;
24
27
  }
25
- /**
26
- * Export a loaded pack as a Cursor plugin directory.
27
- */
28
28
  export declare function exportCursorPlugin(pack: LoadedPack, outputDir: string): CursorPluginExportResult;
29
29
  export {};