prpm 2.1.16 → 2.1.17

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
@@ -8645,6 +8645,96 @@ var init_from_zed = __esm({
8645
8645
  }
8646
8646
  });
8647
8647
 
8648
+ // ../converters/dist/from-codex.js
8649
+ function parseFrontmatter8(content) {
8650
+ const normalizedContent = content.replace(/\r\n/g, "\n");
8651
+ const match = normalizedContent.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
8652
+ if (!match) {
8653
+ return { frontmatter: {}, body: normalizedContent };
8654
+ }
8655
+ try {
8656
+ const frontmatter = jsYaml.load(match[1]);
8657
+ const body = match[2];
8658
+ return { frontmatter: frontmatter || {}, body };
8659
+ } catch (error) {
8660
+ return { frontmatter: {}, body: normalizedContent };
8661
+ }
8662
+ }
8663
+ function parseAllowedTools(toolsString) {
8664
+ return toolsString.split(/\s+/).filter(Boolean).map((tool) => {
8665
+ const match = tool.match(/^([A-Za-z]+)(?:\([^)]*\))?$/);
8666
+ return match ? match[1] : tool;
8667
+ }).filter((tool, index, arr) => arr.indexOf(tool) === index);
8668
+ }
8669
+ function fromCodex(content, metadata) {
8670
+ const { frontmatter, body } = parseFrontmatter8(content);
8671
+ const fm = frontmatter;
8672
+ const sections = [];
8673
+ const metadataSection = {
8674
+ type: "metadata",
8675
+ data: {
8676
+ title: fm.name || metadata.name || metadata.id,
8677
+ description: fm.description || metadata.description || "",
8678
+ version: metadata.version || "1.0.0",
8679
+ author: metadata.author
8680
+ }
8681
+ };
8682
+ metadataSection.data.agentSkills = {
8683
+ name: fm.name,
8684
+ license: fm.license,
8685
+ compatibility: fm.compatibility,
8686
+ allowedTools: fm["allowed-tools"],
8687
+ metadata: fm.metadata
8688
+ };
8689
+ sections.push(metadataSection);
8690
+ if (fm["allowed-tools"]) {
8691
+ const tools = parseAllowedTools(fm["allowed-tools"]);
8692
+ if (tools.length > 0) {
8693
+ const toolsSection = {
8694
+ type: "tools",
8695
+ tools,
8696
+ description: "Pre-approved tools for this skill"
8697
+ };
8698
+ sections.push(toolsSection);
8699
+ }
8700
+ }
8701
+ if (body.trim()) {
8702
+ sections.push({
8703
+ type: "instructions",
8704
+ title: "Instructions",
8705
+ content: body.trim()
8706
+ });
8707
+ }
8708
+ const canonicalContent = {
8709
+ format: "canonical",
8710
+ version: "1.0",
8711
+ sections
8712
+ };
8713
+ const pkg = {
8714
+ ...metadata,
8715
+ id: metadata.id,
8716
+ name: fm.name || metadata.name || metadata.id,
8717
+ version: metadata.version,
8718
+ author: metadata.author,
8719
+ description: fm.description || metadata.description || "",
8720
+ license: fm.license || metadata.license,
8721
+ tags: metadata.tags || [],
8722
+ format: "codex",
8723
+ subtype: "skill",
8724
+ content: canonicalContent
8725
+ };
8726
+ setTaxonomy(pkg, "codex", "skill");
8727
+ return pkg;
8728
+ }
8729
+ var init_from_codex = __esm({
8730
+ "../converters/dist/from-codex.js"() {
8731
+ "use strict";
8732
+ init_cjs_shims();
8733
+ init_taxonomy_utils();
8734
+ init_js_yaml();
8735
+ }
8736
+ });
8737
+
8648
8738
  // ../converters/dist/from-mcp-server.js
8649
8739
  function fromMCPServer(mcpServerJson, metadata) {
8650
8740
  var _a;
@@ -8758,7 +8848,7 @@ function loadSchema(format, subtype) {
8758
8848
  "claude:slash-command": "claude-slash-command.schema.json",
8759
8849
  "claude:hook": "claude-hook.schema.json",
8760
8850
  "claude:plugin": "claude-plugin.schema.json",
8761
- "copilot:skill": "copilot-skill.schema.json",
8851
+ "copilot:skill": "agent-skills.schema.json",
8762
8852
  "cursor:slash-command": "cursor-command.schema.json",
8763
8853
  "cursor:hook": "cursor-hooks.schema.json",
8764
8854
  // cursor + hook subtype uses cursor-hooks schema
@@ -8769,6 +8859,7 @@ function loadSchema(format, subtype) {
8769
8859
  "droid:hook": "droid-hook.schema.json",
8770
8860
  "opencode:slash-command": "opencode-slash-command.schema.json",
8771
8861
  "opencode:plugin": "opencode-plugin.schema.json",
8862
+ "codex:skill": "agent-skills.schema.json",
8772
8863
  "gemini:extension": "gemini-extension.schema.json",
8773
8864
  "mcp:server": "mcp-server.schema.json"
8774
8865
  };
@@ -9875,17 +9966,19 @@ ${content}`;
9875
9966
  function convertToSkill(pkg, config, warnings) {
9876
9967
  var _a, _b;
9877
9968
  let qualityScore = 100;
9878
- const skillName = config.skillName || ((_a = pkg.name) == null ? void 0 : _a.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 64)) || pkg.id.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 64);
9969
+ const metadataSection = pkg.content.sections.find((s) => s.type === "metadata");
9970
+ const agentSkillsData = (metadataSection == null ? void 0 : metadataSection.type) === "metadata" ? metadataSection.data.agentSkills : void 0;
9971
+ const skillName = (agentSkillsData == null ? void 0 : agentSkillsData.name) || config.skillName || ((_a = pkg.name) == null ? void 0 : _a.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 64)) || pkg.id.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 64);
9879
9972
  const skillDescription = config.skillDescription || pkg.description || ((_b = pkg.metadata) == null ? void 0 : _b.description) || "";
9880
9973
  if (!skillDescription) {
9881
9974
  warnings.push("Skill requires a description - using empty string");
9882
9975
  qualityScore -= 20;
9883
9976
  }
9884
- if (!/^[a-z0-9-]+$/.test(skillName)) {
9885
- warnings.push("Skill name should be lowercase with hyphens only");
9977
+ if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(skillName)) {
9978
+ warnings.push("Skill name should be lowercase alphanumeric with single hyphens (no start/end/consecutive hyphens)");
9886
9979
  qualityScore -= 10;
9887
9980
  }
9888
- const frontmatter = generateSkillFrontmatter(skillName, skillDescription);
9981
+ const frontmatter = generateSkillFrontmatter(skillName, skillDescription, pkg, agentSkillsData);
9889
9982
  const content = convertSkillContent(pkg, warnings);
9890
9983
  const fullContent = `${frontmatter}
9891
9984
 
@@ -9902,12 +9995,28 @@ ${content}`;
9902
9995
  qualityScore
9903
9996
  };
9904
9997
  }
9905
- function generateSkillFrontmatter(name, description) {
9998
+ function generateSkillFrontmatter(name, description, pkg, agentSkillsData) {
9906
9999
  const lines = ["---"];
9907
10000
  lines.push(`name: ${name}`);
9908
10001
  const truncatedDesc = description.length > 1024 ? description.slice(0, 1021) + "..." : description;
9909
10002
  const quotedDesc = `"${truncatedDesc.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, "\\n")}"`;
9910
10003
  lines.push(`description: ${quotedDesc}`);
10004
+ const license = (agentSkillsData == null ? void 0 : agentSkillsData.license) || pkg.license;
10005
+ if (license) {
10006
+ lines.push(`license: ${license}`);
10007
+ }
10008
+ if (agentSkillsData == null ? void 0 : agentSkillsData.compatibility) {
10009
+ lines.push(`compatibility: "${agentSkillsData.compatibility}"`);
10010
+ }
10011
+ if (agentSkillsData == null ? void 0 : agentSkillsData.allowedTools) {
10012
+ lines.push(`allowed-tools: ${agentSkillsData.allowedTools}`);
10013
+ }
10014
+ if ((agentSkillsData == null ? void 0 : agentSkillsData.metadata) && Object.keys(agentSkillsData.metadata).length > 0) {
10015
+ lines.push("metadata:");
10016
+ for (const [key, value] of Object.entries(agentSkillsData.metadata)) {
10017
+ lines.push(` ${key}: "${value}"`);
10018
+ }
10019
+ }
9911
10020
  lines.push("---");
9912
10021
  return lines.join("\n");
9913
10022
  }
@@ -12297,9 +12406,12 @@ function toCodex(pkg, options = {}) {
12297
12406
  let qualityScore = 100;
12298
12407
  try {
12299
12408
  const config = options.codexConfig || {};
12409
+ const isSkill = pkg.subtype === "skill";
12300
12410
  const isSlashCommand = pkg.subtype === "slash-command";
12301
12411
  let content;
12302
- if (isSlashCommand) {
12412
+ if (isSkill && !config.forceAgentsMd) {
12413
+ content = convertToSkillMd(pkg, warnings);
12414
+ } else if (isSlashCommand) {
12303
12415
  content = convertSlashCommandToSection(pkg, warnings);
12304
12416
  if (config.appendMode && config.existingContent) {
12305
12417
  content = appendToExistingAgentsMd(config.existingContent, content, pkg.name);
@@ -12329,6 +12441,74 @@ function toCodex(pkg, options = {}) {
12329
12441
  };
12330
12442
  }
12331
12443
  }
12444
+ function convertToSkillMd(pkg, warnings) {
12445
+ var _a;
12446
+ const lines = [];
12447
+ const metadataSection = pkg.content.sections.find((s) => s.type === "metadata");
12448
+ const toolsSection = pkg.content.sections.find((s) => s.type === "tools");
12449
+ const title = ((_a = pkg.metadata) == null ? void 0 : _a.title) || pkg.name;
12450
+ const description = pkg.description || "";
12451
+ const frontmatter = {
12452
+ name: slugify(title),
12453
+ description: truncateDescription(description, 1024)
12454
+ };
12455
+ if (pkg.license) {
12456
+ frontmatter.license = pkg.license;
12457
+ }
12458
+ if ((metadataSection == null ? void 0 : metadataSection.type) === "metadata" && metadataSection.data.agentSkills) {
12459
+ const skillsData = metadataSection.data.agentSkills;
12460
+ if (skillsData.name) {
12461
+ frontmatter.name = skillsData.name;
12462
+ }
12463
+ if (skillsData.license) {
12464
+ frontmatter.license = skillsData.license;
12465
+ }
12466
+ if (skillsData.compatibility) {
12467
+ frontmatter.compatibility = skillsData.compatibility;
12468
+ }
12469
+ if (skillsData.allowedTools) {
12470
+ frontmatter["allowed-tools"] = skillsData.allowedTools;
12471
+ }
12472
+ if (skillsData.metadata && Object.keys(skillsData.metadata).length > 0) {
12473
+ frontmatter.metadata = skillsData.metadata;
12474
+ }
12475
+ }
12476
+ if ((toolsSection == null ? void 0 : toolsSection.type) === "tools" && toolsSection.tools.length > 0 && !frontmatter["allowed-tools"]) {
12477
+ frontmatter["allowed-tools"] = toolsSection.tools.join(" ");
12478
+ }
12479
+ lines.push("---");
12480
+ lines.push(jsYaml.dump(frontmatter, { indent: 2, lineWidth: -1 }).trim());
12481
+ lines.push("---");
12482
+ lines.push("");
12483
+ for (const section of pkg.content.sections) {
12484
+ if (section.type === "metadata")
12485
+ continue;
12486
+ if (section.type === "tools")
12487
+ continue;
12488
+ if (section.type === "persona") {
12489
+ warnings.push("Persona section skipped (not supported by Agent Skills format)");
12490
+ continue;
12491
+ }
12492
+ const sectionContent = convertSection13(section, warnings);
12493
+ if (sectionContent) {
12494
+ lines.push(sectionContent);
12495
+ lines.push("");
12496
+ }
12497
+ }
12498
+ return lines.join("\n").trim() + "\n";
12499
+ }
12500
+ function truncateDescription(desc, maxLength) {
12501
+ if (desc.length <= maxLength)
12502
+ return desc;
12503
+ return desc.substring(0, maxLength - 3) + "...";
12504
+ }
12505
+ function slugify(name) {
12506
+ const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
12507
+ if (!slug) {
12508
+ return "unnamed-skill";
12509
+ }
12510
+ return slug.slice(0, 64);
12511
+ }
12332
12512
  function convertSlashCommandToSection(pkg, warnings) {
12333
12513
  const lines = [];
12334
12514
  const commandName = pkg.name.replace(/^\//, "");
@@ -12419,10 +12599,15 @@ function convertToAgentsMd(pkg, warnings) {
12419
12599
  }
12420
12600
  return lines.join("\n").trim();
12421
12601
  }
12602
+ function escapeRegex(str2) {
12603
+ return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12604
+ }
12422
12605
  function appendToExistingAgentsMd(existingContent, newSection, commandName) {
12423
- const sectionHeader = `## ${commandName.replace(/^\//, "")}`;
12606
+ const cleanCommandName = commandName.replace(/^\//, "");
12607
+ const escapedCommandName = escapeRegex(cleanCommandName);
12608
+ const sectionHeader = `## ${cleanCommandName}`;
12424
12609
  if (existingContent.includes(sectionHeader)) {
12425
- const regex = new RegExp(`## ${commandName.replace(/^\//, "")}[\\s\\S]*?(?=## |$)`, "g");
12610
+ const regex = new RegExp(`## ${escapedCommandName}[\\s\\S]*?(?=## |$)`, "g");
12426
12611
  return existingContent.replace(regex, newSection + "\n\n");
12427
12612
  }
12428
12613
  const trimmedExisting = existingContent.trim();
@@ -12536,13 +12721,25 @@ function parseArgumentHint2(hint) {
12536
12721
  }
12537
12722
  return hint.split(/\s+/).filter(Boolean);
12538
12723
  }
12539
- function generateFilename2() {
12724
+ function generateFilename2(pkg) {
12725
+ if ((pkg == null ? void 0 : pkg.subtype) === "skill") {
12726
+ return "SKILL.md";
12727
+ }
12540
12728
  return "AGENTS.md";
12541
12729
  }
12730
+ function isCodexSkillFormat(content) {
12731
+ const normalizedContent = content.replace(/\r\n/g, "\n");
12732
+ const match = normalizedContent.match(/^---\n([\s\S]*?)\n---/);
12733
+ if (!match)
12734
+ return false;
12735
+ const frontmatterText = match[1];
12736
+ return frontmatterText.includes("name:") && frontmatterText.includes("description:");
12737
+ }
12542
12738
  var init_to_codex = __esm({
12543
12739
  "../converters/dist/to-codex.js"() {
12544
12740
  "use strict";
12545
12741
  init_cjs_shims();
12742
+ init_js_yaml();
12546
12743
  }
12547
12744
  });
12548
12745
 
@@ -12625,7 +12822,7 @@ var init_to_mcp_server = __esm({
12625
12822
  });
12626
12823
 
12627
12824
  // ../converters/dist/schema-files.js
12628
- var import_module, import_path7, schemaRequire, convertersPackagePath, convertersDir, loadSchema2, formatRegistrySchema, agentsMdSchema, canonicalSchema, claudeSchema, continueSchema, copilotSchema, cursorSchema, droidSchema, geminiMdSchema, geminiSchema, kiroSteeringSchema, opencodeSchema, rulerSchema, windsurfSchema, traeSchema, aiderSchema, zencoderSchema, replitSchema, zedSchema, claudeAgentSchema, claudeHookSchema, claudeSkillSchema, claudeSlashCommandSchema, copilotSkillSchema, cursorCommandSchema, cursorHooksSchema, droidHookSchema, droidSkillSchema, droidSlashCommandSchema, kiroAgentSchema, kiroHookSchema, opencodeSlashCommandSchema;
12825
+ var import_module, import_path7, schemaRequire, convertersPackagePath, convertersDir, loadSchema2, formatRegistrySchema, agentsMdSchema, canonicalSchema, claudeSchema, continueSchema, copilotSchema, cursorSchema, droidSchema, geminiMdSchema, geminiSchema, kiroSteeringSchema, opencodeSchema, rulerSchema, windsurfSchema, traeSchema, aiderSchema, zencoderSchema, replitSchema, zedSchema, claudeAgentSchema, claudeHookSchema, claudeSkillSchema, claudeSlashCommandSchema, agentSkillsSchema, copilotSkillSchema, codexSkillSchema, cursorCommandSchema, cursorHooksSchema, droidHookSchema, droidSkillSchema, droidSlashCommandSchema, kiroAgentSchema, kiroHookSchema, opencodeSlashCommandSchema;
12629
12826
  var init_schema_files = __esm({
12630
12827
  "../converters/dist/schema-files.js"() {
12631
12828
  "use strict";
@@ -12659,7 +12856,9 @@ var init_schema_files = __esm({
12659
12856
  claudeHookSchema = loadSchema2("claude-hook.schema.json");
12660
12857
  claudeSkillSchema = loadSchema2("claude-skill.schema.json");
12661
12858
  claudeSlashCommandSchema = loadSchema2("claude-slash-command.schema.json");
12662
- copilotSkillSchema = loadSchema2("copilot-skill.schema.json");
12859
+ agentSkillsSchema = loadSchema2("agent-skills.schema.json");
12860
+ copilotSkillSchema = agentSkillsSchema;
12861
+ codexSkillSchema = agentSkillsSchema;
12663
12862
  cursorCommandSchema = loadSchema2("cursor-command.schema.json");
12664
12863
  cursorHooksSchema = loadSchema2("cursor-hooks.schema.json");
12665
12864
  droidHookSchema = loadSchema2("droid-hook.schema.json");
@@ -12978,7 +13177,8 @@ var init_format_registry = __esm({
12978
13177
  },
12979
13178
  codex: {
12980
13179
  name: "OpenAI Codex CLI",
12981
- description: "OpenAI Codex CLI using AGENTS.md for project instructions",
13180
+ description: "OpenAI Codex CLI skills and AGENTS.md project instructions",
13181
+ documentationUrl: "https://developers.openai.com/codex/skills",
12982
13182
  subtypes: {
12983
13183
  rule: {
12984
13184
  directory: ".",
@@ -12991,7 +13191,7 @@ var init_format_registry = __esm({
12991
13191
  fileExtension: ".md"
12992
13192
  },
12993
13193
  skill: {
12994
- directory: ".openskills",
13194
+ directory: ".codex/skills",
12995
13195
  filePatterns: ["SKILL.md"],
12996
13196
  nested: true,
12997
13197
  nestedIndicator: "SKILL.md",
@@ -13434,6 +13634,7 @@ __export(dist_exports, {
13434
13634
  SCRIPT_LANGUAGE_EXTENSIONS: () => SCRIPT_LANGUAGE_EXTENSIONS,
13435
13635
  VALID_CURSOR_HOOK_TYPES: () => VALID_CURSOR_HOOK_TYPES,
13436
13636
  VALID_HOOK_MAPPING_STRATEGIES: () => VALID_HOOK_MAPPING_STRATEGIES,
13637
+ agentSkillsSchema: () => agentSkillsSchema,
13437
13638
  agentsMdSchema: () => agentsMdSchema,
13438
13639
  aiderSchema: () => aiderSchema,
13439
13640
  canonicalSchema: () => canonicalSchema,
@@ -13442,6 +13643,7 @@ __export(dist_exports, {
13442
13643
  claudeSchema: () => claudeSchema,
13443
13644
  claudeSkillSchema: () => claudeSkillSchema,
13444
13645
  claudeSlashCommandSchema: () => claudeSlashCommandSchema,
13646
+ codexSkillSchema: () => codexSkillSchema,
13445
13647
  continueSchema: () => continueSchema,
13446
13648
  copilotSchema: () => copilotSchema,
13447
13649
  copilotSkillSchema: () => copilotSkillSchema,
@@ -13465,6 +13667,7 @@ __export(dist_exports, {
13465
13667
  fromAider: () => fromAider,
13466
13668
  fromClaude: () => fromClaude,
13467
13669
  fromClaudePlugin: () => fromClaudePlugin,
13670
+ fromCodex: () => fromCodex,
13468
13671
  fromContinue: () => fromContinue,
13469
13672
  fromCopilot: () => fromCopilot,
13470
13673
  fromCursor: () => fromCursor,
@@ -13512,6 +13715,7 @@ __export(dist_exports, {
13512
13715
  isAgentsMdFormat: () => isAgentsMdFormat,
13513
13716
  isAiderFormat: () => isAiderFormat,
13514
13717
  isClaudeFormat: () => isClaudeFormat,
13718
+ isCodexSkillFormat: () => isCodexSkillFormat,
13515
13719
  isContinueFormat: () => isContinueFormat,
13516
13720
  isCopilotFormat: () => isCopilotFormat,
13517
13721
  isCursorFormat: () => isCursorFormat,
@@ -13602,6 +13806,7 @@ var init_dist = __esm({
13602
13806
  init_from_zencoder();
13603
13807
  init_from_replit();
13604
13808
  init_from_zed();
13809
+ init_from_codex();
13605
13810
  init_from_mcp_server();
13606
13811
  init_to_cursor();
13607
13812
  init_to_cursor_hooks();
@@ -24911,6 +25116,9 @@ function getDefaultPath(format, filename, subtype, customName) {
24911
25116
  case "droid":
24912
25117
  return (0, import_path23.join)(process.cwd(), ".factory", `${baseName}.md`);
24913
25118
  case "codex":
25119
+ if (subtype === "skill") {
25120
+ return (0, import_path23.join)(process.cwd(), ".codex", "skills", baseName, "SKILL.md");
25121
+ }
24914
25122
  return (0, import_path23.join)(process.cwd(), "AGENTS.md");
24915
25123
  default:
24916
25124
  throw new CLIError(`Unknown format: ${format}`);
@@ -24954,6 +25162,9 @@ function detectFormat(content, filepath) {
24954
25162
  if (filepath.includes(".zed/extensions") || filepath.includes(".zed/slash_commands")) {
24955
25163
  return "zed";
24956
25164
  }
25165
+ if (filepath.includes(".codex/skills") || (0, import_path23.basename)(filepath) === "SKILL.md") {
25166
+ return "codex";
25167
+ }
24957
25168
  if (isCursorHooksFormat(content)) return "cursor-hooks";
24958
25169
  if (isClaudeFormat(content)) {
24959
25170
  if (content.includes("type: skill")) return "claude-skill";
@@ -24969,6 +25180,7 @@ function detectFormat(content, filepath) {
24969
25180
  if (isAgentsMdFormat(content)) return "agents.md";
24970
25181
  if (isRulerFormat(content)) return "ruler";
24971
25182
  if (isZedFormat(content)) return "zed";
25183
+ if (isCodexSkillFormat(content)) return "codex";
24972
25184
  return null;
24973
25185
  }
24974
25186
  async function confirmOverwrite(filepath) {
@@ -25090,6 +25302,9 @@ async function handleConvert(sourcePath, options) {
25090
25302
  case "droid":
25091
25303
  canonicalPkg = fromDroid(content, metadata);
25092
25304
  break;
25305
+ case "codex":
25306
+ canonicalPkg = fromCodex(content, metadata);
25307
+ break;
25093
25308
  default:
25094
25309
  throw new CLIError(`Unsupported source format: ${sourceFormat}`);
25095
25310
  }
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://registry.prpm.dev/api/v1/schemas/agent-skills.json",
4
+ "$comment": "https://agentskills.io/specification",
5
+ "title": "Agent Skills Format",
6
+ "description": "JSON Schema for Agent Skills - a shared standard implemented by Codex, GitHub Copilot, and other AI assistants. Skills are SKILL.md files with YAML frontmatter.",
7
+ "type": "object",
8
+ "required": ["frontmatter", "content"],
9
+ "properties": {
10
+ "frontmatter": {
11
+ "type": "object",
12
+ "required": ["name", "description"],
13
+ "properties": {
14
+ "name": {
15
+ "type": "string",
16
+ "description": "Skill identifier: 1-64 chars, lowercase alphanumeric and hyphens only, cannot start/end with hyphens or contain consecutive hyphens. Must match parent directory name.",
17
+ "minLength": 1,
18
+ "maxLength": 64,
19
+ "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
20
+ },
21
+ "description": {
22
+ "type": "string",
23
+ "description": "Explains what the skill does and when to use it. Should include specific keywords for agent identification. (1-1024 chars)",
24
+ "minLength": 1,
25
+ "maxLength": 1024
26
+ },
27
+ "license": {
28
+ "type": "string",
29
+ "description": "Specifies skill licensing terms. Keep brief (license name or bundled file reference)."
30
+ },
31
+ "compatibility": {
32
+ "type": "string",
33
+ "description": "Indicates environment requirements (products, system packages, network access). Example: 'Requires git, docker, jq, and internet access'",
34
+ "maxLength": 500
35
+ },
36
+ "allowed-tools": {
37
+ "type": "string",
38
+ "description": "Space-delimited list of pre-approved tools. Experimental; support varies by implementation. Example: 'Bash(git:*) Bash(jq:*) Read'"
39
+ },
40
+ "metadata": {
41
+ "type": "object",
42
+ "description": "Arbitrary string key-value pairs for additional properties not defined by the specification",
43
+ "additionalProperties": {
44
+ "type": "string"
45
+ }
46
+ }
47
+ },
48
+ "additionalProperties": true
49
+ },
50
+ "content": {
51
+ "type": "string",
52
+ "description": "Skill instructions as markdown text. Recommended to keep under 5000 tokens for progressive disclosure."
53
+ }
54
+ },
55
+ "examples": [
56
+ {
57
+ "frontmatter": {
58
+ "name": "code-review",
59
+ "description": "Reviews code for best practices, security issues, and improvements. Use when analyzing pull requests, code changes, or conducting security audits.",
60
+ "license": "MIT",
61
+ "compatibility": "Requires git",
62
+ "metadata": {
63
+ "category": "development",
64
+ "version": "1.0.0"
65
+ }
66
+ },
67
+ "content": "You are an expert code reviewer.\n\n## Instructions\n\n- Check for code smells\n- Verify test coverage\n- Suggest improvements"
68
+ },
69
+ {
70
+ "frontmatter": {
71
+ "name": "pdf-processing",
72
+ "description": "Extracts and processes content from PDF documents. Use for document analysis, text extraction, and PDF manipulation tasks.",
73
+ "allowed-tools": "Bash(pdftotext:*) Read Write"
74
+ },
75
+ "content": "Process PDF documents using available command-line tools.\n\n## Capabilities\n\n- Extract text from PDFs\n- Convert PDF pages to images\n- Merge and split PDF files"
76
+ }
77
+ ]
78
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prpm",
3
- "version": "2.1.16",
3
+ "version": "2.1.17",
4
4
  "description": "Prompt Package Manager CLI - Install and manage prompt-based files",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -45,9 +45,9 @@
45
45
  "license": "MIT",
46
46
  "dependencies": {
47
47
  "@octokit/rest": "^22.0.0",
48
- "@pr-pm/converters": "^2.1.17",
49
- "@pr-pm/registry-client": "^2.3.16",
50
- "@pr-pm/types": "^2.1.17",
48
+ "@pr-pm/converters": "^2.1.18",
49
+ "@pr-pm/registry-client": "^2.3.17",
50
+ "@pr-pm/types": "^2.1.18",
51
51
  "ajv": "^8.17.1",
52
52
  "ajv-formats": "^3.0.1",
53
53
  "commander": "^11.1.0",
@@ -1,50 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://registry.prpm.dev/api/v1/schemas/copilot/skill.json",
4
- "$comment": "https://code.visualstudio.com/docs/copilot/customization/agent-skills",
5
- "title": "GitHub Copilot Skill Format",
6
- "description": "JSON Schema for GitHub Copilot agent skills (.github/skills/*/SKILL.md)",
7
- "type": "object",
8
- "required": ["frontmatter", "content"],
9
- "properties": {
10
- "frontmatter": {
11
- "type": "object",
12
- "description": "YAML frontmatter with skill metadata",
13
- "required": ["name", "description"],
14
- "properties": {
15
- "name": {
16
- "type": "string",
17
- "description": "Unique identifier for the skill. Must be lowercase, using hyphens for spaces.",
18
- "maxLength": 64,
19
- "pattern": "^[a-z0-9-]+$"
20
- },
21
- "description": {
22
- "type": "string",
23
- "description": "Description of what the skill does and when to use it. Be specific about both capabilities and use cases.",
24
- "maxLength": 1024
25
- }
26
- },
27
- "additionalProperties": false
28
- },
29
- "content": {
30
- "type": "string",
31
- "description": "Markdown body with detailed instructions, procedures, examples, and references to bundled resources."
32
- }
33
- },
34
- "examples": [
35
- {
36
- "frontmatter": {
37
- "name": "webapp-testing",
38
- "description": "Guides testing of web applications using browser automation and testing frameworks"
39
- },
40
- "content": "# Web Application Testing\n\nThis skill helps you test web applications effectively.\n\n## Procedures\n\n1. Set up testing environment\n2. Write unit tests\n3. Run integration tests\n\n## Resources\n\n- [Test template](./test-template.ts)"
41
- },
42
- {
43
- "frontmatter": {
44
- "name": "api-documentation",
45
- "description": "Generates and maintains API documentation following OpenAPI specifications"
46
- },
47
- "content": "# API Documentation\n\nThis skill assists with creating comprehensive API documentation.\n\n## Guidelines\n\n- Document all endpoints\n- Include request/response examples\n- Specify authentication requirements"
48
- }
49
- ]
50
- }