prpm 1.1.1 → 1.1.3

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.
package/dist/index.js CHANGED
@@ -83,7 +83,8 @@ function addToLockfile(lockfile, packageId, packageInfo) {
83
83
  sourceSubtype: packageInfo.sourceSubtype,
84
84
  installedPath: packageInfo.installedPath,
85
85
  fromCollection: packageInfo.fromCollection,
86
- hookMetadata: packageInfo.hookMetadata
86
+ hookMetadata: packageInfo.hookMetadata,
87
+ progressiveDisclosure: packageInfo.progressiveDisclosure
87
88
  };
88
89
  lockfile.generated = (/* @__PURE__ */ new Date()).toISOString();
89
90
  }
@@ -494,10 +495,31 @@ function getDestinationDir2(format, subtype, name) {
494
495
  return ".github/instructions";
495
496
  case "kiro":
496
497
  if (subtype === "hook") return ".kiro/hooks";
498
+ if (subtype === "agent") return ".kiro/agents";
497
499
  return ".kiro/steering";
498
500
  case "gemini":
499
501
  return ".gemini/commands";
502
+ case "opencode":
503
+ if (subtype === "agent") return ".opencode/agent";
504
+ if (subtype === "slash-command") return ".opencode/command";
505
+ if (subtype === "tool") return ".opencode/tool";
506
+ return ".opencode/agent";
507
+ case "droid":
508
+ if (subtype === "skill" && packageName) return `.factory/skills/${packageName}`;
509
+ if (subtype === "skill") return ".factory/skills";
510
+ if (subtype === "slash-command") return ".factory/commands";
511
+ if (subtype === "hook") return ".factory/hooks";
512
+ return ".factory/skills";
513
+ // Default to skills
500
514
  case "agents.md":
515
+ case "gemini.md":
516
+ case "claude.md":
517
+ if (subtype === "skill" && packageName) {
518
+ return `.openskills/${packageName}`;
519
+ }
520
+ if (subtype === "agent" && packageName) {
521
+ return `.openagents/${packageName}`;
522
+ }
501
523
  return ".";
502
524
  case "generic":
503
525
  return ".prompts";
@@ -539,7 +561,25 @@ async function directoryExists(dirPath) {
539
561
  return false;
540
562
  }
541
563
  }
564
+ function getManifestFilename(format) {
565
+ switch (format) {
566
+ case "agents.md":
567
+ return "AGENTS.md";
568
+ case "gemini.md":
569
+ return "GEMINI.md";
570
+ case "claude.md":
571
+ return "CLAUDE.md";
572
+ default:
573
+ return "AGENTS.md";
574
+ }
575
+ }
542
576
  async function autoDetectFormat() {
577
+ if (await fileExists("GEMINI.md")) {
578
+ return "gemini.md";
579
+ }
580
+ if (await fileExists("CLAUDE.md")) {
581
+ return "claude.md";
582
+ }
543
583
  if (await fileExists("AGENTS.md")) {
544
584
  return "agents.md";
545
585
  }
@@ -551,6 +591,8 @@ async function autoDetectFormat() {
551
591
  { format: "copilot", dir: ".github/instructions" },
552
592
  { format: "kiro", dir: ".kiro" },
553
593
  { format: "gemini", dir: ".gemini" },
594
+ { format: "opencode", dir: ".opencode" },
595
+ { format: "droid", dir: ".factory" },
554
596
  { format: "agents.md", dir: ".agents" }
555
597
  ];
556
598
  for (const { format, dir } of formatDirs) {
@@ -581,6 +623,237 @@ var init_filesystem = __esm({
581
623
  }
582
624
  });
583
625
 
626
+ // src/core/agents-md-progressive.ts
627
+ function generateSkillXML(entry) {
628
+ const resourceType = entry.resourceType || "skill";
629
+ const tag = resourceType === "agent" ? "agent" : "skill";
630
+ const mainFile = entry.mainFile || (resourceType === "agent" ? "AGENT.md" : "SKILL.md");
631
+ const fullPath = import_path6.default.join(entry.skillPath, mainFile);
632
+ return `<${tag}>
633
+ <name>${escapeXML(entry.name)}</name>
634
+ <description>${escapeXML(entry.description)}</description>
635
+ <path>${escapeXML(fullPath)}</path>
636
+ </${tag}>`;
637
+ }
638
+ function generateSkillsSystemHeader() {
639
+ return `<!-- PRPM_MANIFEST_START -->
640
+
641
+ <skills_system priority="1">
642
+ <usage>
643
+ When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
644
+
645
+ How to use skills (loaded into main context):
646
+ - Use the <path> from the skill entry below
647
+ - Invoke: Bash("cat <path>")
648
+ - The skill content will load into your current context
649
+ - Example: Bash("cat .openskills/backend-architect/SKILL.md")
650
+
651
+ Usage notes:
652
+ - Skills share your context window
653
+ - Do not invoke a skill that is already loaded in your context
654
+ </usage>
655
+
656
+ <available_skills>`;
657
+ }
658
+ function generateAgentsSystemHeader() {
659
+ return `<agents_system priority="1">
660
+ <usage>
661
+ Agents are specialized AI assistants that run in independent contexts for complex multi-step tasks.
662
+
663
+ How to use agents (spawned with independent context):
664
+ - The <path> from the agent entry contains the agent definition file
665
+ - The agent definition will be automatically loaded into the subagent's context
666
+ - Invoke: Task(subagent_type="<agent-name>", prompt="task description")
667
+ - The agent runs in a separate context and returns results
668
+ - Example: Task(subagent_type="code-reviewer", prompt="Review the authentication code in auth.ts")
669
+
670
+ Usage notes:
671
+ - Agents have independent context windows
672
+ - Each agent invocation is stateless
673
+ - Agents are spawned as subprocesses via the Task tool
674
+ - The agent's AGENT.md file is loaded into the subagent's context automatically
675
+ </usage>
676
+
677
+ <available_agents>`;
678
+ }
679
+ function generateManifestFooter(hasAgents, agentsXML) {
680
+ let footer = "</available_skills>\n</skills_system>";
681
+ if (hasAgents && agentsXML) {
682
+ footer += "\n\n" + generateAgentsSystemHeader();
683
+ footer += `
684
+
685
+ ${agentsXML}
686
+
687
+ `;
688
+ footer += "</available_agents>\n</agents_system>";
689
+ }
690
+ footer += "\n\n<!-- PRPM_MANIFEST_END -->";
691
+ return footer;
692
+ }
693
+ async function readAgentsMdManifest(agentsPath = "AGENTS.md") {
694
+ if (!await fileExists(agentsPath)) {
695
+ return {
696
+ beforeManifest: "",
697
+ manifest: "",
698
+ afterManifest: ""
699
+ };
700
+ }
701
+ const content = await import_fs6.promises.readFile(agentsPath, "utf-8");
702
+ let manifestStart = "<!-- PRPM_MANIFEST_START -->";
703
+ let manifestEnd = "<!-- PRPM_MANIFEST_END -->";
704
+ let startIdx = content.indexOf(manifestStart);
705
+ let endIdx = content.indexOf(manifestEnd);
706
+ if (startIdx === -1 || endIdx === -1) {
707
+ manifestStart = "<!-- SKILLS_TABLE_START -->";
708
+ manifestEnd = "<!-- SKILLS_TABLE_END -->";
709
+ startIdx = content.indexOf(manifestStart);
710
+ endIdx = content.indexOf(manifestEnd);
711
+ }
712
+ if (startIdx === -1 || endIdx === -1) {
713
+ manifestStart = "<!-- PRPM Manifest -->";
714
+ manifestEnd = "<!-- End PRPM Manifest -->";
715
+ startIdx = content.indexOf(manifestStart);
716
+ endIdx = content.indexOf(manifestEnd);
717
+ }
718
+ if (startIdx === -1 || endIdx === -1) {
719
+ return {
720
+ beforeManifest: content,
721
+ manifest: "",
722
+ afterManifest: ""
723
+ };
724
+ }
725
+ const beforeManifest = content.substring(0, startIdx);
726
+ const manifest = content.substring(
727
+ startIdx + manifestStart.length,
728
+ endIdx
729
+ ).trim();
730
+ const afterManifest = content.substring(endIdx + manifestEnd.length);
731
+ return {
732
+ beforeManifest,
733
+ manifest,
734
+ afterManifest
735
+ };
736
+ }
737
+ async function addSkillToManifest(entry, agentsPath = "AGENTS.md") {
738
+ const { beforeManifest, manifest, afterManifest } = await readAgentsMdManifest(agentsPath);
739
+ const existingResources = parseSkillsFromManifest(manifest);
740
+ const updatedResources = existingResources.filter((s) => s.name !== entry.name);
741
+ updatedResources.push(entry);
742
+ const skills = updatedResources.filter((r) => (r.resourceType || "skill") === "skill");
743
+ const agents = updatedResources.filter((r) => r.resourceType === "agent");
744
+ const skillsXML = skills.map((s) => generateSkillXML(s)).join("\n\n");
745
+ const agentsXML = agents.length > 0 ? agents.map((a) => generateSkillXML(a)).join("\n\n") : void 0;
746
+ let newContent = "";
747
+ if (!beforeManifest.trim() && !afterManifest.trim()) {
748
+ newContent = "";
749
+ } else {
750
+ newContent = beforeManifest;
751
+ }
752
+ const hasAgents = agents.length > 0;
753
+ newContent += generateSkillsSystemHeader();
754
+ newContent += "\n\n";
755
+ newContent += skillsXML;
756
+ newContent += "\n\n";
757
+ newContent += generateManifestFooter(hasAgents, agentsXML);
758
+ newContent += afterManifest;
759
+ await import_fs6.promises.writeFile(agentsPath, newContent.trim() + "\n", "utf-8");
760
+ }
761
+ async function removeSkillFromManifest(skillName, agentsPath = "AGENTS.md") {
762
+ const { beforeManifest, manifest, afterManifest } = await readAgentsMdManifest(agentsPath);
763
+ if (!manifest) {
764
+ return;
765
+ }
766
+ const existingResources = parseSkillsFromManifest(manifest);
767
+ const updatedResources = existingResources.filter((s) => s.name !== skillName);
768
+ if (updatedResources.length === 0) {
769
+ const newContent2 = (beforeManifest + afterManifest).trim();
770
+ if (newContent2) {
771
+ await import_fs6.promises.writeFile(agentsPath, newContent2 + "\n", "utf-8");
772
+ } else {
773
+ await import_fs6.promises.unlink(agentsPath);
774
+ }
775
+ return;
776
+ }
777
+ const skills = updatedResources.filter((r) => (r.resourceType || "skill") === "skill");
778
+ const agents = updatedResources.filter((r) => r.resourceType === "agent");
779
+ const skillsXML = skills.map((s) => generateSkillXML(s)).join("\n\n");
780
+ const agentsXML = agents.length > 0 ? agents.map((a) => generateSkillXML(a)).join("\n\n") : void 0;
781
+ const hasAgents = agents.length > 0;
782
+ let newContent = beforeManifest;
783
+ newContent += generateSkillsSystemHeader();
784
+ newContent += "\n\n";
785
+ newContent += skillsXML;
786
+ newContent += "\n\n";
787
+ newContent += generateManifestFooter(hasAgents, agentsXML);
788
+ newContent += afterManifest;
789
+ await import_fs6.promises.writeFile(agentsPath, newContent.trim() + "\n", "utf-8");
790
+ }
791
+ function parseSkillsFromManifest(manifestXML) {
792
+ const resources = [];
793
+ const skillFormatRegex = /<skill>\s*<name>([^<]+)<\/name>\s*<description>([^<]+)<\/description>\s*<path>([^<]+)<\/path>\s*<\/skill>/g;
794
+ let match;
795
+ while ((match = skillFormatRegex.exec(manifestXML)) !== null) {
796
+ const [, name, description, fullPath] = match;
797
+ const pathParts = fullPath.trim().split("/");
798
+ const mainFile = pathParts[pathParts.length - 1];
799
+ const dir = pathParts.slice(0, -1).join("/");
800
+ resources.push({
801
+ name: unescapeXML(name.trim()),
802
+ description: unescapeXML(description.trim()),
803
+ skillPath: dir,
804
+ mainFile,
805
+ resourceType: "skill"
806
+ });
807
+ }
808
+ const agentFormatRegex = /<agent>\s*<name>([^<]+)<\/name>\s*<description>([^<]+)<\/description>\s*<path>([^<]+)<\/path>\s*<\/agent>/g;
809
+ while ((match = agentFormatRegex.exec(manifestXML)) !== null) {
810
+ const [, name, description, fullPath] = match;
811
+ const pathParts = fullPath.trim().split("/");
812
+ const mainFile = pathParts[pathParts.length - 1];
813
+ const dir = pathParts.slice(0, -1).join("/");
814
+ resources.push({
815
+ name: unescapeXML(name.trim()),
816
+ description: unescapeXML(description.trim()),
817
+ skillPath: dir,
818
+ mainFile,
819
+ resourceType: "agent"
820
+ });
821
+ }
822
+ if (resources.length === 0) {
823
+ const legacyRegex = /<skill\s+name="([^"]+)"\s+path="([^"]+)">([^<]*)<\/skill>/g;
824
+ while ((match = legacyRegex.exec(manifestXML)) !== null) {
825
+ const [, name, skillPath, description] = match;
826
+ const pathParts = skillPath.split("/");
827
+ const mainFile = pathParts[pathParts.length - 1];
828
+ const dir = pathParts.slice(0, -1).join("/");
829
+ resources.push({
830
+ name: unescapeXML(name),
831
+ description: unescapeXML(description.trim()),
832
+ skillPath: dir,
833
+ mainFile,
834
+ resourceType: "skill"
835
+ });
836
+ }
837
+ }
838
+ return resources;
839
+ }
840
+ function escapeXML(str2) {
841
+ return str2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
842
+ }
843
+ function unescapeXML(str2) {
844
+ return str2.replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&");
845
+ }
846
+ var import_fs6, import_path6;
847
+ var init_agents_md_progressive = __esm({
848
+ "src/core/agents-md-progressive.ts"() {
849
+ "use strict";
850
+ init_cjs_shims();
851
+ import_fs6 = require("fs");
852
+ import_path6 = __toESM(require("path"));
853
+ init_filesystem();
854
+ }
855
+ });
856
+
584
857
  // ../../node_modules/color-name/index.js
585
858
  var require_color_name = __commonJS({
586
859
  "../../node_modules/color-name/index.js"(exports2, module2) {
@@ -1456,15 +1729,15 @@ var require_route = __commonJS({
1456
1729
  };
1457
1730
  }
1458
1731
  function wrapConversion(toModel, graph) {
1459
- const path7 = [graph[toModel].parent, toModel];
1732
+ const path8 = [graph[toModel].parent, toModel];
1460
1733
  let fn = conversions[graph[toModel].parent][toModel];
1461
1734
  let cur = graph[toModel].parent;
1462
1735
  while (graph[cur].parent) {
1463
- path7.unshift(graph[cur].parent);
1736
+ path8.unshift(graph[cur].parent);
1464
1737
  fn = link(conversions[graph[cur].parent][cur], fn);
1465
1738
  cur = graph[cur].parent;
1466
1739
  }
1467
- fn.conversion = path7;
1740
+ fn.conversion = path8;
1468
1741
  return fn;
1469
1742
  }
1470
1743
  module2.exports = function(fromModel) {
@@ -1910,14 +2183,14 @@ var require_templates = __commonJS({
1910
2183
  }
1911
2184
  return results;
1912
2185
  }
1913
- function buildStyle(chalk3, styles) {
2186
+ function buildStyle(chalk4, styles) {
1914
2187
  const enabled = {};
1915
2188
  for (const layer of styles) {
1916
2189
  for (const style of layer.styles) {
1917
2190
  enabled[style[0]] = layer.inverse ? null : style.slice(1);
1918
2191
  }
1919
2192
  }
1920
- let current = chalk3;
2193
+ let current = chalk4;
1921
2194
  for (const [styleName, styles2] of Object.entries(enabled)) {
1922
2195
  if (!Array.isArray(styles2)) {
1923
2196
  continue;
@@ -1929,7 +2202,7 @@ var require_templates = __commonJS({
1929
2202
  }
1930
2203
  return current;
1931
2204
  }
1932
- module2.exports = (chalk3, temporary) => {
2205
+ module2.exports = (chalk4, temporary) => {
1933
2206
  const styles = [];
1934
2207
  const chunks = [];
1935
2208
  let chunk = [];
@@ -1939,13 +2212,13 @@ var require_templates = __commonJS({
1939
2212
  } else if (style) {
1940
2213
  const string = chunk.join("");
1941
2214
  chunk = [];
1942
- chunks.push(styles.length === 0 ? string : buildStyle(chalk3, styles)(string));
2215
+ chunks.push(styles.length === 0 ? string : buildStyle(chalk4, styles)(string));
1943
2216
  styles.push({ inverse, styles: parseStyle(style) });
1944
2217
  } else if (close) {
1945
2218
  if (styles.length === 0) {
1946
2219
  throw new Error("Found extraneous } in Chalk template literal");
1947
2220
  }
1948
- chunks.push(buildStyle(chalk3, styles)(chunk.join("")));
2221
+ chunks.push(buildStyle(chalk4, styles)(chunk.join("")));
1949
2222
  chunk = [];
1950
2223
  styles.pop();
1951
2224
  } else {
@@ -1994,16 +2267,16 @@ var require_source = __commonJS({
1994
2267
  }
1995
2268
  };
1996
2269
  var chalkFactory = (options) => {
1997
- const chalk4 = {};
1998
- applyOptions(chalk4, options);
1999
- chalk4.template = (...arguments_) => chalkTag(chalk4.template, ...arguments_);
2000
- Object.setPrototypeOf(chalk4, Chalk.prototype);
2001
- Object.setPrototypeOf(chalk4.template, chalk4);
2002
- chalk4.template.constructor = () => {
2270
+ const chalk5 = {};
2271
+ applyOptions(chalk5, options);
2272
+ chalk5.template = (...arguments_) => chalkTag(chalk5.template, ...arguments_);
2273
+ Object.setPrototypeOf(chalk5, Chalk.prototype);
2274
+ Object.setPrototypeOf(chalk5.template, chalk5);
2275
+ chalk5.template.constructor = () => {
2003
2276
  throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
2004
2277
  };
2005
- chalk4.template.Instance = ChalkClass;
2006
- return chalk4.template;
2278
+ chalk5.template.Instance = ChalkClass;
2279
+ return chalk5.template;
2007
2280
  };
2008
2281
  function Chalk(options) {
2009
2282
  return chalkFactory(options);
@@ -2114,7 +2387,7 @@ var require_source = __commonJS({
2114
2387
  return openAll + string + closeAll;
2115
2388
  };
2116
2389
  var template;
2117
- var chalkTag = (chalk4, ...strings) => {
2390
+ var chalkTag = (chalk5, ...strings) => {
2118
2391
  const [firstString] = strings;
2119
2392
  if (!isArray(firstString) || !isArray(firstString.raw)) {
2120
2393
  return strings.join(" ");
@@ -2130,14 +2403,14 @@ var require_source = __commonJS({
2130
2403
  if (template === void 0) {
2131
2404
  template = require_templates();
2132
2405
  }
2133
- return template(chalk4, parts.join(""));
2406
+ return template(chalk5, parts.join(""));
2134
2407
  };
2135
2408
  Object.defineProperties(Chalk.prototype, styles);
2136
- var chalk3 = Chalk();
2137
- chalk3.supportsColor = stdoutColor;
2138
- chalk3.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
2139
- chalk3.stderr.supportsColor = stderrColor;
2140
- module2.exports = chalk3;
2409
+ var chalk4 = Chalk();
2410
+ chalk4.supportsColor = stdoutColor;
2411
+ chalk4.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
2412
+ chalk4.stderr.supportsColor = stderrColor;
2413
+ module2.exports = chalk4;
2141
2414
  }
2142
2415
  });
2143
2416
 
@@ -2491,8 +2764,8 @@ async function handleCollectionPublish(manifestPath = "./collection.json") {
2491
2764
  throw new CLIError("\n\u274C Authentication required. Run `prpm login` first.", 1);
2492
2765
  }
2493
2766
  console.log("\u{1F4E6} Publishing collection...\n");
2494
- const fs10 = await import("fs/promises");
2495
- const manifestContent = await fs10.readFile(manifestPath, "utf-8");
2767
+ const fs12 = await import("fs/promises");
2768
+ const manifestContent = await fs12.readFile(manifestPath, "utf-8");
2496
2769
  const manifest = JSON.parse(manifestContent);
2497
2770
  const required = ["id", "name", "description", "packages"];
2498
2771
  const missing = required.filter((field) => !manifest[field]);
@@ -6389,6 +6662,172 @@ var init_from_kiro = __esm({
6389
6662
  }
6390
6663
  });
6391
6664
 
6665
+ // ../converters/dist/from-kiro-agent.js
6666
+ function fromKiroAgent(jsonContent, options = {}) {
6667
+ const warnings = [];
6668
+ let qualityScore = 100;
6669
+ try {
6670
+ const agentConfig = JSON.parse(jsonContent);
6671
+ const content = {
6672
+ format: "canonical",
6673
+ version: "1.0",
6674
+ sections: [
6675
+ {
6676
+ type: "metadata",
6677
+ data: {
6678
+ title: agentConfig.name || "Kiro Agent",
6679
+ description: agentConfig.description || ""
6680
+ }
6681
+ }
6682
+ ]
6683
+ };
6684
+ if (agentConfig.prompt) {
6685
+ parsePromptIntoContent(agentConfig.prompt, content);
6686
+ }
6687
+ const pkg = {
6688
+ id: agentConfig.name || "kiro-agent",
6689
+ name: agentConfig.name || "kiro-agent",
6690
+ version: "1.0.0",
6691
+ description: agentConfig.description || "",
6692
+ author: "",
6693
+ tags: [],
6694
+ format: "kiro",
6695
+ subtype: "agent",
6696
+ content,
6697
+ sourceFormat: "kiro",
6698
+ metadata: {
6699
+ kiroConfig: {
6700
+ inclusion: "always"
6701
+ },
6702
+ kiroAgent: {
6703
+ tools: agentConfig.tools,
6704
+ mcpServers: agentConfig.mcpServers,
6705
+ toolAliases: agentConfig.toolAliases,
6706
+ allowedTools: agentConfig.allowedTools,
6707
+ toolsSettings: agentConfig.toolsSettings,
6708
+ resources: agentConfig.resources,
6709
+ hooks: agentConfig.hooks,
6710
+ useLegacyMcpJson: agentConfig.useLegacyMcpJson,
6711
+ model: agentConfig.model
6712
+ }
6713
+ }
6714
+ };
6715
+ return {
6716
+ content: JSON.stringify(pkg, null, 2),
6717
+ format: "canonical",
6718
+ warnings: warnings.length > 0 ? warnings : void 0,
6719
+ lossyConversion: false,
6720
+ qualityScore
6721
+ };
6722
+ } catch (error) {
6723
+ warnings.push(`Parse error: ${error instanceof Error ? error.message : String(error)}`);
6724
+ return {
6725
+ content: "",
6726
+ format: "canonical",
6727
+ warnings,
6728
+ lossyConversion: true,
6729
+ qualityScore: 0
6730
+ };
6731
+ }
6732
+ }
6733
+ function parsePromptIntoContent(prompt3, content) {
6734
+ if (prompt3.startsWith("file://")) {
6735
+ content.sections.push({
6736
+ type: "instructions",
6737
+ title: "Instructions",
6738
+ content: `Loads instructions from: ${prompt3}`
6739
+ });
6740
+ return;
6741
+ }
6742
+ const sections = prompt3.split(/\n## /);
6743
+ if (sections[0]) {
6744
+ const intro = sections[0].trim();
6745
+ if (intro) {
6746
+ const metadataSection = content.sections[0];
6747
+ if (metadataSection && metadataSection.type === "metadata") {
6748
+ if (!metadataSection.data.description) {
6749
+ metadataSection.data.description = intro;
6750
+ }
6751
+ }
6752
+ }
6753
+ }
6754
+ for (let i = 1; i < sections.length; i++) {
6755
+ const sectionText = sections[i];
6756
+ const lines = sectionText.split("\n");
6757
+ const title = lines[0].trim();
6758
+ const sectionContent = lines.slice(1).join("\n").trim();
6759
+ if (title.toLowerCase() === "instructions") {
6760
+ content.sections.push({
6761
+ type: "instructions",
6762
+ title,
6763
+ content: sectionContent
6764
+ });
6765
+ } else if (title.toLowerCase() === "rules") {
6766
+ const rules = parseRules(sectionContent);
6767
+ content.sections.push({
6768
+ type: "rules",
6769
+ title,
6770
+ items: rules
6771
+ });
6772
+ } else if (title.toLowerCase() === "examples") {
6773
+ const examples = parseExamples(sectionContent);
6774
+ content.sections.push({
6775
+ type: "examples",
6776
+ title,
6777
+ examples
6778
+ });
6779
+ } else {
6780
+ content.sections.push({
6781
+ type: "custom",
6782
+ editorType: "kiro",
6783
+ title,
6784
+ content: sectionContent
6785
+ });
6786
+ }
6787
+ }
6788
+ }
6789
+ function parseRules(text) {
6790
+ const rules = [];
6791
+ const ruleSections = text.split(/\n### /);
6792
+ for (const ruleText of ruleSections) {
6793
+ if (!ruleText.trim())
6794
+ continue;
6795
+ const lines = ruleText.split("\n");
6796
+ const title = lines[0].trim();
6797
+ const description = lines.slice(1).join("\n").trim();
6798
+ rules.push({
6799
+ content: `${title}: ${description}`
6800
+ });
6801
+ }
6802
+ return rules;
6803
+ }
6804
+ function parseExamples(text) {
6805
+ const examples = [];
6806
+ const exampleSections = text.split(/\n### /);
6807
+ for (const exampleText of exampleSections) {
6808
+ if (!exampleText.trim())
6809
+ continue;
6810
+ const lines = exampleText.split("\n");
6811
+ const title = lines[0].trim();
6812
+ const content = lines.slice(1).join("\n");
6813
+ const codeMatch = /```[\w]*\n([\s\S]*?)```/.exec(content);
6814
+ const code = codeMatch ? codeMatch[1].trim() : content;
6815
+ const descMatch = /^([\s\S]*?)(?:```|$)/.exec(content);
6816
+ const description = descMatch && descMatch[1].trim() ? descMatch[1].trim() : title;
6817
+ examples.push({
6818
+ description,
6819
+ code
6820
+ });
6821
+ }
6822
+ return examples;
6823
+ }
6824
+ var init_from_kiro_agent = __esm({
6825
+ "../converters/dist/from-kiro-agent.js"() {
6826
+ "use strict";
6827
+ init_cjs_shims();
6828
+ }
6829
+ });
6830
+
6392
6831
  // ../converters/dist/from-windsurf.js
6393
6832
  function fromWindsurf(content, metadata) {
6394
6833
  const sections = [];
@@ -8778,6 +9217,156 @@ var init_from_gemini = __esm({
8778
9217
  }
8779
9218
  });
8780
9219
 
9220
+ // ../converters/dist/from-opencode.js
9221
+ var init_from_opencode = __esm({
9222
+ "../converters/dist/from-opencode.js"() {
9223
+ "use strict";
9224
+ init_cjs_shims();
9225
+ init_taxonomy_utils();
9226
+ init_js_yaml();
9227
+ }
9228
+ });
9229
+
9230
+ // ../converters/dist/from-ruler.js
9231
+ function fromRuler(markdown, options = {}) {
9232
+ const warnings = [];
9233
+ let qualityScore = 100;
9234
+ try {
9235
+ const cleanedMarkdown = markdown.replace(/<!--.*?-->/gs, "").trim();
9236
+ const content = parseMarkdownContent(cleanedMarkdown, warnings);
9237
+ const metadata = extractMetadata(markdown);
9238
+ const metadataSection = content.sections.find((s) => s.type === "metadata");
9239
+ const description = metadata.description || (metadataSection == null ? void 0 : metadataSection.data.description) || "";
9240
+ const title = (metadataSection == null ? void 0 : metadataSection.data.title) || "Ruler Rule";
9241
+ const pkg = {
9242
+ id: metadata.name || "ruler-rule",
9243
+ name: metadata.name || "ruler-rule",
9244
+ version: "1.0.0",
9245
+ author: metadata.author || "",
9246
+ tags: [],
9247
+ format: "generic",
9248
+ subtype: "rule",
9249
+ description,
9250
+ content,
9251
+ sourceFormat: "ruler",
9252
+ metadata: {
9253
+ title,
9254
+ description
9255
+ }
9256
+ };
9257
+ return {
9258
+ content: JSON.stringify(pkg, null, 2),
9259
+ format: "canonical",
9260
+ warnings: warnings.length > 0 ? warnings : void 0,
9261
+ lossyConversion: false,
9262
+ qualityScore
9263
+ };
9264
+ } catch (error) {
9265
+ warnings.push(`Parse error: ${error instanceof Error ? error.message : String(error)}`);
9266
+ return {
9267
+ content: "",
9268
+ format: "canonical",
9269
+ warnings,
9270
+ lossyConversion: true,
9271
+ qualityScore: 0
9272
+ };
9273
+ }
9274
+ }
9275
+ function extractMetadata(markdown) {
9276
+ const metadata = {};
9277
+ const nameMatch = /<!--\s*Package:\s*(.+?)\s*-->/i.exec(markdown);
9278
+ if (nameMatch) {
9279
+ metadata.name = nameMatch[1].trim();
9280
+ }
9281
+ const authorMatch = /<!--\s*Author:\s*(.+?)\s*-->/i.exec(markdown);
9282
+ if (authorMatch) {
9283
+ metadata.author = authorMatch[1].trim();
9284
+ }
9285
+ const descMatch = /<!--\s*Description:\s*(.+?)\s*-->/i.exec(markdown);
9286
+ if (descMatch) {
9287
+ metadata.description = descMatch[1].trim();
9288
+ }
9289
+ return metadata;
9290
+ }
9291
+ function parseMarkdownContent(markdown, warnings) {
9292
+ const lines = markdown.split("\n");
9293
+ const content = {
9294
+ format: "canonical",
9295
+ version: "1.0",
9296
+ sections: []
9297
+ };
9298
+ let title = "";
9299
+ let description = "";
9300
+ let currentSection = null;
9301
+ let inCodeBlock = false;
9302
+ let buffer = [];
9303
+ for (const line of lines) {
9304
+ if (line.trim().startsWith("```")) {
9305
+ inCodeBlock = !inCodeBlock;
9306
+ buffer.push(line);
9307
+ continue;
9308
+ }
9309
+ if (!inCodeBlock && line.match(/^#+\s/)) {
9310
+ if (currentSection) {
9311
+ content.sections.push({
9312
+ type: "custom",
9313
+ title: currentSection.title,
9314
+ content: buffer.join("\n").trim()
9315
+ });
9316
+ buffer = [];
9317
+ }
9318
+ const match = line.match(/^(#+)\s+(.+)$/);
9319
+ if (match) {
9320
+ const level = match[1].length;
9321
+ const sectionTitle = match[2].trim();
9322
+ if (level === 1 && !title) {
9323
+ title = sectionTitle;
9324
+ currentSection = null;
9325
+ } else {
9326
+ currentSection = { title: sectionTitle, content: "" };
9327
+ }
9328
+ }
9329
+ } else if (currentSection) {
9330
+ buffer.push(line);
9331
+ } else if (!title) {
9332
+ if (line.trim()) {
9333
+ description += (description ? "\n" : "") + line;
9334
+ }
9335
+ }
9336
+ }
9337
+ if (currentSection && buffer.length > 0) {
9338
+ content.sections.push({
9339
+ type: "custom",
9340
+ title: currentSection.title,
9341
+ content: buffer.join("\n").trim()
9342
+ });
9343
+ }
9344
+ content.sections.unshift({
9345
+ type: "metadata",
9346
+ data: {
9347
+ title: title || "Ruler Rule",
9348
+ description: description || ""
9349
+ }
9350
+ });
9351
+ return content;
9352
+ }
9353
+ var init_from_ruler = __esm({
9354
+ "../converters/dist/from-ruler.js"() {
9355
+ "use strict";
9356
+ init_cjs_shims();
9357
+ }
9358
+ });
9359
+
9360
+ // ../converters/dist/from-droid.js
9361
+ var init_from_droid = __esm({
9362
+ "../converters/dist/from-droid.js"() {
9363
+ "use strict";
9364
+ init_cjs_shims();
9365
+ init_taxonomy_utils();
9366
+ init_js_yaml();
9367
+ }
9368
+ });
9369
+
8781
9370
  // ../converters/dist/validation.js
8782
9371
  function loadSchema(format, subtype) {
8783
9372
  const cacheKey = subtype ? `${format}:${subtype}` : format;
@@ -8792,7 +9381,8 @@ function loadSchema(format, subtype) {
8792
9381
  "claude:slash-command": "claude-slash-command.schema.json",
8793
9382
  "claude:hook": "claude-hook.schema.json",
8794
9383
  "cursor:slash-command": "cursor-command.schema.json",
8795
- "kiro:hook": "kiro-hooks.schema.json"
9384
+ "kiro:hook": "kiro-hooks.schema.json",
9385
+ "kiro:agent": "kiro-agent.schema.json"
8796
9386
  };
8797
9387
  schemaFilename = subtypeSchemaMap[cacheKey];
8798
9388
  }
@@ -8806,20 +9396,23 @@ function loadSchema(format, subtype) {
8806
9396
  "kiro": "kiro-steering.schema.json",
8807
9397
  "agents-md": "agents-md.schema.json",
8808
9398
  "gemini": "gemini.schema.json",
9399
+ "opencode": "opencode.schema.json",
9400
+ "ruler": "ruler.schema.json",
9401
+ "droid": "droid.schema.json",
8809
9402
  "canonical": "canonical.schema.json"
8810
9403
  };
8811
9404
  schemaFilename = schemaMap[format] || `${format}.schema.json`;
8812
9405
  }
8813
9406
  const schemaDirectories = [
8814
- (0, import_path7.join)(currentDirname, "..", "schemas"),
8815
- (0, import_path7.join)(currentDirname, "schemas")
9407
+ (0, import_path8.join)(currentDirname, "..", "schemas"),
9408
+ (0, import_path8.join)(currentDirname, "schemas")
8816
9409
  ];
8817
9410
  let schemaContent = null;
8818
9411
  let schemaPath = null;
8819
9412
  for (const dir of schemaDirectories) {
8820
- const candidate = (0, import_path7.join)(dir, schemaFilename);
9413
+ const candidate = (0, import_path8.join)(dir, schemaFilename);
8821
9414
  try {
8822
- schemaContent = (0, import_fs8.readFileSync)(candidate, "utf-8");
9415
+ schemaContent = (0, import_fs9.readFileSync)(candidate, "utf-8");
8823
9416
  schemaPath = candidate;
8824
9417
  break;
8825
9418
  } catch (error) {
@@ -8845,11 +9438,11 @@ function validateFormat(format, data, subtype) {
8845
9438
  const warnings = [];
8846
9439
  if (!valid && validate.errors) {
8847
9440
  for (const error of validate.errors) {
8848
- const path7 = error.instancePath || "/" + error.params.missingProperty || "/";
9441
+ const path8 = error.instancePath || "/" + error.params.missingProperty || "/";
8849
9442
  const message = error.message || "Validation error";
8850
9443
  const validationError = {
8851
- path: path7,
8852
- message: `${path7}: ${message}`,
9444
+ path: path8,
9445
+ message: `${path8}: ${message}`,
8853
9446
  value: error.data
8854
9447
  };
8855
9448
  if (error.keyword === "deprecated") {
@@ -8913,22 +9506,33 @@ function parseMarkdownWithFrontmatter(markdown) {
8913
9506
  }
8914
9507
  function validateMarkdown(format, markdown, subtype) {
8915
9508
  const { frontmatter, content } = parseMarkdownWithFrontmatter(markdown);
8916
- if (format === "windsurf" || format === "agents-md") {
9509
+ if (format === "windsurf" || format === "agents-md" || format === "ruler") {
8917
9510
  return validateFormat(format, { content: markdown }, subtype);
8918
9511
  }
8919
9512
  return validateConversion(format, frontmatter, content, subtype);
8920
9513
  }
8921
- var import_ajv, import_ajv_formats, import_fs8, import_path7, currentDirname, ajv, schemaCache;
9514
+ var import_ajv, import_ajv_formats, import_fs9, import_path8, import_url, currentDirname, ajv, schemaCache;
8922
9515
  var init_validation = __esm({
8923
9516
  "../converters/dist/validation.js"() {
8924
9517
  "use strict";
8925
9518
  init_cjs_shims();
8926
9519
  import_ajv = __toESM(require("ajv"), 1);
8927
9520
  import_ajv_formats = __toESM(require("ajv-formats"), 1);
8928
- import_fs8 = require("fs");
8929
- import_path7 = require("path");
9521
+ import_fs9 = require("fs");
9522
+ import_path8 = require("path");
9523
+ import_url = require("url");
8930
9524
  init_js_yaml();
8931
- currentDirname = __dirname;
9525
+ currentDirname = (() => {
9526
+ if (typeof __dirname !== "undefined") {
9527
+ return __dirname;
9528
+ }
9529
+ try {
9530
+ const importMeta = (0, eval)("import.meta");
9531
+ return (0, import_path8.dirname)((0, import_url.fileURLToPath)(importMeta.url));
9532
+ } catch (e) {
9533
+ return (0, import_path8.join)(process.cwd(), "packages", "converters", "dist");
9534
+ }
9535
+ })();
8932
9536
  ajv = new import_ajv.default({
8933
9537
  allErrors: true,
8934
9538
  verbose: true,
@@ -9835,6 +10439,171 @@ var init_to_kiro = __esm({
9835
10439
  }
9836
10440
  });
9837
10441
 
10442
+ // ../converters/dist/to-kiro-agent.js
10443
+ function toKiroAgent(pkg, options = {}) {
10444
+ var _a;
10445
+ const warnings = [];
10446
+ let qualityScore = 100;
10447
+ try {
10448
+ const agentConfig = {
10449
+ name: pkg.name,
10450
+ description: pkg.description
10451
+ };
10452
+ const prompt3 = convertToPrompt(pkg.content, warnings);
10453
+ if (prompt3) {
10454
+ agentConfig.prompt = prompt3;
10455
+ }
10456
+ if ((_a = pkg.metadata) == null ? void 0 : _a.kiroAgent) {
10457
+ const kiroAgent = pkg.metadata.kiroAgent;
10458
+ if (kiroAgent.tools) {
10459
+ agentConfig.tools = kiroAgent.tools;
10460
+ }
10461
+ if (kiroAgent.mcpServers) {
10462
+ agentConfig.mcpServers = kiroAgent.mcpServers;
10463
+ }
10464
+ if (kiroAgent.toolAliases) {
10465
+ agentConfig.toolAliases = kiroAgent.toolAliases;
10466
+ }
10467
+ if (kiroAgent.allowedTools) {
10468
+ agentConfig.allowedTools = kiroAgent.allowedTools;
10469
+ }
10470
+ if (kiroAgent.toolsSettings) {
10471
+ agentConfig.toolsSettings = kiroAgent.toolsSettings;
10472
+ }
10473
+ if (kiroAgent.resources) {
10474
+ agentConfig.resources = kiroAgent.resources;
10475
+ }
10476
+ if (kiroAgent.hooks) {
10477
+ agentConfig.hooks = kiroAgent.hooks;
10478
+ }
10479
+ if (kiroAgent.useLegacyMcpJson !== void 0) {
10480
+ agentConfig.useLegacyMcpJson = kiroAgent.useLegacyMcpJson;
10481
+ }
10482
+ if (kiroAgent.model) {
10483
+ agentConfig.model = kiroAgent.model;
10484
+ }
10485
+ }
10486
+ if (pkg.subtype === "slash-command") {
10487
+ warnings.push("Slash commands are not directly supported by Kiro agents");
10488
+ qualityScore -= 20;
10489
+ }
10490
+ if (pkg.subtype === "skill") {
10491
+ warnings.push("Skills are converted to agent prompts - some features may be lost");
10492
+ qualityScore -= 10;
10493
+ }
10494
+ const content = JSON.stringify(agentConfig, null, 2);
10495
+ const lossyConversion = warnings.some((w) => w.includes("not supported") || w.includes("may be lost"));
10496
+ return {
10497
+ content,
10498
+ format: "kiro",
10499
+ warnings: warnings.length > 0 ? warnings : void 0,
10500
+ lossyConversion,
10501
+ qualityScore: Math.max(0, qualityScore)
10502
+ };
10503
+ } catch (error) {
10504
+ warnings.push(`Conversion error: ${error instanceof Error ? error.message : String(error)}`);
10505
+ return {
10506
+ content: "",
10507
+ format: "kiro",
10508
+ warnings,
10509
+ lossyConversion: true,
10510
+ qualityScore: 0
10511
+ };
10512
+ }
10513
+ }
10514
+ function convertToPrompt(content, warnings) {
10515
+ const parts = [];
10516
+ const metadataSection = content.sections.find((s) => s.type === "metadata");
10517
+ if (metadataSection == null ? void 0 : metadataSection.data.description) {
10518
+ parts.push(metadataSection.data.description);
10519
+ }
10520
+ const personaSection = content.sections.find((s) => s.type === "persona");
10521
+ if (personaSection) {
10522
+ const persona = personaSection.data;
10523
+ let personaText = "";
10524
+ if (persona.name) {
10525
+ personaText += `You are ${persona.name}`;
10526
+ if (persona.role) {
10527
+ personaText += `, ${persona.role}`;
10528
+ }
10529
+ personaText += ". ";
10530
+ }
10531
+ if (persona.style && persona.style.length > 0) {
10532
+ personaText += `Your communication style is ${persona.style.join(", ")}. `;
10533
+ }
10534
+ if (persona.expertise && persona.expertise.length > 0) {
10535
+ personaText += `You specialize in: ${persona.expertise.join(", ")}. `;
10536
+ }
10537
+ if (personaText) {
10538
+ parts.push(personaText.trim());
10539
+ }
10540
+ }
10541
+ for (const section of content.sections) {
10542
+ if (section.type === "instructions") {
10543
+ const instructionsSection = section;
10544
+ parts.push(`
10545
+ ## ${instructionsSection.title}
10546
+ `);
10547
+ parts.push(instructionsSection.content);
10548
+ } else if (section.type === "rules") {
10549
+ const rulesSection = section;
10550
+ parts.push(`
10551
+ ## ${rulesSection.title}
10552
+ `);
10553
+ for (const rule of rulesSection.items) {
10554
+ parts.push(`- ${rule.content}`);
10555
+ if (rule.rationale) {
10556
+ parts.push(` *Rationale:* ${rule.rationale}`);
10557
+ }
10558
+ }
10559
+ } else if (section.type === "examples") {
10560
+ const examplesSection = section;
10561
+ parts.push(`
10562
+ ## ${examplesSection.title}
10563
+ `);
10564
+ for (const example of examplesSection.examples) {
10565
+ if (example.description) {
10566
+ parts.push(`
10567
+ ### ${example.description}
10568
+ `);
10569
+ }
10570
+ if (example.code) {
10571
+ const lang = example.language || "";
10572
+ parts.push(`\`\`\`${lang}
10573
+ ${example.code}
10574
+ \`\`\``);
10575
+ }
10576
+ }
10577
+ } else if (section.type === "custom") {
10578
+ const customSection = section;
10579
+ if (customSection.title) {
10580
+ parts.push(`
10581
+ ## ${customSection.title}
10582
+ `);
10583
+ }
10584
+ parts.push(customSection.content);
10585
+ }
10586
+ }
10587
+ return parts.join("\n").trim();
10588
+ }
10589
+ function isKiroAgentFormat(content) {
10590
+ try {
10591
+ const parsed = JSON.parse(content);
10592
+ if (!parsed.name && !parsed.description) {
10593
+ return false;
10594
+ }
10595
+ return !!(parsed.prompt || parsed.tools || parsed.mcpServers);
10596
+ } catch {
10597
+ return false;
10598
+ }
10599
+ }
10600
+ var init_to_kiro_agent = __esm({
10601
+ "../converters/dist/to-kiro-agent.js"() {
10602
+ "use strict";
10603
+ init_cjs_shims();
10604
+ }
10605
+ });
10606
+
9838
10607
  // ../converters/dist/to-windsurf.js
9839
10608
  function toWindsurf(pkg) {
9840
10609
  var _a, _b, _c, _d;
@@ -10345,6 +11114,184 @@ var init_to_gemini = __esm({
10345
11114
  }
10346
11115
  });
10347
11116
 
11117
+ // ../converters/dist/to-opencode.js
11118
+ var init_to_opencode = __esm({
11119
+ "../converters/dist/to-opencode.js"() {
11120
+ "use strict";
11121
+ init_cjs_shims();
11122
+ init_js_yaml();
11123
+ }
11124
+ });
11125
+
11126
+ // ../converters/dist/to-ruler.js
11127
+ function toRuler(pkg, options = {}) {
11128
+ var _a, _b;
11129
+ const warnings = [];
11130
+ let qualityScore = 100;
11131
+ try {
11132
+ if ((_b = (_a = pkg.metadata) == null ? void 0 : _a.copilotConfig) == null ? void 0 : _b.applyTo) {
11133
+ warnings.push("Path-specific configuration (applyTo) will be ignored by Ruler");
11134
+ }
11135
+ if (pkg.subtype === "agent" || pkg.subtype === "workflow") {
11136
+ warnings.push(`Subtype "${pkg.subtype}" may not be fully supported by Ruler's simple rule format`);
11137
+ qualityScore -= 10;
11138
+ }
11139
+ if (pkg.subtype === "slash-command") {
11140
+ warnings.push("Slash commands are not supported by Ruler");
11141
+ qualityScore -= 20;
11142
+ }
11143
+ if (pkg.subtype === "hook") {
11144
+ warnings.push("Hooks are not supported by Ruler");
11145
+ qualityScore -= 20;
11146
+ }
11147
+ const content = convertContent6(pkg.content, warnings);
11148
+ const header = `<!-- Package: ${pkg.name} -->
11149
+ <!-- Author: ${pkg.author || "Unknown"} -->
11150
+ ${pkg.description ? `<!-- Description: ${pkg.description} -->
11151
+ ` : ""}`;
11152
+ const fullContent = `${header}
11153
+ ${content}`;
11154
+ const validation = validateMarkdown("ruler", fullContent);
11155
+ const validationErrors = validation.errors.map((e) => e.message);
11156
+ const validationWarnings = validation.warnings.map((w) => w.message);
11157
+ if (validationWarnings.length > 0) {
11158
+ warnings.push(...validationWarnings);
11159
+ }
11160
+ const lossyConversion = warnings.some((w) => w.includes("not supported") || w.includes("ignored"));
11161
+ if (validationErrors.length > 0) {
11162
+ qualityScore -= validationErrors.length * 5;
11163
+ }
11164
+ return {
11165
+ content: fullContent,
11166
+ format: "ruler",
11167
+ warnings: warnings.length > 0 ? warnings : void 0,
11168
+ validationErrors: validationErrors.length > 0 ? validationErrors : void 0,
11169
+ lossyConversion,
11170
+ qualityScore: Math.max(0, qualityScore)
11171
+ };
11172
+ } catch (error) {
11173
+ warnings.push(`Conversion error: ${error instanceof Error ? error.message : String(error)}`);
11174
+ return {
11175
+ content: "",
11176
+ format: "ruler",
11177
+ warnings,
11178
+ lossyConversion: true,
11179
+ qualityScore: 0
11180
+ };
11181
+ }
11182
+ }
11183
+ function convertContent6(content, warnings) {
11184
+ const parts = [];
11185
+ const metadataSection = content.sections.find((s) => s.type === "metadata");
11186
+ if (metadataSection) {
11187
+ if (metadataSection.data.title) {
11188
+ parts.push(`# ${metadataSection.data.title}
11189
+ `);
11190
+ }
11191
+ if (metadataSection.data.description) {
11192
+ parts.push(`${metadataSection.data.description}
11193
+ `);
11194
+ }
11195
+ }
11196
+ for (const section of content.sections) {
11197
+ if (section.type === "metadata") {
11198
+ continue;
11199
+ } else if (section.type === "instructions") {
11200
+ const instructionsSection = section;
11201
+ parts.push(`## ${instructionsSection.title}
11202
+ `);
11203
+ parts.push(`${instructionsSection.content}
11204
+ `);
11205
+ } else if (section.type === "rules") {
11206
+ const rulesSection = section;
11207
+ parts.push(`## ${rulesSection.title}
11208
+ `);
11209
+ for (const rule of rulesSection.items) {
11210
+ parts.push(convertRule(rule));
11211
+ }
11212
+ } else if (section.type === "examples") {
11213
+ const examplesSection = section;
11214
+ parts.push(`## ${examplesSection.title}
11215
+ `);
11216
+ for (const example of examplesSection.examples) {
11217
+ parts.push(convertExample(example));
11218
+ }
11219
+ } else if (section.type === "custom") {
11220
+ const customSection = section;
11221
+ if (customSection.title) {
11222
+ parts.push(`## ${customSection.title}
11223
+ `);
11224
+ }
11225
+ parts.push(`${customSection.content}
11226
+ `);
11227
+ }
11228
+ }
11229
+ return parts.join("\n").trim();
11230
+ }
11231
+ function convertRule(rule) {
11232
+ const parts = [];
11233
+ parts.push(`- ${rule.content}`);
11234
+ if (rule.rationale) {
11235
+ parts.push(`
11236
+ *Rationale:* ${rule.rationale}`);
11237
+ }
11238
+ if (rule.examples && rule.examples.length > 0) {
11239
+ parts.push(`
11240
+ *Examples:*`);
11241
+ for (const example of rule.examples) {
11242
+ parts.push(`
11243
+ \`\`\`
11244
+ ${example}
11245
+ \`\`\``);
11246
+ }
11247
+ }
11248
+ parts.push("\n");
11249
+ return parts.join("");
11250
+ }
11251
+ function convertExample(example) {
11252
+ const parts = [];
11253
+ if (example.description) {
11254
+ parts.push(`### ${example.description}
11255
+ `);
11256
+ }
11257
+ if (example.good !== void 0) {
11258
+ parts.push(`*${example.good ? "Good" : "Bad"} example*
11259
+ `);
11260
+ }
11261
+ if (example.code) {
11262
+ const lang = example.language || "";
11263
+ parts.push("```" + lang);
11264
+ parts.push(example.code);
11265
+ parts.push("```\n");
11266
+ }
11267
+ return parts.join("\n");
11268
+ }
11269
+ function isRulerFormat(content) {
11270
+ const lines = content.trim().split("\n");
11271
+ if (lines[0] === "---") {
11272
+ return false;
11273
+ }
11274
+ const hasHeaders = /^#+\s/.test(content);
11275
+ const hasRuleContent = /rule|instruction|guideline|convention/i.test(content);
11276
+ return hasHeaders || hasRuleContent;
11277
+ }
11278
+ var init_to_ruler = __esm({
11279
+ "../converters/dist/to-ruler.js"() {
11280
+ "use strict";
11281
+ init_cjs_shims();
11282
+ init_validation();
11283
+ }
11284
+ });
11285
+
11286
+ // ../converters/dist/to-droid.js
11287
+ var init_to_droid = __esm({
11288
+ "../converters/dist/to-droid.js"() {
11289
+ "use strict";
11290
+ init_cjs_shims();
11291
+ init_js_yaml();
11292
+ }
11293
+ });
11294
+
10348
11295
  // ../converters/dist/index.js
10349
11296
  var init_dist = __esm({
10350
11297
  "../converters/dist/index.js"() {
@@ -10356,17 +11303,25 @@ var init_dist = __esm({
10356
11303
  init_from_continue();
10357
11304
  init_from_copilot();
10358
11305
  init_from_kiro();
11306
+ init_from_kiro_agent();
10359
11307
  init_from_windsurf();
10360
11308
  init_from_agents_md();
10361
11309
  init_from_gemini();
11310
+ init_from_opencode();
11311
+ init_from_ruler();
11312
+ init_from_droid();
10362
11313
  init_to_cursor();
10363
11314
  init_to_claude();
10364
11315
  init_to_continue();
10365
11316
  init_to_copilot();
10366
11317
  init_to_kiro();
11318
+ init_to_kiro_agent();
10367
11319
  init_to_windsurf();
10368
11320
  init_to_agents_md();
10369
11321
  init_to_gemini();
11322
+ init_to_opencode();
11323
+ init_to_ruler();
11324
+ init_to_droid();
10370
11325
  init_taxonomy_utils();
10371
11326
  init_validation();
10372
11327
  }
@@ -10395,8 +11350,13 @@ function getPackageIcon2(format, subtype) {
10395
11350
  "copilot": "\u2708\uFE0F",
10396
11351
  "kiro": "\u{1F3AF}",
10397
11352
  "gemini": "\u2728",
11353
+ "gemini.md": "\u2728",
11354
+ "claude.md": "\u{1F916}",
11355
+ "opencode": "\u26A1",
11356
+ "droid": "\u{1F3ED}",
10398
11357
  "mcp": "\u{1F517}",
10399
11358
  "agents.md": "\u{1F4DD}",
11359
+ "ruler": "\u{1F4CF}",
10400
11360
  "generic": "\u{1F4E6}"
10401
11361
  };
10402
11362
  return subtypeIcons[subtype] || formatIcons[format] || "\u{1F4E6}";
@@ -10410,8 +11370,13 @@ function getPackageLabel2(format, subtype) {
10410
11370
  "copilot": "GitHub Copilot",
10411
11371
  "kiro": "Kiro",
10412
11372
  "gemini": "Gemini",
11373
+ "gemini.md": "Gemini",
11374
+ "claude.md": "Claude",
11375
+ "opencode": "OpenCode",
11376
+ "droid": "Factory Droid",
10413
11377
  "mcp": "MCP",
10414
11378
  "agents.md": "Agents.md",
11379
+ "ruler": "Ruler",
10415
11380
  "generic": ""
10416
11381
  };
10417
11382
  const subtypeLabels = {
@@ -10596,10 +11561,13 @@ async function handleInstall(packageSpec, options) {
10596
11561
  throw new CLIError("Format conversion is only supported for single-file packages");
10597
11562
  }
10598
11563
  const sourceContent = extractedFiles[0].content;
11564
+ const scopeMatch = packageId.match(/^@([^/]+)\//);
11565
+ const author = scopeMatch ? scopeMatch[1] : "unknown";
10599
11566
  const metadata = {
10600
11567
  id: packageId,
10601
11568
  name: pkg.name || packageId,
10602
11569
  version: actualVersion,
11570
+ author,
10603
11571
  tags: pkg.tags || []
10604
11572
  };
10605
11573
  let canonicalPkg;
@@ -10695,6 +11663,7 @@ async function handleInstall(packageSpec, options) {
10695
11663
  locationOverride = void 0;
10696
11664
  }
10697
11665
  let destPath;
11666
+ let destDir = "";
10698
11667
  let fileCount = 0;
10699
11668
  let hookMetadata = void 0;
10700
11669
  if (format === "claude-md") {
@@ -10706,10 +11675,10 @@ async function handleInstall(packageSpec, options) {
10706
11675
  await saveFile(destPath, mainFile);
10707
11676
  fileCount = 1;
10708
11677
  } else if (extractedFiles.length === 1) {
10709
- let destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
11678
+ destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
10710
11679
  if (locationOverride && effectiveFormat === "cursor") {
10711
11680
  const relativeDestDir = destDir.startsWith("./") ? destDir.slice(2) : destDir;
10712
- destDir = import_path8.default.join(locationOverride, relativeDestDir);
11681
+ destDir = import_path9.default.join(locationOverride, relativeDestDir);
10713
11682
  console.log(` \u{1F4C1} Installing Cursor package to custom location: ${destDir}`);
10714
11683
  }
10715
11684
  let mainFile = extractedFiles[0].content;
@@ -10719,26 +11688,35 @@ async function handleInstall(packageSpec, options) {
10719
11688
  destPath = `${destDir}/SKILL.md`;
10720
11689
  } else if (effectiveFormat === "claude" && effectiveSubtype === "hook") {
10721
11690
  destPath = `${destDir}/settings.json`;
10722
- } else if (effectiveFormat === "agents.md") {
10723
- let targetPath = "AGENTS.md";
10724
- if (locationOverride) {
10725
- targetPath = import_path8.default.join(locationOverride, "AGENTS.override.md");
10726
- console.log(` \u{1F4C1} Installing Agents.md package to custom location: ${targetPath}`);
10727
- }
10728
- destPath = targetPath;
10729
- if (await fileExists(destPath)) {
10730
- if (options.force) {
10731
- console.log(` \u26A0\uFE0F ${destPath} already exists - overwriting (forced).`);
10732
- } else {
10733
- console.log(` \u26A0\uFE0F ${destPath} already exists.`);
10734
- const overwrite = await promptYesNo(
10735
- ` Overwrite existing ${destPath}? (y/N): `,
10736
- ` \u26A0\uFE0F Non-interactive terminal detected. Remove or rename ${destPath} to continue.`
10737
- );
10738
- if (!overwrite) {
10739
- console.log(` \u{1F6AB} Skipping install to avoid overwriting ${destPath}`);
10740
- success = true;
10741
- return;
11691
+ } else if (effectiveFormat === "agents.md" || effectiveFormat === "gemini.md" || effectiveFormat === "claude.md") {
11692
+ if (effectiveSubtype === "skill") {
11693
+ destPath = `${destDir}/SKILL.md`;
11694
+ console.log(` \u{1F4E6} Installing skill to ${destDir}/ for progressive disclosure`);
11695
+ } else if (effectiveSubtype === "agent") {
11696
+ destPath = `${destDir}/AGENT.md`;
11697
+ console.log(` \u{1F916} Installing agent to ${destDir}/ for progressive disclosure`);
11698
+ } else {
11699
+ const manifestFilename = getManifestFilename(effectiveFormat);
11700
+ let targetPath = manifestFilename;
11701
+ if (locationOverride) {
11702
+ targetPath = import_path9.default.join(locationOverride, `${manifestFilename.replace(".md", ".override.md")}`);
11703
+ console.log(` \u{1F4C1} Installing to custom location: ${targetPath}`);
11704
+ }
11705
+ destPath = targetPath;
11706
+ if (await fileExists(destPath)) {
11707
+ if (options.force) {
11708
+ console.log(` \u26A0\uFE0F ${destPath} already exists - overwriting (forced).`);
11709
+ } else {
11710
+ console.log(` \u26A0\uFE0F ${destPath} already exists.`);
11711
+ const overwrite = await promptYesNo(
11712
+ ` Overwrite existing ${destPath}? (y/N): `,
11713
+ ` \u26A0\uFE0F Non-interactive terminal detected. Remove or rename ${destPath} to continue.`
11714
+ );
11715
+ if (!overwrite) {
11716
+ console.log(` \u{1F6AB} Skipping install to avoid overwriting ${destPath}`);
11717
+ success = true;
11718
+ return;
11719
+ }
10742
11720
  }
10743
11721
  }
10744
11722
  }
@@ -10819,10 +11797,10 @@ async function handleInstall(packageSpec, options) {
10819
11797
  await saveFile(destPath, mainFile);
10820
11798
  fileCount = 1;
10821
11799
  } else {
10822
- let destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
11800
+ destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
10823
11801
  if (locationOverride && effectiveFormat === "cursor") {
10824
11802
  const relativeDestDir = destDir.startsWith("./") ? destDir.slice(2) : destDir;
10825
- destDir = import_path8.default.join(locationOverride, relativeDestDir);
11803
+ destDir = import_path9.default.join(locationOverride, relativeDestDir);
10826
11804
  console.log(` \u{1F4C1} Installing Cursor package to custom location: ${destDir}`);
10827
11805
  }
10828
11806
  const packageName = stripAuthorNamespace2(packageId);
@@ -10905,6 +11883,35 @@ ${afterFrontmatter}`;
10905
11883
  }
10906
11884
  }
10907
11885
  }
11886
+ let progressiveDisclosureMetadata;
11887
+ if ((effectiveFormat === "agents.md" || effectiveFormat === "gemini.md" || effectiveFormat === "claude.md") && (effectiveSubtype === "skill" || effectiveSubtype === "agent") && !options.noAppend) {
11888
+ if (!destDir) {
11889
+ throw new Error("Internal error: destDir not set for progressive disclosure installation");
11890
+ }
11891
+ const manifestPath = options.manifestFile || getManifestFilename(effectiveFormat);
11892
+ const resourceName = stripAuthorNamespace2(packageId);
11893
+ const resourceType = effectiveSubtype;
11894
+ const mainFile = resourceType === "agent" ? "AGENT.md" : "SKILL.md";
11895
+ const manifestEntry = {
11896
+ name: resourceName,
11897
+ description: pkg.description || `${pkg.name} ${resourceType}`,
11898
+ skillPath: destDir,
11899
+ mainFile,
11900
+ resourceType
11901
+ };
11902
+ await addSkillToManifest(manifestEntry, manifestPath);
11903
+ console.log(` \u2713 Added ${resourceType} to ${manifestPath} manifest`);
11904
+ progressiveDisclosureMetadata = {
11905
+ mode: "progressive",
11906
+ resourceDir: destDir,
11907
+ manifestPath,
11908
+ resourceName,
11909
+ resourceType,
11910
+ // Legacy fields for backward compatibility
11911
+ skillsDir: destDir,
11912
+ skillName: resourceName
11913
+ };
11914
+ }
10908
11915
  const updatedLockfile = lockfile || createLockfile();
10909
11916
  addToLockfile(updatedLockfile, packageId, {
10910
11917
  version: actualVersion || version,
@@ -10917,8 +11924,9 @@ ${afterFrontmatter}`;
10917
11924
  sourceSubtype: pkg.subtype,
10918
11925
  installedPath: destPath,
10919
11926
  fromCollection: options.fromCollection,
10920
- hookMetadata
11927
+ hookMetadata,
10921
11928
  // Track hook installation metadata for uninstall
11929
+ progressiveDisclosure: progressiveDisclosureMetadata
10922
11930
  });
10923
11931
  setPackageIntegrity(updatedLockfile, packageId, tarball);
10924
11932
  await writeLockfile(updatedLockfile);
@@ -10932,6 +11940,14 @@ ${afterFrontmatter}`;
10932
11940
  \u2705 Successfully installed ${packageId}`);
10933
11941
  console.log(` \u{1F4C1} Saved to: ${destPath}`);
10934
11942
  console.log(` \u{1F512} Lock file updated`);
11943
+ if (progressiveDisclosureMetadata && !options.noAppend) {
11944
+ const manifestFile = progressiveDisclosureMetadata.manifestPath;
11945
+ console.log(`
11946
+ \u{1F393} Skill installed with progressive disclosure`);
11947
+ console.log(` \u{1F4DD} Skill added to ${manifestFile} manifest`);
11948
+ console.log(` \u{1F4A1} The skill is available but not loaded into context by default`);
11949
+ console.log(` \u26A1 To activate: Add skill usage to your code or let the agent discover it`);
11950
+ }
10935
11951
  console.log(`
10936
11952
  \u{1F4A1} This package has been downloaded ${newDownloadCount.toLocaleString()} times`);
10937
11953
  success = true;
@@ -10973,7 +11989,7 @@ async function extractTarball(tarball, packageId) {
10973
11989
  } catch (error) {
10974
11990
  throw new CLIError(`Package decompression failed: ${error.message}`);
10975
11991
  }
10976
- const tmpDir = await import_promises2.default.mkdtemp(import_path8.default.join(import_os3.default.tmpdir(), "prpm-"));
11992
+ const tmpDir = await import_promises2.default.mkdtemp(import_path9.default.join(import_os3.default.tmpdir(), "prpm-"));
10977
11993
  const cleanup = async () => {
10978
11994
  try {
10979
11995
  await import_promises2.default.rm(tmpDir, { recursive: true, force: true });
@@ -11013,15 +12029,15 @@ async function extractTarball(tarball, packageId) {
11013
12029
  await cleanup();
11014
12030
  }
11015
12031
  }
11016
- async function collectExtractedFiles(rootDir, excludedNames, fs10) {
12032
+ async function collectExtractedFiles(rootDir, excludedNames, fs12) {
11017
12033
  const files = [];
11018
12034
  const dirs = [rootDir];
11019
12035
  while (dirs.length > 0) {
11020
12036
  const currentDir = dirs.pop();
11021
12037
  if (!currentDir) continue;
11022
- const entries = await fs10.readdir(currentDir, { withFileTypes: true });
12038
+ const entries = await fs12.readdir(currentDir, { withFileTypes: true });
11023
12039
  for (const entry of entries) {
11024
- const fullPath = import_path8.default.join(currentDir, entry.name);
12040
+ const fullPath = import_path9.default.join(currentDir, entry.name);
11025
12041
  if (entry.isDirectory()) {
11026
12042
  dirs.push(fullPath);
11027
12043
  continue;
@@ -11032,8 +12048,8 @@ async function collectExtractedFiles(rootDir, excludedNames, fs10) {
11032
12048
  if (excludedNames.has(entry.name)) {
11033
12049
  continue;
11034
12050
  }
11035
- const content = await fs10.readFile(fullPath, "utf-8");
11036
- const relativePath = import_path8.default.relative(rootDir, fullPath).split(import_path8.default.sep).join("/");
12051
+ const content = await fs12.readFile(fullPath, "utf-8");
12052
+ const relativePath = import_path9.default.relative(rootDir, fullPath).split(import_path9.default.sep).join("/");
11037
12053
  files.push({
11038
12054
  name: relativePath,
11039
12055
  content
@@ -11043,7 +12059,7 @@ async function collectExtractedFiles(rootDir, excludedNames, fs10) {
11043
12059
  return files;
11044
12060
  }
11045
12061
  async function installFromLockfile(options) {
11046
- var _a;
12062
+ var _a, _b;
11047
12063
  try {
11048
12064
  const lockfile = await readLockfile();
11049
12065
  if (!lockfile) {
@@ -11065,13 +12081,14 @@ async function installFromLockfile(options) {
11065
12081
  console.log(` Installing ${packageId}...`);
11066
12082
  let locationOverride = options.location;
11067
12083
  if (!locationOverride && lockEntry.format === "agents.md" && lockEntry.installedPath) {
11068
- const baseName = import_path8.default.basename(lockEntry.installedPath);
12084
+ const baseName = import_path9.default.basename(lockEntry.installedPath);
11069
12085
  if (baseName === "AGENTS.override.md") {
11070
- locationOverride = import_path8.default.dirname(lockEntry.installedPath);
12086
+ locationOverride = import_path9.default.dirname(lockEntry.installedPath);
11071
12087
  } else if (baseName !== "AGENTS.md") {
11072
- locationOverride = import_path8.default.dirname(lockEntry.installedPath);
12088
+ locationOverride = import_path9.default.dirname(lockEntry.installedPath);
11073
12089
  }
11074
12090
  }
12091
+ const manifestFile = (_a = lockEntry.progressiveDisclosure) == null ? void 0 : _a.manifestPath;
11075
12092
  await handleInstall(packageSpec, {
11076
12093
  version: lockEntry.version,
11077
12094
  as: options.as || lockEntry.format,
@@ -11079,7 +12096,8 @@ async function installFromLockfile(options) {
11079
12096
  frozenLockfile: options.frozenLockfile,
11080
12097
  force: true,
11081
12098
  // Force reinstall when installing from lockfile
11082
- location: locationOverride
12099
+ location: locationOverride,
12100
+ manifestFile
11083
12101
  });
11084
12102
  successCount++;
11085
12103
  } catch (error) {
@@ -11088,7 +12106,7 @@ async function installFromLockfile(options) {
11088
12106
  } else {
11089
12107
  failCount++;
11090
12108
  console.error(` \u274C Failed to install ${packageId}:`);
11091
- console.error(` Type: ${(_a = error == null ? void 0 : error.constructor) == null ? void 0 : _a.name}`);
12109
+ console.error(` Type: ${(_b = error == null ? void 0 : error.constructor) == null ? void 0 : _b.name}`);
11092
12110
  console.error(` Message: ${error instanceof Error ? error.message : String(error)}`);
11093
12111
  if (error instanceof CLIError) {
11094
12112
  console.error(` ExitCode: ${error.exitCode}`);
@@ -11110,9 +12128,9 @@ async function installFromLockfile(options) {
11110
12128
  }
11111
12129
  function createInstallCommand() {
11112
12130
  const command = new import_commander11.Command("install");
11113
- command.description("Install a package from the registry, or install all packages from prpm.lock if no package specified").argument("[package]", "Package to install (e.g., react-rules or react-rules@1.2.0). If omitted, installs all packages from prpm.lock").option("--version <version>", "Specific version to install").option("--as <format>", "Convert and install in specific format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, canonical)").option("--format <format>", "Alias for --as").option("--location <path>", "Custom location for installed files (Agents.md or nested Cursor rules)").option("--subtype <subtype>", "Specify subtype when converting (skill, agent, rule, etc.)").option("--frozen-lockfile", "Fail if lock file needs to be updated (for CI)").action(async (packageSpec, options) => {
12131
+ command.description("Install a package from the registry, or install all packages from prpm.lock if no package specified").argument("[package]", "Package to install (e.g., react-rules or react-rules@1.2.0). If omitted, installs all packages from prpm.lock").option("--version <version>", "Specific version to install").option("--as <format>", "Convert and install in specific format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, gemini.md, claude.md, canonical)").option("--format <format>", "Alias for --as").option("--location <path>", "Custom location for installed files (Agents.md or nested Cursor rules)").option("--subtype <subtype>", "Specify subtype when converting (skill, agent, rule, etc.)").option("--frozen-lockfile", "Fail if lock file needs to be updated (for CI)").option("--no-append", "Skip adding skill to manifest file (skill files only)").option("--manifest-file <filename>", "Custom manifest filename for progressive disclosure (default: AGENTS.md)", "AGENTS.md").action(async (packageSpec, options) => {
11114
12132
  const convertTo = options.format || options.as;
11115
- if (convertTo && !["cursor", "claude", "continue", "windsurf", "copilot", "kiro", "agents.md", "canonical", "gemini"].includes(convertTo)) {
12133
+ if (convertTo && !["cursor", "claude", "continue", "windsurf", "copilot", "kiro", "agents.md", "gemini.md", "claude.md", "canonical", "gemini"].includes(convertTo)) {
11116
12134
  throw new CLIError("\u274C Format must be one of: cursor, claude, continue, windsurf, copilot, kiro, agents.md, canonical, gemini\n\n\u{1F4A1} Examples:\n prpm install my-package --as cursor # Convert to Cursor format\n prpm install my-package --format claude # Convert to Claude format\n prpm install my-package --format kiro # Convert to Kiro format\n prpm install my-package --format agents.md # Convert to Agents.md format\n prpm install my-package # Install in native format", 1);
11117
12135
  }
11118
12136
  if (!packageSpec) {
@@ -11129,12 +12147,14 @@ function createInstallCommand() {
11129
12147
  as: convertTo,
11130
12148
  subtype: options.subtype,
11131
12149
  frozenLockfile: options.frozenLockfile,
11132
- location: options.location
12150
+ location: options.location,
12151
+ noAppend: options.noAppend,
12152
+ manifestFile: options.manifestFile
11133
12153
  });
11134
12154
  });
11135
12155
  return command;
11136
12156
  }
11137
- var import_commander11, import_chalk, import_registry_client5, import_stream, import_promises, tar, import_path8, import_zlib, import_promises2, import_os3;
12157
+ var import_commander11, import_chalk, import_registry_client5, import_stream, import_promises, tar, import_path9, import_zlib, import_promises2, import_os3;
11138
12158
  var init_install = __esm({
11139
12159
  "src/commands/install.ts"() {
11140
12160
  "use strict";
@@ -11150,7 +12170,7 @@ var init_install = __esm({
11150
12170
  tar = __toESM(require("tar"));
11151
12171
  init_errors();
11152
12172
  init_prompts();
11153
- import_path8 = __toESM(require("path"));
12173
+ import_path9 = __toESM(require("path"));
11154
12174
  import_zlib = __toESM(require("zlib"));
11155
12175
  import_promises2 = __toESM(require("fs/promises"));
11156
12176
  import_os3 = __toESM(require("os"));
@@ -11158,15 +12178,16 @@ var init_install = __esm({
11158
12178
  init_lockfile();
11159
12179
  init_cursor_config();
11160
12180
  init_claude_config();
12181
+ init_agents_md_progressive();
11161
12182
  init_dist();
11162
12183
  }
11163
12184
  });
11164
12185
 
11165
12186
  // src/index.ts
11166
12187
  init_cjs_shims();
11167
- var import_commander28 = require("commander");
11168
- var import_fs13 = require("fs");
11169
- var import_path16 = require("path");
12188
+ var import_commander29 = require("commander");
12189
+ var import_fs15 = require("fs");
12190
+ var import_path18 = require("path");
11170
12191
 
11171
12192
  // src/commands/list.ts
11172
12193
  init_cjs_shims();
@@ -11325,8 +12346,9 @@ init_cjs_shims();
11325
12346
  var import_commander2 = require("commander");
11326
12347
  init_lockfile();
11327
12348
  init_filesystem();
11328
- var import_fs6 = require("fs");
12349
+ var import_fs7 = require("fs");
11329
12350
  init_errors();
12351
+ init_agents_md_progressive();
11330
12352
  async function handleUninstall(name) {
11331
12353
  try {
11332
12354
  console.log(`\u{1F5D1}\uFE0F Uninstalling package: ${name}`);
@@ -11334,10 +12356,22 @@ async function handleUninstall(name) {
11334
12356
  if (!pkg) {
11335
12357
  throw new CLIError(`\u274C Package "${name}" not found`, 1);
11336
12358
  }
12359
+ if (pkg.progressiveDisclosure) {
12360
+ const { manifestPath, resourceName, skillName } = pkg.progressiveDisclosure;
12361
+ const name2 = resourceName || skillName;
12362
+ if (name2) {
12363
+ try {
12364
+ await removeSkillFromManifest(name2, manifestPath);
12365
+ console.log(` \u{1F4DD} Removed from ${manifestPath} manifest`);
12366
+ } catch (error) {
12367
+ console.warn(` \u26A0\uFE0F Failed to remove from manifest: ${error}`);
12368
+ }
12369
+ }
12370
+ }
11337
12371
  if (pkg.format === "claude" && pkg.subtype === "hook" && pkg.hookMetadata) {
11338
12372
  const settingsPath = pkg.installedPath || ".claude/settings.json";
11339
12373
  try {
11340
- const settingsContent = await import_fs6.promises.readFile(settingsPath, "utf-8");
12374
+ const settingsContent = await import_fs7.promises.readFile(settingsPath, "utf-8");
11341
12375
  const settings = JSON.parse(settingsContent);
11342
12376
  if (settings.hooks) {
11343
12377
  let removedCount = 0;
@@ -11354,7 +12388,7 @@ async function handleUninstall(name) {
11354
12388
  }
11355
12389
  }
11356
12390
  }
11357
- await import_fs6.promises.writeFile(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
12391
+ await import_fs7.promises.writeFile(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
11358
12392
  console.log(` \u{1FA9D} Removed ${removedCount} hook(s) from ${settingsPath}`);
11359
12393
  }
11360
12394
  } catch (error) {
@@ -11379,12 +12413,12 @@ async function handleUninstall(name) {
11379
12413
  throw new CLIError(`Cannot uninstall ${name}: installation path unknown`, 1);
11380
12414
  }
11381
12415
  try {
11382
- const stats = await import_fs6.promises.stat(targetPath);
12416
+ const stats = await import_fs7.promises.stat(targetPath);
11383
12417
  if (stats.isDirectory()) {
11384
- await import_fs6.promises.rm(targetPath, { recursive: true, force: true });
12418
+ await import_fs7.promises.rm(targetPath, { recursive: true, force: true });
11385
12419
  console.log(` \u{1F5D1}\uFE0F Deleted directory: ${targetPath}`);
11386
12420
  } else if (stats.isFile()) {
11387
- await import_fs6.promises.unlink(targetPath);
12421
+ await import_fs7.promises.unlink(targetPath);
11388
12422
  console.log(` \u{1F5D1}\uFE0F Deleted file: ${targetPath}`);
11389
12423
  }
11390
12424
  } catch (error) {
@@ -11412,17 +12446,17 @@ function createUninstallCommand() {
11412
12446
  // src/commands/index.ts
11413
12447
  init_cjs_shims();
11414
12448
  var import_commander3 = require("commander");
11415
- var import_fs7 = require("fs");
11416
- var import_path6 = __toESM(require("path"));
12449
+ var import_fs8 = require("fs");
12450
+ var import_path7 = __toESM(require("path"));
11417
12451
  init_lockfile();
11418
12452
  init_filesystem();
11419
12453
  init_errors();
11420
12454
  async function scanDirectory(dirPath, format, subtype) {
11421
12455
  try {
11422
- const files = await import_fs7.promises.readdir(dirPath, { withFileTypes: true });
12456
+ const files = await import_fs8.promises.readdir(dirPath, { withFileTypes: true });
11423
12457
  const results = [];
11424
12458
  for (const file of files) {
11425
- const fullPath = import_path6.default.join(dirPath, file.name);
12459
+ const fullPath = import_path7.default.join(dirPath, file.name);
11426
12460
  if (file.isFile()) {
11427
12461
  const id = generateId(file.name);
11428
12462
  results.push({
@@ -11435,11 +12469,11 @@ async function scanDirectory(dirPath, format, subtype) {
11435
12469
  const isCursorAgent = format === "cursor" && subtype === "agent";
11436
12470
  if (isClaudeType || isCursorAgent) {
11437
12471
  try {
11438
- const subFiles = await import_fs7.promises.readdir(fullPath, { withFileTypes: true });
12472
+ const subFiles = await import_fs8.promises.readdir(fullPath, { withFileTypes: true });
11439
12473
  for (const subFile of subFiles) {
11440
12474
  const isValidFile = subFile.isFile() && (subFile.name === "SKILL.md" || subFile.name === "AGENT.md" || subFile.name === "skill.md" || subFile.name === "agent.md");
11441
12475
  if (isValidFile) {
11442
- const subFilePath = import_path6.default.join(fullPath, subFile.name);
12476
+ const subFilePath = import_path7.default.join(fullPath, subFile.name);
11443
12477
  const id = file.name;
11444
12478
  results.push({
11445
12479
  filePath: subFilePath,
@@ -11501,7 +12535,7 @@ async function handleIndex(options = {}) {
11501
12535
  id: file.id,
11502
12536
  version: "0.0.0",
11503
12537
  // Local files don't have versions
11504
- tarballUrl: `file://${import_path6.default.resolve(file.filePath)}`,
12538
+ tarballUrl: `file://${import_path7.default.resolve(file.filePath)}`,
11505
12539
  format: dir.format,
11506
12540
  subtype: dir.subtype
11507
12541
  });
@@ -11767,8 +12801,13 @@ function getPackageIcon(format, subtype) {
11767
12801
  "copilot": "\u2708\uFE0F",
11768
12802
  "kiro": "\u{1F3AF}",
11769
12803
  "gemini": "\u2728",
12804
+ "gemini.md": "\u2728",
12805
+ "claude.md": "\u{1F916}",
12806
+ "opencode": "\u26A1",
12807
+ "droid": "\u{1F3ED}",
11770
12808
  "mcp": "\u{1F517}",
11771
12809
  "agents.md": "\u{1F4DD}",
12810
+ "ruler": "\u{1F4CF}",
11772
12811
  "generic": "\u{1F4E6}"
11773
12812
  };
11774
12813
  return subtypeIcons[subtype] || formatIcons[format] || "\u{1F4E6}";
@@ -11782,8 +12821,13 @@ function getPackageLabel(format, subtype) {
11782
12821
  "copilot": "GitHub Copilot",
11783
12822
  "kiro": "Kiro",
11784
12823
  "gemini": "Gemini",
12824
+ "gemini.md": "Gemini",
12825
+ "claude.md": "Claude",
12826
+ "opencode": "OpenCode",
12827
+ "droid": "Factory Droid",
11785
12828
  "mcp": "MCP",
11786
12829
  "agents.md": "Agents.md",
12830
+ "ruler": "Ruler",
11787
12831
  "generic": ""
11788
12832
  };
11789
12833
  const subtypeLabels = {
@@ -11991,6 +13035,22 @@ Try:`);
11991
13035
  \u{1F310} View in browser: ${webappUrl}`);
11992
13036
  return;
11993
13037
  }
13038
+ if (result.fallback) {
13039
+ console.log("\n\u274C No packages found for your search");
13040
+ let filterMsg = "";
13041
+ if (options.subtype) {
13042
+ filterMsg = ` (${options.subtype}`;
13043
+ if (options.format) {
13044
+ filterMsg += ` for ${options.format}`;
13045
+ }
13046
+ filterMsg += ")";
13047
+ } else if (options.format) {
13048
+ filterMsg = ` (${options.format} format)`;
13049
+ }
13050
+ console.log(`
13051
+ \u{1F4A1} Showing top 10 most popular packages${filterMsg} instead:
13052
+ `);
13053
+ }
11994
13054
  const totalPages = Math.ceil(result.total / limit);
11995
13055
  const shouldPaginate = options.interactive !== false && totalPages > 1;
11996
13056
  if (!shouldPaginate) {
@@ -12292,7 +13352,7 @@ init_install();
12292
13352
  init_cjs_shims();
12293
13353
  var import_commander12 = require("commander");
12294
13354
  var import_promises6 = require("fs/promises");
12295
- var import_path12 = require("path");
13355
+ var import_path13 = require("path");
12296
13356
  var tar2 = __toESM(require("tar"));
12297
13357
  var import_os4 = require("os");
12298
13358
  var import_crypto2 = require("crypto");
@@ -12465,19 +13525,19 @@ function validateMarketplaceJson(data) {
12465
13525
  init_cjs_shims();
12466
13526
  var import_ajv2 = __toESM(require("ajv"));
12467
13527
  var import_ajv_formats2 = __toESM(require("ajv-formats"));
12468
- var import_fs9 = require("fs");
12469
- var import_path9 = require("path");
13528
+ var import_fs10 = require("fs");
13529
+ var import_path10 = require("path");
12470
13530
  var schema2;
12471
13531
  var schemaCandidates = [
12472
13532
  // Source file layout (src/core → ../../schemas)
12473
- (0, import_path9.join)(__dirname, "../../schemas/prpm-manifest.schema.json"),
13533
+ (0, import_path10.join)(__dirname, "../../schemas/prpm-manifest.schema.json"),
12474
13534
  // Bundled layout (dist/index.js → ../schemas)
12475
- (0, import_path9.join)(__dirname, "../schemas/prpm-manifest.schema.json")
13535
+ (0, import_path10.join)(__dirname, "../schemas/prpm-manifest.schema.json")
12476
13536
  ];
12477
13537
  for (const candidate of schemaCandidates) {
12478
13538
  try {
12479
- if ((0, import_fs9.existsSync)(candidate)) {
12480
- schema2 = JSON.parse((0, import_fs9.readFileSync)(candidate, "utf-8"));
13539
+ if ((0, import_fs10.existsSync)(candidate)) {
13540
+ schema2 = JSON.parse((0, import_fs10.readFileSync)(candidate, "utf-8"));
12481
13541
  break;
12482
13542
  }
12483
13543
  } catch {
@@ -12499,27 +13559,27 @@ function validateManifestSchema(manifest) {
12499
13559
  const valid = validate(manifest);
12500
13560
  if (!valid && validate.errors) {
12501
13561
  const errors = validate.errors.map((err) => {
12502
- const path7 = err.instancePath || "manifest";
13562
+ const path8 = err.instancePath || "manifest";
12503
13563
  const message = err.message || "validation failed";
12504
13564
  if (err.keyword === "required") {
12505
13565
  const missingProp = err.params.missingProperty;
12506
13566
  return `Missing required field: ${missingProp}`;
12507
13567
  }
12508
13568
  if (err.keyword === "pattern") {
12509
- return `${path7}: ${message}. Value does not match required pattern.`;
13569
+ return `${path8}: ${message}. Value does not match required pattern.`;
12510
13570
  }
12511
13571
  if (err.keyword === "enum") {
12512
13572
  const allowedValues = err.params.allowedValues;
12513
- return `${path7}: ${message}. Allowed values: ${allowedValues.join(", ")}`;
13573
+ return `${path8}: ${message}. Allowed values: ${allowedValues.join(", ")}`;
12514
13574
  }
12515
13575
  if (err.keyword === "minLength" || err.keyword === "maxLength") {
12516
13576
  const limit = err.params.limit;
12517
- return `${path7}: ${message} (${err.keyword}: ${limit})`;
13577
+ return `${path8}: ${message} (${err.keyword}: ${limit})`;
12518
13578
  }
12519
13579
  if (err.keyword === "oneOf") {
12520
- return `${path7}: must match exactly one schema (check if files array uses either all strings or all objects, not mixed)`;
13580
+ return `${path8}: must match exactly one schema (check if files array uses either all strings or all objects, not mixed)`;
12521
13581
  }
12522
- return `${path7}: ${message}`;
13582
+ return `${path8}: ${message}`;
12523
13583
  });
12524
13584
  return { valid: false, errors };
12525
13585
  }
@@ -12532,8 +13592,8 @@ function getManifestSchema() {
12532
13592
  // src/utils/license-extractor.ts
12533
13593
  init_cjs_shims();
12534
13594
  var import_promises3 = require("fs/promises");
12535
- var import_path10 = require("path");
12536
- var import_fs10 = require("fs");
13595
+ var import_path11 = require("path");
13596
+ var import_fs11 = require("fs");
12537
13597
  var LICENSE_FILE_PATTERNS = [
12538
13598
  "LICENSE",
12539
13599
  "LICENSE.md",
@@ -12582,9 +13642,9 @@ function generateLicenseUrl(repositoryUrl, fileName) {
12582
13642
  async function extractLicenseInfo(repositoryUrl) {
12583
13643
  const cwd = process.cwd();
12584
13644
  for (const fileName of LICENSE_FILE_PATTERNS) {
12585
- const filePath = (0, import_path10.join)(cwd, fileName);
13645
+ const filePath = (0, import_path11.join)(cwd, fileName);
12586
13646
  try {
12587
- await (0, import_promises3.access)(filePath, import_fs10.constants.R_OK);
13647
+ await (0, import_promises3.access)(filePath, import_fs11.constants.R_OK);
12588
13648
  const text = await (0, import_promises3.readFile)(filePath, "utf-8");
12589
13649
  const type2 = detectLicenseType(text);
12590
13650
  const url = generateLicenseUrl(repositoryUrl, fileName);
@@ -12618,7 +13678,7 @@ function validateLicenseInfo(licenseInfo, packageName) {
12618
13678
  // src/utils/snippet-extractor.ts
12619
13679
  init_cjs_shims();
12620
13680
  var import_promises4 = require("fs/promises");
12621
- var import_path11 = require("path");
13681
+ var import_path12 = require("path");
12622
13682
  var MAX_SNIPPET_LENGTH = 2e3;
12623
13683
  async function extractSnippet(manifest) {
12624
13684
  const cwd = process.cwd();
@@ -12634,7 +13694,7 @@ async function extractSnippet(manifest) {
12634
13694
  const firstFile = manifest.files[0];
12635
13695
  fileName = typeof firstFile === "string" ? firstFile : firstFile.path;
12636
13696
  }
12637
- const fullPath = (0, import_path11.join)(cwd, fileName);
13697
+ const fullPath = (0, import_path12.join)(cwd, fileName);
12638
13698
  const stats = await (0, import_promises4.stat)(fullPath);
12639
13699
  if (stats.isDirectory()) {
12640
13700
  console.warn(`\u26A0\uFE0F Skipping snippet extraction: "${fullPath}" is a directory`);
@@ -12860,13 +13920,13 @@ async function validatePackageFiles(manifest) {
12860
13920
  }
12861
13921
  }
12862
13922
  if (manifest.format === "claude" && manifest.subtype === "skill") {
12863
- const hasSkillMd = filePaths.some((path7) => path7.endsWith("/SKILL.md") || path7 === "SKILL.md");
13923
+ const hasSkillMd = filePaths.some((path8) => path8.endsWith("/SKILL.md") || path8 === "SKILL.md");
12864
13924
  if (!hasSkillMd) {
12865
13925
  errors.push("Claude skills must contain a SKILL.md file");
12866
13926
  }
12867
13927
  }
12868
13928
  if (manifest.format === "windsurf") {
12869
- const hasWindsurfRules = filePaths.some((path7) => path7.includes(".windsurf/rules"));
13929
+ const hasWindsurfRules = filePaths.some((path8) => path8.includes(".windsurf/rules"));
12870
13930
  if (!hasWindsurfRules) {
12871
13931
  warnings.push("Windsurf packages typically use .windsurf/rules filename");
12872
13932
  }
@@ -12876,7 +13936,7 @@ async function validatePackageFiles(manifest) {
12876
13936
 
12877
13937
  // src/commands/publish.ts
12878
13938
  async function findAndLoadManifests() {
12879
- const prpmJsonPath = (0, import_path12.join)(process.cwd(), "prpm.json");
13939
+ const prpmJsonPath = (0, import_path13.join)(process.cwd(), "prpm.json");
12880
13940
  let prpmJsonExists = false;
12881
13941
  let prpmJsonError = null;
12882
13942
  try {
@@ -12928,7 +13988,7 @@ async function findAndLoadManifests() {
12928
13988
  throw error;
12929
13989
  }
12930
13990
  }
12931
- const marketplaceJsonPath = (0, import_path12.join)(process.cwd(), ".claude", "marketplace.json");
13991
+ const marketplaceJsonPath = (0, import_path13.join)(process.cwd(), ".claude", "marketplace.json");
12932
13992
  try {
12933
13993
  const content = await (0, import_promises6.readFile)(marketplaceJsonPath, "utf-8");
12934
13994
  const marketplaceData = JSON.parse(content);
@@ -12944,7 +14004,7 @@ async function findAndLoadManifests() {
12944
14004
  return { manifests, collections: [], source: ".claude/marketplace.json" };
12945
14005
  } catch (error) {
12946
14006
  }
12947
- const marketplaceJsonPluginPath = (0, import_path12.join)(process.cwd(), ".claude-plugin", "marketplace.json");
14007
+ const marketplaceJsonPluginPath = (0, import_path13.join)(process.cwd(), ".claude-plugin", "marketplace.json");
12948
14008
  try {
12949
14009
  const content = await (0, import_promises6.readFile)(marketplaceJsonPluginPath, "utf-8");
12950
14010
  const marketplaceData = JSON.parse(content);
@@ -12988,7 +14048,7 @@ function validateManifest(manifest, contextLabel) {
12988
14048
  }
12989
14049
  if (manifest.format === "claude" && manifest.subtype === "skill") {
12990
14050
  const filePaths = normalizeFilePaths2(manifest.files);
12991
- const hasSkillMd = filePaths.some((path7) => path7.endsWith("/SKILL.md") || path7 === "SKILL.md");
14051
+ const hasSkillMd = filePaths.some((path8) => path8.endsWith("/SKILL.md") || path8 === "SKILL.md");
12992
14052
  if (!hasSkillMd) {
12993
14053
  throw new Error(
12994
14054
  `${prefix}Claude skills must contain a SKILL.md file.
@@ -13061,8 +14121,8 @@ function predictScopedPackageName(manifestName, username, organization) {
13061
14121
  return manifestName;
13062
14122
  }
13063
14123
  async function createTarball(manifest) {
13064
- const tmpDir = (0, import_path12.join)((0, import_os4.tmpdir)(), `prpm-${(0, import_crypto2.randomBytes)(8).toString("hex")}`);
13065
- const tarballPath = (0, import_path12.join)(tmpDir, "package.tar.gz");
14124
+ const tmpDir = (0, import_path13.join)((0, import_os4.tmpdir)(), `prpm-${(0, import_crypto2.randomBytes)(8).toString("hex")}`);
14125
+ const tarballPath = (0, import_path13.join)(tmpDir, "package.tar.gz");
13066
14126
  try {
13067
14127
  await (0, import_promises6.mkdir)(tmpDir, { recursive: true });
13068
14128
  const filePaths = normalizeFilePaths2(manifest.files);
@@ -13123,7 +14183,7 @@ async function handlePublish(options) {
13123
14183
  const { manifests, collections, source } = await findAndLoadManifests();
13124
14184
  if (source === "prpm.json (multi-package)" || source === "prpm.json") {
13125
14185
  try {
13126
- const prpmJsonPath = (0, import_path12.join)(process.cwd(), "prpm.json");
14186
+ const prpmJsonPath = (0, import_path13.join)(process.cwd(), "prpm.json");
13127
14187
  const prpmContent = await (0, import_promises6.readFile)(prpmJsonPath, "utf-8");
13128
14188
  const prpmManifest = JSON.parse(prpmContent);
13129
14189
  if (prpmManifest.scripts) {
@@ -14117,8 +15177,8 @@ function createSchemaCommand() {
14117
15177
  init_cjs_shims();
14118
15178
  var import_commander19 = require("commander");
14119
15179
  var import_promises7 = require("fs/promises");
14120
- var import_path13 = require("path");
14121
- var import_fs11 = require("fs");
15180
+ var import_path14 = require("path");
15181
+ var import_fs12 = require("fs");
14122
15182
  var readline3 = __toESM(require("readline/promises"));
14123
15183
  var import_process = require("process");
14124
15184
 
@@ -14485,12 +15545,12 @@ function getDefaultAuthor() {
14485
15545
  async function createExampleFiles(format, files, packageName) {
14486
15546
  const templates = EXAMPLE_TEMPLATES[format] || {};
14487
15547
  for (const file of files) {
14488
- const filePath = (0, import_path13.join)(process.cwd(), file);
14489
- const dirPath = (0, import_path13.join)(filePath, "..");
14490
- if (!(0, import_fs11.existsSync)(dirPath)) {
15548
+ const filePath = (0, import_path14.join)(process.cwd(), file);
15549
+ const dirPath = (0, import_path14.join)(filePath, "..");
15550
+ if (!(0, import_fs12.existsSync)(dirPath)) {
14491
15551
  await (0, import_promises7.mkdir)(dirPath, { recursive: true });
14492
15552
  }
14493
- if ((0, import_fs11.existsSync)(filePath)) {
15553
+ if ((0, import_fs12.existsSync)(filePath)) {
14494
15554
  console.log(` Skipping ${file} (already exists)`);
14495
15555
  continue;
14496
15556
  }
@@ -14504,8 +15564,8 @@ Add your content here.
14504
15564
  }
14505
15565
  }
14506
15566
  async function createReadme(config) {
14507
- const readmePath = (0, import_path13.join)(process.cwd(), "README.md");
14508
- if ((0, import_fs11.existsSync)(readmePath)) {
15567
+ const readmePath = (0, import_path14.join)(process.cwd(), "README.md");
15568
+ if ((0, import_fs12.existsSync)(readmePath)) {
14509
15569
  console.log(" Skipping README.md (already exists)");
14510
15570
  return;
14511
15571
  }
@@ -14539,8 +15599,8 @@ ${config.license}
14539
15599
  console.log(" Created README.md");
14540
15600
  }
14541
15601
  async function initPackage(options) {
14542
- const manifestPath = (0, import_path13.join)(process.cwd(), "prpm.json");
14543
- if ((0, import_fs11.existsSync)(manifestPath) && !options.force) {
15602
+ const manifestPath = (0, import_path14.join)(process.cwd(), "prpm.json");
15603
+ if ((0, import_fs12.existsSync)(manifestPath) && !options.force) {
14544
15604
  throw new Error(
14545
15605
  "prpm.json already exists. Use --force to overwrite, or run this command in a different directory."
14546
15606
  );
@@ -14839,15 +15899,15 @@ function createConfigCommand() {
14839
15899
  init_cjs_shims();
14840
15900
  var import_commander21 = require("commander");
14841
15901
  var import_promises8 = require("fs/promises");
14842
- var import_path14 = require("path");
15902
+ var import_path15 = require("path");
14843
15903
  init_telemetry();
14844
15904
  init_lockfile();
14845
15905
  init_errors();
14846
15906
  function detectPackageInfo(filePath, content) {
14847
- const fileName = (0, import_path14.basename)(filePath);
15907
+ const fileName = (0, import_path15.basename)(filePath);
14848
15908
  const lowerFileName = fileName.toLowerCase();
14849
15909
  if (fileName === "SKILL.md") {
14850
- const dirName = (0, import_path14.basename)((0, import_path14.join)(filePath, ".."));
15910
+ const dirName = (0, import_path15.basename)((0, import_path15.join)(filePath, ".."));
14851
15911
  return {
14852
15912
  format: "claude",
14853
15913
  subtype: "skill",
@@ -14899,8 +15959,8 @@ async function scanDirectory2(dirPath, baseDir, scanDir, maxDepth = 5, currentDe
14899
15959
  try {
14900
15960
  const entries = await (0, import_promises8.readdir)(dirPath, { withFileTypes: true });
14901
15961
  for (const entry of entries) {
14902
- const fullPath = (0, import_path14.join)(dirPath, entry.name);
14903
- const relativePath = (0, import_path14.relative)(baseDir, fullPath);
15962
+ const fullPath = (0, import_path15.join)(dirPath, entry.name);
15963
+ const relativePath = (0, import_path15.relative)(baseDir, fullPath);
14904
15964
  if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist" || entry.name === "build") {
14905
15965
  continue;
14906
15966
  }
@@ -15037,7 +16097,7 @@ async function handleCatalog(directories, options) {
15037
16097
  success = true;
15038
16098
  return;
15039
16099
  }
15040
- const prpmJsonPath = options.output || (0, import_path14.join)(process.cwd(), "prpm.json");
16100
+ const prpmJsonPath = options.output || (0, import_path15.join)(process.cwd(), "prpm.json");
15041
16101
  let manifest;
15042
16102
  if (options.append) {
15043
16103
  try {
@@ -15075,7 +16135,7 @@ async function handleCatalog(directories, options) {
15075
16135
  }
15076
16136
  let description = `${discovered.format} ${discovered.subtype}`;
15077
16137
  try {
15078
- const firstFilePath = (0, import_path14.join)(process.cwd(), discovered.scanDir, discovered.files[0]);
16138
+ const firstFilePath = (0, import_path15.join)(process.cwd(), discovered.scanDir, discovered.files[0]);
15079
16139
  const content = await (0, import_promises8.readFile)(firstFilePath, "utf-8");
15080
16140
  const extractedDesc = extractDescription2(content);
15081
16141
  if (extractedDesc) {
@@ -15140,8 +16200,8 @@ var import_commander22 = require("commander");
15140
16200
  init_user_config();
15141
16201
  init_telemetry();
15142
16202
  var readline4 = __toESM(require("readline"));
15143
- var fs9 = __toESM(require("fs"));
15144
- var path6 = __toESM(require("path"));
16203
+ var fs10 = __toESM(require("fs"));
16204
+ var path7 = __toESM(require("path"));
15145
16205
  init_errors();
15146
16206
  function createReadline() {
15147
16207
  return readline4.createInterface({
@@ -15259,11 +16319,11 @@ async function runCustomPrompt(customPrompt, input2, options, sessionId) {
15259
16319
  return response.json();
15260
16320
  }
15261
16321
  function readPromptFile(filePath) {
15262
- const absolutePath = path6.resolve(filePath);
15263
- if (!fs9.existsSync(absolutePath)) {
16322
+ const absolutePath = path7.resolve(filePath);
16323
+ if (!fs10.existsSync(absolutePath)) {
15264
16324
  throw new Error(`Prompt file not found: ${filePath}`);
15265
16325
  }
15266
- return fs9.readFileSync(absolutePath, "utf-8");
16326
+ return fs10.readFileSync(absolutePath, "utf-8");
15267
16327
  }
15268
16328
  function displayResponse(result, showStats = true) {
15269
16329
  const lastMessage = result.conversation[result.conversation.length - 1];
@@ -16326,52 +17386,57 @@ function createStarredCommand() {
16326
17386
  init_cjs_shims();
16327
17387
  var import_commander27 = require("commander");
16328
17388
  var import_promises9 = require("fs/promises");
16329
- var import_path15 = require("path");
16330
- var import_fs12 = require("fs");
17389
+ var import_path16 = require("path");
17390
+ var import_fs13 = require("fs");
16331
17391
  var import_readline = require("readline");
16332
17392
  var import_chalk2 = __toESM(require_source());
16333
17393
  init_errors();
16334
17394
  init_dist();
16335
- function getDefaultPath(format, filename, subtype) {
16336
- const baseName = (0, import_path15.basename)(filename, (0, import_path15.extname)(filename));
17395
+ function getDefaultPath(format, filename, subtype, customName) {
17396
+ const baseName = customName || (0, import_path16.basename)(filename, (0, import_path16.extname)(filename));
16337
17397
  switch (format) {
16338
17398
  case "cursor":
16339
17399
  if (subtype === "slash-command") {
16340
- return (0, import_path15.join)(process.cwd(), ".cursor", "commands", `${baseName}.md`);
17400
+ return (0, import_path16.join)(process.cwd(), ".cursor", "commands", `${baseName}.md`);
16341
17401
  }
16342
- return (0, import_path15.join)(process.cwd(), ".cursor", "rules", `${baseName}.mdc`);
17402
+ return (0, import_path16.join)(process.cwd(), ".cursor", "rules", `${baseName}.mdc`);
16343
17403
  case "claude":
16344
17404
  if (subtype === "skill") {
16345
- return (0, import_path15.join)(process.cwd(), ".claude", "skills", baseName, "SKILL.md");
17405
+ return (0, import_path16.join)(process.cwd(), ".claude", "skills", baseName, "SKILL.md");
16346
17406
  } else if (subtype === "slash-command") {
16347
- return (0, import_path15.join)(process.cwd(), ".claude", "commands", `${baseName}.md`);
17407
+ return (0, import_path16.join)(process.cwd(), ".claude", "commands", `${baseName}.md`);
16348
17408
  } else {
16349
- return (0, import_path15.join)(process.cwd(), ".claude", "agents", `${baseName}.md`);
17409
+ return (0, import_path16.join)(process.cwd(), ".claude", "agents", `${baseName}.md`);
16350
17410
  }
16351
17411
  case "windsurf":
16352
- return (0, import_path15.join)(process.cwd(), ".windsurf", "rules", `${baseName}.md`);
17412
+ return (0, import_path16.join)(process.cwd(), ".windsurf", "rules", `${baseName}.md`);
16353
17413
  case "kiro":
16354
17414
  if (subtype === "hook") {
16355
- return (0, import_path15.join)(process.cwd(), ".kiro", "hooks", `${baseName}.kiro.hook`);
17415
+ return (0, import_path16.join)(process.cwd(), ".kiro", "hooks", `${baseName}.kiro.hook`);
16356
17416
  }
16357
- return (0, import_path15.join)(process.cwd(), ".kiro", "steering", `${baseName}.md`);
17417
+ if (subtype === "agent") {
17418
+ return (0, import_path16.join)(process.cwd(), ".kiro", "agents", `${baseName}.json`);
17419
+ }
17420
+ return (0, import_path16.join)(process.cwd(), ".kiro", "steering", `${baseName}.md`);
16358
17421
  case "copilot":
16359
- return (0, import_path15.join)(process.cwd(), ".github", "instructions", `${baseName}.instructions.md`);
17422
+ return (0, import_path16.join)(process.cwd(), ".github", "instructions", `${baseName}.instructions.md`);
16360
17423
  case "continue":
16361
17424
  if (subtype === "slash-command" || subtype === "prompt") {
16362
- return (0, import_path15.join)(process.cwd(), ".continue", "prompts", `${baseName}.md`);
17425
+ return (0, import_path16.join)(process.cwd(), ".continue", "prompts", `${baseName}.md`);
16363
17426
  }
16364
- return (0, import_path15.join)(process.cwd(), ".continue", "rules", `${baseName}.md`);
17427
+ return (0, import_path16.join)(process.cwd(), ".continue", "rules", `${baseName}.md`);
16365
17428
  case "agents.md":
16366
- return (0, import_path15.join)(process.cwd(), "agents.md");
17429
+ return (0, import_path16.join)(process.cwd(), "agents.md");
16367
17430
  case "gemini":
16368
- return (0, import_path15.join)(process.cwd(), ".gemini", "commands", `${baseName}.toml`);
17431
+ return (0, import_path16.join)(process.cwd(), ".gemini", "commands", `${baseName}.toml`);
17432
+ case "ruler":
17433
+ return (0, import_path16.join)(process.cwd(), ".ruler", `${baseName}.md`);
16369
17434
  default:
16370
17435
  throw new CLIError(`Unknown format: ${format}`);
16371
17436
  }
16372
17437
  }
16373
17438
  function detectFormat(content, filepath) {
16374
- const ext = (0, import_path15.extname)(filepath).toLowerCase();
17439
+ const ext = (0, import_path16.extname)(filepath).toLowerCase();
16375
17440
  if (ext === ".mdc" || filepath.includes(".cursor/rules") || filepath.includes(".cursor/commands")) {
16376
17441
  return "cursor";
16377
17442
  }
@@ -16393,12 +17458,15 @@ function detectFormat(content, filepath) {
16393
17458
  if (filepath.includes(".continue/rules") || filepath.includes(".continue/prompts") || filepath.includes(".continuerules")) {
16394
17459
  return "continue";
16395
17460
  }
16396
- if ((0, import_path15.basename)(filepath) === "agents.md") {
17461
+ if ((0, import_path16.basename)(filepath) === "agents.md") {
16397
17462
  return "agents.md";
16398
17463
  }
16399
17464
  if (ext === ".toml" || filepath.includes(".gemini/commands")) {
16400
17465
  return "gemini";
16401
17466
  }
17467
+ if (filepath.includes(".ruler/")) {
17468
+ return "ruler";
17469
+ }
16402
17470
  if (isClaudeFormat(content)) {
16403
17471
  if (content.includes("type: skill")) return "claude-skill";
16404
17472
  if (content.includes("type: agent")) return "claude-agent";
@@ -16411,6 +17479,7 @@ function detectFormat(content, filepath) {
16411
17479
  if (isCopilotFormat(content)) return "copilot";
16412
17480
  if (isContinueFormat(content)) return "continue";
16413
17481
  if (isAgentsMdFormat(content)) return "agents.md";
17482
+ if (isRulerFormat(content)) return "ruler";
16414
17483
  return null;
16415
17484
  }
16416
17485
  async function confirmOverwrite(filepath) {
@@ -16474,7 +17543,12 @@ async function handleConvert(sourcePath, options) {
16474
17543
  canonicalPkg = fromWindsurf(content, metadata);
16475
17544
  break;
16476
17545
  case "kiro":
16477
- canonicalPkg = fromKiro(content, metadata);
17546
+ if (isKiroAgentFormat(content)) {
17547
+ const result2 = fromKiroAgent(content);
17548
+ canonicalPkg = JSON.parse(result2.content);
17549
+ } else {
17550
+ canonicalPkg = fromKiro(content, metadata);
17551
+ }
16478
17552
  break;
16479
17553
  case "copilot":
16480
17554
  canonicalPkg = fromCopilot(content, metadata);
@@ -16488,6 +17562,10 @@ async function handleConvert(sourcePath, options) {
16488
17562
  case "gemini":
16489
17563
  canonicalPkg = fromGemini(content, metadata);
16490
17564
  break;
17565
+ case "ruler":
17566
+ const rulerResult = fromRuler(content);
17567
+ canonicalPkg = JSON.parse(rulerResult.content);
17568
+ break;
16491
17569
  default:
16492
17570
  throw new CLIError(`Unsupported source format: ${sourceFormat}`);
16493
17571
  }
@@ -16512,10 +17590,14 @@ async function handleConvert(sourcePath, options) {
16512
17590
  result = toCopilot(canonicalPkg);
16513
17591
  break;
16514
17592
  case "kiro":
16515
- result = toKiro(canonicalPkg, {
16516
- kiroConfig: { inclusion: "always" }
16517
- // Default to always include
16518
- });
17593
+ if (options.subtype === "agent") {
17594
+ result = toKiroAgent(canonicalPkg);
17595
+ } else {
17596
+ result = toKiro(canonicalPkg, {
17597
+ kiroConfig: { inclusion: "always" }
17598
+ // Default to always include
17599
+ });
17600
+ }
16519
17601
  break;
16520
17602
  case "agents.md":
16521
17603
  result = toAgentsMd(canonicalPkg);
@@ -16523,6 +17605,9 @@ async function handleConvert(sourcePath, options) {
16523
17605
  case "gemini":
16524
17606
  result = toGemini(canonicalPkg);
16525
17607
  break;
17608
+ case "ruler":
17609
+ result = toRuler(canonicalPkg);
17610
+ break;
16526
17611
  default:
16527
17612
  throw new CLIError(`Unsupported target format: ${options.to}`);
16528
17613
  }
@@ -16530,15 +17615,15 @@ async function handleConvert(sourcePath, options) {
16530
17615
  throw new CLIError("Conversion failed: No content generated");
16531
17616
  }
16532
17617
  console.log(import_chalk2.default.green(`\u2713 Converted from ${sourceFormat} to ${options.to}`));
16533
- const outputPath = options.output || getDefaultPath(options.to, sourcePath, options.subtype);
16534
- if ((0, import_fs12.existsSync)(outputPath) && !options.yes) {
17618
+ const outputPath = options.output || getDefaultPath(options.to, sourcePath, options.subtype, options.name);
17619
+ if ((0, import_fs13.existsSync)(outputPath) && !options.yes) {
16535
17620
  const shouldOverwrite = await confirmOverwrite(outputPath);
16536
17621
  if (!shouldOverwrite) {
16537
17622
  console.log(import_chalk2.default.yellow("\n\u2716 Conversion cancelled"));
16538
17623
  return;
16539
17624
  }
16540
17625
  }
16541
- const outputDir = (0, import_path15.dirname)(outputPath);
17626
+ const outputDir = (0, import_path16.dirname)(outputPath);
16542
17627
  await (0, import_promises9.mkdir)(outputDir, { recursive: true });
16543
17628
  console.log(import_chalk2.default.dim("Writing converted file..."));
16544
17629
  await (0, import_promises9.writeFile)(outputPath, result.content, "utf-8");
@@ -16554,6 +17639,8 @@ async function handleConvert(sourcePath, options) {
16554
17639
  console.log(import_chalk2.default.dim("\u{1F4A1} Kiro will automatically load steering files from .kiro/steering/"));
16555
17640
  } else if (options.to === "gemini") {
16556
17641
  console.log(import_chalk2.default.dim("\u{1F4A1} Gemini will automatically load commands from .gemini/commands/"));
17642
+ } else if (options.to === "ruler") {
17643
+ console.log(import_chalk2.default.dim("\u{1F4A1} Ruler will automatically load and distribute rules from .ruler/"));
16557
17644
  }
16558
17645
  } catch (error) {
16559
17646
  console.log(import_chalk2.default.red("\u2716 Conversion failed"));
@@ -16561,12 +17648,12 @@ async function handleConvert(sourcePath, options) {
16561
17648
  }
16562
17649
  }
16563
17650
  function createConvertCommand() {
16564
- const command = new import_commander27.Command("convert").description("Convert AI prompt files between formats").argument("<source>", "Source file path to convert").option("-t, --to <format>", "Target format (cursor, claude, windsurf, kiro, copilot, continue, agents.md, gemini)").option("-s, --subtype <subtype>", "Target subtype (agent, skill, slash-command, rule, prompt, etc.)").option("-o, --output <path>", "Output path (defaults to format-specific location)").option("-y, --yes", "Skip confirmation prompts").action(async (source, options) => {
17651
+ const command = new import_commander27.Command("convert").description("Convert AI prompt files between formats").argument("<source>", "Source file path to convert").option("-t, --to <format>", "Target format (cursor, claude, windsurf, kiro, copilot, continue, agents.md, gemini, ruler)").option("-s, --subtype <subtype>", "Target subtype (agent, skill, slash-command, rule, prompt, etc.)").option("-o, --output <path>", "Output path (defaults to format-specific location)").option("-n, --name <name>", 'Custom output filename (without extension, e.g., "my-rule")').option("-y, --yes", "Skip confirmation prompts").action(async (source, options) => {
16565
17652
  try {
16566
17653
  if (!options.to) {
16567
17654
  throw new CLIError("Target format is required. Use --to <format>");
16568
17655
  }
16569
- const validFormats = ["cursor", "claude", "windsurf", "kiro", "copilot", "continue", "agents.md", "gemini"];
17656
+ const validFormats = ["cursor", "claude", "windsurf", "kiro", "copilot", "continue", "agents.md", "gemini", "ruler"];
16570
17657
  if (!validFormats.includes(options.to)) {
16571
17658
  throw new CLIError(
16572
17659
  `Invalid format: ${options.to}
@@ -16586,6 +17673,187 @@ Valid subtypes: ${validSubtypes.join(", ")}`
16586
17673
  to: options.to,
16587
17674
  subtype: options.subtype,
16588
17675
  output: options.output,
17676
+ name: options.name,
17677
+ yes: options.yes
17678
+ });
17679
+ } catch (error) {
17680
+ if (error instanceof CLIError) {
17681
+ throw error;
17682
+ }
17683
+ throw new CLIError(error.message);
17684
+ }
17685
+ });
17686
+ return command;
17687
+ }
17688
+
17689
+ // src/commands/export.ts
17690
+ init_cjs_shims();
17691
+ var import_commander28 = require("commander");
17692
+ var import_fs14 = require("fs");
17693
+ var import_path17 = require("path");
17694
+ var import_chalk3 = __toESM(require_source());
17695
+ init_errors();
17696
+ init_lockfile();
17697
+ init_telemetry();
17698
+ async function exportToRuler(options) {
17699
+ console.log(import_chalk3.default.dim("\u{1F4E6} Exporting installed packages to Ruler format..."));
17700
+ console.log();
17701
+ const packages = await listPackages();
17702
+ if (packages.length === 0) {
17703
+ console.log(import_chalk3.default.yellow("\u26A0 No packages installed"));
17704
+ console.log(import_chalk3.default.dim("Install packages first with: prpm install <package>"));
17705
+ return;
17706
+ }
17707
+ console.log(import_chalk3.default.green(`\u2713 Found ${packages.length} installed package${packages.length === 1 ? "" : "s"}`));
17708
+ console.log();
17709
+ const outputDir = options.output || (0, import_path17.join)(process.cwd(), ".ruler");
17710
+ let rulerExists = false;
17711
+ try {
17712
+ await import_fs14.promises.access(outputDir);
17713
+ rulerExists = true;
17714
+ } catch {
17715
+ }
17716
+ if (!rulerExists) {
17717
+ console.log(import_chalk3.default.yellow(`\u26A0 ${outputDir} directory not found`));
17718
+ console.log(import_chalk3.default.dim("Creating .ruler directory..."));
17719
+ await import_fs14.promises.mkdir(outputDir, { recursive: true });
17720
+ console.log(import_chalk3.default.green(`\u2713 Created ${outputDir}/`));
17721
+ console.log();
17722
+ }
17723
+ let exportedCount = 0;
17724
+ let skippedCount = 0;
17725
+ for (const pkg of packages) {
17726
+ const packageName = pkg.id.split("/").pop() || pkg.id;
17727
+ if (!pkg.installedPath) {
17728
+ console.log(import_chalk3.default.yellow(`\u26A0 Skipping ${pkg.id} - no installation path found`));
17729
+ skippedCount++;
17730
+ continue;
17731
+ }
17732
+ try {
17733
+ const content = await import_fs14.promises.readFile(pkg.installedPath, "utf-8");
17734
+ const rulerContent = createRulerFormat(pkg.id, pkg.version, content, pkg.format, pkg.subtype);
17735
+ const rulerFilename = `${packageName}.md`;
17736
+ const rulerPath = (0, import_path17.join)(outputDir, rulerFilename);
17737
+ await import_fs14.promises.writeFile(rulerPath, rulerContent, "utf-8");
17738
+ console.log(import_chalk3.default.green(`\u2713 Exported ${pkg.id} \u2192 ${rulerFilename}`));
17739
+ exportedCount++;
17740
+ } catch (error) {
17741
+ console.log(import_chalk3.default.red(`\u2716 Failed to export ${pkg.id}: ${error instanceof Error ? error.message : String(error)}`));
17742
+ skippedCount++;
17743
+ }
17744
+ }
17745
+ console.log();
17746
+ console.log(import_chalk3.default.green(`\u2713 Export complete`));
17747
+ console.log(import_chalk3.default.dim(` Exported: ${exportedCount} package${exportedCount === 1 ? "" : "s"}`));
17748
+ if (skippedCount > 0) {
17749
+ console.log(import_chalk3.default.dim(` Skipped: ${skippedCount} package${skippedCount === 1 ? "" : "s"}`));
17750
+ }
17751
+ console.log();
17752
+ await ensureRulerConfig(outputDir);
17753
+ console.log(import_chalk3.default.bold("\u{1F4CB} Next steps:"));
17754
+ console.log(import_chalk3.default.dim("1. Review the exported files in .ruler/"));
17755
+ console.log(import_chalk3.default.dim("2. Edit ruler.toml to configure which agents should use these rules"));
17756
+ console.log(import_chalk3.default.dim("3. Run: ruler apply"));
17757
+ console.log();
17758
+ console.log(import_chalk3.default.dim("\u{1F4A1} Learn more about Ruler: https://okigu.com/ruler"));
17759
+ }
17760
+ function createRulerFormat(packageId, version, content, format, subtype) {
17761
+ const contentWithoutFrontmatter = content.replace(/^---\n[\s\S]*?\n---\n/, "");
17762
+ const frontmatter = [
17763
+ "---",
17764
+ `# Exported from PRPM`,
17765
+ `# Package: ${packageId}`,
17766
+ `# Version: ${version}`,
17767
+ format ? `# Original Format: ${format}` : "",
17768
+ subtype ? `# Subtype: ${subtype}` : "",
17769
+ `# Exported: ${(/* @__PURE__ */ new Date()).toISOString()}`,
17770
+ "---",
17771
+ ""
17772
+ ].filter(Boolean).join("\n");
17773
+ return frontmatter + contentWithoutFrontmatter;
17774
+ }
17775
+ async function ensureRulerConfig(rulerDir) {
17776
+ const configPath = (0, import_path17.join)((0, import_path17.dirname)(rulerDir), "ruler.toml");
17777
+ try {
17778
+ await import_fs14.promises.access(configPath);
17779
+ console.log(import_chalk3.default.dim("\u2139 ruler.toml already exists (not modified)"));
17780
+ } catch {
17781
+ const basicConfig = `# Ruler Configuration
17782
+ # Learn more: https://okigu.com/ruler
17783
+
17784
+ # Define which agents should use these rules
17785
+ # Example:
17786
+ # [agents.cursor]
17787
+ # enabled = true
17788
+ # rules = ["*"] # Apply all rules
17789
+ #
17790
+ # [agents.claude]
17791
+ # enabled = true
17792
+ # rules = ["*"]
17793
+
17794
+ # Uncomment and configure the agents you use:
17795
+ # [agents.cursor]
17796
+ # enabled = false
17797
+ #
17798
+ # [agents.claude]
17799
+ # enabled = false
17800
+ #
17801
+ # [agents.github-copilot]
17802
+ # enabled = false
17803
+ `;
17804
+ await import_fs14.promises.writeFile(configPath, basicConfig, "utf-8");
17805
+ console.log(import_chalk3.default.green(`\u2713 Created ruler.toml configuration template`));
17806
+ }
17807
+ }
17808
+ async function handleExport(options) {
17809
+ const startTime = Date.now();
17810
+ let success = false;
17811
+ let error;
17812
+ let packageCount = 0;
17813
+ try {
17814
+ if (options.to === "ruler") {
17815
+ await exportToRuler(options);
17816
+ const packages = await listPackages();
17817
+ packageCount = packages.length;
17818
+ success = true;
17819
+ } else {
17820
+ throw new CLIError(`Unsupported export target: ${options.to}`);
17821
+ }
17822
+ } catch (err) {
17823
+ error = err instanceof Error ? err.message : String(err);
17824
+ throw new CLIError(`\u274C Export failed: ${error}`, 1);
17825
+ } finally {
17826
+ await telemetry.track({
17827
+ command: "export",
17828
+ success,
17829
+ error,
17830
+ duration: Date.now() - startTime,
17831
+ data: {
17832
+ target: options.to,
17833
+ packageCount
17834
+ }
17835
+ });
17836
+ await telemetry.shutdown();
17837
+ }
17838
+ }
17839
+ function createExportCommand() {
17840
+ const command = new import_commander28.Command("export");
17841
+ command.description("Export installed packages to external tools").option("--to <tool>", "Export target (currently supports: ruler)", "ruler").option("-o, --output <dir>", "Custom output directory").option("-y, --yes", "Skip confirmation prompts").action(async (options) => {
17842
+ try {
17843
+ if (!options.to) {
17844
+ throw new CLIError("Export target is required. Use --to <tool>");
17845
+ }
17846
+ const validTargets = ["ruler"];
17847
+ if (!validTargets.includes(options.to)) {
17848
+ throw new CLIError(
17849
+ `Invalid export target: ${options.to}
17850
+
17851
+ Currently supported: ${validTargets.join(", ")}`
17852
+ );
17853
+ }
17854
+ await handleExport({
17855
+ to: options.to,
17856
+ output: options.output,
16589
17857
  yes: options.yes
16590
17858
  });
16591
17859
  } catch (error) {
@@ -16603,14 +17871,14 @@ init_telemetry();
16603
17871
  init_errors();
16604
17872
  function getVersion() {
16605
17873
  try {
16606
- const packageJsonPath = (0, import_path16.join)(__dirname, "../package.json");
16607
- const packageJson = JSON.parse((0, import_fs13.readFileSync)(packageJsonPath, "utf-8"));
17874
+ const packageJsonPath = (0, import_path18.join)(__dirname, "../package.json");
17875
+ const packageJson = JSON.parse((0, import_fs15.readFileSync)(packageJsonPath, "utf-8"));
16608
17876
  return packageJson.version || "0.0.0";
16609
17877
  } catch {
16610
17878
  return "0.0.0";
16611
17879
  }
16612
17880
  }
16613
- var program = new import_commander28.Command();
17881
+ var program = new import_commander29.Command();
16614
17882
  program.name("prpm").description("Prompt Package Manager - Install and manage prompt-based files").version(getVersion());
16615
17883
  program.addCommand(createInitCommand());
16616
17884
  program.addCommand(createCatalogCommand());
@@ -16639,6 +17907,7 @@ program.addCommand(createBuyCreditsCommand());
16639
17907
  program.addCommand(createSchemaCommand());
16640
17908
  program.addCommand(createConfigCommand());
16641
17909
  program.addCommand(createConvertCommand());
17910
+ program.addCommand(createExportCommand());
16642
17911
  (async () => {
16643
17912
  try {
16644
17913
  await program.parseAsync();