prpm 1.1.2 → 1.1.4
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 +567 -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,6 +11350,10 @@ 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}",
|
|
11034
11359
|
"ruler": "\u{1F4CF}",
|
|
@@ -11045,6 +11370,10 @@ function getPackageLabel2(format, subtype) {
|
|
|
11045
11370
|
"copilot": "GitHub Copilot",
|
|
11046
11371
|
"kiro": "Kiro",
|
|
11047
11372
|
"gemini": "Gemini",
|
|
11373
|
+
"gemini.md": "Gemini",
|
|
11374
|
+
"claude.md": "Claude",
|
|
11375
|
+
"opencode": "OpenCode",
|
|
11376
|
+
"droid": "Factory Droid",
|
|
11048
11377
|
"mcp": "MCP",
|
|
11049
11378
|
"agents.md": "Agents.md",
|
|
11050
11379
|
"ruler": "Ruler",
|
|
@@ -11334,6 +11663,7 @@ async function handleInstall(packageSpec, options) {
|
|
|
11334
11663
|
locationOverride = void 0;
|
|
11335
11664
|
}
|
|
11336
11665
|
let destPath;
|
|
11666
|
+
let destDir = "";
|
|
11337
11667
|
let fileCount = 0;
|
|
11338
11668
|
let hookMetadata = void 0;
|
|
11339
11669
|
if (format === "claude-md") {
|
|
@@ -11345,10 +11675,10 @@ async function handleInstall(packageSpec, options) {
|
|
|
11345
11675
|
await saveFile(destPath, mainFile);
|
|
11346
11676
|
fileCount = 1;
|
|
11347
11677
|
} else if (extractedFiles.length === 1) {
|
|
11348
|
-
|
|
11678
|
+
destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
|
|
11349
11679
|
if (locationOverride && effectiveFormat === "cursor") {
|
|
11350
11680
|
const relativeDestDir = destDir.startsWith("./") ? destDir.slice(2) : destDir;
|
|
11351
|
-
destDir =
|
|
11681
|
+
destDir = import_path9.default.join(locationOverride, relativeDestDir);
|
|
11352
11682
|
console.log(` \u{1F4C1} Installing Cursor package to custom location: ${destDir}`);
|
|
11353
11683
|
}
|
|
11354
11684
|
let mainFile = extractedFiles[0].content;
|
|
@@ -11358,26 +11688,35 @@ async function handleInstall(packageSpec, options) {
|
|
|
11358
11688
|
destPath = `${destDir}/SKILL.md`;
|
|
11359
11689
|
} else if (effectiveFormat === "claude" && effectiveSubtype === "hook") {
|
|
11360
11690
|
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
|
-
|
|
11691
|
+
} else if (effectiveFormat === "agents.md" || effectiveFormat === "gemini.md" || effectiveFormat === "claude.md") {
|
|
11692
|
+
if (effectiveSubtype === "skill") {
|
|
11693
|
+
destPath = `${destDir}/SKILL.md`;
|
|
11694
|
+
console.log(` \u{1F4E6} Installing skill to ${destDir}/ for progressive disclosure`);
|
|
11695
|
+
} else if (effectiveSubtype === "agent") {
|
|
11696
|
+
destPath = `${destDir}/AGENT.md`;
|
|
11697
|
+
console.log(` \u{1F916} Installing agent to ${destDir}/ for progressive disclosure`);
|
|
11698
|
+
} else {
|
|
11699
|
+
const manifestFilename = getManifestFilename(effectiveFormat);
|
|
11700
|
+
let targetPath = manifestFilename;
|
|
11701
|
+
if (locationOverride) {
|
|
11702
|
+
targetPath = import_path9.default.join(locationOverride, `${manifestFilename.replace(".md", ".override.md")}`);
|
|
11703
|
+
console.log(` \u{1F4C1} Installing to custom location: ${targetPath}`);
|
|
11704
|
+
}
|
|
11705
|
+
destPath = targetPath;
|
|
11706
|
+
if (await fileExists(destPath)) {
|
|
11707
|
+
if (options.force) {
|
|
11708
|
+
console.log(` \u26A0\uFE0F ${destPath} already exists - overwriting (forced).`);
|
|
11709
|
+
} else {
|
|
11710
|
+
console.log(` \u26A0\uFE0F ${destPath} already exists.`);
|
|
11711
|
+
const overwrite = await promptYesNo(
|
|
11712
|
+
` Overwrite existing ${destPath}? (y/N): `,
|
|
11713
|
+
` \u26A0\uFE0F Non-interactive terminal detected. Remove or rename ${destPath} to continue.`
|
|
11714
|
+
);
|
|
11715
|
+
if (!overwrite) {
|
|
11716
|
+
console.log(` \u{1F6AB} Skipping install to avoid overwriting ${destPath}`);
|
|
11717
|
+
success = true;
|
|
11718
|
+
return;
|
|
11719
|
+
}
|
|
11381
11720
|
}
|
|
11382
11721
|
}
|
|
11383
11722
|
}
|
|
@@ -11458,10 +11797,10 @@ async function handleInstall(packageSpec, options) {
|
|
|
11458
11797
|
await saveFile(destPath, mainFile);
|
|
11459
11798
|
fileCount = 1;
|
|
11460
11799
|
} else {
|
|
11461
|
-
|
|
11800
|
+
destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
|
|
11462
11801
|
if (locationOverride && effectiveFormat === "cursor") {
|
|
11463
11802
|
const relativeDestDir = destDir.startsWith("./") ? destDir.slice(2) : destDir;
|
|
11464
|
-
destDir =
|
|
11803
|
+
destDir = import_path9.default.join(locationOverride, relativeDestDir);
|
|
11465
11804
|
console.log(` \u{1F4C1} Installing Cursor package to custom location: ${destDir}`);
|
|
11466
11805
|
}
|
|
11467
11806
|
const packageName = stripAuthorNamespace2(packageId);
|
|
@@ -11544,6 +11883,35 @@ ${afterFrontmatter}`;
|
|
|
11544
11883
|
}
|
|
11545
11884
|
}
|
|
11546
11885
|
}
|
|
11886
|
+
let progressiveDisclosureMetadata;
|
|
11887
|
+
if ((effectiveFormat === "agents.md" || effectiveFormat === "gemini.md" || effectiveFormat === "claude.md") && (effectiveSubtype === "skill" || effectiveSubtype === "agent") && !options.noAppend) {
|
|
11888
|
+
if (!destDir) {
|
|
11889
|
+
throw new Error("Internal error: destDir not set for progressive disclosure installation");
|
|
11890
|
+
}
|
|
11891
|
+
const manifestPath = options.manifestFile || getManifestFilename(effectiveFormat);
|
|
11892
|
+
const resourceName = stripAuthorNamespace2(packageId);
|
|
11893
|
+
const resourceType = effectiveSubtype;
|
|
11894
|
+
const mainFile = resourceType === "agent" ? "AGENT.md" : "SKILL.md";
|
|
11895
|
+
const manifestEntry = {
|
|
11896
|
+
name: resourceName,
|
|
11897
|
+
description: pkg.description || `${pkg.name} ${resourceType}`,
|
|
11898
|
+
skillPath: destDir,
|
|
11899
|
+
mainFile,
|
|
11900
|
+
resourceType
|
|
11901
|
+
};
|
|
11902
|
+
await addSkillToManifest(manifestEntry, manifestPath);
|
|
11903
|
+
console.log(` \u2713 Added ${resourceType} to ${manifestPath} manifest`);
|
|
11904
|
+
progressiveDisclosureMetadata = {
|
|
11905
|
+
mode: "progressive",
|
|
11906
|
+
resourceDir: destDir,
|
|
11907
|
+
manifestPath,
|
|
11908
|
+
resourceName,
|
|
11909
|
+
resourceType,
|
|
11910
|
+
// Legacy fields for backward compatibility
|
|
11911
|
+
skillsDir: destDir,
|
|
11912
|
+
skillName: resourceName
|
|
11913
|
+
};
|
|
11914
|
+
}
|
|
11547
11915
|
const updatedLockfile = lockfile || createLockfile();
|
|
11548
11916
|
addToLockfile(updatedLockfile, packageId, {
|
|
11549
11917
|
version: actualVersion || version,
|
|
@@ -11556,8 +11924,9 @@ ${afterFrontmatter}`;
|
|
|
11556
11924
|
sourceSubtype: pkg.subtype,
|
|
11557
11925
|
installedPath: destPath,
|
|
11558
11926
|
fromCollection: options.fromCollection,
|
|
11559
|
-
hookMetadata
|
|
11927
|
+
hookMetadata,
|
|
11560
11928
|
// Track hook installation metadata for uninstall
|
|
11929
|
+
progressiveDisclosure: progressiveDisclosureMetadata
|
|
11561
11930
|
});
|
|
11562
11931
|
setPackageIntegrity(updatedLockfile, packageId, tarball);
|
|
11563
11932
|
await writeLockfile(updatedLockfile);
|
|
@@ -11571,6 +11940,14 @@ ${afterFrontmatter}`;
|
|
|
11571
11940
|
\u2705 Successfully installed ${packageId}`);
|
|
11572
11941
|
console.log(` \u{1F4C1} Saved to: ${destPath}`);
|
|
11573
11942
|
console.log(` \u{1F512} Lock file updated`);
|
|
11943
|
+
if (progressiveDisclosureMetadata && !options.noAppend) {
|
|
11944
|
+
const manifestFile = progressiveDisclosureMetadata.manifestPath;
|
|
11945
|
+
console.log(`
|
|
11946
|
+
\u{1F393} Skill installed with progressive disclosure`);
|
|
11947
|
+
console.log(` \u{1F4DD} Skill added to ${manifestFile} manifest`);
|
|
11948
|
+
console.log(` \u{1F4A1} The skill is available but not loaded into context by default`);
|
|
11949
|
+
console.log(` \u26A1 Your AI agent will activate this skill automatically when relevant based on its description`);
|
|
11950
|
+
}
|
|
11574
11951
|
console.log(`
|
|
11575
11952
|
\u{1F4A1} This package has been downloaded ${newDownloadCount.toLocaleString()} times`);
|
|
11576
11953
|
success = true;
|
|
@@ -11612,7 +11989,7 @@ async function extractTarball(tarball, packageId) {
|
|
|
11612
11989
|
} catch (error) {
|
|
11613
11990
|
throw new CLIError(`Package decompression failed: ${error.message}`);
|
|
11614
11991
|
}
|
|
11615
|
-
const tmpDir = await import_promises2.default.mkdtemp(
|
|
11992
|
+
const tmpDir = await import_promises2.default.mkdtemp(import_path9.default.join(import_os3.default.tmpdir(), "prpm-"));
|
|
11616
11993
|
const cleanup = async () => {
|
|
11617
11994
|
try {
|
|
11618
11995
|
await import_promises2.default.rm(tmpDir, { recursive: true, force: true });
|
|
@@ -11652,15 +12029,15 @@ async function extractTarball(tarball, packageId) {
|
|
|
11652
12029
|
await cleanup();
|
|
11653
12030
|
}
|
|
11654
12031
|
}
|
|
11655
|
-
async function collectExtractedFiles(rootDir, excludedNames,
|
|
12032
|
+
async function collectExtractedFiles(rootDir, excludedNames, fs12) {
|
|
11656
12033
|
const files = [];
|
|
11657
12034
|
const dirs = [rootDir];
|
|
11658
12035
|
while (dirs.length > 0) {
|
|
11659
12036
|
const currentDir = dirs.pop();
|
|
11660
12037
|
if (!currentDir) continue;
|
|
11661
|
-
const entries = await
|
|
12038
|
+
const entries = await fs12.readdir(currentDir, { withFileTypes: true });
|
|
11662
12039
|
for (const entry of entries) {
|
|
11663
|
-
const fullPath =
|
|
12040
|
+
const fullPath = import_path9.default.join(currentDir, entry.name);
|
|
11664
12041
|
if (entry.isDirectory()) {
|
|
11665
12042
|
dirs.push(fullPath);
|
|
11666
12043
|
continue;
|
|
@@ -11671,8 +12048,8 @@ async function collectExtractedFiles(rootDir, excludedNames, fs11) {
|
|
|
11671
12048
|
if (excludedNames.has(entry.name)) {
|
|
11672
12049
|
continue;
|
|
11673
12050
|
}
|
|
11674
|
-
const content = await
|
|
11675
|
-
const relativePath =
|
|
12051
|
+
const content = await fs12.readFile(fullPath, "utf-8");
|
|
12052
|
+
const relativePath = import_path9.default.relative(rootDir, fullPath).split(import_path9.default.sep).join("/");
|
|
11676
12053
|
files.push({
|
|
11677
12054
|
name: relativePath,
|
|
11678
12055
|
content
|
|
@@ -11682,7 +12059,7 @@ async function collectExtractedFiles(rootDir, excludedNames, fs11) {
|
|
|
11682
12059
|
return files;
|
|
11683
12060
|
}
|
|
11684
12061
|
async function installFromLockfile(options) {
|
|
11685
|
-
var _a;
|
|
12062
|
+
var _a, _b;
|
|
11686
12063
|
try {
|
|
11687
12064
|
const lockfile = await readLockfile();
|
|
11688
12065
|
if (!lockfile) {
|
|
@@ -11704,13 +12081,14 @@ async function installFromLockfile(options) {
|
|
|
11704
12081
|
console.log(` Installing ${packageId}...`);
|
|
11705
12082
|
let locationOverride = options.location;
|
|
11706
12083
|
if (!locationOverride && lockEntry.format === "agents.md" && lockEntry.installedPath) {
|
|
11707
|
-
const baseName =
|
|
12084
|
+
const baseName = import_path9.default.basename(lockEntry.installedPath);
|
|
11708
12085
|
if (baseName === "AGENTS.override.md") {
|
|
11709
|
-
locationOverride =
|
|
12086
|
+
locationOverride = import_path9.default.dirname(lockEntry.installedPath);
|
|
11710
12087
|
} else if (baseName !== "AGENTS.md") {
|
|
11711
|
-
locationOverride =
|
|
12088
|
+
locationOverride = import_path9.default.dirname(lockEntry.installedPath);
|
|
11712
12089
|
}
|
|
11713
12090
|
}
|
|
12091
|
+
const manifestFile = (_a = lockEntry.progressiveDisclosure) == null ? void 0 : _a.manifestPath;
|
|
11714
12092
|
await handleInstall(packageSpec, {
|
|
11715
12093
|
version: lockEntry.version,
|
|
11716
12094
|
as: options.as || lockEntry.format,
|
|
@@ -11718,7 +12096,8 @@ async function installFromLockfile(options) {
|
|
|
11718
12096
|
frozenLockfile: options.frozenLockfile,
|
|
11719
12097
|
force: true,
|
|
11720
12098
|
// Force reinstall when installing from lockfile
|
|
11721
|
-
location: locationOverride
|
|
12099
|
+
location: locationOverride,
|
|
12100
|
+
manifestFile
|
|
11722
12101
|
});
|
|
11723
12102
|
successCount++;
|
|
11724
12103
|
} catch (error) {
|
|
@@ -11727,7 +12106,7 @@ async function installFromLockfile(options) {
|
|
|
11727
12106
|
} else {
|
|
11728
12107
|
failCount++;
|
|
11729
12108
|
console.error(` \u274C Failed to install ${packageId}:`);
|
|
11730
|
-
console.error(` Type: ${(
|
|
12109
|
+
console.error(` Type: ${(_b = error == null ? void 0 : error.constructor) == null ? void 0 : _b.name}`);
|
|
11731
12110
|
console.error(` Message: ${error instanceof Error ? error.message : String(error)}`);
|
|
11732
12111
|
if (error instanceof CLIError) {
|
|
11733
12112
|
console.error(` ExitCode: ${error.exitCode}`);
|
|
@@ -11749,9 +12128,9 @@ async function installFromLockfile(options) {
|
|
|
11749
12128
|
}
|
|
11750
12129
|
function createInstallCommand() {
|
|
11751
12130
|
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) => {
|
|
12131
|
+
command.description("Install a package from the registry, or install all packages from prpm.lock if no package specified").argument("[package]", "Package to install (e.g., react-rules or react-rules@1.2.0). If omitted, installs all packages from prpm.lock").option("--version <version>", "Specific version to install").option("--as <format>", "Convert and install in specific format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, gemini.md, claude.md, canonical)").option("--format <format>", "Alias for --as").option("--location <path>", "Custom location for installed files (Agents.md or nested Cursor rules)").option("--subtype <subtype>", "Specify subtype when converting (skill, agent, rule, etc.)").option("--frozen-lockfile", "Fail if lock file needs to be updated (for CI)").option("--no-append", "Skip adding skill to manifest file (skill files only)").option("--manifest-file <filename>", "Custom manifest filename for progressive disclosure (default: AGENTS.md)", "AGENTS.md").action(async (packageSpec, options) => {
|
|
11753
12132
|
const convertTo = options.format || options.as;
|
|
11754
|
-
if (convertTo && !["cursor", "claude", "continue", "windsurf", "copilot", "kiro", "agents.md", "canonical", "gemini"].includes(convertTo)) {
|
|
12133
|
+
if (convertTo && !["cursor", "claude", "continue", "windsurf", "copilot", "kiro", "agents.md", "gemini.md", "claude.md", "canonical", "gemini"].includes(convertTo)) {
|
|
11755
12134
|
throw new CLIError("\u274C Format must be one of: cursor, claude, continue, windsurf, copilot, kiro, agents.md, canonical, gemini\n\n\u{1F4A1} Examples:\n prpm install my-package --as cursor # Convert to Cursor format\n prpm install my-package --format claude # Convert to Claude format\n prpm install my-package --format kiro # Convert to Kiro format\n prpm install my-package --format agents.md # Convert to Agents.md format\n prpm install my-package # Install in native format", 1);
|
|
11756
12135
|
}
|
|
11757
12136
|
if (!packageSpec) {
|
|
@@ -11768,12 +12147,14 @@ function createInstallCommand() {
|
|
|
11768
12147
|
as: convertTo,
|
|
11769
12148
|
subtype: options.subtype,
|
|
11770
12149
|
frozenLockfile: options.frozenLockfile,
|
|
11771
|
-
location: options.location
|
|
12150
|
+
location: options.location,
|
|
12151
|
+
noAppend: options.noAppend,
|
|
12152
|
+
manifestFile: options.manifestFile
|
|
11772
12153
|
});
|
|
11773
12154
|
});
|
|
11774
12155
|
return command;
|
|
11775
12156
|
}
|
|
11776
|
-
var import_commander11, import_chalk, import_registry_client5, import_stream, import_promises, tar,
|
|
12157
|
+
var import_commander11, import_chalk, import_registry_client5, import_stream, import_promises, tar, import_path9, import_zlib, import_promises2, import_os3;
|
|
11777
12158
|
var init_install = __esm({
|
|
11778
12159
|
"src/commands/install.ts"() {
|
|
11779
12160
|
"use strict";
|
|
@@ -11789,7 +12170,7 @@ var init_install = __esm({
|
|
|
11789
12170
|
tar = __toESM(require("tar"));
|
|
11790
12171
|
init_errors();
|
|
11791
12172
|
init_prompts();
|
|
11792
|
-
|
|
12173
|
+
import_path9 = __toESM(require("path"));
|
|
11793
12174
|
import_zlib = __toESM(require("zlib"));
|
|
11794
12175
|
import_promises2 = __toESM(require("fs/promises"));
|
|
11795
12176
|
import_os3 = __toESM(require("os"));
|
|
@@ -11797,6 +12178,7 @@ var init_install = __esm({
|
|
|
11797
12178
|
init_lockfile();
|
|
11798
12179
|
init_cursor_config();
|
|
11799
12180
|
init_claude_config();
|
|
12181
|
+
init_agents_md_progressive();
|
|
11800
12182
|
init_dist();
|
|
11801
12183
|
}
|
|
11802
12184
|
});
|
|
@@ -11804,8 +12186,8 @@ var init_install = __esm({
|
|
|
11804
12186
|
// src/index.ts
|
|
11805
12187
|
init_cjs_shims();
|
|
11806
12188
|
var import_commander29 = require("commander");
|
|
11807
|
-
var
|
|
11808
|
-
var
|
|
12189
|
+
var import_fs15 = require("fs");
|
|
12190
|
+
var import_path18 = require("path");
|
|
11809
12191
|
|
|
11810
12192
|
// src/commands/list.ts
|
|
11811
12193
|
init_cjs_shims();
|
|
@@ -11964,8 +12346,9 @@ init_cjs_shims();
|
|
|
11964
12346
|
var import_commander2 = require("commander");
|
|
11965
12347
|
init_lockfile();
|
|
11966
12348
|
init_filesystem();
|
|
11967
|
-
var
|
|
12349
|
+
var import_fs7 = require("fs");
|
|
11968
12350
|
init_errors();
|
|
12351
|
+
init_agents_md_progressive();
|
|
11969
12352
|
async function handleUninstall(name) {
|
|
11970
12353
|
try {
|
|
11971
12354
|
console.log(`\u{1F5D1}\uFE0F Uninstalling package: ${name}`);
|
|
@@ -11973,10 +12356,22 @@ async function handleUninstall(name) {
|
|
|
11973
12356
|
if (!pkg) {
|
|
11974
12357
|
throw new CLIError(`\u274C Package "${name}" not found`, 1);
|
|
11975
12358
|
}
|
|
12359
|
+
if (pkg.progressiveDisclosure) {
|
|
12360
|
+
const { manifestPath, resourceName, skillName } = pkg.progressiveDisclosure;
|
|
12361
|
+
const name2 = resourceName || skillName;
|
|
12362
|
+
if (name2) {
|
|
12363
|
+
try {
|
|
12364
|
+
await removeSkillFromManifest(name2, manifestPath);
|
|
12365
|
+
console.log(` \u{1F4DD} Removed from ${manifestPath} manifest`);
|
|
12366
|
+
} catch (error) {
|
|
12367
|
+
console.warn(` \u26A0\uFE0F Failed to remove from manifest: ${error}`);
|
|
12368
|
+
}
|
|
12369
|
+
}
|
|
12370
|
+
}
|
|
11976
12371
|
if (pkg.format === "claude" && pkg.subtype === "hook" && pkg.hookMetadata) {
|
|
11977
12372
|
const settingsPath = pkg.installedPath || ".claude/settings.json";
|
|
11978
12373
|
try {
|
|
11979
|
-
const settingsContent = await
|
|
12374
|
+
const settingsContent = await import_fs7.promises.readFile(settingsPath, "utf-8");
|
|
11980
12375
|
const settings = JSON.parse(settingsContent);
|
|
11981
12376
|
if (settings.hooks) {
|
|
11982
12377
|
let removedCount = 0;
|
|
@@ -11993,7 +12388,7 @@ async function handleUninstall(name) {
|
|
|
11993
12388
|
}
|
|
11994
12389
|
}
|
|
11995
12390
|
}
|
|
11996
|
-
await
|
|
12391
|
+
await import_fs7.promises.writeFile(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
11997
12392
|
console.log(` \u{1FA9D} Removed ${removedCount} hook(s) from ${settingsPath}`);
|
|
11998
12393
|
}
|
|
11999
12394
|
} catch (error) {
|
|
@@ -12018,12 +12413,12 @@ async function handleUninstall(name) {
|
|
|
12018
12413
|
throw new CLIError(`Cannot uninstall ${name}: installation path unknown`, 1);
|
|
12019
12414
|
}
|
|
12020
12415
|
try {
|
|
12021
|
-
const stats = await
|
|
12416
|
+
const stats = await import_fs7.promises.stat(targetPath);
|
|
12022
12417
|
if (stats.isDirectory()) {
|
|
12023
|
-
await
|
|
12418
|
+
await import_fs7.promises.rm(targetPath, { recursive: true, force: true });
|
|
12024
12419
|
console.log(` \u{1F5D1}\uFE0F Deleted directory: ${targetPath}`);
|
|
12025
12420
|
} else if (stats.isFile()) {
|
|
12026
|
-
await
|
|
12421
|
+
await import_fs7.promises.unlink(targetPath);
|
|
12027
12422
|
console.log(` \u{1F5D1}\uFE0F Deleted file: ${targetPath}`);
|
|
12028
12423
|
}
|
|
12029
12424
|
} catch (error) {
|
|
@@ -12051,17 +12446,17 @@ function createUninstallCommand() {
|
|
|
12051
12446
|
// src/commands/index.ts
|
|
12052
12447
|
init_cjs_shims();
|
|
12053
12448
|
var import_commander3 = require("commander");
|
|
12054
|
-
var
|
|
12055
|
-
var
|
|
12449
|
+
var import_fs8 = require("fs");
|
|
12450
|
+
var import_path7 = __toESM(require("path"));
|
|
12056
12451
|
init_lockfile();
|
|
12057
12452
|
init_filesystem();
|
|
12058
12453
|
init_errors();
|
|
12059
12454
|
async function scanDirectory(dirPath, format, subtype) {
|
|
12060
12455
|
try {
|
|
12061
|
-
const files = await
|
|
12456
|
+
const files = await import_fs8.promises.readdir(dirPath, { withFileTypes: true });
|
|
12062
12457
|
const results = [];
|
|
12063
12458
|
for (const file of files) {
|
|
12064
|
-
const fullPath =
|
|
12459
|
+
const fullPath = import_path7.default.join(dirPath, file.name);
|
|
12065
12460
|
if (file.isFile()) {
|
|
12066
12461
|
const id = generateId(file.name);
|
|
12067
12462
|
results.push({
|
|
@@ -12074,11 +12469,11 @@ async function scanDirectory(dirPath, format, subtype) {
|
|
|
12074
12469
|
const isCursorAgent = format === "cursor" && subtype === "agent";
|
|
12075
12470
|
if (isClaudeType || isCursorAgent) {
|
|
12076
12471
|
try {
|
|
12077
|
-
const subFiles = await
|
|
12472
|
+
const subFiles = await import_fs8.promises.readdir(fullPath, { withFileTypes: true });
|
|
12078
12473
|
for (const subFile of subFiles) {
|
|
12079
12474
|
const isValidFile = subFile.isFile() && (subFile.name === "SKILL.md" || subFile.name === "AGENT.md" || subFile.name === "skill.md" || subFile.name === "agent.md");
|
|
12080
12475
|
if (isValidFile) {
|
|
12081
|
-
const subFilePath =
|
|
12476
|
+
const subFilePath = import_path7.default.join(fullPath, subFile.name);
|
|
12082
12477
|
const id = file.name;
|
|
12083
12478
|
results.push({
|
|
12084
12479
|
filePath: subFilePath,
|
|
@@ -12140,7 +12535,7 @@ async function handleIndex(options = {}) {
|
|
|
12140
12535
|
id: file.id,
|
|
12141
12536
|
version: "0.0.0",
|
|
12142
12537
|
// Local files don't have versions
|
|
12143
|
-
tarballUrl: `file://${
|
|
12538
|
+
tarballUrl: `file://${import_path7.default.resolve(file.filePath)}`,
|
|
12144
12539
|
format: dir.format,
|
|
12145
12540
|
subtype: dir.subtype
|
|
12146
12541
|
});
|
|
@@ -12406,6 +12801,10 @@ function getPackageIcon(format, subtype) {
|
|
|
12406
12801
|
"copilot": "\u2708\uFE0F",
|
|
12407
12802
|
"kiro": "\u{1F3AF}",
|
|
12408
12803
|
"gemini": "\u2728",
|
|
12804
|
+
"gemini.md": "\u2728",
|
|
12805
|
+
"claude.md": "\u{1F916}",
|
|
12806
|
+
"opencode": "\u26A1",
|
|
12807
|
+
"droid": "\u{1F3ED}",
|
|
12409
12808
|
"mcp": "\u{1F517}",
|
|
12410
12809
|
"agents.md": "\u{1F4DD}",
|
|
12411
12810
|
"ruler": "\u{1F4CF}",
|
|
@@ -12422,6 +12821,10 @@ function getPackageLabel(format, subtype) {
|
|
|
12422
12821
|
"copilot": "GitHub Copilot",
|
|
12423
12822
|
"kiro": "Kiro",
|
|
12424
12823
|
"gemini": "Gemini",
|
|
12824
|
+
"gemini.md": "Gemini",
|
|
12825
|
+
"claude.md": "Claude",
|
|
12826
|
+
"opencode": "OpenCode",
|
|
12827
|
+
"droid": "Factory Droid",
|
|
12425
12828
|
"mcp": "MCP",
|
|
12426
12829
|
"agents.md": "Agents.md",
|
|
12427
12830
|
"ruler": "Ruler",
|
|
@@ -12949,7 +13352,7 @@ init_install();
|
|
|
12949
13352
|
init_cjs_shims();
|
|
12950
13353
|
var import_commander12 = require("commander");
|
|
12951
13354
|
var import_promises6 = require("fs/promises");
|
|
12952
|
-
var
|
|
13355
|
+
var import_path13 = require("path");
|
|
12953
13356
|
var tar2 = __toESM(require("tar"));
|
|
12954
13357
|
var import_os4 = require("os");
|
|
12955
13358
|
var import_crypto2 = require("crypto");
|
|
@@ -13122,19 +13525,19 @@ function validateMarketplaceJson(data) {
|
|
|
13122
13525
|
init_cjs_shims();
|
|
13123
13526
|
var import_ajv2 = __toESM(require("ajv"));
|
|
13124
13527
|
var import_ajv_formats2 = __toESM(require("ajv-formats"));
|
|
13125
|
-
var
|
|
13126
|
-
var
|
|
13528
|
+
var import_fs10 = require("fs");
|
|
13529
|
+
var import_path10 = require("path");
|
|
13127
13530
|
var schema2;
|
|
13128
13531
|
var schemaCandidates = [
|
|
13129
13532
|
// Source file layout (src/core → ../../schemas)
|
|
13130
|
-
(0,
|
|
13533
|
+
(0, import_path10.join)(__dirname, "../../schemas/prpm-manifest.schema.json"),
|
|
13131
13534
|
// Bundled layout (dist/index.js → ../schemas)
|
|
13132
|
-
(0,
|
|
13535
|
+
(0, import_path10.join)(__dirname, "../schemas/prpm-manifest.schema.json")
|
|
13133
13536
|
];
|
|
13134
13537
|
for (const candidate of schemaCandidates) {
|
|
13135
13538
|
try {
|
|
13136
|
-
if ((0,
|
|
13137
|
-
schema2 = JSON.parse((0,
|
|
13539
|
+
if ((0, import_fs10.existsSync)(candidate)) {
|
|
13540
|
+
schema2 = JSON.parse((0, import_fs10.readFileSync)(candidate, "utf-8"));
|
|
13138
13541
|
break;
|
|
13139
13542
|
}
|
|
13140
13543
|
} catch {
|
|
@@ -13156,27 +13559,27 @@ function validateManifestSchema(manifest) {
|
|
|
13156
13559
|
const valid = validate(manifest);
|
|
13157
13560
|
if (!valid && validate.errors) {
|
|
13158
13561
|
const errors = validate.errors.map((err) => {
|
|
13159
|
-
const
|
|
13562
|
+
const path8 = err.instancePath || "manifest";
|
|
13160
13563
|
const message = err.message || "validation failed";
|
|
13161
13564
|
if (err.keyword === "required") {
|
|
13162
13565
|
const missingProp = err.params.missingProperty;
|
|
13163
13566
|
return `Missing required field: ${missingProp}`;
|
|
13164
13567
|
}
|
|
13165
13568
|
if (err.keyword === "pattern") {
|
|
13166
|
-
return `${
|
|
13569
|
+
return `${path8}: ${message}. Value does not match required pattern.`;
|
|
13167
13570
|
}
|
|
13168
13571
|
if (err.keyword === "enum") {
|
|
13169
13572
|
const allowedValues = err.params.allowedValues;
|
|
13170
|
-
return `${
|
|
13573
|
+
return `${path8}: ${message}. Allowed values: ${allowedValues.join(", ")}`;
|
|
13171
13574
|
}
|
|
13172
13575
|
if (err.keyword === "minLength" || err.keyword === "maxLength") {
|
|
13173
13576
|
const limit = err.params.limit;
|
|
13174
|
-
return `${
|
|
13577
|
+
return `${path8}: ${message} (${err.keyword}: ${limit})`;
|
|
13175
13578
|
}
|
|
13176
13579
|
if (err.keyword === "oneOf") {
|
|
13177
|
-
return `${
|
|
13580
|
+
return `${path8}: must match exactly one schema (check if files array uses either all strings or all objects, not mixed)`;
|
|
13178
13581
|
}
|
|
13179
|
-
return `${
|
|
13582
|
+
return `${path8}: ${message}`;
|
|
13180
13583
|
});
|
|
13181
13584
|
return { valid: false, errors };
|
|
13182
13585
|
}
|
|
@@ -13189,8 +13592,8 @@ function getManifestSchema() {
|
|
|
13189
13592
|
// src/utils/license-extractor.ts
|
|
13190
13593
|
init_cjs_shims();
|
|
13191
13594
|
var import_promises3 = require("fs/promises");
|
|
13192
|
-
var
|
|
13193
|
-
var
|
|
13595
|
+
var import_path11 = require("path");
|
|
13596
|
+
var import_fs11 = require("fs");
|
|
13194
13597
|
var LICENSE_FILE_PATTERNS = [
|
|
13195
13598
|
"LICENSE",
|
|
13196
13599
|
"LICENSE.md",
|
|
@@ -13239,9 +13642,9 @@ function generateLicenseUrl(repositoryUrl, fileName) {
|
|
|
13239
13642
|
async function extractLicenseInfo(repositoryUrl) {
|
|
13240
13643
|
const cwd = process.cwd();
|
|
13241
13644
|
for (const fileName of LICENSE_FILE_PATTERNS) {
|
|
13242
|
-
const filePath = (0,
|
|
13645
|
+
const filePath = (0, import_path11.join)(cwd, fileName);
|
|
13243
13646
|
try {
|
|
13244
|
-
await (0, import_promises3.access)(filePath,
|
|
13647
|
+
await (0, import_promises3.access)(filePath, import_fs11.constants.R_OK);
|
|
13245
13648
|
const text = await (0, import_promises3.readFile)(filePath, "utf-8");
|
|
13246
13649
|
const type2 = detectLicenseType(text);
|
|
13247
13650
|
const url = generateLicenseUrl(repositoryUrl, fileName);
|
|
@@ -13275,7 +13678,7 @@ function validateLicenseInfo(licenseInfo, packageName) {
|
|
|
13275
13678
|
// src/utils/snippet-extractor.ts
|
|
13276
13679
|
init_cjs_shims();
|
|
13277
13680
|
var import_promises4 = require("fs/promises");
|
|
13278
|
-
var
|
|
13681
|
+
var import_path12 = require("path");
|
|
13279
13682
|
var MAX_SNIPPET_LENGTH = 2e3;
|
|
13280
13683
|
async function extractSnippet(manifest) {
|
|
13281
13684
|
const cwd = process.cwd();
|
|
@@ -13291,7 +13694,7 @@ async function extractSnippet(manifest) {
|
|
|
13291
13694
|
const firstFile = manifest.files[0];
|
|
13292
13695
|
fileName = typeof firstFile === "string" ? firstFile : firstFile.path;
|
|
13293
13696
|
}
|
|
13294
|
-
const fullPath = (0,
|
|
13697
|
+
const fullPath = (0, import_path12.join)(cwd, fileName);
|
|
13295
13698
|
const stats = await (0, import_promises4.stat)(fullPath);
|
|
13296
13699
|
if (stats.isDirectory()) {
|
|
13297
13700
|
console.warn(`\u26A0\uFE0F Skipping snippet extraction: "${fullPath}" is a directory`);
|
|
@@ -13517,13 +13920,13 @@ async function validatePackageFiles(manifest) {
|
|
|
13517
13920
|
}
|
|
13518
13921
|
}
|
|
13519
13922
|
if (manifest.format === "claude" && manifest.subtype === "skill") {
|
|
13520
|
-
const hasSkillMd = filePaths.some((
|
|
13923
|
+
const hasSkillMd = filePaths.some((path8) => path8.endsWith("/SKILL.md") || path8 === "SKILL.md");
|
|
13521
13924
|
if (!hasSkillMd) {
|
|
13522
13925
|
errors.push("Claude skills must contain a SKILL.md file");
|
|
13523
13926
|
}
|
|
13524
13927
|
}
|
|
13525
13928
|
if (manifest.format === "windsurf") {
|
|
13526
|
-
const hasWindsurfRules = filePaths.some((
|
|
13929
|
+
const hasWindsurfRules = filePaths.some((path8) => path8.includes(".windsurf/rules"));
|
|
13527
13930
|
if (!hasWindsurfRules) {
|
|
13528
13931
|
warnings.push("Windsurf packages typically use .windsurf/rules filename");
|
|
13529
13932
|
}
|
|
@@ -13533,7 +13936,7 @@ async function validatePackageFiles(manifest) {
|
|
|
13533
13936
|
|
|
13534
13937
|
// src/commands/publish.ts
|
|
13535
13938
|
async function findAndLoadManifests() {
|
|
13536
|
-
const prpmJsonPath = (0,
|
|
13939
|
+
const prpmJsonPath = (0, import_path13.join)(process.cwd(), "prpm.json");
|
|
13537
13940
|
let prpmJsonExists = false;
|
|
13538
13941
|
let prpmJsonError = null;
|
|
13539
13942
|
try {
|
|
@@ -13585,7 +13988,7 @@ async function findAndLoadManifests() {
|
|
|
13585
13988
|
throw error;
|
|
13586
13989
|
}
|
|
13587
13990
|
}
|
|
13588
|
-
const marketplaceJsonPath = (0,
|
|
13991
|
+
const marketplaceJsonPath = (0, import_path13.join)(process.cwd(), ".claude", "marketplace.json");
|
|
13589
13992
|
try {
|
|
13590
13993
|
const content = await (0, import_promises6.readFile)(marketplaceJsonPath, "utf-8");
|
|
13591
13994
|
const marketplaceData = JSON.parse(content);
|
|
@@ -13601,7 +14004,7 @@ async function findAndLoadManifests() {
|
|
|
13601
14004
|
return { manifests, collections: [], source: ".claude/marketplace.json" };
|
|
13602
14005
|
} catch (error) {
|
|
13603
14006
|
}
|
|
13604
|
-
const marketplaceJsonPluginPath = (0,
|
|
14007
|
+
const marketplaceJsonPluginPath = (0, import_path13.join)(process.cwd(), ".claude-plugin", "marketplace.json");
|
|
13605
14008
|
try {
|
|
13606
14009
|
const content = await (0, import_promises6.readFile)(marketplaceJsonPluginPath, "utf-8");
|
|
13607
14010
|
const marketplaceData = JSON.parse(content);
|
|
@@ -13645,7 +14048,7 @@ function validateManifest(manifest, contextLabel) {
|
|
|
13645
14048
|
}
|
|
13646
14049
|
if (manifest.format === "claude" && manifest.subtype === "skill") {
|
|
13647
14050
|
const filePaths = normalizeFilePaths2(manifest.files);
|
|
13648
|
-
const hasSkillMd = filePaths.some((
|
|
14051
|
+
const hasSkillMd = filePaths.some((path8) => path8.endsWith("/SKILL.md") || path8 === "SKILL.md");
|
|
13649
14052
|
if (!hasSkillMd) {
|
|
13650
14053
|
throw new Error(
|
|
13651
14054
|
`${prefix}Claude skills must contain a SKILL.md file.
|
|
@@ -13718,8 +14121,8 @@ function predictScopedPackageName(manifestName, username, organization) {
|
|
|
13718
14121
|
return manifestName;
|
|
13719
14122
|
}
|
|
13720
14123
|
async function createTarball(manifest) {
|
|
13721
|
-
const tmpDir = (0,
|
|
13722
|
-
const tarballPath = (0,
|
|
14124
|
+
const tmpDir = (0, import_path13.join)((0, import_os4.tmpdir)(), `prpm-${(0, import_crypto2.randomBytes)(8).toString("hex")}`);
|
|
14125
|
+
const tarballPath = (0, import_path13.join)(tmpDir, "package.tar.gz");
|
|
13723
14126
|
try {
|
|
13724
14127
|
await (0, import_promises6.mkdir)(tmpDir, { recursive: true });
|
|
13725
14128
|
const filePaths = normalizeFilePaths2(manifest.files);
|
|
@@ -13780,7 +14183,7 @@ async function handlePublish(options) {
|
|
|
13780
14183
|
const { manifests, collections, source } = await findAndLoadManifests();
|
|
13781
14184
|
if (source === "prpm.json (multi-package)" || source === "prpm.json") {
|
|
13782
14185
|
try {
|
|
13783
|
-
const prpmJsonPath = (0,
|
|
14186
|
+
const prpmJsonPath = (0, import_path13.join)(process.cwd(), "prpm.json");
|
|
13784
14187
|
const prpmContent = await (0, import_promises6.readFile)(prpmJsonPath, "utf-8");
|
|
13785
14188
|
const prpmManifest = JSON.parse(prpmContent);
|
|
13786
14189
|
if (prpmManifest.scripts) {
|
|
@@ -14774,8 +15177,8 @@ function createSchemaCommand() {
|
|
|
14774
15177
|
init_cjs_shims();
|
|
14775
15178
|
var import_commander19 = require("commander");
|
|
14776
15179
|
var import_promises7 = require("fs/promises");
|
|
14777
|
-
var
|
|
14778
|
-
var
|
|
15180
|
+
var import_path14 = require("path");
|
|
15181
|
+
var import_fs12 = require("fs");
|
|
14779
15182
|
var readline3 = __toESM(require("readline/promises"));
|
|
14780
15183
|
var import_process = require("process");
|
|
14781
15184
|
|
|
@@ -15142,12 +15545,12 @@ function getDefaultAuthor() {
|
|
|
15142
15545
|
async function createExampleFiles(format, files, packageName) {
|
|
15143
15546
|
const templates = EXAMPLE_TEMPLATES[format] || {};
|
|
15144
15547
|
for (const file of files) {
|
|
15145
|
-
const filePath = (0,
|
|
15146
|
-
const dirPath = (0,
|
|
15147
|
-
if (!(0,
|
|
15548
|
+
const filePath = (0, import_path14.join)(process.cwd(), file);
|
|
15549
|
+
const dirPath = (0, import_path14.join)(filePath, "..");
|
|
15550
|
+
if (!(0, import_fs12.existsSync)(dirPath)) {
|
|
15148
15551
|
await (0, import_promises7.mkdir)(dirPath, { recursive: true });
|
|
15149
15552
|
}
|
|
15150
|
-
if ((0,
|
|
15553
|
+
if ((0, import_fs12.existsSync)(filePath)) {
|
|
15151
15554
|
console.log(` Skipping ${file} (already exists)`);
|
|
15152
15555
|
continue;
|
|
15153
15556
|
}
|
|
@@ -15161,8 +15564,8 @@ Add your content here.
|
|
|
15161
15564
|
}
|
|
15162
15565
|
}
|
|
15163
15566
|
async function createReadme(config) {
|
|
15164
|
-
const readmePath = (0,
|
|
15165
|
-
if ((0,
|
|
15567
|
+
const readmePath = (0, import_path14.join)(process.cwd(), "README.md");
|
|
15568
|
+
if ((0, import_fs12.existsSync)(readmePath)) {
|
|
15166
15569
|
console.log(" Skipping README.md (already exists)");
|
|
15167
15570
|
return;
|
|
15168
15571
|
}
|
|
@@ -15196,8 +15599,8 @@ ${config.license}
|
|
|
15196
15599
|
console.log(" Created README.md");
|
|
15197
15600
|
}
|
|
15198
15601
|
async function initPackage(options) {
|
|
15199
|
-
const manifestPath = (0,
|
|
15200
|
-
if ((0,
|
|
15602
|
+
const manifestPath = (0, import_path14.join)(process.cwd(), "prpm.json");
|
|
15603
|
+
if ((0, import_fs12.existsSync)(manifestPath) && !options.force) {
|
|
15201
15604
|
throw new Error(
|
|
15202
15605
|
"prpm.json already exists. Use --force to overwrite, or run this command in a different directory."
|
|
15203
15606
|
);
|
|
@@ -15496,15 +15899,15 @@ function createConfigCommand() {
|
|
|
15496
15899
|
init_cjs_shims();
|
|
15497
15900
|
var import_commander21 = require("commander");
|
|
15498
15901
|
var import_promises8 = require("fs/promises");
|
|
15499
|
-
var
|
|
15902
|
+
var import_path15 = require("path");
|
|
15500
15903
|
init_telemetry();
|
|
15501
15904
|
init_lockfile();
|
|
15502
15905
|
init_errors();
|
|
15503
15906
|
function detectPackageInfo(filePath, content) {
|
|
15504
|
-
const fileName = (0,
|
|
15907
|
+
const fileName = (0, import_path15.basename)(filePath);
|
|
15505
15908
|
const lowerFileName = fileName.toLowerCase();
|
|
15506
15909
|
if (fileName === "SKILL.md") {
|
|
15507
|
-
const dirName = (0,
|
|
15910
|
+
const dirName = (0, import_path15.basename)((0, import_path15.join)(filePath, ".."));
|
|
15508
15911
|
return {
|
|
15509
15912
|
format: "claude",
|
|
15510
15913
|
subtype: "skill",
|
|
@@ -15556,8 +15959,8 @@ async function scanDirectory2(dirPath, baseDir, scanDir, maxDepth = 5, currentDe
|
|
|
15556
15959
|
try {
|
|
15557
15960
|
const entries = await (0, import_promises8.readdir)(dirPath, { withFileTypes: true });
|
|
15558
15961
|
for (const entry of entries) {
|
|
15559
|
-
const fullPath = (0,
|
|
15560
|
-
const relativePath = (0,
|
|
15962
|
+
const fullPath = (0, import_path15.join)(dirPath, entry.name);
|
|
15963
|
+
const relativePath = (0, import_path15.relative)(baseDir, fullPath);
|
|
15561
15964
|
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist" || entry.name === "build") {
|
|
15562
15965
|
continue;
|
|
15563
15966
|
}
|
|
@@ -15694,7 +16097,7 @@ async function handleCatalog(directories, options) {
|
|
|
15694
16097
|
success = true;
|
|
15695
16098
|
return;
|
|
15696
16099
|
}
|
|
15697
|
-
const prpmJsonPath = options.output || (0,
|
|
16100
|
+
const prpmJsonPath = options.output || (0, import_path15.join)(process.cwd(), "prpm.json");
|
|
15698
16101
|
let manifest;
|
|
15699
16102
|
if (options.append) {
|
|
15700
16103
|
try {
|
|
@@ -15732,7 +16135,7 @@ async function handleCatalog(directories, options) {
|
|
|
15732
16135
|
}
|
|
15733
16136
|
let description = `${discovered.format} ${discovered.subtype}`;
|
|
15734
16137
|
try {
|
|
15735
|
-
const firstFilePath = (0,
|
|
16138
|
+
const firstFilePath = (0, import_path15.join)(process.cwd(), discovered.scanDir, discovered.files[0]);
|
|
15736
16139
|
const content = await (0, import_promises8.readFile)(firstFilePath, "utf-8");
|
|
15737
16140
|
const extractedDesc = extractDescription2(content);
|
|
15738
16141
|
if (extractedDesc) {
|
|
@@ -15797,8 +16200,8 @@ var import_commander22 = require("commander");
|
|
|
15797
16200
|
init_user_config();
|
|
15798
16201
|
init_telemetry();
|
|
15799
16202
|
var readline4 = __toESM(require("readline"));
|
|
15800
|
-
var
|
|
15801
|
-
var
|
|
16203
|
+
var fs10 = __toESM(require("fs"));
|
|
16204
|
+
var path7 = __toESM(require("path"));
|
|
15802
16205
|
init_errors();
|
|
15803
16206
|
function createReadline() {
|
|
15804
16207
|
return readline4.createInterface({
|
|
@@ -15916,11 +16319,11 @@ async function runCustomPrompt(customPrompt, input2, options, sessionId) {
|
|
|
15916
16319
|
return response.json();
|
|
15917
16320
|
}
|
|
15918
16321
|
function readPromptFile(filePath) {
|
|
15919
|
-
const absolutePath =
|
|
15920
|
-
if (!
|
|
16322
|
+
const absolutePath = path7.resolve(filePath);
|
|
16323
|
+
if (!fs10.existsSync(absolutePath)) {
|
|
15921
16324
|
throw new Error(`Prompt file not found: ${filePath}`);
|
|
15922
16325
|
}
|
|
15923
|
-
return
|
|
16326
|
+
return fs10.readFileSync(absolutePath, "utf-8");
|
|
15924
16327
|
}
|
|
15925
16328
|
function displayResponse(result, showStats = true) {
|
|
15926
16329
|
const lastMessage = result.conversation[result.conversation.length - 1];
|
|
@@ -16983,57 +17386,57 @@ function createStarredCommand() {
|
|
|
16983
17386
|
init_cjs_shims();
|
|
16984
17387
|
var import_commander27 = require("commander");
|
|
16985
17388
|
var import_promises9 = require("fs/promises");
|
|
16986
|
-
var
|
|
16987
|
-
var
|
|
17389
|
+
var import_path16 = require("path");
|
|
17390
|
+
var import_fs13 = require("fs");
|
|
16988
17391
|
var import_readline = require("readline");
|
|
16989
17392
|
var import_chalk2 = __toESM(require_source());
|
|
16990
17393
|
init_errors();
|
|
16991
17394
|
init_dist();
|
|
16992
17395
|
function getDefaultPath(format, filename, subtype, customName) {
|
|
16993
|
-
const baseName = customName || (0,
|
|
17396
|
+
const baseName = customName || (0, import_path16.basename)(filename, (0, import_path16.extname)(filename));
|
|
16994
17397
|
switch (format) {
|
|
16995
17398
|
case "cursor":
|
|
16996
17399
|
if (subtype === "slash-command") {
|
|
16997
|
-
return (0,
|
|
17400
|
+
return (0, import_path16.join)(process.cwd(), ".cursor", "commands", `${baseName}.md`);
|
|
16998
17401
|
}
|
|
16999
|
-
return (0,
|
|
17402
|
+
return (0, import_path16.join)(process.cwd(), ".cursor", "rules", `${baseName}.mdc`);
|
|
17000
17403
|
case "claude":
|
|
17001
17404
|
if (subtype === "skill") {
|
|
17002
|
-
return (0,
|
|
17405
|
+
return (0, import_path16.join)(process.cwd(), ".claude", "skills", baseName, "SKILL.md");
|
|
17003
17406
|
} else if (subtype === "slash-command") {
|
|
17004
|
-
return (0,
|
|
17407
|
+
return (0, import_path16.join)(process.cwd(), ".claude", "commands", `${baseName}.md`);
|
|
17005
17408
|
} else {
|
|
17006
|
-
return (0,
|
|
17409
|
+
return (0, import_path16.join)(process.cwd(), ".claude", "agents", `${baseName}.md`);
|
|
17007
17410
|
}
|
|
17008
17411
|
case "windsurf":
|
|
17009
|
-
return (0,
|
|
17412
|
+
return (0, import_path16.join)(process.cwd(), ".windsurf", "rules", `${baseName}.md`);
|
|
17010
17413
|
case "kiro":
|
|
17011
17414
|
if (subtype === "hook") {
|
|
17012
|
-
return (0,
|
|
17415
|
+
return (0, import_path16.join)(process.cwd(), ".kiro", "hooks", `${baseName}.kiro.hook`);
|
|
17013
17416
|
}
|
|
17014
17417
|
if (subtype === "agent") {
|
|
17015
|
-
return (0,
|
|
17418
|
+
return (0, import_path16.join)(process.cwd(), ".kiro", "agents", `${baseName}.json`);
|
|
17016
17419
|
}
|
|
17017
|
-
return (0,
|
|
17420
|
+
return (0, import_path16.join)(process.cwd(), ".kiro", "steering", `${baseName}.md`);
|
|
17018
17421
|
case "copilot":
|
|
17019
|
-
return (0,
|
|
17422
|
+
return (0, import_path16.join)(process.cwd(), ".github", "instructions", `${baseName}.instructions.md`);
|
|
17020
17423
|
case "continue":
|
|
17021
17424
|
if (subtype === "slash-command" || subtype === "prompt") {
|
|
17022
|
-
return (0,
|
|
17425
|
+
return (0, import_path16.join)(process.cwd(), ".continue", "prompts", `${baseName}.md`);
|
|
17023
17426
|
}
|
|
17024
|
-
return (0,
|
|
17427
|
+
return (0, import_path16.join)(process.cwd(), ".continue", "rules", `${baseName}.md`);
|
|
17025
17428
|
case "agents.md":
|
|
17026
|
-
return (0,
|
|
17429
|
+
return (0, import_path16.join)(process.cwd(), "agents.md");
|
|
17027
17430
|
case "gemini":
|
|
17028
|
-
return (0,
|
|
17431
|
+
return (0, import_path16.join)(process.cwd(), ".gemini", "commands", `${baseName}.toml`);
|
|
17029
17432
|
case "ruler":
|
|
17030
|
-
return (0,
|
|
17433
|
+
return (0, import_path16.join)(process.cwd(), ".ruler", `${baseName}.md`);
|
|
17031
17434
|
default:
|
|
17032
17435
|
throw new CLIError(`Unknown format: ${format}`);
|
|
17033
17436
|
}
|
|
17034
17437
|
}
|
|
17035
17438
|
function detectFormat(content, filepath) {
|
|
17036
|
-
const ext = (0,
|
|
17439
|
+
const ext = (0, import_path16.extname)(filepath).toLowerCase();
|
|
17037
17440
|
if (ext === ".mdc" || filepath.includes(".cursor/rules") || filepath.includes(".cursor/commands")) {
|
|
17038
17441
|
return "cursor";
|
|
17039
17442
|
}
|
|
@@ -17055,7 +17458,7 @@ function detectFormat(content, filepath) {
|
|
|
17055
17458
|
if (filepath.includes(".continue/rules") || filepath.includes(".continue/prompts") || filepath.includes(".continuerules")) {
|
|
17056
17459
|
return "continue";
|
|
17057
17460
|
}
|
|
17058
|
-
if ((0,
|
|
17461
|
+
if ((0, import_path16.basename)(filepath) === "agents.md") {
|
|
17059
17462
|
return "agents.md";
|
|
17060
17463
|
}
|
|
17061
17464
|
if (ext === ".toml" || filepath.includes(".gemini/commands")) {
|
|
@@ -17213,14 +17616,14 @@ async function handleConvert(sourcePath, options) {
|
|
|
17213
17616
|
}
|
|
17214
17617
|
console.log(import_chalk2.default.green(`\u2713 Converted from ${sourceFormat} to ${options.to}`));
|
|
17215
17618
|
const outputPath = options.output || getDefaultPath(options.to, sourcePath, options.subtype, options.name);
|
|
17216
|
-
if ((0,
|
|
17619
|
+
if ((0, import_fs13.existsSync)(outputPath) && !options.yes) {
|
|
17217
17620
|
const shouldOverwrite = await confirmOverwrite(outputPath);
|
|
17218
17621
|
if (!shouldOverwrite) {
|
|
17219
17622
|
console.log(import_chalk2.default.yellow("\n\u2716 Conversion cancelled"));
|
|
17220
17623
|
return;
|
|
17221
17624
|
}
|
|
17222
17625
|
}
|
|
17223
|
-
const outputDir = (0,
|
|
17626
|
+
const outputDir = (0, import_path16.dirname)(outputPath);
|
|
17224
17627
|
await (0, import_promises9.mkdir)(outputDir, { recursive: true });
|
|
17225
17628
|
console.log(import_chalk2.default.dim("Writing converted file..."));
|
|
17226
17629
|
await (0, import_promises9.writeFile)(outputPath, result.content, "utf-8");
|
|
@@ -17286,8 +17689,8 @@ Valid subtypes: ${validSubtypes.join(", ")}`
|
|
|
17286
17689
|
// src/commands/export.ts
|
|
17287
17690
|
init_cjs_shims();
|
|
17288
17691
|
var import_commander28 = require("commander");
|
|
17289
|
-
var
|
|
17290
|
-
var
|
|
17692
|
+
var import_fs14 = require("fs");
|
|
17693
|
+
var import_path17 = require("path");
|
|
17291
17694
|
var import_chalk3 = __toESM(require_source());
|
|
17292
17695
|
init_errors();
|
|
17293
17696
|
init_lockfile();
|
|
@@ -17303,17 +17706,17 @@ async function exportToRuler(options) {
|
|
|
17303
17706
|
}
|
|
17304
17707
|
console.log(import_chalk3.default.green(`\u2713 Found ${packages.length} installed package${packages.length === 1 ? "" : "s"}`));
|
|
17305
17708
|
console.log();
|
|
17306
|
-
const outputDir = options.output || (0,
|
|
17709
|
+
const outputDir = options.output || (0, import_path17.join)(process.cwd(), ".ruler");
|
|
17307
17710
|
let rulerExists = false;
|
|
17308
17711
|
try {
|
|
17309
|
-
await
|
|
17712
|
+
await import_fs14.promises.access(outputDir);
|
|
17310
17713
|
rulerExists = true;
|
|
17311
17714
|
} catch {
|
|
17312
17715
|
}
|
|
17313
17716
|
if (!rulerExists) {
|
|
17314
17717
|
console.log(import_chalk3.default.yellow(`\u26A0 ${outputDir} directory not found`));
|
|
17315
17718
|
console.log(import_chalk3.default.dim("Creating .ruler directory..."));
|
|
17316
|
-
await
|
|
17719
|
+
await import_fs14.promises.mkdir(outputDir, { recursive: true });
|
|
17317
17720
|
console.log(import_chalk3.default.green(`\u2713 Created ${outputDir}/`));
|
|
17318
17721
|
console.log();
|
|
17319
17722
|
}
|
|
@@ -17327,11 +17730,11 @@ async function exportToRuler(options) {
|
|
|
17327
17730
|
continue;
|
|
17328
17731
|
}
|
|
17329
17732
|
try {
|
|
17330
|
-
const content = await
|
|
17733
|
+
const content = await import_fs14.promises.readFile(pkg.installedPath, "utf-8");
|
|
17331
17734
|
const rulerContent = createRulerFormat(pkg.id, pkg.version, content, pkg.format, pkg.subtype);
|
|
17332
17735
|
const rulerFilename = `${packageName}.md`;
|
|
17333
|
-
const rulerPath = (0,
|
|
17334
|
-
await
|
|
17736
|
+
const rulerPath = (0, import_path17.join)(outputDir, rulerFilename);
|
|
17737
|
+
await import_fs14.promises.writeFile(rulerPath, rulerContent, "utf-8");
|
|
17335
17738
|
console.log(import_chalk3.default.green(`\u2713 Exported ${pkg.id} \u2192 ${rulerFilename}`));
|
|
17336
17739
|
exportedCount++;
|
|
17337
17740
|
} catch (error) {
|
|
@@ -17370,9 +17773,9 @@ function createRulerFormat(packageId, version, content, format, subtype) {
|
|
|
17370
17773
|
return frontmatter + contentWithoutFrontmatter;
|
|
17371
17774
|
}
|
|
17372
17775
|
async function ensureRulerConfig(rulerDir) {
|
|
17373
|
-
const configPath = (0,
|
|
17776
|
+
const configPath = (0, import_path17.join)((0, import_path17.dirname)(rulerDir), "ruler.toml");
|
|
17374
17777
|
try {
|
|
17375
|
-
await
|
|
17778
|
+
await import_fs14.promises.access(configPath);
|
|
17376
17779
|
console.log(import_chalk3.default.dim("\u2139 ruler.toml already exists (not modified)"));
|
|
17377
17780
|
} catch {
|
|
17378
17781
|
const basicConfig = `# Ruler Configuration
|
|
@@ -17398,7 +17801,7 @@ async function ensureRulerConfig(rulerDir) {
|
|
|
17398
17801
|
# [agents.github-copilot]
|
|
17399
17802
|
# enabled = false
|
|
17400
17803
|
`;
|
|
17401
|
-
await
|
|
17804
|
+
await import_fs14.promises.writeFile(configPath, basicConfig, "utf-8");
|
|
17402
17805
|
console.log(import_chalk3.default.green(`\u2713 Created ruler.toml configuration template`));
|
|
17403
17806
|
}
|
|
17404
17807
|
}
|
|
@@ -17468,8 +17871,8 @@ init_telemetry();
|
|
|
17468
17871
|
init_errors();
|
|
17469
17872
|
function getVersion() {
|
|
17470
17873
|
try {
|
|
17471
|
-
const packageJsonPath = (0,
|
|
17472
|
-
const packageJson = JSON.parse((0,
|
|
17874
|
+
const packageJsonPath = (0, import_path18.join)(__dirname, "../package.json");
|
|
17875
|
+
const packageJson = JSON.parse((0, import_fs15.readFileSync)(packageJsonPath, "utf-8"));
|
|
17473
17876
|
return packageJson.version || "0.0.0";
|
|
17474
17877
|
} catch {
|
|
17475
17878
|
return "0.0.0";
|