prpm 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +575 -164
- package/dist/schemas/droid.schema.json +45 -0
- package/dist/schemas/opencode.schema.json +105 -0
- package/package.json +4 -4
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
|
}
|
|
@@ -498,7 +499,27 @@ function getDestinationDir2(format, subtype, name) {
|
|
|
498
499
|
return ".kiro/steering";
|
|
499
500
|
case "gemini":
|
|
500
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
|
|
501
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
|
+
}
|
|
502
523
|
return ".";
|
|
503
524
|
case "generic":
|
|
504
525
|
return ".prompts";
|
|
@@ -540,7 +561,25 @@ async function directoryExists(dirPath) {
|
|
|
540
561
|
return false;
|
|
541
562
|
}
|
|
542
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
|
+
}
|
|
543
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
|
+
}
|
|
544
583
|
if (await fileExists("AGENTS.md")) {
|
|
545
584
|
return "agents.md";
|
|
546
585
|
}
|
|
@@ -552,6 +591,8 @@ async function autoDetectFormat() {
|
|
|
552
591
|
{ format: "copilot", dir: ".github/instructions" },
|
|
553
592
|
{ format: "kiro", dir: ".kiro" },
|
|
554
593
|
{ format: "gemini", dir: ".gemini" },
|
|
594
|
+
{ format: "opencode", dir: ".opencode" },
|
|
595
|
+
{ format: "droid", dir: ".factory" },
|
|
555
596
|
{ format: "agents.md", dir: ".agents" }
|
|
556
597
|
];
|
|
557
598
|
for (const { format, dir } of formatDirs) {
|
|
@@ -582,6 +623,237 @@ var init_filesystem = __esm({
|
|
|
582
623
|
}
|
|
583
624
|
});
|
|
584
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
842
|
+
}
|
|
843
|
+
function unescapeXML(str2) {
|
|
844
|
+
return str2.replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">").replace(/&/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
|
+
|
|
585
857
|
// ../../node_modules/color-name/index.js
|
|
586
858
|
var require_color_name = __commonJS({
|
|
587
859
|
"../../node_modules/color-name/index.js"(exports2, module2) {
|
|
@@ -1457,15 +1729,15 @@ var require_route = __commonJS({
|
|
|
1457
1729
|
};
|
|
1458
1730
|
}
|
|
1459
1731
|
function wrapConversion(toModel, graph) {
|
|
1460
|
-
const
|
|
1732
|
+
const path8 = [graph[toModel].parent, toModel];
|
|
1461
1733
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
1462
1734
|
let cur = graph[toModel].parent;
|
|
1463
1735
|
while (graph[cur].parent) {
|
|
1464
|
-
|
|
1736
|
+
path8.unshift(graph[cur].parent);
|
|
1465
1737
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
1466
1738
|
cur = graph[cur].parent;
|
|
1467
1739
|
}
|
|
1468
|
-
fn.conversion =
|
|
1740
|
+
fn.conversion = path8;
|
|
1469
1741
|
return fn;
|
|
1470
1742
|
}
|
|
1471
1743
|
module2.exports = function(fromModel) {
|
|
@@ -2492,8 +2764,8 @@ async function handleCollectionPublish(manifestPath = "./collection.json") {
|
|
|
2492
2764
|
throw new CLIError("\n\u274C Authentication required. Run `prpm login` first.", 1);
|
|
2493
2765
|
}
|
|
2494
2766
|
console.log("\u{1F4E6} Publishing collection...\n");
|
|
2495
|
-
const
|
|
2496
|
-
const manifestContent = await
|
|
2767
|
+
const fs12 = await import("fs/promises");
|
|
2768
|
+
const manifestContent = await fs12.readFile(manifestPath, "utf-8");
|
|
2497
2769
|
const manifest = JSON.parse(manifestContent);
|
|
2498
2770
|
const required = ["id", "name", "description", "packages"];
|
|
2499
2771
|
const missing = required.filter((field) => !manifest[field]);
|
|
@@ -8945,6 +9217,16 @@ var init_from_gemini = __esm({
|
|
|
8945
9217
|
}
|
|
8946
9218
|
});
|
|
8947
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
|
+
|
|
8948
9230
|
// ../converters/dist/from-ruler.js
|
|
8949
9231
|
function fromRuler(markdown, options = {}) {
|
|
8950
9232
|
const warnings = [];
|
|
@@ -9075,6 +9357,16 @@ var init_from_ruler = __esm({
|
|
|
9075
9357
|
}
|
|
9076
9358
|
});
|
|
9077
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
|
+
|
|
9078
9370
|
// ../converters/dist/validation.js
|
|
9079
9371
|
function loadSchema(format, subtype) {
|
|
9080
9372
|
const cacheKey = subtype ? `${format}:${subtype}` : format;
|
|
@@ -9104,21 +9396,23 @@ function loadSchema(format, subtype) {
|
|
|
9104
9396
|
"kiro": "kiro-steering.schema.json",
|
|
9105
9397
|
"agents-md": "agents-md.schema.json",
|
|
9106
9398
|
"gemini": "gemini.schema.json",
|
|
9399
|
+
"opencode": "opencode.schema.json",
|
|
9107
9400
|
"ruler": "ruler.schema.json",
|
|
9401
|
+
"droid": "droid.schema.json",
|
|
9108
9402
|
"canonical": "canonical.schema.json"
|
|
9109
9403
|
};
|
|
9110
9404
|
schemaFilename = schemaMap[format] || `${format}.schema.json`;
|
|
9111
9405
|
}
|
|
9112
9406
|
const schemaDirectories = [
|
|
9113
|
-
(0,
|
|
9114
|
-
(0,
|
|
9407
|
+
(0, import_path8.join)(currentDirname, "..", "schemas"),
|
|
9408
|
+
(0, import_path8.join)(currentDirname, "schemas")
|
|
9115
9409
|
];
|
|
9116
9410
|
let schemaContent = null;
|
|
9117
9411
|
let schemaPath = null;
|
|
9118
9412
|
for (const dir of schemaDirectories) {
|
|
9119
|
-
const candidate = (0,
|
|
9413
|
+
const candidate = (0, import_path8.join)(dir, schemaFilename);
|
|
9120
9414
|
try {
|
|
9121
|
-
schemaContent = (0,
|
|
9415
|
+
schemaContent = (0, import_fs9.readFileSync)(candidate, "utf-8");
|
|
9122
9416
|
schemaPath = candidate;
|
|
9123
9417
|
break;
|
|
9124
9418
|
} catch (error) {
|
|
@@ -9144,11 +9438,11 @@ function validateFormat(format, data, subtype) {
|
|
|
9144
9438
|
const warnings = [];
|
|
9145
9439
|
if (!valid && validate.errors) {
|
|
9146
9440
|
for (const error of validate.errors) {
|
|
9147
|
-
const
|
|
9441
|
+
const path8 = error.instancePath || "/" + error.params.missingProperty || "/";
|
|
9148
9442
|
const message = error.message || "Validation error";
|
|
9149
9443
|
const validationError = {
|
|
9150
|
-
path:
|
|
9151
|
-
message: `${
|
|
9444
|
+
path: path8,
|
|
9445
|
+
message: `${path8}: ${message}`,
|
|
9152
9446
|
value: error.data
|
|
9153
9447
|
};
|
|
9154
9448
|
if (error.keyword === "deprecated") {
|
|
@@ -9217,23 +9511,28 @@ function validateMarkdown(format, markdown, subtype) {
|
|
|
9217
9511
|
}
|
|
9218
9512
|
return validateConversion(format, frontmatter, content, subtype);
|
|
9219
9513
|
}
|
|
9220
|
-
var import_ajv, import_ajv_formats,
|
|
9514
|
+
var import_ajv, import_ajv_formats, import_fs9, import_path8, import_url, currentDirname, ajv, schemaCache;
|
|
9221
9515
|
var init_validation = __esm({
|
|
9222
9516
|
"../converters/dist/validation.js"() {
|
|
9223
9517
|
"use strict";
|
|
9224
9518
|
init_cjs_shims();
|
|
9225
9519
|
import_ajv = __toESM(require("ajv"), 1);
|
|
9226
9520
|
import_ajv_formats = __toESM(require("ajv-formats"), 1);
|
|
9227
|
-
|
|
9228
|
-
|
|
9521
|
+
import_fs9 = require("fs");
|
|
9522
|
+
import_path8 = require("path");
|
|
9229
9523
|
import_url = require("url");
|
|
9230
9524
|
init_js_yaml();
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
|
|
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
|
+
})();
|
|
9237
9536
|
ajv = new import_ajv.default({
|
|
9238
9537
|
allErrors: true,
|
|
9239
9538
|
verbose: true,
|
|
@@ -10815,6 +11114,15 @@ var init_to_gemini = __esm({
|
|
|
10815
11114
|
}
|
|
10816
11115
|
});
|
|
10817
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
|
+
|
|
10818
11126
|
// ../converters/dist/to-ruler.js
|
|
10819
11127
|
function toRuler(pkg, options = {}) {
|
|
10820
11128
|
var _a, _b;
|
|
@@ -10975,6 +11283,15 @@ var init_to_ruler = __esm({
|
|
|
10975
11283
|
}
|
|
10976
11284
|
});
|
|
10977
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
|
+
|
|
10978
11295
|
// ../converters/dist/index.js
|
|
10979
11296
|
var init_dist = __esm({
|
|
10980
11297
|
"../converters/dist/index.js"() {
|
|
@@ -10990,7 +11307,9 @@ var init_dist = __esm({
|
|
|
10990
11307
|
init_from_windsurf();
|
|
10991
11308
|
init_from_agents_md();
|
|
10992
11309
|
init_from_gemini();
|
|
11310
|
+
init_from_opencode();
|
|
10993
11311
|
init_from_ruler();
|
|
11312
|
+
init_from_droid();
|
|
10994
11313
|
init_to_cursor();
|
|
10995
11314
|
init_to_claude();
|
|
10996
11315
|
init_to_continue();
|
|
@@ -11000,7 +11319,9 @@ var init_dist = __esm({
|
|
|
11000
11319
|
init_to_windsurf();
|
|
11001
11320
|
init_to_agents_md();
|
|
11002
11321
|
init_to_gemini();
|
|
11322
|
+
init_to_opencode();
|
|
11003
11323
|
init_to_ruler();
|
|
11324
|
+
init_to_droid();
|
|
11004
11325
|
init_taxonomy_utils();
|
|
11005
11326
|
init_validation();
|
|
11006
11327
|
}
|
|
@@ -11029,8 +11350,14 @@ function getPackageIcon2(format, subtype) {
|
|
|
11029
11350
|
"copilot": "\u2708\uFE0F",
|
|
11030
11351
|
"kiro": "\u{1F3AF}",
|
|
11031
11352
|
"gemini": "\u2728",
|
|
11353
|
+
"gemini.md": "\u2728",
|
|
11354
|
+
"claude.md": "\u{1F916}",
|
|
11355
|
+
"opencode": "\u26A1",
|
|
11356
|
+
"droid": "\u{1F3ED}",
|
|
11032
11357
|
"mcp": "\u{1F517}",
|
|
11033
11358
|
"agents.md": "\u{1F4DD}",
|
|
11359
|
+
"gemini.md": "\u2728",
|
|
11360
|
+
"claude.md": "\u{1F916}",
|
|
11034
11361
|
"ruler": "\u{1F4CF}",
|
|
11035
11362
|
"generic": "\u{1F4E6}"
|
|
11036
11363
|
};
|
|
@@ -11045,8 +11372,14 @@ function getPackageLabel2(format, subtype) {
|
|
|
11045
11372
|
"copilot": "GitHub Copilot",
|
|
11046
11373
|
"kiro": "Kiro",
|
|
11047
11374
|
"gemini": "Gemini",
|
|
11375
|
+
"gemini.md": "Gemini",
|
|
11376
|
+
"claude.md": "Claude",
|
|
11377
|
+
"opencode": "OpenCode",
|
|
11378
|
+
"droid": "Factory Droid",
|
|
11048
11379
|
"mcp": "MCP",
|
|
11049
11380
|
"agents.md": "Agents.md",
|
|
11381
|
+
"gemini.md": "Gemini.md",
|
|
11382
|
+
"claude.md": "Claude.md",
|
|
11050
11383
|
"ruler": "Ruler",
|
|
11051
11384
|
"generic": ""
|
|
11052
11385
|
};
|
|
@@ -11334,6 +11667,7 @@ async function handleInstall(packageSpec, options) {
|
|
|
11334
11667
|
locationOverride = void 0;
|
|
11335
11668
|
}
|
|
11336
11669
|
let destPath;
|
|
11670
|
+
let destDir = "";
|
|
11337
11671
|
let fileCount = 0;
|
|
11338
11672
|
let hookMetadata = void 0;
|
|
11339
11673
|
if (format === "claude-md") {
|
|
@@ -11345,10 +11679,10 @@ async function handleInstall(packageSpec, options) {
|
|
|
11345
11679
|
await saveFile(destPath, mainFile);
|
|
11346
11680
|
fileCount = 1;
|
|
11347
11681
|
} else if (extractedFiles.length === 1) {
|
|
11348
|
-
|
|
11682
|
+
destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
|
|
11349
11683
|
if (locationOverride && effectiveFormat === "cursor") {
|
|
11350
11684
|
const relativeDestDir = destDir.startsWith("./") ? destDir.slice(2) : destDir;
|
|
11351
|
-
destDir =
|
|
11685
|
+
destDir = import_path9.default.join(locationOverride, relativeDestDir);
|
|
11352
11686
|
console.log(` \u{1F4C1} Installing Cursor package to custom location: ${destDir}`);
|
|
11353
11687
|
}
|
|
11354
11688
|
let mainFile = extractedFiles[0].content;
|
|
@@ -11358,26 +11692,35 @@ async function handleInstall(packageSpec, options) {
|
|
|
11358
11692
|
destPath = `${destDir}/SKILL.md`;
|
|
11359
11693
|
} else if (effectiveFormat === "claude" && effectiveSubtype === "hook") {
|
|
11360
11694
|
destPath = `${destDir}/settings.json`;
|
|
11361
|
-
} else if (effectiveFormat === "agents.md") {
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11376
|
-
|
|
11377
|
-
if (
|
|
11378
|
-
console.log(` \
|
|
11379
|
-
|
|
11380
|
-
|
|
11695
|
+
} else if (effectiveFormat === "agents.md" || effectiveFormat === "gemini.md" || effectiveFormat === "claude.md") {
|
|
11696
|
+
if (effectiveSubtype === "skill") {
|
|
11697
|
+
destPath = `${destDir}/SKILL.md`;
|
|
11698
|
+
console.log(` \u{1F4E6} Installing skill to ${destDir}/ for progressive disclosure`);
|
|
11699
|
+
} else if (effectiveSubtype === "agent") {
|
|
11700
|
+
destPath = `${destDir}/AGENT.md`;
|
|
11701
|
+
console.log(` \u{1F916} Installing agent to ${destDir}/ for progressive disclosure`);
|
|
11702
|
+
} else {
|
|
11703
|
+
const manifestFilename = getManifestFilename(effectiveFormat);
|
|
11704
|
+
let targetPath = manifestFilename;
|
|
11705
|
+
if (locationOverride) {
|
|
11706
|
+
targetPath = import_path9.default.join(locationOverride, `${manifestFilename.replace(".md", ".override.md")}`);
|
|
11707
|
+
console.log(` \u{1F4C1} Installing to custom location: ${targetPath}`);
|
|
11708
|
+
}
|
|
11709
|
+
destPath = targetPath;
|
|
11710
|
+
if (await fileExists(destPath)) {
|
|
11711
|
+
if (options.force) {
|
|
11712
|
+
console.log(` \u26A0\uFE0F ${destPath} already exists - overwriting (forced).`);
|
|
11713
|
+
} else {
|
|
11714
|
+
console.log(` \u26A0\uFE0F ${destPath} already exists.`);
|
|
11715
|
+
const overwrite = await promptYesNo(
|
|
11716
|
+
` Overwrite existing ${destPath}? (y/N): `,
|
|
11717
|
+
` \u26A0\uFE0F Non-interactive terminal detected. Remove or rename ${destPath} to continue.`
|
|
11718
|
+
);
|
|
11719
|
+
if (!overwrite) {
|
|
11720
|
+
console.log(` \u{1F6AB} Skipping install to avoid overwriting ${destPath}`);
|
|
11721
|
+
success = true;
|
|
11722
|
+
return;
|
|
11723
|
+
}
|
|
11381
11724
|
}
|
|
11382
11725
|
}
|
|
11383
11726
|
}
|
|
@@ -11458,10 +11801,10 @@ async function handleInstall(packageSpec, options) {
|
|
|
11458
11801
|
await saveFile(destPath, mainFile);
|
|
11459
11802
|
fileCount = 1;
|
|
11460
11803
|
} else {
|
|
11461
|
-
|
|
11804
|
+
destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
|
|
11462
11805
|
if (locationOverride && effectiveFormat === "cursor") {
|
|
11463
11806
|
const relativeDestDir = destDir.startsWith("./") ? destDir.slice(2) : destDir;
|
|
11464
|
-
destDir =
|
|
11807
|
+
destDir = import_path9.default.join(locationOverride, relativeDestDir);
|
|
11465
11808
|
console.log(` \u{1F4C1} Installing Cursor package to custom location: ${destDir}`);
|
|
11466
11809
|
}
|
|
11467
11810
|
const packageName = stripAuthorNamespace2(packageId);
|
|
@@ -11544,6 +11887,35 @@ ${afterFrontmatter}`;
|
|
|
11544
11887
|
}
|
|
11545
11888
|
}
|
|
11546
11889
|
}
|
|
11890
|
+
let progressiveDisclosureMetadata;
|
|
11891
|
+
if ((effectiveFormat === "agents.md" || effectiveFormat === "gemini.md" || effectiveFormat === "claude.md") && (effectiveSubtype === "skill" || effectiveSubtype === "agent") && !options.noAppend) {
|
|
11892
|
+
if (!destDir) {
|
|
11893
|
+
throw new Error("Internal error: destDir not set for progressive disclosure installation");
|
|
11894
|
+
}
|
|
11895
|
+
const manifestPath = options.manifestFile || getManifestFilename(effectiveFormat);
|
|
11896
|
+
const resourceName = stripAuthorNamespace2(packageId);
|
|
11897
|
+
const resourceType = effectiveSubtype;
|
|
11898
|
+
const mainFile = resourceType === "agent" ? "AGENT.md" : "SKILL.md";
|
|
11899
|
+
const manifestEntry = {
|
|
11900
|
+
name: resourceName,
|
|
11901
|
+
description: pkg.description || `${pkg.name} ${resourceType}`,
|
|
11902
|
+
skillPath: destDir,
|
|
11903
|
+
mainFile,
|
|
11904
|
+
resourceType
|
|
11905
|
+
};
|
|
11906
|
+
await addSkillToManifest(manifestEntry, manifestPath);
|
|
11907
|
+
console.log(` \u2713 Added ${resourceType} to ${manifestPath} manifest`);
|
|
11908
|
+
progressiveDisclosureMetadata = {
|
|
11909
|
+
mode: "progressive",
|
|
11910
|
+
resourceDir: destDir,
|
|
11911
|
+
manifestPath,
|
|
11912
|
+
resourceName,
|
|
11913
|
+
resourceType,
|
|
11914
|
+
// Legacy fields for backward compatibility
|
|
11915
|
+
skillsDir: destDir,
|
|
11916
|
+
skillName: resourceName
|
|
11917
|
+
};
|
|
11918
|
+
}
|
|
11547
11919
|
const updatedLockfile = lockfile || createLockfile();
|
|
11548
11920
|
addToLockfile(updatedLockfile, packageId, {
|
|
11549
11921
|
version: actualVersion || version,
|
|
@@ -11556,8 +11928,9 @@ ${afterFrontmatter}`;
|
|
|
11556
11928
|
sourceSubtype: pkg.subtype,
|
|
11557
11929
|
installedPath: destPath,
|
|
11558
11930
|
fromCollection: options.fromCollection,
|
|
11559
|
-
hookMetadata
|
|
11931
|
+
hookMetadata,
|
|
11560
11932
|
// Track hook installation metadata for uninstall
|
|
11933
|
+
progressiveDisclosure: progressiveDisclosureMetadata
|
|
11561
11934
|
});
|
|
11562
11935
|
setPackageIntegrity(updatedLockfile, packageId, tarball);
|
|
11563
11936
|
await writeLockfile(updatedLockfile);
|
|
@@ -11571,6 +11944,14 @@ ${afterFrontmatter}`;
|
|
|
11571
11944
|
\u2705 Successfully installed ${packageId}`);
|
|
11572
11945
|
console.log(` \u{1F4C1} Saved to: ${destPath}`);
|
|
11573
11946
|
console.log(` \u{1F512} Lock file updated`);
|
|
11947
|
+
if (progressiveDisclosureMetadata && !options.noAppend) {
|
|
11948
|
+
const manifestFile = progressiveDisclosureMetadata.manifestPath;
|
|
11949
|
+
console.log(`
|
|
11950
|
+
\u{1F393} Skill installed with progressive disclosure`);
|
|
11951
|
+
console.log(` \u{1F4DD} Skill added to ${manifestFile} manifest`);
|
|
11952
|
+
console.log(` \u{1F4A1} The skill is available but not loaded into context by default`);
|
|
11953
|
+
console.log(` \u26A1 To activate: Add skill usage to your code or let the agent discover it`);
|
|
11954
|
+
}
|
|
11574
11955
|
console.log(`
|
|
11575
11956
|
\u{1F4A1} This package has been downloaded ${newDownloadCount.toLocaleString()} times`);
|
|
11576
11957
|
success = true;
|
|
@@ -11612,7 +11993,7 @@ async function extractTarball(tarball, packageId) {
|
|
|
11612
11993
|
} catch (error) {
|
|
11613
11994
|
throw new CLIError(`Package decompression failed: ${error.message}`);
|
|
11614
11995
|
}
|
|
11615
|
-
const tmpDir = await import_promises2.default.mkdtemp(
|
|
11996
|
+
const tmpDir = await import_promises2.default.mkdtemp(import_path9.default.join(import_os3.default.tmpdir(), "prpm-"));
|
|
11616
11997
|
const cleanup = async () => {
|
|
11617
11998
|
try {
|
|
11618
11999
|
await import_promises2.default.rm(tmpDir, { recursive: true, force: true });
|
|
@@ -11652,15 +12033,15 @@ async function extractTarball(tarball, packageId) {
|
|
|
11652
12033
|
await cleanup();
|
|
11653
12034
|
}
|
|
11654
12035
|
}
|
|
11655
|
-
async function collectExtractedFiles(rootDir, excludedNames,
|
|
12036
|
+
async function collectExtractedFiles(rootDir, excludedNames, fs12) {
|
|
11656
12037
|
const files = [];
|
|
11657
12038
|
const dirs = [rootDir];
|
|
11658
12039
|
while (dirs.length > 0) {
|
|
11659
12040
|
const currentDir = dirs.pop();
|
|
11660
12041
|
if (!currentDir) continue;
|
|
11661
|
-
const entries = await
|
|
12042
|
+
const entries = await fs12.readdir(currentDir, { withFileTypes: true });
|
|
11662
12043
|
for (const entry of entries) {
|
|
11663
|
-
const fullPath =
|
|
12044
|
+
const fullPath = import_path9.default.join(currentDir, entry.name);
|
|
11664
12045
|
if (entry.isDirectory()) {
|
|
11665
12046
|
dirs.push(fullPath);
|
|
11666
12047
|
continue;
|
|
@@ -11671,8 +12052,8 @@ async function collectExtractedFiles(rootDir, excludedNames, fs11) {
|
|
|
11671
12052
|
if (excludedNames.has(entry.name)) {
|
|
11672
12053
|
continue;
|
|
11673
12054
|
}
|
|
11674
|
-
const content = await
|
|
11675
|
-
const relativePath =
|
|
12055
|
+
const content = await fs12.readFile(fullPath, "utf-8");
|
|
12056
|
+
const relativePath = import_path9.default.relative(rootDir, fullPath).split(import_path9.default.sep).join("/");
|
|
11676
12057
|
files.push({
|
|
11677
12058
|
name: relativePath,
|
|
11678
12059
|
content
|
|
@@ -11682,7 +12063,7 @@ async function collectExtractedFiles(rootDir, excludedNames, fs11) {
|
|
|
11682
12063
|
return files;
|
|
11683
12064
|
}
|
|
11684
12065
|
async function installFromLockfile(options) {
|
|
11685
|
-
var _a;
|
|
12066
|
+
var _a, _b;
|
|
11686
12067
|
try {
|
|
11687
12068
|
const lockfile = await readLockfile();
|
|
11688
12069
|
if (!lockfile) {
|
|
@@ -11704,13 +12085,14 @@ async function installFromLockfile(options) {
|
|
|
11704
12085
|
console.log(` Installing ${packageId}...`);
|
|
11705
12086
|
let locationOverride = options.location;
|
|
11706
12087
|
if (!locationOverride && lockEntry.format === "agents.md" && lockEntry.installedPath) {
|
|
11707
|
-
const baseName =
|
|
12088
|
+
const baseName = import_path9.default.basename(lockEntry.installedPath);
|
|
11708
12089
|
if (baseName === "AGENTS.override.md") {
|
|
11709
|
-
locationOverride =
|
|
12090
|
+
locationOverride = import_path9.default.dirname(lockEntry.installedPath);
|
|
11710
12091
|
} else if (baseName !== "AGENTS.md") {
|
|
11711
|
-
locationOverride =
|
|
12092
|
+
locationOverride = import_path9.default.dirname(lockEntry.installedPath);
|
|
11712
12093
|
}
|
|
11713
12094
|
}
|
|
12095
|
+
const manifestFile = (_a = lockEntry.progressiveDisclosure) == null ? void 0 : _a.manifestPath;
|
|
11714
12096
|
await handleInstall(packageSpec, {
|
|
11715
12097
|
version: lockEntry.version,
|
|
11716
12098
|
as: options.as || lockEntry.format,
|
|
@@ -11718,7 +12100,8 @@ async function installFromLockfile(options) {
|
|
|
11718
12100
|
frozenLockfile: options.frozenLockfile,
|
|
11719
12101
|
force: true,
|
|
11720
12102
|
// Force reinstall when installing from lockfile
|
|
11721
|
-
location: locationOverride
|
|
12103
|
+
location: locationOverride,
|
|
12104
|
+
manifestFile
|
|
11722
12105
|
});
|
|
11723
12106
|
successCount++;
|
|
11724
12107
|
} catch (error) {
|
|
@@ -11727,7 +12110,7 @@ async function installFromLockfile(options) {
|
|
|
11727
12110
|
} else {
|
|
11728
12111
|
failCount++;
|
|
11729
12112
|
console.error(` \u274C Failed to install ${packageId}:`);
|
|
11730
|
-
console.error(` Type: ${(
|
|
12113
|
+
console.error(` Type: ${(_b = error == null ? void 0 : error.constructor) == null ? void 0 : _b.name}`);
|
|
11731
12114
|
console.error(` Message: ${error instanceof Error ? error.message : String(error)}`);
|
|
11732
12115
|
if (error instanceof CLIError) {
|
|
11733
12116
|
console.error(` ExitCode: ${error.exitCode}`);
|
|
@@ -11749,9 +12132,9 @@ async function installFromLockfile(options) {
|
|
|
11749
12132
|
}
|
|
11750
12133
|
function createInstallCommand() {
|
|
11751
12134
|
const command = new import_commander11.Command("install");
|
|
11752
|
-
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) => {
|
|
12135
|
+
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) => {
|
|
11753
12136
|
const convertTo = options.format || options.as;
|
|
11754
|
-
if (convertTo && !["cursor", "claude", "continue", "windsurf", "copilot", "kiro", "agents.md", "canonical", "gemini"].includes(convertTo)) {
|
|
12137
|
+
if (convertTo && !["cursor", "claude", "continue", "windsurf", "copilot", "kiro", "agents.md", "gemini.md", "claude.md", "canonical", "gemini"].includes(convertTo)) {
|
|
11755
12138
|
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);
|
|
11756
12139
|
}
|
|
11757
12140
|
if (!packageSpec) {
|
|
@@ -11768,12 +12151,14 @@ function createInstallCommand() {
|
|
|
11768
12151
|
as: convertTo,
|
|
11769
12152
|
subtype: options.subtype,
|
|
11770
12153
|
frozenLockfile: options.frozenLockfile,
|
|
11771
|
-
location: options.location
|
|
12154
|
+
location: options.location,
|
|
12155
|
+
noAppend: options.noAppend,
|
|
12156
|
+
manifestFile: options.manifestFile
|
|
11772
12157
|
});
|
|
11773
12158
|
});
|
|
11774
12159
|
return command;
|
|
11775
12160
|
}
|
|
11776
|
-
var import_commander11, import_chalk, import_registry_client5, import_stream, import_promises, tar,
|
|
12161
|
+
var import_commander11, import_chalk, import_registry_client5, import_stream, import_promises, tar, import_path9, import_zlib, import_promises2, import_os3;
|
|
11777
12162
|
var init_install = __esm({
|
|
11778
12163
|
"src/commands/install.ts"() {
|
|
11779
12164
|
"use strict";
|
|
@@ -11789,7 +12174,7 @@ var init_install = __esm({
|
|
|
11789
12174
|
tar = __toESM(require("tar"));
|
|
11790
12175
|
init_errors();
|
|
11791
12176
|
init_prompts();
|
|
11792
|
-
|
|
12177
|
+
import_path9 = __toESM(require("path"));
|
|
11793
12178
|
import_zlib = __toESM(require("zlib"));
|
|
11794
12179
|
import_promises2 = __toESM(require("fs/promises"));
|
|
11795
12180
|
import_os3 = __toESM(require("os"));
|
|
@@ -11797,6 +12182,7 @@ var init_install = __esm({
|
|
|
11797
12182
|
init_lockfile();
|
|
11798
12183
|
init_cursor_config();
|
|
11799
12184
|
init_claude_config();
|
|
12185
|
+
init_agents_md_progressive();
|
|
11800
12186
|
init_dist();
|
|
11801
12187
|
}
|
|
11802
12188
|
});
|
|
@@ -11804,8 +12190,8 @@ var init_install = __esm({
|
|
|
11804
12190
|
// src/index.ts
|
|
11805
12191
|
init_cjs_shims();
|
|
11806
12192
|
var import_commander29 = require("commander");
|
|
11807
|
-
var
|
|
11808
|
-
var
|
|
12193
|
+
var import_fs15 = require("fs");
|
|
12194
|
+
var import_path18 = require("path");
|
|
11809
12195
|
|
|
11810
12196
|
// src/commands/list.ts
|
|
11811
12197
|
init_cjs_shims();
|
|
@@ -11964,8 +12350,9 @@ init_cjs_shims();
|
|
|
11964
12350
|
var import_commander2 = require("commander");
|
|
11965
12351
|
init_lockfile();
|
|
11966
12352
|
init_filesystem();
|
|
11967
|
-
var
|
|
12353
|
+
var import_fs7 = require("fs");
|
|
11968
12354
|
init_errors();
|
|
12355
|
+
init_agents_md_progressive();
|
|
11969
12356
|
async function handleUninstall(name) {
|
|
11970
12357
|
try {
|
|
11971
12358
|
console.log(`\u{1F5D1}\uFE0F Uninstalling package: ${name}`);
|
|
@@ -11973,10 +12360,22 @@ async function handleUninstall(name) {
|
|
|
11973
12360
|
if (!pkg) {
|
|
11974
12361
|
throw new CLIError(`\u274C Package "${name}" not found`, 1);
|
|
11975
12362
|
}
|
|
12363
|
+
if (pkg.progressiveDisclosure) {
|
|
12364
|
+
const { manifestPath, resourceName, skillName } = pkg.progressiveDisclosure;
|
|
12365
|
+
const name2 = resourceName || skillName;
|
|
12366
|
+
if (name2) {
|
|
12367
|
+
try {
|
|
12368
|
+
await removeSkillFromManifest(name2, manifestPath);
|
|
12369
|
+
console.log(` \u{1F4DD} Removed from ${manifestPath} manifest`);
|
|
12370
|
+
} catch (error) {
|
|
12371
|
+
console.warn(` \u26A0\uFE0F Failed to remove from manifest: ${error}`);
|
|
12372
|
+
}
|
|
12373
|
+
}
|
|
12374
|
+
}
|
|
11976
12375
|
if (pkg.format === "claude" && pkg.subtype === "hook" && pkg.hookMetadata) {
|
|
11977
12376
|
const settingsPath = pkg.installedPath || ".claude/settings.json";
|
|
11978
12377
|
try {
|
|
11979
|
-
const settingsContent = await
|
|
12378
|
+
const settingsContent = await import_fs7.promises.readFile(settingsPath, "utf-8");
|
|
11980
12379
|
const settings = JSON.parse(settingsContent);
|
|
11981
12380
|
if (settings.hooks) {
|
|
11982
12381
|
let removedCount = 0;
|
|
@@ -11993,7 +12392,7 @@ async function handleUninstall(name) {
|
|
|
11993
12392
|
}
|
|
11994
12393
|
}
|
|
11995
12394
|
}
|
|
11996
|
-
await
|
|
12395
|
+
await import_fs7.promises.writeFile(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
11997
12396
|
console.log(` \u{1FA9D} Removed ${removedCount} hook(s) from ${settingsPath}`);
|
|
11998
12397
|
}
|
|
11999
12398
|
} catch (error) {
|
|
@@ -12018,12 +12417,12 @@ async function handleUninstall(name) {
|
|
|
12018
12417
|
throw new CLIError(`Cannot uninstall ${name}: installation path unknown`, 1);
|
|
12019
12418
|
}
|
|
12020
12419
|
try {
|
|
12021
|
-
const stats = await
|
|
12420
|
+
const stats = await import_fs7.promises.stat(targetPath);
|
|
12022
12421
|
if (stats.isDirectory()) {
|
|
12023
|
-
await
|
|
12422
|
+
await import_fs7.promises.rm(targetPath, { recursive: true, force: true });
|
|
12024
12423
|
console.log(` \u{1F5D1}\uFE0F Deleted directory: ${targetPath}`);
|
|
12025
12424
|
} else if (stats.isFile()) {
|
|
12026
|
-
await
|
|
12425
|
+
await import_fs7.promises.unlink(targetPath);
|
|
12027
12426
|
console.log(` \u{1F5D1}\uFE0F Deleted file: ${targetPath}`);
|
|
12028
12427
|
}
|
|
12029
12428
|
} catch (error) {
|
|
@@ -12051,17 +12450,17 @@ function createUninstallCommand() {
|
|
|
12051
12450
|
// src/commands/index.ts
|
|
12052
12451
|
init_cjs_shims();
|
|
12053
12452
|
var import_commander3 = require("commander");
|
|
12054
|
-
var
|
|
12055
|
-
var
|
|
12453
|
+
var import_fs8 = require("fs");
|
|
12454
|
+
var import_path7 = __toESM(require("path"));
|
|
12056
12455
|
init_lockfile();
|
|
12057
12456
|
init_filesystem();
|
|
12058
12457
|
init_errors();
|
|
12059
12458
|
async function scanDirectory(dirPath, format, subtype) {
|
|
12060
12459
|
try {
|
|
12061
|
-
const files = await
|
|
12460
|
+
const files = await import_fs8.promises.readdir(dirPath, { withFileTypes: true });
|
|
12062
12461
|
const results = [];
|
|
12063
12462
|
for (const file of files) {
|
|
12064
|
-
const fullPath =
|
|
12463
|
+
const fullPath = import_path7.default.join(dirPath, file.name);
|
|
12065
12464
|
if (file.isFile()) {
|
|
12066
12465
|
const id = generateId(file.name);
|
|
12067
12466
|
results.push({
|
|
@@ -12074,11 +12473,11 @@ async function scanDirectory(dirPath, format, subtype) {
|
|
|
12074
12473
|
const isCursorAgent = format === "cursor" && subtype === "agent";
|
|
12075
12474
|
if (isClaudeType || isCursorAgent) {
|
|
12076
12475
|
try {
|
|
12077
|
-
const subFiles = await
|
|
12476
|
+
const subFiles = await import_fs8.promises.readdir(fullPath, { withFileTypes: true });
|
|
12078
12477
|
for (const subFile of subFiles) {
|
|
12079
12478
|
const isValidFile = subFile.isFile() && (subFile.name === "SKILL.md" || subFile.name === "AGENT.md" || subFile.name === "skill.md" || subFile.name === "agent.md");
|
|
12080
12479
|
if (isValidFile) {
|
|
12081
|
-
const subFilePath =
|
|
12480
|
+
const subFilePath = import_path7.default.join(fullPath, subFile.name);
|
|
12082
12481
|
const id = file.name;
|
|
12083
12482
|
results.push({
|
|
12084
12483
|
filePath: subFilePath,
|
|
@@ -12140,7 +12539,7 @@ async function handleIndex(options = {}) {
|
|
|
12140
12539
|
id: file.id,
|
|
12141
12540
|
version: "0.0.0",
|
|
12142
12541
|
// Local files don't have versions
|
|
12143
|
-
tarballUrl: `file://${
|
|
12542
|
+
tarballUrl: `file://${import_path7.default.resolve(file.filePath)}`,
|
|
12144
12543
|
format: dir.format,
|
|
12145
12544
|
subtype: dir.subtype
|
|
12146
12545
|
});
|
|
@@ -12406,8 +12805,14 @@ function getPackageIcon(format, subtype) {
|
|
|
12406
12805
|
"copilot": "\u2708\uFE0F",
|
|
12407
12806
|
"kiro": "\u{1F3AF}",
|
|
12408
12807
|
"gemini": "\u2728",
|
|
12808
|
+
"gemini.md": "\u2728",
|
|
12809
|
+
"claude.md": "\u{1F916}",
|
|
12810
|
+
"opencode": "\u26A1",
|
|
12811
|
+
"droid": "\u{1F3ED}",
|
|
12409
12812
|
"mcp": "\u{1F517}",
|
|
12410
12813
|
"agents.md": "\u{1F4DD}",
|
|
12814
|
+
"gemini.md": "\u2728",
|
|
12815
|
+
"claude.md": "\u{1F916}",
|
|
12411
12816
|
"ruler": "\u{1F4CF}",
|
|
12412
12817
|
"generic": "\u{1F4E6}"
|
|
12413
12818
|
};
|
|
@@ -12422,8 +12827,14 @@ function getPackageLabel(format, subtype) {
|
|
|
12422
12827
|
"copilot": "GitHub Copilot",
|
|
12423
12828
|
"kiro": "Kiro",
|
|
12424
12829
|
"gemini": "Gemini",
|
|
12830
|
+
"gemini.md": "Gemini",
|
|
12831
|
+
"claude.md": "Claude",
|
|
12832
|
+
"opencode": "OpenCode",
|
|
12833
|
+
"droid": "Factory Droid",
|
|
12425
12834
|
"mcp": "MCP",
|
|
12426
12835
|
"agents.md": "Agents.md",
|
|
12836
|
+
"gemini.md": "Gemini.md",
|
|
12837
|
+
"claude.md": "Claude.md",
|
|
12427
12838
|
"ruler": "Ruler",
|
|
12428
12839
|
"generic": ""
|
|
12429
12840
|
};
|
|
@@ -12949,7 +13360,7 @@ init_install();
|
|
|
12949
13360
|
init_cjs_shims();
|
|
12950
13361
|
var import_commander12 = require("commander");
|
|
12951
13362
|
var import_promises6 = require("fs/promises");
|
|
12952
|
-
var
|
|
13363
|
+
var import_path13 = require("path");
|
|
12953
13364
|
var tar2 = __toESM(require("tar"));
|
|
12954
13365
|
var import_os4 = require("os");
|
|
12955
13366
|
var import_crypto2 = require("crypto");
|
|
@@ -13122,19 +13533,19 @@ function validateMarketplaceJson(data) {
|
|
|
13122
13533
|
init_cjs_shims();
|
|
13123
13534
|
var import_ajv2 = __toESM(require("ajv"));
|
|
13124
13535
|
var import_ajv_formats2 = __toESM(require("ajv-formats"));
|
|
13125
|
-
var
|
|
13126
|
-
var
|
|
13536
|
+
var import_fs10 = require("fs");
|
|
13537
|
+
var import_path10 = require("path");
|
|
13127
13538
|
var schema2;
|
|
13128
13539
|
var schemaCandidates = [
|
|
13129
13540
|
// Source file layout (src/core → ../../schemas)
|
|
13130
|
-
(0,
|
|
13541
|
+
(0, import_path10.join)(__dirname, "../../schemas/prpm-manifest.schema.json"),
|
|
13131
13542
|
// Bundled layout (dist/index.js → ../schemas)
|
|
13132
|
-
(0,
|
|
13543
|
+
(0, import_path10.join)(__dirname, "../schemas/prpm-manifest.schema.json")
|
|
13133
13544
|
];
|
|
13134
13545
|
for (const candidate of schemaCandidates) {
|
|
13135
13546
|
try {
|
|
13136
|
-
if ((0,
|
|
13137
|
-
schema2 = JSON.parse((0,
|
|
13547
|
+
if ((0, import_fs10.existsSync)(candidate)) {
|
|
13548
|
+
schema2 = JSON.parse((0, import_fs10.readFileSync)(candidate, "utf-8"));
|
|
13138
13549
|
break;
|
|
13139
13550
|
}
|
|
13140
13551
|
} catch {
|
|
@@ -13156,27 +13567,27 @@ function validateManifestSchema(manifest) {
|
|
|
13156
13567
|
const valid = validate(manifest);
|
|
13157
13568
|
if (!valid && validate.errors) {
|
|
13158
13569
|
const errors = validate.errors.map((err) => {
|
|
13159
|
-
const
|
|
13570
|
+
const path8 = err.instancePath || "manifest";
|
|
13160
13571
|
const message = err.message || "validation failed";
|
|
13161
13572
|
if (err.keyword === "required") {
|
|
13162
13573
|
const missingProp = err.params.missingProperty;
|
|
13163
13574
|
return `Missing required field: ${missingProp}`;
|
|
13164
13575
|
}
|
|
13165
13576
|
if (err.keyword === "pattern") {
|
|
13166
|
-
return `${
|
|
13577
|
+
return `${path8}: ${message}. Value does not match required pattern.`;
|
|
13167
13578
|
}
|
|
13168
13579
|
if (err.keyword === "enum") {
|
|
13169
13580
|
const allowedValues = err.params.allowedValues;
|
|
13170
|
-
return `${
|
|
13581
|
+
return `${path8}: ${message}. Allowed values: ${allowedValues.join(", ")}`;
|
|
13171
13582
|
}
|
|
13172
13583
|
if (err.keyword === "minLength" || err.keyword === "maxLength") {
|
|
13173
13584
|
const limit = err.params.limit;
|
|
13174
|
-
return `${
|
|
13585
|
+
return `${path8}: ${message} (${err.keyword}: ${limit})`;
|
|
13175
13586
|
}
|
|
13176
13587
|
if (err.keyword === "oneOf") {
|
|
13177
|
-
return `${
|
|
13588
|
+
return `${path8}: must match exactly one schema (check if files array uses either all strings or all objects, not mixed)`;
|
|
13178
13589
|
}
|
|
13179
|
-
return `${
|
|
13590
|
+
return `${path8}: ${message}`;
|
|
13180
13591
|
});
|
|
13181
13592
|
return { valid: false, errors };
|
|
13182
13593
|
}
|
|
@@ -13189,8 +13600,8 @@ function getManifestSchema() {
|
|
|
13189
13600
|
// src/utils/license-extractor.ts
|
|
13190
13601
|
init_cjs_shims();
|
|
13191
13602
|
var import_promises3 = require("fs/promises");
|
|
13192
|
-
var
|
|
13193
|
-
var
|
|
13603
|
+
var import_path11 = require("path");
|
|
13604
|
+
var import_fs11 = require("fs");
|
|
13194
13605
|
var LICENSE_FILE_PATTERNS = [
|
|
13195
13606
|
"LICENSE",
|
|
13196
13607
|
"LICENSE.md",
|
|
@@ -13239,9 +13650,9 @@ function generateLicenseUrl(repositoryUrl, fileName) {
|
|
|
13239
13650
|
async function extractLicenseInfo(repositoryUrl) {
|
|
13240
13651
|
const cwd = process.cwd();
|
|
13241
13652
|
for (const fileName of LICENSE_FILE_PATTERNS) {
|
|
13242
|
-
const filePath = (0,
|
|
13653
|
+
const filePath = (0, import_path11.join)(cwd, fileName);
|
|
13243
13654
|
try {
|
|
13244
|
-
await (0, import_promises3.access)(filePath,
|
|
13655
|
+
await (0, import_promises3.access)(filePath, import_fs11.constants.R_OK);
|
|
13245
13656
|
const text = await (0, import_promises3.readFile)(filePath, "utf-8");
|
|
13246
13657
|
const type2 = detectLicenseType(text);
|
|
13247
13658
|
const url = generateLicenseUrl(repositoryUrl, fileName);
|
|
@@ -13275,7 +13686,7 @@ function validateLicenseInfo(licenseInfo, packageName) {
|
|
|
13275
13686
|
// src/utils/snippet-extractor.ts
|
|
13276
13687
|
init_cjs_shims();
|
|
13277
13688
|
var import_promises4 = require("fs/promises");
|
|
13278
|
-
var
|
|
13689
|
+
var import_path12 = require("path");
|
|
13279
13690
|
var MAX_SNIPPET_LENGTH = 2e3;
|
|
13280
13691
|
async function extractSnippet(manifest) {
|
|
13281
13692
|
const cwd = process.cwd();
|
|
@@ -13291,7 +13702,7 @@ async function extractSnippet(manifest) {
|
|
|
13291
13702
|
const firstFile = manifest.files[0];
|
|
13292
13703
|
fileName = typeof firstFile === "string" ? firstFile : firstFile.path;
|
|
13293
13704
|
}
|
|
13294
|
-
const fullPath = (0,
|
|
13705
|
+
const fullPath = (0, import_path12.join)(cwd, fileName);
|
|
13295
13706
|
const stats = await (0, import_promises4.stat)(fullPath);
|
|
13296
13707
|
if (stats.isDirectory()) {
|
|
13297
13708
|
console.warn(`\u26A0\uFE0F Skipping snippet extraction: "${fullPath}" is a directory`);
|
|
@@ -13517,13 +13928,13 @@ async function validatePackageFiles(manifest) {
|
|
|
13517
13928
|
}
|
|
13518
13929
|
}
|
|
13519
13930
|
if (manifest.format === "claude" && manifest.subtype === "skill") {
|
|
13520
|
-
const hasSkillMd = filePaths.some((
|
|
13931
|
+
const hasSkillMd = filePaths.some((path8) => path8.endsWith("/SKILL.md") || path8 === "SKILL.md");
|
|
13521
13932
|
if (!hasSkillMd) {
|
|
13522
13933
|
errors.push("Claude skills must contain a SKILL.md file");
|
|
13523
13934
|
}
|
|
13524
13935
|
}
|
|
13525
13936
|
if (manifest.format === "windsurf") {
|
|
13526
|
-
const hasWindsurfRules = filePaths.some((
|
|
13937
|
+
const hasWindsurfRules = filePaths.some((path8) => path8.includes(".windsurf/rules"));
|
|
13527
13938
|
if (!hasWindsurfRules) {
|
|
13528
13939
|
warnings.push("Windsurf packages typically use .windsurf/rules filename");
|
|
13529
13940
|
}
|
|
@@ -13533,7 +13944,7 @@ async function validatePackageFiles(manifest) {
|
|
|
13533
13944
|
|
|
13534
13945
|
// src/commands/publish.ts
|
|
13535
13946
|
async function findAndLoadManifests() {
|
|
13536
|
-
const prpmJsonPath = (0,
|
|
13947
|
+
const prpmJsonPath = (0, import_path13.join)(process.cwd(), "prpm.json");
|
|
13537
13948
|
let prpmJsonExists = false;
|
|
13538
13949
|
let prpmJsonError = null;
|
|
13539
13950
|
try {
|
|
@@ -13585,7 +13996,7 @@ async function findAndLoadManifests() {
|
|
|
13585
13996
|
throw error;
|
|
13586
13997
|
}
|
|
13587
13998
|
}
|
|
13588
|
-
const marketplaceJsonPath = (0,
|
|
13999
|
+
const marketplaceJsonPath = (0, import_path13.join)(process.cwd(), ".claude", "marketplace.json");
|
|
13589
14000
|
try {
|
|
13590
14001
|
const content = await (0, import_promises6.readFile)(marketplaceJsonPath, "utf-8");
|
|
13591
14002
|
const marketplaceData = JSON.parse(content);
|
|
@@ -13601,7 +14012,7 @@ async function findAndLoadManifests() {
|
|
|
13601
14012
|
return { manifests, collections: [], source: ".claude/marketplace.json" };
|
|
13602
14013
|
} catch (error) {
|
|
13603
14014
|
}
|
|
13604
|
-
const marketplaceJsonPluginPath = (0,
|
|
14015
|
+
const marketplaceJsonPluginPath = (0, import_path13.join)(process.cwd(), ".claude-plugin", "marketplace.json");
|
|
13605
14016
|
try {
|
|
13606
14017
|
const content = await (0, import_promises6.readFile)(marketplaceJsonPluginPath, "utf-8");
|
|
13607
14018
|
const marketplaceData = JSON.parse(content);
|
|
@@ -13645,7 +14056,7 @@ function validateManifest(manifest, contextLabel) {
|
|
|
13645
14056
|
}
|
|
13646
14057
|
if (manifest.format === "claude" && manifest.subtype === "skill") {
|
|
13647
14058
|
const filePaths = normalizeFilePaths2(manifest.files);
|
|
13648
|
-
const hasSkillMd = filePaths.some((
|
|
14059
|
+
const hasSkillMd = filePaths.some((path8) => path8.endsWith("/SKILL.md") || path8 === "SKILL.md");
|
|
13649
14060
|
if (!hasSkillMd) {
|
|
13650
14061
|
throw new Error(
|
|
13651
14062
|
`${prefix}Claude skills must contain a SKILL.md file.
|
|
@@ -13718,8 +14129,8 @@ function predictScopedPackageName(manifestName, username, organization) {
|
|
|
13718
14129
|
return manifestName;
|
|
13719
14130
|
}
|
|
13720
14131
|
async function createTarball(manifest) {
|
|
13721
|
-
const tmpDir = (0,
|
|
13722
|
-
const tarballPath = (0,
|
|
14132
|
+
const tmpDir = (0, import_path13.join)((0, import_os4.tmpdir)(), `prpm-${(0, import_crypto2.randomBytes)(8).toString("hex")}`);
|
|
14133
|
+
const tarballPath = (0, import_path13.join)(tmpDir, "package.tar.gz");
|
|
13723
14134
|
try {
|
|
13724
14135
|
await (0, import_promises6.mkdir)(tmpDir, { recursive: true });
|
|
13725
14136
|
const filePaths = normalizeFilePaths2(manifest.files);
|
|
@@ -13780,7 +14191,7 @@ async function handlePublish(options) {
|
|
|
13780
14191
|
const { manifests, collections, source } = await findAndLoadManifests();
|
|
13781
14192
|
if (source === "prpm.json (multi-package)" || source === "prpm.json") {
|
|
13782
14193
|
try {
|
|
13783
|
-
const prpmJsonPath = (0,
|
|
14194
|
+
const prpmJsonPath = (0, import_path13.join)(process.cwd(), "prpm.json");
|
|
13784
14195
|
const prpmContent = await (0, import_promises6.readFile)(prpmJsonPath, "utf-8");
|
|
13785
14196
|
const prpmManifest = JSON.parse(prpmContent);
|
|
13786
14197
|
if (prpmManifest.scripts) {
|
|
@@ -14774,8 +15185,8 @@ function createSchemaCommand() {
|
|
|
14774
15185
|
init_cjs_shims();
|
|
14775
15186
|
var import_commander19 = require("commander");
|
|
14776
15187
|
var import_promises7 = require("fs/promises");
|
|
14777
|
-
var
|
|
14778
|
-
var
|
|
15188
|
+
var import_path14 = require("path");
|
|
15189
|
+
var import_fs12 = require("fs");
|
|
14779
15190
|
var readline3 = __toESM(require("readline/promises"));
|
|
14780
15191
|
var import_process = require("process");
|
|
14781
15192
|
|
|
@@ -15142,12 +15553,12 @@ function getDefaultAuthor() {
|
|
|
15142
15553
|
async function createExampleFiles(format, files, packageName) {
|
|
15143
15554
|
const templates = EXAMPLE_TEMPLATES[format] || {};
|
|
15144
15555
|
for (const file of files) {
|
|
15145
|
-
const filePath = (0,
|
|
15146
|
-
const dirPath = (0,
|
|
15147
|
-
if (!(0,
|
|
15556
|
+
const filePath = (0, import_path14.join)(process.cwd(), file);
|
|
15557
|
+
const dirPath = (0, import_path14.join)(filePath, "..");
|
|
15558
|
+
if (!(0, import_fs12.existsSync)(dirPath)) {
|
|
15148
15559
|
await (0, import_promises7.mkdir)(dirPath, { recursive: true });
|
|
15149
15560
|
}
|
|
15150
|
-
if ((0,
|
|
15561
|
+
if ((0, import_fs12.existsSync)(filePath)) {
|
|
15151
15562
|
console.log(` Skipping ${file} (already exists)`);
|
|
15152
15563
|
continue;
|
|
15153
15564
|
}
|
|
@@ -15161,8 +15572,8 @@ Add your content here.
|
|
|
15161
15572
|
}
|
|
15162
15573
|
}
|
|
15163
15574
|
async function createReadme(config) {
|
|
15164
|
-
const readmePath = (0,
|
|
15165
|
-
if ((0,
|
|
15575
|
+
const readmePath = (0, import_path14.join)(process.cwd(), "README.md");
|
|
15576
|
+
if ((0, import_fs12.existsSync)(readmePath)) {
|
|
15166
15577
|
console.log(" Skipping README.md (already exists)");
|
|
15167
15578
|
return;
|
|
15168
15579
|
}
|
|
@@ -15196,8 +15607,8 @@ ${config.license}
|
|
|
15196
15607
|
console.log(" Created README.md");
|
|
15197
15608
|
}
|
|
15198
15609
|
async function initPackage(options) {
|
|
15199
|
-
const manifestPath = (0,
|
|
15200
|
-
if ((0,
|
|
15610
|
+
const manifestPath = (0, import_path14.join)(process.cwd(), "prpm.json");
|
|
15611
|
+
if ((0, import_fs12.existsSync)(manifestPath) && !options.force) {
|
|
15201
15612
|
throw new Error(
|
|
15202
15613
|
"prpm.json already exists. Use --force to overwrite, or run this command in a different directory."
|
|
15203
15614
|
);
|
|
@@ -15496,15 +15907,15 @@ function createConfigCommand() {
|
|
|
15496
15907
|
init_cjs_shims();
|
|
15497
15908
|
var import_commander21 = require("commander");
|
|
15498
15909
|
var import_promises8 = require("fs/promises");
|
|
15499
|
-
var
|
|
15910
|
+
var import_path15 = require("path");
|
|
15500
15911
|
init_telemetry();
|
|
15501
15912
|
init_lockfile();
|
|
15502
15913
|
init_errors();
|
|
15503
15914
|
function detectPackageInfo(filePath, content) {
|
|
15504
|
-
const fileName = (0,
|
|
15915
|
+
const fileName = (0, import_path15.basename)(filePath);
|
|
15505
15916
|
const lowerFileName = fileName.toLowerCase();
|
|
15506
15917
|
if (fileName === "SKILL.md") {
|
|
15507
|
-
const dirName = (0,
|
|
15918
|
+
const dirName = (0, import_path15.basename)((0, import_path15.join)(filePath, ".."));
|
|
15508
15919
|
return {
|
|
15509
15920
|
format: "claude",
|
|
15510
15921
|
subtype: "skill",
|
|
@@ -15556,8 +15967,8 @@ async function scanDirectory2(dirPath, baseDir, scanDir, maxDepth = 5, currentDe
|
|
|
15556
15967
|
try {
|
|
15557
15968
|
const entries = await (0, import_promises8.readdir)(dirPath, { withFileTypes: true });
|
|
15558
15969
|
for (const entry of entries) {
|
|
15559
|
-
const fullPath = (0,
|
|
15560
|
-
const relativePath = (0,
|
|
15970
|
+
const fullPath = (0, import_path15.join)(dirPath, entry.name);
|
|
15971
|
+
const relativePath = (0, import_path15.relative)(baseDir, fullPath);
|
|
15561
15972
|
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist" || entry.name === "build") {
|
|
15562
15973
|
continue;
|
|
15563
15974
|
}
|
|
@@ -15694,7 +16105,7 @@ async function handleCatalog(directories, options) {
|
|
|
15694
16105
|
success = true;
|
|
15695
16106
|
return;
|
|
15696
16107
|
}
|
|
15697
|
-
const prpmJsonPath = options.output || (0,
|
|
16108
|
+
const prpmJsonPath = options.output || (0, import_path15.join)(process.cwd(), "prpm.json");
|
|
15698
16109
|
let manifest;
|
|
15699
16110
|
if (options.append) {
|
|
15700
16111
|
try {
|
|
@@ -15732,7 +16143,7 @@ async function handleCatalog(directories, options) {
|
|
|
15732
16143
|
}
|
|
15733
16144
|
let description = `${discovered.format} ${discovered.subtype}`;
|
|
15734
16145
|
try {
|
|
15735
|
-
const firstFilePath = (0,
|
|
16146
|
+
const firstFilePath = (0, import_path15.join)(process.cwd(), discovered.scanDir, discovered.files[0]);
|
|
15736
16147
|
const content = await (0, import_promises8.readFile)(firstFilePath, "utf-8");
|
|
15737
16148
|
const extractedDesc = extractDescription2(content);
|
|
15738
16149
|
if (extractedDesc) {
|
|
@@ -15797,8 +16208,8 @@ var import_commander22 = require("commander");
|
|
|
15797
16208
|
init_user_config();
|
|
15798
16209
|
init_telemetry();
|
|
15799
16210
|
var readline4 = __toESM(require("readline"));
|
|
15800
|
-
var
|
|
15801
|
-
var
|
|
16211
|
+
var fs10 = __toESM(require("fs"));
|
|
16212
|
+
var path7 = __toESM(require("path"));
|
|
15802
16213
|
init_errors();
|
|
15803
16214
|
function createReadline() {
|
|
15804
16215
|
return readline4.createInterface({
|
|
@@ -15916,11 +16327,11 @@ async function runCustomPrompt(customPrompt, input2, options, sessionId) {
|
|
|
15916
16327
|
return response.json();
|
|
15917
16328
|
}
|
|
15918
16329
|
function readPromptFile(filePath) {
|
|
15919
|
-
const absolutePath =
|
|
15920
|
-
if (!
|
|
16330
|
+
const absolutePath = path7.resolve(filePath);
|
|
16331
|
+
if (!fs10.existsSync(absolutePath)) {
|
|
15921
16332
|
throw new Error(`Prompt file not found: ${filePath}`);
|
|
15922
16333
|
}
|
|
15923
|
-
return
|
|
16334
|
+
return fs10.readFileSync(absolutePath, "utf-8");
|
|
15924
16335
|
}
|
|
15925
16336
|
function displayResponse(result, showStats = true) {
|
|
15926
16337
|
const lastMessage = result.conversation[result.conversation.length - 1];
|
|
@@ -16983,57 +17394,57 @@ function createStarredCommand() {
|
|
|
16983
17394
|
init_cjs_shims();
|
|
16984
17395
|
var import_commander27 = require("commander");
|
|
16985
17396
|
var import_promises9 = require("fs/promises");
|
|
16986
|
-
var
|
|
16987
|
-
var
|
|
17397
|
+
var import_path16 = require("path");
|
|
17398
|
+
var import_fs13 = require("fs");
|
|
16988
17399
|
var import_readline = require("readline");
|
|
16989
17400
|
var import_chalk2 = __toESM(require_source());
|
|
16990
17401
|
init_errors();
|
|
16991
17402
|
init_dist();
|
|
16992
17403
|
function getDefaultPath(format, filename, subtype, customName) {
|
|
16993
|
-
const baseName = customName || (0,
|
|
17404
|
+
const baseName = customName || (0, import_path16.basename)(filename, (0, import_path16.extname)(filename));
|
|
16994
17405
|
switch (format) {
|
|
16995
17406
|
case "cursor":
|
|
16996
17407
|
if (subtype === "slash-command") {
|
|
16997
|
-
return (0,
|
|
17408
|
+
return (0, import_path16.join)(process.cwd(), ".cursor", "commands", `${baseName}.md`);
|
|
16998
17409
|
}
|
|
16999
|
-
return (0,
|
|
17410
|
+
return (0, import_path16.join)(process.cwd(), ".cursor", "rules", `${baseName}.mdc`);
|
|
17000
17411
|
case "claude":
|
|
17001
17412
|
if (subtype === "skill") {
|
|
17002
|
-
return (0,
|
|
17413
|
+
return (0, import_path16.join)(process.cwd(), ".claude", "skills", baseName, "SKILL.md");
|
|
17003
17414
|
} else if (subtype === "slash-command") {
|
|
17004
|
-
return (0,
|
|
17415
|
+
return (0, import_path16.join)(process.cwd(), ".claude", "commands", `${baseName}.md`);
|
|
17005
17416
|
} else {
|
|
17006
|
-
return (0,
|
|
17417
|
+
return (0, import_path16.join)(process.cwd(), ".claude", "agents", `${baseName}.md`);
|
|
17007
17418
|
}
|
|
17008
17419
|
case "windsurf":
|
|
17009
|
-
return (0,
|
|
17420
|
+
return (0, import_path16.join)(process.cwd(), ".windsurf", "rules", `${baseName}.md`);
|
|
17010
17421
|
case "kiro":
|
|
17011
17422
|
if (subtype === "hook") {
|
|
17012
|
-
return (0,
|
|
17423
|
+
return (0, import_path16.join)(process.cwd(), ".kiro", "hooks", `${baseName}.kiro.hook`);
|
|
17013
17424
|
}
|
|
17014
17425
|
if (subtype === "agent") {
|
|
17015
|
-
return (0,
|
|
17426
|
+
return (0, import_path16.join)(process.cwd(), ".kiro", "agents", `${baseName}.json`);
|
|
17016
17427
|
}
|
|
17017
|
-
return (0,
|
|
17428
|
+
return (0, import_path16.join)(process.cwd(), ".kiro", "steering", `${baseName}.md`);
|
|
17018
17429
|
case "copilot":
|
|
17019
|
-
return (0,
|
|
17430
|
+
return (0, import_path16.join)(process.cwd(), ".github", "instructions", `${baseName}.instructions.md`);
|
|
17020
17431
|
case "continue":
|
|
17021
17432
|
if (subtype === "slash-command" || subtype === "prompt") {
|
|
17022
|
-
return (0,
|
|
17433
|
+
return (0, import_path16.join)(process.cwd(), ".continue", "prompts", `${baseName}.md`);
|
|
17023
17434
|
}
|
|
17024
|
-
return (0,
|
|
17435
|
+
return (0, import_path16.join)(process.cwd(), ".continue", "rules", `${baseName}.md`);
|
|
17025
17436
|
case "agents.md":
|
|
17026
|
-
return (0,
|
|
17437
|
+
return (0, import_path16.join)(process.cwd(), "agents.md");
|
|
17027
17438
|
case "gemini":
|
|
17028
|
-
return (0,
|
|
17439
|
+
return (0, import_path16.join)(process.cwd(), ".gemini", "commands", `${baseName}.toml`);
|
|
17029
17440
|
case "ruler":
|
|
17030
|
-
return (0,
|
|
17441
|
+
return (0, import_path16.join)(process.cwd(), ".ruler", `${baseName}.md`);
|
|
17031
17442
|
default:
|
|
17032
17443
|
throw new CLIError(`Unknown format: ${format}`);
|
|
17033
17444
|
}
|
|
17034
17445
|
}
|
|
17035
17446
|
function detectFormat(content, filepath) {
|
|
17036
|
-
const ext = (0,
|
|
17447
|
+
const ext = (0, import_path16.extname)(filepath).toLowerCase();
|
|
17037
17448
|
if (ext === ".mdc" || filepath.includes(".cursor/rules") || filepath.includes(".cursor/commands")) {
|
|
17038
17449
|
return "cursor";
|
|
17039
17450
|
}
|
|
@@ -17055,7 +17466,7 @@ function detectFormat(content, filepath) {
|
|
|
17055
17466
|
if (filepath.includes(".continue/rules") || filepath.includes(".continue/prompts") || filepath.includes(".continuerules")) {
|
|
17056
17467
|
return "continue";
|
|
17057
17468
|
}
|
|
17058
|
-
if ((0,
|
|
17469
|
+
if ((0, import_path16.basename)(filepath) === "agents.md") {
|
|
17059
17470
|
return "agents.md";
|
|
17060
17471
|
}
|
|
17061
17472
|
if (ext === ".toml" || filepath.includes(".gemini/commands")) {
|
|
@@ -17213,14 +17624,14 @@ async function handleConvert(sourcePath, options) {
|
|
|
17213
17624
|
}
|
|
17214
17625
|
console.log(import_chalk2.default.green(`\u2713 Converted from ${sourceFormat} to ${options.to}`));
|
|
17215
17626
|
const outputPath = options.output || getDefaultPath(options.to, sourcePath, options.subtype, options.name);
|
|
17216
|
-
if ((0,
|
|
17627
|
+
if ((0, import_fs13.existsSync)(outputPath) && !options.yes) {
|
|
17217
17628
|
const shouldOverwrite = await confirmOverwrite(outputPath);
|
|
17218
17629
|
if (!shouldOverwrite) {
|
|
17219
17630
|
console.log(import_chalk2.default.yellow("\n\u2716 Conversion cancelled"));
|
|
17220
17631
|
return;
|
|
17221
17632
|
}
|
|
17222
17633
|
}
|
|
17223
|
-
const outputDir = (0,
|
|
17634
|
+
const outputDir = (0, import_path16.dirname)(outputPath);
|
|
17224
17635
|
await (0, import_promises9.mkdir)(outputDir, { recursive: true });
|
|
17225
17636
|
console.log(import_chalk2.default.dim("Writing converted file..."));
|
|
17226
17637
|
await (0, import_promises9.writeFile)(outputPath, result.content, "utf-8");
|
|
@@ -17286,8 +17697,8 @@ Valid subtypes: ${validSubtypes.join(", ")}`
|
|
|
17286
17697
|
// src/commands/export.ts
|
|
17287
17698
|
init_cjs_shims();
|
|
17288
17699
|
var import_commander28 = require("commander");
|
|
17289
|
-
var
|
|
17290
|
-
var
|
|
17700
|
+
var import_fs14 = require("fs");
|
|
17701
|
+
var import_path17 = require("path");
|
|
17291
17702
|
var import_chalk3 = __toESM(require_source());
|
|
17292
17703
|
init_errors();
|
|
17293
17704
|
init_lockfile();
|
|
@@ -17303,17 +17714,17 @@ async function exportToRuler(options) {
|
|
|
17303
17714
|
}
|
|
17304
17715
|
console.log(import_chalk3.default.green(`\u2713 Found ${packages.length} installed package${packages.length === 1 ? "" : "s"}`));
|
|
17305
17716
|
console.log();
|
|
17306
|
-
const outputDir = options.output || (0,
|
|
17717
|
+
const outputDir = options.output || (0, import_path17.join)(process.cwd(), ".ruler");
|
|
17307
17718
|
let rulerExists = false;
|
|
17308
17719
|
try {
|
|
17309
|
-
await
|
|
17720
|
+
await import_fs14.promises.access(outputDir);
|
|
17310
17721
|
rulerExists = true;
|
|
17311
17722
|
} catch {
|
|
17312
17723
|
}
|
|
17313
17724
|
if (!rulerExists) {
|
|
17314
17725
|
console.log(import_chalk3.default.yellow(`\u26A0 ${outputDir} directory not found`));
|
|
17315
17726
|
console.log(import_chalk3.default.dim("Creating .ruler directory..."));
|
|
17316
|
-
await
|
|
17727
|
+
await import_fs14.promises.mkdir(outputDir, { recursive: true });
|
|
17317
17728
|
console.log(import_chalk3.default.green(`\u2713 Created ${outputDir}/`));
|
|
17318
17729
|
console.log();
|
|
17319
17730
|
}
|
|
@@ -17327,11 +17738,11 @@ async function exportToRuler(options) {
|
|
|
17327
17738
|
continue;
|
|
17328
17739
|
}
|
|
17329
17740
|
try {
|
|
17330
|
-
const content = await
|
|
17741
|
+
const content = await import_fs14.promises.readFile(pkg.installedPath, "utf-8");
|
|
17331
17742
|
const rulerContent = createRulerFormat(pkg.id, pkg.version, content, pkg.format, pkg.subtype);
|
|
17332
17743
|
const rulerFilename = `${packageName}.md`;
|
|
17333
|
-
const rulerPath = (0,
|
|
17334
|
-
await
|
|
17744
|
+
const rulerPath = (0, import_path17.join)(outputDir, rulerFilename);
|
|
17745
|
+
await import_fs14.promises.writeFile(rulerPath, rulerContent, "utf-8");
|
|
17335
17746
|
console.log(import_chalk3.default.green(`\u2713 Exported ${pkg.id} \u2192 ${rulerFilename}`));
|
|
17336
17747
|
exportedCount++;
|
|
17337
17748
|
} catch (error) {
|
|
@@ -17370,9 +17781,9 @@ function createRulerFormat(packageId, version, content, format, subtype) {
|
|
|
17370
17781
|
return frontmatter + contentWithoutFrontmatter;
|
|
17371
17782
|
}
|
|
17372
17783
|
async function ensureRulerConfig(rulerDir) {
|
|
17373
|
-
const configPath = (0,
|
|
17784
|
+
const configPath = (0, import_path17.join)((0, import_path17.dirname)(rulerDir), "ruler.toml");
|
|
17374
17785
|
try {
|
|
17375
|
-
await
|
|
17786
|
+
await import_fs14.promises.access(configPath);
|
|
17376
17787
|
console.log(import_chalk3.default.dim("\u2139 ruler.toml already exists (not modified)"));
|
|
17377
17788
|
} catch {
|
|
17378
17789
|
const basicConfig = `# Ruler Configuration
|
|
@@ -17398,7 +17809,7 @@ async function ensureRulerConfig(rulerDir) {
|
|
|
17398
17809
|
# [agents.github-copilot]
|
|
17399
17810
|
# enabled = false
|
|
17400
17811
|
`;
|
|
17401
|
-
await
|
|
17812
|
+
await import_fs14.promises.writeFile(configPath, basicConfig, "utf-8");
|
|
17402
17813
|
console.log(import_chalk3.default.green(`\u2713 Created ruler.toml configuration template`));
|
|
17403
17814
|
}
|
|
17404
17815
|
}
|
|
@@ -17468,8 +17879,8 @@ init_telemetry();
|
|
|
17468
17879
|
init_errors();
|
|
17469
17880
|
function getVersion() {
|
|
17470
17881
|
try {
|
|
17471
|
-
const packageJsonPath = (0,
|
|
17472
|
-
const packageJson = JSON.parse((0,
|
|
17882
|
+
const packageJsonPath = (0, import_path18.join)(__dirname, "../package.json");
|
|
17883
|
+
const packageJson = JSON.parse((0, import_fs15.readFileSync)(packageJsonPath, "utf-8"));
|
|
17473
17884
|
return packageJson.version || "0.0.0";
|
|
17474
17885
|
} catch {
|
|
17475
17886
|
return "0.0.0";
|