prpm 1.1.1 → 1.1.2

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
@@ -494,6 +494,7 @@ function getDestinationDir2(format, subtype, name) {
494
494
  return ".github/instructions";
495
495
  case "kiro":
496
496
  if (subtype === "hook") return ".kiro/hooks";
497
+ if (subtype === "agent") return ".kiro/agents";
497
498
  return ".kiro/steering";
498
499
  case "gemini":
499
500
  return ".gemini/commands";
@@ -1910,14 +1911,14 @@ var require_templates = __commonJS({
1910
1911
  }
1911
1912
  return results;
1912
1913
  }
1913
- function buildStyle(chalk3, styles) {
1914
+ function buildStyle(chalk4, styles) {
1914
1915
  const enabled = {};
1915
1916
  for (const layer of styles) {
1916
1917
  for (const style of layer.styles) {
1917
1918
  enabled[style[0]] = layer.inverse ? null : style.slice(1);
1918
1919
  }
1919
1920
  }
1920
- let current = chalk3;
1921
+ let current = chalk4;
1921
1922
  for (const [styleName, styles2] of Object.entries(enabled)) {
1922
1923
  if (!Array.isArray(styles2)) {
1923
1924
  continue;
@@ -1929,7 +1930,7 @@ var require_templates = __commonJS({
1929
1930
  }
1930
1931
  return current;
1931
1932
  }
1932
- module2.exports = (chalk3, temporary) => {
1933
+ module2.exports = (chalk4, temporary) => {
1933
1934
  const styles = [];
1934
1935
  const chunks = [];
1935
1936
  let chunk = [];
@@ -1939,13 +1940,13 @@ var require_templates = __commonJS({
1939
1940
  } else if (style) {
1940
1941
  const string = chunk.join("");
1941
1942
  chunk = [];
1942
- chunks.push(styles.length === 0 ? string : buildStyle(chalk3, styles)(string));
1943
+ chunks.push(styles.length === 0 ? string : buildStyle(chalk4, styles)(string));
1943
1944
  styles.push({ inverse, styles: parseStyle(style) });
1944
1945
  } else if (close) {
1945
1946
  if (styles.length === 0) {
1946
1947
  throw new Error("Found extraneous } in Chalk template literal");
1947
1948
  }
1948
- chunks.push(buildStyle(chalk3, styles)(chunk.join("")));
1949
+ chunks.push(buildStyle(chalk4, styles)(chunk.join("")));
1949
1950
  chunk = [];
1950
1951
  styles.pop();
1951
1952
  } else {
@@ -1994,16 +1995,16 @@ var require_source = __commonJS({
1994
1995
  }
1995
1996
  };
1996
1997
  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 = () => {
1998
+ const chalk5 = {};
1999
+ applyOptions(chalk5, options);
2000
+ chalk5.template = (...arguments_) => chalkTag(chalk5.template, ...arguments_);
2001
+ Object.setPrototypeOf(chalk5, Chalk.prototype);
2002
+ Object.setPrototypeOf(chalk5.template, chalk5);
2003
+ chalk5.template.constructor = () => {
2003
2004
  throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
2004
2005
  };
2005
- chalk4.template.Instance = ChalkClass;
2006
- return chalk4.template;
2006
+ chalk5.template.Instance = ChalkClass;
2007
+ return chalk5.template;
2007
2008
  };
2008
2009
  function Chalk(options) {
2009
2010
  return chalkFactory(options);
@@ -2114,7 +2115,7 @@ var require_source = __commonJS({
2114
2115
  return openAll + string + closeAll;
2115
2116
  };
2116
2117
  var template;
2117
- var chalkTag = (chalk4, ...strings) => {
2118
+ var chalkTag = (chalk5, ...strings) => {
2118
2119
  const [firstString] = strings;
2119
2120
  if (!isArray(firstString) || !isArray(firstString.raw)) {
2120
2121
  return strings.join(" ");
@@ -2130,14 +2131,14 @@ var require_source = __commonJS({
2130
2131
  if (template === void 0) {
2131
2132
  template = require_templates();
2132
2133
  }
2133
- return template(chalk4, parts.join(""));
2134
+ return template(chalk5, parts.join(""));
2134
2135
  };
2135
2136
  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;
2137
+ var chalk4 = Chalk();
2138
+ chalk4.supportsColor = stdoutColor;
2139
+ chalk4.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
2140
+ chalk4.stderr.supportsColor = stderrColor;
2141
+ module2.exports = chalk4;
2141
2142
  }
2142
2143
  });
2143
2144
 
@@ -2491,8 +2492,8 @@ async function handleCollectionPublish(manifestPath = "./collection.json") {
2491
2492
  throw new CLIError("\n\u274C Authentication required. Run `prpm login` first.", 1);
2492
2493
  }
2493
2494
  console.log("\u{1F4E6} Publishing collection...\n");
2494
- const fs10 = await import("fs/promises");
2495
- const manifestContent = await fs10.readFile(manifestPath, "utf-8");
2495
+ const fs11 = await import("fs/promises");
2496
+ const manifestContent = await fs11.readFile(manifestPath, "utf-8");
2496
2497
  const manifest = JSON.parse(manifestContent);
2497
2498
  const required = ["id", "name", "description", "packages"];
2498
2499
  const missing = required.filter((field) => !manifest[field]);
@@ -6389,6 +6390,172 @@ var init_from_kiro = __esm({
6389
6390
  }
6390
6391
  });
6391
6392
 
6393
+ // ../converters/dist/from-kiro-agent.js
6394
+ function fromKiroAgent(jsonContent, options = {}) {
6395
+ const warnings = [];
6396
+ let qualityScore = 100;
6397
+ try {
6398
+ const agentConfig = JSON.parse(jsonContent);
6399
+ const content = {
6400
+ format: "canonical",
6401
+ version: "1.0",
6402
+ sections: [
6403
+ {
6404
+ type: "metadata",
6405
+ data: {
6406
+ title: agentConfig.name || "Kiro Agent",
6407
+ description: agentConfig.description || ""
6408
+ }
6409
+ }
6410
+ ]
6411
+ };
6412
+ if (agentConfig.prompt) {
6413
+ parsePromptIntoContent(agentConfig.prompt, content);
6414
+ }
6415
+ const pkg = {
6416
+ id: agentConfig.name || "kiro-agent",
6417
+ name: agentConfig.name || "kiro-agent",
6418
+ version: "1.0.0",
6419
+ description: agentConfig.description || "",
6420
+ author: "",
6421
+ tags: [],
6422
+ format: "kiro",
6423
+ subtype: "agent",
6424
+ content,
6425
+ sourceFormat: "kiro",
6426
+ metadata: {
6427
+ kiroConfig: {
6428
+ inclusion: "always"
6429
+ },
6430
+ kiroAgent: {
6431
+ tools: agentConfig.tools,
6432
+ mcpServers: agentConfig.mcpServers,
6433
+ toolAliases: agentConfig.toolAliases,
6434
+ allowedTools: agentConfig.allowedTools,
6435
+ toolsSettings: agentConfig.toolsSettings,
6436
+ resources: agentConfig.resources,
6437
+ hooks: agentConfig.hooks,
6438
+ useLegacyMcpJson: agentConfig.useLegacyMcpJson,
6439
+ model: agentConfig.model
6440
+ }
6441
+ }
6442
+ };
6443
+ return {
6444
+ content: JSON.stringify(pkg, null, 2),
6445
+ format: "canonical",
6446
+ warnings: warnings.length > 0 ? warnings : void 0,
6447
+ lossyConversion: false,
6448
+ qualityScore
6449
+ };
6450
+ } catch (error) {
6451
+ warnings.push(`Parse error: ${error instanceof Error ? error.message : String(error)}`);
6452
+ return {
6453
+ content: "",
6454
+ format: "canonical",
6455
+ warnings,
6456
+ lossyConversion: true,
6457
+ qualityScore: 0
6458
+ };
6459
+ }
6460
+ }
6461
+ function parsePromptIntoContent(prompt3, content) {
6462
+ if (prompt3.startsWith("file://")) {
6463
+ content.sections.push({
6464
+ type: "instructions",
6465
+ title: "Instructions",
6466
+ content: `Loads instructions from: ${prompt3}`
6467
+ });
6468
+ return;
6469
+ }
6470
+ const sections = prompt3.split(/\n## /);
6471
+ if (sections[0]) {
6472
+ const intro = sections[0].trim();
6473
+ if (intro) {
6474
+ const metadataSection = content.sections[0];
6475
+ if (metadataSection && metadataSection.type === "metadata") {
6476
+ if (!metadataSection.data.description) {
6477
+ metadataSection.data.description = intro;
6478
+ }
6479
+ }
6480
+ }
6481
+ }
6482
+ for (let i = 1; i < sections.length; i++) {
6483
+ const sectionText = sections[i];
6484
+ const lines = sectionText.split("\n");
6485
+ const title = lines[0].trim();
6486
+ const sectionContent = lines.slice(1).join("\n").trim();
6487
+ if (title.toLowerCase() === "instructions") {
6488
+ content.sections.push({
6489
+ type: "instructions",
6490
+ title,
6491
+ content: sectionContent
6492
+ });
6493
+ } else if (title.toLowerCase() === "rules") {
6494
+ const rules = parseRules(sectionContent);
6495
+ content.sections.push({
6496
+ type: "rules",
6497
+ title,
6498
+ items: rules
6499
+ });
6500
+ } else if (title.toLowerCase() === "examples") {
6501
+ const examples = parseExamples(sectionContent);
6502
+ content.sections.push({
6503
+ type: "examples",
6504
+ title,
6505
+ examples
6506
+ });
6507
+ } else {
6508
+ content.sections.push({
6509
+ type: "custom",
6510
+ editorType: "kiro",
6511
+ title,
6512
+ content: sectionContent
6513
+ });
6514
+ }
6515
+ }
6516
+ }
6517
+ function parseRules(text) {
6518
+ const rules = [];
6519
+ const ruleSections = text.split(/\n### /);
6520
+ for (const ruleText of ruleSections) {
6521
+ if (!ruleText.trim())
6522
+ continue;
6523
+ const lines = ruleText.split("\n");
6524
+ const title = lines[0].trim();
6525
+ const description = lines.slice(1).join("\n").trim();
6526
+ rules.push({
6527
+ content: `${title}: ${description}`
6528
+ });
6529
+ }
6530
+ return rules;
6531
+ }
6532
+ function parseExamples(text) {
6533
+ const examples = [];
6534
+ const exampleSections = text.split(/\n### /);
6535
+ for (const exampleText of exampleSections) {
6536
+ if (!exampleText.trim())
6537
+ continue;
6538
+ const lines = exampleText.split("\n");
6539
+ const title = lines[0].trim();
6540
+ const content = lines.slice(1).join("\n");
6541
+ const codeMatch = /```[\w]*\n([\s\S]*?)```/.exec(content);
6542
+ const code = codeMatch ? codeMatch[1].trim() : content;
6543
+ const descMatch = /^([\s\S]*?)(?:```|$)/.exec(content);
6544
+ const description = descMatch && descMatch[1].trim() ? descMatch[1].trim() : title;
6545
+ examples.push({
6546
+ description,
6547
+ code
6548
+ });
6549
+ }
6550
+ return examples;
6551
+ }
6552
+ var init_from_kiro_agent = __esm({
6553
+ "../converters/dist/from-kiro-agent.js"() {
6554
+ "use strict";
6555
+ init_cjs_shims();
6556
+ }
6557
+ });
6558
+
6392
6559
  // ../converters/dist/from-windsurf.js
6393
6560
  function fromWindsurf(content, metadata) {
6394
6561
  const sections = [];
@@ -8778,6 +8945,136 @@ var init_from_gemini = __esm({
8778
8945
  }
8779
8946
  });
8780
8947
 
8948
+ // ../converters/dist/from-ruler.js
8949
+ function fromRuler(markdown, options = {}) {
8950
+ const warnings = [];
8951
+ let qualityScore = 100;
8952
+ try {
8953
+ const cleanedMarkdown = markdown.replace(/<!--.*?-->/gs, "").trim();
8954
+ const content = parseMarkdownContent(cleanedMarkdown, warnings);
8955
+ const metadata = extractMetadata(markdown);
8956
+ const metadataSection = content.sections.find((s) => s.type === "metadata");
8957
+ const description = metadata.description || (metadataSection == null ? void 0 : metadataSection.data.description) || "";
8958
+ const title = (metadataSection == null ? void 0 : metadataSection.data.title) || "Ruler Rule";
8959
+ const pkg = {
8960
+ id: metadata.name || "ruler-rule",
8961
+ name: metadata.name || "ruler-rule",
8962
+ version: "1.0.0",
8963
+ author: metadata.author || "",
8964
+ tags: [],
8965
+ format: "generic",
8966
+ subtype: "rule",
8967
+ description,
8968
+ content,
8969
+ sourceFormat: "ruler",
8970
+ metadata: {
8971
+ title,
8972
+ description
8973
+ }
8974
+ };
8975
+ return {
8976
+ content: JSON.stringify(pkg, null, 2),
8977
+ format: "canonical",
8978
+ warnings: warnings.length > 0 ? warnings : void 0,
8979
+ lossyConversion: false,
8980
+ qualityScore
8981
+ };
8982
+ } catch (error) {
8983
+ warnings.push(`Parse error: ${error instanceof Error ? error.message : String(error)}`);
8984
+ return {
8985
+ content: "",
8986
+ format: "canonical",
8987
+ warnings,
8988
+ lossyConversion: true,
8989
+ qualityScore: 0
8990
+ };
8991
+ }
8992
+ }
8993
+ function extractMetadata(markdown) {
8994
+ const metadata = {};
8995
+ const nameMatch = /<!--\s*Package:\s*(.+?)\s*-->/i.exec(markdown);
8996
+ if (nameMatch) {
8997
+ metadata.name = nameMatch[1].trim();
8998
+ }
8999
+ const authorMatch = /<!--\s*Author:\s*(.+?)\s*-->/i.exec(markdown);
9000
+ if (authorMatch) {
9001
+ metadata.author = authorMatch[1].trim();
9002
+ }
9003
+ const descMatch = /<!--\s*Description:\s*(.+?)\s*-->/i.exec(markdown);
9004
+ if (descMatch) {
9005
+ metadata.description = descMatch[1].trim();
9006
+ }
9007
+ return metadata;
9008
+ }
9009
+ function parseMarkdownContent(markdown, warnings) {
9010
+ const lines = markdown.split("\n");
9011
+ const content = {
9012
+ format: "canonical",
9013
+ version: "1.0",
9014
+ sections: []
9015
+ };
9016
+ let title = "";
9017
+ let description = "";
9018
+ let currentSection = null;
9019
+ let inCodeBlock = false;
9020
+ let buffer = [];
9021
+ for (const line of lines) {
9022
+ if (line.trim().startsWith("```")) {
9023
+ inCodeBlock = !inCodeBlock;
9024
+ buffer.push(line);
9025
+ continue;
9026
+ }
9027
+ if (!inCodeBlock && line.match(/^#+\s/)) {
9028
+ if (currentSection) {
9029
+ content.sections.push({
9030
+ type: "custom",
9031
+ title: currentSection.title,
9032
+ content: buffer.join("\n").trim()
9033
+ });
9034
+ buffer = [];
9035
+ }
9036
+ const match = line.match(/^(#+)\s+(.+)$/);
9037
+ if (match) {
9038
+ const level = match[1].length;
9039
+ const sectionTitle = match[2].trim();
9040
+ if (level === 1 && !title) {
9041
+ title = sectionTitle;
9042
+ currentSection = null;
9043
+ } else {
9044
+ currentSection = { title: sectionTitle, content: "" };
9045
+ }
9046
+ }
9047
+ } else if (currentSection) {
9048
+ buffer.push(line);
9049
+ } else if (!title) {
9050
+ if (line.trim()) {
9051
+ description += (description ? "\n" : "") + line;
9052
+ }
9053
+ }
9054
+ }
9055
+ if (currentSection && buffer.length > 0) {
9056
+ content.sections.push({
9057
+ type: "custom",
9058
+ title: currentSection.title,
9059
+ content: buffer.join("\n").trim()
9060
+ });
9061
+ }
9062
+ content.sections.unshift({
9063
+ type: "metadata",
9064
+ data: {
9065
+ title: title || "Ruler Rule",
9066
+ description: description || ""
9067
+ }
9068
+ });
9069
+ return content;
9070
+ }
9071
+ var init_from_ruler = __esm({
9072
+ "../converters/dist/from-ruler.js"() {
9073
+ "use strict";
9074
+ init_cjs_shims();
9075
+ }
9076
+ });
9077
+
8781
9078
  // ../converters/dist/validation.js
8782
9079
  function loadSchema(format, subtype) {
8783
9080
  const cacheKey = subtype ? `${format}:${subtype}` : format;
@@ -8792,7 +9089,8 @@ function loadSchema(format, subtype) {
8792
9089
  "claude:slash-command": "claude-slash-command.schema.json",
8793
9090
  "claude:hook": "claude-hook.schema.json",
8794
9091
  "cursor:slash-command": "cursor-command.schema.json",
8795
- "kiro:hook": "kiro-hooks.schema.json"
9092
+ "kiro:hook": "kiro-hooks.schema.json",
9093
+ "kiro:agent": "kiro-agent.schema.json"
8796
9094
  };
8797
9095
  schemaFilename = subtypeSchemaMap[cacheKey];
8798
9096
  }
@@ -8806,6 +9104,7 @@ function loadSchema(format, subtype) {
8806
9104
  "kiro": "kiro-steering.schema.json",
8807
9105
  "agents-md": "agents-md.schema.json",
8808
9106
  "gemini": "gemini.schema.json",
9107
+ "ruler": "ruler.schema.json",
8809
9108
  "canonical": "canonical.schema.json"
8810
9109
  };
8811
9110
  schemaFilename = schemaMap[format] || `${format}.schema.json`;
@@ -8913,12 +9212,12 @@ function parseMarkdownWithFrontmatter(markdown) {
8913
9212
  }
8914
9213
  function validateMarkdown(format, markdown, subtype) {
8915
9214
  const { frontmatter, content } = parseMarkdownWithFrontmatter(markdown);
8916
- if (format === "windsurf" || format === "agents-md") {
9215
+ if (format === "windsurf" || format === "agents-md" || format === "ruler") {
8917
9216
  return validateFormat(format, { content: markdown }, subtype);
8918
9217
  }
8919
9218
  return validateConversion(format, frontmatter, content, subtype);
8920
9219
  }
8921
- var import_ajv, import_ajv_formats, import_fs8, import_path7, currentDirname, ajv, schemaCache;
9220
+ var import_ajv, import_ajv_formats, import_fs8, import_path7, import_url, currentDirname, ajv, schemaCache;
8922
9221
  var init_validation = __esm({
8923
9222
  "../converters/dist/validation.js"() {
8924
9223
  "use strict";
@@ -8927,8 +9226,14 @@ var init_validation = __esm({
8927
9226
  import_ajv_formats = __toESM(require("ajv-formats"), 1);
8928
9227
  import_fs8 = require("fs");
8929
9228
  import_path7 = require("path");
9229
+ import_url = require("url");
8930
9230
  init_js_yaml();
8931
- currentDirname = __dirname;
9231
+ if (typeof __dirname !== "undefined") {
9232
+ currentDirname = __dirname;
9233
+ } else {
9234
+ const getModuleUrl = new Function("return import.meta.url");
9235
+ currentDirname = (0, import_path7.dirname)((0, import_url.fileURLToPath)(getModuleUrl()));
9236
+ }
8932
9237
  ajv = new import_ajv.default({
8933
9238
  allErrors: true,
8934
9239
  verbose: true,
@@ -9835,6 +10140,171 @@ var init_to_kiro = __esm({
9835
10140
  }
9836
10141
  });
9837
10142
 
10143
+ // ../converters/dist/to-kiro-agent.js
10144
+ function toKiroAgent(pkg, options = {}) {
10145
+ var _a;
10146
+ const warnings = [];
10147
+ let qualityScore = 100;
10148
+ try {
10149
+ const agentConfig = {
10150
+ name: pkg.name,
10151
+ description: pkg.description
10152
+ };
10153
+ const prompt3 = convertToPrompt(pkg.content, warnings);
10154
+ if (prompt3) {
10155
+ agentConfig.prompt = prompt3;
10156
+ }
10157
+ if ((_a = pkg.metadata) == null ? void 0 : _a.kiroAgent) {
10158
+ const kiroAgent = pkg.metadata.kiroAgent;
10159
+ if (kiroAgent.tools) {
10160
+ agentConfig.tools = kiroAgent.tools;
10161
+ }
10162
+ if (kiroAgent.mcpServers) {
10163
+ agentConfig.mcpServers = kiroAgent.mcpServers;
10164
+ }
10165
+ if (kiroAgent.toolAliases) {
10166
+ agentConfig.toolAliases = kiroAgent.toolAliases;
10167
+ }
10168
+ if (kiroAgent.allowedTools) {
10169
+ agentConfig.allowedTools = kiroAgent.allowedTools;
10170
+ }
10171
+ if (kiroAgent.toolsSettings) {
10172
+ agentConfig.toolsSettings = kiroAgent.toolsSettings;
10173
+ }
10174
+ if (kiroAgent.resources) {
10175
+ agentConfig.resources = kiroAgent.resources;
10176
+ }
10177
+ if (kiroAgent.hooks) {
10178
+ agentConfig.hooks = kiroAgent.hooks;
10179
+ }
10180
+ if (kiroAgent.useLegacyMcpJson !== void 0) {
10181
+ agentConfig.useLegacyMcpJson = kiroAgent.useLegacyMcpJson;
10182
+ }
10183
+ if (kiroAgent.model) {
10184
+ agentConfig.model = kiroAgent.model;
10185
+ }
10186
+ }
10187
+ if (pkg.subtype === "slash-command") {
10188
+ warnings.push("Slash commands are not directly supported by Kiro agents");
10189
+ qualityScore -= 20;
10190
+ }
10191
+ if (pkg.subtype === "skill") {
10192
+ warnings.push("Skills are converted to agent prompts - some features may be lost");
10193
+ qualityScore -= 10;
10194
+ }
10195
+ const content = JSON.stringify(agentConfig, null, 2);
10196
+ const lossyConversion = warnings.some((w) => w.includes("not supported") || w.includes("may be lost"));
10197
+ return {
10198
+ content,
10199
+ format: "kiro",
10200
+ warnings: warnings.length > 0 ? warnings : void 0,
10201
+ lossyConversion,
10202
+ qualityScore: Math.max(0, qualityScore)
10203
+ };
10204
+ } catch (error) {
10205
+ warnings.push(`Conversion error: ${error instanceof Error ? error.message : String(error)}`);
10206
+ return {
10207
+ content: "",
10208
+ format: "kiro",
10209
+ warnings,
10210
+ lossyConversion: true,
10211
+ qualityScore: 0
10212
+ };
10213
+ }
10214
+ }
10215
+ function convertToPrompt(content, warnings) {
10216
+ const parts = [];
10217
+ const metadataSection = content.sections.find((s) => s.type === "metadata");
10218
+ if (metadataSection == null ? void 0 : metadataSection.data.description) {
10219
+ parts.push(metadataSection.data.description);
10220
+ }
10221
+ const personaSection = content.sections.find((s) => s.type === "persona");
10222
+ if (personaSection) {
10223
+ const persona = personaSection.data;
10224
+ let personaText = "";
10225
+ if (persona.name) {
10226
+ personaText += `You are ${persona.name}`;
10227
+ if (persona.role) {
10228
+ personaText += `, ${persona.role}`;
10229
+ }
10230
+ personaText += ". ";
10231
+ }
10232
+ if (persona.style && persona.style.length > 0) {
10233
+ personaText += `Your communication style is ${persona.style.join(", ")}. `;
10234
+ }
10235
+ if (persona.expertise && persona.expertise.length > 0) {
10236
+ personaText += `You specialize in: ${persona.expertise.join(", ")}. `;
10237
+ }
10238
+ if (personaText) {
10239
+ parts.push(personaText.trim());
10240
+ }
10241
+ }
10242
+ for (const section of content.sections) {
10243
+ if (section.type === "instructions") {
10244
+ const instructionsSection = section;
10245
+ parts.push(`
10246
+ ## ${instructionsSection.title}
10247
+ `);
10248
+ parts.push(instructionsSection.content);
10249
+ } else if (section.type === "rules") {
10250
+ const rulesSection = section;
10251
+ parts.push(`
10252
+ ## ${rulesSection.title}
10253
+ `);
10254
+ for (const rule of rulesSection.items) {
10255
+ parts.push(`- ${rule.content}`);
10256
+ if (rule.rationale) {
10257
+ parts.push(` *Rationale:* ${rule.rationale}`);
10258
+ }
10259
+ }
10260
+ } else if (section.type === "examples") {
10261
+ const examplesSection = section;
10262
+ parts.push(`
10263
+ ## ${examplesSection.title}
10264
+ `);
10265
+ for (const example of examplesSection.examples) {
10266
+ if (example.description) {
10267
+ parts.push(`
10268
+ ### ${example.description}
10269
+ `);
10270
+ }
10271
+ if (example.code) {
10272
+ const lang = example.language || "";
10273
+ parts.push(`\`\`\`${lang}
10274
+ ${example.code}
10275
+ \`\`\``);
10276
+ }
10277
+ }
10278
+ } else if (section.type === "custom") {
10279
+ const customSection = section;
10280
+ if (customSection.title) {
10281
+ parts.push(`
10282
+ ## ${customSection.title}
10283
+ `);
10284
+ }
10285
+ parts.push(customSection.content);
10286
+ }
10287
+ }
10288
+ return parts.join("\n").trim();
10289
+ }
10290
+ function isKiroAgentFormat(content) {
10291
+ try {
10292
+ const parsed = JSON.parse(content);
10293
+ if (!parsed.name && !parsed.description) {
10294
+ return false;
10295
+ }
10296
+ return !!(parsed.prompt || parsed.tools || parsed.mcpServers);
10297
+ } catch {
10298
+ return false;
10299
+ }
10300
+ }
10301
+ var init_to_kiro_agent = __esm({
10302
+ "../converters/dist/to-kiro-agent.js"() {
10303
+ "use strict";
10304
+ init_cjs_shims();
10305
+ }
10306
+ });
10307
+
9838
10308
  // ../converters/dist/to-windsurf.js
9839
10309
  function toWindsurf(pkg) {
9840
10310
  var _a, _b, _c, _d;
@@ -10345,6 +10815,166 @@ var init_to_gemini = __esm({
10345
10815
  }
10346
10816
  });
10347
10817
 
10818
+ // ../converters/dist/to-ruler.js
10819
+ function toRuler(pkg, options = {}) {
10820
+ var _a, _b;
10821
+ const warnings = [];
10822
+ let qualityScore = 100;
10823
+ try {
10824
+ if ((_b = (_a = pkg.metadata) == null ? void 0 : _a.copilotConfig) == null ? void 0 : _b.applyTo) {
10825
+ warnings.push("Path-specific configuration (applyTo) will be ignored by Ruler");
10826
+ }
10827
+ if (pkg.subtype === "agent" || pkg.subtype === "workflow") {
10828
+ warnings.push(`Subtype "${pkg.subtype}" may not be fully supported by Ruler's simple rule format`);
10829
+ qualityScore -= 10;
10830
+ }
10831
+ if (pkg.subtype === "slash-command") {
10832
+ warnings.push("Slash commands are not supported by Ruler");
10833
+ qualityScore -= 20;
10834
+ }
10835
+ if (pkg.subtype === "hook") {
10836
+ warnings.push("Hooks are not supported by Ruler");
10837
+ qualityScore -= 20;
10838
+ }
10839
+ const content = convertContent6(pkg.content, warnings);
10840
+ const header = `<!-- Package: ${pkg.name} -->
10841
+ <!-- Author: ${pkg.author || "Unknown"} -->
10842
+ ${pkg.description ? `<!-- Description: ${pkg.description} -->
10843
+ ` : ""}`;
10844
+ const fullContent = `${header}
10845
+ ${content}`;
10846
+ const validation = validateMarkdown("ruler", fullContent);
10847
+ const validationErrors = validation.errors.map((e) => e.message);
10848
+ const validationWarnings = validation.warnings.map((w) => w.message);
10849
+ if (validationWarnings.length > 0) {
10850
+ warnings.push(...validationWarnings);
10851
+ }
10852
+ const lossyConversion = warnings.some((w) => w.includes("not supported") || w.includes("ignored"));
10853
+ if (validationErrors.length > 0) {
10854
+ qualityScore -= validationErrors.length * 5;
10855
+ }
10856
+ return {
10857
+ content: fullContent,
10858
+ format: "ruler",
10859
+ warnings: warnings.length > 0 ? warnings : void 0,
10860
+ validationErrors: validationErrors.length > 0 ? validationErrors : void 0,
10861
+ lossyConversion,
10862
+ qualityScore: Math.max(0, qualityScore)
10863
+ };
10864
+ } catch (error) {
10865
+ warnings.push(`Conversion error: ${error instanceof Error ? error.message : String(error)}`);
10866
+ return {
10867
+ content: "",
10868
+ format: "ruler",
10869
+ warnings,
10870
+ lossyConversion: true,
10871
+ qualityScore: 0
10872
+ };
10873
+ }
10874
+ }
10875
+ function convertContent6(content, warnings) {
10876
+ const parts = [];
10877
+ const metadataSection = content.sections.find((s) => s.type === "metadata");
10878
+ if (metadataSection) {
10879
+ if (metadataSection.data.title) {
10880
+ parts.push(`# ${metadataSection.data.title}
10881
+ `);
10882
+ }
10883
+ if (metadataSection.data.description) {
10884
+ parts.push(`${metadataSection.data.description}
10885
+ `);
10886
+ }
10887
+ }
10888
+ for (const section of content.sections) {
10889
+ if (section.type === "metadata") {
10890
+ continue;
10891
+ } else if (section.type === "instructions") {
10892
+ const instructionsSection = section;
10893
+ parts.push(`## ${instructionsSection.title}
10894
+ `);
10895
+ parts.push(`${instructionsSection.content}
10896
+ `);
10897
+ } else if (section.type === "rules") {
10898
+ const rulesSection = section;
10899
+ parts.push(`## ${rulesSection.title}
10900
+ `);
10901
+ for (const rule of rulesSection.items) {
10902
+ parts.push(convertRule(rule));
10903
+ }
10904
+ } else if (section.type === "examples") {
10905
+ const examplesSection = section;
10906
+ parts.push(`## ${examplesSection.title}
10907
+ `);
10908
+ for (const example of examplesSection.examples) {
10909
+ parts.push(convertExample(example));
10910
+ }
10911
+ } else if (section.type === "custom") {
10912
+ const customSection = section;
10913
+ if (customSection.title) {
10914
+ parts.push(`## ${customSection.title}
10915
+ `);
10916
+ }
10917
+ parts.push(`${customSection.content}
10918
+ `);
10919
+ }
10920
+ }
10921
+ return parts.join("\n").trim();
10922
+ }
10923
+ function convertRule(rule) {
10924
+ const parts = [];
10925
+ parts.push(`- ${rule.content}`);
10926
+ if (rule.rationale) {
10927
+ parts.push(`
10928
+ *Rationale:* ${rule.rationale}`);
10929
+ }
10930
+ if (rule.examples && rule.examples.length > 0) {
10931
+ parts.push(`
10932
+ *Examples:*`);
10933
+ for (const example of rule.examples) {
10934
+ parts.push(`
10935
+ \`\`\`
10936
+ ${example}
10937
+ \`\`\``);
10938
+ }
10939
+ }
10940
+ parts.push("\n");
10941
+ return parts.join("");
10942
+ }
10943
+ function convertExample(example) {
10944
+ const parts = [];
10945
+ if (example.description) {
10946
+ parts.push(`### ${example.description}
10947
+ `);
10948
+ }
10949
+ if (example.good !== void 0) {
10950
+ parts.push(`*${example.good ? "Good" : "Bad"} example*
10951
+ `);
10952
+ }
10953
+ if (example.code) {
10954
+ const lang = example.language || "";
10955
+ parts.push("```" + lang);
10956
+ parts.push(example.code);
10957
+ parts.push("```\n");
10958
+ }
10959
+ return parts.join("\n");
10960
+ }
10961
+ function isRulerFormat(content) {
10962
+ const lines = content.trim().split("\n");
10963
+ if (lines[0] === "---") {
10964
+ return false;
10965
+ }
10966
+ const hasHeaders = /^#+\s/.test(content);
10967
+ const hasRuleContent = /rule|instruction|guideline|convention/i.test(content);
10968
+ return hasHeaders || hasRuleContent;
10969
+ }
10970
+ var init_to_ruler = __esm({
10971
+ "../converters/dist/to-ruler.js"() {
10972
+ "use strict";
10973
+ init_cjs_shims();
10974
+ init_validation();
10975
+ }
10976
+ });
10977
+
10348
10978
  // ../converters/dist/index.js
10349
10979
  var init_dist = __esm({
10350
10980
  "../converters/dist/index.js"() {
@@ -10356,17 +10986,21 @@ var init_dist = __esm({
10356
10986
  init_from_continue();
10357
10987
  init_from_copilot();
10358
10988
  init_from_kiro();
10989
+ init_from_kiro_agent();
10359
10990
  init_from_windsurf();
10360
10991
  init_from_agents_md();
10361
10992
  init_from_gemini();
10993
+ init_from_ruler();
10362
10994
  init_to_cursor();
10363
10995
  init_to_claude();
10364
10996
  init_to_continue();
10365
10997
  init_to_copilot();
10366
10998
  init_to_kiro();
10999
+ init_to_kiro_agent();
10367
11000
  init_to_windsurf();
10368
11001
  init_to_agents_md();
10369
11002
  init_to_gemini();
11003
+ init_to_ruler();
10370
11004
  init_taxonomy_utils();
10371
11005
  init_validation();
10372
11006
  }
@@ -10397,6 +11031,7 @@ function getPackageIcon2(format, subtype) {
10397
11031
  "gemini": "\u2728",
10398
11032
  "mcp": "\u{1F517}",
10399
11033
  "agents.md": "\u{1F4DD}",
11034
+ "ruler": "\u{1F4CF}",
10400
11035
  "generic": "\u{1F4E6}"
10401
11036
  };
10402
11037
  return subtypeIcons[subtype] || formatIcons[format] || "\u{1F4E6}";
@@ -10412,6 +11047,7 @@ function getPackageLabel2(format, subtype) {
10412
11047
  "gemini": "Gemini",
10413
11048
  "mcp": "MCP",
10414
11049
  "agents.md": "Agents.md",
11050
+ "ruler": "Ruler",
10415
11051
  "generic": ""
10416
11052
  };
10417
11053
  const subtypeLabels = {
@@ -10596,10 +11232,13 @@ async function handleInstall(packageSpec, options) {
10596
11232
  throw new CLIError("Format conversion is only supported for single-file packages");
10597
11233
  }
10598
11234
  const sourceContent = extractedFiles[0].content;
11235
+ const scopeMatch = packageId.match(/^@([^/]+)\//);
11236
+ const author = scopeMatch ? scopeMatch[1] : "unknown";
10599
11237
  const metadata = {
10600
11238
  id: packageId,
10601
11239
  name: pkg.name || packageId,
10602
11240
  version: actualVersion,
11241
+ author,
10603
11242
  tags: pkg.tags || []
10604
11243
  };
10605
11244
  let canonicalPkg;
@@ -11013,13 +11652,13 @@ async function extractTarball(tarball, packageId) {
11013
11652
  await cleanup();
11014
11653
  }
11015
11654
  }
11016
- async function collectExtractedFiles(rootDir, excludedNames, fs10) {
11655
+ async function collectExtractedFiles(rootDir, excludedNames, fs11) {
11017
11656
  const files = [];
11018
11657
  const dirs = [rootDir];
11019
11658
  while (dirs.length > 0) {
11020
11659
  const currentDir = dirs.pop();
11021
11660
  if (!currentDir) continue;
11022
- const entries = await fs10.readdir(currentDir, { withFileTypes: true });
11661
+ const entries = await fs11.readdir(currentDir, { withFileTypes: true });
11023
11662
  for (const entry of entries) {
11024
11663
  const fullPath = import_path8.default.join(currentDir, entry.name);
11025
11664
  if (entry.isDirectory()) {
@@ -11032,7 +11671,7 @@ async function collectExtractedFiles(rootDir, excludedNames, fs10) {
11032
11671
  if (excludedNames.has(entry.name)) {
11033
11672
  continue;
11034
11673
  }
11035
- const content = await fs10.readFile(fullPath, "utf-8");
11674
+ const content = await fs11.readFile(fullPath, "utf-8");
11036
11675
  const relativePath = import_path8.default.relative(rootDir, fullPath).split(import_path8.default.sep).join("/");
11037
11676
  files.push({
11038
11677
  name: relativePath,
@@ -11164,9 +11803,9 @@ var init_install = __esm({
11164
11803
 
11165
11804
  // src/index.ts
11166
11805
  init_cjs_shims();
11167
- var import_commander28 = require("commander");
11168
- var import_fs13 = require("fs");
11169
- var import_path16 = require("path");
11806
+ var import_commander29 = require("commander");
11807
+ var import_fs14 = require("fs");
11808
+ var import_path17 = require("path");
11170
11809
 
11171
11810
  // src/commands/list.ts
11172
11811
  init_cjs_shims();
@@ -11769,6 +12408,7 @@ function getPackageIcon(format, subtype) {
11769
12408
  "gemini": "\u2728",
11770
12409
  "mcp": "\u{1F517}",
11771
12410
  "agents.md": "\u{1F4DD}",
12411
+ "ruler": "\u{1F4CF}",
11772
12412
  "generic": "\u{1F4E6}"
11773
12413
  };
11774
12414
  return subtypeIcons[subtype] || formatIcons[format] || "\u{1F4E6}";
@@ -11784,6 +12424,7 @@ function getPackageLabel(format, subtype) {
11784
12424
  "gemini": "Gemini",
11785
12425
  "mcp": "MCP",
11786
12426
  "agents.md": "Agents.md",
12427
+ "ruler": "Ruler",
11787
12428
  "generic": ""
11788
12429
  };
11789
12430
  const subtypeLabels = {
@@ -11991,6 +12632,22 @@ Try:`);
11991
12632
  \u{1F310} View in browser: ${webappUrl}`);
11992
12633
  return;
11993
12634
  }
12635
+ if (result.fallback) {
12636
+ console.log("\n\u274C No packages found for your search");
12637
+ let filterMsg = "";
12638
+ if (options.subtype) {
12639
+ filterMsg = ` (${options.subtype}`;
12640
+ if (options.format) {
12641
+ filterMsg += ` for ${options.format}`;
12642
+ }
12643
+ filterMsg += ")";
12644
+ } else if (options.format) {
12645
+ filterMsg = ` (${options.format} format)`;
12646
+ }
12647
+ console.log(`
12648
+ \u{1F4A1} Showing top 10 most popular packages${filterMsg} instead:
12649
+ `);
12650
+ }
11994
12651
  const totalPages = Math.ceil(result.total / limit);
11995
12652
  const shouldPaginate = options.interactive !== false && totalPages > 1;
11996
12653
  if (!shouldPaginate) {
@@ -16332,8 +16989,8 @@ var import_readline = require("readline");
16332
16989
  var import_chalk2 = __toESM(require_source());
16333
16990
  init_errors();
16334
16991
  init_dist();
16335
- function getDefaultPath(format, filename, subtype) {
16336
- const baseName = (0, import_path15.basename)(filename, (0, import_path15.extname)(filename));
16992
+ function getDefaultPath(format, filename, subtype, customName) {
16993
+ const baseName = customName || (0, import_path15.basename)(filename, (0, import_path15.extname)(filename));
16337
16994
  switch (format) {
16338
16995
  case "cursor":
16339
16996
  if (subtype === "slash-command") {
@@ -16354,6 +17011,9 @@ function getDefaultPath(format, filename, subtype) {
16354
17011
  if (subtype === "hook") {
16355
17012
  return (0, import_path15.join)(process.cwd(), ".kiro", "hooks", `${baseName}.kiro.hook`);
16356
17013
  }
17014
+ if (subtype === "agent") {
17015
+ return (0, import_path15.join)(process.cwd(), ".kiro", "agents", `${baseName}.json`);
17016
+ }
16357
17017
  return (0, import_path15.join)(process.cwd(), ".kiro", "steering", `${baseName}.md`);
16358
17018
  case "copilot":
16359
17019
  return (0, import_path15.join)(process.cwd(), ".github", "instructions", `${baseName}.instructions.md`);
@@ -16366,6 +17026,8 @@ function getDefaultPath(format, filename, subtype) {
16366
17026
  return (0, import_path15.join)(process.cwd(), "agents.md");
16367
17027
  case "gemini":
16368
17028
  return (0, import_path15.join)(process.cwd(), ".gemini", "commands", `${baseName}.toml`);
17029
+ case "ruler":
17030
+ return (0, import_path15.join)(process.cwd(), ".ruler", `${baseName}.md`);
16369
17031
  default:
16370
17032
  throw new CLIError(`Unknown format: ${format}`);
16371
17033
  }
@@ -16399,6 +17061,9 @@ function detectFormat(content, filepath) {
16399
17061
  if (ext === ".toml" || filepath.includes(".gemini/commands")) {
16400
17062
  return "gemini";
16401
17063
  }
17064
+ if (filepath.includes(".ruler/")) {
17065
+ return "ruler";
17066
+ }
16402
17067
  if (isClaudeFormat(content)) {
16403
17068
  if (content.includes("type: skill")) return "claude-skill";
16404
17069
  if (content.includes("type: agent")) return "claude-agent";
@@ -16411,6 +17076,7 @@ function detectFormat(content, filepath) {
16411
17076
  if (isCopilotFormat(content)) return "copilot";
16412
17077
  if (isContinueFormat(content)) return "continue";
16413
17078
  if (isAgentsMdFormat(content)) return "agents.md";
17079
+ if (isRulerFormat(content)) return "ruler";
16414
17080
  return null;
16415
17081
  }
16416
17082
  async function confirmOverwrite(filepath) {
@@ -16474,7 +17140,12 @@ async function handleConvert(sourcePath, options) {
16474
17140
  canonicalPkg = fromWindsurf(content, metadata);
16475
17141
  break;
16476
17142
  case "kiro":
16477
- canonicalPkg = fromKiro(content, metadata);
17143
+ if (isKiroAgentFormat(content)) {
17144
+ const result2 = fromKiroAgent(content);
17145
+ canonicalPkg = JSON.parse(result2.content);
17146
+ } else {
17147
+ canonicalPkg = fromKiro(content, metadata);
17148
+ }
16478
17149
  break;
16479
17150
  case "copilot":
16480
17151
  canonicalPkg = fromCopilot(content, metadata);
@@ -16488,6 +17159,10 @@ async function handleConvert(sourcePath, options) {
16488
17159
  case "gemini":
16489
17160
  canonicalPkg = fromGemini(content, metadata);
16490
17161
  break;
17162
+ case "ruler":
17163
+ const rulerResult = fromRuler(content);
17164
+ canonicalPkg = JSON.parse(rulerResult.content);
17165
+ break;
16491
17166
  default:
16492
17167
  throw new CLIError(`Unsupported source format: ${sourceFormat}`);
16493
17168
  }
@@ -16512,10 +17187,14 @@ async function handleConvert(sourcePath, options) {
16512
17187
  result = toCopilot(canonicalPkg);
16513
17188
  break;
16514
17189
  case "kiro":
16515
- result = toKiro(canonicalPkg, {
16516
- kiroConfig: { inclusion: "always" }
16517
- // Default to always include
16518
- });
17190
+ if (options.subtype === "agent") {
17191
+ result = toKiroAgent(canonicalPkg);
17192
+ } else {
17193
+ result = toKiro(canonicalPkg, {
17194
+ kiroConfig: { inclusion: "always" }
17195
+ // Default to always include
17196
+ });
17197
+ }
16519
17198
  break;
16520
17199
  case "agents.md":
16521
17200
  result = toAgentsMd(canonicalPkg);
@@ -16523,6 +17202,9 @@ async function handleConvert(sourcePath, options) {
16523
17202
  case "gemini":
16524
17203
  result = toGemini(canonicalPkg);
16525
17204
  break;
17205
+ case "ruler":
17206
+ result = toRuler(canonicalPkg);
17207
+ break;
16526
17208
  default:
16527
17209
  throw new CLIError(`Unsupported target format: ${options.to}`);
16528
17210
  }
@@ -16530,7 +17212,7 @@ async function handleConvert(sourcePath, options) {
16530
17212
  throw new CLIError("Conversion failed: No content generated");
16531
17213
  }
16532
17214
  console.log(import_chalk2.default.green(`\u2713 Converted from ${sourceFormat} to ${options.to}`));
16533
- const outputPath = options.output || getDefaultPath(options.to, sourcePath, options.subtype);
17215
+ const outputPath = options.output || getDefaultPath(options.to, sourcePath, options.subtype, options.name);
16534
17216
  if ((0, import_fs12.existsSync)(outputPath) && !options.yes) {
16535
17217
  const shouldOverwrite = await confirmOverwrite(outputPath);
16536
17218
  if (!shouldOverwrite) {
@@ -16554,6 +17236,8 @@ async function handleConvert(sourcePath, options) {
16554
17236
  console.log(import_chalk2.default.dim("\u{1F4A1} Kiro will automatically load steering files from .kiro/steering/"));
16555
17237
  } else if (options.to === "gemini") {
16556
17238
  console.log(import_chalk2.default.dim("\u{1F4A1} Gemini will automatically load commands from .gemini/commands/"));
17239
+ } else if (options.to === "ruler") {
17240
+ console.log(import_chalk2.default.dim("\u{1F4A1} Ruler will automatically load and distribute rules from .ruler/"));
16557
17241
  }
16558
17242
  } catch (error) {
16559
17243
  console.log(import_chalk2.default.red("\u2716 Conversion failed"));
@@ -16561,12 +17245,12 @@ async function handleConvert(sourcePath, options) {
16561
17245
  }
16562
17246
  }
16563
17247
  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) => {
17248
+ 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
17249
  try {
16566
17250
  if (!options.to) {
16567
17251
  throw new CLIError("Target format is required. Use --to <format>");
16568
17252
  }
16569
- const validFormats = ["cursor", "claude", "windsurf", "kiro", "copilot", "continue", "agents.md", "gemini"];
17253
+ const validFormats = ["cursor", "claude", "windsurf", "kiro", "copilot", "continue", "agents.md", "gemini", "ruler"];
16570
17254
  if (!validFormats.includes(options.to)) {
16571
17255
  throw new CLIError(
16572
17256
  `Invalid format: ${options.to}
@@ -16586,6 +17270,187 @@ Valid subtypes: ${validSubtypes.join(", ")}`
16586
17270
  to: options.to,
16587
17271
  subtype: options.subtype,
16588
17272
  output: options.output,
17273
+ name: options.name,
17274
+ yes: options.yes
17275
+ });
17276
+ } catch (error) {
17277
+ if (error instanceof CLIError) {
17278
+ throw error;
17279
+ }
17280
+ throw new CLIError(error.message);
17281
+ }
17282
+ });
17283
+ return command;
17284
+ }
17285
+
17286
+ // src/commands/export.ts
17287
+ init_cjs_shims();
17288
+ var import_commander28 = require("commander");
17289
+ var import_fs13 = require("fs");
17290
+ var import_path16 = require("path");
17291
+ var import_chalk3 = __toESM(require_source());
17292
+ init_errors();
17293
+ init_lockfile();
17294
+ init_telemetry();
17295
+ async function exportToRuler(options) {
17296
+ console.log(import_chalk3.default.dim("\u{1F4E6} Exporting installed packages to Ruler format..."));
17297
+ console.log();
17298
+ const packages = await listPackages();
17299
+ if (packages.length === 0) {
17300
+ console.log(import_chalk3.default.yellow("\u26A0 No packages installed"));
17301
+ console.log(import_chalk3.default.dim("Install packages first with: prpm install <package>"));
17302
+ return;
17303
+ }
17304
+ console.log(import_chalk3.default.green(`\u2713 Found ${packages.length} installed package${packages.length === 1 ? "" : "s"}`));
17305
+ console.log();
17306
+ const outputDir = options.output || (0, import_path16.join)(process.cwd(), ".ruler");
17307
+ let rulerExists = false;
17308
+ try {
17309
+ await import_fs13.promises.access(outputDir);
17310
+ rulerExists = true;
17311
+ } catch {
17312
+ }
17313
+ if (!rulerExists) {
17314
+ console.log(import_chalk3.default.yellow(`\u26A0 ${outputDir} directory not found`));
17315
+ console.log(import_chalk3.default.dim("Creating .ruler directory..."));
17316
+ await import_fs13.promises.mkdir(outputDir, { recursive: true });
17317
+ console.log(import_chalk3.default.green(`\u2713 Created ${outputDir}/`));
17318
+ console.log();
17319
+ }
17320
+ let exportedCount = 0;
17321
+ let skippedCount = 0;
17322
+ for (const pkg of packages) {
17323
+ const packageName = pkg.id.split("/").pop() || pkg.id;
17324
+ if (!pkg.installedPath) {
17325
+ console.log(import_chalk3.default.yellow(`\u26A0 Skipping ${pkg.id} - no installation path found`));
17326
+ skippedCount++;
17327
+ continue;
17328
+ }
17329
+ try {
17330
+ const content = await import_fs13.promises.readFile(pkg.installedPath, "utf-8");
17331
+ const rulerContent = createRulerFormat(pkg.id, pkg.version, content, pkg.format, pkg.subtype);
17332
+ const rulerFilename = `${packageName}.md`;
17333
+ const rulerPath = (0, import_path16.join)(outputDir, rulerFilename);
17334
+ await import_fs13.promises.writeFile(rulerPath, rulerContent, "utf-8");
17335
+ console.log(import_chalk3.default.green(`\u2713 Exported ${pkg.id} \u2192 ${rulerFilename}`));
17336
+ exportedCount++;
17337
+ } catch (error) {
17338
+ console.log(import_chalk3.default.red(`\u2716 Failed to export ${pkg.id}: ${error instanceof Error ? error.message : String(error)}`));
17339
+ skippedCount++;
17340
+ }
17341
+ }
17342
+ console.log();
17343
+ console.log(import_chalk3.default.green(`\u2713 Export complete`));
17344
+ console.log(import_chalk3.default.dim(` Exported: ${exportedCount} package${exportedCount === 1 ? "" : "s"}`));
17345
+ if (skippedCount > 0) {
17346
+ console.log(import_chalk3.default.dim(` Skipped: ${skippedCount} package${skippedCount === 1 ? "" : "s"}`));
17347
+ }
17348
+ console.log();
17349
+ await ensureRulerConfig(outputDir);
17350
+ console.log(import_chalk3.default.bold("\u{1F4CB} Next steps:"));
17351
+ console.log(import_chalk3.default.dim("1. Review the exported files in .ruler/"));
17352
+ console.log(import_chalk3.default.dim("2. Edit ruler.toml to configure which agents should use these rules"));
17353
+ console.log(import_chalk3.default.dim("3. Run: ruler apply"));
17354
+ console.log();
17355
+ console.log(import_chalk3.default.dim("\u{1F4A1} Learn more about Ruler: https://okigu.com/ruler"));
17356
+ }
17357
+ function createRulerFormat(packageId, version, content, format, subtype) {
17358
+ const contentWithoutFrontmatter = content.replace(/^---\n[\s\S]*?\n---\n/, "");
17359
+ const frontmatter = [
17360
+ "---",
17361
+ `# Exported from PRPM`,
17362
+ `# Package: ${packageId}`,
17363
+ `# Version: ${version}`,
17364
+ format ? `# Original Format: ${format}` : "",
17365
+ subtype ? `# Subtype: ${subtype}` : "",
17366
+ `# Exported: ${(/* @__PURE__ */ new Date()).toISOString()}`,
17367
+ "---",
17368
+ ""
17369
+ ].filter(Boolean).join("\n");
17370
+ return frontmatter + contentWithoutFrontmatter;
17371
+ }
17372
+ async function ensureRulerConfig(rulerDir) {
17373
+ const configPath = (0, import_path16.join)((0, import_path16.dirname)(rulerDir), "ruler.toml");
17374
+ try {
17375
+ await import_fs13.promises.access(configPath);
17376
+ console.log(import_chalk3.default.dim("\u2139 ruler.toml already exists (not modified)"));
17377
+ } catch {
17378
+ const basicConfig = `# Ruler Configuration
17379
+ # Learn more: https://okigu.com/ruler
17380
+
17381
+ # Define which agents should use these rules
17382
+ # Example:
17383
+ # [agents.cursor]
17384
+ # enabled = true
17385
+ # rules = ["*"] # Apply all rules
17386
+ #
17387
+ # [agents.claude]
17388
+ # enabled = true
17389
+ # rules = ["*"]
17390
+
17391
+ # Uncomment and configure the agents you use:
17392
+ # [agents.cursor]
17393
+ # enabled = false
17394
+ #
17395
+ # [agents.claude]
17396
+ # enabled = false
17397
+ #
17398
+ # [agents.github-copilot]
17399
+ # enabled = false
17400
+ `;
17401
+ await import_fs13.promises.writeFile(configPath, basicConfig, "utf-8");
17402
+ console.log(import_chalk3.default.green(`\u2713 Created ruler.toml configuration template`));
17403
+ }
17404
+ }
17405
+ async function handleExport(options) {
17406
+ const startTime = Date.now();
17407
+ let success = false;
17408
+ let error;
17409
+ let packageCount = 0;
17410
+ try {
17411
+ if (options.to === "ruler") {
17412
+ await exportToRuler(options);
17413
+ const packages = await listPackages();
17414
+ packageCount = packages.length;
17415
+ success = true;
17416
+ } else {
17417
+ throw new CLIError(`Unsupported export target: ${options.to}`);
17418
+ }
17419
+ } catch (err) {
17420
+ error = err instanceof Error ? err.message : String(err);
17421
+ throw new CLIError(`\u274C Export failed: ${error}`, 1);
17422
+ } finally {
17423
+ await telemetry.track({
17424
+ command: "export",
17425
+ success,
17426
+ error,
17427
+ duration: Date.now() - startTime,
17428
+ data: {
17429
+ target: options.to,
17430
+ packageCount
17431
+ }
17432
+ });
17433
+ await telemetry.shutdown();
17434
+ }
17435
+ }
17436
+ function createExportCommand() {
17437
+ const command = new import_commander28.Command("export");
17438
+ 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) => {
17439
+ try {
17440
+ if (!options.to) {
17441
+ throw new CLIError("Export target is required. Use --to <tool>");
17442
+ }
17443
+ const validTargets = ["ruler"];
17444
+ if (!validTargets.includes(options.to)) {
17445
+ throw new CLIError(
17446
+ `Invalid export target: ${options.to}
17447
+
17448
+ Currently supported: ${validTargets.join(", ")}`
17449
+ );
17450
+ }
17451
+ await handleExport({
17452
+ to: options.to,
17453
+ output: options.output,
16589
17454
  yes: options.yes
16590
17455
  });
16591
17456
  } catch (error) {
@@ -16603,14 +17468,14 @@ init_telemetry();
16603
17468
  init_errors();
16604
17469
  function getVersion() {
16605
17470
  try {
16606
- const packageJsonPath = (0, import_path16.join)(__dirname, "../package.json");
16607
- const packageJson = JSON.parse((0, import_fs13.readFileSync)(packageJsonPath, "utf-8"));
17471
+ const packageJsonPath = (0, import_path17.join)(__dirname, "../package.json");
17472
+ const packageJson = JSON.parse((0, import_fs14.readFileSync)(packageJsonPath, "utf-8"));
16608
17473
  return packageJson.version || "0.0.0";
16609
17474
  } catch {
16610
17475
  return "0.0.0";
16611
17476
  }
16612
17477
  }
16613
- var program = new import_commander28.Command();
17478
+ var program = new import_commander29.Command();
16614
17479
  program.name("prpm").description("Prompt Package Manager - Install and manage prompt-based files").version(getVersion());
16615
17480
  program.addCommand(createInitCommand());
16616
17481
  program.addCommand(createCatalogCommand());
@@ -16639,6 +17504,7 @@ program.addCommand(createBuyCreditsCommand());
16639
17504
  program.addCommand(createSchemaCommand());
16640
17505
  program.addCommand(createConfigCommand());
16641
17506
  program.addCommand(createConvertCommand());
17507
+ program.addCommand(createExportCommand());
16642
17508
  (async () => {
16643
17509
  try {
16644
17510
  await program.parseAsync();